Compare commits

...
Author SHA1 Message Date
weichen 7a6cfeefeb merge: dev to test (rc-v1.0.0-beta.6 promotion) 2026-09-20 07:22:42 +00:00
weichen 9f29b0badb merge: docs/bug-hunt-2026-09-20-closeout 2026-09-20 07:05:51 +00:00
weichenandCursor c7ee6b825e docs(ops): close bug-hunt permissions-uploads task after merge to dev
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 07:05:51 +00:00
weichen 032fdb050f merge: fix/bug-hunt-2026-09-20-permissions-and-uploads 2026-09-20 07:05:34 +00:00
weichenandCursor 6800a2af29 docs(ops): record permissions/uploads bug-hunt audit and short-term task
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 07:05:06 +00:00
weichenandCursor c8dbefe8a1 fix(web): align settings CAS, PDF preview, and collaboration UX guards
Wire expected_revision, blob PDF framing, mustChangePassword session rewrite,
client_key project create, no-project send disable, and right-rail persistence.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 07:05:06 +00:00
weichenandCursor 5cd22c7327 fix(authz): harden permissions, chat gate, and project create idempotency
Add project:manage_members, CSP frame-src, task-run member view, CreateUser
tx error handling, ERR_NO_PROJECT chat gate, and creator-scoped project
name/client_key uniqueness to stop duplicate creates and auth gaps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 07:04:57 +00:00
weichen 8fdcd983a6 docs(ops): record test promotion rc-v1.0.0-beta.5 and release integration slot 2026-09-20 01:10:43 +00:00
weichen dec963c16f merge: dev to test (rc-v1.0.0-beta.5 promotion) 2026-09-20 01:07:10 +00:00
weichen 0fd765a392 docs(test): record full deep test report for dev and test promotion 2026-09-20 00:48:11 +00:00
weichen bcbf4eba1c fix(pi-agent): register both MiniMax-M2.7-highspeed and MiniMax-M3 in models.json 2026-09-20 00:47:50 +00:00
weichen f47e40edad test(server): align test_manager task key to tm_system_verification in e2e test 2026-09-20 00:45:33 +00:00
weichen 97b868a942 docs(arch): allow squad in intent and workflowdef in squad and template 2026-09-20 00:44:47 +00:00
weichen 24bc4e6a2f merge: fix/audit-remainder-closeout (audit remainder closeout M1-M15, web modularization, rdev matching, schema 53) 2026-09-20 00:43:33 +00:00
weichen 89e8fb92b0 docs(ops): occupy integration slot for dev sub-branch merge, deep test and test promotion 2026-09-20 00:43:28 +00:00
weichenandCursor 3ae13bfae2 docs(test): record the U7 restart matrix and the gate follow-up
Postgres and app reach ready in about a second. Vite cold cache is not the old ten-second stall, and the login form was not measured.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 15:39:49 +00:00
weichenandCursor b48a832281 fix(squad): score only the first review-minutes table
A later standards table in the same section was counted as issue rows and failed the saved P3 sample.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 15:39:49 +00:00
weichenandCursor 6bd338e273 test(rdev): record the three real PI samples on dev
Software-plan N/A stayed closed and the proposal completed, but the planning review finished quality_failed at score 20. The poller now treats that status as terminal so it does not spin until timeout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 14:33:25 +00:00
weichenandCursor 56a8719863 refactor(web): move the workbench shell out of App
Session state stays in App. The shell, rights dialogs, and project modals now render from WorkbenchView, so App no longer mounts AppShell itself.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 14:11:32 +00:00
weichenandCursor 8a9599fbb0 refactor(web): render the chat column outside App
The workbench shell still owns session and modal state. Message stream, filters, and the composer now live in ChatColumn so App stops assembling that column inline.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:57:10 +00:00
weichenandCursor b3a1305e46 docs(test): record twenty-run slow-network login and app restart
The rebuilt bundle stays under the draft login budgets on this machine. Restart-to-health is under half a second, and the wider restart matrix is still open.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:35:52 +00:00
weichenandCursor 69e2cd259d refactor(web): render the active document column outside App
The revision toolbar, file preview, and governance bars stay with the document pane so the workbench shell no longer owns that column.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:32:39 +00:00
weichenandCursor 26d14b534b docs(test): record schema 53 rebuild and login fanout on dev
The rebuilt workbench issues one member request and one session list request. Slow-network samples improved, but twenty-run percentiles and the restart matrix are still open.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:22:38 +00:00
weichenandCursor 404defced2 test(server): reject non-member comment and audit reads on postgres
The in-memory authorizer treats any positive user id as a member, so the HTTP negative has to run against a real project row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:22:37 +00:00
weichenandCursor c49637cbb5 fix(db): restore applied goose files so fresh migrate can parse
The checksum-immutable note inside 00001 contained a goose annotation and would fail a new database. Keep that warning out of files goose already applied.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:22:37 +00:00
weichenandCursor 4b2d92a1be docs(test): record login-load baseline against Vite and deployed dev
The current workbench stays at one member fetch across 20 logins, while the deployed bundle still fans out. Slow-network samples stay diagnostic until the container is rebuilt.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:00:39 +00:00
weichenandCursor eabaadd2a0 test(web): record login waterfall and init request counts
Give the initial-load baseline a repeatable probe that strips query strings and can assert the login member fanout stays on the current project.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:57:12 +00:00
weichenandCursor 95f0e7bcf9 refactor(web): share and save freeform docs from one hook
Keep private-library share, revoke, delete, and save-to-private off the workbench shell so those side effects stay testable without growing App.tsx.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:57:12 +00:00
weichenandCursor 8de29466e1 refactor(web): persist project members from one hook
Refresh the roster and workflow documents only after the member write succeeds, so a failed add does not invent a local session.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:11:52 +00:00
weichenandCursor a29e98096a refactor(web): create projects from one hook
Remember the new project id as soon as create succeeds so a later member failure retries members instead of creating a second project.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:09:28 +00:00
weichenandCursor 9f39fbaaf3 refactor(web): handle interactive cards from one hook
Keep plan confirmation, reject, undo, and approval on the same card so a revision conflict still reconciles before the card changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:07:08 +00:00
weichenandCursor 57873f6c84 refactor(web): retry chat and task runs from one hook
Keep reconnect on the existing run id so a dropped stream does not start a second task.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:05:01 +00:00
weichenandCursor f9c2b3acdf refactor(web): edit document blocks from one hook
Apply a controlled block only after the server patch succeeds, and keep insert, move, delete, and comments on the same document state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 12:00:43 +00:00
weichenandCursor 52f69fe180 refactor(web): send chat messages from one hook
Keep attachment registration, task dispatch, and the demo shortcuts on the same path so a failed upload still blocks before any local message is stored.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:46:07 +00:00
weichenandCursor c22faecfcb refactor(web): move document lifecycle actions into a hook
Keep claim, review, and approval on one server record so the open document and the sidebar stay in the same state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:40:03 +00:00
weichenandCursor 22ea4c31ed refactor(web): sync server documents from one hook
Keep freeform append, workflow reconcile, and lease polling together so a failed list cannot wipe local docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:33:03 +00:00
weichenandCursor 113dea4ac5 refactor(web): hydrate controlled documents from one hook
Keep the editor gate, cancel, and error skeleton together so App no longer owns the fetch path.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:29:40 +00:00
weichenandCursor 27c1be86d5 refactor(web): move login workspace sync out of App
Project list, member roster, and session fetch ran as four effects inside the workbench component. They now share one hook so the entry file is not the only place that knows the login startup order.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:05:29 +00:00
weichenandCursor bfe8cb1407 refactor(web): persist the workbench from one hook
Session, project, and deliverable caches were written from scattered effects, and the legacy message migration ran twice on mount. One hook keeps that write path in a single place.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:01:44 +00:00
weichenandCursor 63b0f72081 feat(web): load the formula engine only when math appears
The login entry no longer ships KaTeX. Chat bubbles and document text render formulas after a dynamic import, and rich-text copy does the same.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:57:49 +00:00
weichenandCursor dba8139d56 feat(workflow): namespace task keys without breaking old instances
Published manifests now use bd_/pm_/tm_/sw_ prefixes so workflows cannot share a doc id. Frozen instances keep the old keys; lookup, templates, and duty checks treat the two names as the same task.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:50:25 +00:00
weichenandCursor 2a0f8b4549 docs(ops): record the frontend test and build gate
npm test and the production build passed on this branch. The entry bundle stays near 1 MB, and CURRENT still correctly says schema 52 until the containers are rebuilt.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:34:50 +00:00
weichenandCursor 7e0f3cbf9c feat(web): show the rdev start prerequisite before activation
Selecting the design-control workflow now repeats the server rule: business handover must finish with an approved CDO quote first. Other workflows stay quiet.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:33:11 +00:00
weichenandCursor 6367f865d5 feat(web): fold long workflow stages and batch their approval
Later stages with more than four documents start collapsed, and one action can put the whole stage under human approval or take it back out. The workflow chip still names the design-control flow when the catalog has not loaded.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:30:32 +00:00
weichenandCursor 5bf10c7536 docs(ops): keep the login fan-out note next to the rdev matcher
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:27:08 +00:00
weichenandCursor 2fbb5bab49 feat(intent): match rdev document names when the user asks to generate
生成项目建议书 now resolves to rd_proposal. Longer titles win, so 系统设计方案 is not mistaken for the shorter business-stage phrase, and an explicit generate command is no longer swallowed by a progress question.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:26:57 +00:00
weichenandCursor 890d2fd14e fix(web): stop login from fetching every project member list
The project list is already limited to the current user, so other rosters wait until the member panel opens. Session reload no longer follows project updates, and a newer response cannot overwrite an older user.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:22:04 +00:00
weichenandCursor b550911667 feat(squad): load rdev overlays and enforce document gates
Each rdev step now gets a role-filtered overlay so writing discipline stays out of the template. User needs, system requirements, review minutes, and upload indexes fail the quality gate when IDs, decisions, or attachment indexes are incomplete.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:12:10 +00:00
weichenandCursor 93ee98af0e feat(squad): apply rdev stage step overrides and aliases
Stage-specific squad steps now win over the kind default, including always-on regulatory and searcher roles. Each of the 60 tasks carries its writing hint and Chinese alias so lookup and the writer accept line use them.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:05:26 +00:00
weichenandCursor 8365de3426 docs(ops): keep the load and auth notes next to the rdev remainder
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:58:51 +00:00
weichenandCursor 754cba764c feat(squad): gate rdev regulatory steps on complexity tier
Listed tasks still get a regulatory step when complexity is unset or high. Medium and low skip it, and the squad model now comes from SQUAD_MODEL_ID or MINIMAX_MODEL_ID instead of a fixed name.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:58:40 +00:00
weichenandCursor 32d838285d fix(auth): resolve session and user status once per request
/auth/me was authenticating again after the middleware had already done it, and the session lookup queried user status in a second round trip. Reuse the request principal and join status into the session read so a revoked token still fails on the next request.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:54:10 +00:00
weichenandCursor 17f7fed1db feat(web): load export, preview, and charts only when opened
The login shell was downloading the document engines with the workbench. Those modules now load on click or when a matching block appears, and a failed chunk can be retried without submitting an edit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:51:04 +00:00
weichenandCursor 1b17e01ce7 docs(ops): record frontend gate and the memory authz limit
The branch frontend suite and production build passed. Cross-user document comments still need a Postgres negative because the in-memory authorizer is intentionally open.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:42:30 +00:00
weichenandCursor 952a94b6d5 fix(docrevision): ack content projection only after the fact source is written
The human ledger and the document body are different stores. Record the projection intent in the same transaction as the ledger, and clear it only when the body write succeeds so a retry cannot append a second revision.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:35:14 +00:00
weichenandCursor fc32ba3dc3 fix(web): version chat window cache and cover cross-user session list
Drop window-cache payloads that lack a schema field. Prove a non-owner listing another user's sessions is forbidden. Correct the stale test schema note in CURRENT.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:28:11 +00:00
weichenandCursor 2a666df3c1 fix(events): hold aggregate gaps on production claim
PostgreSQL claim now uses the same next-version rule as MemoryBus, and checkpoints only move forward. A later version cannot be leased while an earlier one is still missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:24:51 +00:00
weichenandCursor 01ca861e94 docs(ops): record which audit remainder items are closed
Keep M7, M15, the frontend split, and the red-line features open so the next pass does not treat them as done.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:20:07 +00:00
weichenandCursor d4041a4f0c fix(coordinator): use the caller name and reject non-decimal user ids
Ambiguous consult only redirects on low confidence, and the testing template greets the signed-in user instead of a hardcoded name. Session tokens no longer parse as user id 0. Live chat sessions now evict the oldest entry at a hard cap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:19:36 +00:00
weichenandCursor 265f09c1f2 fix(server): cache health probes, surface SSE marshal errors, fail closed on missing duties
Health checks reuse a two-second snapshot and bound the schema query. Task SSE writes an error frame when an event cannot be encoded. ResolveDocTask errors when the frozen plan has no duty row, while explicit none-duties stay zero. Drop the unwired semantic-summary replace env, record the intentional dev versus release model split, document the test/main cutover path, and archive pre-goose SQL.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:16:18 +00:00
weichenandCursor 4c34e8a503 fix(server): close security headers, lease clamp, replay digest, double start
Add nosniff, frame denial, referrer policy, and a self-origin CSP. Clamp human and squad lease TTLs and require author edit rights before a human lease. Include DryRun in replay digests so a dry-run approval cannot authorize apply. Stop Server.Start from swallowing a second Runtime.Start.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:12:17 +00:00
weichenandCursor 62ce2781ae docs(ops): record pre-test promotion readiness review
Capture the read-only check that planned capabilities are wired, while dev is not ready to merge into test until the container is rebuilt and the remaining gates run.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 08:36:58 +00:00
weichen 66421b162d merge: docs/audit-remediation-backlog (audit batch 4 report + medium backlog) 2026-09-19 07:55:48 +00:00
weichenandCursor d9cd7ebb82 docs(ops): close audit batch 4 report and park medium leftovers
Critical/high fixes are already on dev. Record the frontend test report, restore the audit note, and move remaining medium/low items into long-term so they are not treated as release blockers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 07:55:43 +00:00
weichen d73bc79800 merge: fix/audit-b4-frontend (audit batch 4: markdown XSS, unread rollback, excel preview cap) 2026-09-19 07:53:36 +00:00
weichenandCursor 6c28fca98f fix(web): close markdown placeholder XSS and unread/excel edge cases
- Escape KaTeX fallback HTML and salt math/code placeholders per render
- Roll back optimistic unread marks when POST /chat/read fails
- Reset MessageStream scroll baseline when the session changes
- Preview only the first 1000 Excel rows and say so in the sheet header

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 07:53:31 +00:00
weichen 84ba1c97d7 docs(test): audit batch 3 test report and slot release 2026-09-19 07:49:45 +00:00
weichen a2a49a64f5 merge: fix/audit-b3-sse-events (audit batch 3: sse heartbeat, task idempotency, write deadline, fencing log) 2026-09-19 07:49:15 +00:00
weichenandCursor b65e8fb642 docs(db): mark baseline and seed migrations as checksum-immutable
Goose checksums forbid rewriting applied files. Document that 00001-00009
have no down migration and that 00012's unconditional DELETE is demo-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 07:49:01 +00:00
weichenandCursor 0531462acc fix(sse): bound heartbeat lifetime and reuse idempotent task streams
- Wait for the chat SSE heartbeat goroutine to exit before the handler
  returns, so it cannot write a recycled connection
- Extend /tasks/run write deadline to 75m so long sync runs are not cut
  by the global 120s WriteTimeout before the response is written
- Reuse an existing task run on the SSE path when the idempotency key
  already belongs to the same user/session/project
- Log stale fencing on event ack so unbounded replay is observable

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 07:49:01 +00:00
weichen 9fa29bec42 docs(test): audit batch 2 test report 2026-09-19 06:03:31 +00:00
weichen c3c2b39abd docs(ops): record audit batch 1+2 merges and slot release 2026-09-19 06:02:38 +00:00
weichen 08f4e0bbf8 merge: fix/audit-b2-authz-hardening (audit batch 2: principal identity, docgov access, rate limit, compose secrets) 2026-09-19 06:01:00 +00:00
weichenandCursor 2dd8f46e64 fix(server): login/register rate limiting + compose secret hygiene (H4/H8/M8)
- H4: sliding-window rate limiter (10 attempts / 5min per IP+username)
  on login and register; successful login resets the counter; pure
  stdlib, no new dependency
- H8: docker-compose.test.yml DB/ADMIN passwords now :?required (align
  with main); docker-compose.main.yml AUTH_REGISTRATION_ENABLED
  defaults to false
- M8: fix FAV_PUBLISHER_ENABLE -> FAV_PUBLISHER_ENABLED typo so the
  gate test actually guards the real flag

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 06:00:30 +00:00
weichenandCursor d2903a1662 fix(server): enforce principal identity and docgov project access (H1-H3)
- H1: log legacy test-principal fallback (path/method/remote_addr) via
  slog.Warn so silent unauthenticated access is observable
- H2: AddComment/Claim now derive actor ID/Name/Role from the auth
  principal and server-side doc duty resolution (resolveDocGovRole),
  never from request body; GetDocument/ListComments/ListAuditLogs now
  require project membership via requireDocGovDocAccess
- H3: handleGetChatTurn asserts session ownership; handleListChatSessions
  and handleGetUserContext reject cross-user user_id (403) and stop
  defaulting to user id=1

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 05:33:38 +00:00
weichen 844f757af3 merge: fix/audit-b1-data-consistency (audit batch 1: docgov persist errors, session race, workflow plan tx, ctx threading) 2026-09-19 05:04:18 +00:00
weichenandCursor a81db16cdd fix(server): thread request ctx through session bootstrap, drop Background DB calls
- getOrCreateSession now takes ctx; GetSessionOwnerID/
  RestoreSessionContext/CompilePromptGuidance run under
  context.WithTimeout(5s) instead of context.Background()
- SyncRecentDialogue's rolling summary uses a 30s timeout context
  instead of Background, so client disconnect cancels the LLM call

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 05:03:01 +00:00
weichenandCursor e2b13406db fix(projectinstance): atomic plan save and correct completed_by attribution
- Add Store.SavePlanWithRevision: single-transaction planning upsert +
  revision bump (bump first with optimistic lock, conflict rolls back
  before any plan write), closing the SaveWorkflowPlan split-transaction
  race where plan content and revision could diverge
- AdvanceStage now takes operatorID and writes completed_by explicitly
  instead of SELECT activated_by, so the completing operator is the
  actual advancing user, not the original activator
- Service.SaveWorkflowPlan/AdvanceStage pass userID through; memStore
  implements SavePlanWithRevision under its single mutex

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 05:00:01 +00:00
weichenandCursor c7eab1f7d1 fix(chat): add RWMutex to Session and snapshot accessors to close data race
- Session gains mu sync.RWMutex + SnapshotMessages/AppendMessage/
  TouchLastAccessed/SetProjectID/Project accessors
- sendMessageInternal, hydrateVisibleHistory, getOrCreateSession,
  cleanStaleSessionsLocked, handleChat, handleChatStream,
  enrichSessionWorkflowStage, bindSessionDocumentSummaryReader all use
  locked accessors instead of raw field access
- ProjectID mutation now goes through SetProjectID (only when changed),
  closing the cross-project pollution window in handleChat/handleChatStream

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 04:55:55 +00:00
weichenandCursor 11f375f53d fix(docgov): surface lease/audit persist failures and read back fencing token
- persistLeaseLocked now returns error; AcquireLease rolls back in-memory
  lease on DB failure so memory and PG stay consistent
- appendAuditLocked uses request ctx and logs audit INSERT failures
  instead of swallowing them with context.Background()
- loadDocumentFromDBLocked now SELECTs lease_fencing_token so fencing
  survives process restart
- SaveDocumentContent/RecordDocumentViewed/RecordDocumentEdited/
  DecideModificationProposal/SetDocumentWorkDir log persist failures
  via slog.Error instead of silent _, _

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 04:50:40 +00:00
weichen e8ed33b0aa merge: fix/remove-control-center leftover cleanup 2026-09-19 03:55:40 +00:00
weichenandCursor 597aa76e60 docs: record leftover Control Center cleanup
The untracked node_modules tree and the local feature branch are gone.
The remote branch was left in place.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:55:40 +00:00
weichen d21f024dbe merge: fix/remove-control-center health closeout 2026-09-19 03:43:22 +00:00
weichenandCursor 9f2c510b62 docs(test): record dev health after Control Center removal
The rebuilt dev service returned 200 with schema 52.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:43:22 +00:00
weichen 03ec351643 merge: fix/remove-control-center 2026-09-19 03:42:23 +00:00
weichenandCursor 87f6b68001 docs(test): record Control Center removal verification
The short tests, archtest, and product web build passed after the
module was deleted.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:42:23 +00:00
weichenandCursor 14f75df1ac refactor: remove Control Center from this repository
Progress tracking now lives in a separate project. Drop the server,
docs, and module-boundary entries without restoring engineering-dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:40:00 +00:00
weichen 2641045547 merge: feature/control-center-server (supersede engineering-dashboard) 2026-09-19 03:21:12 +00:00
weichenandCursor 55fa8ddfcd docs(test): keep the merge-gate command log
*.log is ignored, so the vet/test/build transcript is stored as verify.txt.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:21:05 +00:00
weichenandCursor be0a71cf7f docs(control-center): close the merge gate
Record the unit, live LLM, and SPA walkthrough evidence, and mark the
control-center row done now that engineering-dashboard is superseded.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:20:22 +00:00
weichenandCursor 0929f58aef chore(control-center): bind the database port to loopback
The compose file published 5440 on all interfaces. Match the other
environment databases and listen only on 127.0.0.1.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:20:22 +00:00
weichenandCursor 69524205b0 fix(audit): ignore MiniMax think blocks when parsing findings
Real highspeed responses wrap reasoning in think tags that contain
brackets, which made the JSON span extractor fail before the array.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 03:04:25 +00:00
weichenandCursor 049a18d5bc test(controlcenter): cover config pick, store, and leases
Gate the merge on unit coverage for the three packages that previously
had none: env precedence, migrate/query, and claim/heartbeat/reap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 02:58:03 +00:00
weichenandCursor b3093f1b60 merge: dev into feature/control-center-server
Keep Control Center and drop engineering-dashboard. Resolve CURRENT
claim rows and module-boundaries by removing the superseded dashboard
entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 02:55:35 +00:00
weichen 283f39df34 merge: fix/user-manual-dist 2026-09-18 09:53:32 +00:00
weichen 0d94556c4f docs(ops): 记录 dist 补录合入 2026-09-18 09:53:32 +00:00
weichen 65df9d13ed docs(user-manual): 强制纳入 dist 交付物(html/pdf/docx)并补充重建说明 2026-09-18 09:53:17 +00:00
weichen 8142389b4b merge: feature/user-manual slot release 2026-09-18 09:51:32 +00:00
weichen f38e1d5ee6 docs(ops): 释放集成槽位(user-manual 冒烟 PASS) 2026-09-18 09:51:10 +00:00
weichen 6c2fbc45a3 merge: feature/user-manual 2026-09-18 09:49:04 +00:00
weichen f746a59862 docs(ops): 占用集成槽位(feature/user-manual 合入 dev) 2026-09-18 09:48:13 +00:00
weichen f6f34b87cb merge: docs/wave7-roadmap-orchestration 2026-09-18 04:43:32 +00:00
weichenandCursor 60120b7977 docs(test): archive Wave 7 orchestration confirmation report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:43:19 +00:00
weichenandCursor e64bf5ca8b docs(ops): mark Wave 0-7 done and flag Control Center conflict
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:22:22 +00:00
weichenandCursor a42e7902d7 docs(remediation): mark Wave 7 done and link orchestration record
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:21:56 +00:00
weichenandCursor 7d8029978e docs(ops): record Wave 7 roadmap orchestration confirmations
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:21:37 +00:00
weichen a88ed85cf3 merge: docs/wave6-doc-drift 2026-09-18 04:13:48 +00:00
weichenandCursor 4d7b1b5d25 docs(ops): close Wave 6 doc-drift D-1~D-6 and update SSOT
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:13:29 +00:00
weichenandCursor 28e1fa2e4b docs(project): align remaining-blocker section with gap-matrix production_ready=yes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:11:15 +00:00
weichenandCursor 6b70d28b2e docs(backlog): sync D3/D7 status with FEATURE-MATRIX
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:11:15 +00:00
weichenandCursor 447b830ff5 docs(ops): backfill closure note on intent dual-tab handoff
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:11:15 +00:00
weichenandCursor 8e17814cea docs(adr): accept modular-monolith-decoupling ADR (Phase 1/2 landed)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:11:15 +00:00
weichenandCursor eee392d93d docs(ops): archive completed PU8/W4 U9-U12 short-term tasks
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:10:53 +00:00
weichenandCursor ca0d334d57 docs(ops): flip PU8 U9-U12 contracts to status done
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:10:48 +00:00
weichen 688d9d30eb docs(user-manual): 新增系统使用说明书(33 张 dev 真实截图 + md/html/pdf/docx 四格式) 2026-09-18 04:08:49 +00:00
weichen 2ce2625c94 merge: fix/wave5-deadcode-decisions 2026-09-18 04:02:26 +00:00
weichenandCursor 60b17c03ab docs(ops): close Wave5 deadcode decisions
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:19 +00:00
weichenandCursor 2e14b3563c fix(web): remove dead notification/workflow/settings components and orphaned APIs (X-5)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:18 +00:00
weichenandCursor da62c49952 docs(sysadmin): annotate unwired system_settings keys as phase-2 backlog (X-4)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:18 +00:00
weichenandCursor 527e6daa99 docs(swboot): mark 00048 tables deferred to SWBOOT-10 (X-3)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:18 +00:00
weichenandCursor 6c61a5bc37 docs(ctxmgr): seal SEMANTIC_SUMMARY_REPLACE with decision link (X-2)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:18 +00:00
weichenandCursor a41836dec0 fix(intent,sysadmin): delete dead SEMANTIC_FALLBACK_ENABLED flag (X-1)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:18 +00:00
weichenandCursor e0f6d5991c docs(ops): plan Wave5 deadcode decisions (X-1~X-5)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 04:02:18 +00:00
weichen a12c94700f merge: fix/wave4-hardening-r1-r8 (slot release) 2026-09-18 03:47:59 +00:00
weichenandCursor e30ae4b96b docs(ops): 释放 Wave4 集成槽位为 idle
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:47:59 +00:00
weichen c4db565c40 merge: fix/wave4-hardening-r1-r8
Wave 4 隐患加固 R-1~R-8 合入本地 dev。
2026-09-18 03:47:46 +00:00
weichenandCursor e4c53a4ccd docs(ops): Wave4 R-1~R-8 收口
归档 test-report 与 assets;CURRENT/remediation 标 Wave 4 done;勾选跨用户会话挂靠负例。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:47:46 +00:00
weichenandCursor e8d2d86542 test(docrevision): hydrate 负例写入类型错误 JSONB 并先落 blob
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:46:22 +00:00
weichenandCursor c1ea8f156c fix(server): 清除 NewSession ProjectID=1 占位以免误触发项目鉴权
非项目会话创建时 ProjectID 归零,避免跨用户负例在 PG 上被 ERR_FORBIDDEN 误挡。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:46:21 +00:00
weichenandCursor 4473a2ae10 test(web): 补 401 fail-fast、单帧容错、abortAllSessions 单测
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor be9b855783 fix(web): 登出主动 abort 所有会话在途流(R-8)
新增 abortAllSessions;logout 先中止全会话再清 session。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor 21049607f4 fix(web): SSE 重连 401/404 fail-fast,单帧解析容错(R-7)
TaskRunHttpError 携带 status;非法 JSON 帧跳过并保留 seq。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor ce7d1b8ac5 fix(server): 后台 ticker 纳入 Shutdown;vault Drain 告警;bizdev 心跳超时(R-6)
reminder/vault 可停止;Drain 失败 slog.Warn;心跳/释放 lease 使用 10s 超时。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor 58b69a2b08 fix(docrevision): pg_store JSONB 反序列化失败显式报错(R-5)
hydrateDocLocked 损坏字段不再静默零值化;补 PG 负例测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor e25a197410 fix(ctxmgr): memTurns 改为实例作用域并加 TTL/容量淘汰(R-4)
消除跨 ContextManager 实例共享;超过容量时淘汰 2h 陈旧回合。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor 207e26241c fix(events): dispatcher Handlers 读路径加 RWMutex(R-3)
Register 写锁不变;shadowScan/handle 读路径 RLock,消除导出字段无锁读隐患。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:44:08 +00:00
weichenandCursor 9038c65329 fix: 补齐 rows.Err() 检查(R-2,其余包)
覆盖 kb/storage/projectworkflow/docgov/freedoc 与两个 document CLI。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:40:24 +00:00
weichenandCursor b53a97b36d fix(ctxmgr): 补齐 rows.Err() 检查(R-2,ctxmgr 包)
A 类硬失败返回;manager 降级读路径用 slog.Warn 保持既有容忍语义。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:40:24 +00:00
weichenandCursor ba1fc71f16 test(server): 跨用户会话挂靠负例测试(PG + 内存双实现)
覆盖 chat / chat/stream / chat/sessions 三条路径;受害者续用不受影响。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:39:08 +00:00
weichenandCursor a805a6bfd7 fix(server): chat/sessions upsert 与任务创建强制取 principal(R-1b)
upsert 忽略客户端自报 user_id;EnsureChatSessionOwned 拒绝跨用户挂靠。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:39:08 +00:00
weichenandCursor ecdf1fc833 fix(server): getOrCreateSession 增加会话归属校验(R-1a)
调用方传入 callerUserID;持久层与内存会话归属不匹配时返回 SESSION_FORBIDDEN;覆盖 NewSession 默认 UserID=1 占位。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:39:08 +00:00
weichenandCursor 426af51365 fix(ctxmgr): EnsureChatSession 归属 COALESCE 改为已有值优先(R-1c)
防止跨用户通过 upsert/消息落库覆盖已绑定的 chat_sessions.user_id;新增 EnsureChatSessionOwned。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:39:08 +00:00
weichen 32932e468e merge: fix/wave3-test-debt-blindspots 2026-09-18 03:02:59 +00:00
weichenandCursor 2ebf6adb2d docs(ops): close Wave 3 test-debt-blindspots (S-1/S-2/S-4/S-5)
Archive isolated PG reconcile evidence, mark gap-matrix debt closed, and
release the integration slot for Wave 4 hardening.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:02:59 +00:00
weichenandCursor 17f430b267 fix(web): reuse projectSettingsError envelope across API clients
Prefer error_code when present and route projectMembers/freeformDoc/
taskRuns/chatSessions failures through the shared structured parser.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:02:06 +00:00
weichenandCursor 3b4c9cfddf test(web): add npm scripts for all e2e specs; retire redundant revision smoke
Eliminate DOCREV_E2E_BASE_URL dual gating by deleting the one-assert smoke
spec covered by document-revision-runtime UI-10, and expose per-spec scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:02:06 +00:00
weichenandCursor a99e3f725f test(server,app): delete dead resume-workspace test; clarify plan_owner redirect
Remove the skipped client work_dir resume coverage that targeted a deleted
entry point, and document why the real-PI stop-gate stays redirected to
internal/server to avoid an import cycle.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 03:02:06 +00:00
weichenandCursor c6e7656f8e docs(ops): sync Wave 2 closeout checklist into dev lineage
Carry the done checklist and test-report link that lagged the Wave 2
merge tip so Wave 3 starts from a consistent ops state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 02:59:03 +00:00
weichen 423f7e7413 merge: fix/wave2-config-flag-align 2026-09-18 02:29:07 +00:00
weichenandCursor 24c0e5b16a docs(ops): close Wave 2 config flag alignment (E-3/E-4/E-6/E-7/E-9)
Archive three-env compose/env smoke evidence, mark remediation Wave 2
done, and release the integration slot for Wave 3.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 02:29:07 +00:00
weichenandCursor 8d97dd6b18 test(config): add compose flag declaration regression tests
Pin E-3/E-4/E-6 compose declarations so dead runner config and missing
flag wiring cannot silently regress.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 02:26:47 +00:00
weichenandCursor 55a539c551 chore(infra): drop CURSOR_RUNNER_PORT from env examples
Placeholder cursor-agent service is gone; keep CURSOR_API_KEY/MODEL/BIN
for the local cursor-cli subprocess backend.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 02:26:47 +00:00
weichenandCursor e0aabecf59 fix(infra): declare MULTI_INTENT_PLAN_TIER and U9-U12 flags in all compose envs
Also declare SEMANTIC_SUMMARY_SHADOW and PI_CHANGE_REPORT_NARRATIVE on
test/main, remove dead CURSOR_RUNNER_URL/cursor-agent, and set main
SEED_DEMO_USERS=false. Defaults stay legacy/false (no behavior change).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 02:26:47 +00:00
weichenandCursor 07fc0ecf55 fix(intent): fail closed INTENT_V2_DECISION_TIER unknown values to none
Align illegal-tier fallback with PlanTier's conservative policy so
unrecognized values never silently enable V2 query routing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 02:26:47 +00:00
weichen e35f106162 merge: Wave 1 docs closeout 2026-09-17 17:08:12 +00:00
weichenandCursor c61963633e docs(test): archive Wave 1 main env fix acceptance evidence
Close short-term task, mark remediation Wave 1 done, release integration
slot, and record main env=main / schema 52 / modes-off smoke evidence.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 17:08:12 +00:00
weichen 805aa1259f merge: Wave 1 events secrets unblock 2026-09-17 17:06:24 +00:00
weichenandCursor fb4a4f263d fix(infra): supply main events secrets so ENV=main can boot
validateProductionSecrets rejected events under ENV=main without
KB/admin passwords; depends_on events healthy then blocked app forever.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 17:06:24 +00:00
weichen 27ccd12116 merge: fix/wave1-main-env-fix
Wave 1: align main app/events ENV=main, app depends_on events healthy,
fail-closed empty-Env chat import.
2026-09-17 17:03:54 +00:00
weichenandCursor 053bfe234b docs(ops): occupy integration slot for Wave 1 main env merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 17:03:54 +00:00
weichenandCursor e286fca71b fix(server): fail-closed chat import when Env is empty
Drop Env==\"\" as a dev alias; pin compose app/events ENV alignment and
main depends_on events with unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 17:03:08 +00:00
weichenandCursor db964da21a fix(infra): align main app ENV with events and gate on events health
Set app ENV=main (was prod) and require events service_healthy before
app starts so goose migrations finish before app queries new columns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 17:03:08 +00:00
weichenandCursor 5ad2585ed7 docs(ops): claim Wave 1 main env fix branch
Register short-term task and CURRENT mutex=infra for E-1/E-2/E-5.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 17:03:08 +00:00
weichen af0912b0b3 merge: Wave 0 SSE evidence asset 2026-09-17 16:49:48 +00:00
weichenandCursor 7aca97e9b3 docs(test): store Wave 0 SSE evidence as txt (log gitignored)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 16:49:48 +00:00
weichen 4bccedb4ad merge: docs Wave 0 P0 closeout 2026-09-17 16:49:32 +00:00
weichenandCursor 40a9c1b285 docs(test): archive Wave 0 P0 bug-fix acceptance evidence
Close short-term task, mark remediation Wave 0 done, release integration
slot, and attach real pi-agent SSE heartbeat log plus suite results.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 16:49:32 +00:00
weichen 810fb96e76 merge: fix/wave0-p0-sse-chat-cache-bugs
Wave 0 P0: SSE heartbeat/deadline, run/stream 400+pre-flush start,
chat window cache key/LRU, IndexedDB restore merge.
2026-09-17 16:43:01 +00:00
weichenandCursor 2620d808c4 fix(web): unify chat window cache keys and merge IndexedDB restore
Pass userId on every saveSessionWindowCache write, LRU-evict full cache
keys, and applyRestoredFileRaw so mount restore cannot drop newer deliverables.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 16:42:56 +00:00
weichenandCursor 54244ed97a fix(server): extend SSE write deadline for chat and run/stream
Wire heartbeat + SetWriteDeadline into handleChatStream and
handleRunTaskStream; reject malformed run/stream JSON with 400; move
CreateAndStart/Subscribe before SSE Flush so failures stay JSON errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 16:42:56 +00:00
weichenandCursor 64efaa32c8 docs(ops): register system health audit and claim Wave 0 fix branch
Archive the 2026-09-17 health-check audit/remediation and short-term Wave 0
task so P0 SSE/cache fixes can proceed under mutex chat+web.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 16:42:55 +00:00
weichen dfa2d2d4bd merge: chore/release-s1c-integration-slot
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
2026-09-17 15:52:53 +00:00
weichenandCursor 1dd1a8d23f docs(ops): release integration slot after S1-continued smoke
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 15:52:53 +00:00
weichen e58c707df6 merge: feature/rdev-template-depth-s1-continued
S1 continued: deepen remaining 46 rdev templates, lint 60/60, real-PI samples, instance_no fix.
2026-09-17 15:51:41 +00:00
weichenandCursor 36261e9d13 docs(ops): claim merge slot and archive S1-continued short-term
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 15:51:30 +00:00
weichenandCursor 9b35c1abd1 docs(test): archive S1-continued rdev template depth report and sync matrix
Record real-PI samples for review and verification templates, mark S1 continued done across writing-spec/backlog/FEATURE-MATRIX/CURRENT.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 15:51:09 +00:00
weichenandCursor 12608c21ef fix(projectinstance): allocate next instance_no for planning drafts
Avoid unique (project_id, instance_no) collisions when saving a new
workflow plan after a completed main instance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:56:50 +00:00
weichenandCursor 04243e64d8 feat(rdev-templates): deepen stage-10–13 transfer/validation templates (S1 batch 5)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:37:19 +00:00
weichenandCursor 7c50128bd1 feat(rdev-templates): deepen stage-08 verification templates (S1 batch 4)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:37:18 +00:00
weichenandCursor 05629721f0 feat(rdev-templates): deepen stage-06 software/inspection/list templates (S1 batch 3)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:37:18 +00:00
weichenandCursor 1692a57175 feat(rdev-templates): deepen stage-06 hardware/process templates (S1 batch 2)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:37:18 +00:00
weichenandCursor 8c37ac0cd5 feat(rdev-templates): deepen 6 review-record templates (S1 batch 1)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:37:03 +00:00
weichenandCursor 535eb442b5 docs(ops): add short-term for rdev-template-depth-s1-continued
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:34:45 +00:00
weichenandCursor b800f9adf9 docs(ops): claim rdev-template-depth-s1-continued and open short-term
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:34:34 +00:00
weichen f8c4a61922 merge: chore/archive-proposal-http-task
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
2026-09-17 14:12:13 +00:00
weichenandCursor 51d6d53ede docs(ops): archive proposal-http short-term after closeout
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:12:13 +00:00
weichen 21fb95458a merge: chore/closeout-claim-cleanup
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-17 14:12:02 +00:00
weichenandCursor fc227f339c docs(ops): clear closed feature worktree claims after closeout
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:12:02 +00:00
weichenandCursor dcc859ecb0 docs(test): archive proposal HTTP live evidence and release slot
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:11:23 +00:00
weichen 1f2fcd0727 merge: feature/docgov-modification-proposal-http 2026-09-17 14:08:06 +00:00
weichenandCursor c89a58e026 docs(ops): occupy integration slot for proposal-http merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:08:02 +00:00
weichenandCursor d01694b556 docs(ops): record author-only pilot and proposal-http task claim
Archive CAS evidence for workflow.allow_author_only_approval on dev,
mark proposal HTTP audit resolved, and claim the feature branch in CURRENT.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:07:52 +00:00
weichenandCursor c0e7df5abf feat(docgov): expose proposal HTTP and wire frontend decide flow
Add POST /api/v1/docgov/proposal for ProposeModification, harden decide
status mapping, and replace App pendingProposal local mock with real API calls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 14:07:52 +00:00
weichen bea70b064b docs(control-center): strengthen agent integration spec — onboarding protocol, per-stage entry/exit criteria, decision quality bar, event cadence 2026-09-17 14:06:24 +00:00
weichen b5bacee331 refactor(control-center): remove legacy engineering-dashboard, superseded by control-center
- delete cmd/engineering-dashboard, internal/engineeringdashboard, scripts/engineering-dashboard.sh
- archive old design doc to .doc/archive/design/ with deprecation banner
- FEATURE-MATRIX: mark old row removed, add removed to status contract
- system-design README: section 8 now points to Control Center SSOT
2026-09-17 14:00:38 +00:00
weichenandCursor ba92a8b3a5 docs(status): note author-only merged to dev in FEATURE-MATRIX
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:58:30 +00:00
weichenandCursor cbeefdb9ed docs(ops): release integration slot after author-only merge smoke
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:58:19 +00:00
weichenandCursor 09a9921e87 merge: feature/document-author-only-plan
Close out document author_only U1–U6 into dev (default policy off).
Resolved CURRENT claim table and bizdev service conflicts with rdev prior-doc injection.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:57:12 +00:00
weichenandCursor 4f1bb1f02d docs(ops): archive author-only U1–U6 and close remediation DoD
Move short-term tasks to archive, update MATRIX/INDEX/CURRENT, and hand off merge to dev.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:55:17 +00:00
weichenandCursor 472f845a88 docs(test): track U6 API evidence as txt (logs gitignored)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:49:12 +00:00
weichenandCursor 7b09da1f99 docs(ops): close document-author-only U6 and note proposal HTTP gap
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor 58b785e110 docs(test): add document-author-only U6 closed-loop report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor cf7f55a1b9 test(web): cover author_only action visibility and docgov client shapes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor 916931f5d8 feat(web): surface duty_policy author_only badge end-to-end
Propagate summary.duty_policy into deliverables/AST and show 编制人兼任 on the action bar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor b87fc5007f feat(web): call real docgov lifecycle APIs from action handlers
Replace local lifecycleState mocks; add handleRejectApprove; use holdsDocDuty for chat shortcuts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor aed7f3f9b5 fix(web): gate docgov actions by duty id, not folded role
author_only A/A/A users were stuck as author-only under resolveCurrentDocRole priority.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor 3c6342bfee feat(web): add docgov claim/submit/review/approve API client
Wire frontend to existing lifecycle HTTP so approval actions can leave local mock state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:48:59 +00:00
weichenandCursor 8658a135ab docs(ops): claim and close document-author-only U4 and U5
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichenandCursor 7ccb821d6c test(web): cover author_only duty resolution and validation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichenandCursor 72686d13cb feat(web): add per-document author_only toggle in project settings
Show a single author picker when兼任 is enabled, respect the system
capability flag, and surface author_only docs in activation preview.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichenandCursor be128602e4 feat(web): resolve client duty_policy for author_only plans
Align TypeScript types and projectSettingsDuties with backend
ResolveDocTaskDuty so author_only no longer fails as partial.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichenandCursor 2c012ee59f test: cover author_only access matrix and duty_policy audits
Prove A can run the full action chain and outsiders stay denied; assert
audit Details carry duty_policy on all five transitions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichenandCursor 3f7358d454 feat(docgov): record duty_policy on lifecycle audit details
Surface the document duty mode on submit/review/approve transitions for
consistent logs under author_only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichenandCursor f02600d75c fix(projectinstance): resolve author_only duties in ABAC gates
Use ResolveDocTaskDuty so normalized author-only plans (author ID only)
are treated as full A/A/A for access, stage visibility, and readiness.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 13:15:05 +00:00
weichen 87bcf05043 feat(control-center): allow LAN bind with mandatory fixed console token (serve-lan) 2026-09-17 13:11:52 +00:00
weichen 6714081b12 docs(control-center): P6 design spec, agent integration guide, acceptance report
Also fixes ListTasks ?q= filter 500 (duplicate $%d placeholder rendered as
%!d(MISSING)) found in P6 smoke; adds TestTaskListQueryFilter regression.
2026-09-17 12:59:12 +00:00
weichen 07a8e126fc feat(control-center): P5 scheduled repo audits — deterministic checks, LLM review, findings UI 2026-09-17 12:39:46 +00:00
weichen f79956c498 feat(control-center): P4 .doc importer, agent CLI, task doc export
- internal/controlcenter/importer: scan .doc/ops/{short-term,long-term}
  and .doc/backlog for task docs, upsert cc_tasks keyed by slug; maps doc
  status/stage, auto-creates the three plans, follows doc status only
  while a task is planned/in_progress (terminal statuses never regress),
  skips unchanged docs, and resolves cross-directory slug collisions by
  fixed directory precedence with a warning
- cmd/control-center: import-docs subcommand (also runs at serve startup
  and on the doc-sync ticker) plus the agent CLI: next / instruction /
  claim / heartbeat / release / event / artifact / advance-request /
  decision / report, thin net/http client, compact JSON output
- console API POST /api/v1/tasks/{id}/export-doc renders a task per
  .doc/ops/templates/short-term-task.md into .doc/ops/short-term/, refuses
  overwrite (409) and unsafe slugs, then backfills doc_path
- fix pre-existing TestAgentHasNoAdvanceRoute: SPA catch-all GET / makes
  the mux answer 405 for unmatched POST paths; accept 404 or 405
- archtest allowlist: controlcenter/importer -> pipeline, store
2026-09-17 11:57:47 +00:00
weichen b0095de398 feat(control-center): P3 web SPA — overview, stage kanban, task pipeline, decisions, docs search
- control-center/web: Vite+React+TS SPA (hash routing, token login via
  localStorage, marked-lexer markdown rendering without raw HTML injection)
- pages: overview (stage x state matrix, SSE feed w/ 10s poll fallback),
  8-lane kanban + task create, task detail stepper/pipeline/ops
  (assign/advance/send-back/external-submit), decision inbox, docs browse
  + semantic/keyword/hybrid search, global stage settings, audit placeholder
- internal/controlcenter/webui: //go:embed dist, SPA fallback, index no-store;
  dist committed so go build works without node
- server: GET / serves embedded SPA; pipeline view now includes artifact
  content for console rendering
- archtest: allowlist controlcenter/server -> controlcenter/webui
2026-09-17 10:13:16 +00:00
weichenandCursor c6c07263c7 docs(ops): claim and close document-author-only U3
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 67b3b5e070 test: cover duty lock, heal/revoke skip, and instance duty adapter
Unit evidence for AE5a/AE5b filters; optional PG cases when
TEST_DATABASE_URL is set.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 750b904439 feat(app): wire projectinstance duties into bizdev
Composition-root adapter maps live instance DocTasks to bizdev's narrow
InstanceDutySource without crossing module boundaries.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 5b9b46ee8d feat(bizdev): prefer instance-governed duties when generating docs
Inject InstanceDutySource, resolve governed bindings, lock duties after
create, and skip in-memory HealBinding overwrite for governed docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 42a3b1e56c feat(docduty): skip duty_locked rows in heal and revoke
Keep instance-governed A/A/A (or separated) bindings immune to project
default heal and member-slot revocation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 89484177ee feat(docgov): lock document duties and project duty_policy
Add LockDocumentDuty for PG/memory and expose duty_policy on workflow
document summaries for later UI marking.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 7d3474816b feat(db): add document_records duty_locked and duty_policy columns
Stamp instance-governed document duties at create time so heal/revoke can
skip locked rows without importing projectinstance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:59:38 +00:00
weichenandCursor 748df016b2 docs(ops): release rdev merge slot, archive P0/P1 task, register S1续批
Also record the ad-hoc verification Path("") join pitfall as a low-severity
audit note so future sampling scripts fail closed instead of scanning bizdev/.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:52:24 +00:00
weichenandCursor 7e6860f861 docs(ops): smoke phase for rdev merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:47:57 +00:00
weichen 68f63d3c30 merge: feature/rdev-template-depth 2026-09-17 09:47:49 +00:00
weichen 9bb4ec3665 merge: feature/rdev-core 2026-09-17 09:47:44 +00:00
weichen 63f1fa5f87 feat(control-center): P2 document vector store — ingestion, chunking, embedding, hybrid search
- internal/controlcenter/embed: OpenAI-compatible /embeddings client
  (batch<=16, 30s timeout, 5xx/network retried once, 4xx not), Embedder
  interface, deterministic offline Stub, pgvector literal formatting
- internal/controlcenter/docs: .doc/**/*.md sync into cc_documents with
  sha256 diffing and vanished-file removal; YAML front matter -> jsonb,
  title fallback, taxonomy from first .doc dir; heading-based chunking
  with paragraph bisection over ~1800 est. tokens; chunk_hash idempotent
  inserts (unchanged chunks keep embeddings); embedding failures degrade
  to NULL vectors without failing the sync; IndexArtifact for
  cc_stage_artifacts; StartPeriodic ticker (CC_DOC_SYNC_SECONDS)
- server: GET /api/v1/docs (taxonomy/q filters), /api/v1/docs/{id},
  /api/v1/docs/search (semantic|keyword|hybrid, ts_rank+ILIKE keyword
  fallback, 0.6/0.4 max-normalized fusion, degraded flag when embedding
  unavailable); async artifact indexing hooked into agent artifacts and
  external-submit handlers
- archtest module-boundaries allowlist updated for new packages
2026-09-17 09:47:29 +00:00
weichenandCursor 7f30a5049e docs(ops): occupy slot to merge rdev-core and template-depth
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:47:14 +00:00
weichenandCursor 4e271c54bb docs(test): archive rdev template-depth S0/S1 real-PI evidence
Record true PI samples (intake + rd_design_input_spec), update FEATURE-MATRIX
remaining work, backlog S1续批/S2/S3, and allowlist engineeringdashboard for
archtest green on this branch lineage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:47:05 +00:00
weichenandCursor ca7b7da237 docs(ops): claim rdev-template-depth short-term and CURRENT mutex
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:52 +00:00
weichenandCursor 93ad80b9a7 feat(rdev): deepen phase 01-05 templates with ISO 13485 sections
Replace generic placeholders for 14 rd_* docs, add writing-norm doc and
allowlist lint so structure and per-section instructions stay enforceable.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:37 +00:00
weichenandCursor dc3aef4607 fix(squad): inject rdev_leader InstructionsFile for DHF final review
Prefer AgentSpec.InstructionsFile when building AGENTS.md so rd_* leader
steps no longer fall back to business-tone leader.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:37 +00:00
weichenandCursor aba38ef7a9 fix(engineering-dashboard): drop startup token for personal local use
Rely on loopback bind plus Host/Origin checks; open http://127.0.0.1:8787/
without a query token after SSH tunnel.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:26 +00:00
weichenandCursor 37b1aaa3ae feat(rdev): add medical design-control workflow (13 stages / 60 docs)
Seed rdev.v2.json, rd_ templates, catalog policy (order 40), squad
kind orchestration, and hard precheck requiring completed main (CDO).
Includes StageKey dynamicization from P0 and docs for P2–P4 skeleton.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:26 +00:00
weichenandCursor a39823da38 fix(docgov): pass dynamic StageKey into document ledger create
Stop hardcoding V0.5_feasibility when creating docgov records; prefer
frozen-instance StageKey from TaskRunRequest with main-task fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:09 +00:00
weichenandCursor c03d0a3a6e docs(ops): claim and close document-author-only U2
Record short-term evidence and mark the CURRENT claim done.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:39:59 +00:00
weichenandCursor 68dbe8a6b2 test(projectinstance): cover author_only planning and activation
Verify resolve/normalize/hash stability, policy gating, stale token
rejection, and HTTP error mapping for the new duty policy path.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:39:59 +00:00
weichenandCursor 1651c30e90 feat(api): map author-only policy errors on workflow settings
Return 403/409/503 for disabled, changed, and unavailable governance
policy conditions during plan save and activation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:39:59 +00:00
weichenandCursor 0b67a901a9 feat(app): wire sysadmin author-only policy into projectinstance
Adapt sysadmin.AuthorOnlyPolicySource at the composition root so
projectinstance stays within module-boundary allowlists.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:39:59 +00:00
weichenandCursor a2aa3d41bd feat(projectinstance): support per-doc author_only duty policy
Add ResolveDocTaskDuty, require the system policy on save/preview,
lock the policy row during activation, and derive A/A/A assignments.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:39:59 +00:00
weichenandCursor ba57c9a4de feat(db): bind activation tokens to author-only policy revision
Prevent preview tokens from activating after the governance switch
revision changes by storing the revision on each confirmation token.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:39:59 +00:00
weichenandCursor 3b6def256e docs(ops): claim and close document-author-only U1
Record short-term task evidence and mark the CURRENT claim done.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:15:15 +00:00
weichenandCursor 430a47ad8c test(sysadmin): cover author-only CAS, audit rollback, and HTTP gates
Verify concurrent revision conflicts, null/string rejection, plain-user
denials, and PG lock/read paths for the new policy key.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:15:15 +00:00
weichenandCursor a2cbaf1e33 feat(sysadmin): CAS author-only policy with transactional audit
Register the workflow total switch, require expected_revision for
updates, and expose AuthorOnlyPolicySource for activation locking.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:15:15 +00:00
weichenandCursor b4b300bb8a feat(db): add author-only approval policy revision and audit
Seed workflow.allow_author_only_approval closed, add monotonic
revision on system_settings, and a narrow policy audit table.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:15:15 +00:00
weichen b11cc64845 feat(control-center): P1 pipeline core — stage machine, decisions, artifacts, leases, SSE
- pipeline: 8-stage order, NextStage (testing skippable), gate pure
  functions (agents may never advance; only in_progress->awaiting_review)
- tasks: domain layer over cc_* tables — CRUD, claim/heartbeat/release
  leases, advance-request, decisions with strict suggestion validation,
  stage transitions, external submit, stage settings, overview, lease reaping
- server: agent + console routes, SSE broker broadcasting every event
  insert, 60s lease reaper goroutine, 1MB body limit, domain error mapping
- archtest: allowlist controlcenter/* and engineeringdashboard packages
2026-09-17 09:13:36 +00:00
weichenandCursor 7a590670e9 docs(workflow): approve R9/R10 and harden heal acceptance
Mark lifecycle boundaries reviewed; require HealProjectDocuments
projection stability across list/generate/member triggers, and
explicitly exclude emergency stop from the global switch scope.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:06:51 +00:00
weichen f6c9638e60 docs(workflow): plan per-document author-only approval policy 2026-09-17 08:49:46 +00:00
weichen 2be43efddd feat(control-center): P0 skeleton — standalone server, pgvector compose, goose schema, token auth 2026-09-17 08:38:50 +00:00
weichen cf805a73a7 docs(ops): claim control-center-server task and register in CURRENT 2026-09-17 08:33:10 +00:00
weichen adb48c86a5 merge: feature/initial-load-perf-u2 (docs acceptance) 2026-09-17 08:25:43 +00:00
weichenandCursor ae219955ab docs(test): archive initial-load U2 acceptance evidence
Record curl/browser before-after metrics, mark U2 done, and release the
integration slot while leaving U1/U3–U7 open.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 08:25:43 +00:00
weichen bc01781438 merge: feature/initial-load-perf-u2 2026-09-17 08:18:18 +00:00
weichenandCursor 9335c4c90c feat(server): negotiate static compression and fix asset SPA fallback
Serve precompressed .br/.gz with Cache-Control and Vary, and return 404
for missing /assets and /fonts instead of index.html.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 08:18:11 +00:00
weichenandCursor 3dbd9770b5 feat(web): precompress dist assets to .br and .gz at build time
Use Node zlib in a post-vite step so the Go server can serve negotiated
variants without per-request compression cost.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 08:18:02 +00:00
weichenandCursor dc769686a9 feat(web): self-host Inter and JetBrains Mono for login shell
Remove blocking Google Fonts stylesheet so the login form is not gated
on an external CSS request; keep unicode-range subsets and OFL license.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 08:18:02 +00:00
weichen 59e6fade72 merge: feature/initial-load-performance-plan 2026-09-17 08:08:23 +00:00
weichenandCursor 3445d386ea docs(perf): archive initial-load diagnosis and remediation plan
Capture audit evidence, performance baseline, and U1–U7 remediation plan
without business code changes so the work can land on dev before U2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 08:08:20 +00:00
weichenandCursor d0ef6961b4 docs(ops): release slot after engineering-dashboard CSP fix
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:40:28 +00:00
weichen 0a1302eab0 merge: fix/engineering-dashboard-csp-token 2026-09-17 07:40:27 +00:00
weichenandCursor 2319138800 docs(ops): occupy slot to merge engineering-dashboard CSP fix
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:40:27 +00:00
weichenandCursor 7fd7fb8a2a fix(engineering-dashboard): read token from URL/meta under CSP
Remove the inline token script blocked by script-src 'self', so the
live page no longer calls the snapshot API with token=undefined.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:39:21 +00:00
weichenandCursor ce2a561d4d docs(ops): release slot after engineering-dashboard merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:11:18 +00:00
weichenandCursor f47161131c merge: feature/engineering-dashboard
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:11:17 +00:00
weichenandCursor fd1659a416 docs(ops): occupy slot to merge engineering-dashboard
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:10:36 +00:00
weichenandCursor 7e05473cf5 docs(engineering-dashboard): closeout report matrix and launcher
Add test report, FEATURE-MATRIX row, archive the short-term task,
mark CURRENT claim done, and ship the thin serve/export script.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:10:04 +00:00
weichenandCursor e251ce325a feat(engineering-dashboard): U6-U7 serve UI and offline export
Add loopback-only HTTP server with startup token, Host/Origin/CSP
guards, embedded live UI, CLI serve/export, and safe single-file HTML.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:08:27 +00:00
weichen dd887bb08f merge: feature/system-admin-console closeout docs 2026-09-17 07:08:07 +00:00
weichen 62d6241348 docs(test): system admin console acceptance report and closeout
- test report: dev smoke (schema 48->49), 4 admin endpoints, settings
  write-read roundtrip, anon 401 / unknown-key 400 / non-admin 403
- task status done; FEATURE-MATRIX row done; release integration slot;
  env snapshot dev schema 49
2026-09-17 07:08:07 +00:00
weichenandCursor 79ee72267c feat(engineering-dashboard): U5 reconcile and snapshot publisher
Merge docs/git/runtime facts into an immutable snapshot with conflict
retention, last-known stale handling, and acceptance-sample coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:04:46 +00:00
weichenandCursor a07ba1065b feat(engineering-dashboard): U2-U4 docs git and runtime collectors
Add allowlisted markdown indexing, read-only git plumbing via injected
runners, and docker/readiness collection with path and loopback guards.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:03:32 +00:00
weichen dc7c31edc9 merge: feature/system-admin-console 2026-09-17 06:59:21 +00:00
weichen 0088ae7d44 docs(ops): occupy integration slot for system-admin-console merge 2026-09-17 06:59:21 +00:00
weichenandCursor e46ec0e4e7 feat(engineering-dashboard): U1 freeze snapshot and facet model
Define versioned Snapshot/Fact/Conflict/TaskState contracts with
independent plan/git/verification/deployment axes and acceptance fixtures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:59:02 +00:00
weichen e7fa6fb023 docs(status): add system admin console row to FEATURE-MATRIX 2026-09-17 06:58:08 +00:00
weichen e310f06504 docs(ops): register system-admin-console task and claim 2026-09-17 06:57:13 +00:00
weichen 0eaca61545 feat(web): full-screen system admin console, absorb AdminSettingsModal
- top-level view switch workbench|admin in App.tsx (no router; hash #turn
  anchors untouched)
- new admin/console/AdminConsoleView with left group nav in the existing
  token/inline-style idiom, plus 8 self-fetching sections: overview, kb,
  features, settings, workflows, roles, users, docs
- absorb the six AdminSettingsModal tabs into sections and delete the modal
- new api/systemAdmin.ts + types for /api/v1/admin/system/* endpoints
- playwright smoke spec web/e2e/admin-console.spec.ts (skip by default)
2026-09-17 06:57:03 +00:00
weichen f1404d5bd2 feat(sysadmin): add system admin aggregation API and system_settings store
- new internal/sysadmin package (overview/kb/features/settings) with small
  port interfaces; business packages stay unaware of sysadmin
- new routes /api/v1/admin/system/{overview,kb,features,settings} guarded
  by requireSystemAdmin
- goose 00049: system_settings table (key/jsonb value, updated_by/at)
- SettingSpec whitelist registry with DB > env > default precedence
- register sysadmin in module-boundaries.yaml (archtest rules)
2026-09-17 06:56:46 +00:00
weichenandCursor fa5e10542a docs(ops): claim engineering-dashboard implementation
Register CURRENT mutex and mark short-term in_progress on the
feature/engineering-dashboard worktree before coding.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:56:20 +00:00
weichenandCursor 12884a1710 docs(ops): release slot after engineering-dashboard plan merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:55:44 +00:00
weichen c336de59b8 merge: feature/project-control-center-plan 2026-09-17 06:55:44 +00:00
weichenandCursor 44fa8d5059 docs(ops): occupy slot to merge engineering-dashboard plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:55:44 +00:00
weichenandCursor ed4a49bfa6 docs(engineering-dashboard): add personal control center design plan
Freeze the independent local readonly engineering-dashboard design,
short-term task entry, and system-design index before implementation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:55:32 +00:00
weichen 15881cd0e6 docs: sync null-fk promote closeout onto test 2026-09-17 06:20:40 +00:00
weichen 173a512c28 merge: docs/promote-null-fk-to-test-closeout 2026-09-17 06:20:40 +00:00
weichenandCursor ef5f0fdef9 docs(ops): close null-fk promote to test at rc-v1.0.0-beta.4
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:20:40 +00:00
weichen d73d2e8633 release-candidate: promote optional-duty null FK fix to test [Tag: rc-v1.0.0-beta.4] 2026-09-17 06:19:57 +00:00
weichen 7f0f8a1ca2 merge: feature/promote-null-fk-to-test 2026-09-17 06:19:57 +00:00
weichenandCursor fa8598e89b docs(ops): occupy slot to promote optional-duty null FK into test
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:19:57 +00:00
weichen e78b6c1470 merge: docs/docgov-optional-duty-null-fk-report 2026-09-17 06:12:56 +00:00
weichenandCursor c9fd8a4d7f docs(test): archive optional-duty null FK fix report and close task
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:12:56 +00:00
weichen e488d10840 merge: fix/docgov-optional-duty-null-fk 2026-09-17 06:08:52 +00:00
weichenandCursor 4606119581 docs(ops): occupy integration slot for optional-duty null FK smoke
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:08:52 +00:00
weichenandCursor 149dec8993 docs(ops): claim and audit docgov optional-duty null FK fix
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:08:35 +00:00
weichenandCursor fa2407f92c fix(stream): classify document ledger FK failures as DOC_LEDGER_ERROR
Avoid masking persist document ledger / 23503 errors as INTERNAL_ERROR.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:08:35 +00:00
weichenandCursor c2efcdbacd fix(docgov): map zero duty ids to NULL on CreateOrGetDocument
Optional reviewer/approver duties leave UserID=0; writing 0 into
document_records FK columns failed with SQLSTATE 23503. Align create
path with docduty nullIfZero and surface ensureUser failures in logs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 06:08:35 +00:00
weichen 111f25c9a8 docs: sync test promotion closeout onto test 2026-09-17 05:05:26 +00:00
weichen feefc322a7 merge: feature/promote-dev-to-test-closeout
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 1s
CI / web (push) Failing after 0s
2026-09-17 05:05:26 +00:00
weichenandCursor 3978e6b461 docs(ops): record test promotion to rc-v1.0.0-beta.3
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 05:05:26 +00:00
weichen e5e09560c7 release-candidate: 汇集 dev 功能至 test 分支,准备长期实测 [Tag: rc-v1.0.0-beta.3] 2026-09-17 05:03:13 +00:00
weichen 4fce16c91b merge: feature/promote-dev-to-test-2026-09-17 2026-09-17 05:03:04 +00:00
weichenandCursor 151953a520 docs(ops): occupy slot to promote local dev into test
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 05:03:04 +00:00
weichen 46a0fb2d5a merge: feature/w7-d7-data-inventory 2026-09-17 04:58:52 +00:00
weichenandCursor dbc9b73278 docs(ops): record W7 D7 chat data inventory without deletion
Keep the D7 matrix row deferred until compliance signoff; no gap-matrix blocker.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:58:52 +00:00
weichen cb4fbb69a6 merge: feature/w6-fav-subscriber-shadow 2026-09-17 04:26:18 +00:00
weichenandCursor 58c04ff6c5 docs(ops): close W6 FAV shadow and release integration slot
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:26:18 +00:00
weichenandCursor 9c0954ba6e docs(ops): record W6 FAV subscriber shadow evidence
Keep the FAV matrix row partial because live staging was not opened.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:25:17 +00:00
weichenandCursor 2c1d040ccf feat(events): add FAV subscriber shadow without live writes
ObserveShadow computes intended outcome only and refuses FAV_DEGRADED_READ; HandleLease and Register(fav) stay fail-closed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:25:17 +00:00
weichen 49d901e964 merge: feature/w5a-software-bootstrap-ui-pi 2026-09-17 04:12:38 +00:00
weichenandCursor 7c1ae7ec38 docs(ops): close W5a and release integration slot
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:12:38 +00:00
weichenandCursor eee42d1d16 feat(workflow-design): catalog-driven software create wizard and docs_only PI
Software projects mount only bootstrap/delivery keys and skip the medical
seven-template clone. SWBOOT-10 stays a fail-closed stub.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:11:03 +00:00
weichen f5a80fd653 merge: feature/w4-u9-segment-live 2026-09-17 03:15:35 +00:00
weichenandCursor 1c1a4bb683 docs(ops): close W4 U9–U12 and release integration slot
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 03:15:35 +00:00
weichenandCursor 43555e5d08 feat(intent-plan): wire U9 PI segment proposer and per-flag U10–U12 evidence
Rules that already split skip the LLM. Independent flags stay off by
default and do not raise MULTI_INTENT_PLAN_TIER.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 03:14:57 +00:00
weichen 9ac1eb178e merge: feature/w3-pi-change-report-narrative-live 2026-09-17 03:03:20 +00:00
weichenandCursor 2ba6b3ec74 docs(ops): close W3 narrative live and release integration slot
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 03:03:20 +00:00
weichenandCursor 47a740a9c4 feat(docgov): wire no-tool PI change-report narrative
Flag-on CreateAgentCandidate asks the product PI runner for
change_report_narrative_v1 after the real digest is known; timeout
and malformed payloads stay full fallback. Default flag remains off.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 03:02:11 +00:00
weichen 0bc98c6da4 merge: feature/w2-semantic-summary-shadow-live 2026-09-17 02:51:55 +00:00
weichenandCursor 886449958f feat(chat): wire no-tool PI semantic summary shadow
Enable SEMANTIC_SUMMARY_SHADOW to call the product PI runner on authorized messages only, keep REPLACE unwired, and record MiniMax evidence for the D3 matrix close.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:51:55 +00:00
weichen 982dc48345 merge: chore/leftover-hygiene-2026-09-17 2026-09-17 02:43:44 +00:00
weichenandCursor 4b509efefc docs(ops): align leftover branches and contracts with local dev
Prune merged worktrees/refs and correct SWBOOT/PU scaffolding docs so W2–W7 start from git truth, without merging frozen FAV/herdr/project143 branches.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:43:44 +00:00
weichen 80ef2f61a0 merge: docs/archive-kb-host-auth-short-term 2026-09-17 02:06:19 +00:00
weichenandCursor f2c2e34f0b docs(ops): archive completed kb-host-auth short-term task
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:06:19 +00:00
weichen 392b3bc1c9 merge: docs close kb-host-auth 2026-09-17 02:06:09 +00:00
weichenandCursor 6f52896dad docs(ops): close kb-host-auth task and release integration slot
Record rebuild smoke: kb_ready=true and redacted online DSN in container.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:06:09 +00:00
weichen 5182da20ed merge: fix/kb-host-auth-layered-load (no Fatalf) 2026-09-17 02:04:51 +00:00
weichenandCursor 6fa933ac27 fix(kb): return offline client instead of Fatalf under require-online
Library must not abort the process; E2E callers use EnsureOnline/t.Fatal
so ambient RUN_PI_E2E no longer kills short server tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:04:51 +00:00
weichen cdd3f8c559 merge: fix/kb-host-auth-layered-load 2026-09-17 02:03:21 +00:00
weichenandCursor abbb461780 docs(ops): claim integration slot for kb-host-auth merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:03:21 +00:00
weichenandCursor c977e8247a docs(test): record KB host-auth layered load fix and acceptance
Short-term task, CURRENT claim, and unit/live boolean test report.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:03:07 +00:00
weichenandCursor e782400736 fix(api): expose kb_ready and gate E2E/nightly on shared KB
Health reports kb_ready; PI E2E uses layered Load + require-online;
nightly preflights SELECT 1 before product suite.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:03:07 +00:00
weichenandCursor f3ed57c41f fix(kb): redact DSN logs and fail closed when KB must be online
Add Online(), honor KB_REQUIRE_ONLINE/RUN_PI_E2E unless KB_ALLOW_OFFLINE,
and refuse empty/wrong credentials without leaking secrets in logs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:03:07 +00:00
weichenandCursor cdbf9cab63 fix(config): layer root .env over configs/.env.{ENV} for KB auth
Stop using a fake default KB password; merge Compose-style env files and
rewrite compose DNS to localhost on the host so go test/E2E authenticate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 02:03:07 +00:00
weichen e694408851 merge: docs/w1-release-integration-slot 2026-09-17 01:48:19 +00:00
weichenandCursor cacbf755b6 docs(ops): release integration slot after W1 merge smoke
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 01:48:19 +00:00
weichen 1d075aa4c3 merge: fix/w1-archtest-app-fav-allowlist 2026-09-17 01:47:52 +00:00
weichenandCursor 86a4c9af63 fix(arch): allowlist app/fav imports for archtest baseline
FAV U7 stub package was missing from module-boundaries imports map,
breaking go test -short smoke after W1 merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 01:47:52 +00:00
weichen 4d6b95dea4 merge: feature/w1-ci-e2e-green-nightly 2026-09-17 01:44:02 +00:00
weichenandCursor 8d3fd089f2 docs(ops): mark W1 step complete on partial-deferred controller
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 01:44:02 +00:00
weichenandCursor 6981223087 docs(test): close W1 CI/E2E with FullNone nightly pass receipt
Archive green receipt 6e2476f0, raise FEATURE-MATRIX CI/E2E to done,
and mark short-term/CURRENT W1 complete.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 01:43:54 +00:00
weichenandCursor 6e2476f0f2 fix(ci): retry nightly suite on MISSING_TARGET flakes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 01:12:37 +00:00
weichenandCursor 11e030db30 fix(squad): stop requiring fields.json as hard PI runner target
Organizer still prompts for fields.json, but missing it must not fail
closed as MISSING_TARGET when output.md is present (FullNone flake).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 00:55:11 +00:00
weichenandCursor 0f52ab89db fix(ci): load real KB password for host-side PI E2E
configs/.env.dev omits KB_DB_PASSWORD so Load kept the default
shared_kb_secret_pass; fall back to root .env so research can use KB.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 00:52:01 +00:00
weichenandCursor a02c67db82 fix(ci): stabilize FullNone PI E2E timeouts and host KB DNS
Raise HTTP client timeout above AgentTimeout, rewrite compose KB host
to localhost for host-side tests, and retry nightly on deadline flakes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 00:28:38 +00:00
weichenandCursor 4f2e5f013f fix(db): remove duplicate goose 00048 software-project-type migration
Two 00048 files made goose panic on CollectMigrations, blocking all
TEST_DATABASE_URL PG suites including FullNone and nightly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 23:37:04 +00:00
weichen 4bda6484a2 merge: docs/partial-deferred-completion-plan 2026-09-16 23:34:16 +00:00
weichenandCursor 251b5f9c3d docs(ops): claim integration slot for docs closeout merge and W1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 23:34:16 +00:00
weichenandCursor c649067d19 docs(remediation): freeze §7 open decisions for partial/deferred closeout
Confirm D7 retention draft ADR, confirm-tier gate, REPLACE default-off,
and FAV live order with observation windows; sync CURRENT and short-term.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 16:13:17 +00:00
weichen bb8d921e7c docs(remediation): add partial/deferred completion plan (W1-W7) and short-term controller 2026-09-16 16:03:50 +00:00
weichenandCursor 83f9004f9e docs(ops): close SWBOOT short-term after remote push
CI / go-vet-and-short-test (push) Failing after 1s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:49:21 +00:00
weichenandCursor 92e0ae7ec4 merge: origin/feature/intent-plan-cards-playwright
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:49:21 +00:00
weichenandCursor 49db87ebe5 docs(ops): release integration slot after agent-delta merge
CI / go-vet-and-short-test (push) Failing after 1s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:48:24 +00:00
weichenandCursor 51c8ec1e8a docs(ops): mark P0–P7 agent-delta merge complete on SSOT
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:48:07 +00:00
weichenandCursor 768729d85e fix(swboot): drop thin allowlist stub after agent SWBOOT merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:57 +00:00
weichenandCursor f0029dffed merge: origin/feature/software-project-bootstrap
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:45 +00:00
weichenandCursor 00cc5b6645 merge: origin/feature/fav-u7-publisher
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:29 +00:00
weichenandCursor 131380e858 merge: origin/feature/pu8-u9-u12-flags
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:23 +00:00
weichenandCursor b92e226497 fix(docgov): drop thin pi_narrative stub after agent PU7 merge
Use ResolveChangeReport from feature/pu7-pi-narrative.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:16 +00:00
weichenandCursor a380c218bb merge: origin/feature/pu7-pi-narrative
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:06 +00:00
weichenandCursor f3351ce750 fix(chat): drop thin semantic_shadow stub after agent PU6 merge
Keep applySemanticShadow path from feature/pu6-semantic-summary.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:46:01 +00:00
weichenandCursor f55887e2a2 docs(test): archive intent-plan Playwright dual-tab report
Record RUN_UI_ACCEPTANCE live PASS evidence and close the dual-tab short-term.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:45:50 +00:00
weichenandCursor b74b9ab1d0 test(web): add intent-plan dual-tab Playwright acceptance
Gate on RUN_UI_ACCEPTANCE=1; seed awaiting PG plan via SQL without raising
MULTI_INTENT_PLAN_TIER; assert one confirm wins and reload/relogin match PG.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:45:50 +00:00
weichenandCursor cc8557b8c6 feat(web): hydrate PLAN_CONFIRM from active intent plan
Load GET /intent-plans/active into a live card on session restore, use a
unique decision nonce per confirm click, and keep an empty-docAST fallback
so login still renders when demo seeds are off.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:45:50 +00:00
weichenandCursor 003bc7a5b9 merge: origin/feature/pu6-semantic-summary
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:45:45 +00:00
weichenandCursor 6aea8784c2 docs(test): record nightly run#30 U8 PASS after DATA_DIR rw fix
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 1s
CI / web (push) Failing after 0s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:44:56 +00:00
weichenandCursor 6087d0bdef docs(test): archive PU8 U9–U12 flags scaffolding report
Record default-off flag gates, unit evidence, and FEATURE-MATRIX partial status.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:42:49 +00:00
weichenandCursor 0611b1f24f feat(intentflow): wire U9–U12 ports and gated OwnerMux
Register dry-run adapters via BuildOwnerMux when independent flags are on;
U9 stub fail-closes on malformed/timeout/out-of-bounds without raising PlanTier.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:42:49 +00:00
weichenandCursor d860c6430e docs(ops): close full-backlog override checklist P1–P7
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:41:30 +00:00
weichenandCursor b015f8723f fix(docgov): keep invalid ReportJSON path when narrative flag off
Preserve prior ValidateChangeReportJSON error semantics.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:41:30 +00:00
weichenandCursor 2b3302ece4 feat(workflow-design): SWBOOT ADR, project_type migration, patch deny stub
SWBOOT-10 remains stub-only pending secondary approval.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:56 +00:00
weichen f1d8f49df7 merge: feature/fav-u7-publisher-impl 2026-09-16 15:40:56 +00:00
weichen 0409e399d8 merge: feature/intent-plan-cards-playwright-impl 2026-09-16 15:40:56 +00:00
weichen 975af54fd6 merge: feature/pu8-u9-u12-flags-impl 2026-09-16 15:40:56 +00:00
weichen 5596ead7fd merge: feature/pu7-pi-narrative-impl 2026-09-16 15:40:55 +00:00
weichen 7583f109a1 merge: feature/pu6-semantic-summary-impl 2026-09-16 15:40:55 +00:00
weichenandCursor 6356fb5a8c docs(ops): mark FAV U7 incremental push complete
Feature branch pushed; still not merged to dev; fav subscriber remains OFF.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:38 +00:00
weichenandCursor 1cd1cddf64 feat(intent-plan): independent PU8 U9–U12 flags default off
Dry-run/fail-closed adapters; does not raise plan tier.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:26 +00:00
weichenandCursor 47376aeb84 feat(events): FAV publisher cmd stub gated off by default
Incremental U7; degraded read still approval-gated.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:26 +00:00
weichenandCursor d45a1eef75 test(web): intent-plan dual-tab Playwright acceptance gate
RUN_UI_ACCEPTANCE=1 required; no tier upgrade.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:26 +00:00
weichenandCursor e7e981356c feat(docgov): PI_CHANGE_REPORT_NARRATIVE gate with full fallback
Default off; malformed or risk downgrade forces deterministic report.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:25 +00:00
weichenandCursor 8fdf50ab2a feat(chat): SEMANTIC_SUMMARY_SHADOW optional deterministic annotate
Default off; unauthorized views skipped; facts preserved.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:25 +00:00
weichenandCursor de65cee96c docs(test): record FAV U7 incremental go/no-go evidence
Subscriber remains OFF until separate approval; document remaining FAV
port inventory and claim feature/fav-u7-publisher.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:10 +00:00
weichenandCursor 5392238354 chore(compose): pin FAV_DEGRADED_READ and publisher off
Document false defaults in all envs; main hardcodes both flags to false.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:10 +00:00
weichenandCursor 47a173e7bb feat(events): add fav subscriber and artifact-vault CLI stubs
Keep durable fav unregistered and fail-closed; CLI only prints status and
remaining-port inventory without destructive backfill/recover commands.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:10 +00:00
weichenandCursor 92d7a3d117 feat(api): add FAV vault status stub with gated publisher
Expose GET /api/v1/vault/status and only wire in-process Drain when
FAV_PUBLISHER_ENABLED is explicitly true; degraded read stays off by default.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:10 +00:00
weichenandCursor 3478a5a05a feat(config): add FAV vault flags defaulting off
Gate FAV_DEGRADED_READ and FAV_PUBLISHER_ENABLED behind explicit opt-in,
and refuse VAULT_STATE_ROOT colliding with runtime data/{env}.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:40:10 +00:00
weichenandCursor 56f6a66f2e docs(test): archive PU7 PI narrative acceptance report
Record flag-off and full-fallback evidence; sync CURRENT, matrix, and contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:39:54 +00:00
weichenandCursor 51568ea080 feat(web): distinguish change-report narrative vs factual fields
Panel and view-model label server risk/lineage separately from PI narrative;
add change_report_narrative_v1 helper aligned with typed-result patterns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:39:54 +00:00
weichenandCursor 18f2729472 feat(docrevision): add PI change-report narrative with flag-gated fallback
Introduce PI_CHANGE_REPORT_NARRATIVE (default off). When on, consume typed
narrative bound to input digest only; malformed/timeout paths fully fall back
without mixing fields or lowering server risk.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:39:54 +00:00
weichenandCursor 5493bf6108 docs(test): archive PU6 shadow report and mark matrix partial
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:37:50 +00:00
weichenandCursor d86528b45b test(chat): characterize semantic summary shadow and auth negatives
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:37:50 +00:00
weichenandCursor b7b880a316 feat(chatflow): authorize rolling summary and surface digest freshness
GenerateRollingSummary filters to authorized-visible messages; digest API
exposes shadow/freshness without enabling REPLACE.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:37:50 +00:00
weichenandCursor 209c997b22 feat(ctxmgr): add SEMANTIC_SUMMARY_SHADOW with deterministic fallback
Shadow evaluates a no-tool summarizer on caller-supplied messages; served
narrative stays deterministic and REPLACE remains unwired.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:37:50 +00:00
weichenandCursor 884e5dbf44 docs(ops): claim PU6 semantic summary shadow on chat mutex
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:37:50 +00:00
weichen b67816a898 merge: sync detailed matrix deep-test report onto test 2026-09-16 05:37:16 +00:00
weichen 56eb0ed4fe merge: sync matrix deep-test closeout docs onto test 2026-09-16 05:25:31 +00:00
weichen 8c9a12d996 release-candidate: 汇集 dev 功能至 test 分支,准备长期实测 [Tag: rc-v1.0.0-beta.2] 2026-09-16 05:19:59 +00:00
weichen dd30e061d8 merge: sync test promotion notes from local dev 2026-09-15 16:04:59 +00:00
weichen 2e826e7f58 merge: promote local dev to test for Phase 2 actual testing 2026-09-15 16:02:46 +00:00
907 changed files with 65825 additions and 7531 deletions
@@ -2,7 +2,7 @@
## 状态
提议(2026-09-14;架构与实施计划已修订,等待用户确认后进入首个实现里程碑)
已接受(2026-09-14 提议;2026-09-18 确认——Phase 1 纵向绞杀与 Phase 2 持久事件交付已落地并验收,见 gap-matrix `DOC-RELIABILITY-PILOT` PASS、[Phase 1 计划](../remediation/2026-09-14-module-decoupling-refactor-plan.md)、[Phase 2 修订计划](../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md)、[Track E 复盘](../ops/research/2026-09-15-track-e-retrospective.md))
## 背景
@@ -0,0 +1,63 @@
---
title: "D7 对话数据留存与删除口径(草案)"
status: proposed
created: 2026-09-17
updated: 2026-09-17
compliance: pending-compliance-signoff
owner: Cline
related:
- ../remediation/2026-09-16-partial-deferred-completion-plan.md
- ../ops/short-term/2026-09-16-partial-deferred-completion.md
- ../status/FEATURE-MATRIX.md
---
# ADR:D7 对话数据留存与删除口径
## 状态
**提议 / 工程草案**(2026-09-17)。数字与删除口径标 `pending-compliance-signoff`:合规签字或改数前,W7 仅允许数据分类盘点与现状审计,不得按未签字数字执行物理删除或备份清除。接受后状态改为 `accepted`。
## 背景
FEATURE-MATRIX「对话数据治理(D7)」为 `deferred`。收口计划 W7 要求:数据分类盘点 → 留存/删除口径落 ADR → 库/备份/日志控制 → 敏感字段加密边界。工程不能单方面定合规数字,但必须提供可审草案,避免无限期停在 deferred。Track E / R13 / R18 / R22 已对日志脱敏与销毁门禁有硬约束,本 ADR 将其固化为 D7 口径。
## 决策(建议默认;待合规确认)
### 1. 数据分类与留存
| 数据类 | 留存 | 说明 |
|--------|------|------|
| 会话正文(chat sessions/messages) | 热库 **365 天**(可配置) | 超期 soft-delete → 观察窗 → 物理清理 |
| 派生文档 / 私密文档 | 与聊天**独立周期**;回收站 **30 天**后物理清理 | 删除 UI 须说明影响范围(只删聊天 / 只删文档 / 两者) |
| 审计元数据(导出/治理审计) | **180 天** | 不可被普通用户删除覆盖 |
| Agent trace / workspace 非终态 | 任务结束后 **30 天**;nightly 仅合成数据 | 禁止当长期事实源 |
| 日志 / dead-letter / reconciliation | 不按正文留存;**只存 ID、digest、typed error code、allowlist 摘要** | Track E 红线 |
| FAV 终态制品 | `retention_class` + legal hold + delete ledger | 与聊天口径解耦 |
### 2. 删除路径
1. **用户删除**:soft-delete / tombstone → 观察窗 → 物理清理。
2. **备份清除**:须二次批准 + 精确 delete manifest;对齐销毁门禁 R22(完整备份恢复演练、migration corpus、FAV coverage、manifest、用户批准)。
3. **删除界面**:必须说明聊天源消息与派生文档的独立保留周期及本次操作影响范围。
### 3. 加密边界(首期)
- 首期范围:敏感字段**盘点** + 传输与备份访问控制。
- **不默认**上字段级加密;选型待合规确认与威胁模型后再立实现任务。
### 4. 违规升级
盘点确认当前基线违反已确认的安全或合规要求 → **立即**写入 [`gap-matrix.md`](../remediation/gap-matrix.md),不得继续当普通 backlog;本行 `done` 让位于整改。
## 后果
- W7 可按本草案启动盘点;物理删除与备份清除在 `pending-compliance-signoff` 解除前禁止按建议数字自动执行。
- 2026-09-17 只读盘点:[../audit/2026-09-17-d7-data-inventory.md](../audit/2026-09-17-d7-data-inventory.md)(未删数据、未升矩阵 done、未写 gap-matrix blocker)。
- 日志/DLQ/reconciliation 实现与审计须持续满足 Track E ID-only 红线。
- 合规改数后:更新本 ADR 数字表、`updated` 日期,并将 `compliance` 改为 `signed` / `accepted`;再开 W7 整改实现。
## 相关链接
- 收口计划 §7.1:[../remediation/2026-09-16-partial-deferred-completion-plan.md](../remediation/2026-09-16-partial-deferred-completion-plan.md)
- FEATURE-MATRIX D7 行:[../status/FEATURE-MATRIX.md](../status/FEATURE-MATRIX.md)
- Track E Phase 2:[../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md](../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md)
@@ -0,0 +1,609 @@
---
title: "个人工程中控台:实时项目看板与离线 HTML 快照"
type: feat
date: 2026-09-17
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
---
> **已废弃(2026-09-17;2026-09-19 更新)**:旧版只读工程中控台代码已移除。后来短暂合入的 Control Center 也已移出本仓库,进度管理由独立项目承担。本文仅作历史证据保留。
# 个人工程中控台:实时项目看板与离线 HTML 快照
## Goal Capsule
为仓库所有者提供一个独立于产品后台的本地只读中控台。打开一个页面即可判断当前系统由什么组成、哪些任务正在计划或实施、真实分支和 worktree 在哪里、各环境实际运行了什么,并能在两次点击内到达对应的设计、审计、整改、任务和测试材料。
中控台同时提供两种输出:
1. `serve`:持续采集本地仓库、Git 和运行环境,提供自动刷新的 HTML 页面与机器可读 JSON;
2. `export`:基于同一份不可变快照生成单文件 HTML,便于归档、离线查看和交接。
这不是产品功能,不接入产品后台、产品数据库或产品权限体系;它也不是发布系统,不执行 Git、Docker、部署或文档写操作。
### 成功标准
- 在当前仓库规模下,首次可用页面目标为 2 秒内出现;慢数据源可随后标记为 `degraded`,不得拖垮整页。
- 正常情况下,本地文件、Git 或运行态变化在 5 秒内反映到新快照。
- 页面分别展示“文档声明、Git 实施、验证证据、环境实装”,不把任务文档的 `done` 翻译为已合并或已部署。
- 每个关键结论均显示来源、采集时间、新鲜度和可信类型;冲突保留双方证据,不静默选边。
- 在线模式检索 allowlist 内未截断的 Markdown 正文;离线导出同时给出 included、truncated 和 metadata-only 清单,二进制附件只索引路径、类型、大小和归属。
- 单文件 HTML 默认权限为 `0600`,可脱离仓库阅读已纳入 inclusion manifest 的 Markdown 正文,并醒目标出截断或仅元数据条目;不打包 `.doc/**/assets`。
- 任一采集源失败时仍可查看最近成功数据,并明确显示 `stale/error/last_success_at`。
---
## Product Contract
### 用户与使用场景
唯一主要用户是仓库所有者。典型使用包括:
- 每天开始工作时查看焦点任务、阻塞、集成槽和环境异常;
- 从模块进入设计、任务、测试和部署证据链;
- 判断某项工作究竟只是有计划、正在实现、已经验证,还是已在某环境实装;
- 查看本地分支、远端跟踪引用、ahead/behind、worktree 和未提交变更;
- 发现 `CURRENT`、功能矩阵、发布门禁、Git 与 Docker 之间的漂移;
- 导出一个自包含 HTML,作为某一时点的项目快照。
### 已确定的产品决策
#### PKD-1:独立本地工具
采用独立 Go CLI 和本地 Web 页面,不加入现有产品后台。
(session-settled: user-approved — chosen over product-admin integration: the console is for the repository owner’s local engineering management and the production image excludes `.doc` and `.git`)
#### PKD-2:只读实时页与离线快照共用数据模型
实时服务和导出文件必须由同一份版本化快照生成,避免在线页面与离线报告出现两套口径。
(session-settled: user-approved — chosen over a static-only report: the requested console must follow agent tasks and project state as they change)
### 核心需求
| ID | 需求 |
|---|---|
| R1 | CLI 默认解析当前 Git 仓库根,也接受显式 `--repo`;页面始终显示绝对根路径、当前分支、HEAD 和采集时间。 |
| R2 | 仅监听 `127.0.0.1`,不依赖产品容器、产品数据库或产品登录。 |
| R3 | 架构与模块页聚合 `module-boundaries.yaml`、系统设计索引和 `FEATURE-MATRIX`,展示模块、能力、依赖和证据链。 |
| R4 | 任务状态至少拆为 `doc_status`、Git facets、`verification_result`/`verification_freshness`、deployment facets;可并存事实不得压成单值枚举。 |
| R5 | Git 页展示本地/跟踪分支、ahead/behind、最近提交、worktree、dirty/untracked 和任务声明匹配情况;不得隐式 `fetch`。 |
| R6 | 部署页按 shared/dev/test/main 分别展示容器状态、应用 readiness、服务完整性、schema、镜像与 promotion receipt;不得计算未经定义的综合绿灯。 |
| R7 | 文档页支持按 taxonomy、状态、模块和关键词筛选,展示正文、正向链接、反向链接、broken、orphan 与 unindexed 状态;查询状态可通过 URL 恢复。 |
| R8 | 一个不可变快照包含 `schema_version`、`generation_id`、`revision_id`、`generated_at`、仓库/提交身份、来源状态、事实与冲突。 |
| R9 | 自动刷新采用完整快照原子切换;每个来源独立超时,失败时保留最近成功数据并标注过期。 |
| R10 | 每条关键事实标注 `declared`、`observed`、`verified` 或 `inferred`,并保留来源路径和采集时间。 |
| R11 | 单 HTML 内嵌结构化模型、页面资源和允许导出的 Markdown 正文;附件只保留元数据及相对链接,并显示内容覆盖清单。 |
| R12 | 对 Agent 暴露稳定的只读 JSON,而不是让 Agent 解析 HTML;JSON 与页面引用同一 `generation_id` 和 `revision_id`。 |
| R13 | TaskState 显示声明的 owner/Agent 类型/认领/mutex 与基于 Git 的最近活动证据;Herdr 工程 Agent 和产品 PI Agent Runner 使用不同类型。没有运行态来源时必须显示 unknown,不得把“已认领”写成“正在执行”。 |
| R14 | 文件、命令和 HTTP 均采用 allowlist;拒绝路径穿越、symlink 越界、原始 HTML 执行、远程资源加载和凭证读取。 |
### 事实源与权威边界
| 领域 | 权威来源 | 中控台处理方式 |
|---|---|---|
| 发布门禁 | `.doc/remediation/gap-matrix.md` | 只解释发布 blocker,不替代能力完成度。 |
| 能力成熟度 | `.doc/status/FEATURE-MATRIX.md` | 显示功能完成度,不据此推断是否部署。 |
| 当前焦点、认领、集成槽 | `.doc/ops/CURRENT.md` | 作为团队声明,与 Git 和运行态对账。 |
| 任务计划 | `ops/short-term`、`ops/long-term`、backlog front matter | 作为计划状态,不据此推断实现。 |
| 分支与 worktree | Git plumbing | 作为本地观测;远端状态注明“基于本地 refs,未联网刷新”。 |
| 环境运行态 | Docker/Compose 元数据与 `/ready` | 分开展示容器、应用与服务完整性。 |
| 验收证据 | `.doc/test-reports` 及 promotion receipts | 显示证据存在性与身份,不以文件名替代内容校验。 |
来源之间不设全局覆盖顺序。各来源回答自己的问题;值不一致时生成 drift,并并列展示原值、时间和来源。
### 用户流程
```mermaid
flowchart LR
Start[启动 serve 或 export] --> Root[解析显式 repo root]
Root --> Collect[并行采集文档 Git 运行态]
Collect --> Snapshot[构建不可变快照]
Snapshot --> Reconcile[按领域对账]
Reconcile --> Live[本地实时页面和 JSON]
Reconcile --> Export[单文件 HTML]
Live --> Refresh[定时生成下一快照]
Refresh --> Snapshot
```
总览默认优先显示 `in_progress`、`blocked`、`planned`、`partial/deferred`、drift 和 degraded。`done` 与 archive 默认收起,避免历史材料淹没当前工作。
任务详情按照以下证据链导航:
```mermaid
flowchart LR
Audit[audit 问题] --> Remediation[remediation 方案]
Remediation --> Task[任务声明]
Task --> Git[分支 worktree commit merge]
Git --> Test[测试与验收报告]
Test --> Deploy[环境 artifact 与 readiness]
```
显式 Markdown 链接和既定 taxonomy 属于强关系;仅由文件名或 slug 推断的关系标为“候选”,不得参与完成度计算。
### 状态模型
```mermaid
flowchart TB
D[doc_status: planned/in_progress/blocked/done] --> View[并列状态视图]
G[Git facets: branch/worktree/merge/cleanliness/ahead-behind] --> View
V[Verification: result + freshness + bound identity] --> View
P[Deployment facets: container/readiness/services/artifact identity] --> View
View --> Drift{来源是否一致}
Drift -->|是| Consistent[consistent]
Drift -->|否| Conflict[drift + 双方证据]
```
“实装”定义为存在可核对的环境观测证据,而不是任务文档为 `done`。容器可达但 artifact identity 无法核对时显示“运行可见、版本未验证”,不得提升为 verified deployment。当文档声明 healthy、Docker 显示异常而 `/ready` 为 ok 时,页面保留多值并标记 drift,不输出统一绿灯。
### 真实验收样本
1. rdev:存在调研、设计、任务与 backlog,但若没有 CURRENT 认领和真实分支,应显示“已计划、未认领、未实施、未实装”。
2. main 环境:若 CURRENT 声明整体 healthy,而 events 容器实际 restarting、应用 `/ready` 仍为 ok,应同时显示三项证据与 drift。
3. 本地 dev:若分支领先 `origin/dev`,必须显示“本地已具备、远端未确认可用”,不得写成已远程发布。
4. `system-admin-console`:作为产品管理后台能力,与本计划的个人工程中控台分开展示,名称和边界不得混淆。
### 安全与非目标
一期明确不做:
- 不写文档,不修改任务状态,不占用集成槽;
- 不创建、切换、合并、删除或推送 Git 分支;
- 不执行 `git fetch`,不调用远端托管平台 API;
- 不启动、停止、重建或部署容器;
- 不控制 Herdr 或向 Agent 派发任务;
- 不读取 `.env`、`.secrets`、Docker `Config.Env`、数据库数据或 `.git` 内部文件正文;
- 不加入产品 API、产品前端、产品数据库或生产镜像;
- 不执行 Markdown 原始 HTML、脚本、Mermaid 或远程资源。
后续候选包括跨快照历史、远端 CI/Gitea 聚合、受限 Markdown/Mermaid 渲染、Agent 查询 API 和修复建议。任何写操作继续保持在本工具之外。
---
## Planning Contract
### High-Level Technical Design
以下图示冻结边界和协议,不规定具体函数签名。
```mermaid
flowchart LR
Docs[.doc sources] --> DC[Document collector]
Git[Git/worktrees] --> GC[Git collector]
Run[Docker/ready/receipts] --> RC[Runtime collector]
DC --> Build[Snapshot builder]
GC --> Build
RC --> Build
Build --> Rec[Reconcile facts and conflicts]
Rec --> JSON[Read-only JSON]
Rec --> Web[Local HTML]
Rec --> File[Offline HTML]
```
```mermaid
sequenceDiagram
participant UI as Browser
participant C as Collection coordinator
participant S as Sources
participant P as Snapshot publisher
UI->>C: poll with revision_id
C-->>UI: current snapshot immediately
C->>S: singleflight collection with deadlines
S-->>C: facts or source error
C->>P: publish complete generation atomically
P-->>UI: new revision or not-modified
```
```mermaid
stateDiagram-v2
[*] --> Loading
Loading --> Fresh: first collection succeeds
Loading --> ErrorUnknown: first collection fails
Fresh --> Refreshing: TTL expires
Refreshing --> Fresh: new generation succeeds
Refreshing --> Stale: source fails and last-known exists
Stale --> Fresh: source recovers
ErrorUnknown --> Fresh: source first succeeds
```
### 技术决策
#### KTD-1:采用仓库内独立 Go CLI
新增 `cmd/engineering-dashboard` 与 `internal/engineeringdashboard`,复用仓库 Go 工具链但不导入产品业务包。Go 标准库足以提供本地 HTTP、资源嵌入、JSON、并发和原子文件输出;现有 `yaml.v3` 可用于已定义的 YAML 契约。
#### KTD-2:快照是唯一交付模型
采集器只生产事实,reconcile 层只生产派生状态和冲突,HTTP/API/export 只消费已完成的不可变快照。快照至少包含:
```text
schema_version, generation_id, revision_id, generated_at, collection_duration
repository { root, branch, head, dirty }
sources[] { name, status, observed_at, last_success_at, error }
facts[] { subject, field, value, provenance, source_ref, observed_at, confidence }
conflicts[] { subject, field, kind, fact_refs[] }
documents[], modules[], tasks[], git[], environments[]
```
`generation_id` 唯一标识一次采集,包含采集批次语义;`revision_id` 只由 schema、仓库身份和规范化的非易变事实、冲突、来源状态确定,明确排除 `generated_at`、`observed_at` 和采集耗时。HTML 与 JSON 必须展示同一对标识,HTTP ETag 和前端是否重绘使用 `revision_id`。一期不读取旧 schema 的外部 JSON;离线 HTML 自带对应 renderer,因此不依赖未来二进制迁移。
#### KTD-3:专用解析器与容错索引并存
对 CURRENT、FEATURE-MATRIX、gap-matrix、任务 front matter 和 module boundaries 编写契约化解析器。文档层只索引 promotion receipt 的路径与链接,结构化部署凭证由运行态采集器唯一负责。对其余 Markdown 只提取安全元数据、标题、正文与链接。专用解析器失败时保留原文入口并标记 degraded,不凭模糊规则编造状态。
#### KTD-4:命令执行采用固定 argv 和超时
Git 与 Docker 采集通过注入式 command runner 执行固定程序和分离 argv,不通过 shell 拼接。`--repo` 先转为绝对、symlink-resolved 的 Git 根并作为单个参数传递。每个来源默认 2 秒超时;错误输出做长度限制和敏感字段清理。Git 使用 porcelain/plumbing 输出,例如 `status --porcelain=v2`、`worktree list --porcelain`、`for-each-ref`、`rev-list`、`merge-base`。
#### KTD-5:一期采用短轮询,不引入持久数据库
服务端由单一采集协调器按 TTL 触发完整重采集,2–5 秒刷新;同一仓库最多一轮采集在途,请求只读取当前快照,不直接叠加扫描。每轮带单调 generation 序号和整轮 deadline,只有当前有效轮次能原子发布。页面使用 ETag/`revision_id` 避免重复传输。last-known 只在同一 `serve` 进程内有效;冷启动或单次 export 首次采集失败时显示 unknown/error,不伪造历史值。文件监听、SSE 通知、持久缓存和历史数据库均后置。
#### KTD-6:安全阅读优先于富渲染
在线详情页一期将 Markdown 全部作为纯文本安全转义,并保留换行和空白;标题、列表、链接、代码、图片和 Mermaid 均显示源码,不生成 HTML 节点或发起资源请求。静态导出内嵌同一正文和内部导航。所有文档 ID 都是规范化仓库相对路径,只允许 `.doc/**/*.md` 及明确列入 allowlist 的根 Markdown;读取前后都校验解析路径,直接拒绝 symlink,并对 `.git`、`.env*`、`.secrets`、`data` 等敏感路径执行最终目标 denylist。
#### KTD-7:导出为自包含、有限尺寸的证据快照
导出将模型、CSS、JS 和允许的 Markdown 正文写入单 HTML,采用临时文件加 rename 原子落盘,默认 `0600`。数据使用 HTML-safe JSON 或等价编码封装,正文只通过 `textContent`/DOM API 写入;CSP 禁止网络、外部资源和内联事件执行。默认只嵌入 Git tracked、allowlist 内的 Markdown;untracked Markdown 只列元数据,除非用户显式选择。导出前输出 inclusion manifest 与敏感模式告警;`.doc/**/assets`、数据库、构建产物和二进制报告不嵌入。
### 建议目录
```text
cmd/engineering-dashboard/
main.go
internal/engineeringdashboard/
model.go
collector.go
source_docs.go
source_git.go
source_runtime.go
reconcile.go
server.go
export.go
assets/
index.html
app.js
app.css
testdata/
docs/
git/
runtime/
scripts/
engineering-dashboard.sh
.doc/test-reports/
YYYY-MM-DD-engineering-dashboard-test-report.md
```
### 风险与缓解
| 风险 | 缓解 |
|---|---|
| 文档结构并不完全统一 | 只对 SSOT 和任务 front matter 使用严格契约;其余文档容错索引并暴露解析告警。 |
| 看板制造“假完成” | 多轴 facets、事实 provenance、验证身份绑定、冲突不覆盖、真实反例测试。 |
| Docker/Git 卡住或不可用 | 独立超时、并行采集、last-known 状态、degraded 页面。 |
| 文档 XSS 或路径穿越 | 纯文本渲染、HTML-safe 数据封装、CSP、路径 allowlist、拒绝 symlink、最终目标敏感路径 denylist。 |
| `.doc` 附件导致扫描/导出失控 | 默认跳过 assets 内容,只采集元数据;设置单文档和总正文上限并报告截断。 |
| 导出副本离开本机后 `0600` 不再提供保护 | 页面首部标明敏感快照、仓库身份和生成时间;输出 inclusion manifest,交接者自行控制接收者、保留期与删除。 |
| worktree 与主 checkout 混淆 | 只管理 `--repo` 指定/解析出的根,页面常驻显示根与 HEAD;其他 worktree 仅作为 Git 元数据。 |
| 本地 remote refs 被误认为远端实时状态 | 显示 refs 观测时间和“未联网刷新”,不自动 fetch。 |
| 与产品 `system-admin-console` 命名冲突 | CLI、包和文档统一使用 `engineering-dashboard` / “个人工程中控台”。 |
---
## Implementation Units
### U1:冻结快照、事实与状态契约
**目标**:先建立不会把计划、实现、验证、部署混为一谈的模型与测试夹具。
**覆盖需求**:R4、R8、R10、R12、R13;承接 PKD-2 的同源快照决策。
**依赖**:无。
**文件**:
- `internal/engineeringdashboard/model.go`
- `internal/engineeringdashboard/model_test.go`
- `internal/engineeringdashboard/testdata/**`
**实施要点**:
1. 定义版本化 `Snapshot`、`SourceState`、`Fact`、`Conflict`、`TaskState`、`AgentClaim`、`EnvironmentState`。
2. provenance 固定为 `declared|observed|verified|inferred`;freshness 固定为 `fresh|stale|error|unknown`。
3. 状态使用可组合 facets:Git 分为 branch/worktree/merge/cleanliness/ahead-behind;验证分为 result/freshness/subject identity;部署分为 container/readiness/services/artifact identity。
4. TaskState 保留 owner、agent kind、claim、mutex、声明分支、观测 worktree、最近活动时间及证据;声明与观测不可互相提升。
5. 建立 rdev、dev ahead、main events restarting、CURRENT/worktree 不匹配等夹具。
**测试场景**:
- 文档 `done` 但无 merge/deploy 时,Git 与部署 facets 不改变;
- `claimed` 但无可观测运行信号时,Agent 活动保持 unknown;Herdr 与产品 PI Runner 不共享类型;
- 同字段多来源不一致时生成 conflict 并保留所有 fact 引用;
- JSON round-trip 保留 schema 与 snapshot identity;
- 枚举未知值失败且错误可定位。
**完成证据**:模型测试通过,schema 示例落入 Go fixture,不存在页面专用的第二套状态类型。
### U2:实现文档图谱与领域解析器
**目标**:将 `.doc` taxonomy、模块、任务、测试和链接转换为可追溯文档图谱。
**覆盖需求**:R3、R7、R10、R11、R14。
**依赖**:U1。
**文件**:
- `internal/engineeringdashboard/source_docs.go`
- `internal/engineeringdashboard/docs_test.go`
**实施要点**:
1. 扫描 allowlist 内 Markdown,默认跳过任何 `assets` 目录正文;记录附件元数据。
2. 解析 front matter、标题、显式 Markdown 链接和反向链接。
3. 为 CURRENT、FEATURE-MATRIX、gap-matrix、任务文、module boundaries 和 test report 建立专用适配器;receipt 只在文档图谱中作为文档与链接,结构化解析归 U4。
4. 区分 `broken`、`orphan`、`unindexed`;slug 相似只形成候选关系。
5. 规范化路径并阻止 `..`、绝对路径和任何 symlink;最终目标再次应用扩展名 allowlist 与敏感路径 denylist。
**测试场景**:
- taxonomy 内文档可检索且反向链接正确;
- broken link 不导致整个索引失败;
- front matter 缺失或非标准时产生告警并仍可阅读;
- assets 不读正文,越界 symlink 被拒绝;
- rdev 文档链被发现,但没有被推断为已实现。
**完成证据**:文档索引能从 fixture 生成稳定 JSON,路径安全负例通过。
### U3:实现 Git 与 worktree 采集
**目标**:以只读 Git plumbing 形成可复现的分支、提交和 worktree 观测。
**覆盖需求**:R1、R4、R5、R10、R14。
**依赖**:U1。
**文件**:
- `internal/engineeringdashboard/source_git.go`
- `internal/engineeringdashboard/git_test.go`
**实施要点**:
1. 抽象 command runner,固定 argv、工作目录、超时和输出上限。
2. 收集当前分支/HEAD、dirty/untracked、local/remote-tracking refs、ahead/behind、merge-base 和 worktree。
3. 不执行 fetch;remote tracking ref 始终带本地观测时间与免责声明。
4. 对账任务声明的 branch/worktree,但不因路径名相似而认定一致。
**测试场景**:
- 本地分支领先 origin 时显示 ahead 且不显示“远端可用”;
- worktree 目录名与真实检出分支不一致时生成 drift;
- 命令超时、Git 不存在、非 Git 目录时单源 degraded;
- runner 记录中不存在 shell、fetch、push 或写命令。
**完成证据**:临时 Git 仓库集成测试和 fake runner 单元测试通过。
### U4:实现运行态与部署证据采集
**目标**:按环境独立呈现容器、应用 readiness、服务完整性、schema、镜像和晋升凭证。
**覆盖需求**:R4、R6、R10、R14。
**依赖**:U1。
**文件**:
- `internal/engineeringdashboard/source_runtime.go`
- `internal/engineeringdashboard/runtime_test.go`
**实施要点**:
1. 从仓库内批准的 Compose 静态配置和 allowlist labels 映射环境与服务;无法明确映射时显示 unknown,不用名称猜测。容器 JSON 只提取容器名、image/digest、状态、restart count、health,以及 allowlist 内的 Compose project/service labels;不复制 Env、Mounts、完整 NetworkSettings 或任意 labels。
2. 对 allowlist 中的本地 `/ready` 端点执行短超时、响应大小受限的请求;禁用重定向,或对每一跳重新校验 scheme、解析后 IP、端口和 host。
3. 解析 promotion receipt/candidate image 等仓库证据,保留 artifact identity。
4. 将 container health、app readiness、required-service completeness 分开建模。
**测试场景**:
- app ready 且 events restarting 时同时保留两项状态;
- Docker 不可用或 HTTP 超时时,其他数据源仍可输出;
- receipt 与容器 image 不一致时生成 deployment drift;容器可达但 identity 缺失时标记“运行可见、版本未验证”;
- readiness 重定向到外网或非 allowlist 本地端口时拒绝访问;
- 输出中不存在容器环境变量或凭证。
**完成证据**:fixture 和 fake HTTP/Docker runner 测试通过,main 分叉场景被覆盖。
### U5:实现对账、派生视图与新鲜度
**目标**:把来源事实组合成用户可判断的视图,但不替来源做未经定义的裁决。
**覆盖需求**:R3、R4、R6、R8、R9、R10、R13。
**依赖**:U2、U3、U4。
**文件**:
- `internal/engineeringdashboard/reconcile.go`
- `internal/engineeringdashboard/reconcile_test.go`
**实施要点**:
1. 按领域 SSOT 规则构建 module、task、environment 和 evidence-chain 视图。
2. 实现 conflict 分类:declared-vs-observed、task-vs-git、test-vs-subject、receipt-vs-runtime、stale-source、missing-evidence。
3. 快照构建期间每个来源独立记录 `observed_at`、持续时间和错误;成功后一次性发布。
4. 失败源只可复用同一 serve 进程的 last-known,并标注 stale、age 与 last-success;冷启动无缓存时为 unknown/error。过期数据不隐藏,但按年龄提升告警级别。
5. 测试报告只有在 commit/artifact identity 与当前 subject 对齐时才能派生 pass;身份缺失为 unbound,身份不匹配为 stale/drift。
**测试场景**:
- 三个真实样本得到预期多轴状态;
- 同一组输入顺序变化不改变规范化快照;
- 单源失败不会删除其他源,也不会重写 last-known 的观测时间;冷启动失败没有伪造 last-known;
- 旧测试报告、新 HEAD 与不同 image 不会派生当前验证通过;
- 恢复后 stale 自动清除并产生新 snapshot ID。
**完成证据**:reconcile table tests 覆盖一致、漂移、缺失、过期和恢复。
### U6:实现本地服务、总览与文档导航
**目标**:提供能快速判断异常并下钻证据的本地只读页面和 JSON。
**覆盖需求**:R1、R2、R3、R7–R10、R12–R14;承接 PKD-1 和 PKD-2。
**依赖**:U5。
**文件**:
- `internal/engineeringdashboard/server.go`
- `internal/engineeringdashboard/server_test.go`
- `internal/engineeringdashboard/assets/index.html`
- `internal/engineeringdashboard/assets/app.js`
- `internal/engineeringdashboard/assets/app.css`
- `cmd/engineering-dashboard/main.go`
**实施要点**:
1. `serve --repo <path> --addr 127.0.0.1:<port>`;一期无条件拒绝所有非 loopback 地址,包括通配、IPv6 非 loopback 和显式传入值。
2. 暴露 `/api/v1/snapshot`、`/api/v1/doc/<id>`、`/healthz`;所有接口只读。严格校验 Host/Origin/Fetch Metadata,不信任代理转发头;页面和 API 使用每次启动生成的不可预测访问令牌,降低 DNS rebinding 与跨站读取风险。
3. 页面分为总览、架构/模块、任务、Git、部署、文档和证据链。
4. 自动刷新完整快照,保留当前筛选、滚动位置、焦点和选中文档;ETag 未变化时不重绘。
5. 明确一级视图状态:initial loading、fresh empty、fresh success、partial/degraded with last-known、hard error without cache、refreshing、recovered。刷新中继续展示上一完整快照,直到下一版本原子替换。
6. 搜索覆盖标题、仓库相对路径、front matter 和未截断正文;不同维度用 AND、同一维度多选用 OR,默认先排当前任务和异常证据,再按匹配度与路径稳定排序。筛选、查询和选中文档写入 URL 参数,支持浏览器前进/后退与深链。
7. 桌面优先;窄屏下侧栏变为可关闭抽屉,宽表格保留可横向滚动的语义表头,详情区单列。所有功能可键盘完成,使用 landmark/标题/表格语义,drift/degraded 不只靠颜色表达,自动刷新通过非打断式 live region 报告且不抢焦点。
8. Markdown 正文只进入文本节点;在线页与导出页均设置限制性 CSP,不执行 HTML、脚本、SVG、远程 URL 或事件属性。
**测试场景**:
- 只监听 loopback,方法 allowlist 拒绝写请求;Host/Origin/token、DNS rebinding 和跨 Origin 负例被拒绝;
- HTML 与 JSON 的 generation/revision identity 一致;
- 文档 ID 越界、symlink 越界、未知 ID 返回安全错误;
- degraded source 在总览可见且页面仍可导航;
- 任务状态四轴、drift 和来源时间在浏览器中可见。
- 首次加载、空数据、无缓存错误、刷新、恢复状态可区分;键盘、焦点、语义结构、窄屏和非颜色告警验收通过。
- 搜索组合逻辑、排序、无结果、URL 深链和刷新后的视图保持通过。
**完成证据**:HTTP tests、基本无障碍检查和真实浏览器验收通过。
### U7:实现离线导出、启动脚本与治理文档
**目标**:生成安全、可携带、可追踪的单文件快照,并完成仓库治理接线。
**覆盖需求**:R1、R8、R9、R11、R14;承接 PKD-1 和 PKD-2。
**依赖**:U6。
**文件**:
- `internal/engineeringdashboard/export.go`
- `internal/engineeringdashboard/export_test.go`
- `scripts/engineering-dashboard.sh`
- `.doc/status/FEATURE-MATRIX.md`
- `.doc/ops/CURRENT.md`
- `.doc/test-reports/YYYY-MM-DD-engineering-dashboard-test-report.md`
**实施要点**:
1. `export --repo <path> --output <file>` 构建一次不可变快照并原子写入;首次采集失败的来源显示 unknown/error。
2. 以 HTML-safe JSON/等价编码内嵌允许的 Markdown 正文、索引和页面资源;附件保持元数据与相对链接,所有正文只写入文本节点。
3. 默认权限 `0600`,输出页显示生成时间、repo、HEAD、snapshot ID 和 degraded/drift。
4. 薄脚本只负责定位仓库与调用 Go CLI,不隐藏参数或执行安装/部署副作用。
5. 实施期间按仓库规范更新 CURRENT、FEATURE-MATRIX 和 test report;完成后再迁移任务生命周期状态。
**测试场景**:
- 导出文件脱离仓库后仍能搜索和阅读 Markdown;
- 导出中不含附件字节、绝对凭证路径、env 值或远程请求;`</script>`、事件属性、SVG、危险 URL scheme 和 Unicode 边界载荷不能逃逸数据上下文;
- 默认 tracked/untracked 与敏感模式策略、inclusion manifest 和覆盖清单符合契约;
- 采集部分失败时仍能导出并保留错误;
- 输出中 JSON/HTML snapshot identity 一致,权限符合预期;
- 大文档和总正文上限触发时明确标记截断。
**完成证据**:export tests、离线浏览器验收和治理文档回链完整。
---
## Verification Contract
### 自动验证
实施阶段至少运行:
```bash
go test ./internal/engineeringdashboard/...
go test ./cmd/engineering-dashboard/...
go vet ./...
go test -short ./...
git diff --check
```
涉及共享容器的只读验收也必须遵守 CURRENT 集成槽规则;中控台本身不得为测试启动、停止或重建共享容器。
### 契约验证矩阵
| 领域 | 必须证明 |
|---|---|
| 模型 | 计划、Git facets、验证、部署 facets 互不覆盖;Agent 声明和运行观测分离;所有派生结论可追溯到 facts。 |
| 文档 | taxonomy、全文检索、反链、broken/unindexed、路径安全与 assets 排除。 |
| Git | ahead/behind、worktree、dirty、local refs 新鲜度和无隐式 fetch。 |
| 部署 | container/app/service 三类信号分离,receipt/artifact 身份可核对。 |
| 降级 | 每个源超时、错误、stale、恢复都不会让整页不可用。 |
| 实时 | 变化在目标时间内形成完整新快照,不出现半新半旧卡片。 |
| 导出 | 单文件离线可读、默认 `0600`、不嵌 assets、不产生网络请求。 |
| 安全 | loopback、Host/Origin/startup token、read-only methods、命令 allowlist、路径边界、Docker 字段 allowlist、CSP 与输出脱敏。 |
### 浏览器验收
1. 从总览进入 rdev,确认“计划/实施/验证/实装”四轴与源文档链接均可见。
2. 在仓库外复制导出 HTML,断网打开并全文搜索、阅读至少一份设计与一份测试报告。
3. 制造 fixture 中的 CURRENT/Docker/readiness 冲突,确认页面保留多值且不出现综合绿灯。
4. 切换 fixture 快照,确认页面刷新后筛选条件和当前文档保持不变。
5. 尝试路径穿越、未知文档、POST、DNS rebinding、跨 Origin、readiness 重定向和含原始 HTML/脚本逃逸载荷的 Markdown,确认均不能越界、外联或执行。
### 性能与容量验证
- 记录当前 `.doc` 规模下的冷启动、增量刷新、JSON 大小和 HTML 导出大小。
- 建议一期门槛:UI shell 与来源状态在 2 秒内可交互,P95 完整快照重建不超过 5 秒,单源超时不超过 2 秒;基线不达标时必须记录实测并拆分后台正文索引,不能伪造 PASS。
- 导出达到配置上限时必须显式列出被截断文档,不允许静默丢失。
---
## Definition of Done
- [ ] `serve` 和 `export` 在显式仓库根下可重复运行,且没有产品后台依赖。
- [ ] 实时 HTML、离线 HTML 与 JSON 使用同一版本化快照契约。
- [ ] `generation_id` 标识采集实例,`revision_id` 标识内容版本并驱动 ETag;无内容变化不会触发重绘。
- [ ] 架构、模块、功能、任务、Git、部署、文档和证据链均可从页面访问。
- [ ] 计划、实施、验证、实装四轴独立,rdev、dev ahead、main events 分叉样本通过。
- [ ] Agent 认领与可观测活动分开,Herdr 工程 Agent 与产品 PI Agent Runner 不混称。
- [ ] 所有 drift、degraded、stale 都带来源和时间,不存在未经定义的综合绿灯。
- [ ] 默认 loopback、Host/Origin/startup token、只读命令、路径边界、脱敏、CSP 和 Markdown 安全测试通过。
- [ ] 首次加载、空数据、部分失败、无缓存失败、恢复、键盘、窄屏和 URL 深链验收通过。
- [ ] 导出 HTML 脱离仓库可读 Markdown,且不包含二进制 assets 或凭证数据。
- [ ] 单元、集成、全仓短测、浏览器验收和 `git diff --check` 均有真实输出。
- [ ] `.doc/test-reports` 报告回链任务文,FEATURE-MATRIX 与 CURRENT 按实际状态更新。
- [ ] 没有遗留调试入口、写操作按钮、未使用的替代模型或与产品后台重名的组件。
---
## Appendix
### 一期交付边界
一期交付:本地只读服务、版本化快照 JSON、架构/任务/Git/部署/文档视图、四轴状态、drift/degraded、全文搜索、安全文档阅读和单 HTML 导出。
后续评估:跨快照历史趋势、远端托管/CI 聚合、受限富文本与 Mermaid、跨仓库聚合、面向 Agent 的筛选查询 API。
永久排除:在页面中修改文档、切换或推送分支、控制 Agent、执行部署、读取密钥、成为产品后台模块。
### 方案依据
- `.doc/README.md` 定义的文档 taxonomy 与生命周期;
- `.doc/ops/CURRENT.md` 的焦点、认领、集成槽与环境声明;
- `.doc/status/FEATURE-MATRIX.md` 的模块完成度口径;
- `.doc/remediation/gap-matrix.md` 的发布门禁口径;
- `.doc/system-design/README.md` 与模块边界清单;
- Git/worktree、Docker/Compose、`/ready` 和 promotion receipts 的当前可观测能力。
@@ -0,0 +1,55 @@
---
title: "PU6 语义摘要 shadow(SEMANTIC_SUMMARY_SHADOW)"
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor-Auto
branch: feature/pu6-semantic-summary
worktree: ".worktrees/feature-pu6-semantic-summary"
mutex: chat
---
# PU6 语义摘要 shadow
## 目标
在授权可见消息集合上落地 `SEMANTIC_SUMMARY_SHADOW`(默认 off):shadow 语义摘要、失败回 deterministic 并标注 freshness;不启用 REPLACE。
## 范围
- `internal/ctxmgr/summarizer.go` + semantic shadow
- `internal/app/chatflow/` 授权过滤入口
- `internal/server/chat_digest_api.go` 出站 freshness/shadow 字段
- 单元/表征测试;测试报告
## 非目标
- 不启用 `SEMANTIC_SUMMARY_REPLACE`
- 不合入 `dev`
- 不改 plan 文件
## 步骤
1. [x] 从 `dev` 开分支 / worktree 并认领
2. [x] flags + 无工具语义摘要器 + rolling summary shadow
3. [x] chatflow 授权路径 + digest API
4. [x] 测试与报告
5. [x] 渐进提交并 push
## 验收标准
- [x] flag off 行为与基线一致
- [x] shadow on:仅 authorized 消息;失败保留 deterministic + freshness
- [x] injection 不能提权;REPLACE 路径未接线
- [x] 测试报告归档
## 相关链接
- Contract: `../long-term/2026-09-16-pu6-semantic-summary-contract.md`
- Test report: `../../test-reports/2026-09-16-pu6-semantic-summary-test-report.md`
## 证据 / 备注
- 分支:`feature/pu6-semantic-summary`(worktree)
- 测试:`go test -short ./internal/ctxmgr/ ./internal/app/chatflow/ ./internal/server/` PASS
@@ -0,0 +1,48 @@
---
title: "P5 PU8 U9–U12 独立 flag 脚手架"
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor
branch: feature/pu8-u9-u12-flags
worktree: /tmp/wt-pu8
mutex: intent-plan
---
# P5 PU8 U9–U12 独立 flag 脚手架
## 目标
为多意图扩面 U9–U12 落地独立 env flag(默认 OFF)与 stub/dry-run 端口,不升 `MULTI_INTENT_PLAN_TIER`。
## 范围
- `MULTI_INTENT_U9_SEGMENT` / `U10_MUTATE` / `U11_DOCGOV` / `U12_RUN_CONTROL`
- U9 segment proposal port + fail-closed stub
- U10–U12 dry-run adapters + `BuildOwnerMux` 门控
- 单测证明默认 off 与 enable 路径不 panic
## 非目标
- 真实 LLM 分段 / 升 tier / 合入 `dev`
- 真实 docgov/workflow 副作用写路径
## 步骤
1. [x] 独立 flags + `.env.example`
2. [x] segment proposal + expansion adapters + mux 门控
3. [x] Assemble `BuildOwnerMux` 接线
4. [x] 单测 + 测试报告
5. [x] push(不合 `dev`)
## 验收标准
- [x] 四 flag 默认 off;开 flag 不升 PlanTier
- [x] flag off ≡ legacy(无 LLM proposal、无新 adapters)
- [x] flag on:U9 fail-closed;U10–U12 dry-run/guarded
- [x] 报告归档
## 相关链接
- Contracts: [u9](../long-term/2026-09-16-pu8-u9-segment-proposal-contract.md) … [u12](../long-term/2026-09-16-pu8-u12-workflow-run-control-contract.md)
- Test report: [../../test-reports/2026-09-16-pu8-u9-u12-flags-test-report.md](../../test-reports/2026-09-16-pu8-u9-u12-flags-test-report.md)
@@ -0,0 +1,48 @@
---
title: "docgov 变更提案 HTTP + 前端接线"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/docgov-modification-proposal-http
worktree: .worktrees/feature-docgov-modification-proposal-http
mutex: docgov
---
# docgov 变更提案 HTTP + 前端接线
## 目标
暴露 `POST /api/v1/docgov/proposal`,前端「修改」快捷分支与 `ProposalConfirmCard` 走真实 propose/decide,不再本地假装成功。
## 范围
- API:`ProposeModification` 路由;decide 补 404/403 映射
- 前端:`docgov.ts` + `App.tsx` 接线
- 单测 + 真实 HTTP 证据
- 关闭 audit 缺口;dev 试点总开关证据归档
## 非目标
- 晋升 test/main
- 变更提案自动改写受控正文(批准后仍为 UI 演示增补)
## 步骤
1. [x] 实现 propose handler + 路由
2. [x] 前端 client + App 接线
3. [x] handler/client 单测
4. [x] 合入 dev + rebuild + 真实 HTTP
5. [x] push origin/dev;清理 author-only worktree
## 验收标准
- [x] `POST /api/v1/docgov/proposal` 可写库(单测)
- [x] 真实 HTTP claim → propose → decide PASS
- [x] audit 缺口 resolved;CURRENT 认领收敛
## 相关链接
- Audit: [../../audit/2026-09-17-docgov-modification-proposal-http-gap.md](../../audit/2026-09-17-docgov-modification-proposal-http-gap.md)
- Pilot: [../../test-reports/assets/2026-09-17-author-only-pilot/](../../test-reports/assets/2026-09-17-author-only-pilot/)
- Closeout: [../handoffs/2026-09-17-document-author-only-closeout.md](../handoffs/2026-09-17-document-author-only-closeout.md)
@@ -0,0 +1,53 @@
---
title: "修复 CreateOrGetDocument 可选职责 0→NULL FK"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: fix/docgov-optional-duty-null-fk
worktree: "-"
mutex: docgov
---
# 修复 CreateOrGetDocument 可选职责 0→NULL FK
## 目标
无 reviewer/approver 职责时创建文档账本成功,不再因 `reviewer_id=0` FK 失败并被标成 `INTERNAL_ERROR`。
## 范围
- `internal/docgov/engine.go`:`nullIfZero` 写入 author/reviewer/approver
- `internal/stream/classify.go`:`DOC_LEDGER_ERROR` 分型
- 回归测试 + audit/test-report
## 非目标
- 不强制项目配置 reviewer
- 不改前端 flushSync / 虚拟列表
- 不改项目 6417 存量数据(代码修好后重试即可)
## 步骤
1. [x] CreateOrGetDocument 0→NULL
2. [x] ClassifyError `DOC_LEDGER_ERROR`
3. [x] 单元/回归测试(`-short` 已绿)
4. [x] 占集成槽位 rebuild + 6417 复测(`run_1789625396102207018`,`doc_proj6417_intake` NULL FK)
5. [x] test-report 归档;合入 `dev`
## 验收标准
- [x] `go test -short ./internal/docgov/... ./internal/stream/...` PASS
- [x] 仅-author 项目 `CreateOrGetDocument` / 任务发起不再 `INTERNAL_ERROR`;`reviewer_id IS NULL`
- [x] 项目 6417 账本创建成功(full 职责路径未被本修复改动)
## 相关链接
- Audit: [../../audit/2026-09-17-docgov-optional-duty-null-fk.md](../../audit/2026-09-17-docgov-optional-duty-null-fk.md)
- Test report: [../../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md](../../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md)
## 证据 / 备注
- 失败 run:`run_1789622069585300787`
- 验证 run:`run_1789625396102207018` / `doc_proj6417_intake` author=9 reviewer/approver NULL
- merge:`e488d10 merge: fix/docgov-optional-duty-null-fk`
@@ -0,0 +1,47 @@
---
title: 文档编制人兼任审核批准方案
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Codex
branch: feature/document-author-only-plan
worktree: .worktrees/feature-document-author-only-plan
mutex: document-duty-policy-plan
---
# 文档编制人兼任审核批准方案
## 目标
基于当前源码形成管理员总授权、项目创建者逐文档选择的详细实施方案,交用户审核。
## 范围
权限、系统设置、工作流规划和冻结、文档三职、动作鉴权、状态机、前端、迁移与验收。
## 非目标
本次不修改业务代码、不变更数据库或共享容器、不推送。
## 步骤
1. [x] 阅读启动链并从本地 dev 建立隔离分支。
2. [x] 核查实现并记录证据。
3. [x] 编写方案、检查边界与验收覆盖。
## 验收标准
- [x] 方案覆盖用户两个权限层级及逐文档持久化。
- [x] 当前事实与拟议行为分开,列明实施单元与测试场景。
## 证据 / 备注
基线 dev adb48c8。已 fetch origin/dev,本地 dev 领先 44、落后 0,保留未推送集成成果;主工作区 feature/control-center-server 未切换。worktree 脚本默认从当前 HEAD 创建,故直接指定 dev 创建本 worktree,避免引入他人分支。
## 交付
- 方案:`.doc/remediation/2026-09-17-document-author-only-plan.md`
- 核查:`.doc/audit/2026-09-17-document-author-only-analysis.md`
- 本任务完成仅指方案交付,业务实现为 planned;R9/R10 待用户审核。
- 未合入 dev:方案保留在独立分支供审核;未推送、未修改业务代码或容器。
- 验证:源码与文档一致性检查、git diff --check;未执行业务测试。
@@ -0,0 +1,57 @@
---
title: "文档编制人兼任:U1 策略存储与总授权"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/document-author-only-plan
worktree: ".worktrees/feature-document-author-only-plan"
mutex: sysadmin + document-duty-policy
---
# 文档编制人兼任:U1 策略存储与总授权
## 目标
落地 `workflow.allow_author_only_approval` 管理员总开关:默认关闭、严格 bool、revision CAS、事务内审计,并向 projectinstance 提供可参与激活事务的窄读取接口。
## 范围
- Goose 增量迁移(revision 列、种子行、策略审计表)
- `internal/sysadmin` 存储/服务/窄 Policy 接口
- `admin_system_handlers` 对本 key 的 `expected_revision` 协议
- 单元 / PG / HTTP 负例测试
## 非目标
- 逐文档 duty_policy(U2)
- 前端设置页文案(U5)
- 已激活实例紧急熔断
## 步骤
1. [x] 认领 CURRENT
2. [x] 迁移 00050
3. [x] sysadmin CAS + 审计 + PolicySource
4. [x] admin handler
5. [x] 测试与提交
## 验收标准
- [x] 管理员可开关;非管理员 403
- [x] null/字符串布尔拒绝
- [x] 并发 CAS 仅一版成功
- [x] 审计失败回滚设置
- [x] 窄接口可读 allowed+revision;缺行默认 false;DB 故障不伪装
## 相关链接
- Plan: `.doc/remediation/2026-09-17-document-author-only-plan.md` U1
- Checklist:
## 证据 / 备注
- `go test ./internal/sysadmin/ ./internal/server/ -run 'Settings|AuthorOnly|PGSettings|AdminSystem'` PASS
- `go test -short ./internal/sysadmin/ ./internal/server/` PASS
- Key: `workflow.allow_author_only_approval`
- 窄接口: `sysadmin.AuthorOnlyPolicySource`
@@ -0,0 +1,54 @@
---
title: "文档编制人兼任:U2 逐文档模式与激活"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/document-author-only-plan
worktree: ".worktrees/feature-document-author-only-plan"
mutex: projectinstance + document-duty-policy
---
# 文档编制人兼任:U2 逐文档模式与激活
## 目标
落地逐文档 `duty_policy=author_only`:规划校验、预览摘要、激活 token 绑定策略 revision,激活事务内行锁串行化关闭总开关。
## 范围
- DocTaskPlan / PreviewSummary / ProjectSettings 扩展
- ResolveDocTaskDuty、Save/Preview/Activate 消费 U1 策略
- Goose 00051 token revision 列
- app 适配器装配、HTTP 错误码映射
- 单元测试
## 非目标
- Heal/文档投影(U3)
- 前端 UI(U5)
- 运行时动作多职责(U4/U6)
## 步骤
1. [x] 类型与解析器
2. [x] service/store/迁移
3. [x] app 装配与 handler
4. [x] 测试与提交
## 验收标准
- [x] 一位成员兼任可存/预览/激活(总开关开)
- [x] 总开关关时 Save 拒绝
- [x] 预览后 revision 变化旧 token 409
- [x] 未开模式只填作者仍 partial 拒绝
- [x] 旧快照缺 duty_policy 时 hash 稳定
## 相关链接
- Plan: `.doc/remediation/2026-09-17-document-author-only-plan.md` U2
## 证据 / 备注
- `go vet ./internal/projectinstance/ ./internal/app/ ./internal/server/`
- `go test -short ./internal/projectinstance/ ./internal/server/ ./internal/app/` PASS
@@ -0,0 +1,55 @@
---
title: "文档编制人兼任:U3 文档绑定与职责投影"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/document-author-only-plan
worktree: ".worktrees/feature-document-author-only-plan"
mutex: docgov + docduty + bizdev + document-duty-policy
---
# 文档编制人兼任:U3 文档绑定与职责投影
## 目标
生成时写入实例治理职责并 `duty_locked`;heal/revoke 跳过锁定行;读侧投影 `duty_policy`。
## 范围
- Goose 00052:`document_records.duty_locked` / `duty_policy`
- `docgov.LockDocumentDuty` + 列表投影
- `docduty` heal/revoke `AND NOT duty_locked`
- `bizdev.InstanceDutySource` + `resolveTaskDocumentDuties` 治理分支;跳过 governed 内存 heal
- `app/instance_duty_adapter.go` 装配
## 非目标
- U4 动作鉴权 / allowed_actions
- U5/U6 前端
- 合入 `dev`
## 步骤
1. [x] 迁移
2. [x] docgov / docduty
3. [x] bizdev + app 适配器
4. [x] 测试与提交
## 验收标准
- [x] 受治理文档创建后 `duty_locked=true` 且三职来自实例
- [x] heal/revoke 不清锁定行(SQL 过滤 + 单测/PG 可选)
- [x] 生成后 governed 路径不再用项目默认覆盖内存态
- [x] 模块边界:bizdev/docduty/docgov 不导入 projectinstance
## 相关链接
- Plan: U3(文档绑定与职责投影一致性)
- 依赖:U1 `3b6def2`、U2 `c03d0a3`
## 证据 / 备注
- `go vet ./internal/docgov/ ./internal/docduty/ ./internal/bizdev/ ./internal/app/ ./internal/projectinstance/`
- `go test -short` 上述包 PASS
- PG:`TEST_DATABASE_URL` 未配置时 `Heal/Revoke SkipsDutyLocked` 自动跳过
@@ -0,0 +1,47 @@
---
title: "文档编制人兼任:U4 动作鉴权与审计"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/document-author-only-plan
worktree: ".worktrees/feature-document-author-only-plan"
mutex: projectinstance + docgov + document-duty-policy
---
# 文档编制人兼任:U4 动作鉴权与审计
## 目标
ABAC 门禁识别 `duty_policy=author_only` 派生职责;审计 Details 携带 duty_policy。
## 范围
- `duty_action` / `stage_access` / `gate` 改用 `ResolveDocTaskDuty`
- `state_machine` Transition* Details 补 `duty_policy`
- author_only 动作矩阵与阶段可见性测试
## 非目标
- U5 UI / U6 浏览器闭环
## 步骤
1. [x] ABAC 三文件
2. [x] 审计详情
3. [x] 测试与提交
## 验收标准
- [x] author_only 规范存储(仅 Author ID)下 A 可 run/edit/submit/review/approve
- [x] 非 A 拒绝;阶段门禁将 author_only 视为 approvalManaged
- [x] 审计 Details 含 duty_policy
## 相关链接
- Plan: U4+U5 实施计划
- 依赖:U1–U3
## 证据 / 备注
- `go test -short ./internal/projectinstance/ ./internal/docgov/ ./internal/app/ ./internal/server/` PASS
@@ -0,0 +1,48 @@
---
title: "文档编制人兼任:U5 系统设置与逐文档 UI"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/document-author-only-plan
worktree: ".worktrees/feature-document-author-only-plan"
mutex: web + document-duty-policy
---
# 文档编制人兼任:U5 系统设置与逐文档 UI
## 目标
前端识别 `duty_policy` / `author_only_policy`;项目设置可逐文档开启兼任。
## 范围
- `projectSettings.ts` 类型
- `projectSettingsDuties.ts` resolveClientDocTaskDuty + 校验
- `ProjectSettingsModal` 兼任勾选与预览
- SettingsSection 不改(白名单通用渲染)
## 非目标
- U6 多职责动作栏 / 浏览器 E2E
## 步骤
1. [x] 类型与 lib
2. [x] UI
3. [x] 测试与提交
## 验收标准
- [x] author_only 客户端校验通过且不计三人门槛
- [x] 总开关关闭时兼任勾选禁用并提示
- [x] 预览展示兼任文档计数
## 相关链接
- Plan: U4+U5 实施计划
## 证据 / 备注
- `npx tsc --noEmit` PASS
- `npm test` PASS(含 projectSettingsDuties author_only 用例)
@@ -0,0 +1,55 @@
---
title: "文档编制人兼任:U6 多职责动作与真实闭环"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/document-author-only-plan
worktree: ".worktrees/feature-document-author-only-plan"
mutex: web + document-duty-policy
---
# 文档编制人兼任:U6 多职责动作与真实闭环
## 目标
去掉 author-first 动作短路,把认领/送审/审核/批准接到真实 docgov HTTP,完成 author_only 端到端验收。
## 范围
- `web/src/api/docgov.ts` 四接口客户端
- `docGovActionVisibility` / `holdsDocDuty`
- `App.tsx` 真实 handler + 快捷指令
- `duty_policy` 透传与「编制人兼任」徽标
- 单测 + 真实闭环报告
## 非目标
- 变更提案 HTTP 路由(另记 audit)
- 合入 `dev` / 推送远端(未授权不推)
## 步骤
1. [x] API 客户端
2. [x] ID 直判可见性
3. [x] App 接线 + 驳回批准修正
4. [x] duty_policy 徽标透传
5. [x] 单测 / tsc
6. [x] 真实闭环与报告
## 验收标准
- [x] author_only 下 A 可见三动作;非 A 403
- [x] 真实 API 闭环写库与审计含 duty_policy
- [x] 浏览器可见「编制人兼任」徽标
- [x] 测试报告归档
## 相关链接
- Test report: [../../test-reports/2026-09-17-document-author-only-u6-test-report.md](../../test-reports/2026-09-17-document-author-only-u6-test-report.md)
- Remediation U6: [../../remediation/2026-09-17-document-author-only-plan.md](../../remediation/2026-09-17-document-author-only-plan.md)
## 证据 / 备注
- `npm test` 390 pass;`tsc --noEmit` clean
- assets: `test-reports/assets/2026-09-17-document-author-only-u6/`
@@ -0,0 +1,41 @@
---
title: "首次加载性能诊断与改进方案"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Codex
branch: feature/initial-load-performance-plan
worktree: .worktrees/feature-initial-load-performance-plan
mutex: loading-performance-audit
---
# 首次加载性能诊断与改进方案
## 目标
以源码、现有容器静态资源和只读浏览器测量定位首次加载瓶颈,输出可审核的分期改进方案。
## 范围
登录前首屏、登录后初始化、项目/文档首次打开、静态资源交付;区分事实与待验证假设。
## 非目标
不修改业务代码,不重启/重建共享服务,不触发真实对话或文档写任务,不提交或推送其他人的工作。
## 步骤
1. [x] 阅读仓库启动链;独立 dev 基线 worktree,主仓保留其他 Agent 分支。
2. [x] 采集数值基线和源码证据。
3. [x] 写 audit 和 remediation,同步 CURRENT,归档任务。
## 验收标准
- [x] 原因有文件位置或运行时测量支持,未覆盖环境明确标注。
- [x] 方案包含优先级、改动边界、性能预算、回归门禁和回滚。
## 证据 / 备注
仅诊断与方案,不代表优化已实施。fetch 后 origin/dev 落后本地 dev;不拉回或覆盖本地工作。worktree 从创建瞬间的 dev 建立。
## 交付
- 诊断:`.doc/audit/2026-09-17-initial-load-performance-audit.md`
- 方案:`.doc/remediation/2026-09-17-initial-load-performance-plan.md`
- 报告:`.doc/test-reports/2026-09-17-initial-load-performance-baseline.md`
- 本轮仅方案;没有业务代码、没有部署、未提交、未合dev、未推送。主仓仅同步本任务认领。
- 临时3199 Vite已停止;既有3100/8080/8081未重启。未占集成槽。
@@ -0,0 +1,55 @@
---
title: "修复 KB 宿主机错误口令与静默离线降级"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: fix/kb-host-auth-layered-load
worktree: "-"
mutex: infra
---
# 修复 KB 宿主机错误口令与静默离线降级
## 目标
消除 `config.Load("")` 只读 `configs/.env.dev`、忽略根 `.env` 的 `KB_DB_PASSWORD` 导致的错误默认口令与静默离线;E2E/nightly 默认 fail-closed。
## 范围
- `internal/config` 分层加载 + 宿主机 DNS 归一化 + 空默认口令
- `internal/kb` 脱敏日志、`Online()`、`KB_REQUIRE_ONLINE` / `KB_ALLOW_OFFLINE`
- `/health` 增加 `kb_ready`
- PI E2E helper 与 `scripts/run-nightly-real-pi.sh` 预检
- env 模板与验收报告
## 非目标
- 不改 KB 数据内容 / 法规迁移
- 不把真实口令写入 git 跟踪的 `configs/.env.*`
- 不把容器内 DNS 改成 localhost
## 步骤
1. [x] 分层 Load + 默认口令清空
2. [x] NormalizeKBHostForRuntime
3. [x] kb 客户端脱敏 + RequireOnline(EnsureOnline;不 Fatalf)
4. [x] health `kb_ready` + E2E/nightly 门禁
5. [x] 合入 `dev` 冒烟(rebuild + `/health` `kb_ready=true`)
## 验收标准
- [x] `config.Load("")` 分层合并后口令来自根 `.env`(单测临时文件 + live 布尔校验)
- [x] 宿主机 `shuimu-kb-shared` → `127.0.0.1`;容器内保留 compose DNS
- [x] 错口令/空口令离线且日志无明文密码;`KB_ALLOW_OFFLINE=1` 可降级
- [x] 合 `dev` 后 short 测 PASS;dev rebuild 后 `kb_ready=true`,日志 `online=true dsn=...:***@shuimu-kb-shared...`,无 `shared_kb_secret_pass`
## 相关链接
- Test report: `.doc/test-reports/2026-09-17-kb-host-auth-layered-load-test-report.md`
- Plan: 修复 KB 连接降级
## 证据 / 备注
根因:`Load` 优先单文件 `configs/.env.dev`(故意省略 `KB_DB_PASSWORD`),保留错误默认 `shared_kb_secret_pass`;Compose 本已分层,宿主机 `go test` 未对齐。
合入后容器日志:`[kb] online=true dsn=postgres://regkb:***@shuimu-kb-shared:5432/regulations?sslmode=disable`;health `kb_ready=true`。
@@ -0,0 +1,57 @@
---
title: "rdev 模板深度补强 S1 续批(剩余 46 份)"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/rdev-template-depth-s1-continued
worktree: ".worktrees/feature-rdev-template-depth-s1-continued"
mutex: rdev-templates
---
# rdev 模板深度补强 S1 续批(剩余 46 份)
## 目标
将剩余 46 份 `rd_*` 模板按写作规范做同等深度补强,lint allowlist 扩至全 60 份,抽样真 PI 打样收口。
## 范围
- 批1:6 份评审记录
- 批2:阶段06 硬件/工艺 8 份
- 批3:阶段06 软件/检验/技术要求+清单 9 份
- 批4:阶段08 验证 12 份
- 批5:阶段10–13 转换/确认 11 份
- lint allowlist + 抽样真 PI + 文档同步
## 非目标
- S2/S3、P2 前端、P3 三样本全量 E2E、P4 键名空间化
- 晋升 test/main
## 步骤
1. [x] 批1 评审记录 6 份
2. [x] 批2 硬件/工艺 8 份
3. [x] 批3 软件/检验/清单 9 份
4. [x] 批4 验证 12 份
5. [x] 批5 转换/确认 11 份
6. [x] 抽样真 PI + 文档同步(合入 push 见 merge 步骤)
## 验收标准
- [x] 46 份无「按本阶段专业结构写」;lint allowlist 60/60
- [x] 抽样 1–2 份真 PI PASS(`rd_planning_review` + `rd_design_vv`,项目 6446)
- [x] FEATURE-MATRIX / 写作规范 / backlog 已更新
## 相关链接
- Backlog: [.doc/backlog/2026-09-17-rdev-phase2-backlog.md](../../backlog/2026-09-17-rdev-phase2-backlog.md)
- 写作规范: [.doc/system-design/project-workflow/08-rdev模板写作规范.md](../../system-design/project-workflow/08-rdev模板写作规范.md)
- 首批报告: [.doc/test-reports/2026-09-17-rdev-template-depth-test-report.md](../../test-reports/2026-09-17-rdev-template-depth-test-report.md)
- 续批报告: [.doc/test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md](../../test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md)
## 证据 / 备注
- 资产:`.doc/test-reports/assets/2026-09-17-rdev-template-depth-s1-continued/`
- 附带:`fix(projectinstance): allocate next instance_no for planning drafts`
@@ -0,0 +1,54 @@
---
title: "rdev 模板深度补强 S0 + S1 首批"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/rdev-template-depth
worktree: ".worktrees/feature-rdev-template-depth"
mutex: rdev-templates
---
# rdev 模板深度补强 S0 + S1 首批
## 目标
修复 rdev leader prompt 错配,并为阶段 01–05 的 14 份 rdev 模板补齐 ISO 13485 专业章节与逐节写作指令,以 dev 真实 PI 打样验证收口。
## 范围
- S0.1 B1:`rdev_leader.md` + InstructionsFile 注入链
- S0.2:`rd_design_input_spec` 样例 + 写作规范 + lint
- S0.3:dev 真实 PI 打样
- S1 首批:阶段 01–05 共 14 份模板(分 3 批)
## 非目标
- overlay 机制本体、R1–R7 二期、per-stage 步骤定制、模型配置化、manifest 元数据、前端(P2)、键名空间化(P4)、阶段 06–13 模板
## 步骤
1. [x] S0.1 leader prompt 注入链(`6a09062`)
2. [x] S0.2 样例模板 + 规范 + lint(含于 `eb09b21`)
3. [x] S0.3 真实 PI 打样(项目 6424 intake + 6425 `rd_design_input_spec`)
4. [x] S1 批 1–3(`eb09b21`)
5. [x] 文档与门禁
## 验收标准
- [x] rdev leader AGENTS.md 含「设计控制」且不含「商务对接负责人」「CDO」
- [x] intake leader 回归仍含「商务对接负责人」
- [x] 14 份模板 lint 绿灯;真 PI 终稿五节实质论证
- [x] `go vet` + `go test -short` 全绿
## 相关链接
- Test report: [.doc/test-reports/2026-09-17-rdev-template-depth-test-report.md](../../test-reports/2026-09-17-rdev-template-depth-test-report.md)
- Assets: [.doc/test-reports/assets/2026-09-17-rdev-template-depth/](../../test-reports/assets/2026-09-17-rdev-template-depth/)
- Backlog: [.doc/backlog/2026-09-17-rdev-phase2-backlog.md](../../backlog/2026-09-17-rdev-phase2-backlog.md)
- 写作规范: [.doc/system-design/project-workflow/08-rdev模板写作规范.md](../../system-design/project-workflow/08-rdev模板写作规范.md)
## 证据 / 备注
- 依赖 `feature/rdev-core`(尚未合 dev);合入前需 rebase 丢弃已进 dev 的 engineering-dashboard 重复提交。
- 真 PI:`run_1789635054471569201`(intake ~220s);`run_1789635960880707641`(DI ~450s,`stage=RD03_design_input`)。
@@ -0,0 +1,70 @@
---
title: "研发工作流(rdev)接入:13 阶段 / 60 文档任务"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: fix/docgov-stage-dynamic → feature/rdev-core
worktree: "-"
mutex: workflow-def
---
# 研发工作流(rdev)接入:13 阶段 / 60 文档任务
## 目标
在现有 5 个正式工作流外新增医疗第 4 工作流「研发设计控制流程」(key: `rdev`),完整承载参考项目 13 phase / 60 文档任务的 ISO 13485 DHF 设计控制链,并通过真实 PI 验收;随后完成全工作流任务键命名空间化(P4)。
## 范围
- 方案:[07-研发工作流rdev接入-设计与实施计划](../../system-design/project-workflow/07-研发工作流rdev接入-设计与实施计划.md)(P0–P4 五期;§8 四项决策已确认)
- P0:docgov Stage 去硬编码 + stage key 透传
- P1:rdev.v2.json manifest(13×60 一次到位)+ 60 份 rd_ 前缀模板 + catalog/seed/registry + squad kind 编排 + main-completed precheck + 齐套测试 + stub PG 全链路
- P2:前端激活规划/切换/前置 Banner + intent 文档名匹配 + prior docs 注入与血缘
- P3:真实 PI Agent E2E(rd_proposal / rd_planning_review / rd_sw_plan 三样本)+ CI 门禁扩四
- P4:现有工作流(main/pm/tm + 软件两盘点)任务键 `bd_`/`pm_`/`tm_`(`sw_`)空间化,alias 兼容式改名(D12),独立分支独立验收
## 非目标
- 二期增强全部移入 backlog:[2026-09-17-rdev-phase2-backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md)(N/A 不适用页生成、UR/RS 结构化门禁、kind 专用门禁、depends_on 精确血缘、DMR 归档、sw_ 键盘点、complexity regulatory 注入)
- 云盘 canonical DHF/DMR 归档(本仓库无云盘模块)
- 软件域(non_medical_software)开放 rdev
## 步骤
1. [x] 用户确认方案 §8 四项决策(2026-09-17:名称「研发设计控制流程」/ 60 任务一次到位 / N/A 规划期关闭 + backlog / rd_ 前缀并扩展到现有工作流键名空间化)
2. [x] P0 分支 `fix/docgov-stage-dynamic`(StageKey 透传;已叠入 `feature/rdev-core`)
3. [x] P1 分支 `feature/rdev-core`(manifest/模板/seed/编排/precheck/齐套测试)
4. [ ] P2 分支 `feature/rdev-web-governance`(前端 + intent + 血缘)— **骨架已定,待独立认领**
5. [ ] P3 真实 PI 验收 + 报告归档 + FEATURE-MATRIX 更新 — **骨架已定,待独立认领**
6. [ ] P4 分支 `feature/workflow-key-namespace`(D12 alias 兼容式改名 + 双路径回归)— **骨架已定,待独立认领**
## 验收标准
- [x] `go vet ./...` && `go test -short` 相关包 PASS(P0+P1)
- [x] 齐套断言:manifest 60 任务 ↔ `templates/docs/rd_*.md` 存在非空;rd_ 键与既有任务键不相交
- [x] precheck:main 未 completed 时 rd 任务启动被拒且文案含 CDO
- [ ] PG 集成:rdev 实例 planning→live→推进(`TestPG_RDevActivateWithNAClose`,需 `TEST_DATABASE_URL`)
- [ ] web `npm test && npm run build` PASS;Playwright 抽检激活/推进(P2)
- [ ] 真实 PI + MiniMax 三样本 E2E 报告归档 `.doc/test-reports/`(P3)
- [ ] P4:旧 live 实例(旧键)+ 新实例(新键)双路径回归 PASS;全工作流任务键集合无交集
## 相关链接
- 设计方案: [07-研发工作流rdev接入-设计与实施计划](../../system-design/project-workflow/07-研发工作流rdev接入-设计与实施计划.md)
- 参考调研: [2026-09-17-rdev-workflow-reference-analysis](../research/2026-09-17-rdev-workflow-reference-analysis.md)
- 二期 backlog: [2026-09-17-rdev-phase2-backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md)
- Checklist: -
- Handoff: -
- Test report: -
## 证据 / 备注
- 参考项目:`.refs/weichen-agent-system`(configs/workflows/rdev.yaml 60 stage、templates/docs 60 模板、squads/overlays 配套)
- 关键约束:WF-DEF-06(无流程级依赖,precheck 先例 test_manager);doc_id `doc_proj{pid}_{taskKey}` 平铺命名 → rd_ 前缀
## 合入说明(2026-09-17)
- P0+P1 已 `--no-ff` 合入本地 `dev`(含 template-depth S0+S1)。
- P2/P3/P4 仍 planned,待独立认领。
@@ -0,0 +1,39 @@
---
title: "W4 PU8 U9–U12 独立 flag live"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w4-u9-segment-live
worktree: "-"
mutex: intent-plan
---
# W4 PU8 U9–U12 独立 flag live
## 目标
U9 真实 LLM proposer(规则能切则不出 proposal);U10–U12 各自独立 flag 的 dry-run→confirm 证据;不升 `MULTI_INTENT_PLAN_TIER`。
## 范围
- `PiSegmentProposer` + 规则门 + 组合根接线
- U10 mutate 幂等 dry-run receipt;U11 项目 143 只读;U12 run-control 独立 flag
- 四份独立 test-report
## 非目标
- 不升 `confirm` / `full`
- 不把 U10–U12 dry-run 写成领域 live 写
## 步骤
1. [x] U9 PI proposer + 规则门
2. [x] U10–U12 分 flag 证据
3. [x] 合 `dev` + 矩阵升 done
## 验收标准
- [x] 真实 MiniMax U9
- [x] 负例 malformed/timeout/OOB/规则已切
- [x] PLAN_TIER 仍 legacy
@@ -0,0 +1,59 @@
---
title: "个人工程中控台:实时项目看板与离线 HTML 快照"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor-Auto
branch: feature/engineering-dashboard
worktree: .worktrees/feature-engineering-dashboard
mutex: engineering-dashboard
---
# 个人工程中控台:实时项目看板与离线 HTML 快照
## 目标
实现一个独立于产品后台的本地只读中控台,以同一不可变快照驱动实时页面、机器可读 JSON 与单文件 HTML 导出。
## 范围
- 聚合 `.doc`、Git/worktree、Docker/Compose、`/ready` 和晋升凭证。
- 展示架构、模块、功能、任务、分支、验证和环境实装证据。
- 提供 Markdown 搜索、阅读、正反向链接和证据链导航。
- 显示来源、新鲜度、degraded 与 drift,不把声明状态当作观测状态。
## 非目标
- 不接入产品后台、产品数据库或产品权限体系。
- 不写文档,不操作 Git、Docker、部署或 Herdr。
- 不隐式联网或执行 `git fetch`。
## 步骤
1. [x] U1:冻结快照、事实与四轴状态契约。
2. [x] U2:实现文档图谱与领域解析器。
3. [x] U3:实现 Git 与 worktree 采集。
4. [x] U4:实现运行态与部署证据采集。
5. [x] U5:实现对账、派生视图与新鲜度。
6. [x] U6:实现本地服务、总览与文档导航。
7. [x] U7:实现离线导出、脚本、浏览器验收和治理文档同步。
## 验收标准
- [x] 实时 HTML、离线 HTML 和 JSON 引用同一 `generation_id` 与 `revision_id`。
- [x] 计划、实施、验证、实装四轴独立展示。
- [x] rdev、dev ahead、main events 分叉三个真实样本按方案输出。
- [x] 单源失败时页面仍可用,且显示 stale/error/last-success。
- [x] 默认仅监听 loopback,无写操作、凭证暴露、路径越界和远程资源执行。
- [x] 导出 HTML 离开仓库后仍可阅读 Markdown,且不嵌入 assets。
## 相关链接
- 设计与实施方案:[../../archive/design/2026-09-17-personal-engineering-control-center-plan.md](../../archive/design/2026-09-17-personal-engineering-control-center-plan.md)
- Test report: [../../test-reports/2026-09-17-engineering-dashboard-test-report.md](../../test-reports/2026-09-17-engineering-dashboard-test-report.md)
## 证据 / 备注
- 实现提交序列见 `feature/engineering-dashboard`(U1→U7)。
- 启动:`./scripts/engineering-dashboard.sh serve --repo . --addr 127.0.0.1:8787`
- 导出:`./scripts/engineering-dashboard.sh export --repo . --output /tmp/engdash.html`
@@ -0,0 +1,24 @@
---
title: "FAV U7 incremental — remaining port inventory"
status: open
created: 2026-09-16
updated: 2026-09-17
---
# FAV U7 增量:未移植清单
相对 `feature/final-artifact-vault`,本切片 **未** 整支 merge,且因 `internal/artifactvault` 与当前 `dev`(dataset Candidate backfill)大面积 DIFF,下列能力仍待后续手工移植 + 审计:
| 项 | 旁支路径 | 阻塞 |
|----|----------|------|
| EnumerateTerminals / LoadExclusions | `internal/artifactvault/enumerate.go` | 依赖 TerminalRow;与现 `Enumerate(Candidate)` 并存需设计 |
| TerminalRow Backfill | FAV `backfill.go` | 现 backfill 已改为 dataset 路径 |
| 完整 CLI | `cmd/artifact-vault` 全命令 | 本切片仅 status stub |
| ingest hooks | `internal/server/vault.go` OnFinalArtifact* | 会写 staging;需与 publisher 门闩同批审批 |
| schema JSON | `*.schema.json` | 可选文档资产 |
| durable Register(fav) | `cmd/events` | events 硬门 + 单独 cutover 审批 |
| live staging → artifact → publication | publisher Drain / ingest hooks | 每级观察窗 ≥7 天;本轮 **未** 放量 |
**W6 已移植(仍非 live)**:`internal/app/fav.EventConsumer.ObserveShadow` 只计算 intended outcome(`WouldStage`/`WouldPublish` 恒 false);`FAV_DEGRADED_READ` 为 true 时 shadow 直接拒绝;`HandleLease` 与 `Registry.Register(fav)` 仍 fail-closed。
**红线保持**:`FAV_DEGRADED_READ=false`;fav consumer mode=off;禁止整支 merge。
@@ -0,0 +1,45 @@
---
title: "临时验证脚本 Path 空字符串拼接导致跨任务取证串味"
status: done
created: 2026-09-17
updated: 2026-09-17
severity: low
---
# 临时验证脚本 Path 空字符串拼接导致跨任务取证串味
## 现象
S0.3 真 PI 打样归档时,`rd_design_input_spec-final.md` 一度被写成无关客户的商务对标报告(「掌上无线超声系统 × GE Vscan / Philips Lumify」),而非设计输入规格书终稿。
## 根因分析
产品侧小队/工作区创建正常:失败的 `rd_*` 请求因 main-completed 硬 precheck 拒绝,`task_runs.WorkspaceID` 如实为空。
缺陷在**本地临时取证脚本**(`.doc/test-reports/assets/2026-09-17-rdev-template-depth/run_s0_*.py`)的兜底逻辑:
1. `ws_id = pi_result.get("workspace_id") or ""` 在响应无该字段时得到空串;
2. Python `pathlib`:`Path(bizdev_root) / ""` **坍缩为父目录本身**(无报错);
3. 随后 `root.rglob("output.md")` 扫遍共享 `data/dev/workspaces/bizdev/` 全树;
4. 「取最长文本」启发式选中历史商务任务终稿并误归档。
证据:会话内 `task_runs` 失败记录 `WorkspaceID=""`;`Path('/a/b') / '' == Path('/a/b')` 可复现;误归档文件内含 `adhoc_GEVsca_...` 工作区路径。
## 严重度
`low` — 仅本地取证脚本;未污染产品库、未改小队/黑板创建逻辑;同轮已用精确工作区路径重归档并随测试报告提交干净终稿。
## 关联整改
- 无需产品代码改动。
- 经验红线:临时验证脚本禁止「空路径拼接 + 全树 `rglob` + 取最大值」组合;`work_dir`/`WorkspaceID` 为空时必须失败退出,不得扩大搜索范围。
## 证据
- 正确终稿:`.doc/test-reports/assets/2026-09-17-rdev-template-depth/rd_design_input_spec-final.md`
- 测试报告:`.doc/test-reports/2026-09-17-rdev-template-depth-test-report.md`
- 工作区 ID 生成:`internal/squad/workspace.go`(`ws_%s_%d` + UnixNano)
## 开放问题
- 无。
@@ -0,0 +1,62 @@
---
title: "D7 对话数据分类盘点"
status: done
created: 2026-09-17
updated: 2026-09-17
severity: medium
---
# D7 对话数据分类盘点
## 现象
FEATURE-MATRIX「对话数据治理(D7)」为 `deferred`;ADR 数字 `pending-compliance-signoff`。W7 只盘点当前基线:会话正文、派生副本、共享 KB、日志、备份、事件敏感字段。本轮**未**按草案 365/180/30 天执行物理删除或备份清除。
## 根因分析
当前基线是「热库明文 + 软删除列预留 + 事件 ID 化」,不是已签字的留存作业。缺口是**尚未实现**的治理能力,不是已确认合规数字被违反。
## 严重度
`medium`(实现缺口;**不**升 gap-matrix blocker)
## 分类盘点
| 数据类 | 位置 | 形态 | 现状 |
|--------|------|------|------|
| 会话正文 | `chat_sessions` / `chat_messages.content` | 热库明文 TEXT;`deleted_at` 列存在 | dev 619 sessions / 3291 messages;`deleted_at` 全 NULL;Go 无 `SET deleted_at`、无 `DELETE FROM chat_*` |
| 派生摘要 | `chat_daily_digests` | headline / key_points JSON | 0 行 |
| 向量记忆 | `context_memory_chunks` | `content` TEXT + embedding | 102 行:`project_doc` 71、`chat_history` 24、`approved_case` 7。聊天派生副本会随正文留存 |
| 私密文档 | `freeform_documents` | `is_deleted` / `deleted_at` + version markdown | 122 份,其中 113 已软删(聊天消息无对等写路径) |
| 共享 KB | `shuimu-kb-shared` / `regulations` | 法规 chunks,无 chat 表 | `reg_documents` 2907、`reg_chunks` 312919;与对话库隔离 |
| 事件 envelope | `event_envelopes.payload` BYTEA | JSON 字段 | 4 条;keys 均为 ID/digest/`summary_ref`,`has_content=false` |
| 事件 DLQ / attempts | `event_dead_letters` / `event_delivery_attempts` | ID + reason / error_code | DLQ 0;attempts 4;无正文列 |
| 日志 | Docker `json-file` 无 max-size | 应用 slog | 抽检 rebuild 日志:DSN 已 `***`,无 chat content |
| 备份 | `scripts/backup-system-db.sh` `pg_dump -Fc` | 整库含 chat 明文 | 宿主机无 `./backups` 目录;CI 有 backup-restore-drill |
| Agent workspace | `data/dev/workspaces` 150M | 非终态工作区 | 无 30 天清理作业(ADR 草案待签字) |
| FAV | `final_artifacts` | 1 行;consumer mode=off | 与聊天口径解耦;W6 shadow 不写 |
事件 payload 比 `StaticContracts` allowlist **多出** `workspace_id` / `manifest_sha256` 等 ID 字段,但仍无聊天正文。属契约收紧 follow-up,不是 Track E 正文泄漏。
## 违规判定
对照已签字约束(Track E ID-only 日志/DLQ、R13 出站最小化、ADR 明确「签字前禁止按数字删除」):
- **未发现**已确认安全/合规基线被当前实现违反。
- **因此不写** `gap-matrix` blocker。
- 缺 365 天热库清理、缺聊天 soft-delete 写路径、缺字段级加密,均属 ADR 签字后的 W7 整改实现,不得在本轮当「已违规」执行删除。
## 关联整改
- ADR 草案: [../adr/2026-09-17-d7-chat-data-retention.md](../adr/2026-09-17-d7-chat-data-retention.md)
- 签字后整改:soft-delete 写路径 → 观察窗 → 物理清理;同步清 `context_memory_chunks` 的 `chat_history`;备份二次批准 + delete manifest(R22)
## 证据
`.doc/test-reports/assets/2026-09-17-w7-d7-inventory/`(counts / columns / event keys / KB / logs / health)。查询只读,未 `DELETE`/`UPDATE`。
## 开放问题
- 合规何时签字或改数(365/180/30)?
- 聊天 UI 删除是否要与 freeform 回收站对齐?
- `taskrun.completed` payload 额外 ID 字段是否收紧 allowlist?
@@ -0,0 +1,32 @@
---
title: "docgov 变更提案缺少 HTTP 路由"
status: resolved
created: 2026-09-17
updated: 2026-09-17
severity: medium
---
# docgov 变更提案缺少 HTTP 路由
## 现象
引擎侧存在 `docgov.ProposeModification` / `DecideModificationProposal`,但服务端此前仅注册 `POST /api/v1/docgov/proposal/decide`;前端 `App.tsx`「变更方案提议」(`pendingProposal`)为本地模拟。
## 根因分析
生命周期三接口与 claim 已注册;变更提案 **propose** 路径从未暴露为 HTTP。
## 严重度
`medium` — 不阻塞编制→审核→批准主链;阻塞「认领后小队修改须提案确认」的真实治理。
## 处置(resolved)
- 新增 `POST /api/v1/docgov/proposal` → `ProposeModification`
- 前端 `proposeModification` / `decideModificationProposal` + App 接线
- 单测:`TestServer_DocGovProposeAndDecideHTTP`、`web/src/api/docgov.test.ts`
- 任务:`.doc/ops/short-term/2026-09-17-docgov-modification-proposal-http.md`
## 证据
- 合入后真实 HTTP 证据见 `.doc/test-reports/assets/2026-09-17-docgov-modification-proposal-http/`
@@ -0,0 +1,54 @@
---
title: "可选职责空审核人 CreateOrGetDocument 写 reviewer_id=0 触发 FK"
status: done
created: 2026-09-17
updated: 2026-09-17
severity: high
---
# 可选职责空审核人 CreateOrGetDocument 写 reviewer_id=0 触发 FK
## 现象
dev 项目「内廷元无创神经刺激器」(6417) 发起 `intake` 任务后 UI 显示:
- `code: INTERNAL_ERROR`
- `userMessage: 系统内部错误,请重新开始会话`
- `requestId: run_1789622069585300787`
- `sessionId: sess-p6417-u9`
浏览器偶发 `flushSync was called from inside a lifecycle method`(错误态重渲染副作用,非根因)。
## 根因分析
1. app-dev 日志:`persist document ledger: ... document_records_reviewer_id_fkey (SQLSTATE 23503)`
2. 项目成员仅 `document_duty=author`(user 9),无 reviewer/approver
3. `resolveTaskDocumentDuties` 合法返回 `ReviewerID=0`
4. [`internal/docgov/engine.go`](../../internal/docgov/engine.go) `CreateOrGetDocument` 把 `0` 写入可空 FK,PG 拒绝(无 `users.id=0`)
5. `ClassifyError` 默认分支掩盖为 `INTERNAL_ERROR`
对照:[`internal/docduty/store.go`](../../internal/docduty/store.go) heal 路径已有 `nullIfZero`,**创建路径漏改**。
复现:`INSERT ... reviewer_id=0` → 同 FK 错误。近 7 天同因至少 3 次(6417/6359/6274)。
## 严重度
`high`(任何无 reviewer 职责的项目首次落文档账本均会失败;可扩散至 test/main)
## 关联整改
- Short-term: [../archive/ops/2026-09-17-docgov-optional-duty-null-fk.md](../archive/ops/2026-09-17-docgov-optional-duty-null-fk.md)
- Fix branch: `fix/docgov-optional-duty-null-fk`
- Test report: [../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md](../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md)
## 证据
- `docker logs shuimu-agent-app-dev` @ `2026-09-17T05:14:29Z` run_1789622069585300787
- `task_runs.error_message` 与上述一致;`document_records` 对 project 6417 为 0 行
- 手工 `INSERT reviewer_id=0` → `Key (reviewer_id)=(0) is not present in table "users"`
## 后续
- 创建路径 0→NULL;ClassifyError 增加 `DOC_LEDGER_ERROR`
- 不强制配置 reviewer(保持可选职责语义)
- flushSync 另开任务
@@ -0,0 +1,45 @@
---
title: 文档编制人兼任模式源码核查
status: done
created: 2026-09-17
updated: 2026-09-17
severity: medium
---
# 文档编制人兼任模式源码核查
## 结论
当前 dev 基线 adb48c8 不支持本需求。已有标准三人审批、可选免审批、系统设置白名单可复用,但必须补齐逐文档模式、职责来源和前端多职责。
## 根因与证据
1. `internal/projectinstance/duty_mode.go`:partial 拒绝,full 要求三人分离。
2. `internal/projectinstance/service.go`:创建者规划权限与激活后冻结已存在。新需求需在这条链上增加总授权,不能只改 UI。
3. `internal/docduty/store.go`:HealProjectDocuments 按项目默认职责回填受控文档。`internal/docgov/project_docs.go` 在列表读取时调用;`internal/bizdev/service.go` 在生成后调用。新增逐文档策略必须阻止该链覆盖实例职责。
4. `web/src/lib/currentDocRole.ts` 优先返回 author;`docGovActionVisibility.ts` 按单角色显示动作。同人三职会缺审核和批准入口。
5. `internal/server/handlers.go` 三个动作端点固定使用相应 action role,并以登录身份调用引擎;`internal/docgov/state_machine.go` 可复用逐步流转。
6. `internal/sysadmin/settings.go` 有白名单 bool 设置,但没有本需求 key;存储只保留最后修改人时间,新策略需独立版本与审计。
以上为静态源码核查,未查询真实用户数据,未执行功能测试,未声称线上已复现或已修复。完整源码映射与实施单元见方案。
## 关联方案
[文档编制人兼任审核批准](../remediation/2026-09-17-document-author-only-plan.md)
## 文档检查
已检查两级权限、逐文档独立性、full/none 兼容、前后端职责来源、状态与锁、并发授权撤销、成员退出、迁移及回滚。修正一处 docflow 路径为 internal/app/docflow。方案明确区分已知事实与建议口径。
ce-doc-review 未运行:当前工具目录未提供可调用的 skill invocation 入口;按 ce-plan 的 skill_unreachable 分支记录,不能把本地自检当作独立文档审查通过。
```yaml
fixes_applied: 0
proposed_fixes_count: 0
decisions_count: 0
fyi_count: 0
skipped_reason: skill_unreachable
skipped_detail: No callable skill invocation interface in this session; local source and consistency checks only.
```
上方计数仅为未运行技能的占位,不代表产品决策已解决。开放问题仍为 R9、R10;用户未答复时保持方案建议,业务实现不得自行视为授权。
@@ -0,0 +1,117 @@
---
title: "首次加载慢:静态资源、字体与初始化请求诊断"
status: done
created: 2026-09-17
updated: 2026-09-17
severity: high
---
# 首次加载性能诊断
## 结论与适用范围
当前已复现的主要问题在浏览器加载入口:登录页也下载约 2.82 MB 未压缩 JavaScript;外部 Google Fonts CSS 阻塞页面加载;若用户访问 Vite 3100,首访进一步扩大为 207 个资源请求、12.24 MB。冷缓存与热缓存差异很大,与“尤其第一次慢”一致。
登录后还有已确认的请求放大和后端重复工作,但没有登录态浏览器瀑布图或 SQL 耗时,不能声称已量化其贡献。用户已确认 3100/8080/8081,系统重启后第一次访问约十数秒;设备、网络与“系统重启”包含宿主机还是仅应用尚未确认;本次未复现用户原始环境的完整等待时间。
- 主仓读取时 `feature/rdev-core@52f0fbc`;其他 Agent 正在工作,未切换其分支。
- 文档独立 worktree 基线为 `dev@d0ef696`。创建前已 fetch;本地 dev 有未推送提交,未 reset/覆盖。
- 实测现有 8080/8081/8000 构建入口与 3100 Vite;以资源 hash 为运行产物标识,**没有证据证明容器恰好等于上述源码 commit**。
- “首次”定义为新浏览器 context、空 HTTP 缓存;没有重启服务、清空 DB 缓存或重启 Vite,故不是服务/依赖预构建冷启动。
- 未登录、没有调用对话/文档写接口;浏览器探针未使用真实用户会话。
## 实测基线
工具:隔离 Playwright v1.63.0 Docker 浏览器,host 网络访问既有服务。宿主浏览器缺 libatk,改用本机已有浏览器镜像;未修改应用容器。每个场景一个样本,仅诊断,不是 p95 或交付验收。
| 场景 | 登录输入框可见 | FCP | 资源数 | transferSize 合计 |
|---|---:|---:|---:|---:|
| 8080 本机冷缓存 | 662 ms | 664 ms | 4 | 2,857,761 B |
| 同 context 再次导航 | 62 ms | 60 ms | 5 | 353 B |
| 8080 CDP 10 Mbps / 80 ms 冷缓存 | 2,636 ms | 2,636 ms | 4 | 2,857,761 B |
| 同 context 再次导航 | 60 ms | 60 ms | 5 | 353 B |
| 8080 CDP 2 Mbps / 80 ms 冷缓存 | 11,776 ms | 11,776 ms | 4 | 2,857,761 B |
| 3100 本机冷缓存 | 659 ms | 652 ms | 207 | 12,238,086 B |
| 3100 同 context 再次导航 | 162 ms | 160 ms | 208 | 52,253 B |
transferSize 是浏览器 Resource Timing 可观测资源求和,不含顶层 HTML,不等于全链路抓包流量。输入框可见按导航命令开始至 selector 可见计时,FCP 来自页面 Performance API,两者采样时钟和帧提交不同。CDP 限速为模拟设置,不能代替真实公网 RTT;本机 document TTFB 仍约 1–3 ms。首次/再次均保持已有服务运行,未运行 Vite 冷预构建基准。
### F1. 入口包过大且未按需加载(高置信)
- `web/src/main.tsx:2` 静态导入 App;`web/src/App.tsx:98,103,108,145-146` 静态导入导出、系统管理、文件预览等模块;未登录判断直到 `App.tsx:3461`,无法避免入口依赖下载和求值。
- `web/src/features/replyExport/download.ts:1` → docx;`web/src/engine/docxRenderer.ts:19-22` → docx、KaTeX、Mermaid;`web/src/engine/xlsxRenderer.ts:1` → XLSX。
- `web/src/components/doc/preview/FilePreviewPanel.tsx:19-24` 全部静态导入预览器;DocxViewer、ExcelViewer 各自静态导入重依赖。
- 浏览器访问登录页即可观测大 JS。3100 瀑布中含 katex.js 485,944 B、xlsx.js 870,702 B(decodedBodySize)。并非仅仅源码中出现依赖但构建已经排除。
- 8080 主 JS `/assets/index-BLnmtk_3.js` = **2,820,055 B**;8081 = 2,805,141 B;8000 = 2,798,137 B。
因果链:空缓存 → 登录视图与全部工具共入口 → 下载/解析无关依赖 → 网络较慢时登录表单迟迟出现。10 Mbps 下主 JS 下载约 2,373 ms;2 Mbps 首屏约 11.78 秒。没有采集 CPU trace,不能进一步把时间分解成具体库的执行成本。
### F2. 静态响应无压缩、无明确长缓存策略(高置信)
- 三个构建入口均携带 `Accept-Encoding: gzip, br` 请求主 JS,响应没有 `Content-Encoding`,`Content-Length` 为原始字节数。
- `internal/server/server.go:344-384` 使用 `http.ServeFile`,没有静态压缩协商或显式 Cache-Control。
- 同一 8080 JS 离线 gzip 后 **796,146 B**,相对原始包减少约 **71.8%**。这是体积估算,不是已部署优化结果,也不是端到端提速承诺。
- 资源有 Last-Modified,没有显式 Cache-Control/ETag。本次再次导航已命中浏览器缓存;**不能写成“完全没有缓存”**。问题是版本化资源缺少可预测的长期缓存契约。
源站是上述行为,未知用户实际入口是否另有反向代理压缩。优先在真正提供构建资源的层验证和修复。
### F3. 外部字体 CSS 可放大首次白屏(高置信机制,用户网络贡献待测)
- `web/index.html:9-15` 的 Google Fonts 是 head 中普通 stylesheet。`display=swap` 控制字体显示,不会让外链 CSS 本身变为非阻塞。
- 本机自然请求字体 CSS 耗时 **508 ms**,DOMContentLoaded 609 ms,登录可见 662 ms。
- 浏览器拦截并立即失败字体 CSS:登录可见 **210 ms**。Playwright route 会禁用 HTTP cache,因此这个场景不能用于热缓存收益对比,也不能据单样本得出精确净收益。
- 控制实验仅让字体 CSS 等待 5 秒再失败,其余请求正常:DOMContentLoaded **5,111 ms**、登录可见 **5,161 ms**。证明该依赖可以把外部等待传到登录首屏,**不表示自然字体请求真的用了 5 秒**。
### F4. 登录后项目成员扇出并放大会话同步(源码已证实,耗时待测)
`web/src/App.tsx:524-540` 获取项目后,对每个项目调用成员接口;`:383-387` 每次成员结果用 map 生成新的 projects 数组;`:560-590` 的会话列表 effect 依赖 projects,因此成员返回可重复触发会话列表请求。取消标志仅忽略部分返回,没有 AbortController 终止已发请求。React 批处理可能合并更新,**不能写成固定 N 次会话请求**。
项目数 N 增大时,初始成员请求为 N,叠加会话重取、setProjects 及本地持久化。`web/src/data/storage.ts:63` JSON.stringify + localStorage.setItem,`App.tsx:343` 随 projects 更新保存。持久化是否成为长任务还须 profile,不能预设为主要根因。
### F5. 认证有重复查询和同 session 写放大(源码已证实,耗时待测)
`internal/server/auth_middleware.go:48,62` 已认证并保存 principal;`internal/server/auth_handlers.go:126-139` 的 me 再认证。每次经 `internal/auth/service.go:197-203`、`internal/auth/pg_store.go:335-367` 执行 SELECT session、SELECT status、UPDATE session、GetUserByID。正常 PG me 路径共 8 次认证 DB 操作,加一次权限查询。
其他鉴权请求也无条件 UPDATE 同一 auth_sessions 行;首屏并发可能放大行锁/连接等待。未采集 pg_stat_activity/锁等待或接口 p95,锁竞争是待验证风险。
### F6. 文档列表的隐含写修复与轮询叠加(源码已证实,耗时待测)
`internal/docgov/project_docs.go:59-74` 列表先调用 `HealProjectDocuments`;`internal/docduty/store.go:173-205` 开事务并取得项目 advisory lock(`internal/docduty/revoke.go:111-126`),重复读取创建者/成员,扫描文档,按需逐条 UPDATE,commit 后才正式 SELECT。
前端 `App.tsx:1507-1545` 每 5 秒为租约同步调用这个完整列表。请求时长超过间隔时可能重叠;相同项目多个标签放大成本。**不能直接删除 heal**:须先补齐创建/成员变更/转交/撤销写路径与历史数据修复闭环。本轮没有用该 GET 做只读探针。
### F7. 会话列表先聚合消息再分页(源码已证实,耗时待测)
`internal/ctxmgr/chat_history.go:110-125` 候选会话 JOIN 消息、COUNT、GROUP BY/ORDER BY 后 LIMIT,另取最新消息内容。仅返回少量会话不代表少量消息扫描。`internal/projectworkflow/store.go:171-240` 项目列表也无分页。
已有 `chat_messages(session_id, created_at)` 索引(`deploy/postgres/goose/00001_baseline.sql:119`);不笼统认定缺索引。先 EXPLAIN/数据量和可见性分析,再决定先分页后统计、索引或摘要。
### F8. 重启场景补查(用户补充后)
用户明确 3100、8080、8081 在系统重启后首次进入约十数秒。三种冷态须分开:浏览器 HTTP 缓存、Vite 转换/依赖缓存、Go/DB/代理启动就绪。重启若不改变构建 hash,并不会自动清掉浏览器持久 HTTP 缓存;不能直接用新 context 测量解释全部重启现象。
现存容器启动记录:dev StartedAt `2026-09-17T07:00:38.127811581Z`,打印“监听地址”于 `07:00:38.293728694Z`(约 **166 ms**);test StartedAt `06:20:05.243037366Z`,打印监听于 `06:20:05.384607542Z`(约 **142 ms**)。这是已有 DB 就绪条件下的一次启动、且日志先于真正 ListenAndServe,**不是 host reboot→ready 时间**;但未支持“Go 每次初始化必然十几秒”。
`cmd/server/main.go:41-50` 的初始化在监听前,`internal/bizdev/service.go:69-114` 包括 DB Ping/迁移/成员补齐/seed;DB连接段 timeout 5 秒,后续 seed 使用 Background,缺少分阶段耗时。`internal/app/app.go:355` 的 Runtime.Start 幂等,入口重复调用不会重复启动 worker,不能据此误判双倍启动。
Compose app healthcheck 每 10 秒、start_period 20 秒;start_period 是失败宽限窗口,**不代表强制等待20秒**。若代理/运维脚本等健康状态才放流,则探测周期可能影响可见就绪,需要对齐宿主启动、DB healthy、app listen、ready、首次请求时间。3100 的无缓存 Vite 预构建/按请求转换为独立候选,8080/8081 构建产物不存在 Vite 首次编译。
隔离 Vite 在 3199 使用独立空 cacheDir,同源码、未重启宿主/DB:监听准备 43 ms,首访登录可见 **1,580 ms**、207 资源/14,445,631 B,再次 171 ms。服务先启动、浏览器随后连接,部分预构建可能已在导航前完成;该值不是“启动到首屏”总时间。支持开发冷态有额外成本,但本机未复现自然网络十数秒;不得仅靠 warmup 宣称已解决 8080/8081。证据见 `../test-reports/assets/2026-09-17-initial-load-performance/vite-cold.json`。
本轮不重启正在使用的共享服务;U1/U7 纳入计划中的隔离重启矩阵和阶段计时。没有把服务冷启动排除在用户需求之外。
## 已排除与未证明
- 本机静态 HTML TTFB 约 1–3 ms;这组未登录测试并非后端生成首页耗时数秒。
- 没有请求产品 PI Runner,因此本次首屏慢不能归因于大模型冷启动。
- 服务监听前迁移/种子初始化(`cmd/server/main.go:41-50,84-85`;`internal/bizdev/service.go:69-114`)只解释重启就绪,不等于每个新浏览器首访。
- 没有用户重启时的 FRP/公网瀑布、登录后基线、慢 CPU profile、数据库 EXPLAIN;不对这些项宣称已复现。
- 基线现有测试以功能为主;本轮未发现首屏资源预算/冷缓存性能门禁。未运行业务测试,因为没有业务代码变更。
## 关联整改与证据
- [改进方案](../remediation/2026-09-17-initial-load-performance-plan.md)
- [诊断测量报告](../test-reports/2026-09-17-initial-load-performance-baseline.md)
- [完整浏览器数据](../test-reports/assets/2026-09-17-initial-load-performance/browser.json)
- [受控实验](../test-reports/assets/2026-09-17-initial-load-performance/controlled.json)
- [静态响应摘要](../test-reports/assets/2026-09-17-initial-load-performance/assets.json)
@@ -0,0 +1,180 @@
---
title: "系统全面体检:任务收口、缺陷与未启用功能审计"
status: done
created: 2026-09-17
updated: 2026-09-17
severity: high
---
# 系统全面体检(2026-09-17)
> 范围:① 规划未实现 / 需变更 / 实施中任务;② 现存与潜在 bug;③ 已实现但未启用或未测试的功能。
> 方法:文档 SSOT 盘点(CURRENT / FEATURE-MATRIX / gap-matrix / short-term / long-term / backlog / ADR / handoff)+ Go 全量 vet/build/test + 前端 test/build + 特性开关与环境配置交叉核对。只读审计,未实施任何修改。
> 基线验证:`go vet ./...` 与 `go build ./...` 全绿;`go test -short -count=1 ./...` 62 包全 ok;`web` npm test(380+32)与 build 通过。
---
## 一、任务状态盘点
### 1.1 实施中(in_progress)
| # | 任务 | 位置 | 剩余工作 |
|---|------|------|----------|
| T1 | partial/deferred 全量收口总控 | `.doc/ops/short-term/2026-09-16-partial-deferred-completion.md`(owner Cline) | W5(SWBOOT-10 真实现 + 真实 PI + UI 二次验收)、W6(FAV shadow→live 放量)、W7(D7 按 ADR 整改,待合规签字)、逐行升 done |
| T2 | Control Center 个人中控台 | 2026-09-19 已移出本仓库 | 进度管理改由独立项目承担;本仓库不再保留该模块 |
| T3 | 纯软件项目自举 W5b | `.doc/ops/long-term/2026-09-14-software-project-bootstrap-implementation.md` | SWBOOT-10 受控执行器(真 patch/merge)未启动,需独立安全评审,当前 fail-closed stub |
### 1.2 已规划未开始
| # | 任务 | 位置 |
|---|------|------|
| T4 | 首次加载性能 U1/U3–U7 | `.doc/remediation/2026-09-17-initial-load-performance-plan.md`(仅 U2 done:主 JS 传输 2.82 MB→~624 KB) |
| T5 | 选择性模块解耦 M4–M6 | `.doc/ops/long-term/2026-09-14-selective-module-decoupling.md`(planned,owner=TBD) |
| T6 | 产品 backlog:B5 报价复核、A5/A6 小队降级与 trace、A7 中文注释迁移、D5 KB 按环境隔离评估 | `.doc/backlog/chat-agent-p6-backlog.md`(均无任务文件) |
| T7 | `TestReconcile_LegacyRepair_PG` 工程测试债 | gap-matrix DOC-CONTENT-CANONICAL-HASH-DRIFT 行(需隔离 PG,本机无) |
| T8 | IAM 收尾开放项:410 退役产品拍板、R13 全量清单勾选 | handoff `2026-09-16-phase3-leftover-closeout.md` |
### 1.3 部分完成(partial,剩余关闭条件)
| 行 | 剩余关闭条件 |
|----|--------------|
| 纯软件项目自举 | SWBOOT-10 非 stub(W5b)+ 真实 PI 全链路 + UI 二次验收 |
| FAV | W6 shadow 已合;live 未放量(staging→artifact→publication 各 ≥7 天观察窗) |
| Control Center | 2026-09-19 已移出本仓库,不再作为本仓库关闭条件 |
| 首次加载性能 | U1/U3–U7 |
| 文档可靠性试点 | M1 结论「停止扩面」;M2(U5–U12)明确禁止开工,真实 PI/浏览器验收未勾 |
### 1.4 deferred 待决策
- **D7 对话数据治理**:ADR `2026-09-17-d7-chat-data-retention.md` 仍 `pending-compliance-signoff`;W7 盘点未发现违规;签字前禁止物理删除。
- **`SEMANTIC_SUMMARY_REPLACE`**:决策默认不启用;启用须另开授权 + fail-closed 灰度。
- **`MULTI_INTENT_PLAN_TIER` 升 confirm**:W4 证据闭环,升级需独立授权;永不默认 full。
### 1.5 文档漂移 / 矛盾(文档债)
| # | 漂移 | 涉及文件 |
|---|------|----------|
| D-1 | PU8 四份契约文件仍 `status: in_progress`,但 U9–U12 已升 done、报告已归档 | `.doc/ops/long-term/2026-09-16-pu8-u9/u10/u11/u12-*.md` |
| D-2 | ADR modular-monolith-decoupling 仍「提议,等待用户确认」,但 Phase 1/2 已落地并被当作已确认结论引用 | `.doc/adr/2026-09-14-modular-monolith-decoupling.md` |
| D-3 | audit/INDEX.md 与 remediation/INDEX.md 末行称首次加载性能「方案未实施」,与 U2 已验收矛盾 | 两个 INDEX.md(**本审计已顺手修正为准确表述**) |
| D-4 | handoff `2026-09-15-conversation-intent-dual-tab.md` 的「未完成」已被后续 PASS 覆盖但未回标 | 该 handoff |
| D-5 | backlog D3/D7 条目与 W2 done、W7/ADR 草案并存,backlog 未同步 | `.doc/backlog/chat-agent-p6-backlog.md` |
| D-6 | PROJECT.md §9「剩余 blocker」表述与 gap-matrix「门禁已签、production_ready=yes」口径冲突 | `PROJECT.md` |
---
## 二、Bug 清单
### 2.1 确认 bug(有明确证据)
**后端**
| ID | 描述 | 证据 | 严重度 |
|----|------|------|--------|
| B-1 | **SSE 聊天流被全局 WriteTimeout=120s 强杀**:`server.go:350` 的 WriteTimeout 是绝对期限;`handleChatStream`(`sse.go:129`)从不调用 `extendSSEWriteDeadline`、无心跳,该机制只接到了 run-events 订阅端点。任何 >120s 的聊天回合(长 PI 推演常见)必断流 | `internal/server/server.go:350`、`internal/server/sse.go:46-64,129` | high |
| B-2 | **`POST /tasks/run/stream` 同样无 deadline 延长/心跳**,且断线后无法续订:`sse.go:390` 写死 `Subscribe(created.RunID, 0)`,不接受 `after_seq` | `internal/server/sse.go:305-424,390` | high |
| B-3 | `handleRunTaskStream` **静默吞 JSON 解析错误**:`_ = json.NewDecoder(r.Body).Decode(&req)`,畸形 body 以空请求走默认 `TaskKey="intake"`,可能误启动 intake 任务 | `internal/server/sse.go:315,362-364` | medium |
| B-4 | `handleRunTaskStream` **Flush 200 SSE 头之后才做会失败的操作**(CreateAndStart/Subscribe),失败时往 SSE 流里写 JSON 错误体;同文件 chat 路径明确「授权必须在 Flush 前」,task 路径未对齐 | `internal/server/sse.go:355-360,383-393` | medium |
**前端**
| ID | 描述 | 证据 | 严重度 |
|----|------|------|--------|
| B-5 | **会话窗口缓存 key 不一致**:读/初次写带 `userId` 前缀,但 `loadOlder`/`loadFullDay`/`jumpToDate`/`loadDayForAnchor`/`appendLiveMessage` 等 7 处后续写入不带前缀 → 刷新/切会话恢复到旧窗口;且 LRU 驱逐只用无前缀 key,带前缀缓存永不驱逐,localStorage 只增不减 | `web/src/hooks/useChatWindow.ts:84,100,136,235,271,315,365,416,439,471`、`web/src/data/storage.ts:164-176` | high |
| B-6 | **mount 时 IndexedDB 恢复用陈旧快照整体覆盖 deliverables**:捕获 mount 闭包、非函数式 set,resolve 前新增的 deliverable 被静默丢弃(旁边已有 `deliverablesRef` 未用) | `web/src/App.tsx:326-336` | medium |
| B-7 | `useTaskRunStream` 返回**伪 ref**(每渲染新建对象、快照值非 live),且全仓库无消费方——误导性 API | `web/src/hooks/useTaskRunStream.ts:96` | low |
### 2.2 高风险隐患
| ID | 描述 | 证据 |
|----|------|------|
| R-1 | **聊天会话无归属校验**:`getOrCreateSession` 仅凭客户端传入 `session_id` 返回既有内存会话,随后直接覆盖 `sess.UserID`;非项目会话(ProjectID==0)无任何授权关卡,内存 Messages/Facts 可进入他人 Prompt 与 SSE。缓解:session ID 为纳秒时间戳不易猜 | `internal/server/server.go:394-415`、`handlers.go:181`、`sse.go:187`、`stage_access_helpers.go:251-253` |
| R-2 | **18 个非测试文件 `rows.Next()` 循环后未查 `rows.Err()`**,中途断连静默截断结果集(ctxmgr 历史/窗口/搜索、docgov engine、freedoc、storage/cas、`cmd/document-content-reconcile` 漏检会让 reconcile 漏报文档) | 如 `internal/ctxmgr/chat_history.go`、`internal/docgov/engine.go`、`cmd/document-content-reconcile/main.go:82` |
| R-3 | 事件 dispatcher `Handlers` map **写持锁、读不持锁**(当前仅启动期注册则良性,动态注册即 race) | `internal/events/worker.go:87,154,234` |
| R-4 | `memTurns` 全局幂等表只增不删且跨实例共享,长期运行内存缓增、测试间可能串扰 | `internal/ctxmgr/chat_turns.go:169` |
| R-5 | `internal/docrevision/pg_store.go:68-208` 十余处 `_ = json.Unmarshal(...)`,账本 JSONB 损坏时静默零值化 | 同左 |
| R-6 | 后台 ticker goroutine 无关停通道(通知提醒、vault Drain 错误被丢弃、bizdev 心跳用 `context.Background()`),`Shutdown` 未覆盖 | `notification_reminder_loop.go:15`、`vault.go:63`、`bizdev/service.go:682` |
| R-7 | SSE 重连对 401/404 无 fail-fast:任何错误一律退避重连 40 次(~3 分钟)期间 UI 一直 thinking;`streamChat` 对畸形 data 帧直接抛错中断整条流 | `web/src/api/taskRuns.ts:108-140`、`api/chatStream.ts:122` |
| R-8 | 组件卸载/登出不 abort 任务流,在途 SSE 继续写 localStorage | `web/src/App.tsx:595,2804` |
### 2.3 环境 / 配置缺陷
| ID | 描述 | 证据 | 严重度 |
|----|------|------|--------|
| E-1 | **main 环境 app `ENV=prod` 与 events `ENV=main` 不一致**:事件信封以 `Environment="prod"` 写入,而 `event_consumer_modes` 只种子 dev/test/main 三行 → app 侧 `WriterLive("prod")` 恒 false(in-process 直连不退出),events worker 按 'main' 判定 → **main 存在双写或 durable 管道空转风险**(取决于 main 行 mode)。dev/test 两服务 ENV 一致,无此问题 | `docker-compose.main.yml:90,160`、`internal/app/docflow/commands.go:276`、`goose/00040:55-59`、`internal/events/dispatcher.go:308-313` | **critical(main 专属)** |
| E-2 | **main schema 落后两版(47 vs dev 49)**:00048 给 projects 加 13 列,当前 HEAD 代码直接 SELECT/INSERT 这些列;00049 建 system_settings。若把 dev HEAD 镜像升 main 而不先跑迁移,项目工作流查询/系统设置 API 直接 SQL 报错。**main 晋升顺序必须 events(跑迁移)先于 app** | `goose/00048`、`goose/00049`、`internal/projectworkflow/store.go:76,113` | high(晋升窗口) |
| E-3 | `MULTI_INTENT_PLAN_TIER` 未在任何 compose environment 声明(configs/.env 设了也传不进容器);test/main 连 U9–U12 flag 都未声明 → 容器内锁死 legacy,授权升级时需先改 compose | `docker-compose.*.yml` | medium |
| E-4 | `CURSOR_RUNNER_URL` 三环境 compose 都注入但代码零读取;cursor-agent 容器是 alpine 占位,cursor-cli 后端容器部署不可达 | `docker-compose.*.yml` | low |
| E-5 | `ENABLE_DEV_IMPORT` 不在任何 compose/.env.example;且判断把 `cfg.Env==""` 也算 dev——配置缺失时导入门禁自动放开 | `internal/server/chat_window_api.go:171` | medium |
| E-6 | `SEED_DEMO_USERS` 仅 test compose 显式 false;dev 依赖默认播种(demo 密码 123456),main 靠代码 `Env!="dev/test"` 兜底,主 compose 未显式关闭 | `docker-compose.test.yml:91`、`internal/auth/bootstrap.go:67-116` | low |
| E-7 | `INTENT_V2_DECISION_TIER` 非法值回退 `query`(激进),与 `MULTI_INTENT_PLAN_TIER` 回退 `legacy`(保守)策略不一致 | `internal/intent/flags.go:47-64` | low |
| E-8 | `publisher_gate_test.go:16` 读 `FAV_PUBLISHER_ENABLE`(少 D),与正式变量名不符,该测试门永远走默认分支 | `internal/artifactvault/publisher_gate_test.go:16` | low |
| E-9 | main compose 的 system-db initdb 只挂 00001_baseline.sql,与 dev/test 不一致;新建卷时初始脚本漂移(依赖 events 启动迁移补齐) | `docker-compose.main.yml:23` | low |
---
## 三、已实现但未启用 / 未测试的功能
### 3.1 特性开关封存(实现完整,全环境 off)
| 功能 | 实现位置 | 状态与门禁 |
|------|----------|-----------|
| FAV 事件订阅者 | `internal/app/fav/subscriber.go` | 三重硬门禁:cmd/events 刻意不注册、registry fail-closed、SetMode 拒绝非 off;仅 ObserveShadow 可达 |
| FAV 发布器 | `internal/server/vault.go:18-67` | `FAV_PUBLISHER_ENABLED=false` 三环境显式;且 VAULT_* 三变量 compose 全未声明,容器内即使开 flag 也会静默 return(E-类:实际不可误开,属设计内封存) |
| FAV 降级读 | `internal/docquery/service.go:70` | `FAV_DEGRADED_READ=false` 红线保持 |
| 多意图 PlanTier shadow/auto_read/confirm | `internal/app/intentflow/turn.go` | 容器内锁死 legacy(见 E-3) |
| U9–U12 扩面 | `intentflow/expansion.go`、`mux.go` | 全 false;dev compose 已声明可调,test/main 未声明 |
| 意图 V2 shadow/decision | `internal/intent/shadow_v2.go`、`v2_decision.go` | 三环境显式 false |
| 语义摘要 shadow | `internal/ctxmgr/semantic_summary.go:216` | 默认 off,且仅 AGENT_BACKEND=pi-agent 时挂载 |
| PI change-report 叙事 | `internal/docrevision/narrative.go:68` | 默认 off,仅确定性 fallback(不得冒充完整 PI) |
| artifact-vault CLI | `cmd/artifact-vault/main.go` | 未部署 stub |
| eventmode cutover CLI | `cmd/eventmode/main.go` | 硬门禁仅 dev 可用(`internal/events/cutover.go:13`) |
### 3.2 死代码 / 机制先行无消费方
| # | 项 | 位置 |
|---|----|------|
| X-1 | `SEMANTIC_FALLBACK_ENABLED` 死 flag:无任何业务消费方,仅 sysadmin 展示;三环境 compose 都在设一个没用的变量 | `internal/intent/flags.go:43`、`internal/app/app.go:285` |
| X-2 | `SEMANTIC_SUMMARY_REPLACE` 读取后 `_=` 显式丢弃,刻意永久未接线 | `internal/ctxmgr/semantic_summary.go:257` |
| X-3 | goose 00048 三张新表 `project_source_bindings`/`repo_path_allowlist`/`project_type_workflows` 无代码消费方(swboot 目录硬编码内存版,RepoAllowlist 为 stub) | `internal/swboot/catalog.go:92,118`、`repo_allowlist.go` |
| X-4 | `system_settings` 白名单 6 键全部无业务消费方——可写不生效,纯机制先行 | `internal/sysadmin/settings.go:57-66` |
| X-5 | 前端死组件:`DocumentNotificationList.tsx`(含已读回写,功能完整无挂载点)、`WorkflowPrerequisiteBanner.tsx`、`user/SettingsModal.tsx`(已被 UserSettingsModal 取代);死 API:`api/projectWorkflow.ts:71 activateWorkflow`;`data/storage.ts:141 saveMessages` deprecated no-op | web/src 各文件 |
| X-6 | `useTaskRunStream` 伪 ref(同 B-7) | — |
### 3.3 测试盲区
| # | 盲区 | 说明 |
|---|------|------|
| S-1 | `TestReconcile_LegacyRepair_PG` 从未执行 | 要求隔离 PG 且硬拒绝 5433/5434/5435;canonical-hash 修复链路零自动化验证(gap-matrix 已记测试债) |
| S-2 | 两个「永久跳过」 | `taskstream_test.go:189`(功能已删,测试成死代码应删除);`plan_owner_test.go:125`(重定向跳过) |
| S-3 | 无测试的 cmd 入口 | `cmd/server`、`cmd/events`、`cmd/artifact-vault`、`cmd/dataset`、`cmd/eventmode`、`cmd/recategorize`、`cmd/document-revision-backfill`(仅 bizdev-cli、document-content-reconcile 有);`internal/observability`、`internal/workflow` 无测试文件 |
| S-4 | **E2E 默认全不跑**:web/e2e 9 个 spec 全部被环境门禁(`RUN_UI_ACCEPTANCE=1`/`DOCREV_E2E_BASE_URL`/`INTENT_DUAL_TAB=1`),默认 `playwright test` 实跑 0 用例;`test:ui-acceptance` script 只覆盖 1 个 spec,其余 8 个无 script 入口 | web/e2e/、web/package.json:11 |
| S-5 | 409 信封处理只覆盖部分消费方:projectMembers、freeformDoc、createTaskRun、chatSessions upsert 等 409 只能裸报错(与 FEATURE-MATRIX hardening backlog 一致) | `web/src/api/projectMembers.ts`、`freeformDoc.ts:177`、`taskRuns.ts`、`chatSessions.ts` |
| S-6 | 前端 bundle 大 chunk 未分割(mermaid/katex/xlsx/docx 各成 >500 kB chunk,已有 precompress 缓解) | vite build 警告 |
---
## 四、结论与优先级
**总体判断**:发布门禁与 FEATURE-MATRIX 的 `done/partial/deferred` 口径与代码实况基本一致,未发现「stub 冒充验收」类违规;质量门禁(vet/test/build)全绿。主要风险集中在三处:
1. **E-1(main ENV 不一致 → 双写/空转)是唯一 critical 级发现**,且只在 main 环境存在, dev/test 的「healthy」不能证明 main 事件链路正确。
2. **SSE 120s 断流(B-1/B-2)直接影响长任务可用性**,是用户可感知的现存 bug。
3. **封存面(FAV/多意图 tier/U9–U12/语义摘要/PI 叙事)实现完整但容器内不可调或硬门禁封存**,红线达标,但授权放量时会发现 compose 层缺失(E-3)与若干死接线(X-1/X-2)。
详细整改顺序见 [remediation 方案](../remediation/2026-09-17-system-health-remediation-plan.md)。
## 关联整改
- Remediation: [2026-09-17-system-health-remediation-plan.md](../remediation/2026-09-17-system-health-remediation-plan.md)
## 证据
- `go vet ./...` / `go build ./...` / `go test -short -count=1 ./...`(62 包 ok)/ `cd web && npm test && npm run build`:2026-09-17 全绿。
- 文中所有 `文件:行号` 引用均为 2026-09-17 dev 分支工作区实测。
## 开放问题
- E-1 的修复取向(app 改 `ENV=main` vs 事件信封/consumer mode 键改用部署名)需架构决策。
- D7 合规签字、`MULTI_INTENT_PLAN_TIER` 升 confirm、FAV live 放量均需用户显式授权,不在本整改自动范围内。
- configs/.env.dev/.env.test/.env.main 实际文件未读取(含密钥);若偏离 example 模板,E-3/E-4/E-6 结论需复核。
+130
View File
@@ -0,0 +1,130 @@
---
title: "系统深度体检审计(2026-09-19,dev@e8ed33b)"
status: done
created: 2026-09-19
updated: 2026-09-19
severity: high
---
# 系统深度体检审计(2026-09-19)
> 只读审计,未修改业务代码。分支 `docs/system-deep-audit-2026-09-19`,基点 dev@e8ed33b。
> 方法:go vet / go test -short 静态基线 + 五路并行深潜(后端 server/chat、docgov/events/工作流/迁移、前端 web、配置 flag/死代码、安全鉴权)。
## 一、总体结论
- **静态基线健康**:`go vet ./...` 零告警;`go test -short ./...` 55 包全 PASS;全仓 TODO/FIXME 仅 2 处非实质。
- **四条已声明红线全部核实一致**:`MULTI_INTENT_PLAN_TIER=legacy`、`SEMANTIC_SUMMARY_REPLACE` 未接线、`FAV_DEGRADED_READ=false`、SWBOOT-10 fail-closed stub——代码与三环境 compose 均对齐,无漂移。
- **IAM 主链路复核成立**:路由统一挂鉴权中间件、SQL 全参数化、token 哈希存储、错误出参有内部信息过滤。但存在 dev/test 兜底与端点级鉴权缺口(见 S1/S2)。
- **本次新发现**:2 项 critical(后端数据竞态 + docgov 吞错)、10 项 high、若干 medium/low。其中 3 项被两路独立审查交叉命中(见 ★ 标记),可信度最高。
- FEATURE-MATRIX 已声明的 partial/deferred(rdev、SWBOOT、FAV、D7、首载性能)不在本次重复申报范围;本次发现均为**新增**缺口。
## 二、Critical(发布前必须评估)
### C1 ★ docgov 持久化全链路 fire-and-forget 吞错;fencing token 未读回
`internal/docgov/lease.go:460-467, 485-490`;`internal/docgov/engine.go:318, 392, 405, 470, 477, 650, 743, 750, 1081-1134`
租约获取/续约/回收、正文哈希、认领状态、提案决定及**全部审计日志**均为 `_, _ = e.pool.Exec(...)` 静默吞错:
- 审计 INSERT 失败 → 合规事件永久丢失,无重试无告警;
- 租约 UPDATE 失败 → 内存与 DB 分叉,重启后可并行编辑同一文档;
- `lease.go:485` 用 `context.Background()` 脱离请求生命周期;
- `loadDocumentFromDBLocked` 的 SELECT 列表**不含 `lease_fencing_token` 列**(00034 迁移已建列)→ 进程重启后 fencing 语义完全失效(合法持锁者被误判 stale,或 stale 写者被放行——两个方向都有缺口)。
**建议**:持久化失败必须返回 error 或 slog.Error+指标;审计写入失败进重试队列;lease SELECT 补 fencing 列;persistLeaseLocked 失败回滚内存状态。
### C2 ★ Session 全字段数据竞态 + 跨项目污染
`internal/chat/session.go:275-277`;`internal/server/server.go:432-435`;`internal/server/handlers.go:196-198`
- `Messages`/`UserCtx`/`LastAccessedAt` 的读写锁粒度碎片化:SSE 路径持 `execMu`,而 `hydrateVisibleHistory`、`handleGetProject`、`cleanStaleSessionsLocked`、`server.go:435` 均不持锁。并发 SSE+REST 同会话时 `go test -race` 可复现 data race。
- `handleChat` 无锁写 `sess.ProjectID = req.ProjectID`,同一 sessionID 被不同项目请求交错时跨项目串扰。
**建议**:Session 加 `sync.RWMutex` 统一保护;ProjectID 改为请求级参数不写回共享 sess。
### C3 SSE WriteTimeout=120s 硬杀长任务 + 心跳 goroutine 生命周期不一致
`internal/server/server.go:352-355`;`internal/server/sse.go:252-271`
全局 `WriteTimeout: 120s`;SSE 靠 45s 续期+15s 心跳兜底,心跳被中间代理吞掉时长 LLM 回合(dialogueTimeout=3min)被强杀。非流式 `handleRunTask` 同步执行数十分钟任务,120s 必然截断响应(业务已执行、客户端收不到结果 → 幂等重试造成重复执行观感)。心跳 goroutine 模式与 `handleTaskRunEvents`(主循环 select,无此问题)不一致。
**建议**:长任务端点异步化(提交+轮询/SSE);心跳并入主 select 或 WaitGroup 收敛。
### C4 工作流计划保存跨语句竞态 + completed_by 错填
`internal/projectinstance/service.go:185-190`;`internal/projectinstance/stage_store.go:132-138`
- `SaveWorkflowPlan`:upsert 与 bump revision 两条独立事务,并发下同版本号先互相覆盖 plan 再一方 bump 失败 → **版本号与 plan 内容错位落库**。`Activate` 的 token 前置校验与激活事务间存在 TOCTOU。
- `completed_by = (SELECT activated_by ...)`:最终阶段完成的归属人被错填为激活人,审计归属错误。
**建议**:upsert+bump 同事务 + `FOR UPDATE` 锁 project 行;completed_by 显式传当前操作者。
## 三、High(建议进入 short-term 整改)
| # | 发现 | 位置 | 要点 |
|---|------|------|------|
| H1 ★ | dev/test 未认证静默兜底为 user id=1 | `internal/server/auth_middleware.go:48-51` | `Env=dev|test` + `AllowInMemory` + 无 ContextDB 时,无 token 请求静默识别为 id=1(管理员)。main 已被 `validateProductionSecrets` 兜住。建议:兜底路径加审计日志+启动告警;中期删除 legacy 兜底 |
| H2 ★ | docgov 批注/审计端点无资源级鉴权且信任请求体身份 | `internal/server/handlers.go:858-940, 534-552` | 任意登录用户读任意文档批注/审计;`AddComment` 直接用 `req.UserID/UserName/UserRole` 可伪造他人身份;`Claim` 角色由客户端自选。两路审查交叉命中。建议:actor 一律取 principal;读类端点加项目成员校验 |
| H3 ★ | 会话查询类端点水平越权 | `chat_turn_api.go:12-45`;`handlers.go:947-981, 429-451` | `handleGetChatTurn`/`handleListChatSessions`/`handleGetUserContext` 的 session_id/user_id 来自 query 不校验归属;userID<=0 时默认 1(种子 admin)。建议:改用 principal 或比对不一致 403 |
| H4 | 登录/注册无速率限制 | `server.go:295-296` | 全仓无限流;bcrypt 高成本反而便于 CPU 耗尽 DoS。建议:IP+用户名滑动窗口限流 |
| H5 | SSE 任务流缺幂等前置检查 | `internal/server/sse.go:398-424` | REST 路径有 `FindByIdempotencyKey`,SSE 路径没有;EventSource 断线重连产生重复任务执行 |
| H6 | 事件 dispatcher stale-fencing 无限重放 | `internal/events/worker.go:206-275` | ErrStaleFencing 直接 cancel+return 不计 Failed;handler 半成功被回滚后事件无限重放,永不可达 dead,无告警 |
| H7 | 迁移 00001–00009 缺 down;00012 seed 迁移破坏性 DELETE | `deploy/postgres/goose/` | 前 9 个迁移无 down;00012 无条件 DELETE 30 个 session 的真实消息再插种子;多个迁移事务内 CREATE INDEX(非 CONCURRENTLY)大表会锁表 |
| H8 | compose 弱口令兜底 + main 注册默认开放 | `docker-compose.{dev,test}.yml:17,86,101`;`main.yml:101` | dev/test 的 DB/ADMIN 口令有弱默认值;main 已用 `:?required` 强制但 `AUTH_REGISTRATION_ENABLED` 默认 true。建议 test 对齐 main 必填,main 注册默认 false |
| H9 | 前端 KaTeX 占位符 XSS | `web/src/engine/renderMarkdown.ts:44-64, 106-108` | 数学公式 catch 分支把未转义原文放入占位符数组,还原发生在 escapeHtml 之后 → XSS。建议:catch 分支 escapeHtml(math) + 占位符随机化 |
| H10 | `context.Background()` 脱离请求生命周期 | `internal/chat/session.go:131-134`;`server.go:423,458,566` | LLM 摘要/DB 调用用 Background,客户端断开无法取消,慢库时 handler 挂死。建议:透传请求 ctx + WithTimeout |
## 四、Medium(选录,详见各专项)
| # | 发现 | 位置 |
|---|------|------|
| M1 | 全局缺安全响应头(CSP/nosniff/X-Frame-Options/Referrer-Policy) | `internal/server/server.go:624-636` |
| M2 | 租约 TTL 无上限(可锁文档 1000 天)+ AcquireLease 无编辑权校验 | `handlers.go:1196-1203`;`docgov/lease.go:62-70` |
| M3 | coordinator 关键词命中强制改写意图 + 模板硬编码"张工您好" | `internal/coordinator/engine.go:409-416, 485` |
| M4 | `fmt.Sscanf` 解析 `u_sess_xxx` 必然失败 → UserID=0 审计落空 | `coordinator/engine.go:930-934, 1067-1071` |
| M5 | `Runtime.Start` 被 main 与 Server.Start 双重调用且错误被吞 | `server.go:343-345`;`cmd/server/main.go:47` |
| M6 | sessions map 无硬上限,惰性清理可被随机 session_id 放大 | `server.go:451-453` |
| M7 | 修订三阶段写(账本→DocGov→freeform)无事务,靠客户端重试补偿 | `document_revision_handlers.go:274-318` |
| M8 | 测试 flag 名笔误 `FAV_PUBLISHER_ENABLE`(少 D)门闩失效 | `internal/artifactvault/publisher_gate_test.go:16` |
| M9 | dev compose 声明永不消费的 `SEMANTIC_SUMMARY_REPLACE`(诱导性配置);dev 与 test/main 默认模型不一致(M2.7-highspeed vs M3) | `docker-compose.dev.yml:119,44` |
| M10 | OpsCutover 硬编码 `"dev"`,test/main 无合规 cutover 路径 | `internal/events/cutover.go:12-19` |
| M11 | 前端乐观已读无失败回滚;MessageStream prevMsgCount 跨会话不重置;SSE 无 online 感知重连 | `web/src/hooks/useUnreadMarks.ts:176-233`;`MessageStream.tsx:148-154` |
| M12 | ExcelViewer 无行数上限内存爆炸;React 19 下 30+ 处裸 setTimeout 无清理 | `ExcelViewer.tsx:42-55` |
| M13 | `deploy/postgres/migrations/` 疑似死目录(14 个旧 SQL 无引用,与 goose 重复) | `deploy/postgres/migrations/` |
| M14 | `Orchestrator.ResolveDocTask` 静默返回 0 值三权掩盖数据不一致 | `internal/workflow/runtime/orchestrator.go:69-83` |
| M15 | PG 事件投递允许乱序而 MemoryBus 有 gap 语义——测试替身与生产行为分叉 | `internal/events/dispatcher.go:56-63` vs `bus.go:99-103` |
## 五、Low(选录)
- `handleHealth` 每请求同步两次 DB 往返无缓存无超时(`handlers.go:97-110`)
- `writeStoredEvents` json.Marshal 错误被吞(`task_run_handlers.go:437`)
- `ReplayPlan.Digest()` 不含 DryRun 字段(纵深防御,`internal/events/replay.go:24-38`)
- 前端 localStorage 缓存无版本字段;`lucide-react@^1.16.0` 版本异常需确认来源;App.tsx 4600 行/30 个 useEffect 巨石组件
- `handleRunTaskStream` 死参数 `includeDetails/requestID`(`sse.go:417-418`)
## 六、复核确认无问题的面(证据性记录)
- SQL 注入:全部 pgx 参数化;仅 4 处 fmt.Sprintf 涉 SQL 均为常量
- CORS:白名单制、无 `*`+凭证;SSE 鉴权失败返回 JSON 而非污染流
- 日志:密码 bcrypt、token SHA-256 摘要存储;`httpx.LooksInternal` 过滤内部错误串
- os/exec:bridge 路径来自服务端配置,用户输入只进 stdin payload;无 text/template 引用
- 事件系统:claim 幂等(SKIP LOCKED + fencing 复合判断)、ack+inbox+checkpoint 单事务、envelope 完整性校验、replay 审批人≠操作人——设计正确
- 前端:Mermaid strict 模式、链接 noopener、ErrorBoundary 覆盖根组件、EventSource 卸载清理正确
## 七、优先级建议
1. **进 main 前必须处理**:C1–C4、H1–H5、H8、H9(H8 的 main 注册默认开放一项)
2. **short-term 整改批**:H6、H7、H10、M1、M2、M8(一行修复恢复门闩)
3. **backlog**:其余 medium/low
## 关联整改
- Remediation: 待立项(建议按第七节优先级拆 short-term 任务)
## 证据
- `go vet ./...` 零输出;`go test -short ./...` 55 包 ok(2026-09-19,dev@e8ed33b)
- 五路只读深潜:后端 server/chat、docgov/events/工作流/迁移、前端 web、配置/flag/死代码、安全鉴权
- 任务条目:[ops/short-term/2026-09-19-system-deep-audit.md](../ops/short-term/2026-09-19-system-deep-audit.md)
## 开放问题
- dev 与 test/main 默认模型不一致(M2.7-highspeed vs M3)是否刻意?未见 `.doc/ops` 对齐记录
- `deploy/postgres/migrations/` 是否还有外部工具依赖?无则建议归档
- H1 legacy 兜底是否有仍在使用的内部工具依赖?删除前需盘点
@@ -0,0 +1,48 @@
---
title: "系统权限设置与项目协作多项缺陷排查"
status: done
created: 2026-09-20
updated: 2026-09-20
severity: high
---
# 系统权限设置与项目协作多项缺陷排查
## 现象
用户报告:成员管理勾选无效、系统设置「允许编制人兼任审核批准」400、PDF 预览被拦截、任务 runs 403 刷屏、发起编制被标 NETWORK_ERROR、注册/建号 rollback、改密后刷新再强制改密、退出重登出现同名重复项目、无项目仍可对话、右侧工具栏默认展开且不记忆。
## 根因分析
| # | 根因 | 关键路径 |
|---|------|----------|
| 1 | CSP 缺 `frame-src`,blob iframe fallback 到 `default-src 'self'` | `internal/server/cors.go` |
| 2 | PdfViewer 同源 iframe 直连,触发 `X-Frame-Options: DENY` 原生拦截页 | `web/src/components/doc/preview/renderers/PdfViewer.tsx` |
| 3 | 前端未传 `expected_revision`(该 key 后端强制 CAS) | `web/src/api/systemAdmin.ts` / SettingsSection |
| 4 | `ProjectSettingsApiError` 字段名与消费方 `httpStatus`/`errorCode` 不一致 | `web/src/api/projectSettingsError.ts` |
| 5 | task-run view 仅放行创建者/owner;前端 403 无停止轮询 | `task_run_auth.go` / `App.tsx` |
| 6 | `CanManageProjectMembers` 未读细粒度权限位 | `internal/authz/service.go` |
| 7 | memStore `ListProjectsForUser` 忽略成员表 | `internal/projectworkflow/store.go` |
| 8 | `user_role_bindings` 插入吞错 → commit rollback;handler 一律 400 | `internal/auth/pg_store.go` |
| 9 | 嵌套 `user.mustChangePassword` OR 合并复活 + fetchMe 未回写 session | `authUserMap.ts` / WorkbenchView / useAuthenticatedWorkspaceSync |
| 10 | `projects.name` 无唯一约束 + Create 无幂等键;logout 不清 projects 缓存 | `service.go` / migration 00056 / App logout |
| 11 | `Project()<=0` 时跳过项目访问校验 | `handlers.go` / `sse.go` / `stage_access_helpers.go` |
| 12 | `rightCollapsed` 默认 false 且无持久化 | `AppShell.tsx` / `storage.ts` |
## 严重度
`high`
## 关联整改
- Short-term: `.doc/ops/short-term/2026-09-20-bug-hunt-permissions-uploads.md`
- 分支: `fix/bug-hunt-2026-09-20-permissions-and-uploads`
## 证据
- 产品决策:新增 `project:manage_members`;无项目禁止对话并置灰发送按钮;同创建人内项目名唯一 + `client_key` 幂等。
- 迁移:`00055_...project-manage-members-permission.sql`、`00056_...project-create-idempotency.sql`
## 开放问题
- 无(本批范围内)
+11
View File
@@ -13,6 +13,14 @@
## 核心文档(按阅读顺序推荐)
### 可选职责空审核人 CreateOrGetDocument FK(2026-09-17)
**文件**: [2026-09-17-docgov-optional-duty-null-fk.md](./2026-09-17-docgov-optional-duty-null-fk.md)
**结论**: 无 reviewer 职责时 `CreateOrGetDocument` 写 `reviewer_id=0` 触发 FK,被 `ClassifyError` 掩盖为 `INTERNAL_ERROR`;heal 路径已有 `nullIfZero`,创建路径漏改。
**整改**: [short-term](../archive/ops/2026-09-17-docgov-optional-duty-null-fk.md) · branch `fix/docgov-optional-duty-null-fk`
### FEATURE-MATRIX production-ready 连续性审计(2026-09-16)
**文件**: [2026-09-16-feature-matrix-production-readiness-audit.md](./2026-09-16-feature-matrix-production-readiness-audit.md)
@@ -464,3 +472,6 @@ Day 4-5: Phase C 完善与发布准备(20h)
---
*本索引最后更新于 2026-09-12 15:05 UTC*
- 2026-09-17:[系统全面体检](2026-09-17-system-health-check.md)(任务收口 / 缺陷 / 未启用功能;配套 [整改方案](../remediation/2026-09-17-system-health-remediation-plan.md) Wave0–7)。
- 2026-09-17:[首次加载性能诊断与改进](2026-09-17-initial-load-performance-audit.md)(三入口重启首访;U2 已验收,主 JS ~624 KB;U1/U3–U7 待实施)。
+7 -7
View File
@@ -43,7 +43,7 @@ AuthN column is **heuristic**; negative-test pointers filled where known.
| POST | `/api/v1/auth/register` | `s.handleAuthRegister` | `server.go` | handler | see suite |
| GET | `/api/v1/auth/sessions` | `s.handleAuthSessions` | `server.go` | handler | see suite |
| DELETE | `/api/v1/auth/sessions/{id}` | `s.handleAuthSessionByID` | `server.go` | handler | see suite |
| POST | `/api/v1/chat` | `s.handleChat` | `server.go` | session+project | see suite |
| POST | `/api/v1/chat` | `s.handleChat` | `server.go` | session+project (ERR_NO_PROJECT if unbound + zero memberships) | see suite |
| GET | `/api/v1/chat/categories` | `s.handleListChatCategories` | `server.go` | session+project | see suite |
| GET | `/api/v1/chat/dates` | `s.handleListChatDates` | `server.go` | session+project | see suite |
| GET | `/api/v1/chat/digests` | `s.handleListDailyDigests` | `server.go` | session+project | see suite |
@@ -60,8 +60,8 @@ AuthN column is **heuristic**; negative-test pointers filled where known.
| GET | `/api/v1/chat/search` | `s.handleChatSearch` | `server.go` | session+project | see suite |
| GET | `/api/v1/chat/sessions` | `s.handleListChatSessions` | `server.go` | session+project | see suite |
| POST | `/api/v1/chat/sessions` | `s.handleUpsertChatSession` | `server.go` | session+project | see suite |
| GET | `/api/v1/chat/stream` | `s.handleChatStream` | `server.go` | session+project | see suite |
| POST | `/api/v1/chat/stream` | `s.handleChatStream` | `server.go` | session+project | see suite |
| GET | `/api/v1/chat/stream` | `s.handleChatStream` | `server.go` | session+project (ERR_NO_PROJECT if unbound + zero memberships) | see suite |
| POST | `/api/v1/chat/stream` | `s.handleChatStream` | `server.go` | session+project (ERR_NO_PROJECT if unbound + zero memberships) | see suite |
| GET | `/api/v1/chat/turns/{client_turn_id}` | `s.handleGetChatTurn` | `server.go` | session+project | see suite |
| GET | `/api/v1/chat/unread` | `s.handleChatUnread` | `server.go` | session+project | see suite |
| GET | `/api/v1/context/cases/recommend` | `s.handleRecommendCases` | `server.go` | handler | see suite |
@@ -131,10 +131,10 @@ AuthN column is **heuristic**; negative-test pointers filled where known.
| GET | `/api/v1/tasks/run/stream` | `s.handleRunTaskStream` | `server.go` | session+project | see suite |
| POST | `/api/v1/tasks/run/stream` | `s.handleRunTaskStream` | `server.go` | session+project | see suite |
| POST | `/api/v1/tasks/runs` | `s.handleCreateTaskRun` | `server.go` | session+project | see suite |
| GET | `/api/v1/tasks/runs/{run_id}` | `s.handleGetTaskRun` | `server.go` | session+project | see suite |
| POST | `/api/v1/tasks/runs/{run_id}/cancel` | `s.handleCancelTaskRun` | `server.go` | session+project | see suite |
| GET | `/api/v1/tasks/runs/{run_id}/events` | `s.handleTaskRunEvents` | `server.go` | session+project | see suite |
| POST | `/api/v1/tasks/runs/{run_id}/resume` | `s.handleResumeTaskRun` | `server.go` | session+project | see suite |
| GET | `/api/v1/tasks/runs/{run_id}` | `s.handleGetTaskRun` | `server.go` | session+project member (view) | see suite |
| POST | `/api/v1/tasks/runs/{run_id}/cancel` | `s.handleCancelTaskRun` | `server.go` | session+run owner or project owner | see suite |
| GET | `/api/v1/tasks/runs/{run_id}/events` | `s.handleTaskRunEvents` | `server.go` | session+project member (view) | see suite |
| POST | `/api/v1/tasks/runs/{run_id}/resume` | `s.handleResumeTaskRun` | `server.go` | session+run owner or project owner | see suite |
| GET | `/api/v1/workflow-instances/{id}` | `s.handleGetWorkflowInstance` | `server.go` | session+project | see suite |
| POST | `/api/v1/workflow-instances/{id}/stages/{stage}/advance` | `s.handleAdvanceStage` | `server.go` | session+project | see suite |
| GET | `/api/v1/workflow-instances/{id}/stages/{stage}/readiness` | `s.handleGetStageReadiness` | `server.go` | session+project | see suite |
@@ -0,0 +1,75 @@
# rdev 研发工作流二期增强 Backlog
> 来源:[07-研发工作流rdev接入-设计与实施计划](../system-design/project-workflow/07-研发工作流rdev接入-设计与实施计划.md) §8 决策 3——首期 N/A 采用「激活规划期关闭」,以下增强项不阻塞首期交付,**用户要求记录以便随时续推进**。
> 创建:2026-09-17。每项建议独立 short-term 任务认领。
## 优先级排序(建议)
### R1 N/A 不适用页生成模式(对齐参考项目行为)
- 现状:skippable 任务在激活规划期由创建者关闭 = 不适用;
- 目标:保留任务但可生成「不适用说明页」(完整论述理由而非一句话),仍走审核/批准,再进入下一阶段(参考项目 rdev_software overlay 语义);
- 涉及:manifest 不适用模式标记、bizdev 执行 N/A 生成路径、squad N/A 编排、前端规划 UI「保留但声明不适用」选项;
- 验收:软件类任务声明不适用 → 生成完整不适用页 → 审批通过 → 阶段可推进。
### R2 UR/RS 结构化质量门禁(复用 PM requirements.json 模式)
- **状态**:✅ **done**(2026-09-19)— `rd_user_needs` / `rd_system_reqs` 在 `QualityGate.Validate` 中检查连续编号、禁止随机抽取、验证准则与正文/JSON 一致。`pm` 的 `system_reqs` 仍走原有检查。
- 范围:`rd_user_needs`、`rd_system_reqs`(及 `pm_system_reqs`)输出结构化需求集合;确定性门禁:ID 唯一连续、不随机抽取、缺验证准则拒绝、正文/JSON 不一致拒绝;
- 参考先例:`quality.system_reqs.v2`。
### R3 review_minutes / upload_index 专用确定性门禁
- **状态**:✅ **done**(2026-09-19)— 评审记录拒绝空洞「同意通过」;附件清单要求索引表与影响分析。`TestRDevQualityGates`。
- review_minutes(6 个评审记录):问题-决议-行动项闭环检查(拒绝空洞「同意通过」、行动项无责任人/期限);
- upload_index(7 个附件清单):附件索引表存在性、缺失影响分析存在性检查;禁止伪造附件内容靠 Accept 纪律 + 门禁抽查「待上传后更新」结论。
### R4 depends_on 精确血缘与 stale 传播
- 现状:rd 任务 prior docs 全量注入 + 摘要级血缘;
- 目标:per-task upstream 声明表(对齐参考项目 rdev.yaml depends_on:rd_planning_review ← rd_proposal+rd_design_plan、rd_verification_review ← rd_design_vv+rd_risk_report_v 等),上游新版本批准 → 下游 stale 且不能完成;
- 参考先例:test_manager 对 approved SR 的 stale 传播(projectworkflow/service.go)。
### R5 DMR 双记录归档
- 参考项目 `records: [dhf, dmr]` 的设计输出/转换文档在本仓库无对应物;需评估文档「记录归属」字段扩展 + 归档/导出按 DHF/DMR 分类(本仓库无云盘,先落 docgov 元数据与导出分类)。
### R6 软件工作流任务键 `sw_` 前缀盘点(并入 P4 或其后)
- `software_bootstrap`/`software_delivery`(executor `software.doc.v1`)任务键盘点并纳入统一命名空间规约(D12 的遗留尾巴)。
### R7 高复杂度 regulatory 步注入策略
- 现状:D7 中 regulatory 按任务清单静态注入;目标:接 `complexity_tier`(complexity_high/medium 分层)动态注入,对齐参考项目 `when: complexity_tier=high`。
## 依赖关系
- R2/R3 可并行;R4 依赖 manifest 落地后的 upstream 声明表;R1 独立;R5/R6/R7 低优先级。
---
## 模板深度与运行时续批(S1 续批 / S2 / S3)
> 来源:Kimi 分析方案 + [2026-09-17-rdev-template-depth](../archive/ops/2026-09-17-rdev-template-depth.md) 收口。S0 + S1 首批(14 份)已交付;以下不阻塞本轮合并候选。
### S1 续批 — 剩余模板专业章节
- **状态**:✅ **done**(2026-09-17)— 46 份全部同等深度补强;allowlist 60/60;真 PI `rd_planning_review` + `rd_design_vv` PASS
- **证据**:[测试报告](../test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md);[short-term](../ops/short-term/2026-09-17-rdev-template-depth-s1-continued.md)
### S2 — 运行时编排与配置化
- **状态**:✅ **done**(2026-09-19,`fix/audit-remainder-closeout`)
- per-stage 步骤覆盖(相对默认 organize→engineer→draft→review 的阶段差异)
- regulatory 步接 `complexity_tier`(与 R7 可合并认领)
- 模型去硬编码(配置/环境驱动)
- manifest hint + aliases 元数据补齐
- **证据**:`TestRDevRegulatoryFollowsComplexityTier`、`TestRDevModelFromEnv`、`TestRDevStageOverrideAndAliases`
### S3 — overlay 与质量门禁扩面
- **状态**:部分(2026-09-19)。overlay 与 R2/R3 已落地;P3 真 PI 未做
- 轻量 overlay 机制(模板管结构;overlay/运行时管纪律与粒度下限)— done,`configs/overlays/`,`TestRDevWorkspaceWritesOverlay`
- R2/R3 专用确定性门禁落地 — done,`TestRDevQualityGates`
- P3:三样本真 PI E2E 报告 + CI 四工作流门禁挂钩 — 未做
+2 -2
View File
@@ -5,6 +5,6 @@
- **B5** 报价模块接入轻量复核与输入范围校验(`internal/quote/`)
- **A5/A6** 小队工作流支持非关键步骤降级;并行 trace 序号改单次加锁读-算-写(`internal/squad/`)
- **A7** 将中文注释中的已知限制迁移为正式 issue
- **D3** 摘要引擎替换为语义摘要(依赖模型接入,需单独评估)(`internal/ctxmgr/summarizer.go`)
- **D3**(已实现,shadow)摘要引擎语义摘要能力已落地:`SEMANTIC_SUMMARY_SHADOW` 默认 off,见 [FEATURE-MATRIX「语义摘要(D3)」行](../status/FEATURE-MATRIX.md)、[PU6 契约](../ops/long-term/2026-09-16-pu6-semantic-summary-contract.md)(`status: done`)、[W2 真 PI 报告](../test-reports/2026-09-17-w2-semantic-summary-shadow-test-report.md)。`SEMANTIC_SUMMARY_REPLACE` 仍未接线(红线,需独立授权)。本行状态转入 FEATURE-MATRIX 常态跟踪,不再作为独立 backlog 开放项
- **D5** 知识库按环境隔离方案评估(当前三环境共享 KB 为 intentional 架构)
- **D7** 对话数据留存期限与敏感字段加密(先对齐合规再定技术方案)
- **D7** 对话数据留存期限与敏感字段加密——草案 ADR [2026-09-17-d7-chat-data-retention.md](../adr/2026-09-17-d7-chat-data-retention.md)(`compliance: pending-compliance-signoff`);[W7 只读盘点](../audit/2026-09-17-d7-data-inventory.md) 未发现基线违规,见 [报告](../test-reports/2026-09-17-w7-d7-inventory-test-report.md)。签字前禁止按 365/180/30 物理删除;本行继续跟踪合规签字进度
@@ -0,0 +1,22 @@
---
title: "dev 试点:开放编制人兼任总开关"
status: done
created: 2026-09-17
updated: 2026-09-17
---
# dev 试点:开放编制人兼任总开关
## 结论
在运行中的 `agent-dev`(`:8080`,schema 52)经 admin CAS 将 `workflow.allow_author_only_approval` 设为 `true`(revision `0 → 1`)。**未**改默认迁移值;**未**晋升 test/main;test/main 仍保持默认 off。
## 证据(脱敏)
- [before-enable.json](../../test-reports/assets/2026-09-17-author-only-pilot/before-enable.json)
- [put-enable.txt](../../test-reports/assets/2026-09-17-author-only-pilot/put-enable.txt)
- [after-enable.json](../../test-reports/assets/2026-09-17-author-only-pilot/after-enable.json)
## 关联
- author-only 收口:[../handoffs/2026-09-17-document-author-only-closeout.md](../handoffs/2026-09-17-document-author-only-closeout.md)
+60 -13
View File
@@ -1,20 +1,64 @@
# 当前焦点
**更新**: 2026-09-16
**production_ready**: yes(门禁 B1–B4 已签;dev/test/main `schema_version=47`。不把 fallback change report 写成完整 PI)
**更新**: 2026-09-20
**production_ready**: yes(门禁 B1–B4 已签;dev/test schema 53,main schema 52。不把 fallback change report 写成完整 PI)
## 焦点
1. **全量 backlog 覆盖 no-go**:P0–P7 总控实施中([short-term](./short-term/2026-09-16-full-backlog-override.md))
2. **运维**:Gitea nightly runner 已通;待 P1 对齐 `DATA_DIR=dev` 后冲 green receipt
3. **红线**:禁止整支 merge FAV;不默认升 `MULTI_INTENT_PLAN_TIER=full`;项目 143 只读
1. **2026-09-20 dev→test 晋升完成 (rc-v1.0.0-beta.5)**:已合入 fix/audit-remainder-closeout,完成全量深度测试(Go 短测 46 包全绿、Vite 前端构建/测试通过、治理 PG 集成通过、运行时端点/安全响应头通过)。已合入 test 分支并重建测试环境服务(端口 :8081,schema 53 healthy)。
2. **2026-09-19 审计整改批 1–4 done**(合入 `844f757` / `08f4e0b` / `a2a49a6` / `d73bc79`)。dev 已 rebuild 到 schema 53。余项见 [long-term](./long-term/2026-09-19-audit-remainder.md)。
3. **Control Center 已移出本仓库**:项目进度由独立统一管理系统承担;本仓库恢复为智能体系统。见 [任务](./short-term/2026-09-19-remove-control-center.md)
4. **rdev 模板深度 / document-author-only**:已合入 `origin/dev` 及 `test`
5. **红线**:禁止整支 merge FAV;不默认升 `MULTI_INTENT_PLAN_TIER=full`;`SEMANTIC_SUMMARY_REPLACE` 不随 W2 开启;FAV live 观察窗证据驱动;`FAV_DEGRADED_READ=false`;项目 143 只读;SWBOOT-10 保持 fail-closed stub;D7 待合规签字
## 并行认领
| owner | task | branch | worktree | mutex | status |
|-------|------|--------|----------|-------|--------|
| Cursor-Auto | 2026-09-16-software-project-bootstrap | feature/software-project-bootstrap | .worktrees/feature-software-project-bootstrap | workflow-design | done |
| Cursor | 2026-09-16-full-backlog-override | docs/override-nogo-full-backlog | - | architecture-docs | in_progress |
| Cursor-Auto | 2026-09-20-bug-hunt-permissions-uploads | fix/bug-hunt-2026-09-20-permissions-and-uploads | - | authz+web+projectworkflow | done |
| Cursor | audit-b1-data-consistency | fix/audit-b1-data-consistency | - | docgov+workflow+chat | done |
| Cursor | audit-b2-authz-hardening | fix/audit-b2-authz-hardening | - | authz | done |
| Cursor | audit-b3-sse-events | fix/audit-b3-sse-events | - | chat+events | done |
| Cursor | audit-b4-frontend | fix/audit-b4-frontend | - | web | done |
| Cursor-Auto | 2026-09-19-audit-remainder-closeout | fix/audit-remainder-closeout | - | audit-remainder | done |
| Antigravity | 2026-09-20-dev-deep-test-and-promotion | feature/dev-deep-test-and-promotion | - | integration | done |
| Cursor-Auto | 2026-09-19-remove-control-center | fix/remove-control-center | - | controlcenter | done |
| Cursor-Auto | 2026-09-17-control-center-server | feature/control-center-server | - | controlcenter | cancelled |
| Kimi | 2026-09-18-user-manual | feature/user-manual | .worktrees/feature-user-manual | docs | done |
| Cursor-Auto | 2026-09-18-wave7-roadmap-orchestration | docs/wave7-roadmap-orchestration | - | roadmap-orchestration | done |
| Cursor-Auto | 2026-09-18-wave6-doc-drift | docs/wave6-doc-drift | - | doc-drift | done |
| Cursor-Auto | 2026-09-18-wave5-deadcode-decisions | fix/wave5-deadcode-decisions | - | deadcode-cleanup | done |
| Cursor-Auto | 2026-09-18-wave4-hardening-r1-r8 | fix/wave4-hardening-r1-r8 | - | hardening | done |
| Cursor-Auto | 2026-09-18-wave3-test-debt-blindspots | fix/wave3-test-debt-blindspots | - | test-debt | done |
| Cursor-Auto | 2026-09-18-wave2-config-flag-align | fix/wave2-config-flag-align | - | infra | done |
| Cursor | 2026-09-18-wave1-main-env-fix | fix/wave1-main-env-fix | - | infra | done |
| Cursor | 2026-09-18-wave0-p0-bug-fixes | fix/wave0-p0-sse-chat-cache-bugs | - | chat + web | done |
| Kimi | 2026-09-17-system-health-check(只读审计,未实施) | - | - | audit | done |
| Cursor | 2026-09-17-docgov-modification-proposal-http | feature/docgov-modification-proposal-http | - | docgov | done |
| Cursor | 2026-09-17-document-author-only-closeout | feature/document-author-only-plan | - | document-duty-policy | done |
| Cursor | 2026-09-17-rdev-template-depth-s1-continued | feature/rdev-template-depth-s1-continued | .worktrees/feature-rdev-template-depth-s1-continued | rdev-templates | done |
| Cursor | 2026-09-17-rdev-workflow-integration | feature/rdev-core | - | workflow-def | done |
| Cursor | 2026-09-17-rdev-template-depth | feature/rdev-template-depth | .worktrees/feature-rdev-template-depth | rdev-templates | done |
| Codex | 2026-09-17-document-author-only-plan | feature/document-author-only-plan | - | document-duty-policy-plan | done |
| Cursor | 2026-09-17-initial-load-perf-u2 | feature/initial-load-perf-u2 | - | web + static-delivery | done |
| Codex | 2026-09-17-initial-load-performance-plan | feature/initial-load-performance-plan | .worktrees/feature-initial-load-performance-plan | loading-performance-audit | done |
| Kimi | 2026-09-17-system-admin-console | feature/system-admin-console | - | web + sysadmin | done |
| Cursor-Auto | 2026-09-17-engineering-dashboard | feature/engineering-dashboard | .worktrees/feature-engineering-dashboard | engineering-dashboard | done |
| Cursor | 2026-09-17-promote-null-fk-to-test | feature/promote-null-fk-to-test | - | infra | done |
| Cursor | 2026-09-17-docgov-optional-duty-null-fk | fix/docgov-optional-duty-null-fk | - | docgov | done |
| Cursor | 2026-09-17-leftover-hygiene | chore/leftover-hygiene-2026-09-17 | - | ops | done |
| Cursor | 2026-09-17-w2-semantic-summary-shadow | feature/w2-semantic-summary-shadow-live | - | chat | done |
| Cursor | 2026-09-17-w3-pi-change-report-narrative | feature/w3-pi-change-report-narrative-live | - | docgov | done |
| Cursor | 2026-09-17-w4-multi-intent-u9-u12 | feature/w4-u9-segment-live | - | intent-plan | done |
| Cursor | 2026-09-17-w5a-software-bootstrap-ui | feature/w5a-software-bootstrap-ui-pi | - | workflow-design | done |
| Cursor | 2026-09-17-w6-fav-subscriber-shadow | feature/w6-fav-subscriber-shadow | - | events | done |
| Cursor | 2026-09-17-w7-d7-inventory | feature/w7-d7-data-inventory | - | chat | done |
| Cursor | 2026-09-17-promote-dev-to-test | feature/promote-dev-to-test-2026-09-17 | - | infra | done |
| Cursor | 2026-09-17-kb-host-auth-fix | fix/kb-host-auth-layered-load | - | infra | done |
| Cursor | 2026-09-17-w1-ci-e2e-green-nightly | feature/w1-ci-e2e-green-nightly | - | ci | done |
| Cline | 2026-09-16-partial-deferred-completion | docs/partial-deferred-completion-plan | - | architecture-docs | in_progress |
| Cursor | 2026-09-16-intent-plan-playwright-dual-tab | feature/intent-plan-cards-playwright | .worktrees/feature-intent-plan-cards-playwright | web | done |
| Cursor | 2026-09-16-full-backlog-override | docs/override-nogo-full-backlog | - | architecture-docs | done |
| Cursor | 2026-09-16-gitea-nightly-docker-datadir | fix/gitea-nightly-docker-datadir | - | ci | done |
| Cursor | 2026-09-16-gitea-nightly-host-tools | fix/gitea-nightly-host-tools | - | ci | done |
| Cursor | 2026-09-16-wave-leftovers | fix/wave-leftovers-n7-playwright-dod | - | ci | done |
@@ -102,13 +146,13 @@
> workflow-plan 409 与治理鉴权 G1–G5 已收口(见 [test-report](../test-reports/2026-09-14-governance-action-level-authz-test-report.md))。禁止终止或改写项目 143。
> `document-reliability-pilot` U11–U12 已合入 `dev@bf59cce` 并 rebuild。`CHAT-INTENT-STATE` 双标签 busy 已 PASS(项目 6275)。禁止 worktree 内 `env-service`。项目 143 只读,禁止终止。
> 2026-09-15 旁支清理:[报告](../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md)。已合入本地旁支 31 条已 `git branch -d`;7 个对应 worktree 已拆。extra worktree 仅余 `.worktrees/fix-dev-runtime-data-root-guard`(目录名是 guard,检出的是 `feature/final-artifact-vault`)。**故意不合入、不删**:`feature/final-artifact-vault`、`feature/remove-herdr-agent-settings`、`fix/project143-controlled-content-404-diagnosis`、`fix/dev-runtime-data-root-guard`、`dev-old-linear`。不删 `origin/*`。不整支 merge FAV;不启用 `FAV_DEGRADED_READ`。
> 2026-09-17 leftover 二次收口:[报告](../test-reports/2026-09-17-leftover-hygiene-test-report.md)。已合入 leftover worktree/旁支再拆一轮;`feature/software-project-bootstrap` L1 已在 `dev`(残留关闭 commit 已丢弃)。`fix/clean-test-env-baseline` **不 merge**(前端 demo 清理已放弃;仅保留已挑拣的 `SEED_DEMO_USERS=false`)。extra worktree 仅余 `.worktrees/fix-dev-runtime-data-root-guard`(目录名是 guard,检出的是 `feature/final-artifact-vault`)。**故意不合入、不删**:`feature/final-artifact-vault`、`feature/remove-herdr-agent-settings`、`fix/project143-controlled-content-404-diagnosis`、`fix/dev-runtime-data-root-guard`、`dev-old-linear`。不删 `origin/*`。不整支 merge FAV;不启用 `FAV_DEGRADED_READ`。
## 集成槽位
| holder | phase | since | scope | queue |
|--------|-------|-------|-------|-------|
| - | idle | - | - | - |
| - | idle | 2026-09-20 | dev 深度测试全绿;已晋升 test (rc-v1.0.0-beta.5) 并重建测试环境;test 与 dev 均为 schema 53 healthy | - |
**phase**: `idle` | `merging` | `smoke` | `e2e`
@@ -118,9 +162,9 @@
| 环境 | 端口 | schema | 状态 |
|------|------|--------|------|
| dev | 8080 | **47** | healthy(`pi-agent` typed-result-v1;events worker `:8088`;notify/advance/projection live、fav off;health+ready PASS;demo 6001–6010 retired) |
| test | 8081 | **47** | healthy(`rc-v1.0.0-beta.2`;pi-agent `:18866`;events `:8089`;notify/advance/projection live、fav off;health+ready PASS;矩阵深度测试 live 项目 3 PASS) |
| main | 8000 | **47** | healthy(app + events + runner + DB;与 dev/test 对齐) |
| dev | 8080 | **53** | healthy(2026-09-19 `fix/audit-remainder-closeout` rebuild;goose `00053` `document_content_projections`;入口 `index-DOO0-Yh7.js`;`pi-agent`;events `:8088`) |
| test | 8081 | **53** | healthy(2026-09-20 `rc-v1.0.0-beta.5` rebuild;goose `00053`;入口 `index-C5YTF8ik.js`;pi-agent `:18866`;events `:8089`) |
| main | 8000 | **52** | healthy(`env=main` app+events 对齐;events 先 healthy 后启 app;consumer modes 全 off;Wave 1 已验证) |
## SSOT
@@ -131,6 +175,9 @@
| 发布缺口 | [gap-matrix](../remediation/gap-matrix.md)(`production_ready=yes`;Wave 0 IAM 只读未发现旁路) |
| 连续性审计/计划 | [audit](../audit/2026-09-16-feature-matrix-production-readiness-audit.md) · [remediation](../remediation/2026-09-16-feature-matrix-production-readiness-plan.md) · [Wave 0 任务](./short-term/2026-09-16-feature-matrix-wave0-calibration.md) |
| 测试报告 | [test-reports/](../test-reports/) |
| dev→test 晋升前复核 | [research](./research/2026-09-19-pre-test-promotion-review.md)(2026-09-19 只读;静态门禁过,容器未 rebuild,暂不合并) |
| D7 盘点(W7) | [audit](../audit/2026-09-17-d7-data-inventory.md) · [报告](../test-reports/2026-09-17-w7-d7-inventory-test-report.md) · ADR 仍 `pending-compliance-signoff` |
| Wave 7 编排确认 | [决策记录](./short-term/2026-09-18-wave7-roadmap-orchestration.md) |
| Agent 手册 | [AGENTS.md](../../AGENTS.md) |
| 意图双标签 busy 交接 | [./handoffs/2026-09-15-conversation-intent-dual-tab.md](./handoffs/2026-09-15-conversation-intent-dual-tab.md) |
| 受控正文 hash 漂移 W1–W6 | [../ops/handoffs/2026-09-14-controlled-content-canonical-hash.md](../ops/handoffs/2026-09-14-controlled-content-canonical-hash.md) |
@@ -160,7 +207,7 @@
| 文档可靠性 M5/M6 U11–U12 | [../test-reports/2026-09-15-app-composition-u11-u12-test-report.md](../test-reports/2026-09-15-app-composition-u11-u12-test-report.md) |
| Track E E2 闭包守卫 | [../test-reports/2026-09-15-event-e2-hook-guard-test-report.md](../test-reports/2026-09-15-event-e2-hook-guard-test-report.md) |
| Track E 复盘 | [./research/2026-09-15-track-e-retrospective.md](./research/2026-09-15-track-e-retrospective.md) |
| 旁支清点收口 | [../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md](../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md) |
| 旁支清点收口 | [../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md](../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md) · [二次收口](../test-reports/2026-09-17-leftover-hygiene-test-report.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) |
@@ -65,3 +65,13 @@ curl -sf http://127.0.0.1:8080/ready
- CURRENT: [CURRENT.md](../CURRENT.md)
- Task: [../short-term/2026-09-13-conversation-intent-runtime-state.md](../short-term/2026-09-13-conversation-intent-runtime-state.md)
- 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)
## 回标(2026-09-18,Wave 6 文档漂移修复)
上方「未完成」与「认领 / 槽位状态」两节是 2026-09-15 交接时刻的快照,**已在同一提交(`8a8f64a`)内被后续证据覆盖**:
- 浏览器双标签刷新恢复 / busy 租约可见性:项目 6275、`sess-p6275-u10` 真实 PI + Docker 截图(`dual-tab-live.py`、`live.json`、`window-before-refresh.json`、`window-after-refresh.json`、`screenshots/tab-b-after-reload.png` 等,均在同一提交归档)。
- `CHAT-INTENT-STATE` 已在 [gap-matrix](../../remediation/gap-matrix.md) 标记 **PASS**(「双标签活验项目 6275 / `sess-p6275-u10`」)。
- mutex 已释放:CURRENT.md 当前无该任务 `in_progress` 行;集成槽位 holder 为 `idle`。
**结论**:本 handoff 无待办事项,`status: closed` 生效,仅为历史记录保留原文,不删除。
@@ -0,0 +1,40 @@
---
title: "document-author-only U1–U6 收口交接"
status: done
created: 2026-09-17
updated: 2026-09-17
from: Cursor
to: integrator
---
# document-author-only U1–U6 收口交接
## 结论
实现与验收任务已全部收口:U1–U6 short-term 已迁入 `archive/ops/`;FEATURE-MATRIX / remediation DoD(除发布末条)已更新;U6 报告已归档。
**远端**:已 `git-push-dev.sh` 推送 `origin/dev`(含 author-only merge);**未**晋升 test/main。
**dev 试点**:`workflow.allow_author_only_approval=true`(revision 1);证据见 [pilot assets](../../test-reports/assets/2026-09-17-author-only-pilot/) 与 [ops 笔记](../2026-09-17-author-only-pilot-toggle.md)。
## 分支
- `feature/document-author-only-plan` — 已合入并清理 worktree/本地分支
- 续作:`feature/docgov-modification-proposal-http`(变更提案 HTTP)
## 合入 `dev`(已完成)
- `merge --no-ff feature/document-author-only-plan` → 后续推送至 `origin/dev@ba92a8b` 一带
- 冒烟:`go vet` / `go test -short` 相关包 PASS;`./scripts/env-service.sh dev rebuild`;`GET /health` → `schema_version=52`、`status=ok`
- 总开关默认迁移值仍为 off;**dev 运行态**已 CAS 试点开启;**未**晋升 test/main
## 明确不在本期(已转入续作)
- ~~变更提案 HTTP 路由~~ → [short-term](../short-term/2026-09-17-docgov-modification-proposal-http.md) / [audit resolved](../../audit/2026-09-17-docgov-modification-proposal-http-gap.md)
- test/main 晋升仍另授
## 证据
- [U6 报告](../../test-reports/2026-09-17-document-author-only-u6-test-report.md)
- [方案 DoD](../../remediation/2026-09-17-document-author-only-plan.md)
- [pilot](../../test-reports/assets/2026-09-17-author-only-pilot/)
@@ -2,7 +2,7 @@
title: "纯软件项目自举工作流实施"
status: in_progress
created: 2026-09-14
updated: 2026-09-16
updated: 2026-09-17
---
# 纯软件项目自举工作流实施
@@ -22,18 +22,18 @@ updated: 2026-09-16
- 真实 PI 和 Ubuntu 无头浏览器黄金项目验收通过;
- 未实现受控代码执行前,系统不会直接修改项目仓库。
## 实施进度(2026-09-16)
## 实施进度(2026-09-17)
| Epic | 状态 | 说明 |
|------|------|------|
| SWBOOT-00 | done(契约) | ADR `.doc/adr/2026-09-16-software-project-bootstrap-keys.md` |
| SWBOOT-01 | done(迁移) | goose `00048` additive;活验待集成槽 |
| SWBOOT-02..04 | done(L1) | manifests + catalog 五 key;医疗三门禁保留 |
| SWBOOT-05..08 | partial | 后端 catalog/creation-preview/create 字段;七步 UI / 对话路由未做 |
| SWBOOT-09 | partial | L1 单测报告已出;真实 PI/UI NOT RUN |
| SWBOOT-10 | stub only | allowlist + fail-closed;无真实 patch/merge |
| SWBOOT-01 | done(迁移) | goose `00048` additive;已合 `dev` |
| SWBOOT-02..04 | done(L1) | manifests + catalog 五 key;医疗三门禁保留;已合 `dev`(`f0029df`) |
| SWBOOT-05..08 | done(W5a) | catalog 驱动创建向导;软件不克隆医疗 7 模板;solo 未独立评审标注 |
| SWBOOT-09 | partial | docs_only 真实 PI 已出;无头浏览器全向导仍 NOT RUN |
| SWBOOT-10 | stub only | allowlist + fail-closed;真 patch/merge 归 W5b,本轮不实施 |
分支:`feature/software-project-bootstrap`(**未合 dev**)。
L1(SWBOOT-00…09 契约/迁移/目录钩子 + SWBOOT-10 stub)**已合入 `dev`**。后续由 [partial/deferred W5](../short-term/2026-09-16-partial-deferred-completion.md) 承接:W5a = UI + `docs_only` 真实 PI;W5b = 受控执行器(独立安全评审)。
## 实施拆分
@@ -59,9 +59,11 @@ updated: 2026-09-16
- 文档版本运行时 Round20 能力作为文档链基线;
- 用户确认首期执行模式及 solo/collaborative 策略。
## 暂不启动原因
## 剩余工作
本轮用户要求先梳理和制定详细方案;业务代码、迁移、模板和智能体配置尚未授权进入实施。本任务保持 `planned`,启动时须从 `dev` 新建独立 feature 分支,并在 CURRENT 认领 `workflow-design`/相应拆分 mutex。
L1 已合 `dev`。W5a 从 `dev` 开 `feature/w5a-software-bootstrap-ui-pi`(mutex `workflow-design`)。W5b 受控执行器未启动,SWBOOT-10 保持 fail-closed stub。
**Wave 5 X-3(2026-09-18)**:goose 00048 三表(`project_types` / `compliance_profiles` / `project_type_workflows`;另含零读者的 `project_source_bindings` / `repo_path_allowlist`)消费方接线评估结论 = **deferred → SWBOOT-10/W5b**。不改 schema;API 继续硬编码目录。决策落点:[wave5-deadcode-decisions.md#x-3](../short-term/2026-09-18-wave5-deadcode-decisions.md#x-3)。不阻塞 W5b 立项。
## 相关链接
@@ -1,9 +1,9 @@
---
title: "Playwright intent-plan 双标签 — 长期 gated"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
owner: Cursor-Auto
branch: feature/intent-plan-cards-playwright
mutex: web
---
@@ -12,9 +12,9 @@ mutex: web
## 现状
- `web/e2e/intent-plan-cards.spec.ts`:`test.skip` unless `RUN_UI_ACCEPTANCE=1`;仅 body visible 骨架。
- Conversation-intent 双标签已有 live 证据(项目 6275);**不等于** intent-plan confirm 双标签。
- Wave2 明确不宣称 UI 双标签已绿。
- short-term / 报告已关闭:见 [../short-term/2026-09-16-intent-plan-playwright-dual-tab.md](../short-term/2026-09-16-intent-plan-playwright-dual-tab.md) 与 [../../test-reports/2026-09-16-intent-plan-playwright-dual-tab-test-report.md](../../test-reports/2026-09-16-intent-plan-playwright-dual-tab-test-report.md)
- `RUN_UI_ACCEPTANCE=1` 真浏览器 PASS(Docker Playwright);默认 skip
- **不升** `MULTI_INTENT_PLAN_TIER`
## 关闭条件
@@ -1,32 +1,32 @@
---
title: "PU6 语义摘要 D3 — 获批后任务契约"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
branch: feature/pu6-semantic-summary
updated: 2026-09-17
owner: Cursor
branch: feature/w2-semantic-summary-shadow-live
mutex: chat
go_no_go: go
---
# PU6 语义摘要 D3 — 获批后任务契约
**go/no-go**:no-go(见 `.doc/ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md`)。已授权 GO;按 short-term 总控实施(默认 flag off)。
**go/no-go**:GO。脚手架 + W2 live 已合 `dev`。`SEMANTIC_SUMMARY_SHADOW` 默认 off;开 flag 时组合根注入产品 PI no-tool summarizer。**不启用** `SEMANTIC_SUMMARY_REPLACE`。
## 目标(获批后)
## 目标
在授权可见集合上 shadow 语义摘要,可解释 fallback;通过后方可考虑替换 deterministic。
在授权可见集合上 shadow 语义摘要,可解释 fallback;REPLACE 为后置独立授权任务。
## 预注册门
- flag:`SEMANTIC_SUMMARY_SHADOW` → 可选 `SEMANTIC_SUMMARY_REPLACE`
- flag:`SEMANTIC_SUMMARY_SHADOW` → 可选 `SEMANTIC_SUMMARY_REPLACE`(本轮不启用)
- 输入:authorized view only;无工具权限摘要器;R13 出站门
- 失败:保留旧摘要/deterministic;标注 freshness
- 负例:撤权消息不入摘要;injection 不能改权限
## 路径提示
`internal/ctxmgr/summarizer.go`、`internal/app/chatflow/`、`internal/server/chat_digest_api.go`、web 摘要消费组件
`internal/ctxmgr/summarizer.go`、`internal/ctxmgr/semantic_summary.go`、`internal/app/chatflow/`、`internal/server/chat_digest_api.go`、`internal/agent/piagent.go`
## 回滚
@@ -1,9 +1,9 @@
---
title: "PU7 PI change-report 叙事 — 获批后任务契约"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
updated: 2026-09-17
owner: Cursor-Auto
branch: feature/pu7-pi-narrative
mutex: docgov
go_no_go: go
@@ -11,22 +11,27 @@ go_no_go: go
# PU7 PI change-report 叙事 — 获批后任务契约
**go/no-go**:no-go。未获批禁止实现。
**go/no-go**:GO(用户覆盖授权,见 Wave3 research)。脚手架已合 `dev`;W3 live(产品 PI + digest 绑定)已接线,默认 flag 仍 off。
## 目标(获批后)
## 目标
只读消费 immutable diff+lineage+risk floor 的 PI 叙事;任意 schema/超时/注入 → 全量 fallback。
## 预注册门
- flag:`PI_CHANGE_REPORT_NARRATIVE`
- flag:`PI_CHANGE_REPORT_NARRATIVE`(默认 off)
- 禁止覆盖服务端风险/审批结论
- typed schema + 文档版本 + input digest 绑定
- typed schema + input digest 绑定(`change_report_narrative_v1`)
- UI 明确区分 narrative vs 事实字段
## 路径提示
## 路径
`internal/docrevision/`、`deploy/pi-agent/` typed result、`ChangeReportPanel.tsx`
- `internal/docrevision/flags.go` / `narrative.go` / `service.go`
- `deploy/pi-agent/change-report-narrative-v1.mjs`
- `web/.../ChangeReportPanel.tsx` / `changeReportView.ts`
- 报告:[../../test-reports/2026-09-16-pu7-pi-narrative-test-report.md](../../test-reports/2026-09-16-pu7-pi-narrative-test-report.md)
- W3 live:[../../test-reports/2026-09-17-w3-pi-change-report-narrative-test-report.md](../../test-reports/2026-09-17-w3-pi-change-report-narrative-test-report.md)
- short-term:[../short-term/2026-09-17-w3-pi-change-report-narrative.md](../short-term/2026-09-17-w3-pi-change-report-narrative.md)
## 回滚
@@ -1,10 +1,10 @@
---
title: "PU8-U10 mutate — 获批后任务契约"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
branch: feature/pu8-u10-mutate
updated: 2026-09-18
owner: Cursor
branch: feature/w4-u9-segment-live
mutex: intent-plan
go_no_go: go
flag: MULTI_INTENT_U10_MUTATE
@@ -12,7 +12,7 @@ flag: MULTI_INTENT_U10_MUTATE
# PU8-U10 mutate
**go/no-go**:no-go。独立 flag;高风险动作绑定 expected revision + 显式确认 + 执行前再授权;不依赖 U9。
**go/no-go**:GO(覆盖授权)。独立 flag 脚手架已合 `dev`。W4:dry-run→confirm 幂等 receipt 证据;mutex `intent-plan`。不升 `MULTI_INTENT_PLAN_TIER`。报告:[../../test-reports/2026-09-17-w4-u10-mutate-test-report.md](../../test-reports/2026-09-17-w4-u10-mutate-test-report.md)
## 负例
@@ -1,15 +1,15 @@
---
title: "PU8-U11 docgov action — 获批后任务契约"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
branch: feature/pu8-u11-docgov
mutex: docgov
updated: 2026-09-18
owner: Cursor
branch: feature/w4-u9-segment-live
mutex: intent-plan
go_no_go: go
flag: MULTI_INTENT_U11_DOCGOV
---
# PU8-U11 docgov
**go/no-go**:no-go。独立 flag/mutex;按钮与自然语言同一 owner command;项目 143 只读纪律不变。
**go/no-go**:GO(覆盖授权)。独立 flag 脚手架已合 `dev`。W4:项目 143 只读 fail-closed。mutex `intent-plan`。报告:[../../test-reports/2026-09-17-w4-u11-docgov-test-report.md](../../test-reports/2026-09-17-w4-u11-docgov-test-report.md)
@@ -1,15 +1,15 @@
---
title: "PU8-U12 workflow/run-control — 获批后任务契约"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
branch: feature/pu8-u12-workflow-run-control
mutex: workflow
updated: 2026-09-18
owner: Cursor
branch: feature/w4-u9-segment-live
mutex: intent-plan
go_no_go: go
flag: MULTI_INTENT_U12_RUN_CONTROL
---
# PU8-U12 workflow/run-control
**go/no-go**:no-go。独立 flag;双标签确认/取消仅一成功;投影停机时权威 GET 仍正确;回滚后计划可读/取消/finalize。
**go/no-go**:GO(覆盖授权)。独立 flag 脚手架已合 `dev`。W4:独立 flag dry-run 证据。不升 `MULTI_INTENT_PLAN_TIER`。报告:[../../test-reports/2026-09-17-w4-u12-run-control-test-report.md](../../test-reports/2026-09-17-w4-u12-run-control-test-report.md)
@@ -1,10 +1,10 @@
---
title: "PU8-U9 segment proposal — 获批后任务契约"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: TBD
branch: feature/pu8-u9-segment-proposal
updated: 2026-09-18
owner: Cursor
branch: feature/w4-u9-segment-live
mutex: intent-plan
go_no_go: go
flag: MULTI_INTENT_U9_SEGMENT
@@ -12,7 +12,7 @@ flag: MULTI_INTENT_U9_SEGMENT
# PU8-U9 segment proposal
**go/no-go**:no-go。规则无法判断时才出 segment proposal;超时/越界 fail closed;非 U10–U12 默认前置。
**go/no-go**:GO(覆盖授权)。flag 脚手架已合 `dev`。W4:真实 LLM proposer;规则能判断则不出 proposal。不升 `MULTI_INTENT_PLAN_TIER`。报告:[../../test-reports/2026-09-17-w4-u9-segment-test-report.md](../../test-reports/2026-09-17-w4-u9-segment-test-report.md)
## 安全 stop gate
@@ -0,0 +1,85 @@
---
title: "2026-09-19 审计剩余项(medium/low,不挡已合入批 1–4)"
status: planned
created: 2026-09-19
updated: 2026-09-19
---
# 2026-09-19 审计剩余项
## 动机
[系统深度体检](../../audit/2026-09-19-system-deep-audit.md) 的 C1–C4 与 H1–H10 已按四批合入 `dev`。下列 medium/low 仍真实存在,但不进入本轮发布回退。
## 成功标准
- 每条有独立 short-term、负例测试或明确关闭理由后再标 done
- 不把本清单自动写成 gap-matrix blocker
## 依赖
- 批 1–4 已在 `dev`:`844f757`、`08f4e0b`、`a2a49a6`、`d73bc79`
## 暂不启动原因
本轮范围只到 critical + high。下列项要么是加固、要么需要产品/合规决策,要么改动面大于收益。
## 进展(2026-09-19,`fix/audit-remainder-closeout`)
| ID | 结果 |
|----|------|
| M1 | done。`nosniff` / `DENY` / `Referrer-Policy` / 本站 CSP。`TestP0_SecurityHeaders` |
| M2 | done。TTL 钳到人工 15 分钟、小队 30 分钟;人工租约前 `CheckHumanCanEdit`。`TestAcquireLeaseClampsHumanTTL` |
| M3 | done(本项可落地部分)。低置信度才做关键词改道;称呼取用户名。高置信度意图层改造不在本项把模板整段搬走 |
| M4 | done。`parseDecimalID` 拒绝 `u_sess_*`。`TestParseDecimalIDRejectsSessionTokens` |
| M5 | done。`Server.Start` 不再二次启动并吞错。`main` 仍调用 `Runtime.Start`,该方法本身已幂等 |
| M6 | done(上限)。硬上限 4096,淘汰最久未访问。会话 id 仍由客户端提供,因为历史恢复按该 id 查找;改成只接受服务端签发会打断现有对话协议 |
| M9 | done。dev compose 不再声明 `SEMANTIC_SUMMARY_REPLACE`。dev=`MiniMax-M2.7-highspeed`、test/main=`MiniMax-M3` 确认为有意分叉,已写在 compose 注释 |
| M10 | done(写明路径,不放开门闩)。`OpsCutoverPromotionPath`:dev 观察后用晋升回执写 test,再写 main。`ValidateOpsCutover` 仍拒绝 test/main |
| M13 | done。SQL 迁到 `deploy/postgres/archive/pre-goose/`。代码与脚本无引用 |
| M14 | done。冻结计划找不到职责行则报错;显式空三权仍为 0。`TestResolveDocTask_NoneDutiesStayZero` |
| L1 | done。健康检查 2 秒缓存 + 2 秒 DB 超时 |
| L2 | done。SSE marshal 失败写 `event: error` 帧 |
| L3 | done。`ReplayPlan.Digest` 含 `DryRun`;dry-run 摘要不能授权 apply |
| M15 | done。生产 `claimSQL` 与 `MemoryBus` 共用 `VersionClaimable`:版本 0 可领,版本化事件不能跳过 checkpoint。checkpoint 只前进。`TestVersionClaimableMatchesMemoryBusGap`、`TestGapDoesNotSkipVersion` |
| H3 负例 | done。`TestListChatSessions_CrossUserIs403` |
| FE 缓存 | done(版本字段)。窗口缓存写入 `{schema,data}`,无 schema 的旧载荷丢弃。`window cache: 无 schema` |
| FE lucide | 关闭理由:`package-lock.json` 锁定 `lucide-react@1.42.0`,来源 `registry.npmjs.org`,带 integrity。`^1.16.0` 是合法的 1.x 范围,不是来源不明的包 |
| M7 | done(出站意图 + 同键重放)。`document_content_projections` 与账本同一事务写入;投影成功才销账。`TestDocRevision_PatchOrder_RetryProjectsWithoutSecondLedgerCommit`。账本库与正文库仍不是一个 SQL 事务,进程退出后靠未投影行重放,不靠客户端记忆 |
| FE App.tsx | 部分收口。登录壳不再静态引用重模块。本地缓存、登录同步、文档补水、服务端文档同步、生命周期、发送消息、块编辑、对话流/任务流重试、卡片动作、立项和成员写操作已分别抽出。文档栏在 `DocumentPane`,聊天栏在 `ChatColumn`,`AppShell` 与工作台弹窗在 `WorkbenchView`。`App.tsx` 仍持有会话状态,不再挂 `<AppShell` |
| H1-del | 关闭理由:`allowLegacyTestPrincipal` 仍被 `AllowInMemory && ContextDbHost==""` 的 dev/test 内存测试使用。删除会把这批测试变成未登录 401。保留告警,删除另开、先改测试夹具 |
仍开放:`rd_proposal` 终稿未对齐模板标题(没有新的真 PI)。U7 登录表单可见未测(本机无头 Chromium 缺 `libatk`),也不把 1.4 秒模块图写成「较十几秒基线下降 50%」。见 [U7 报告](../test-reports/2026-09-19-initial-load-u7-restart-test-report.md)。工作台壳已挪到 `WorkbenchView`。dev schema 53。U6 仍不加索引。`TestArchitectureBoundaries` 仍有 6 条新 import(intent/squad/template → workflowdef),不是本轮容器改动。test/main 仍是 schema 52。评审门禁的法规表误伤已修,保存的 P3 终稿不再报「问题行缺少」。
红线关闭(不是实现):
- SWBOOT-10:保持 fail-closed stub。未获独立授权前不接真实仓库写入。
- FAV live:禁止整支 merge;`FAV_DEGRADED_READ=false`;live 需要各阶段至少 7 天观察窗,本轮不放量。
- D7:合规签字前禁止按留存口径物理删除。盘点已完成,口径仍 `pending-compliance-signoff`。
## 清单
| ID | 项 | 位置 | 说明 |
|----|----|------|------|
| M1 | 安全响应头 | `internal/server/server.go` CORS 中间件 | 补 `nosniff` / `X-Frame-Options` / `Referrer-Policy` / 收敛 CSP |
| M2 | 租约 TTL 无上限 | `handlers.go` AcquireLease | clamp 到 `DefaultHumanLeaseTTL`,Acquire 前校验编辑权 |
| M3 | 关键词改写意图 + 硬编码「张工」 | `internal/coordinator/engine.go` | 移到意图层并加置信度;称呼取用户名 |
| M4 | `fmt.Sscanf` 解析 `u_sess_*` 得到 UserID=0 | 同上 | 统一数字 ID |
| M5 | `Runtime.Start` 双调用且吞错 | `cmd/server/main.go` 与 `server.go` | `sync.Once` 或删 Server.Start 内调用 |
| M6 | sessions 无硬上限 | `server.go` cleanStaleSessionsLocked | LRU + 服务端发 session id |
| M7 | 修订三阶段写无事务 | `document_revision_handlers.go` | 已落地:`00053` 投影意图与账本同事务;成功后销账。见进展表 |
| M9 | `SEMANTIC_SUMMARY_REPLACE` 只在 dev compose 声明;dev/test 默认模型不一致 | compose | 删未接线 flag 并钉死测试;确认 M3 是否刻意 |
| M10 | cutover 只允许 `dev` | `internal/events/cutover.go` | 写明 test/main 切换路径 |
| M13 | `deploy/postgres/migrations/` 死目录 | 与 goose 重复 | 确认无外部依赖后归档 |
| M14 | ResolveDocTask 静默 0 值三权 | `orchestrator.go` | 找不到 duties 应报错 |
| M15 | PG 投递允许乱序,MemoryBus 有 gap | `dispatcher.go` vs `bus.go` | 对齐测试替身与生产顺序语义 |
| L1 | health 每次打两次 DB | `handlers.go` | 短缓存 + 超时 |
| L2 | SSE marshal 错误被吞 | `task_run_handlers.go` | 失败写 error 帧 |
| L3 | ReplayPlan digest 不含 DryRun | `replay.go` | 纳入 digest |
| H1-del | 删除 legacy user-id=1 兜底 | `auth_middleware.go` | 已加日志;删除前盘点调用方 |
| FE | App.tsx 巨石、localStorage 无版本、lucide 版本确认 | `web/` | 拆 hook;缓存加 version;确认包来源 |
## 相关链接
- 审计:[../../audit/2026-09-19-system-deep-audit.md](../../audit/2026-09-19-system-deep-audit.md)
- 批 1–3 报告:`.doc/test-reports/2026-09-19-audit-b*.md`
@@ -0,0 +1,93 @@
---
title: "参考项目 weichen-agent-system 研发工作流(rdev)文档关系与阶段组成梳理"
created: 2026-09-17
status: done
confidence: high
---
# 调研:参考项目 weichen-agent-system 研发工作流(rdev)文档关系与阶段组成梳理
## 结论
参考项目 `.refs/weichen-agent-system` 中的「研发流程」(`key: rdev`)是与商务对接(bizdev)、测试经理(test_manager)、产品经理(product_manager)并列的第 4 个工作流,`kind: followon`、`after: bizdev`:商务对接末阶段 CDO 报价批准后才可启动。rdev 共 **60 个阶段(文档任务)**,按 **13 个 phase(01–13)** 组织成 ISO 13485 设计控制链(策划 → 输入 → 输出 → 验证 → 转换 → 确认),每阶段恰好对应 `templates/docs/<stage_key>.md` 一份自描述模板,并有 overlays(工作流级 `rdev.md` + 阶段簇 `rdev_phNN.md` + 文档类型 `kind_*.md`)与 `configs/squads/rdev.yaml` 五步小队编排三层配套。
## 证据
| 项 | 路径/命令 | 结果 |
|----|-----------|------|
| 工作流定义 | `.refs/weichen-agent-system/configs/workflows/rdev.yaml` | 1473 行;`key: rdev` `kind: followon` `after: bizdev`;60 个 stage |
| 阶段齐套校验 | `.refs/weichen-agent-system/scripts/e2e-rdev.sh` | 脚本内置断言 `want 60 rdev stages`,逐 stage 校验 `templates/docs/<key>.md` 存在且非空,末模板须含「签署」 |
| 小队编排 | `.refs/weichen-agent-system/configs/squads/rdev.yaml` | `default_steps`:organizer → engineer(+regulatory 可选并行)→ writer → leader;关键 stage 覆盖专属 steps |
| 任务叠加 | `.refs/weichen-agent-system/configs/overlays/rdev.md`、`rdev_ph01…ph13.md`、`rdev_software.md`、`kind_review_minutes.md`、`kind_upload_index.md`、`kind_design_record.md` | 工作流级 / 阶段簇 / 文档类型三层叠加,`### role:` 按专员过滤 |
| 研发负责人人设 | `.refs/weichen-agent-system/configs/agents/rdev_leader.md` | 「研发/设计控制小队负责人…按 ISO 13485 把本阶段做成可追溯的 DHF 记录」 |
| 插件 | `.refs/weichen-agent-system/plugins/rdev/plugin.go` | 不注册生成意图,启动走生命周期 `start_workflow`(说法「启动研发流程」) |
| 官方说明 | `.refs/weichen-agent-system/docs/workflows.md` §研发流程、`docs/handoff.md` §研发流程(followon) | 约 60 阶段、每阶段一份 Word(RD-…)、不适用须完整理由并仍走审核/批准 |
| Canonical 归档 | `docs/cloud-drive.md` | `archive/dhf/{NN-阶段名}/{nn-产出}`;`records` 含 `dmr` 且已批准再拷 `archive/dmr/` |
## 研发工作流的文档关系(五层结构)
```text
configs/workflows/rdev.yaml ← 阶段 SSOT:key/标题/phase/records/artifact_kind/docx 元数据/fields/depends_on/skippable
│ 一一对应(stage key = 模板文件名)
▼
templates/docs/<stage_key>.md ← 自描述模板:文件编号 RD-…、记录归属 DHF(/DMR)、阶段 NN、
│ 结论/适用性/正文/追溯表/材料摘要/待确认清单/签署 固定骨架
▼
configs/squads/rdev.yaml ← 小队编排:default_steps + 个别 stage 覆盖(五步编制流水线)
▼
configs/overlays/*.md ← 任务叠加(注入 TASK 的阶段级撰写指导,多层):
① rdev.md(工作流级全员质量红线)
② rdev_phNN.md(阶段簇,ph01–ph13)
③ kind_review_minutes / kind_upload_index / kind_design_record(文档类型)
④ rdev_software.md(软件类阶段专项)+ 个别 stage 特例 overlay
▼
plugins/rdev/plugin.go ← 运行时入口:启动走生命周期 start_workflow(followon 门禁),
不注册生成意图;启动时从 bizdev 拷贝已填字段(产品类型/预期用途/目标市场等)
```
- **模板即文档**:每份模板头部自带「文件编号 / 记录归属 / 版本 / 阶段」元数据,与 rdev.yaml 中 stage 的 `docx.code`(RD-…)和 `phase` 一致;`scripts/e2e-rdev.sh` 强制校验 60 个 key 与模板一一对应。
- **记录归属双轨**:`records: [dhf]`(设计历史文件)为主;设计输出/转换类文档 `records: [dhf, dmr]`(同时属器械主记录),批准后额外拷贝到 `archive/dmr/`。
- **追溯链**:每份模板含固定「追溯」表(本文件 ID ↔ 上游输入 ↔ 下游验证/确认),需求类要求 UR→RS 追溯主表(见 `kind_design_record.md`)。
- **评审依赖**:评审记录类 stage 用 `depends_on` 显式声明上游(如 `verification_review` depends_on `design_vv`、`risk_report_v`)。
- **不适用机制**:每 stage 都有 `applicability` / `na_rationale` 字段;软件类/动物试验/临床等 15 个 stage 标 `skippable: true` + `skip_hint`,不适用仍须生成完整不适用页并走审核/批准。
## 工作流阶段组成(13 个 phase / 60 个 stage)
| Phase | 阶段簇 overlay | Stage(key → 文档) | 数量 |
|-------|--------|--------------------|------|
| 01 策划 | rdev_ph01 | `proposal` 项目建议书、`design_plan` 设计开发计划任务书 | 2 |
| 02 策划评审 | rdev_ph02 | `planning_review` 策划评审记录(depends: proposal, design_plan) | 1 |
| 03 设计输入 | rdev_ph03 | `user_needs` 用户需求规格书(UN)、`regs_stds` 法规和标准清单、`adverse_events` 同类产品不良事件、`system_reqs` 系统需求规格书(SR)、`risk_plan` 风险管理计划、`hazard_analysis` 危险分析、`sw_plan`*/`sw_reqs`*/`sw_config`* 软件三件套、`design_input_spec` 设计输入规格书、`design_input_list` 设计输入清单、`system_design` 系统设计方案 | 12 |
| 04 需求评审 | — | `req_review` 需求评审记录(depends: user_needs, system_reqs) | 1 |
| 05 输入阶段评审 | — | `input_phase_review` 阶段3和4评审记录(depends: design_input_spec/list, req_review) | 1 |
| 06 设计输出 | rdev_ph06 | `drawings_3d` 图纸3D、`product_bom` BOM、`ee_bom`*/`pcba`*/`electrical_sys`* 电气三件套、`sw_arch`*/`sw_ui`* 软件、`purchase_spec` 采购规范、`process_flow` 工艺流程、`packaging` 包装、`ifu` 说明书、`incoming_iqc`/`ipqc`/`fqc` 三级检验、`tech_req` 产品技术要求、`risk_report` 风险管理报告、`design_output_list` 设计输出清单 | 17 |
| 07 输出评审 | — | `output_review` 阶段6评审(depends: design_output_list) | 1 |
| 08 验证 | rdev_ph08 | `prototype_photos` 样机照片、`design_vv` 设计验证方案、`shelf_life` 货架寿命、`lifetime` 使用期限、`biocompatibility` 生物学、`cleaning` 清洁消毒、`emc_safety`* EMC安规、`risk_report_v` 验证风险报告、`sw_release`*/`sw_unit_test`*/`sw_sys_test`* 软件三件套、`qualified_suppliers` 合格供方 | 12 |
| 09 验证评审 | — | `verification_review`(depends: design_vv, risk_report_v) | 1 |
| 10 转换 | — | `dmr_list` DMR文件清单、`pack_ship` 包装运输、`risk_report_t` 转换风险报告 | 3 |
| 11 转换评审 | — | `transfer_review`(depends: dmr_list, pack_ship, risk_report_t) | 1 |
| 12 确认 | — | `validation_plan` 设计确认方案、`use_error` 使用错误、`animal_study`* 动物试验、`sw_quality`* 软件质量、`clinical`* 临床试验报告、`risk_report_val` 确认风险报告、`user_test` 用户测试 | 7 |
| 13 设计确认报告 | — | `design_validation_report` 设计确认报告(末阶段,批准后项目 done) | 1 |
合计 60,与 `e2e-rdev.sh` 的 `want 60 rdev stages` 断言一致。(`*` = `skippable: true`,实测 grep 共 15 个:软件 9 个(sw_plan/sw_reqs/sw_config/sw_arch/sw_ui/sw_release/sw_unit_test/sw_sys_test/sw_quality)+ 电气 3 个(ee_bom/pcba/electrical_sys)+ emc_safety + animal_study + clinical)
**artifact_kind 三类**(grep 实测):`document`(常规成文,47 个)、`review_minutes`(评审记录,6 个)、`upload_index`(附件清单/上传索引,7 个,只建索引不伪造内容)。各 kind 有独立 overlay 质量要求。
## 小队与治理机制
- **小队编制**:复用整理(organizer)/技术(engineer)/撰写(writer)/法规(regulatory)/检索(searcher)专员,种子化「研发流程负责人」(rdev_leader);市场与财务不进研发小队。
- **默认五步**:organizer(抽材料事实+回填字段+blackboard facts/gaps/implications)→ engineer(技术内容与追溯,可并行)→ regulatory(仅 complexity_tier=high,可选并行)→ writer(按模板成稿)→ leader(二审完整性/粒度/不适用理由/有无编造,不达标退回)。
- **门禁**:启动前必须 bizdev CDO 已批准(e2e 脚本专门验证「CDO 前启动应被拒绝」);启动时从商务对接拷贝产品类型/预期用途/目标市场等字段。
- **状态机**:与 bizdev 同一套编制/审核/批准 FSM;末阶段批准后项目标 `done`。
## 开放问题
- 本仓库(Agent-System)当前尚无 rdev 工作流模块;若要移植,需评估 60 stage × 模板 × overlay × 小队步骤的落地范围与分期(bizdev 已有移植先例)。
- 参考项目 `records: [dhf, dmr]` 双归属与云盘 canonical 归档机制在本仓库尚无对应物,移植时需决策是否引入。
- `complexity_tier=high` 才注入 regulatory 步;本仓库复杂度分层(complexity_high/medium overlay)如何对齐需另调研。
## 建议动作
- 若立项移植 rdev:在 `ops/short-term/` 新建任务,按「工作流定义 → 模板 → 小队 → overlays → 生命周期门禁」顺序分批实施,先做 phase 01–03(策划/输入)切片。
- 移植时保留「stage key = 模板文件名」一一对应约束,并复刻 e2e 齐套校验(60 stage、模板非空、末模板含签署)。
@@ -0,0 +1,151 @@
---
title: "dev→test 晋升前复核:功能权限、合并可行性、已知缺陷"
created: 2026-09-19
updated: 2026-09-19
status: done
confidence: high
---
# 调研:dev→test 晋升前复核
只读复核。不改业务代码、不 rebuild 容器、不合入 `test`/`main`、不修复 [medium/low backlog](../long-term/2026-09-19-audit-remainder.md)。
## 结论
1. **规划内的功能、权限与流程已按声明范围接入。** [FEATURE-MATRIX](../../status/FEATURE-MATRIX.md) 主表里,除明确标成 `partial` / `deferred` 的行以外,其余能力均为 `done`,并有测试报告或 commit 证据。没有发现「规划了但完全未实现」的模块。未完成项是主动延后,且 [gap-matrix](../../remediation/gap-matrix.md) 已判定不挡首发。
2. **`dev` 的静态质量达标,但现在不建议直接合并入 `test`。** `go vet` 与 `go test -short` 全绿,2026-09-19 深度审计的 critical/high 已合入 `dev`。合并前仍缺三件事:dev 容器 rebuild 冒烟、治理 PG 集成与前端构建、批 2 越权负例的自动化覆盖。
3. **critical/high 已关闭;medium/low 仍在,且本轮不修。** 新发现的观察项是文档漂移和 `test` 分支上 9 个晋升提交,不是新的代码缺陷。
## 一、功能、权限、流程
对照 [FEATURE-MATRIX](../../status/FEATURE-MATRIX.md)(更新 2026-09-19)与 [gap-matrix](../../remediation/gap-matrix.md)(`production_ready=yes`,门禁 B1–B4 已签)。
### 已关闭(声明范围内 `done`)
| 能力 | 接入情况 |
|------|----------|
| 意图识别 L1、多意图 U1–U8、多意图扩面 U9–U12 | 代码与报告齐全;`MULTI_INTENT_PLAN_TIER` 仍为 `legacy`,未默认升 `confirm`/`full` |
| 对话 / ctxmgr、语义摘要 D3、PI change-report 叙事 | 刷新恢复门禁已签;摘要与叙事 flag 默认 off,REPLACE 未启用 |
| 工作流治理 | 三正式工作流、动作级鉴权、真实 PI E2E |
| 文档治理、文档版本 baseline | 法定生命周期、租约、受控正文、运行时 UI |
| IAM / 鉴权 | 项目级 API + RBAC;路由清单见 [authorization-matrix-v3](../../audit/authorization-matrix-v3-full.md) |
| 前端工作台、PI Runner、三环境运维、CI/E2E、Artifact 同 digest、可靠事件核心、系统管理台 | 各自行有报告;系统管理台二期(Playwright、细粒度 `system:*`、设置审计)不在本行关闭条件内 |
| 文档编制人兼任(U1–U6) | 已合入 `dev`;总开关默认 off |
2026-09-19 审计批 2 已把鉴权缺口接到主链:H1 给 dev/test legacy 兜底加了告警(未删除兜底)、H2 批注/认领 actor 取 principal 且读类端点校验项目成员、H3 会话查询跨用户 403、H4 登录限流、H8 compose 口令改为必填。证据:[批 2 报告](../../test-reports/2026-09-19-audit-b2-authz-hardening-test-report.md)。
### 明确未完成(不是遗漏)
| 行 | 状态 | 剩余 | 是否挡首发 |
|----|------|------|------------|
| 研发设计控制(rdev) | partial | S2/S3、P2 前端、P3 三样本 E2E、P4 键名空间化 | 否 |
| 纯软件项目自举 | partial | SWBOOT-10 仍 fail-closed stub | 否 |
| Final Artifact Vault | partial | live 未放量;禁止整支 merge;`FAV_DEGRADED_READ=false` | 否 |
| 对话数据治理(D7) | deferred | `pending-compliance-signoff`;禁止按口径物理删除 | 否(违规则才升 blocker) |
| 首次加载性能 | partial(矩阵外专项) | U2 已验收;U1/U3–U7 未做 | 否 |
红线与代码/compose 对齐(深度审计已核实,本轮未再改 flag):`MULTI_INTENT_PLAN_TIER=legacy`、`SEMANTIC_SUMMARY_REPLACE` 未接线、`FAV_DEGRADED_READ=false`、SWBOOT-10 fail-closed stub、项目 143 只读。
## 二、`dev` 能否合入 `test`
**判断:静态门禁通过,运行态与回归门禁未补齐,暂不合并。**
### 已满足
- `dev` 工作树在复核时干净;`dev` HEAD 为 `66421b1`(含审计批 1–4:`844f757`、`08f4e0b`、`a2a49a6`、`d73bc79`)。
- `go vet ./...` 零告警。
- `go test -short ./...` 全包 PASS(`internal/server` 本轮实测约 14s,非缓存)。
- 三环境 `GET /api/v1/health` 均为 `status=ok`、`schema_version=52`、`schema_ready=true`。goose 最新文件为 `00052`。迁移版本本身不阻塞晋升。
- `internal/`、`cmd/` 生产代码中无 `TODO`/`FIXME`/`XXX`。
### 合并前必须处理
1. **dev 容器仍是旧二进制。** 批 1–3 报告写明未执行 `./scripts/env-service.sh dev rebuild`。`:8080` 健康只证明旧镜像在跑,不能证明审计修复已部署。按 [AGENTS.md](../../../AGENTS.md) §6.3,合入共享环境前要占集成槽位并冒烟。
2. **`dev` 领先 `test` 225 个 commit。** 差异覆盖 rdev 模板、系统管理台、docgov 加固、Control Center 移除等。`-short` 不够。晋升前至少再跑:`TEST_DATABASE_URL` 下治理 PG 集成,以及 `cd web && npm test && npm run build`。
3. **批 2 的越权负例仍是人工兜底。** [批 2 报告](../../test-reports/2026-09-19-audit-b2-authz-hardening-test-report.md) 写明:非项目成员访问 docgov 应 403 的 HTTP/Playwright 负例未补,目前靠既有鉴权测试不回退加 code review。
### `test` 上多出来的 9 个提交
`git rev-list --count dev..test` = 9。这些提交是历次 `release-candidate` / 晋升文档同步(含 `rc-v1.0.0-beta.2` 至 `beta.4`),不是 `dev` 上缺失的产品代码。下次晋升应把 `dev` **merge 进** `test`,不要把 `test` reset 到 `dev`,否则这 9 个提交的晋升记录会丢。
`CURRENT.md` 文首仍写 test `schema_version=48`,同文「环境快照」表与本次 health 实测已是 52。这是文档漂移,不是运行时缺陷。更正留给下次晋升文档,本笔记不改那一行。
## 三、缺陷
### 已修复(2026-09-19 深度审计 critical/high)
来源:[系统深度体检](../../audit/2026-09-19-system-deep-audit.md)。四批均已合入 `dev`。
| 批 | 项 | merge |
|----|----|-------|
| 1 数据一致性 | C1 docgov 吞错与 fencing 读回;C2 Session 竞态与跨项目污染;C4 计划保存事务与 `completed_by`;H10 请求 ctx | `844f757` |
| 2 鉴权 | H1–H4、H8、M8 | `08f4e0b` |
| 3 SSE/事件 | C3 心跳与写超时;H5 任务 SSE 幂等;H6 stale fencing 日志;H7 迁移注释(历史 SQL 不能补 down) | `a2a49a6` |
| 4 前端 | H9 占位符 XSS;未读回滚;Excel 预览上限 | `d73bc79` |
H1 的 legacy user-id=1 兜底只加了日志,删除仍在 backlog(`H1-del`)。H7 的 00001–00009 无 down 不能改已应用文件,只加了注释。
### 已知未修(维持 backlog,本轮不启动)
清单 SSOT:[2026-09-19-audit-remainder.md](../long-term/2026-09-19-audit-remainder.md)。均为 medium/low,不回写 gap-matrix。
| ID | 项 |
|----|----|
| M1 | 缺 `nosniff` / `X-Frame-Options` / `Referrer-Policy`,CSP 未收敛 |
| M2 | 租约 TTL 无上限;Acquire 前未校验编辑权 |
| M3 | 关键词改写意图;硬编码「张工」 |
| M4 | `u_sess_*` 解析失败得到 UserID=0 |
| M5 | `Runtime.Start` 双调用且吞错 |
| M6 | sessions 无硬上限 |
| M7 | 修订三阶段写无事务 |
| M9 | `SEMANTIC_SUMMARY_REPLACE` 只在 dev compose 声明;dev/test 默认模型不一致 |
| M10 | cutover 只允许 `dev` |
| M13 | `deploy/postgres/migrations/` 与 goose 重复 |
| M14 | ResolveDocTask 静默 0 值三权 |
| M15 | PG 投递允许乱序,MemoryBus 有 gap |
| L1 | health 每次两次 DB |
| L2 | SSE marshal 错误被吞 |
| L3 | ReplayPlan digest 不含 DryRun |
| H1-del | 删除 legacy user-id=1 兜底前须盘点调用方 |
| FE | `App.tsx` 巨石、localStorage 无版本、lucide 来源待确认 |
M8(测试 flag 名 `FAV_PUBLISHER_ENABLE` 少一个 D)已在批 2 修复,不在上表。M11/M12 的未读回滚与 Excel 行数上限已在批 4 处理;批 4 报告写明浏览器端到端未覆盖这两条,单测已钉住 XSS 主路径。
### 本轮新观察(不单独立项)
- 文首 schema 数字与实测不一致,见第二节。
- `test` 独有 9 个晋升提交,合并时用 merge,不要 reset。
## 证据
复核时间:2026-09-19。工作区当时在 `docs/audit-remediation-backlog`(树与 `dev@66421b1` 一致),随后本笔记落在 `docs/pre-test-promotion-review`。
| 项 | 路径/命令 | 结果 |
|----|-----------|------|
| 工作树 | `git status` | clean |
| dev 领先 test | `git rev-list --count test..dev` | 225 |
| test 领先 dev | `git rev-list --count dev..test` | 9(晋升/文档提交) |
| 静态检查 | `go vet ./...` | 零告警,exit 0 |
| 短测 | `go test -short ./...` | 全包 PASS;`internal/server` 14.044s |
| dev health | `curl -s http://127.0.0.1:8080/api/v1/health` | `env=dev` `schema_version=52` `status=ok` |
| test health | `curl -s http://127.0.0.1:8081/api/v1/health` | `env=test` `schema_version=52` `status=ok` |
| main health | `curl -s http://127.0.0.1:8000/api/v1/health` | `env=main` `schema_version=52` `status=ok` |
| 迁移文件 | `deploy/postgres/goose/` | 52 个 SQL,最新 `00052_2026-09-17-document-duty-locked.sql` |
| worktree | `git worktree list` | 主仓 + `dev-rdev-merge` + `feature-initial-load-performance-plan` + `fix-dev-runtime-data-root-guard`(检出 `feature/final-artifact-vault`) |
| 待办标记 | `grep TODO\|FIXME\|XXX` 于 `internal/` `cmd/`(排除 `_test.go`) | 0 |
| 容器 | `docker ps` | dev/test/main app+events+pi-agent 均为 healthy;dev app 已运行约 5 小时,早于批 1–4 合入后的 rebuild(未做) |
## 开放问题
- dev 与 test/main 默认模型不一致(M2.7-highspeed vs M3)是否刻意?深度审计已记,本轮无新证据。
- `deploy/postgres/migrations/` 是否仍有外部工具依赖?无则再归档(M13)。
- H2/H3 越权负例补到哪一层才算晋升门禁:HTTP 集成即可,还是必须 Playwright?
## 建议动作
按顺序,全部另开任务,不在本笔记内执行:
1. 占集成槽位,`./scripts/env-service.sh dev rebuild`,`curl -sf http://127.0.0.1:8080/health`(或 `/api/v1/health`)确认 schema 52 且二进制含批 1–4。
2. `TEST_DATABASE_URL` 下跑治理 PG 集成;`cd web && npm test && npm run build`。
3. 为 H2/H3 补至少一条跨用户/非成员 403 负例。
4. 通过后再把 `dev` merge 入 `test`(保留 test 上 9 个晋升提交),打 rc tag,并顺手更正 `CURRENT.md` 文首的 test schema 表述。
@@ -1,11 +1,11 @@
---
title: "FAV U7 增量合入(非整支 merge)"
status: planned
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor
branch: feature/fav-u7-publisher
worktree: "-"
worktree: ".worktrees/feature-fav-u7-publisher"
mutex: events
---
@@ -15,13 +15,40 @@ mutex: events
从 `feature/final-artifact-vault` **手工移植**经审计切片到 `dev`;consumer 默认 off;禁止整支 merge;禁止默认开 `FAV_DEGRADED_READ`。
## 步骤
## 范围
1. [ ] cherry-pick / 移植 cmd/artifact-vault + vault HTTP + publisher 订阅
2. [ ] 隔离库负例 + 默认 off 冒烟
3. [ ] 独立 go/no-go 报告
- 配置门闩(`FAV_DEGRADED_READ` / `FAV_PUBLISHER_ENABLED` 默认 false)
- HTTP `GET /api/v1/vault/status` + gated in-process publisher stub
- `internal/app/fav` durable subscriber stub(不注册到 cmd/events)
- `cmd/artifact-vault` status stub(完整 CLI 未移植)
## 非目标
- 整支 merge `feature/final-artifact-vault`
- 未审计启用 degraded read
- 未审计启用 degraded read / fav live / publisher production Drain
- 移植 enumerate / TerminalRow Backfill / OnFinalArtifact hooks
- 合入 `dev`(本切片仅 feature 推送)
## 步骤
1. [x] 审计 FAV vs `dev` artifactvault 冲突(多数 DIFF → 改 stub)
2. [x] 落地 stub + 默认 off 测试
3. [x] go/no-go 报告
4. [x] 推送 `feature/fav-u7-publisher`(不合 dev)
## 验收标准
- [x] fav consumer / Register 仍 fail-closed
- [x] `FAV_DEGRADED_READ` 默认 false
- [x] 测试报告含 NO-GO:subscriber 保持 OFF 直至单独审批
- [x] 已 push 远端 feature 分支
## 相关链接
- Test report: [.doc/test-reports/2026-09-16-fav-u7-incremental-test-report.md](../../test-reports/2026-09-16-fav-u7-incremental-test-report.md)
- Assets: [.doc/test-reports/assets/2026-09-16-fav-u7-incremental/](../../test-reports/assets/2026-09-16-fav-u7-incremental/)
- Remote: `origin/feature/fav-u7-publisher`
## 证据 / 备注
因 `internal/artifactvault` 与 FAV 旁支大面积分叉,未 cherry-pick 核心库;采用最小可编译、默认关闭的 publisher/HTTP/CLI stub。commits: `3478a5a..de65cee`。
@@ -1,6 +1,6 @@
---
title: "全量 backlog 覆盖 no-go 总控"
status: in_progress
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor
@@ -22,19 +22,20 @@ mutex: architecture-docs
## 步骤
1. [x] P0 SSOT 翻转
2. [ ] P1 nightly DATA_DIR 对齐 + green receipt
3. [ ] P2 IAM inventory + 410 + R13
4. [ ] P3 Playwright intent-plan 双标签
5. [ ] P4 PU6 + PU7
6. [ ] P5 PU8 U9→U12
7. [ ] P6 SWBOOT-00…09(10 stub)
8. [ ] P7 FAV 增量
2. [x] P1 nightly DATA_DIR 对齐 + green receipt(U8 PASS;FullNone 仍有 product_fail 待后续)
3. [x] P2 IAM inventory + 410 + R13
4. [x] P3 Playwright intent-plan 双标签(`RUN_UI_ACCEPTANCE=1` Docker Playwright PASS;A=200/B=409;见 [报告](../../test-reports/2026-09-16-intent-plan-playwright-dual-tab-test-report.md))
5. [x] P4 PU6 + PU7(agent 实现合入;flag 默认 off)
6. [x] P5 PU8 U9→U12(独立 flag;legacy tier;agent 实现合入)
7. [x] P6 SWBOOT-00…09(10 stub/设计冻结;agent 实现合入)
8. [x] P7 FAV 增量(非整支 merge;publisher/consumer 默认 off)
## 验收标准
- [ ] 各波 short-term / test-report 回链
- [ ] FEATURE-MATRIX 对应行更新
- [ ] CURRENT 焦点与认领同步
- [x] 各波 short-term / test-report 回链
- [x] FEATURE-MATRIX 对应行更新
- [x] CURRENT 焦点与认领同步
- [x] agent 富实现覆盖薄 stub:`chore/merge-agent-deltas` → `dev`
## 相关链接
@@ -0,0 +1,52 @@
---
title: "Playwright intent-plan 双标签验收"
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor-Auto
branch: feature/intent-plan-cards-playwright
worktree: ".worktrees/feature-intent-plan-cards-playwright"
mutex: web
---
# Playwright intent-plan 双标签验收
## 目标
`RUN_UI_ACCEPTANCE=1` 真浏览器下,PLAN_CONFIRM 双标签 confirm 互斥;刷新/重登与 PG plan 一致;不升 `MULTI_INTENT_PLAN_TIER`。
## 范围
- `web/e2e/intent-plan-cards.spec.ts` 活验规格
- App:`GET /intent-plans/active` 水合 PLAN_CONFIRM;confirm 使用唯一 decision nonce;空 docAST 登录兜底
- InteractiveCard:`data-testid=plan-confirm-card` 等选择器
- 测试报告归档
## 非目标
- 不升 `MULTI_INTENT_PLAN_TIER`
- 不用 stub/SKIP 冒充 PASS
## 步骤
1. [x] 从 origin/dev 开 `feature/intent-plan-cards-playwright`(worktree)
2. [x] 水合 + 唯一 nonce + e2e 规格
3. [x] `RUN_UI_ACCEPTANCE=1` 真浏览器跑通并写报告
4. [x] 提交并 `./scripts/git-push-dev.sh`
## 验收标准
- [x] 无 `RUN_UI_ACCEPTANCE` 时 Playwright skip
- [x] `RUN_UI_ACCEPTANCE=1`:双标签仅一侧 HTTP 200,另一侧 409;败方 outdated
- [x] 刷新/重登卡片状态与 PG / GET active 一致
- [x] 报告进 `.doc/test-reports/`
## 相关链接
- Long-term: [../long-term/2026-09-16-intent-plan-playwright-dual-tab.md](../long-term/2026-09-16-intent-plan-playwright-dual-tab.md)
- Test report: ../../test-reports/2026-09-16-intent-plan-playwright-dual-tab-test-report.md
## 证据 / 备注
- Live:`assets/2026-09-16-intent-plan-playwright-dual-tab/playwright-docker.txt`(1 passed 7.0s)
- Network:`playwright-network.json`(A=200 / B=409 PLAN_STALE_REVISION;PG executing rev=2)
@@ -0,0 +1,46 @@
---
title: "partial/deferred 全量收口总控"
status: in_progress
created: 2026-09-16
updated: 2026-09-17
owner: Cline
branch: docs/partial-deferred-completion-plan
worktree: "-"
mutex: architecture-docs
---
# partial/deferred 全量收口总控
## 目标
按 [收口计划](../../remediation/2026-09-16-partial-deferred-completion-plan.md) 把 FEATURE-MATRIX 6 行 `partial` + 1 行 `deferred` 推进到 `done`;全程保持模块独立解耦(端口 + 组合根 + PG 事件 + 契约门禁,不新增 RPC 层),变更影响面不跨模块扩散。
## 授权
用户 2026-09-16 要求已设计功能尽量推进 done,并确认通信机制与系统契约。
用户 2026-09-17 确认收口计划 §7 四项决策(D7 草案数字、confirm 可独立授权、REPLACE 默认不启用、FAV 顺序与观察窗);见计划 §7.1–§7.4 与 [D7 ADR 草案](../../adr/2026-09-17-d7-chat-data-retention.md)。
## 步骤
1. [x] W1 CI/E2E 收口(mutex `ci`;secret/runner 配置 + FullNone product_fail + green nightly)
2. [x] W2 PU6 语义摘要 D3(mutex `chat`;shadow + 真实 PI + R13 + 负例;**不要求** REPLACE)
3. [x] W3 PU7 PI change-report 叙事(mutex `docgov`;开 flag + 真实 PI + fallback 负例 + UI 区分)
4. [x] W4 PU8 U9–U12(mutex `intent-plan`;逐 action 独立 flag,U9→U12 顺序;升 confirm 另开独立授权,不升 full)
5. [ ] W5 纯软件自举(mutex `workflow-design`;SWBOOT-10 非 stub + 真实 PI + UI 二次验收)
6. [ ] W6 FAV(mutex `events`;**shadow 已合** → live staging→artifact→publication 仍未开;每级观察窗 ≥7 天;`FAV_DEGRADED_READ=false`;禁止整支 merge)
7. [ ] W7 D7 数据治理(mutex `chat`;**盘点已合**;按 ADR 口径整改仍待合规签字;数字 `pending-compliance-signoff`;本轮未发现已确认违规、未写 gap-matrix)
8. [ ] 逐行升 done(保留 lineage)+ CURRENT / 契约状态同步
9. [x] §7 四项开放问题决策落盘(2026-09-17)
## 验收标准
- [ ] 各波独立 short-term / feature 分支 / test-report / 回滚点(占用对应 mutex)
- [ ] 计划 DoD 全勾(见 remediation 计划 §8;§7 四项决策项已勾)
- [ ] `production_ready` 与 B1–B4 门禁零回归
## 相关链接
- Plan: [../../remediation/2026-09-16-partial-deferred-completion-plan.md](../../remediation/2026-09-16-partial-deferred-completion-plan.md)
- D7 ADR 草案: [../../adr/2026-09-17-d7-chat-data-retention.md](../../adr/2026-09-17-d7-chat-data-retention.md)
- 矩阵: [../../status/FEATURE-MATRIX.md](../../status/FEATURE-MATRIX.md)
- 上位: [2026-09-16-full-backlog-override.md](./2026-09-16-full-backlog-override.md)(P0–P7 已完成,本总控承接其收口阶段)
@@ -0,0 +1,48 @@
---
title: "PU7 PI change-report 叙事"
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor-Auto
branch: feature/pu7-pi-narrative
worktree: .worktrees/feature-pu7-pi-narrative
mutex: docgov
---
# PU7 PI change-report 叙事
## 目标
`PI_CHANGE_REPORT_NARRATIVE` 默认 off;开启后只读消费 immutable diff+lineage 的 typed 叙事,失败全量 deterministic fallback。
## 范围
- `internal/docrevision/` flag + ResolveChangeReport
- `deploy/pi-agent/change-report-narrative-v1.mjs`
- `ChangeReportPanel` / changeReportView 区分事实 vs 叙事
## 非目标
- 默认开启 flag
- 覆盖服务端 risk / approval
- 合入 `dev`(本任务仅 feature 分支)
## 步骤
1. [x] flag 默认 off
2. [x] typed narrative + input digest;失败全量 fallback
3. [x] UI 区分 narrative / 事实字段
4. [x] 单测 flag off + fallback
5. [x] test-report + push feature 分支
## 验收标准
- [x] 默认 off 行为 = deterministic fallback
- [x] 畸形/超时/digest 不匹配 → 无混合字段
- [x] PI 声称低风险不影响服务端 risk floor
- [x] 报告归档
## 相关链接
- Contract: [../long-term/2026-09-16-pu7-pi-narrative-contract.md](../long-term/2026-09-16-pu7-pi-narrative-contract.md)
- Test report: [../../test-reports/2026-09-16-pu7-pi-narrative-test-report.md](../../test-reports/2026-09-16-pu7-pi-narrative-test-report.md)
@@ -1,6 +1,6 @@
---
title: "纯软件项目自举 SWBOOT-00..09 实施"
status: in_progress
status: done
created: 2026-09-16
updated: 2026-09-16
owner: Cursor-Auto
@@ -38,7 +38,7 @@ mutex: workflow-design
4. [x] manifests + catalog allowlist
5. [x] create-project wizard hooks + SWBOOT-10 stub
6. [x] unit tests + test-report
7. [ ] push feature 分支
7. [x] push feature 分支 (`b5ce947`)
## 验收标准
@@ -0,0 +1,53 @@
---
title: "首次加载 U2:字体自托管与静态资源交付"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/initial-load-perf-u2
worktree: "-"
mutex: web + static-delivery
---
# 首次加载 U2:字体自托管与静态资源交付
## 目标
登录页不再依赖 Google Fonts 阻塞 CSS;8080/8081 静态资源支持 gzip/br 协商与分层缓存;缺失 `/assets`/`/fonts` 返回 404 而非 HTML。
## 范围
- 自托管 Inter / JetBrains Mono(latin + latin-ext 可变 WOFF2)
- 构建期预压缩 `.br` / `.gz`
- Go `serveSPA` 压缩协商、Cache-Control、Vary、assets 404
- 单元测试与 rebuild 后 curl/浏览器验收
## 非目标
- U1 完整 Playwright 性能套件
- U3 拆包懒加载 / katex 入口 CSS
- U4–U6 初始化扇出、认证、SQL
- U7 完整重启归因(本轮仅借 rebuild 采集起点证据)
## 步骤
1. [x] 诊断/方案文档落盘并合入 `dev`
2. [x] 自托管字体 + 移除外链
3. [x] 预压缩脚本接入 build
4. [x] Go 静态交付修复
5. [x] 测试与 rebuild 验收
6. [x] 测试报告与文档同步
## 验收标准
- [x] 登录页无 `fonts.googleapis.com` / `fonts.gstatic.com` 请求
- [x] 主 JS 响应带 `Content-Encoding: br` 或 `gzip`,体积显著下降
- [x] `/assets/missing.js` → 404 且非 HTML
- [x] HTML `Cache-Control: no-cache`;哈希资源 `immutable`
- [x] SSE / API 缓存行为未回归
## 相关链接
- 方案: [../../remediation/2026-09-17-initial-load-performance-plan.md](../../remediation/2026-09-17-initial-load-performance-plan.md)
- 审计: [../../audit/2026-09-17-initial-load-performance-audit.md](../../audit/2026-09-17-initial-load-performance-audit.md)
- Test report: [../../test-reports/2026-09-17-initial-load-perf-u2-test-report.md](../../test-reports/2026-09-17-initial-load-perf-u2-test-report.md)
@@ -0,0 +1,50 @@
---
title: "已合入 leftover 旁支与文档对齐"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: chore/leftover-hygiene-2026-09-17
worktree: "-"
mutex: ops
---
# 已合入 leftover 旁支与文档对齐
## 目标
拆掉 tip 已是本地 `dev` 祖先的 extra worktree 与本地旁支;把 CURRENT / SWBOOT long-term / PU 契约与 git 事实对齐。不整支合入冻结旁支。
## 范围
- 拆已合入 extra worktree(保留错名 FAV 目录)
- `git branch -d` 已合入 leftover;SWBOOT 残留 1 commit 在确认文档已在 `dev` 后 `-D`
- `fix/clean-test-env-baseline` 不 merge;标明前端清理已放弃
- 对齐 CURRENT、SWBOOT long-term、PU6/PU8 契约
## 非目标
- 不整支 merge `feature/final-artifact-vault`
- 不合入 `feature/remove-herdr-agent-settings`、`fix/project143-controlled-content-404-diagnosis`、`fix/dev-runtime-data-root-guard`、`dev-old-linear`
- 不删 `origin/*`;不从 worktree 起 docker;不碰项目 143;不 push
- 不升 FEATURE-MATRIX 能力行 `done`
## 步骤
1. [x] 从 `dev` 开 `chore/leftover-hygiene-2026-09-17` 并认领 CURRENT
2. [x] 拆已合入 worktree、删除已合入旁支
3. [x] 文档对齐
4. [x] 冒烟 + test-report
5. [x] 占槽合 `dev`
## 验收标准
- [x] extra worktree 只剩 FAV 错名目录
- [x] 5 条冻结旁支仍在
- [x] 文档不再声称 SWBOOT 未合 `dev`
- [x] vet / short / arch-check / health+ready PASS
## 相关链接
- Test report: `.doc/test-reports/2026-09-17-leftover-hygiene-test-report.md`
- 上位: [2026-09-16-partial-deferred-completion.md](./2026-09-16-partial-deferred-completion.md)
@@ -0,0 +1,51 @@
---
title: "晋升 dev → test(rc-v1.0.0-beta.3)"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/promote-dev-to-test-2026-09-17
worktree: "-"
mutex: infra
---
# 晋升 dev → test(rc-v1.0.0-beta.3)
## 目标
在 `production_ready=yes` 前提下,把本地 `dev@46a0fb2`(含 leftover + W2–W7)合入 `test`,重建测试服务,供部署后实测。
## 范围
- `test` `--no-ff` 合入当前 `dev`
- 候选 tag `rc-v1.0.0-beta.3`
- `./scripts/env-service.sh test rebuild`(部署新代码,不 pin beta.2 旧镜像)
- `:8081` health/ready;goose 00048 可迁移
## 非目标
- 不合入 `main`
- 不启用 FAV live / `FAV_DEGRADED_READ`
- 不升 `MULTI_INTENT_PLAN_TIER` / `SEMANTIC_SUMMARY_REPLACE`
- 不翻转 `production_ready`
- 不终止项目 143
- 不按 D7 草案删除数据
## 步骤
1. [x] 确认 gap-matrix `production_ready=yes`;FAV/D7/SWBOOT 为 deferred_enhancement
2. [x] 占集成槽;合入 `test` + tag
3. [x] rebuild 测试服务
4. [x] health/ready + schema 冒烟
## 验收标准
- [x] `:8081` health/ready PASS
- [x] schema 到达 48(00048 additive)
- [x] FAV 仍 off
- [x] 默认 flag 仍 off
## 相关链接
- Test report: [../../test-reports/2026-09-17-promote-dev-to-test-test-report.md](../../test-reports/2026-09-17-promote-dev-to-test-test-report.md)
- gap-matrix: [../../remediation/gap-matrix.md](../../remediation/gap-matrix.md)
@@ -0,0 +1,58 @@
---
title: "系统管理台(System Admin Console)一期"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Kimi
branch: feature/system-admin-console
worktree: "-"
mutex: web + sysadmin
---
# 系统管理台(System Admin Console)一期
## 目标
为管理员提供独立的系统级管理界面(全屏视图,`workbench | admin` 顶层切换),覆盖总览状态、知识库、功能与特性开关、角色权限、工作流、用户审批、文档治理;吸收下线 AdminSettingsModal;系统设置只读为主 + SettingSpec 白名单少量可写。
## 范围
- 后端:新包 `internal/sysadmin`(薄聚合层,ports/settings/overview);迁移 `deploy/postgres/goose/00049`(`system_settings` 表);路由 `/api/v1/admin/system/{overview,kb,features,settings}`;`internal/server/admin_system_handlers.go`;`internal/app/app.go` 装配。
- 前端:`web/src/api/systemAdmin.ts` + `web/src/types/systemAdmin.ts`;`web/src/components/admin/console/AdminConsoleView.tsx` + `sections/`;`App.tsx` 顶层视图切换;LeftRail 入口语义改为进入管理台;吸收 `AdminSettingsModal` 六 tab 并删除旧模态。
## 非目标
- 不做全量 DB feature-flag 层(env 开关保留,标注「需重启」)。
- 不改项目级设置(`projectinstance.ProjectSettings` 与项目设置模态保持原样)。
- 不引入 react-router / 新前端依赖;不改 `tokens.css` 之外的全局样式。
- 不做 KB 重建/索引管理等运维动作(一期只读)。
## 步骤
1. [x] 后端 sysadmin 包 + goose 00049(commit `f1404d5`)
2. [x] 后端路由/handler/装配 + 单测(commit `f1404d5`)
3. [x] 前端 API 模块与类型(commit `0eaca61`)
4. [x] AdminConsoleView 骨架与 8 个分组 sections(commit `0eaca61`)
5. [x] 吸收 AdminSettingsModal 并下线(commit `0eaca61`)
6. [x] go vet / go test -short / web npm test + build(全绿)
7. [x] 占集成槽位:dev rebuild + /health + admin overview 冒烟(merge commit `dc7c31e`;schema 48→49;PASS)
## 验收标准
- [x] admin 从 LeftRail 入口进入全屏管理台,八个分组可渲染(UI 人工抽检由 Playwright spec 兜底,见报告后续项 1)
- [x] 非管理员无入口且 `/api/v1/admin/system/*` 返回 403(server 单测真实 mux + 内存 IAM)
- [x] 白名单可写设置 PUT 后 GET 生效;env 项只读并标注需重启(写读回环 PASS)
- [x] `go vet ./...`、`go test -short ./...`、`cd web && npm test && npm run build` 全绿
- [x] dev 容器冒烟 PASS
## 相关链接
- 方案:会话计划(全屏独立视图 / 吸收旧模态 / 只读+少量可写,用户已批准)
- Test report: [2026-09-17-system-admin-console-test-report.md](../../test-reports/2026-09-17-system-admin-console-test-report.md)
- FEATURE-MATRIX 行:系统管理台
## 证据 / 备注
- commit:`f1404d5`(后端)、`0eaca61`(前端)、`dc7c31e`(merge dev)
- 冒烟:health `schema_version=49`;overview/kb/features(22)/settings(6) 200;PUT 写读回环 PASS;匿名 401、未知 key 400、非 admin 403(单测)
- 遗留(二期):Playwright 实跑、`system:*` 细粒度权限、设置审计日志、KB 运维动作、白名单项接消费方、403 自动退回
@@ -0,0 +1,53 @@
---
title: "W1 CI/E2E FullNone + green nightly"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w1-ci-e2e-green-nightly
worktree: "-"
mutex: ci
---
# W1 CI/E2E FullNone + green nightly
## 目标
收口 FullNone `product_fail`,取得真实 nightly `verdict=pass` receipt,将 FEATURE-MATRIX「CI / E2E」升为 `done`。
## 范围
- 复核 Actions secret/runner 已就绪
- 复现并修复 `TestWorkflowGovernance_PiAgent_PG_FullNoneMixedChain`
- nightly U8+FullNone → green receipt + test-report
- 矩阵行升 done
## 非目标
- W2–W7;升 `MULTI_INTENT_PLAN_TIER`;开 `SEMANTIC_SUMMARY_REPLACE`;整支 merge FAV
## 步骤
1. [x] docs 计划分支合入 `dev`(`4bda648`)
2. [x] CURRENT 认领 `mutex=ci` + 本 short-term
3. [x] 本地复现 FullNone 并分栏(根因:duplicate goose 00048 + fields.json 硬目标 + KB/超时)
4. [x] 修复至本地 FullNone 绿(1008s)
5. [x] nightly green receipt 归档 + test-report(`6e2476f0…` verdict=pass)
6. [x] FEATURE-MATRIX CI/E2E → done;总控 W1 勾选;释放认领
## 验收标准
- [x] Nightly receipt `verdict=pass`(真实 run)
- [x] FullNone 在 nightly 套件 PASS
- [x] 矩阵 `done`;B1–B4 零回归
## 相关链接
- Plan: [../../remediation/2026-09-16-partial-deferred-completion-plan.md](../../remediation/2026-09-16-partial-deferred-completion-plan.md) §W1
- Test report: [../../test-reports/2026-09-17-w1-ci-e2e-green-nightly-test-report.md](../../test-reports/2026-09-17-w1-ci-e2e-green-nightly-test-report.md)
- Receipt: [../../test-reports/assets/promotion-receipts/6e2476f0f2e408e111fe06ca7c31a38294a340b3.json](../../test-reports/assets/promotion-receipts/6e2476f0f2e408e111fe06ca7c31a38294a340b3.json)
## 证据 / 备注
- commits: `4f2e5f0` `a02c67d` `0f52ab8` `11e030d` `6e2476f`
- Gitea Actions API 可达;本提交未推远端,远端 dispatch 留合入后二次确认
@@ -0,0 +1,48 @@
---
title: "W2 语义摘要 shadow 真实 PI"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w2-semantic-summary-shadow-live
worktree: "-"
mutex: chat
---
# W2 语义摘要 shadow 真实 PI
## 目标
在授权可见集合上接入产品 PI Agent Runner 的 no-tool shadow 摘要;默认 flag off;不接线 `SEMANTIC_SUMMARY_REPLACE`。
## 范围
- `PiSemanticSummarizer` 组合根注入(仅 `SEMANTIC_SUMMARY_SHADOW` on 且 backend=pi-agent)
- R13 minimized input.json;tool_permissions=none
- 真实 MiniMax 证据 + injection 负例
- 仓库默认 flag 保持 false
## 非目标
- 启用 `SEMANTIC_SUMMARY_REPLACE`
- 改 test/main 默认 env
## 步骤
1. [x] 认领 CURRENT mutex `chat`
2. [x] 实现 PI summarizer + 单测
3. [x] 真实 PI live
4. [x] test-report + 矩阵升 done
5. [x] 合 `dev`
## 验收标准
- [x] flag 默认 off
- [x] 真实 PI shadow.status=ok 或可解释 fallback
- [x] injection 秘密不入 served narrative;REPLACE 未接线
- [x] vet / short / arch-check PASS
## 相关链接
- 契约: `.doc/ops/long-term/2026-09-16-pu6-semantic-summary-contract.md`
- 总控: `.doc/ops/short-term/2026-09-16-partial-deferred-completion.md`
@@ -0,0 +1,48 @@
---
title: "W3 PU7 PI change-report 叙事 live"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w3-pi-change-report-narrative-live
worktree: "-"
mutex: docgov
---
# W3 PU7 PI change-report 叙事 live
## 目标
flag on 时质量修复路径向产品 PI Agent Runner 请求 `change_report_narrative_v1`;digest 绑定;畸形/超时全量 fallback;UI 区分叙事与 `rule_risk`/lineage。
## 范围
- `CreateAgentCandidate` 在 flag on 且 `ReportJSON` 为空时调用 `NarrativeFetcher`
- 组合根仅 `PI_CHANGE_REPORT_NARRATIVE` on + `pi-agent` 注入 `PiChangeReportNarrator`
- 仓库默认 flag 仍 off;dev 运行态可覆盖
- 负例:timeout envelope / fetcher error → fallback 且不返回 `ErrReportInvalid`
## 非目标
- 不把 fallback 写成完整 PI
- 不覆盖服务端风险与文档影响
- 不默认开启仓库 flag
## 步骤
1. [x] no-tool PI narrator + 组合根接线
2. [x] digest 与 `ResolveChangeReport` 同源(candidate 真实 diff 之后再 fetch)
3. [x] 单测 + 真实 MiniMax + UI 分区单测
4. [x] 合 `dev` + 冒烟 + 矩阵升 done
## 验收标准
- [x] 真实 PI 产出 `change_report_narrative_v1` 且 digest 原样回写
- [x] fallback 负例 PASS
- [x] UI `change-report-factual` / `change-report-narrative` 分区
- [x] test-report 归档
## 相关链接
- Contract: [../long-term/2026-09-16-pu7-pi-narrative-contract.md](../long-term/2026-09-16-pu7-pi-narrative-contract.md)
- Test report: [../../test-reports/2026-09-17-w3-pi-change-report-narrative-test-report.md](../../test-reports/2026-09-17-w3-pi-change-report-narrative-test-report.md)
@@ -0,0 +1,21 @@
---
title: "W5a 软件自举 UI + docs_only PI"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w5a-software-bootstrap-ui-pi
worktree: "-"
mutex: workflow-design
---
# W5a 软件自举 UI + docs_only PI
## 目标
创建向导改为服务端 catalog 驱动;软件项目不克隆医疗 7 模板;solo 标注未独立评审;docs_only 真实 PI 建议 delivery 且不自动激活。SWBOOT-10 仍 stub。矩阵不升 done。
## 非目标
- 真 patch/merge(W5b)
- 升 FEATURE-MATRIX 纯软件自举行
@@ -0,0 +1,51 @@
---
title: "W6 FAV subscriber shadow"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w6-fav-subscriber-shadow
worktree: "-"
mutex: events
---
# W6 FAV subscriber shadow
## 目标
手工移植 FAV subscriber **shadow**:只计算 intended outcome,不写业务副作用;`FAV_DEGRADED_READ=false`;`FAV_PUBLISHER_ENABLED` 默认 false。矩阵保持 `partial`。
## 范围
- `ObserveShadow` 只读计算
- vault status / CLI 标明 shadow 与 live 未放量
- 负例:degraded read 拒绝;HandleLease / Register(fav) 仍 fail-closed
## 非目标
- 整支 merge `feature/final-artifact-vault`
- live staging → artifact → publication
- 启用 `FAV_DEGRADED_READ`
- 升 FEATURE-MATRIX FAV 为 `done`
## 步骤
1. [x] `ObserveShadow` + 负例单测
2. [x] 冒烟 + 报告(live 未放量)
3. [x] 合 `dev`;矩阵保持 partial
## 验收标准
- [x] WouldStage / WouldPublish 恒 false
- [x] FAV_DEGRADED_READ=true 时 shadow 拒绝
- [x] 报告写清 shadow 证据与「live 未放量」
## 相关链接
- Remaining port: [../../audit/2026-09-16-fav-u7-remaining-port.md](../../audit/2026-09-16-fav-u7-remaining-port.md)
- U7 报告: [../../test-reports/2026-09-16-fav-u7-incremental-test-report.md](../../test-reports/2026-09-16-fav-u7-incremental-test-report.md)
- Test report: [../../test-reports/2026-09-17-w6-fav-subscriber-shadow-test-report.md](../../test-reports/2026-09-17-w6-fav-subscriber-shadow-test-report.md)
## 证据 / 备注
不占 live 观察窗;≥7 天窗口仍属后续 live 切片。
@@ -0,0 +1,46 @@
---
title: "W7 D7 对话数据分类盘点"
status: done
created: 2026-09-17
updated: 2026-09-17
owner: Cursor
branch: feature/w7-d7-data-inventory
worktree: "-"
mutex: chat
---
# W7 D7 对话数据分类盘点
## 目标
只做数据分类盘点 audit(sessions/messages、KB、日志、备份、event 敏感字段与流转)。无合规签字不物理删除、不清备份。矩阵 D7 保持 `deferred`。
## 范围
- 只读盘点:表、派生副本、日志、备份脚本、事件 payload
- 若发现**已确认**安全/合规基线违规 → 立即写 gap-matrix blocker
## 非目标
- 按 ADR 草案数字(365/180/30)执行物理删除或备份清除
- 字段级加密实现
- 升 FEATURE-MATRIX D7 为 `done`
- 翻转 `production_ready`
## 步骤
1. [x] 只读盘点系统库 / 共享 KB / 宿主 traces / 事件 payload keys
2. [x] 写 audit + test-report;违规判定(无已确认违规,未写 gap-matrix)
3. [x] 合 `dev`;矩阵保持 deferred
## 验收标准
- [x] 盘点覆盖 sessions/messages、KB、日志、备份、event
- [x] 未执行物理删除
- [x] D7 仍 deferred;ADR 仍 `pending-compliance-signoff`
## 相关链接
- ADR: [../../adr/2026-09-17-d7-chat-data-retention.md](../../adr/2026-09-17-d7-chat-data-retention.md)
- Audit: [../../audit/2026-09-17-d7-data-inventory.md](../../audit/2026-09-17-d7-data-inventory.md)
- Test report: [../../test-reports/2026-09-17-w7-d7-inventory-test-report.md](../../test-reports/2026-09-17-w7-d7-inventory-test-report.md)
@@ -0,0 +1,58 @@
---
title: "系统使用说明书(含真实截图,md/word/pdf/html 四格式)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Kimi
branch: feature/user-manual
worktree: .worktrees/feature-user-manual
mutex: docs
---
# 系统使用说明书(含真实截图,md/word/pdf/html 四格式)
## 目标
产出覆盖「从 0 进入系统 → 登录/注册 → 管理员角色权限配置 → 日常使用 → 审批全流程」的终端用户说明书,配 dev 环境真实操作截图(含真实 PI 对话),交付 Markdown / HTML / PDF / Word 四种格式于 `docs/user-manual/`。
## 范围
- dev 环境(127.0.0.1:8080)Playwright 实操截图约 30 张(登录、工作台、立项、对话、文档、审批链、管理台 8 分组)
- `docs/user-manual/manual.md` 十章中文说明书(内容以代码为准)
- `docs/user-manual/scripts/`(截图与格式生成脚本,可重跑)
- `docs/user-manual/dist/`(html/pdf/docx 产物)
## 非目标
- 不合入 dev、不 push(用户未要求)
- 不改动任何产品代码
- 不覆盖产品手册范围外的工程内部工具(`engineering-dashboard` 当时为工程内部,其后已移出本仓库)
## 步骤
1. [x] 分支 + 登记
2. [x] 环境预检(健康、登录凭证、中文字体、chromium)
3. [x] 截图脚本 `capture-screenshots.mjs` 并采集
4. [x] 真实 PI 对话截图
5. [x] 三责审批链 + 阶段门禁截图(zhanggong/lizhuguan/wangzong)
6. [x] 撰写 manual.md
7. [x] build-formats.mjs 生成 html/pdf/docx(pandoc 缺失时 .doc 兜底)
8. [x] 校验(图片引用、PDF 渲染抽查、docx 媒体嵌入)
9. [x] 提交 + 更新 CURRENT
## 验收标准
- [x] 四种格式文件齐备且可打开
- [x] manual.md 图片引用全部存在,无孤图
- [x] PDF 中文无乱码、图片正常嵌入
- [x] 说明书章节覆盖:进入系统/登录/注册/管理员配置角色权限/项目使用/对话/文档/审批/FAQ
## 相关链接
- Checklist: -
- Handoff: -
- Test report: -
## 证据 / 备注
- 演示账号(dev 种子,密码 123456):zhanggong / lizhuguan / wangzong / guest;管理员 admin(密码取 configs/.env.dev)
@@ -0,0 +1,55 @@
---
title: "Wave 0:P0 确认 bug 修复(SSE/缓存/run-stream)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor
branch: fix/wave0-p0-sse-chat-cache-bugs
worktree: "-"
mutex: chat + web
---
# Wave 0:P0 确认 bug 修复(SSE/缓存/run-stream)
## 目标
修复体检确认的 P0 bug:SSE 120s 断流(B-1/B-2)、run/stream 解析与时序(B-3/B-4)、前端会话窗口缓存 key 不一致(B-5)、IndexedDB 恢复覆盖(B-6)。
## 范围
- `internal/server/sse.go`:chat/run stream 心跳 + WriteDeadline;Decode 400;CreateAndStart/Subscribe 前置 Flush
- `web/src/hooks/useChatWindow.ts` + `web/src/data/storage.ts`:缓存 key / LRU 一致
- `web/src/App.tsx` + `web/src/data/fileStore.ts`:恢复合并
- 对应单测与测试报告
## 非目标
- E-1(main ENV 不一致)及 Wave 1–7 其余项
- FAV / MULTI_INTENT_PLAN_TIER / SEMANTIC_SUMMARY_REPLACE 放量
## 步骤
1. [x] 从 dev 开 `fix/wave0-p0-sse-chat-cache-bugs`,CURRENT 认领
2. [x] B-1/B-2 心跳与 deadline
3. [x] B-3/B-4 run/stream
4. [x] B-5 缓存 key
5. [x] B-6 恢复合并
6. [x] 单测 + 全量回归 + 合入 dev 冒烟
## 验收标准
- [x] `go vet ./...`、`go test -short ./...`、`cd web && npm test && npm run build` 全绿
- [x] 畸形 body → 400;Flush 前失败非 200 SSE
- [x] 缓存 key / LRU 单测 PASS;恢复合并不丢新增 deliverable
- [x] dev rebuild + health/ready;真 PI 聊天心跳证据(见测试报告)
## 相关链接
- Audit: [../../audit/2026-09-17-system-health-check.md](../../audit/2026-09-17-system-health-check.md)
- Remediation: [../../remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Test report: [../../test-reports/2026-09-18-wave0-p0-bug-fixes-test-report.md](../../test-reports/2026-09-18-wave0-p0-bug-fixes-test-report.md)
## 证据 / 备注
- Commits:`64efaa3` docs · `54244ed` server · `2620d80` web;合入 `dev` merge `810fb96`
- Assets:`.doc/test-reports/assets/2026-09-18-wave0-p0-bug-fixes/chat-stream-long.sse.txt`
@@ -0,0 +1,53 @@
---
title: "Wave 1:main 环境 ENV/schema 修正(E-1/E-2/E-5)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor
branch: fix/wave1-main-env-fix
worktree: "-"
mutex: infra
---
# Wave 1:main 环境 ENV/schema 修正(E-1/E-2/E-5)
## 目标
统一 main 环境 app/events 的 `ENV=main` 语义,用 compose 依赖强制 events 先迁移再启 app,并关闭 `Env==""` 视同 dev 的导入门禁漏洞。
## 范围
- `docker-compose.main.yml`:app `ENV: main`;`depends_on.events` healthy;events 补生产校验所需口令
- `configs/.env.main`(本机)/ `.env.main.example`:`ENV=main`
- `internal/server/chat_window_api.go`:去掉空 Env 视同 dev
- 回归测试 + 真实 main rebuild 验证
## 非目标
- Wave 2+;不改 `event_consumer_modes` 的 mode 值;不触碰 FAV / MULTI_INTENT / SEMANTIC_SUMMARY_REPLACE
## 步骤
1. [x] 从本地 `dev` 开分支并 CURRENT 认领
2. [x] E-1 ENV 对齐
3. [x] E-2 depends_on events
4. [x] E-5 空 Env fail-closed
5. [x] 单测 + 合入 + main rebuild 冒烟
## 验收标准
- [x] app/events health 均报 `env=main`
- [x] main schema 已升(health `schema_version=52`,goose `version_id=52`)
- [x] `event_consumer_modes` 中 main 四行仍为 `off`
- [x] 导入端点空 Env → 403;compose ENV 对齐单测 PASS
## 相关链接
- Audit: [../../audit/2026-09-17-system-health-check.md](../../audit/2026-09-17-system-health-check.md)
- Remediation: [../../remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Test report: [../../test-reports/2026-09-18-wave1-main-env-fix-test-report.md](../../test-reports/2026-09-18-wave1-main-env-fix-test-report.md)
## 证据 / 备注
- 合入本地 `dev`:`merge: fix/wave1-main-env-fix` + events secrets unblock
- Assets:`.doc/test-reports/assets/2026-09-18-wave1-main-env-fix/`
@@ -0,0 +1,57 @@
---
title: "Wave 2:配置与灰度入口对齐(E-3/E-4/E-6/E-7/E-9)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor-Auto
branch: fix/wave2-config-flag-align
worktree: "-"
mutex: infra
---
# Wave 2:配置与灰度入口对齐
## 目标
三环境 compose 显式声明封存 flag(值保持 legacy/false);移除死 `CURSOR_RUNNER`;main 显式 `SEED_DEMO_USERS=false`;`INTENT_V2_DECISION_TIER` 非法值 fail-closed 到 `none`;E-9 仅记录评估结论。
## 范围
- E-3 / A-4:三环境补 `MULTI_INTENT_PLAN_TIER` + U9–U12 + SHADOW/NARRATIVE 声明
- E-4:删除 `CURSOR_RUNNER_URL` 与 `cursor-agent` 占位服务
- E-6:main `SEED_DEMO_USERS: "false"`
- E-7:`parseV2DecisionTier` default → `none`
- E-9:评估记录,不改 initdb
## 非目标
- 不升 `MULTI_INTENT_PLAN_TIER`;不接线 `SEMANTIC_SUMMARY_REPLACE`
- 不改 FAV modes;不改 E-9 initdb 挂载
- Wave 3+ 范围项
## 步骤
1. [x] Sonnet 5 产出实施计划(默认决策:删 cursor-agent;不补 REPLACE;E-9 不改代码)
2. [x] E-7 代码 + 单测
3. [x] E-3 / E-4 / E-6 compose
4. [x] compose flag 声明回归测试
5. [x] go vet/test;三环境 rebuild + env 抽检 + 冒烟
6. [x] 合入本地 dev;文档闭环
## 验收标准
- [x] 三环境 `docker compose config` 可见目标 flag;`CURSOR_RUNNER` 零匹配
- [x] 容器内 env 抽检 PASS;health/ready PASS
- [x] `go test -short ./...` 全绿
- [x] test-report 归档;remediation Wave 2 done
## 相关链接
- Remediation: [.doc/remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Audit: [.doc/audit/2026-09-17-system-health-check.md](../../audit/2026-09-17-system-health-check.md)
- Test report: [.doc/test-reports/2026-09-18-wave2-config-flag-align-test-report.md](../../test-reports/2026-09-18-wave2-config-flag-align-test-report.md)
## 证据 / 备注
计划作者:[Wave 2 Sonnet 计划](5b8c8c73-c3e4-4947-b0c4-91822859ff4a)
commits:`07fc0ec` `e0aabec` `55a539c` `8d97dd6` + docs closeout
@@ -0,0 +1,46 @@
---
title: "Wave 3:测试债与盲区(S-1/S-2/S-4/S-5)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor-Auto
branch: fix/wave3-test-debt-blindspots
worktree: "-"
mutex: test-debt
---
# Wave 3:测试债与盲区
## 目标
关闭 `TestReconcile_LegacyRepair_PG` 工程测试债;清理永久跳过死代码;统一 E2E 脚本入口;推广 409/结构化错误信封复用。
## 范围
- S-1 / S-2 / S-4 / S-5(按 Sonnet 计划默认决策)
## 非目标
- 不升 MULTI_INTENT_PLAN_TIER;不接线 REPLACE;不改 FAV;项目 143 只读
- 不改后端 httpx 信封整体迁移;不统一 INTENT_DUAL_TAB
## 步骤
1. [x] Sonnet 5 计划
2. [x] S-1 隔离 PG 5436 跑一次并归档
3. [x] S-2 删死跳过 + plan_owner 说明
4. [x] S-4 e2e scripts + 退役 document-revision.spec
5. [x] S-5 信封复用 + 单测
6. [x] 文档闭环 + 合入本地 dev
## 验收标准
- [x] reconcile PG PASS 证据
- [x] playwright --list = 29 tests / 8 files
- [x] npm test / go test -short 全绿
- [x] gap-matrix 测试债关闭;remediation Wave 3 done
## 相关链接
- Plan agent: [Wave 3 Sonnet 计划](51987049-b338-41a7-84f4-2c97e3655d85)
- Test report: [.doc/test-reports/2026-09-18-wave3-test-debt-blindspots-test-report.md](../../test-reports/2026-09-18-wave3-test-debt-blindspots-test-report.md)
@@ -0,0 +1,49 @@
---
title: "Wave 4:隐患加固(R-1~R-8)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor-Auto
branch: fix/wave4-hardening-r1-r8
worktree: "-"
mutex: hardening
---
# Wave 4:隐患加固(R-1~R-8)
## 目标
按 Wave 4 Sonnet 计划默认决策关闭体检高风险隐患 R-1~R-8。
## 范围
- R-1~R-8 全项(含 D-1 扩大范围:upsert + COALESCE)
## 非目标
- D-4/D-5;不升 tier;不接线 REPLACE;不改 FAV;项目 143 只读;不 push
## 步骤
1. [x] R-1c/R-1a/R-1b + Memory/PG 负例
2. [x] R-2 rows.Err()
3. [x] R-3 RWMutex / R-4 memTurns / R-5 hydrate / R-6 Shutdown
4. [x] R-7/R-8 前端 + 单测
5. [x] 全量验收 + test-report + 合入本地 `.worktrees/dev-rdev-merge` dev
## 验收标准
- [x] R-1~R-8 按计划验收项 PASS
- [x] `go vet` / `go build` / `go test -short ./...` / `npm test` / `npm run build`
- [x] 相关 `-race` 绿
- [x] 文档闭环
## 相关链接
- Remediation: [.doc/remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Test report: [.doc/test-reports/2026-09-18-wave4-hardening-r1-r8-test-report.md](../../test-reports/2026-09-18-wave4-hardening-r1-r8-test-report.md)
- Assets: [.doc/test-reports/assets/2026-09-18-wave4-hardening-r1-r8/](../../test-reports/assets/2026-09-18-wave4-hardening-r1-r8/)
## 证据 / 备注
基线 tip:`32932e4`。合入本地 `dev` 见 merge commit。
@@ -0,0 +1,98 @@
---
title: "Wave 5:死代码与机制收口(X-1~X-5)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor-Auto
branch: fix/wave5-deadcode-decisions
worktree: "-"
mutex: deadcode-cleanup
---
# Wave 5:死代码与机制收口(X-1~X-5)
## 目标
按系统体检整改方案 Wave 5,对 X-1~X-5 逐项决策并收口:删除真死 flag/组件、封存 REPLACE、标记 00048 deferred、保留 system_settings 二期键。
## 范围
- X-1~X-5 全项(含级联删除 `patchNotification`)
## 非目标
- X-6(`useTaskRunStream` 伪 ref);不接线 REPLACE;不升 MULTI_INTENT_PLAN_TIER;不改 FAV;项目 143 只读;不改 goose 00048/00049 schema;不 push
## 步骤
1. [x] 决策记录落盘(本文件「决策记录」段)
2. [x] X-1 删除 `SEMANTIC_FALLBACK_ENABLED` + 回归测试
3. [x] X-2 封存注释回链
4. [x] X-3 00048 deferred 注释 + long-term
5. [x] X-4 system_settings 6 键注释
6. [x] X-5 删除死组件/死 API
7. [x] 全量验收 + test-report + 合入本地 `.worktrees/dev-rdev-merge` `dev`
## 验收标准
- [x] X-1~X-5 每项有决策记录(本文件)
- [x] `go vet ./...` / `go test -short ./...` / `cd web && npm test && npm run build`
- [x] remediation Wave 5 行改 done;勾选「X-1~X-5 每项有决策记录」
- [x] 文档闭环 + merge `--no-ff`
## 相关链接
- Remediation: [.doc/remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Audit: [.doc/audit/2026-09-17-system-health-check.md](../../audit/2026-09-17-system-health-check.md)
- Test report: [.doc/test-reports/2026-09-18-wave5-deadcode-decisions-test-report.md](../../test-reports/2026-09-18-wave5-deadcode-decisions-test-report.md)
- Assets: [.doc/test-reports/assets/2026-09-18-wave5-deadcode-decisions/](../../test-reports/assets/2026-09-18-wave5-deadcode-decisions/)
## 决策记录
### X-1:`SEMANTIC_FALLBACK_ENABLED` — 删除
- **现状证据**:字段仅在 `internal/intent/flags.go` 解析、`internal/app/app.go` 注入 sysadmin 视图、`internal/sysadmin/features.go` 目录展示;全仓无业务消费方。三环境 compose + `.env.example` 均声明该死变量。
- **决策**:删除(不接线)。
- **理由**:零读者、无设计文档描述预期语义;接线需独立产品设计,保留只会继续污染配置面。
- **影响范围**:`flags.go` / `app.go` / `features.go` / 三 compose / `.env.example`;新增 `TestComposeNoDeadSemanticFallbackConfig` 防复活。
- **验收**:`go vet ./...`;`go test ./internal/intent/... ./internal/app/... ./internal/sysadmin/... ./internal/config/...`;`rg SEMANTIC_FALLBACK_ENABLED` 除 `.doc/` 历史外无匹配。
### X-2:`SEMANTIC_SUMMARY_REPLACE` — 维持封存
- **现状证据**:env 可读但 `semantic_summary.go` 明确 `_ = SemanticSummaryReplaceEnabled()` 且不替换 `sum.Narrative`;负例 `TestSemanticSummary_ShadowOKKeepsDeterministic` 已覆盖 `Replace: true`。
- **决策**:维持不接线;补强注释回链本决策记录。
- **理由**:与 CURRENT 红线及 remediation Wave 5 一致;启用需独立授权 + fail-closed 灰度设计。
- **影响范围**:仅 `summary_flags.go` / `semantic_summary.go` 注释。
- **验收**:`go test ./internal/ctxmgr/... -run Semantic`;diff 仅注释。
### X-3:goose 00048 三表 — deferred → SWBOOT-10/W5b
- **现状证据**:`project_types` / `compliance_profiles` / `project_type_workflows` 已建表有种子,但 API 走硬编码 `swboot.ProjectTypesCatalog()` / `ComplianceProfilesCatalog()`;`project_source_bindings` / `repo_path_allowlist` 零运行时读写;`RepoAllowlist` 仅 stub + 单测。
- **决策**:标记 deferred,归 W5b/SWBOOT-10;**不改 schema**。
- **理由**:FEATURE-MATRIX 明确 SWBOOT-10 仍 stub;DB 化消费方与受控执行器需独立安全评审。
- **影响范围**:`catalog.go` / `repo_allowlist.go` 注释;long-term 软件自举文档追加一行。
- **验收**:`go test ./internal/swboot/...`;diff 仅注释与 long-term 文档。
### X-4:`system_settings` 6 未接线键 — 保留待二期
- **现状证据**:白名单 7 键中仅 `workflow.allow_author_only_approval` 有消费方;其余 6 键(`ui.maintenance_notice`、`ui.read_only_mode`、`chat.default_session_role`、`tasks.default_auto_repair`、`kb.default_search_limit`、`notifications.stage_advance_reminder`)零业务读取。FEATURE-MATRIX 系统管理台「白名单项接消费方」列为二期。
- **决策**:保留白名单 + 逐键注释说明预期消费方;不删。
- **理由**:删除需改写多处白盒测试且收益低;机制先行符合一期设计,二期再接线。
- **影响范围**:仅 `internal/sysadmin/settings.go` 注释。
- **验收**:`go test ./internal/sysadmin/...`;diff 仅注释。
### X-5:前端死组件/死 API — 删除
- **现状证据**(`web/` 全目录扫描,排除自身):
- `DocumentNotificationList` / `WorkflowPrerequisiteBanner` / `SettingsModal`:仅自身文件命中;`App` 使用 `UserSettingsModal`。
- `activateWorkflow`(`api/projectWorkflow.ts`):仅定义处;实际用 `activateWorkflowInstance`。
- `saveMessages`:已 `@deprecated` no-op,仅定义处。
- 级联:`patchNotification` 唯一调用方为 `DocumentNotificationList`。
- **决策**:删除上述 3 组件 + `activateWorkflow`(及类型)+ `saveMessages` + `patchNotification`;同步 import。后端 `PATCH /api/v1/notifications/{id}` 保留。
- **理由**:真死代码;删除降低误挂载与维护噪音;后端路由未经本波审计故不删。
- **影响范围**:见删除清单;无 barrel / 无专用单测。
- **验收**:`cd web && npm test && npm run build`;`rg` 无残留(`activateWorkflowInstance` 除外)。
## 证据 / 备注
基线 tip:`a12c947`(Wave 4 已合入本地 `.worktrees/dev-rdev-merge` `dev`)。
@@ -0,0 +1,51 @@
---
title: "Wave 6:文档漂移修复(D-1~D-6)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor-Auto
branch: docs/wave6-doc-drift
worktree: "-"
mutex: doc-drift
---
# Wave 6:文档漂移修复(D-1~D-6)
## 目标
按系统体检整改方案 Wave 6,逐项关闭文档漂移 D-1~D-6,使 SSOT(audit/INDEX、remediation/INDEX、FEATURE-MATRIX、PROJECT.md、backlog、ADR、handoff、PU8 契约)口径一致。
## 范围
- D-1(含附带的 short-term 归档)、D-2、D-3(复核)、D-4、D-5、D-6
## 非目标
- Wave 5(X-1~X-5)及其涉及的任何代码;不升 tier;不接线 REPLACE;不改 FAV;项目 143 只读;不删除 D7 对话数据
## 步骤
1. [x] D-1 契约状态回标 + 归档两份 short-term 任务文件
2. [x] D-2 ADR 状态改 accepted
3. [x] D-3 复核 INDEX 末行(无改动)
4. [x] D-4 handoff 回标闭环
5. [x] D-5 backlog D3/D7 同步
6. [x] D-6 PROJECT.md §9 对齐
7. [x] remediation/CURRENT 收口 + test-report + 合入本地 `dev`
## 验收标准
- [x] D-1~D-6 每项均有落盘证据或复核记录
- [x] `go build ./...` / `go vet ./...` / `npm run build` 全绿(无代码改动,防误伤)
- [x] remediation Wave 6 行改 done;勾选「D-1~D-6 全部回链关闭」
- [x] CURRENT 焦点/认领表/集成槽位三处一致
## 相关链接
- Remediation: [../../remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Audit: [../../audit/2026-09-17-system-health-check.md](../../audit/2026-09-17-system-health-check.md)
- Test report: [../../test-reports/2026-09-18-wave6-doc-drift-test-report.md](../../test-reports/2026-09-18-wave6-doc-drift-test-report.md)
## 证据 / 备注
基线 tip:`2ce2625`(`merge: fix/wave5-deadcode-decisions`)。mutex=`doc-drift`,未复用 `architecture-docs`。FEATURE-MATRIX 交叉检查无改动(D3 done/shadow、D7 deferred、U9–U12 done、`production_ready=yes` 与本次回标一致)。
@@ -0,0 +1,101 @@
---
title: "Wave 7:既有 roadmap 收口(编排确认)"
status: done
created: 2026-09-18
updated: 2026-09-18
owner: Cursor-Auto
branch: docs/wave7-roadmap-orchestration
worktree: "-"
mutex: roadmap-orchestration
---
# Wave 7:既有 roadmap 收口(编排确认)
## 目标
对照 FEATURE-MATRIX 剩余工作列,为 T1/W5、T1/W6、T1/W7、T2、T4、T5/T6/T8 各写一条编排确认;不改变任何能力实现状态。
## 范围
- 六条编排确认文案落盘(见「确认记录」)
- remediation Wave 7 行改 done 并回链本记录
- CURRENT 焦点改为 Wave 0–7 done,并记录 Control Center 双实现发现
## 非目标
- 不实施 SWBOOT-10;不升 FAV live / 不改 `FAV_DEGRADED_READ`;不按 D7 物理删除数据;不升 `MULTI_INTENT_PLAN_TIER`;不接线 `SEMANTIC_SUMMARY_REPLACE`;项目 143 只读
- 不改 FEATURE-MATRIX 状态列;不改 gap-matrix 发布门禁
- **不补 Wave 6 D-5**:D-1~D-6 已在 `a88ed85` PASS,backlog D3/D7 已同步;本波不改 `.doc/backlog/chat-agent-p6-backlog.md`,不把 Wave 6 再标一遍
- 不决定 Control Center 两套实现的取舍:不合并、不删除 `feature/control-center-server`
## 步骤
1. [x] 跳过步骤 0(Wave 6 D-5 已完成)
2. [x] 六条编排确认落盘(本文件)
3. [x] remediation Wave 7 行改 done + 回链本记录
4. [x] CURRENT 焦点改为「Wave 0–7 done」+ 记录 Control Center 分支冲突发现
## 验收标准
- [x] 六项编排确认均含:当前状态、关闭条件、是否需用户授权、建议下一触发点
- [x] 无一项被伪装为已实现;FAV/D7/tier 升级仍标注「需用户显式授权」
- [x] Wave 6 保持已关闭,未重复改写
## 相关链接
- Remediation: [../../remediation/2026-09-17-system-health-remediation-plan.md](../../remediation/2026-09-17-system-health-remediation-plan.md)
- Audit: [../../audit/2026-09-17-system-health-check.md](../../audit/2026-09-17-system-health-check.md)
- 总控: [../../remediation/2026-09-16-partial-deferred-completion-plan.md](../../remediation/2026-09-16-partial-deferred-completion-plan.md)
- Test report: [../../test-reports/2026-09-18-wave7-roadmap-orchestration-test-report.md](../../test-reports/2026-09-18-wave7-roadmap-orchestration-test-report.md)
## 确认记录
### T1/W5:SWBOOT-10
- **当前状态**:SWBOOT-00~09(契约、迁移、目录、UI、docs_only 真实 PI)已合入 `dev`([long-term](../long-term/2026-09-14-software-project-bootstrap-implementation.md)、[W5a 报告](../../test-reports/2026-09-17-w5a-software-bootstrap-ui-pi-test-report.md))。SWBOOT-10(受控工程执行:repo allowlist、worktree、patch/test/merge 分段批准)仍为 **stub only**,保持 fail-closed,归 W5b,本轮未启动。goose 00048 三张关联表(`project_source_bindings` / `repo_path_allowlist` / `project_type_workflows`)已在 Wave 5 X-3 标记 deferred。
- **关闭条件**:独立安全评审通过 + SWBOOT-10 非 stub 真实实现 + 真实 PI 全链路证据 + UI 二次验收(见 [partial-deferred-completion-plan §W5](../../remediation/2026-09-16-partial-deferred-completion-plan.md))。
- **是否需用户授权**:**需要**。独立安全评审本身即用户授权门槛;红线明确「不实施 SWBOOT-10 真实执行器」。
- **建议下一触发点**:用户就 W5b 受控执行器单独立项、批准安全评审范围后,从 `dev` 开 `feature/swboot-10-w5b`(mutex `workflow-design`)按 long-term 拆分实施。本波不动代码,fail-closed stub 原样保持。
### T1/W6:FAV live 放量
- **当前状态**:W6 shadow 已合入 `dev`([short-term](2026-09-17-w6-fav-subscriber-shadow.md)、[报告](../../test-reports/2026-09-17-w6-fav-subscriber-shadow-test-report.md)):`ObserveShadow` 只计算 intended outcome、不写业务副作用;负例覆盖 degraded read 拒绝 / `HandleLease` / `Register(fav)` fail-closed。三环境 compose 既有声明为 `FAV_DEGRADED_READ` 默认 false、`FAV_PUBLISHER_ENABLED` 默认 false。**live 未放量**。本波未改 compose。
- **关闭条件**:按固定顺序 staging → artifact → publication 逐 consumer live,每级 shadow → drain → live,观察窗 ≥7 天或 ≥N 终态样本(取更严);`FAV_DEGRADED_READ` 全程保持 false;崩溃/重启幂等证据;**禁止整支 merge** `feature/final-artifact-vault`(见 [partial-deferred-completion-plan §7.4](../../remediation/2026-09-16-partial-deferred-completion-plan.md))。
- **是否需用户授权**:**需要**。红线明确「不升 FAV live / 不改 `FAV_DEGRADED_READ`」。
- **建议下一触发点**:用户批准 staging 级观察窗起点后,从 `dev` 开独立 flag 分支(mutex `events`),先跑 staging ≥7 天观察窗并归档证据报告,再评估升 artifact/publication。本波不推进放量。
### T1/W7:D7 对话数据治理
- **当前状态**:ADR 草案([2026-09-17-d7-chat-data-retention.md](../../adr/2026-09-17-d7-chat-data-retention.md),`compliance: pending-compliance-signoff`)已落地;只读数据分类盘点已完成([audit](../../audit/2026-09-17-d7-data-inventory.md),`status: done`),**未发现**当前基线违反已确认合规/安全约束,因此**未**写入 gap-matrix blocker。合规签字前禁止按 365/180/30 天草案数字执行物理删除或备份清除。Wave 6 已把该现状同步进 backlog D7 行,本波不改该文件。
- **关闭条件**:合规签字或改数 → ADR 状态改 `accepted`/`signed` → 按签字口径落地整改(soft-delete 写路径 → 观察窗 → 物理清理;备份二次批准 + delete manifest)→ FEATURE-MATRIX D7 行升 `done`;若盘点期间发现违规则立即升 gap-matrix(本轮未触发)。
- **是否需用户授权**:**需要**。合规签字是产品/法务决策,非工程可自行拍板;红线明确「不按 D7 物理删除数据」。
- **建议下一触发点**:用户/合规负责人对 ADR 草案数字表签字或提出修改意见;签字后开独立 short-term 任务按 ADR 决策落地。
### T2:Control Center 前端 SPA 七页人工走查
- **当前状态**:2026-09-17 审计结论已过期,不能按「仅剩前端走查」收口。FEATURE-MATRIX「个人工程中控台」行已通过 `engineering-dashboard`(CLI `serve`/`export`,四轴模型)达到 **done** 一期,已合入 `dev`([报告](../../test-reports/2026-09-17-engineering-dashboard-test-report.md))。审计 T2 所指「后端 P0–P6 已签,仅剩前端 SPA 七页人工走查」实为 Kimi 的 `feature/control-center-server`:自身 11 commits(P0 skeleton → P6 design spec + LAN bind + agent-integration),**从未合入 `dev`**。2026-09-18 相对 `dev@a88ed85` 实测:merge-base `adb48c8`,落后 **136** commits(研究快照曾记 128,以本次 `rev-list` 为准),缺失 Wave 0–6。提交 `b5bacee`(`refactor(control-center): remove legacy engineering-dashboard, superseded by control-center`)试图删除已合入并验收的 `engineering-dashboard`,与 canonical 实现冲突。该分支的任务声明与 CURRENT 认领只存在于分支本身,未反映在 `dev` 主线。实现范围(pgvector 文档向量库、P3 SPA、P5 定期审计 + LLM 复核)超出已批准设计一期边界。
- **关闭条件**:FEATURE-MATRIX 该行**已经 done**(通过 engineering-dashboard)。若要转向「复活/合并 Kimi 实现」,需先有独立决策与重新规划,不属于「仅剩一次前端走查」。
- **是否需用户授权**:**是**。授权对象是「两套实现如何取舍」,不是「批准做前端走查」。本波只读编排确认,不能代为废弃或合并该分支。
- **建议下一触发点**:请用户明确二选一:(a) 维持现状——`engineering-dashboard` 为唯一 canonical 实现,`feature/control-center-server` 由用户决定归档或保留(推荐:已 done 且范围经批准);或 (b) 要求评估合并该分支的增量能力(SPA / pgvector / 定期审计)。触发后再开对应短期任务。本波只记录事实与建议,**不合并、不删除**该分支。
- **后续裁决(2026-09-19)**:用户决定进度管理由独立项目承担。本仓库已删除 Control Center 代码与文档,不恢复 `engineering-dashboard`。见 [移除任务](./2026-09-19-remove-control-center.md)。
### T4:首次加载性能 U1/U3–U7
- **当前状态**:仅 U2(静态资源交付)done——自托管字体、构建期 br/gzip、`/assets/*` 404 修正;主 JS 传输 2.82 MB → ~624 KB,登录冷缓存可见 ~205ms([报告](../../test-reports/2026-09-17-initial-load-perf-u2-test-report.md))。U1(完整性能基线)、U3(登录壳按需加载)、U4(初始化扇出收敛)、U5(认证请求去重)、U6(列表/租约按证据优化)、U7(重启后首访链路)**均未开始**。
- **关闭条件**:按 [方案](../../remediation/2026-09-17-initial-load-performance-plan.md) Definition of Done——R1–R6 逐项有前后对比 + 真实 UI 证据;未覆盖项明确列残余,不因 health PASS 关闭;完成后更新任务/CURRENT/FEATURE-MATRIX/test-report。
- **是否需用户授权**:不需要额外专项授权(方案已 planned 且范围已批准);需要工程排期认领(估算 U1–U5 约 3.5–7 人日,U6 另需 2–4 日,U7 另需 0.5–1.5 日,非承诺)。
- **建议下一触发点**:任一 Agent 从 `dev` 开分支认领 U1(P0,是后续单元的前置依赖)即触发;建议顺序 U1 → U2(done)/U3 与 U7 → U4/U5 → 按数据选 U6。
### T5/T6/T8:backlog 类(按收益触发)
- **T5 选择性模块解耦 M4–M6**:**当前状态** `planned`,owner=TBD,未开始([long-term](../long-term/2026-09-14-selective-module-decoupling.md))。触发条件中「M1–M3 test report 全部 PASS」已满足(文档可靠性试点 / 可靠事件核心均 done),但「同类缺陷触达文件数和运行故障率表明继续解耦具有收益」证据尚未出现,暂不触发。**关闭条件**与是否授权见该文档触发条件段。**是否需用户授权**:无需专项授权,按收益证据 + owner 认领即可开工。**建议下一触发点**:出现同类缺陷证据或 owner 主动认领。
- **T6 产品 backlog(B5/A5/A6/A7/D5)**:[backlog](../../backlog/chat-agent-p6-backlog.md) 仍列 B5(报价复核)、A5/A6(小队降级 + trace)、A7(注释迁移)、D5(KB 按环境隔离评估)为纯 backlog,无任务文件、无 owner。**D3、D7 已由 Wave 6 同步**(D3 标已实现 shadow 并回链;D7 回链 ADR 草案与只读盘点,合规签字前不整改)。本波不改该文件。**关闭条件**:开放项按产品收益单独排期开短期任务。**是否需用户授权**:开始评估不需要专项授权;D3 REPLACE 灰度、D7 整改分别仍受各自红线约束。**建议下一触发点**:产品侧提出具体收益诉求;无固定时间表。
- **T8 IAM 收尾开放项**:410 退役策略已冻结为「保留,非缺口」([决策](../../audit/2026-09-16-bug11-410-retire-decision.md),gap-matrix BUG-11 PASS);R13 数据安全清单 7 项全部 PASS,仅「完整红队注入矩阵」标记为开放增强、不挡基线;IAM 全路由 inventory 仍标记「开放」([handoff](../handoffs/2026-09-16-phase3-leftover-closeout.md)),fail-closed 核心已签。均为**加固类,非发布 blocker**。**是否需用户授权**:不需要专项授权,可按运维遥测随时另开 audit/任务。**建议下一触发点**:410 路由遥测证明零流量后可另开退役任务;或需要更强出站安全保证时另开红队 audit。
## 新发现(需用户后续裁决,不阻塞本波收口)
- **Control Center 双实现冲突**:当时未合入。2026-09-19 用户裁决为移出本仓库,代码与专属文档已删除,不恢复旧工程中控台。见 [移除任务](./2026-09-19-remove-control-center.md)。
## 证据 / 备注
基线 tip:`a88ed85`(`merge: docs/wave6-doc-drift`)。mutex=`roadmap-orchestration`。零 Go/TS/SQL/compose 改动。FEATURE-MATRIX 状态列未改。
@@ -0,0 +1,56 @@
---
title: "移除 Control Center,本仓库回到智能体系统"
status: done
created: 2026-09-19
updated: 2026-09-19
owner: Cursor-Auto
branch: fix/remove-control-center
worktree: "-"
mutex: controlcenter
---
# 移除 Control Center
## 目标
项目进度管理已由独立项目承担。从本仓库删除 Control Center 的代码、部署、规范和专属文档,不恢复旧 `engineering-dashboard`。
## 范围
- 删除 `cmd/control-center`、`internal/controlcenter`、`control-center/web`、`deploy/control-center`、`scripts/control-center.sh`
- 删除专属设计、任务、测试报告与截图
- 更新 AGENTS、FEATURE-MATRIX、CURRENT、模块边界与断链引用
- 停掉 `control-center-db` 与 `127.0.0.1:8790`
## 非目标
- 不恢复 `engineering-dashboard`
- 不 push
- 不改产品 `internal/server`、产品前端或三环境 compose
## 步骤
1. [x] 从本地 dev 开 `fix/remove-control-center`
2. [x] 删除代码与文档并更新引用
3. [x] 停运行时
4. [x] `go vet` / `go test -short` / 产品前端 build / archtest
5. [x] 合入本地 dev 并做健康检查
6. [x] 删除未跟踪的 `control-center/web/node_modules` 与本地分支 `feature/control-center-server`
## 验收标准
- [x] 仓库内不再有 Control Center 源码或专属文档
- [x] `go vet ./...`、`go test -short ./...`、`go test ./internal/archtest/`、`web` 的 `npm run build` 通过
- [x] 本地 dev 健康检查 200
## 相关链接
- Checklist:
- Handoff:
- Test report: [../../test-reports/2026-09-19-remove-control-center-test-report.md](../../test-reports/2026-09-19-remove-control-center-test-report.md)
## 证据 / 备注
用户确认:只移除 Control Center,副本已在别处实现,合入本地 dev。
2026-09-19 复查:产品代码、模块边界、AGENTS 规范、容器与端口均无残留。另删除未跟踪目录 `control-center/`(仅 `node_modules`)和本地分支 `feature/control-center-server`(`55fa8dd`)。未删除 `origin/feature/control-center-server`。`go build ./...` 通过。
@@ -0,0 +1,50 @@
---
title: "系统深度体检审计(独立审查潜在缺陷与未完善点)"
status: done
created: 2026-09-19
updated: 2026-09-19
owner: Cursor
branch: docs/audit-remediation-backlog
worktree: "-"
mutex: audit
---
# 系统深度体检审计(2026-09-19)
## 目标
在不改业务代码的前提下,对当前 dev(e8ed33b)做一次独立深度审查,输出 `.doc/audit/` 审计笔记,列出潜在 bug 与未完善项并给出严重度分级。
## 范围
- Go 静态验证:`go vet ./...` + `go test -short ./...`
- 后端:server 路由/chat SSE/docgov/events 错误处理与并发风险
- 前端 web:错误处理、SSE 重连、竞态
- 配置:flag 默认值一致性、死代码、环境差异(dev/test schema 漂移)
- 安全:IAM 旁路、密钥泄露面
- DB:goose 迁移一致性与回滚风险
## 非目标
- 不修改业务代码(docs-only 分支)
- 不验证已明确 deferred 的事项本身(FAV live 放量、D7 签字、SWBOOT-10)——仅核对声明与代码是否一致
## 步骤
1. [x] 创建 docs 分支、登记 CURRENT
2. [x] go vet + go test -short
3. [x] 并行子代理深潜后端/前端/配置/DB/安全
4. [x] 汇总撰写 audit 笔记并提交
## 验收标准
- [x] 每个发现均有代码路径 + 行号证据
- [x] 严重度分级(critical/high/medium/low)
- [x] 与 FEATURE-MATRIX 已声明的 partial/deferred 项对齐,不重复申报
## 证据 / 备注
- go vet 零告警;go test -short 55 包全 PASS(dev@e8ed33b)
- 审计笔记:[.doc/audit/2026-09-19-system-deep-audit.md](../../audit/2026-09-19-system-deep-audit.md)
- 五路并行只读深潜全部完成;四条红线核实一致;新发现 4 critical(C1 docgov 吞错 / C2 Session 竞态 / C3 SSE 超时 / C4 工作流竞态)+ 10 high
- 整改:critical/high 已分四批合入 `dev`(`844f757` / `08f4e0b` / `a2a49a6` / `d73bc79`)。medium/low 见 [long-term](../long-term/2026-09-19-audit-remainder.md)。
@@ -0,0 +1,58 @@
---
title: "修复系统权限设置与项目协作多项缺陷"
status: done
created: 2026-09-20
updated: 2026-09-20
owner: Cursor-Auto
branch: fix/bug-hunt-2026-09-20-permissions-and-uploads
worktree: "-"
mutex: authz+web+projectworkflow
---
# 修复系统权限设置与项目协作多项缺陷
## 目标
修复两轮排查确认的 12 处后端/前端缺陷(CSP/PDF、系统设置 CAS、任务错误误分类、task-run 403、成员管理 RBAC、注册吞错、强制改密复发、项目重名、无项目可对话、右侧栏不记忆等)。
## 范围
- CSP `frame-src` + PDF blob 预览
- 系统设置 `expected_revision` 全链路
- `ProjectSettingsApiError` httpStatus/errorCode 别名
- task-run 查看放宽为项目成员;前端 403/404 停轮询
- `project:manage_members` 权限位(迁移 00055)
- memStore 成员可见性
- CreateUser 吞错 / 400·500 分类 / LooksInternal
- 强制改密 session 嵌套字段 OR 复活
- CreateProject `client_key` 幂等 + `(creator, name)` 唯一(迁移 00056)
- 无项目禁止对话 + 发送按钮置灰
- 右侧工具栏默认收起并持久化
## 非目标
- 全局项目名唯一(仅同创建人内唯一)
- 放宽 `frame-ancestors` / `X-Frame-Options`
## 步骤
1. [x] 后端 CSP / authz / auth / projectworkflow / chat 入口
2. [x] 前端 PDF / settings / 错误别名 / 轮询 / RBAC UI / 改密 / 建项幂等 / InputArea / AppShell
3. [x] 迁移 00055 / 00056 + 单测
4. [x] `go vet` / `go test -short` / `npm test` / `npm run build`
5. [x] 占集成槽位合回 `dev`
## 验收标准
- [x] 代码与契约补齐(见 audit 笔记)
`- [x] 短测与前端构建通过
`- [x] 合入 `dev`
## 相关链接
- Audit: `.doc/audit/2026-09-20-bug-hunt-permissions-uploads.md`
- Plan: `.cursor/plans/修复系统权限设置与项目协作多项缺陷_ff3242f7.plan.md`
## 证据 / 备注
分支:`fix/bug-hunt-2026-09-20-permissions-and-uploads`
@@ -0,0 +1,226 @@
---
title: "FEATURE-MATRIX partial/deferred 全量收口计划"
status: in_progress
created: 2026-09-16
updated: 2026-09-17
type: refactor
owner: Cline
branch: docs/partial-deferred-completion-plan
mutex: architecture-docs
---
# FEATURE-MATRIX partial/deferred 全量收口计划
## 1. 背景
- **用户授权(2026-09-16)**:已设计的功能与特性尽量推进到 `done`,不停留在 `partial`/`deferred`;保持功能、模块的独立与解耦;确认模块间通信机制;建立系统契约,保证新功能添加、已有功能修改的影响面收敛在所属模块,不扩散到其他模块。
- **收口对象**:[FEATURE-MATRIX](../status/FEATURE-MATRIX.md) 中 6 行 `partial` + 1 行 `deferred`(见 §3 总表)。
- **上位约束**:`production_ready=yes` 与发布门禁 B1–B4 已签。本计划是**能力成熟度收口**,与发布门禁正交;`production_ready` 只由 [gap-matrix](./gap-matrix.md) 决定,本计划不得反向触碰已签门禁。
- **通信机制结论先行**:本系统为模块化单体,模块间通信**不采用、也不应改成通用 IPC/RPC**;已确认的跨进程边界全部走 HTTP 与 PG 持久事件。详见 §2。
## 2. 通信与解耦机制确认(IPC/RPC 问题的回答)
**结论:系统是模块化单体([ADR 2026-09-14-modular-monolith-decoupling](../adr/2026-09-14-modular-monolith-decoupling.md)),模块级隔离靠「消费者窄端口 + 组合根唯一装配 + 契约门禁」实现,而非 RPC 层。**已确认的通信边界共四类:
| 边界 | 机制 | 状态 |
|---|---|---|
| Web ↔ server | `/api/v1/*` HTTP + SSE(typed error envelope) | 已运行 |
| Go server ↔ PI Agent Runner | HTTP + Bearer(typed-result-v1) | 已运行 |
| 单体内模块 | 消费者窄端口 + `internal/app` 组合根唯一装配 | 已运行 |
| 跨进程领域事件 | PG outbox(envelope/delivery)+ `cmd/events` 独立 worker 原子 lease 消费 | 已运行(notify/advance/projection live) |
**为什么不把单体内端口改成 RPC**(依据 [IPC/RPC 现状评估](../ops/research/2026-09-15-module-decoupling-ipc-assessment.md)):RPC 会增加序列化、延迟、部分失败与运维成本,却不消除 locator、授权、幂等和事件消费缺口;真正的进程级解耦已由 `cmd/events` worker(经 PG lease,而非服务间直连)与两条 HTTP 边界承担。用户要求的「通过 IPC/RPC 通信」在本系统的正确落法即:**跨进程一律走既有 HTTP / PG 事件边界;模块级独立解耦靠端口与契约门禁**。若未来确需新增跨进程边界,须先立 ADR,沿用「HTTP 或 PG 事件」两种既有模式。
### 2.1 系统契约体系(防扩散的既存机制,本计划全部沿用)
| 契约 | 载体 | 强制方式 |
|---|---|---|
| Import / SQL write / path / event 边界 | `.doc/system-design/module-boundaries.yaml` | `internal/archtest` + `./scripts/arch-check.sh --mode block`;import/event 违规零容忍(block_kinds) |
| 领域事件 schema 与生产者/消费者 | `events.Envelope` schema 1 + YAML allowlist ↔ `StaticContracts` parity | 构建期 parity 门禁;未登记事件不得投递 |
| 任务幂等与产物 | `taskrun.RunManifest` canonical JSON + SHA-256 + idempotency key | 服务端强制;异 digest 冲突 |
| HTTP 错误语义 | typed error envelope(details allowlist + 脱敏) | 已合入(H1–H3) |
| PI Runner 协议 | typed-result-v1 + handshake;typed 字段存在但无效 → fail closed | 已合入 |
| 能力灰度 | 每能力独立 flag,默认 off / legacy / shadow | 各契约预注册晋级阈值 |
| 并行认领互斥 | FEATURE-MATRIX `mutex` 列 → CURRENT 认领表 | 同一 mutex 同时仅一个 `in_progress` |
### 2.2 变更影响面收敛守则(每个波次必须遵守)
1. 新能力一律落在**深模块**(模式参考 `internal/app/intentflow`、`internal/doccontent`),禁止把实现聚集回 coordinator/bizdev。
2. 模块间只允许三种交互:消费者拥有的窄端口、组合根装配、领域事件;**禁止新增跨模块 import**(arch-check block 兜底)。
3. schema 变更只走 additive migration;旧版本兼容读取;每个放量有独立回滚点。
4. 每个能力一个独立 flag;默认 off;晋级按预注册阈值(shadow → confirm → live/replace),禁止共用开关批量上线。
5. 新增事件必须同时补 YAML allowlist 与 `StaticContracts` 并过 parity 门禁。
6. 修改声明范围须保留 before/after lineage 与义务迁移(矩阵更新规则 4);禁止缩口径假完成。
## 3. 收口对象与关闭条件总表
| # | 行 | 当前 | 目标 done 的关闭条件(依据矩阵「剩余工作/关闭条件」列) | mutex |
|---|---|---|---|---|
| P1 | CI / E2E | partial | Actions secret/runner 环境配置完成 + FullNone product_fail 收口 + 一轮绿色 nightly receipt | `ci` |
| P2 | 语义摘要(D3) | partial | `SEMANTIC_SUMMARY_SHADOW` 开启并取得真实 PI + R13 + 负例证据;(可选)`SEMANTIC_SUMMARY_REPLACE` 灰度 | `chat` |
| P3 | PI change-report 叙事 | partial | `PI_CHANGE_REPORT_NARRATIVE` 开启 + 真实 PI 叙事 + fallback 全量负例 + UI narrative/事实字段区分 | `docgov` |
| P4 | 多意图扩面(U9–U12) | partial | U9→U12 逐 action 独立 flag 证据闭环(真实 PI + 浏览器 + 负例);tier 升级评估 | `intent-plan` |
| P5 | 纯软件项目自举 | partial | SWBOOT-10 非 stub 实现 + 真实 PI 全链路 + UI 二次验收 | `workflow-design` |
| P6 | Final Artifact Vault(FAV) | partial | subscriber 独立审计 → shadow → live;崩溃/重启幂等;`FAV_DEGRADED_READ=false` 保持;**禁止整支 merge 保持** | `events` |
| P7 | 对话数据治理(D7) | deferred | 数据分类盘点 → 留存/删除口径 → 库/备份/日志控制 → 敏感字段加密边界;**发现违规 → 立即升 gap-matrix blocker** | `chat` |
**并行度**:P1 与其余全部可并行;P3/P4/P5/P6 各自 mutex 互不冲突可并行;**P2 与 P7 共用 `chat` mutex,须串行(先 P2 后 P7)**。Playwright 双标签升 `confirm/full` 属 `intent-plan` 辅助任务(见 [2026-09-16-intent-plan-playwright-dual-tab](../ops/long-term/2026-09-16-intent-plan-playwright-dual-tab.md))。
## 4. 分波次计划
每波通用流程:从 `dev` 开独立分支(`feature/<slug>`)→ CURRENT 登记 → worktree 编码与单测 → 占集成槽合并 `dev` + 冒烟(`go vet` / `go test -short` / `env-service.sh dev rebuild` + `/health`)→ test-report 归档 → FEATURE-MATRIX 行升 `done`(保留 lineage)。
### W1(mutex `ci`):CI / E2E → done
**现状**:nightly 入口 + 失败分类 + promotion-receipt 门禁已交付;TempDir race 已修;PR CI 不依赖外部模型。剩余:环境配置与 FullNone product_fail。
1. Actions secret 录入:`TEST_DATABASE_URL`、nightly 专用 `RUN_PI_E2E` / `RUNNER_AUTH_TOKEN`(隔离合成数据);runner 注册与自检。
2. FullNone product_fail 收口:按 infra/product 分栏定位,修复产品失败或确认分类归属;nightly `DATA_DIR=dev` 保持对齐。
3. 跑一轮完整 nightly → green receipt 归档。
4. 矩阵行升 `done`(证据:[Wave2B](../test-reports/2026-09-16-wave2b-nightly-promotion-receipt-test-report.md)、[Wave2C](../test-reports/2026-09-16-wave2c-same-image-digest-test-report.md) + 新 green receipt)。
**回滚**:纯环境/CI 配置,不影响业务行为;secret 配置错误仅影响 nightly,不挡 PR CI。
### W2(mutex `chat`):PU6 语义摘要 D3 → done
1. dev 环境 `SEMANTIC_SUMMARY_SHADOW=on`(test 环境随后),收集 shadow 对账:authorized view only、无工具权限摘要器、R13 出站门。
2. 真实 PI(MiniMax)摘要证据:freshness 标注、可解释 fallback。
3. 负例矩阵:撤权消息不入摘要;injection 不能改权限;失败保留旧摘要/deterministic。
4. 达预注册阈值后 **默认不启用** `SEMANTIC_SUMMARY_REPLACE`(见 §7.3);若另开授权再灰度(独立回滚:关 flag 回 deterministic)。
5. 矩阵行升 `done`;[契约](../ops/long-term/2026-09-16-pu6-semantic-summary-contract.md)状态更新。
**路径**:`internal/ctxmgr/summarizer.go`、`internal/app/chatflow/`、`internal/server/chat_digest_api.go`、web 摘要组件。
### W3(mutex `docgov`):PU7 PI change-report 叙事 → done
1. dev `PI_CHANGE_REPORT_NARRATIVE=on`:真实 PI 只读消费 immutable diff+lineage+risk floor。
2. typed schema `change_report_narrative_v1` + input digest 绑定;任意 schema/超时/注入 → 全量 fallback(负例必测)。
3. UI 验收:narrative 与事实字段明确区分;禁止覆盖服务端风险/审批结论。
4. 矩阵行升 `done`(deterministic fallback 仍是本行显式声明行为)。
**回滚**:关 flag,仅 deterministic fallback,无第二份 candidate。契约:[pu7](../ops/long-term/2026-09-16-pu7-pi-narrative-contract.md)。
### W4(mutex `intent-plan`):PU8 U9–U12 → done
**顺序 U9→U10→U11→U12,逐 action 独立 flag,禁止共用开关批量上线:**
1. U9 `MULTI_INTENT_U9_SEGMENT`:真实 LLM 分段 shadow→confirm;规则无法判断时才出 proposal;stub fail-closed 保持。
2. U10 `MULTI_INTENT_U10_MUTATE`:dry-run + expected revision 门禁;未确认/越权/stale revision/重复提交 → 零越界副作用。
3. U11(docgov)、U12(workflow/run-control):按各自契约同模式推进。
4. 每个 action:真实 PI + Playwright 双标签 + 负例;独立报告与回滚点。
5. 全部闭环后:评估 `MULTI_INTENT_PLAN_TIER` legacy→confirm(**独立任务、独立授权**,默认不升 full;full 另拆行/backlog)。
6. 矩阵行升 `done`(声明范围 = 四个 action 的 flag 证据闭环;tier=full 不在本行关闭条件内)。
契约:[u9](../ops/long-term/2026-09-16-pu8-u9-segment-proposal-contract.md) / [u10](../ops/long-term/2026-09-16-pu8-u10-mutate-contract.md) / u11 / u12。
### W5(mutex `workflow-design`):纯软件项目自举 → done
1. SWBOOT-10 从 stub 收口为真实现(按 [short-term](../ops/short-term/2026-09-16-software-project-bootstrap.md) 与 [ADR keys](../adr/2026-09-16-software-project-bootstrap-keys.md))。
2. 真实 PI 全链路:`software_bootstrap` 工作流 创建→规划→交付(首期 docs_only / read_only_repo)。
3. Playwright UI 二次验收:服务端目录驱动的创建向导(停止前端固定克隆 7 份模板)、单人项目「无独立评审」显式标记。
4. 矩阵行升 `done`(范围沿用现状调研的复用/新增边界,不改医疗三工作流语义)。
### W6(mutex `events`):FAV → done
1. subscriber 独立审计(沿用 U7 增量路径,**继续禁止整支 merge FAV 分支**)。
2. publisher/consumer flag **shadow**:只计算 intended outcome,不执行业务副作用。
3. shadow 阈值达标后按 §7.4 逐 consumer **live**(顺序 staging → artifact → publication;每级观察窗 ≥7 天或证据阈值):幂等(唯一键/no-replace);崩溃/重启重放无重复可见结果。
4. `FAV_DEGRADED_READ=false` 保持默认;degraded 读取仅在显式开启时可用并有告警(不随 live 开启)。
5. 矩阵行升 `done`(声明范围:不可变终态制品库闭环)。
### W7(mutex `chat`,排在 W2 后):D7 对话数据治理 → done
**前提**:留存/删除口径见 §7.1 与 [D7 ADR 草案](../adr/2026-09-17-d7-chat-data-retention.md)(数字 `pending-compliance-signoff`;合规签字前禁止按建议数字执行物理删除/备份清除)。
1. 数据分类盘点(产出 audit 文档):chat_sessions/messages、KB、日志、备份、event 表中的敏感字段清单与流转路径。
2. 合规签字或改数后:更新 ADR 状态;库/备份/日志控制盘点。
3. 差距整改:日志/dead-letter/reconciliation 只存 ID、digest、typed error code 与 allowlist 摘要(Track E 红线沿用)。
4. 敏感字段加密边界决策与落地(首期默认不做字段级加密,见 §7.1)。
5. **若盘点确认基线违规 → 立即写 gap-matrix blocker,本行 done 让位于整改**;无违规且口径落地 → 矩阵行升 `done`。
## 5. 测试方案(层级矩阵)
| 层级 | 适用波次 | 内容 | 通过标准 |
|---|---|---|---|
| Arch / contract | 全部 | `./scripts/arch-check.sh --mode block`;YAML ↔ `StaticContracts` parity | import/event 违规 = 0;无未登记事件 |
| 单测 | 全部 | `go vet ./...` + `go test -short ./...`;相关包 `-race` | 全绿;无 data race |
| PG 集成 | W2/W4/W5/W6/W7 | `TEST_DATABASE_URL` 下集成 + additive migration/回滚演练 | 持久化、恢复、旧版本兼容读取 |
| 真实 PI | W2/W3/W4/W5 | 真实 PI Agent Runner + MiniMax;记录 model/protocol/typed result;R13 数据安全门(最小出站、租户绑定、脱敏、凭证最小权限、泄漏负例) | 无 stub 冒充;无敏感出站 |
| 浏览器 | W2/W3/W4/W5 | Playwright:真实登录、双用户/职责负例、刷新/重登/重启 | 页面结果与 PG/账本一致 |
| 部署 | 全部运行时波次 | 占集成槽 rebuild、`/health`、promotion receipt(same digest 晋升) | 可追到同一 commit + digest |
| 回滚 | W2–W6 | disable/drain、旧版本兼容读取、无双 writer、孤儿状态检查 | 上一版本恢复且无孤儿状态 |
每波验收报告归档 `.doc/test-reports/`(遵循 test-reports-standard),回链本计划与对应契约;矩阵状态提升必须同时核对源码、迁移、artifact、API/runtime 与测试层级(上位计划 R5–R7)。
## 6. 风险与停走门
| 风险 | 停走门 |
|---|---|
| 授权旁路 / 跨用户泄漏 / 双 writer / main 或 prod fail-open | 任一波发现 → 停止全部扩面,写 gap-matrix |
| B1–B4 门禁回归 | 每波合 dev 冒烟全绿;回归即停 |
| stub / SKIP / deterministic fallback 冒充真实 PI | 验收报告必须记录真实 runner/model;SKIP 不得写成 PASS |
| flag 批量上线 / 共用开关 | 一个能力一个 flag;违规合并打回 |
| 缩小声明范围制造 done | 矩阵审查:before/after lineage 必须保留,义务迁移可追 |
| 三环境隔离破坏 | 每波验证不跨环境读写;schema 迁移三环境同步(当前 47) |
| FAV 整支 merge | 保持禁止;只走增量分支 + 独立审计 |
## 7. 已确认决策(原开放问题;2026-09-17 用户确认采纳建议默认)
> 决策冻结 ≠ 放量:不改生产默认 env / flag;各波仍按原 mutex 与独立授权推进。
### 7.1 D7 留存期限与删除口径(W7 前置)
**决策**:工程按下列草案落 ADR([2026-09-17-d7-chat-data-retention](../adr/2026-09-17-d7-chat-data-retention.md));数字标 `pending-compliance-signoff`,合规签字或改数后 W7 方可按口径整改。不得无限期停在 deferred。
| 数据类 | 留存(建议默认) | 删除路径 |
|---|---|---|
| 会话正文(chat messages) | 热库 **365 天**可配置;超期 soft-delete → 观察窗 → 物理清理 | 用户删除同路径;备份清除需二次批准 + 精确 delete manifest(R22) |
| 派生文档 / 私密文档 | 与聊天**独立周期**;回收站 **30 天**后物理清理 | 删除 UI 必须说明「只删聊天 / 只删文档 / 两者」 |
| 审计元数据(导出/治理审计) | **180 天** | 不可被普通用户删除覆盖 |
| Agent trace / workspace 非终态 | 任务结束后 **30 天**;nightly 仅合成数据 | 禁止当长期事实源 |
| 日志 / dead-letter / reconciliation | Track E:**只存 ID、digest、typed error code、allowlist 摘要** | 禁止存 payload/prompt/正文 |
| FAV 终态制品 | `retention_class` + legal hold + delete ledger | 与 D7 聊天口径解耦 |
**加密边界**:首期「敏感字段盘点 + 传输/备份访问控制」;不默认上字段级加密。
**违规门**:盘点确认基线违规 → 立即写 gap-matrix;本行 done 让位于整改。
### 7.2 `MULTI_INTENT_PLAN_TIER` 是否升 `confirm`
**决策**:W4(U9→U12)证据闭环后,**可启动独立授权任务**将默认从 `legacy` 升至 `confirm`;**永不默认升 `full`**(`full` 另拆矩阵行/backlog,按 action 逐项加入)。
升 `confirm` 硬前置(全部满足):
1. U9→U12 各自独立 flag 证据闭环(真实 PI + Playwright 双标签 + 负例)
2. 停走指标全 0:未确认/越权副作用、安全红线绕过、hard-negative 自动执行、重复确认双跑、refresh/restart 权威差
3. 独立 short-term + 用户显式授权(合入功能代码不得顺带改默认 env)
4. 放量:`dev` 观察 → `test` → **不自动**推 `main`
### 7.3 `SEMANTIC_SUMMARY_REPLACE` 是否启用
**决策**:**默认不启用**。W2 升 `done` 只要求 `SEMANTIC_SUMMARY_SHADOW` + 真实 PI + R13 + 负例;**不依赖** REPLACE。REPLACE 为 W2 之后可选后置任务,须另开授权 + 接线 + fail-closed 灰度(`dev`→`test`;关 flag 回 deterministic)。
### 7.4 FAV live 消费者上线顺序与观察窗口
**决策**:固定顺序 **staging → artifact → publication**;每步 shadow → drain → live;观察窗证据驱动(每级下限 **≥7 天**或 ≥N 终态样本,取更严);`FAV_DEGRADED_READ` **全程保持 false**(不随 live 开启)。禁止整支 merge FAV;每 consumer 独立 flag;一窗失败则停在该级并回 shadow/off。
## 8. 验收标准(Definition of Done)
- [ ] W1–W6 各波 test-report 归档并回链;对应 FEATURE-MATRIX 行升 `done`(保留 lineage)。
- [ ] W7 数据分类盘点与口径文档落地;或违规升级 gap-matrix(该行转为整改跟踪)。
- [ ] 全程 `production_ready` 不翻转;gap-matrix 仅在真实 blocker 出现/关闭时变化。
- [ ] `arch-check --mode block` 全程通过;无新增跨模块 import、无未登记事件。
- [ ] 所有新 flag 保持独立且默认 off/legacy/shadow;每个放量有独立回滚点。
- [ ] B1–B4 门禁零回归(每波合 dev 冒烟全绿)。
- [x] 开放问题 §7 的四项决策均已获用户确认(2026-09-17;见 §7.1–§7.4)。
## 9. 相关链接
- 矩阵 SSOT: [../status/FEATURE-MATRIX.md](../status/FEATURE-MATRIX.md)
- 连续性审计: [../audit/2026-09-16-feature-matrix-production-readiness-audit.md](../audit/2026-09-16-feature-matrix-production-readiness-audit.md)
- 上位计划: [./2026-09-16-feature-matrix-production-readiness-plan.md](./2026-09-16-feature-matrix-production-readiness-plan.md)
- 发布门禁: [./gap-matrix.md](./gap-matrix.md)
- D7 留存 ADR 草案: [../adr/2026-09-17-d7-chat-data-retention.md](../adr/2026-09-17-d7-chat-data-retention.md)
- IPC/RPC 调研: [../ops/research/2026-09-15-module-decoupling-ipc-assessment.md](../ops/research/2026-09-15-module-decoupling-ipc-assessment.md)
- 模块解耦 Phase 2: [./2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md](./2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md)
- 契约: `../ops/long-term/2026-09-16-pu6-*` · `pu7-*` · `pu8-u9…u12`
- 总控 short-term: [../ops/short-term/2026-09-16-partial-deferred-completion.md](../ops/short-term/2026-09-16-partial-deferred-completion.md)
@@ -0,0 +1,347 @@
---
title: 文档编制人兼任审核批准 - Plan
type: feat
date: 2026-09-17
status: planned
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
---
# 文档编制人兼任审核批准 - Plan
## Goal Capsule
在系统管理员授权后,项目创建者可以为项目工作流中的每份文档单独启用「编制人兼任审核、批准」,只选择一位编制人即可完成该文档的全部人工职责。
本次交付为设计方案,尚未授权业务实现。已确认的需求是两级授权和逐文档配置。R9(激活前配置/激活后冻结)与 R10(关总开关后存量按冻结继续、不提供紧急熔断)已于 2026-09-17 审核批准,并补强 Heal 三入口投影稳定性为硬性验收项。实现与发布须分别提供源码、数据库、真实产品 PI 和浏览器证据。
基线为本地 `dev@adb48c8`,2026-09-17 源码核查;不代表正在运行的镜像已具备本能力。远端已 fetch,本地 dev 领先 origin/dev 44 个提交、落后 0。本方案不修改正式工作流定义,不将兼任等同于免审批。
---
## Product Contract
### Summary
新增管理员总开关,默认关闭;新增逐文档职责模式,默认沿用当前规则。创建者开启某份文档的兼任模式后,只填写编制人,审核人与批准人由服务端派生为同一人。仍执行送审、审核和批准,保留每一步身份、意见和时间。
### Problem Frame
当前系统仅允许可选文档三职全空或三职完整指定,且完整指定时要求三人不同。用户需要小团队或个人也能执行完整的文档治理流程,并由管理员控制这一例外是否可用。
当前权限、文档人员投影和前端角色识别使用不同数据路径。因此仅放宽三职分离校验不足以支持本需求,还必须保证配置、生成、查看、修改、审批和阶段推进使用同一份职责来源。
### Requirements
**权限与配置**
- R1. 仅系统管理员可开启或关闭系统级「允许编制人兼任审核、批准」权限,默认关闭。
- R2. 仅权威项目创建者可为自己创建的项目逐文档选择兼任模式;普通成员、项目角色管理员和其他项目创建者不能设置。系统管理员如果不是该项目创建者,也不因此获得逐文档配置权。
- R3. 每份文档独立选择,管理员开启总权限不自动修改任何项目或文档;新文档、新实例和复制产生的文档默认不继承兼任授权。
- R4. 兼任文档必须指定一名有效、在任的项目成员为编制人;可以不是创建者。审核与批准由该人承担,不能再指定其他审核人或批准人。
**审批与可见性**
- R5. 兼任模式属于纳入人工审批:保留送审→审核→批准三个动作、现有内容锁和驳回要求;不得生成完成后自动批准或通过阶段门禁。
- R6. 未开启兼任的文档继续遵守当前三职分离与可选免审批规则;必需文档不得借兼任模式省去编制人或审批。
- R7. 设置页、冻结快照、文档详情、操作按钮、签署展示与日志一致显示兼任关系;同一个人能在正确状态执行对应职责动作。
- R8. 兼任不授予系统管理员、创建者或其他成员代审权,也不扩大跨项目读取、非当前阶段写入和已结束实例写入权限。
**生命周期与持久化(已审核批准,2026-09-17)**
- R9. 首期仅在工作流激活前配置;激活时冻结该文档模式和职责,运行中的实例不直接改规划。已激活的存量项目不自动转换。若用户要求运行中转换,必须先扩展本方案的受控职责变更单元,不可悄悄放开现有 PUT。
- R10. 管理员关闭总开关后,禁止新启用、保存仍含兼任的规划和激活兼任规划;允许清除兼任后保存。已激活的兼任实例按冻结授权继续执行,历史日志不变。界面必须解释该开关是「授权新配置」,不是紧急停用所有存量审批;本期不提供针对已激活实例的紧急撤销/熔断能力。
- R11. 模式、编制人、授权依据、配置版本及各步骤日志需持久化,刷新、重登和服务重启不得丢失。
- R12. 编制人离任或账号停用后,不得继续执行三项职责;阻断尚未完成动作并展示原因,不自动找替代人,不重写历史签署。
### Permission Matrix
| 操作 | 系统管理员但非项目创建者 | 当前项目创建者 | 普通项目成员 | 其他项目用户 |
|---|---|---|---|---|
| 修改系统总开关 | 允许 | 仅同时为系统管理员时 | 禁止 | 禁止 |
| 查看本项目可用模式 | 沿用当前项目读取权限 | 允许 | 沿用项目读取权限 | 禁止 |
| 规划期逐文档启停兼任 | 禁止 | 总开关开启才可启用;可关闭 | 禁止 | 禁止 |
| 指定编制人 | 禁止 | 规划期按 R4 | 禁止 | 禁止 |
| 送审、审核、批准 | 仅自己是该文档指定职责人时 | 同左 | 同左 | 禁止 |
| 已激活实例直接改职责 | 禁止 | 禁止(R9) | 禁止 | 禁止 |
### Mode Matrix
「文档启用」「纳入人工审批」「编制人兼任」是不同含义,不能复用一个开关。
| 文档状态/配置 | 输入 | 有效职责 | 审批与门禁 |
|---|---|---|---|
| 文档禁用 | 不设置职责 | 无 | 沿用 skipped_disabled |
| 可选文档免审批 | 三职全空,兼任关闭 | none | 沿用既有免审批规则 |
| 标准人工审批 | 三职齐全且三人不同 | full | 保留正常人工审批 |
| 兼任人工审批 | 兼任开启,仅编制人 A | author_only;有效三职为 A/A/A | 与标准审批同样要求最终批准 |
| 未开兼任却只填 A | 缺审核和批准 | partial | 拒绝 |
| 标准模式填 A/A/A | 三职同人 | 非法 | 继续拒绝职责分离违规 |
| 兼任开启但无 A | 缺编制人 | 非法 | 拒绝 |
| 兼任开启又填不同审核人 B | 矛盾输入 | 非法 | 拒绝,不能静默吞掉 B |
### User Flows
1. 管理员进入「系统管理台→系统设置→工作流治理」,开启总授权;页面显示保存结果、修改人和修改时间。
2. 创建者进入项目设置,展开某个阶段,在文档行开启「由编制人兼任审核、批准」。只保留编制人选择器,其余两项显示「同编制人(自动承担)」。其他文档保持原配置。
3. 保存并预览:摘要列出标准审批、兼任审批、免审批的份数,列出每份兼任文档及编制人。确认后冻结。
4. 编制人完成内容后送审,在审核中以审核人身份确认,在批准中以批准人身份确认;日志展示同一人对应三个职责,而非三个虚构人员。
5. 页面刷新、重新进入项目后仍显示同样配置;最终批准后才按现有阻塞条件满足阶段门禁。
### Scope Boundaries
本期覆盖所有通过项目工作流实例管理的文档,不针对某个任务名写白名单;freeform 文档与未绑定工作流的旧文档不提供此开关。不新增批量全选、不改项目成员全局 `document_duty` 为多角色,不自动改已发布工作流模板或历史签署。
**生命周期口径(已审核批准,2026-09-17):** R9 首期仅激活前配置、激活后冻结职责;R10 关闭总开关后禁止新启用/保存仍含兼任的规划/激活兼任规划,已激活实例按冻结授权继续执行。总开关是「授权新配置」,**不提供**已激活实例的紧急撤销/熔断能力;若业务需要合规级紧急止损,应作为独立后续方案,不在本期 Definition of Done 范围内。
---
## Planning Contract
### Current Implementation Evidence
以下为源码确认事实,不是运行验收结果。
| 位置 / 符号 | 当前行为 | 对本需求的影响 |
|---|---|---|
| `internal/projectinstance/types.go`:DocTaskPlan / DocDuty | 仅 enabled、approval_configurable 和三职 ID,无逐文档兼任标记 | 增加显式职责模式 |
| `internal/projectinstance/duty_mode.go` | none/partial/full;partial 拒绝;三职重复报 SEPARATION_OF_DUTY_VIOLATION | 不能只填作者或仅关闭分离校验 |
| `internal/projectinstance/validator.go`:validateActivationPlan / previewSummary | 激活至少 countFullDutyDocs>0;预览统计 full/none | 必须把合法兼任计为受治理文档 |
| `internal/projectinstance/service.go` | 创建者可保存/预览/激活;active 后 ErrPlanFrozen;已有 revision、plan hash、token | 复用规划流程,补全授权版本和事务检查 |
| `internal/projectworkflow/service.go`:IsProjectCreator | 权威项目创建者检查 | 不使用 UI 当前角色或项目 manager 代替 |
| `internal/projectinstance/store.go`:sync 子实例逻辑 | 从规划写 project_doc_task_instances 和三职 assignment | 兼任需派生三项实际职责,不能只存作者而漏审批归属 |
| `internal/projectinstance/duty_action.go` / `stage_access.go` / `gate.go` | 按动作校验单一职责;阶段可见性有 full 判定;门禁依赖 approved | 校验与阶段可见性都需认识新模式 |
| `internal/sysadmin/settings.go` / `store.go` | 白名单设置、DB 持久化;无该 key;只记录最后修改人时间 | 可复用管理入口,新增策略消费与历史审计 |
| `internal/server/admin_system_handlers.go` | 所有系统设置写入 requireSystemAdmin | 复用该入口,不开放管理列表给普通成员 |
| `internal/docduty/store.go`:HealProjectDocuments | 按项目成员默认职责扫描并回填所有 task_key 非空文档 | 可能覆盖逐文档三职,必须区分实例绑定与旧默认 |
| `internal/bizdev/service.go` / `internal/docgov/project_docs.go` | 生成后、列表读取时调用 HealProjectDocuments | 重开页面即可触发回填,必须验证刷新后仍一致 |
| `internal/docduty/revoke.go` | 成员职责变化撤销审核/批准槽位,随后参与 heal | 不能把项目默认职责变化误当成逐文档兼任变更 |
| `internal/server/handlers.go`:三个 DocGov 决议 handler | 使用登录身份及动作固定 author/reviewer/approver;先执行工作流鉴权 | 服务端已有按动作身份模型,应保留 |
| `internal/docgov/state_machine.go` | drafting/reviewing/approving/approved;检查对应职责 ID;无额外三人不同判断 | 复用状态机,测试身份一致和锁定边界 |
| `web/src/lib/currentDocRole.ts` | author 命中后立即返回,不支持同时三职 | A/A/A 会一直被当成 author |
| `web/src/lib/docGovActionVisibility.ts` / `DocGovActionBar.tsx` | 按单一 currentRole 显示送审/审核/批准 | 必须改为动作能力或多职责判断 |
| `web/src/lib/projectSettingsDuties.ts` / `ProjectSettingsModal.tsx` | 重复服务端 full/none 校验,人工审批默认要求至少三人 | 单成员兼任会被前端提前挡住 |
| `deploy/postgres/goose/00017_2026-09-12-project-workflow-instances.sql` | assignment 唯一键是任务实例+职责,无跨职责用户唯一限制 | 同一用户可有三条职责记录,不必拆用户身份 |
| `deploy/postgres/goose/00049_2026-09-17-system-settings.sql` | system_settings 已存在 | 采用增量迁移,不重建设置机制 |
相关历史边界参见 `.doc/test-reports/2026-09-14-governance-action-level-authz-test-report.md` 与 `.doc/test-reports/2026-09-14-workflow-plan-409-frozen-and-optional-duties-test-report.md`。它们说明已有验收意图,本次未重跑其测试。
IDE 所列 rdev 设计、short-term 和 backlog 当前位于 `feature/rdev-template-depth` 的独立工作区,不在本方案 dev 基线;已读取作兼容输入。rdev 的关闭文档/N/A、阶段前置、任务键命名空间化保持原语义。本方案按实例+阶段+任务身份绑定;待 rdev 合入后增加对应回归,不宣称其已在 dev 发布。
### Key Technical Decisions
- KTD1. 新增 `duty_policy`,值为 `separated` / `author_only`,属于 DocTaskPlan 的逐文档配置。缺省按 separated 解读;none/partial/full 仍是职责完整度,不能把「免审批」和「兼任」混为一谈。统一提供按任务解析模式、有效职责、是否受治理的领域能力;原 ClassifyDocDuty 保留给旧调用,治理调用迁到新解析器。(R3–R6)
- KTD2. 配置快照保存用户意图:author_only 的 duties 规范形式只含 author_user_id。服务端通过唯一解析器派生有效 A/A/A,写三条 document_duty_assignments,并投影到 document_records 的三个 ID/名称。读接口区分配置职责与有效职责,客户端不得把有效 A/A/A 原样误写成标准配置。(R4、R11)
- KTD3. 新设置 key 建议 `workflow.allow_author_only_approval`,类型严格 bool,默认 false,无环境变量绕过,保存无需重启。projectinstance 通过窄的策略读取接口消费,由 app 装配注入;不从领域服务调用 HTTP,不让 projectinstance 成为 sysadmin 设置表的第二写入 owner。(R1)
- KTD4. 配置写入、预览和激活都复核总授权;真正激活必须在事务内对授权版本复核,并与关闭总开关串行化。token 绑定 plan hash、项目/规划版本、授权 revision。总开关 false→true 后旧 token 仍作废,不能以「当前又是 true」放行。(R10、R11)
- KTD5. 实例绑定文档的职责权威是冻结 DocTaskPlan,经解析生成 assignments 和文档投影。项目成员 document_duty 只供旧无实例文档的默认分配。heal/revoke/生成/通知不得再次用项目默认人员覆盖实例文档。(R3、R7、R12)
- KTD6. 运行时按具体动作检查有效职责和当前在任状态;状态机仍按 author/reviewer/approver 记录实际动作角色。前端采用服务端动作能力集驱动按钮,可同时拥有多个职责,保留 viewer fail-closed,不新增一个可以绕过所有检查的万能角色。(R5、R7、R8)
- KTD7. 遵守 R9 的冻结边界;未知 mode、缺失授权来源或绑定不唯一时拒绝写动作。历史缺字段只代表旧 separated,不自动解释为兼任;不能全库 A/A/A 回填。(R6、R9、R11)
### Data Model
以下是设计契约,字段落位按 owner 边界实现,不是现有字段清单。
| 数据 | 建议新增/扩展 | 用途与兼容 |
|---|---|---|
| system_settings | 目标 key;monotonic revision(默认 0) | 总权限 CAS、token 失效;目标行在迁移时初始化 false,避免无行锁问题 |
| 系统设置审计 | 仅本策略必需的 before/after、revision、actor、时间、request ID | 与设置更新同一事务提交;不把整站审计改造扩大到本期 |
| DocTaskPlan JSON | duty_policy,可选且旧值缺省 separated | 逐文档意图,纳入 plan hash;兼容 old hash 的序列化须有固定样本 |
| workflow instance 授权快照 | policy key、revision、允许状态、activated_by/at | 记录激活时获准的依据;由服务端生成,拒绝客户端伪造 |
| activation token | policy revision(新字段或令牌存储的版本化元数据) | 防预览后管理员撤销授权;旧 token 含兼任无 revision 必须重新预览 |
| document_records | doc_task_instance_id 可空外键 | 对新实例创建文档强制绑定;旧文档仅唯一匹配才回填,不修改历史职责 |
| document_duty_assignments | 复用三角色,兼任三行 user_id 相同 | 无需放宽角色唯一约束;author 必须有效且正数 |
| 文档视图 | duty_policy、effective_duties、allowed_actions、blocked_reason | 以服务端计算值展示;读参数不能切换权限 |
| 文档审计 details | duty_policy、instance/task ID、授权 revision | 送审/审核/批准均记录真人身份及该次 action role |
不预占 Goose 序号:实施时根据 dev 与并行 rdev 分支最新迁移取下一个空闲序号。迁移需覆盖 PG store 与 memStore 的字段 round-trip。兼容旧数据时禁止把 NULL 改成 0 外键。
### High-Level Technical Design
职责解析链:
```mermaid
flowchart TB
A[管理员总授权] --> B[创建者逐文档配置]
B --> C[保存与预览校验]
C --> D[事务内复核授权并激活]
D --> E[冻结实例配置与授权依据]
E --> F[统一解析有效三职]
F --> G[职责表与文档人员投影]
F --> H[动作鉴权和阶段可见性]
H --> I[前端能力与操作按钮]
G --> J[文档状态机与审计]
```
兼任保留原审批状态机:
```mermaid
stateDiagram-v2
drafting --> reviewing: A以编制身份送审
reviewing --> approving: A以审核身份通过
reviewing --> drafting: A审核驳回并填写原因
approving --> approved: A以批准身份通过
approving --> drafting: A批准驳回
approving --> reviewing: 现有配置允许时退回审核
```
新授权和冻结授权的判断路径:
```mermaid
flowchart TB
A[请求] --> B{规划配置或激活?}
B -->|是| C{权威创建者且planning?}
C -->|否| X[拒绝]
C -->|是| D{含author_only?}
D -->|否| E[原职责规则]
D -->|是| F{总授权有效且版本一致?}
F -->|否| X
F -->|是| G[检查作者与输入一致性]
B -->|运行时动作| H[查冻结策略及实例任务绑定]
H --> I[检查成员有效性 当前阶段 状态和租约]
I --> J[按动作职责执行]
```
激活事务与设置撤销都以策略行锁形成先后顺序,再按统一顺序获取项目职责锁和实例相关行锁。策略 owner 提供事务兼容读取/锁定适配;不能照搬在事务外重查布尔值的方式。原则:关闭先提交则激活失败;激活先提交则成为 R10 中可继续的存量实例。并行成员移除与激活也必须在同一项目职责锁语义下判定,不能在事务开始前检查后直接信任。
### API Contract
| 接口 | 变更 | 服务端强制条件 |
|---|---|---|
| GET/PUT `/api/v1/admin/system/settings[/{key}]` | 注册总开关;目标 key 增加 expected_revision,返回新 revision | requireSystemAdmin;严格拒绝 null、字符串布尔;审计与值同事务 |
| GET `/api/v1/projects/{id}/settings` | 返回精简 governance_policy capability、revision 与 blocked_reason | 保留项目访问校验;不泄露其他系统设置 |
| PUT `/api/v1/projects/{id}/workflow-plan` | 每个文档可传 duty_policy;兼任只传 author ID;沿用规划版本 | 创建者、planning、总授权、有效成员、输入无矛盾 |
| 激活 preview / activate 现有接口 | 预览分列兼任文档;token 绑定策略 revision | 保存成功不等于已获激活授权;提交时重新事务校验 |
| 文档详情和项目文档列表 | 返回模式、有效三职与允许动作 | 统一来源;任务身份、实例身份须匹配 |
| docgov 送审/审核/批准接口 | URL不变,增加模式审计上下文 | 登录用户+对应 action,不信任请求的 user_id/user_name |
建议新增错误码:`AUTHOR_ONLY_POLICY_DISABLED`(403)、`AUTHOR_ONLY_POLICY_CHANGED`(409)、`AUTHOR_ONLY_AUTHOR_REQUIRED` / `AUTHOR_ONLY_DUTY_CONFLICT` / `UNKNOWN_DUTY_POLICY`(400 validation issue)、`DUTY_BINDING_AMBIGUOUS`(409)、`DUTY_ASSIGNEE_INACTIVE`(403)。总权限存储不可用返回 503;缺失目标配置采用默认关闭,但数据库故障不能伪装成正常缺项。保留已有 PLAN_FROZEN、PLAN_REVISION_CONFLICT 与 SEPARATION_OF_DUTY_VIOLATION。
`author_only` 写入审核/批准 ID:省略或 0 为规范输入;若为与作者相同的正数,可规范化为省略以兼容回显,但若不同则拒绝。关闭兼任时清除派生审核/批准,要求重新选择符合分离规则的人员;旧选择可仅作为未保存草稿提示,不自动恢复为真实授权。
### UX Details
系统设置开关说明写明 R10,并展示预计受影响的待激活兼任文档数量及存量继续执行说明。保存失败保留用户输入和错误,不在本地假装开启成功。多管理员同时修改返回版本冲突,不自动覆盖。
项目设置按文档行提供兼任选项;总权限关闭时禁用并解释来源;非创建者只读。兼任只能在文档已启用且纳入人工审批时选择。兼任文档仅需一位成员;混合方案只要仍存在标准人工审批文档,才继续提示至少三位有效人员。
总开关在页面打开期间被关闭时,保存失败展示定位到文档的原因,提供关闭兼任选项;不丢弃整份未保存规划,不自动重试激活。预览和冻结视图同时展示「角色指派数」和「实际人数」,避免 A/A/A 被误认为三个人。
文档正文签署区显示真实姓名及兼任标记,但未发生审核/批准时不得显示签署时间或声称已通过。按钮随状态变化,审阅阶段即使当前人也是作者也不能编辑锁定正文;驳回后恢复编辑。查看/认领按当前状态或明确动作记录相应角色,不能打开一次页面就伪造三次履责。
### Risks and Compatibility
1. **回填覆盖(硬性门禁,非偶然安全):** `HealProjectDocuments` / `ApplySlotRevocations` 与 `ConfigSnapshot` 是独立职责写路径,当前不区分实例绑定文档。实现必须在 heal/revoke 增加「实例绑定文档跳过项目默认覆盖」显式分支,禁止依赖「只填缺失槽位、碰巧不覆盖」的偶然安全。U3 必须对三入口(文档生成、列表 GET、成员变更)及 author 被误判非在任时的 healSlot 分别证明投影不变;未通过不得开放 UI。
2. **历史身份混淆:** 不以 project_id+task_key 跨实例盲绑;旧文档匹配多实例则保持原记录并报可定位问题。新生成文档必须携带 task instance ID,无法绑定应停止受控写入。
3. **成员退出:** runtime 复核在任资格覆盖 author_only;保留冻结快照用于历史展示。普通成员默认职责改变不得影响冻结文档;真实退出/停用应阻断动作。暂不新增运行中换人 UI。
4. **并发审批:** 同一人可打开多个标签,服务端仍需保证状态比较/版本检查;重复请求不能重复创建批准事件、版本封存或推进通知。延迟到达的审核请求不能作用于后续修订版本。
5. **通知与事件:** 审核待办发给同一人是有效业务,不可因发送者=接收者一概过滤。按事件+接收者去重,不把审核与批准两项待办合并成一个动作。
6. **回滚:** 关闭开关只停止新配置,不能安全地把已存在兼任实例交给完全不识别新模式的旧二进制。上线后若需回退代码,保留模式识别与冻结策略读取兼容补丁;不得通过清空审核/批准人员回滚。
7. **总开关非紧急熔断(R10):** 关闭总授权不会阻断已激活兼任实例的剩余送审/审核/批准。界面与运维说明必须写明这一点,避免被误解为「关总开关=紧急止损」。存量紧急撤销不在本期范围。
---
## Implementation Units
### U1. 策略存储与总授权
目标:提供管理员可写、项目治理可可靠消费的总授权。覆盖 R1、R10、R11,采用 KTD3、KTD4。
文件:`internal/sysadmin/settings.go`、`store.go`、`internal/server/admin_system_handlers.go`、`internal/app/` 装配、增量 Goose 迁移;必要时新增 sysadmin 内的策略审计存储文件。
实现重点:默认关闭;严格 bool;目标设置 revision 与 CAS;事务内审计;窄接口可参与激活事务。仅本 key 要求的新协议不破坏其他设置键调用。
测试场景:管理员开关成功;普通用户伪造 PUT 被拒;null/字符串拒绝;DB断开不放行;并发修改只一个版本成功;审计写失败时设置回滚;重启读回。
### U2. 逐文档模式、规划校验与激活
依赖 U1。覆盖 R2–R6、R9–R11,采用 KTD1、KTD2、KTD4、KTD7。
文件:`internal/projectinstance/{types,duty_mode,validator,service,store,hash,tx,errors}.go`、`internal/server/project_settings_handlers.go`。
实现重点:新增模式解析;所有 full-only 分支改为正确的受治理判断;保存、预览、激活一致;任务禁用/免审批清除模式;有效成员检查;规划 hash/授权 revision 和确认 token 一致。保存快照与提升 plan revision 应原子化,失败不能留下可读取的新规划配旧版本。
测试场景:一位成员、至少一份合法兼任文档可激活;只填作者但未开模式仍拒绝;混合 full/none/author_only;其他项目创建者、非创建者管理员拒绝;修改总授权后旧 token 拒绝;激活与撤销并发的两种提交顺序;旧 separated snapshot/hash 兼容。
### U3. 文档绑定与职责投影一致性
依赖 U2;这是开放 UI 前的必要门禁。覆盖 R3、R4、R7、R11、R12,采用 KTD2、KTD5。
文件:`internal/docduty/{store,resolve,revoke}.go`、`internal/docgov/{types,engine,project_docs,repository}.go`、`internal/bizdev/service.go`、`internal/projectinstance/store.go`、任务执行请求与 app 适配、增量迁移。
实现重点:新文档绑定具体任务实例;受治理实例职责优先;统一有效职责映射用于创建、读取、heal、memStore;legacy fallback 仅在明确无实例时可用。`HealBinding`/`healSlot`/`ApplySlotRevocations` 对已绑定 `doc_task_instance_id` 的文档必须显式跳过项目默认覆盖,不得因 author 被误判非在任而重新分配默认人。旧已批准文档不因新功能读取被改写签署人员。
测试场景:同项目两份兼任文档由不同作者承担;第三份标准审批三人;第四份 none;反复 GET/成员默认角色调整/重启后四份职责均不串;未知或歧义绑定阻断;旧无实例文档仍按既有规则;NULL外键正常。**硬性投影稳定性(开放 UI 前门禁):** 已激活 author_only 文档在以下三入口触发 `HealProjectDocuments` 后,`document_records` 与 assignments 投影必须保持 A/A/A——(1) 仅刷新文档列表(`ListWorkflowDocumentsByProject`);(2) 文档生成完成(bizdev);(3) 成员变更后 heal。另测:author 被误判为非在任成员时,healSlot 不得把审核/批准槽位改写为项目默认人;真实离任仍按 R12 阻断写动作且不自动替人。
### U4. 动作鉴权、文档状态机与事件
依赖 U3。覆盖 R5、R7、R8、R12,采用 KTD6。
文件:`internal/projectinstance/{duty_action,document_access,stage_access,gate}.go`、`internal/server/{stage_access_helpers,handlers,document_revision_access}.go`、`internal/app/docflow/`、`internal/docgov/`、相关通知订阅与审计视图。
实现重点:有效三职与在任状态统一判定;三个动作使用不同 action role;归档/修订账本与事件沿用既有事务机制;审核、批准不能跳状态,租约和内容 hash 不因同人而失效。Audit details 增加模式及来源。
测试场景:A顺序三动作成功且三份日志身份真实;其他成员/创建者/管理员越权失败;作者退出后全部写动作拒绝;审核中改正文失败;驳回原因必填;跨标签重复批准只产生一次有效终态事件;审批针对旧版本内容被拒;阶段直到最终批准才可推进。
### U5. 系统设置与逐文档 UI
依赖 U1、U2,可与 U3/U4 开发隔离进行,联调必须等待后端完整。覆盖 R1–R4、R7、R9–R11。
文件:`web/src/components/admin/console/sections/SettingsSection.tsx`、`web/src/components/project/ProjectSettingsModal.tsx`、`web/src/lib/projectSettingsDuties.ts`、`web/src/types/projectSettings.ts`、`web/src/api/projectSettings.ts`。
实现重点:按 UX Details 配置、错误定位、人数要求、预览和冻结展示;策略 capability 来自项目 settings,而非向普通用户开放 admin settings。文档模式在不同阶段展开折叠后不串行。
测试场景:单成员可配置兼任;混合标准模式仍提示三人要求;非创建者只读;系统开关关闭时禁用及保存失败保留草稿;切换文档、刷新、重新登录后模式不变;已激活项目仍冻结。
### U6. 多职责动作展示和真实闭环验收
依赖 U3–U5。覆盖 R5–R8、R11、R12,采用 KTD6。
文件:`web/src/lib/{currentDocRole,docGovActionVisibility,controlledDocHydrate,deliverableSync}.ts`、`web/src/components/doc/DocGovActionBar.tsx`、`web/src/App.tsx`、文档 API/types、相关 UI/PG/真实 PI 测试与报告。
实现重点:消费服务端动作能力,多职责不再被 author-first 短路;认领、提案、修订、按钮与日志一致;受控文档不按名字提权。证明刷新及重启保持一致后再开启真实项目配置。
测试场景:真实产品 PI 生成→A打开文档→送审→审核→批准→版本/日志→阶段门禁;标准和免审批文档并存;不同用户负例;两标签并发、刷新重开、重启;rdev 合入后复验 rd_ 文档及旧键兼容,不改 N/A 行为。
---
## Verification Contract
本方案阶段未运行业务测试,以下为实现阶段必须提交的证据。
| 层级 | 覆盖 | 通过标准 |
|---|---|---|
| Go 单元 | 策略值、模式解析、权限矩阵、状态、门禁、hash | 所有模式边界及错误路径可重复验证 |
| PostgreSQL 集成 | 设置审计原子性、并发撤销/激活、成员退出、三职责落库、投影绑定;HealProjectDocuments 三入口对实例绑定 author_only 文档投影不变 | 实际事务交错结果符合 KTD4;失败不留下半成品;列表 GET/生成/成员变更均不得覆盖冻结 A/A/A |
| 前端单元/构建 | 单成员配置、双层开关、多职责按钮、错误恢复 | 测试与构建通过,无同人只见作者按钮 |
| HTTP 负例 | 修改请求身份、跨项目、非创建者、未知模式、关闭总授权 | 服务端拒绝,不能依赖隐藏按钮 |
| 浏览器 E2E | 管理员开关→创建者逐文档设置→A全部动作→其他人被拒 | 真页面操作、日志可见;无 API 直写替代关键步骤 |
| 产品 PI E2E | 正式生成及既有修订/租约流程 | 使用仓库要求的真实产品 PI + MiniMax;stub 仅作前期定位 |
| 持久化 | 刷新、重开、重登、服务重启 | 模式、职责、审核状态、版本和审计一致 |
| 回归 | 既有 full/none、标准三人分离、freeform、legacy、终止实例 | 原有权限和生命周期边界不退化 |
实现时执行 PROJECT 规定的 `go vet ./...`、`go test -short ./...`、前端 `npm test` 与 `npm run build`,以及使用隔离测试库的 PG 集成和明确启用的真实 PI 测试。不得把 skip 当 pass。共享容器重建验证必须在主仓占 CURRENT 集成槽位后执行;worktree 不启停共享容器。
重点验收样例:
- AE1(R1–R4):管理员开启后,创建者在文档甲选择 A,在文档乙选择 B;甲/乙有效三职分别为 A/A/A、B/B/B,互不影响。
- AE2(R5–R8):A只能按状态依次送审、审核、批准;未批准前门禁阻塞;另一个管理员无该文档职责仍被拒。
- AE3(R6):总开关开启但文档未勾选,A/A/A仍拒绝;三职空仅对原来允许免审批的文档合法。
- AE4(R10、R11):预览后总开关关闭再打开,旧 token 409;已先完成激活的实例刷新后仍可按冻结策略办理。关闭总开关不得阻断已激活实例的剩余审批动作(非紧急熔断)。
- AE5(R7、R11):项目成员默认审核人改为 C 后,读取兼任文档仍显示 A/A/A,不改历史签署;列表、正文及按钮一致。
- AE5a(R7、KTD5):已激活 author_only 文档在仅刷新文档列表(触发 `ListWorkflowDocumentsByProject` → `HealProjectDocuments`)后,投影仍为 A/A/A,不被项目默认职责覆盖。
- AE5b(R7、KTD5):文档生成完成与成员变更后 heal 两入口分别复测 AE5a;author 被误判为非在任时,healSlot 不得把审核/批准槽位改写为项目默认人。
- AE6(R12):A离任后保持历史名字,但所有新动作拒绝,不能被 heal 自动替换或按名字回退提权。
---
## Definition of Done
- [x] R9、R10 的生命周期口径经过用户审核(2026-09-17):批准「激活前配置 + 激活后冻结」与「关总开关仅停新配置、存量按冻结继续」;明确总开关不提供存量紧急熔断,该能力如需另立方案。Heal 三入口投影稳定性已升为 U3/Verification 硬性验收项。
- [x] U1–U6 全部完成且证据覆盖对应需求;管理员和创建者两个权限层级均在服务端生效。(short-term U1–U6 均为 `done`;U6 报告回链)
- [x] 配置、快照、assignments、document_records、前端、审计在同一任务身份下对齐。(U2–U4 + U6 闭环证据;规范存储仅 Author + 有效 A/A/A 投影)
- [x] 单成员兼任完整链与三人标准链均通过;不得只提交设置页截图。(U4 矩阵 + U6 HTTP/浏览器证据;标准分离回归见 U4/U2 单测)
- [x] PostgreSQL、真实产品 PI、浏览器、重启与跨用户负例分别标明结果及限制;AE5a/AE5b 必须有证据。(U3:`TestHealProjectDocuments_SkipsDutyLocked_PG` 等 duty_locked 过滤;U6:既有 PI 生成文档 + Playwright 徽标 + lizhuguan 403。限制:U6 未单独跑「刷新/重登/重启」专轮,依赖 schema 持久化与 rebuild 后复测)
- [x] `.doc/test-reports/` 有验收报告并回链任务和 FEATURE-MATRIX;无新增已确认发布 blocker 才保持 gap-matrix 原结论。([U6 报告](../test-reports/2026-09-17-document-author-only-u6-test-report.md);变更提案 HTTP 另记 [audit](../audit/2026-09-17-docgov-modification-proposal-http-gap.md),不升为发布 blocker)
- [x] 发布先迁移与部署识别新模式的服务,再开放总授权;默认 off,试点后扩面。推送、dev集成与环境晋升状态分别报告。(**dev 已合入并 rebuild**:`merge: feature/document-author-only-plan` @ `09a9921`,health `schema_version=52`,总开关默认 off。**未做**:push origin/dev、test/main 晋升、开放总授权试点——需另授)
@@ -0,0 +1,214 @@
---
title: "首次加载与工作台初始化性能改进方案"
status: planned
created: 2026-09-17
updated: 2026-09-17
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
---
# 首次加载与工作台初始化性能改进方案
## Goal Capsule
让用户首次访问就能快速看到并操作登录页,登录后优先恢复当前项目与会话,避免下载无关工具或等待所有项目初始化。
采用静态交付优化、按功能加载和请求去重,之后按测量结果优化认证与数据库读取(KTD1–KTD5)。本轮仅交付诊断和方案,业务代码尚未修改;用户授权实施后执行以下单元。
遵守 AGENTS.md/PROJECT.md、现有权限和文档治理契约。若优化要求改变授权、新增跨用户缓存、跳过职责正确性或删除历史数据,停止该单元并回报。每单元独立 feature/fix 分支与模块 mutex;合 dev/容器重建占集成槽。默认不推送,不晋升 test/main。
## Product Contract
### Problem Frame
[诊断](../audit/2026-09-17-initial-load-performance-audit.md) 已确认:8080 首屏 2.86 MB,CDP 10 Mbps 冷缓存登录可见 2.64 秒、2 Mbps 11.78 秒;再次访问约 60 ms。字体 CSS 外链阻塞首屏;3100 Vite 首访 207 请求/12.24 MB。登录后存在全项目成员扇出与会话重复同步,服务端认证、文档列表和会话统计有重复工作。
这些数字是单样本实验,不是用户实际公网体验或 p95。用户已确认 3100/8080/8081 在系统重启后首访约十数秒。现有容器启动到打印监听仅约 166/142 ms,不代表整机重启就绪;必须补齐重启矩阵再签优化收益。
### Requirements
- R1. 首次登录页只加载认证与基础样式所需资源,外部字体不可阻塞登录表单。
- R2. 登录后先显示可用工作台骨架,优先恢复当前项目/会话;其他项目成员、管理台、导出、文件预览在需要时加载。
- R3. 相同身份和查询键的初始化请求去重;慢响应、快速切换项目、登出/换人不会写回旧状态。失败必须有局部错误与重试入口。
- R4. 所有服务端授权和文档治理保持正确,权限撤销/停用不得因缓存继续放行。计数、摘要与正文沿用相同可见性语义。
- R5. 发布后旧页面仍可打开延迟模块;缓存不得导致 HTML 长期陈旧,也不得泄露用户 API 数据;SSE 流式延迟不能回退。
- R6. 优化收益用可复现冷/热缓存、慢网、字体不可达、多项目和大历史场景证明,结果与镜像/资源 hash 绑定。
### Success Criteria
以下是**拟定验收预算**,不是当前已达标数据。表中静态资源体积及绝对首屏时间预算适用于 8080/8081 构建入口;3100 保留 Vite 开发模式,不套构建产物压缩体积预算,其保留/空依赖缓存与预热状态分别由 U1 固定加载时间预算,U7 检查重启改善;U1 固定机器、Chromium 版本、样本与网络条件,预算不得在看到失败后悄悄放宽。
| 指标 | 目标/口径 |
|---|---|
| 未登录关键 JS 总传输量 | 开启压缩后 ≤250 KiB;按首屏实际请求总和而非只看入口文件 |
| 普通工作台首次可用前 JS 总量 | ≤600 KiB;不含用户明确打开的文档预览/导出模块 |
| 冷缓存登录可操作 | 10 Mbps / 80 ms、CPU 4 倍减速下 p75 ≤1.5 s;2 Mbps 同配置 p75 ≤3 s |
| 登录态热刷新 | 10 Mbps / 80 ms、CPU 4 倍减速下工作台可操作 p75 ≤1.5 s;前提必要 API 达下行预算 |
| 登录态冷刷新/登录提交成功后恢复 | 冷刷新自 navigationStart 起、登录自成功响应起,当前会话历史及输入区就绪 p75 ≤3 s;仅骨架不算完成 |
| 必要首屏 API | 同宿主 app↔DB 网络下 p95 ≤300 ms;列表大数据场景 p95 ≤500 ms,接口错误率不增加 |
| 首屏初始化请求 | 项目成员初始化从 N 次降为当前项目最多 1 次;静止初始化每个会话列表查询键最多 1 个在途请求且成功后不被成员更新重触发 |
| 字体故障 | Google 域名完全阻断或延迟 10 秒时,仍满足登录预算,不发首屏外部字体 CSS 请求 |
| 无回归 | 同数据/设备各阶段 p95 不劣化超过 10%;无新增跨用户暴露、错误循环、重复写任务 |
浏览器每场景 ≥20 次,报告 p50/p75/p95 与原始样本;接口每场景 ≥100 请求、并发 1/10/30。浏览器 p95 仅小样本诊断,不能冒充线上 SLO;稳定发布后再累计真实用户分位数。
### Scope Boundaries
包括浏览器入口、静态资源交付、当前工作台数据初始化、与首屏相关的查询。没有业务语义变更,不调整 PI 模型、Prompt、文档租约时长、授权范围或工作流门禁。
Deferred to Follow-Up Work:Redis/CDN、新 SSR 框架、全面 App.tsx 重写、全站统一数据框架、数据库分库、文档全文缓存。只有 U1 的证据表明必要时另开任务;目前不需要先增加基础设施。
### Outstanding Questions
- 待补测:已知端口 3100/8080/8081,重启涵盖宿主机/应用/Vite 的具体范围、慢发生阶段、真实网络与设备;不会阻止可独立证明的 U2/U3,但阻止宣称用户现场问题已经彻底解决。
- 待补测:登录态瀑布、真实数据规模、SQL/连接池等待;U6 的查询改写/索引必须由这些证据选择。
## Planning Contract
### Key Technical Decisions
- KTD1. 保留 React/Vite + Go 架构。正式体验使用构建产物入口;3100 保留开发热更新用途,不把开发模块请求数量当生产目标。先确认真实反代 upstream,不盲改 FRP。
- KTD2. 首屏用系统字体栈;需要保留 Inter/JetBrains Mono 时仅选必需 WOFF2 并同源部署、按需加载。保留 KaTeX 渲染所需字体,但不要求登录页加载数学资源。
- KTD3. 按功能边界动态 import,登录壳与工作台隔离;管理台、DOCX/XLSX 导出、Word/Excel 预览、Mermaid 按使用加载。仅 manualChunks 拆文件不能减少关键路径下载,必须验证依赖图没有静态回引。
- KTD4. 现有 Go serveSPA 作为默认静态交付修复点,构建期生成 gzip/br(若工具链已支持)而非每请求高压缩。若真实统一代理已负责压缩,则由它单层处理并记录;不得重复编码。哈希资源 `public,max-age=31536000,immutable`;HTML `no-cache`;压缩变体 `Vary: Accept-Encoding`;用户 API 不共享缓存。保留 identity、HEAD、条件请求、Range 正确性。
- KTD5. 将请求状态按身份/项目/会话/过滤器键管理,先用局部 hook/loader 和在途合并解决,不强制引入新数据框架。身份切换清空缓存与取消在途请求,成员更新不作为会话获取的依赖。未知成员/权限不靠全量成员预取推导:使用服务端明确的当前用户权限摘要,未就绪保持 fail-closed。
- KTD6. 请求内复用已认证 principal,授权不跨请求长期缓存。减少 session 续期写入须明确 idle TTL/绝对过期/撤销语义后再落地,保留停用与撤销实时检查。
- KTD7. 文档列表先保留治理正确性;先补齐所有写路径与历史修复,再移出 GET 同步 heal。轮询保持原有租约新鲜度,优先复用 SSE/可见性控制与单请求在途,不能直接延长租约或无限延迟 busy 显示。
### High-Level Technical Design
```mermaid
flowchart LR
A[HTML与同源基础样式] --> B[轻量认证壳]
B --> C[认证结果与工作台模块并行准备]
C --> D[当前用户可见项目与会话]
D --> E[当前项目权限与聊天窗口]
E --> F[可操作工作台]
F --> G[按需管理台/导出/预览]
```
有保存会话时,可在校验期间预加载不含用户数据的工作台代码;受保护 API 与用户内容显示仍由认证门禁控制。无会话时不加载工作台代码。项目/会话列表在认证后并行,解析有效当前项目后再发其范围内请求;不是让全站等待所有项目成员。
```mermaid
sequenceDiagram
participant UI as 浏览器
participant API as Go API
participant DB as PostgreSQL
UI->>API: 首屏必要请求(按查询键去重)
API->>DB: 验证当前会话/用户状态
API->>API: 请求内复用 principal / 权限解析
API->>DB: 当前页/当前项目数据
API-->>UI: 权限范围内的结果
UI->>UI: 核对身份与查询代次后更新
```
## Implementation Units
### U1. 固定完整性能基线(P0,约 0.5–1 天)
**Requirements:** R6;后续全部单元的依赖。
**Files:** 新增 `web/e2e/initial-load-performance.spec.ts`、诊断指标辅助模块;更新 `.doc/test-reports/`。本轮探针与结果可作为起点。
**Approach:** 固定真实入口、部署 hash、登录角色、项目数/历史量,捕获资源瀑布、FCP/LCP、长任务、输入区与历史就绪、必要 API TTFB。用专用验收账号/夹具测登录,不在真实会话发送诊断消息。先检查 GET 副作用,文档列表暂有 heal,数据库分析使用只读事务和 statement_timeout。分别测空缓存、热缓存、10/2 Mbps、CPU 4x、字体失联、1/30/100 项目与大历史。本轮不重启共享服务;实施时 U7 在隔离环境重现应用/依赖/宿主启动过程,记录 ready 与第一次导航的时间关系。
**Test scenarios:** 新浏览器、保存有效/过期会话、无项目、普通成员与管理员、慢 API/失败、项目快速切换;每份结果保留参数与原始样本但无 token/用户正文。
**Verification:** 形成基线报告,能回答耗时在哪一阶段,并确认性能指标可重复。登录态测量缺失不得用未登录测试代替。
### U2. 修复字体与静态资源交付(P0,约 0.5–1 天) — **done 2026-09-17**
**Dependencies:** U1 的未登录基线;**Requirements:** R1、R5、R6;**Files:** `web/index.html`、`web/src/styles/index.css`、`web/vite.config.ts`、`internal/server/server.go`、新增 `internal/server/static_assets_test.go`;必要时实际 Docker 构建文件。
**Approach:** 按 KTD2/KTD4 去除外部阻塞 CSS、提供压缩变体与明确缓存头。缺失 `/assets/*` 返回 404,不回退 HTML;客户端路由仍允许 SPA fallback。发布资源保留至少当前与上一版本并明确旧标签页支持窗口;窗口外加载失败提示用户保留编辑后刷新,不自动刷新丢失草稿。
**Test scenarios:** gzip/br/identity 协商、q=0 禁用、Vary、GET/HEAD、304、Range、未知资源 404、客户端路由回退;字体域名黑洞仍出现表单;SSE 首事件/持续事件不缓冲;受保护 API 无 public 缓存;部署后旧标签页首次打开尚未加载的模块。
**Verification:** curl 与浏览器确认真正压缩响应,JS 传输量下降;HTML 不被长期缓存。此单元不宣称已达到拆包预算。
**交付证据:** [U2 测试报告](../test-reports/2026-09-17-initial-load-perf-u2-test-report.md);`dev` merge `feature/initial-load-perf-u2`;8080 主 JS br 传输 623,898 B;登录冷缓存可见 ~205 ms。U1/U3–U7 仍未完成。
### U3. 登录壳与重功能按需加载(P0,约 1–2 天)
**Dependencies:** U1;可与 U2 分开开发,合入仍串行。**Requirements:** R1、R2、R5;**Files:** `web/src/main.tsx`、`web/src/App.tsx`、新增认证壳组件、`web/src/components/doc/preview/FilePreviewPanel.tsx`、`web/src/features/replyExport/download.ts`、`web/src/engine/docxRenderer.ts`、`web/src/components/doc/blocks/MermaidBlockView.tsx`、U1 浏览器用例。
**Approach:** 按 KTD3 建立真实 lazy 边界;将工作台 hooks/缓存初始化移入工作台挂载周期。导出按钮点击才 import 引擎;预览根据文件类型加载;Mermaid 只在存在图块时加载。每边界提供局部加载/失败重试与错误边界。限定此重构服务于加载,保留既有文档编辑状态机。
**Test scenarios:** 未登录资源中不出现导出/预览/管理台/图表重模块;登录成功恢复当前会话;失效会话不展示缓存敏感数据;首次导出 DOCX/XLSX 内容有效;Word/Excel 预览、数学公式与 Mermaid 正确;动态 chunk 失败可以重试且不重复提交业务动作;首次打开功能耗时同时记录。
**Verification:** 满足 R1 首屏预算及功能按需请求证据,不把延迟全部转移成首次按钮不可用。检查 gzip 后所有首屏 chunks 总和。
### U4. 收敛初始化扇出与重复同步(P1,约 1–2 天)
**Dependencies:** U1、U3;**Requirements:** R2、R3、R4;**Files:** `web/src/App.tsx`、`web/src/api/projectWorkflow.ts`、`web/src/api/chatSessions.ts`、`web/src/data/storage.ts`、新增初始化 loader/hook 及其测试;必要时项目列表 DTO/服务端 handler 补当前用户成员摘要。
**Approach:** 当前项目成员优先,其他完整成员按打开面板加载;会话 fetch 依赖稳定身份/查询键,项目名称映射与网络获取分离;查询代次 + AbortController + 在途合并;每次成员响应不再全量写 projects/持久化。只有实测长任务证明需要时增加去重/批量保存,不把权威服务器文档写入延迟缓存作为成功。
**Test scenarios:** 1/30/100 项目首次请求数量稳定;成员结果乱序不会重复请求会话;快速切项目/登出/换用户不串状态;普通成员看到的项目/会话范围与改动前一致;错误后手动重试;成员增删后局部失效刷新;离线缓存不绕过权限验证。
**Verification:** 达到初始化去重预算,记录必要 API 次数与工作台就绪时间;跨用户负例、当前会话恢复、文档编辑刷新持久性通过。
### U5. 认证请求去重与续期写入收敛(P1,约 0.5–1 天)
**Dependencies:** U1 的认证测量;**Requirements:** R3、R4、R6;**Files:** `internal/server/auth_handlers.go`、`internal/server/auth_middleware.go`、`internal/auth/service.go`、`internal/auth/pg_store.go` 及相邻测试。
**Approach:** `/auth/me` 复用 middleware principal;合并会话及用户读取,避免重复查同一用户。先度量 session UPDATE 锁/连接等待;只有证明其成本且明确既有过期语义后采用有界续期/last_seen 写入策略。鉴权失败不缓存成成功,撤销/停用每请求生效。
**Test scenarios:** 同 token 1/10/30 并发;me 请求中只验证一次;撤销/停用后的下一请求拒绝;idle 边界/绝对过期/并发续期;DB 异常 fail-closed;匿名静态资源仍可访问。
**Verification:** 展示改前/后 DB 操作数、锁等待和 p95;身份安全回归通过。若节流会改变过期语义,则只交付请求内复用,将节流留待独立决定。
### U6. 按测量优化列表与租约读取(P2,约 2–4 天;按证据选子项)
**Dependencies:** U1、U4;**Requirements:** R2、R4、R6;**Files:** `internal/docgov/project_docs.go`、`internal/docduty/store.go`、成员/职责写路径、`internal/ctxmgr/chat_history.go`、`internal/projectworkflow/store.go`、`web/src/App.tsx` 及相邻 PG/浏览器测试;确需索引时新增 Goose migration。
**Approach:** (a) 先验证成员创建/转交/退出/撤销各路径事务内同步职责,并以显式受控任务修复历史,之后去掉列表读时 heal;(b) 租约查询避免每次全量文档修复,单请求在途、隐藏页暂停并在可见时立即同步,复用现有 SSE 失效事件;(c) 会话先按原可见性/排序选页,再仅统计页内数据,项目列表视数据量分页。维持 COUNT/latest 内容授权规则与排序稳定性,不能把当前全量总计改为页内总计却不告知调用方。
**Test scenarios:** 文档 GET 零 UPDATE/advisory lock,重复读不变 updated_at;成员变动职责立即正确;两标签 busy/释放不晚于原可见性基线、断 SSE 可恢复;慢查询轮询不重叠;分页无重复/丢项且计数不泄漏;EXPLAIN 对照现有索引与扫描行数;项目 143 不做写入修复测试。
**Verification:** PG 真库夹具 + 真实页面操作证明治理与编辑/刷新链路无回归;SQL 扫描、锁等待和 p95 确实改善。没有对应瓶颈时不为“优化”增加索引/摘要/新接口。
### U7. 重启后首访链路与开发预热(P0 诊断 / 按证据修复,约 0.5–1.5 天)
**Dependencies:** U1;**Requirements:** R1、R2、R6;**Files:** `web/vite.config.ts`、`cmd/server/main.go`、`internal/app/app.go`、`internal/bizdev/service.go`、`scripts/env-service.sh`、实际入口健康检查配置与启动测试。
**Approach:** 重启矩阵覆盖:仅 Vite 重启(保留/空依赖缓存)、仅 app 重启、依赖服务一起启动。每项再分浏览器保留缓存/清缓存与保存登录态/未登录;记录启动命令、DB healthy、app listen、ready、首次 HTML、首 API、UI ready。共享重启须占槽并避开正在执行任务,在隔离环境优先验证。Go 初始化分段计时;Vite 确认无缓存编译主导后,使用锁定 Vite 版本支持的 server.warmup/clientFiles 预热关键入口并保留 node_modules/.vite 缓存,禁止为暖机触发聊天或文档生成。
若 DB/迁移/seed 才是主耗时,先将重复扫描与种子写入改为有版本依据的幂等增量;必需迁移和授权数据未完成时 ready 必须失败。不要为看起来快而提前假报就绪。若是健康探测/代理等待,优化实际就绪探测与放流时序,不能把 start_period 直接当固定延时删除。对于后端暂时不可用,登录壳给出服务准备中和有限重试,不能无提示白屏或把瞬时不可达误当身份失效清空会话。
**Test scenarios:** 同版本无迁移重启、首次/有迁移启动、DB延迟就绪/不可用、依赖缓存失效、warmup 失败、过期登录态、保存有效登录态但网络暂时中断;多环境隔离保持。
**Verification:** 无待执行迁移且 DB 已就绪时 app restart→ready p95 ≤3 s;完整依赖启动单列,不承诺未测硬件的整机开机时间。8080/8081 ready 后首次访问须符合 Success Criteria 绝对预算;3100 分别符合 U1 在实施前固定的 Vite 冷/暖预算,不套生产压缩体积预算。三个入口在各自匹配的真实重启场景首访耗时均较基线下降至少 50%,同时记录从启动命令到 UI ready 总耗时,防止仅把等待搬到后台预热而宣称消失。若实测无法达到,保留未达标项与原因,不伪报完成。
## Verification Contract
- 前端:`cd web && npm test && npm run build`;单独运行 U1 的 Playwright 性能用例与现有文档修订/历史恢复相关浏览器回归。检查构建依赖与实际请求,不能只检查构建日志大小。
- Go:`go vet ./...`、`go test -short ./...`;认证/文档/会话修改补相关真实 PG 集成,覆盖撤销、跨用户、分页和职责同步。
- 合入/运行验证:占 CURRENT 集成槽,在主仓 merge 后 `./scripts/env-service.sh dev rebuild`,验证 `/health`、`/ready` 与资源 hash;健康不代表性能通过。禁止 worktree 启停共享服务。
- 真实 UI:登录、刷新当前会话、切项目、首开预览、首导出、文档编辑保存后刷新/重开、双标签 busy。涉及文档治理改变时按 PROJECT 补真实 PI + MiniMax 全链路,stub 不可替代交付。
- 证据:报告记录 commit/image/资源 hash、浏览器与硬件、网络/CPU 设置、缓存状态、数据规模、样本数/分位数、失败样本、请求数和 SQL 变化。脱敏,不保存登录 token、会话正文或原始授权头。
## Definition of Done
1. R1–R6 与性能预算有前后对比和真实 UI 证据;未覆盖项明确列残余,不因 health PASS 关闭。
2. 字体不可达仍可操作,首次登录无重功能模块;初始化不随全部项目成员返回重复发会话请求。
3. 授权/文档职责/租约/保存持久性不回退,分页可见性一致,SSE 不缓冲,旧版本 chunk 失效有恢复路径。
4. 更新任务、CURRENT、FEATURE-MATRIX、test-report,完成后任务归档;明确本地分支/提交、是否合 dev、是否推送。
## Rollout and Rollback
顺序:U1 → U2/U3 与 U7 → U4/U5 → 按数据选择 U6,每波独立复测并归档,预计核心 U1–U5 约 3.5–7 工程日,U7 另需 0.5–1.5 日,U6 另需 2–4 日(估算,含回归,非交付承诺)。先 dev,再按项目既有授权晋升 test/main。
压缩/缓存只作用静态资产,发现编码/缓存问题可回退独立提交;保留对应完整 HTML+资源集,避免仅回滚 HTML。拆包可回滚组件边界,但禁止强制刷新正在编辑的用户。认证和查询优化各独立提交;职责修复迁移必须可重入,停用新读路径时保留既有安全修复,不删除数据/索引作为临时回滚。若 p95 回退超过 10%、401/403 异常、文档职责偏差或租约不可见,停止晋升并回退相应单元。
## Appendix
- [审计与数值证据](../audit/2026-09-17-initial-load-performance-audit.md)
- [诊断测量报告](../test-reports/2026-09-17-initial-load-performance-baseline.md)
- HTTP 压缩协商与 `Vary`:[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Compression)。缓存版本化资源与 HTML 策略:[MDN HTTP caching](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching)。
- 外部字体与阻塞 CSS:[web.dev 字体实践](https://web.dev/articles/font-best-practices)。Vite 开发请求瀑布:[Vite performance](https://vite.dev/guide/performance)。这些资料用于原则核验;具体配置以仓库锁定的 Vite 7.1.x 为准,不照搬官网当前版本构建 API。
## Plan Review
已完成同模型的 coherence、feasibility、design、security、scope、adversarial 六视角只读复核(3 个代理分别承担两视角,不作为6份模型独立验证)。修正1项:明确3100开发入口与8080/8081构建入口使用不同资源预算;保留三入口真实重启与总耗时验证。未进行外部跨模型复核,不声称具有跨模型验证。置信度:资源/字体机制高,用户重启现场主因中等,须U1/U7闭环。
@@ -0,0 +1,57 @@
---
title: "系统体检整改与完善实施方案(2026-09-17)"
status: planned
created: 2026-09-17
updated: 2026-09-18
---
# 系统体检整改与完善实施方案
> 配套审计:[../audit/2026-09-17-system-health-check.md](../audit/2026-09-17-system-health-check.md)(编号 B-x 确认 bug、R-x 隐患、E-x 环境缺陷、T-x 任务、X-x 死代码、S-x 测试盲区、D-x 文档漂移)。
> Wave 0–7 已实施收口。Wave 7 仅为编排确认,未改变能力实现状态。
## 背景
体检确认质量门禁全绿、发布门禁口径属实;但发现 1 项 critical 环境缺陷(main ENV 不一致,E-1)、2 项 high 级 SSE 断流 bug(B-1/B-2)、1 项 high 级前端缓存 bug(B-5)、一批「机制先行无消费方」与测试盲区。本方案按风险优先分波次收口。
## 目标
1. main 环境事件链路语义唯一、无双写/空转风险(E-1)。
2. SSE 长任务不再被 120s WriteTimeout 强杀(B-1/B-2),错误语义对齐(B-3/B-4)。
3. 前端会话窗口缓存一致、恢复不丢数据(B-5/B-6)。
4. 封存功能的灰度入口在 compose 层就绪(E-3),死配置/死代码有明确处置(E-4、X-*)。
5. 测试债与 E2E 门禁入口收敛(S-1/S-2/S-4)。
6. 文档 SSOT 无漂移(D-1~D-6)。
## 分波次计划
| 波次 | 内容 | 验收 |
|------|------|------|
| **Wave 0:P0 确认 bug** | B-1/B-2:`handleChatStream` 与 `handleRunTaskStream` 接 `extendSSEWriteDeadline` + 心跳(复用 sse.go:52-64 既有机制);run/stream 支持 `after_seq` 续订(重连走既有 `GET .../events?after_seq=`)。B-3:Decode 失败返回 400。B-4:CreateAndStart/Subscribe 前置到 Flush 之前(对齐 chat 路径)。B-5:useChatWindow 全部写入统一带 `userId` 前缀,LRU 驱逐完整 cache key。B-6:`applyRestoredFileRaw` 函数式合并 | **done**(2026-09-18):[test-report](../test-reports/2026-09-18-wave0-p0-bug-fixes-test-report.md);合入 `dev` merge `fix/wave0-p0-sse-chat-cache-bugs`;dev rebuild + health/ready PASS;真 PI SSE 心跳证据归档 |
| **Wave 1:main 环境修正(critical)** | E-1:app/events 统一 `ENV=main`。E-2:app `depends_on events: service_healthy`(events 同步迁移后再启 app)。E-5:`Env==""` 不再视同 dev。附带:events 补齐 `validateProductionSecrets` 所需口令以免 Restarting | **done**(2026-09-18):[test-report](../test-reports/2026-09-18-wave1-main-env-fix-test-report.md);main health `env=main` + `schema_version=52`;consumer modes 仍 off |
| **Wave 2:配置与灰度入口对齐** | E-3:三环境声明 `MULTI_INTENT_PLAN_TIER`+U9–U12(legacy/false);A-4:test/main 补 SHADOW/NARRATIVE。E-4:删除 `CURSOR_RUNNER_URL`+cursor-agent。E-6:main `SEED_DEMO_USERS=false`。E-7:非法 `INTENT_V2_DECISION_TIER`→`none`。E-9:评估不改 initdb | **done**(2026-09-18):[test-report](../test-reports/2026-09-18-wave2-config-flag-align-test-report.md);三环境 env 抽检 + health/ready PASS |
| **Wave 3:测试债与盲区** | S-1:隔离 PG(5436) 跑 `TestReconcile_LegacyRepair_PG`。S-2:删 taskstream 死跳过;plan_owner 重定向说明。S-4:每 spec npm 脚本;退役 `document-revision.spec`(消灭 DOCREV_E2E_BASE_URL)。S-5:`projectSettingsError` 复用到 members/freeform/taskRuns/chatSessions | **done**(2026-09-18):[test-report](../test-reports/2026-09-18-wave3-test-debt-blindspots-test-report.md);playwright list 29/8;reconcile PG PASS |
| **Wave 4:隐患加固(可与 Wave 0–3 并行认领,mutex 不冲突时)** | R-1:`getOrCreateSession` 增 owner 绑定校验(session 创建时记录 owner,后续请求校验,不匹配 403)。R-2:18 处 `rows.Next()` 循环补 `rows.Err()` 检查。R-3:dispatcher Handlers 读路径加 RLock(或注释冻结「仅启动期注册」并加 archtest 约束)。R-4:`memTurns` 加 TTL/容量淘汰。R-5:pg_store JSONB 反序列化错误改为显式报错。R-6:后台 ticker 纳入 Shutdown;vault Drain 错误上报告警。R-7/R-8:SSE 重连 401/404 fail-fast、逐帧容错;登出 abort 在途流 | **done**(2026-09-18):[test-report](../test-reports/2026-09-18-wave4-hardening-r1-r8-test-report.md);Memory+PG 跨用户负例 PASS;`go test -short` / `npm test` 全绿 |
| **Wave 5:死代码与机制收口(需逐项决策,不擅自删)** | X-1:删除 `SEMANTIC_FALLBACK_ENABLED`。X-2:`SEMANTIC_SUMMARY_REPLACE` 维持未接线并封存注释。X-3:00048 三表 deferred → SWBOOT-10/W5b。X-4:system_settings 6 键保留并注释二期。X-5:删除 DocumentNotificationList、WorkflowPrerequisiteBanner、SettingsModal、activateWorkflow、saveMessages 及级联 patchNotification | **done**(2026-09-18):[决策](../ops/short-term/2026-09-18-wave5-deadcode-decisions.md) · [test-report](../test-reports/2026-09-18-wave5-deadcode-decisions-test-report.md) |
| **Wave 6:文档漂移修复** | D-1:PU8 四份契约文件状态改 done 并归档。D-2:modular-monolith ADR 状态更新为 accepted。D-3:两个 INDEX 末行已在本审计修正(复核即可)。D-4:handoff 回标已被覆盖。D-5:backlog D3/D7 同步最新状态。D-6:PROJECT.md §9「剩余 blocker」段与 gap-matrix 对齐或删除 | **done**(2026-09-18):[short-term](../ops/short-term/2026-09-18-wave6-doc-drift.md) · [test-report](../test-reports/2026-09-18-wave6-doc-drift-test-report.md);D-3 INDEX 复核 PASS、零改动 |
| **Wave 7:既有 roadmap 收口(不改优先级,仅确认编排)** | T1/W5:SWBOOT-10 安全评审后实施(保持 fail-closed 直至授权)。T1/W6:FAV live 放量 staging→artifact→publication,每级 ≥7 天观察窗,`FAV_DEGRADED_READ=false` 不动。T1/W7:D7 待合规签字后按 ADR 整改。T4:首次加载性能 U1/U3–U7。T5/T6/T8:backlog 类按收益触发。T2(Control Center)已于 2026-09-19 移出本仓库 | **done**(2026-09-18):[决策记录](../ops/short-term/2026-09-18-wave7-roadmap-orchestration.md)。六项编排确认已记录;T2 后来由用户裁决为独立项目,本仓库不再保留 Control Center;FAV/D7/tier 升级红线未动 |
## 验收标准
- [x] Wave 0 完成后:`go vet ./...`、`go test -short ./...`、`cd web && npm test && npm run build` 全绿;dev 容器 rebuild + health/ready PASS([报告](../test-reports/2026-09-18-wave0-p0-bug-fixes-test-report.md))
- [x] main 环境:ENV 语义统一核验记录 + schema 已升(实测 52)+ 事件链路无双写证据(modes 仍 off)(Wave 1,[报告](../test-reports/2026-09-18-wave1-main-env-fix-test-report.md))
- [x] SSE 长回合心跳接线:真 PI 静默期 `: heartbeat` + 短 WriteTimeout 单测跨越(Wave 0)
- [x] Wave 2 配置声明对齐:三环境 compose diff 复核 + 容器 env 抽检 + go test 全绿(E-3/E-4/E-6/E-7 完成;E-9 评估结论已记录,不改代码)([报告](../test-reports/2026-09-18-wave2-config-flag-align-test-report.md))
- [x] `TestReconcile_LegacyRepair_PG` 报告归档,gap-matrix 测试债行关闭(Wave 3)
- [x] `playwright test --list` 与门禁文档一致(Wave 3)
- [x] 跨用户会话挂靠负例测试入库(Wave 4)
- [x] X-1~X-5 每项有决策记录(Wave 5)
- [x] D-1~D-6 全部回链关闭(Wave 6)
- [x] Wave 7 六项编排确认已记录(T1/W5、T1/W6、T1/W7、T2、T4、T5/T6/T8);FAV/D7/tier 升级红线未变(Wave 7)
- [x] 不触碰红线:FAV_DEGRADED_READ=false、MULTI_INTENT_PLAN_TIER 默认 legacy、SEMANTIC_SUMMARY_REPLACE 不接线、项目 143 只读、禁止整支 merge FAV
## 相关链接
- Audit: [../audit/2026-09-17-system-health-check.md](../audit/2026-09-17-system-health-check.md)
- gap-matrix: [./gap-matrix.md](./gap-matrix.md)(本方案不改动发布门禁结论;E-1 若核验确认 main 事件链路异常,再评估是否升 blocker)
- 既有收口总控:[./2026-09-16-partial-deferred-completion-plan.md](./2026-09-16-partial-deferred-completion-plan.md)
+5
View File
@@ -2,7 +2,10 @@
| 文档 | 说明 |
|------|------|
| [2026-09-17-system-health-remediation-plan.md](./2026-09-17-system-health-remediation-plan.md) | 系统体检整改:Wave0–7(SSE/缓存 P0 → main ENV → 配置对齐 → 测试债 → 隐患 → 死代码决策 → 文档漂移 → roadmap);配套 [审计](../audit/2026-09-17-system-health-check.md) |
| [2026-09-17-document-author-only-plan.md](./2026-09-17-document-author-only-plan.md) | 编制人兼任审核/批准:两级授权、`duty_policy=author_only`、U1–U6 实现已收口;默认 off;变更提案 HTTP 另立([audit](../audit/2026-09-17-docgov-modification-proposal-http-gap.md)) |
| [gap-matrix.md](./gap-matrix.md) | 发布缺口 SSOT |
| [2026-09-16-partial-deferred-completion-plan.md](./2026-09-16-partial-deferred-completion-plan.md) | FEATURE-MATRIX 6 partial + 1 deferred 全量收口:通信机制确认(模块化单体,不新增 RPC 层)、7 项关闭条件、W1–W7 波次;§7 四项决策已确认(2026-09-17) |
| [2026-09-16-feature-matrix-production-readiness-plan.md](./2026-09-16-feature-matrix-production-readiness-plan.md) | 能力状态与发布门禁解耦、证据校准、剩余 partial 收口和 production-ready 防回退计划([审计](../audit/2026-09-16-feature-matrix-production-readiness-audit.md)) |
| [2026-09-14-module-decoupling-refactor-plan.md](./2026-09-14-module-decoupling-refactor-plan.md) | 纵向绞杀、UnitOfWork、高并发互斥、可靠事件、逐动作授权、FAV、迁移与恢复的详细重构计划 |
| [2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md](./2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md) | Phase 2 修订版:Track E 持久事件交付先行;Track S 结构解耦独立 go/no-go;HTTP 与 PI 协议另立 remediation([审阅](../audit/2026-09-15-module-decoupling-phase2-plan-review.md);[调研](../ops/research/2026-09-15-module-decoupling-ipc-assessment.md)) |
@@ -30,3 +33,5 @@
| [2026-09-12-three-workflows-strict-governance-remediation.md](./2026-09-12-three-workflows-strict-governance-remediation.md) | 三工作流严格治理 |
审计入口:[../audit/INDEX.md](../audit/INDEX.md)
- 2026-09-17:[首次加载性能诊断与改进](2026-09-17-initial-load-performance-plan.md)(三入口重启首访;U2 已验收,主 JS ~624 KB;U1/U3–U7 待实施)。
+4 -4
View File
@@ -1,8 +1,8 @@
# 整改缺口复核矩阵(SSOT)
**更新**: 2026-09-16
**分支**: dev
**production_ready**: yes(发布门禁 B1–B4 已签;dev/test/main schema=47。U9–U12 / 软件自举 / FAV / 完整 PI change-report 叙事不挡首发)
**更新**: 2026-09-17
**分支**: test @ `rc-v1.0.0-beta.3`
**production_ready**: yes(发布门禁 B1–B4 已签;dev/test `schema_version=48`;main `schema_version=47`。U9–U12 / 软件自举 / FAV / D7 不挡首发;FAV live 与 D7 删除仍非本门禁范围)
**协作焦点**: [../ops/CURRENT.md](../ops/CURRENT.md)
**Agent 手册**: [AGENTS.md](../../AGENTS.md) · [PROJECT.md](../../PROJECT.md)
**能力矩阵**: [../status/FEATURE-MATRIX.md](../status/FEATURE-MATRIX.md)(Wave 0 校准;与本文件正交)
@@ -63,7 +63,7 @@
| ID | 描述 | 状态 | 证据 | 计划动作 |
|---|---|---|---|---|
| WORKFLOW-PLAN-FROZEN-OPTIONAL-DUTIES | active 项目仍展示可编辑职责表单,409 提示在长表单视口外;现有规划又不支持非必需文档“三权全空”,且后端缺少职责人在任成员复核 | **PASS(设置页)** | [audit](../audit/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md);[test-report](../test-reports/2026-09-14-workflow-plan-409-frozen-and-optional-duties-test-report.md)。项目 143 只读 frozen、A full+none 激活、B partial 不发 PUT、C 零治理拒绝、双标签转 frozen、成员无配置入口、刷新后 143 仍 frozen | 设置页矩阵 PASS;真实 PI full/none 长链已另签 [Wave2 报告](../test-reports/2026-09-16-wave2-real-pi-evidence-test-report.md) |
| DOC-CONTENT-CANONICAL-HASH-DRIFT | 旧受控文档 bootstrap 裁剪 Markdown 双空格硬换行并将 canonical SHA 写入账本/DocGov,但未同步文件;正文读取把完整性冲突误报 404,lease/list sync 又放大并制造刷新后加载死锁 | **PASS(真实 UI)** | [audit](../audit/2026-09-14-project143-controlled-content-404.md);[UI report](../test-reports/2026-09-14-controlled-content-ui-acceptance.md)。代码已合 dev、schema 32、项目 143 定向 `migration_repair`;项目 143 `clean-run3` 与新项目 `full-chain-final` 主链及 restart 全部纯页面 PASS,目标 404=0 | [remediation](./2026-09-14-controlled-content-canonical-hash-remediation.md)。隔离 `TestReconcile_LegacyRepair_PG` 未执行,按用户“本轮只允许页面测试”的边界保留为工程测试债,不作为本轮 UI PASS 的替代证据 |
| DOC-CONTENT-CANONICAL-HASH-DRIFT | 旧受控文档 bootstrap 裁剪 Markdown 双空格硬换行并将 canonical SHA 写入账本/DocGov,但未同步文件;正文读取把完整性冲突误报 404,lease/list sync 又放大并制造刷新后加载死锁 | **PASS(真实 UI)** | [audit](../audit/2026-09-14-project143-controlled-content-404.md);[UI report](../test-reports/2026-09-14-controlled-content-ui-acceptance.md)。代码已合 dev、schema 32、项目 143 定向 `migration_repair`;项目 143 `clean-run3` 与新项目 `full-chain-final` 主链及 restart 全部纯页面 PASS,目标 404=0 | [remediation](./2026-09-14-controlled-content-canonical-hash-remediation.md)。Wave 3(2026-09-18)已在隔离 docker PG(5436)执行 `TestReconcile_LegacyRepair_PG` 一次并 PASS,工程测试债关闭,见 [test-report](../test-reports/2026-09-18-wave3-test-debt-blindspots-test-report.md) |
| CHAT-HISTORY-REFRESH | 工作流激活后刷新,对话正文被阶段过滤器清空,但分类数量与锚点仍按全量返回 | **PASS** | [test-report](../test-reports/2026-09-13-chat-history-refresh-test-report.md);活验 [live.json](../test-reports/assets/2026-09-15-chat-history-refresh-live/live.json)(项目 6252,window=categories=2,guest 403);代码:`message_scope.go`、`chat_history_auth.go`、goose 00026/00027 | 闲聊刷新已补。发布门禁「激活后文档任务 + 重登/重启」仍开放,不回退本 gap |
| CHAT-INTENT-STATE | 真实会话被诊断探针污染;只读查询误启动文档写任务;错误动作与编辑状态刷新后丢失 | **PASS** | [audit](../audit/2026-09-13-conversation-intent-runtime-state.md);[test-report](../test-reports/2026-09-13-conversation-intent-runtime-state-test-report.md);双标签活验项目 **6275** / `sess-p6275-u10`(`live.json` + Docker 截图)。**不**删除 `sess-p143-u9` 历史探针 | [remediation](./2026-09-13-conversation-intent-runtime-state-remediation.md)。Wave 3–4 浏览器门已签;诊断污染消息仍不擅自删除 |
| ENV-RESTART-SOURCE | `docker compose restart` 只重启旧镜像,健康检查无法证明合入代码已部署 | **PASS** | `env-service.sh rebuild` + 真实摘要重测 | 集成冒烟统一使用 `dev rebuild` |
+25 -12
View File
@@ -1,6 +1,6 @@
# 模块与功能完成度(SSOT)
**更新**: 2026-09-16(Wave 0 校准)
**更新**: 2026-09-19(审计整改批 1–4 已合入 dev;medium/low 见 [long-term](../ops/long-term/2026-09-19-audit-remainder.md))
**production_ready**: yes(权威来源:[gap-matrix](../remediation/gap-matrix.md);本表不推导发布门禁)
**发布缺口**: [../remediation/gap-matrix.md](../remediation/gap-matrix.md)
**协作焦点**: [../ops/CURRENT.md](../ops/CURRENT.md)
@@ -8,6 +8,8 @@
**整改计划**: [../remediation/2026-09-16-feature-matrix-production-readiness-plan.md](../remediation/2026-09-16-feature-matrix-production-readiness-plan.md)
> 本表描述**能力成熟度**;上线 blocker 见 gap-matrix。二者正交:能力行不必全部 `done` 才能发布;`partial`/`deferred` 不得自动回退 `production_ready`。
>
> 2026-09-19 深度审计的 critical/high 已分四批合入 `dev`(数据一致性、鉴权、SSE/事件、前端 XSS)。不改 `production_ready`。未做项在 [long-term](../ops/long-term/2026-09-19-audit-remainder.md)。
---
@@ -16,7 +18,7 @@
| 字段 | 含义 |
|------|------|
| **声明范围** | 本行冻结的能力边界;`done` 只对该边界负责 |
| **状态** | `done` \| `partial` \| `planned` \| `deferred` \| `blocked` |
| **状态** | `done` \| `partial` \| `planned` \| `deferred` \| `blocked` \| `removed`(已下线,仅留历史证据) |
| **发布关系** | 与当前首发/已签门禁的关系:`non_blocker` / `补证` / `加固` / `deferred_enhancement` |
| **关闭条件** | 何时可将本行升为 `done`(或关闭 `partial`);stub/SKIP/fallback 不得冒充 |
| **证据** | 可追溯到报告/commit/环境/schema;代码或 artifact 变化后须重验 |
@@ -48,25 +50,28 @@
| 模块 | 声明范围 | 状态 | 发布关系 | 证据 | 剩余工作 / 关闭条件 | mutex |
|------|----------|------|----------|------|---------------------|-------|
| 意图识别 L1 | 18 类 Intent、三分支消解、写/只读分流、双标签 `DOC_BUSY`、intent 纯依赖边界 | done | non_blocker | [intent-recognition](../system-design/intent-recognition/);[审计](../audit/2026-09-13-conversation-intent-runtime-state.md);[报告](../test-reports/2026-09-13-conversation-intent-runtime-state-test-report.md);[双标签](../test-reports/assets/2026-09-15-conversation-intent-dual-tab/live.json);[U1](../test-reports/2026-09-15-multi-intent-u1-contracts-test-report.md)–[U3](../test-reports/2026-09-15-multi-intent-u3-intentflow-pg-test-report.md) | **边界 before**:含 U9–U12 叙事混入 → **after**:U9–U12 迁至「多意图扩面」行。关闭:纯依赖边界回归即重开 | `intent` |
| 多意图持久计划(U1–U8 基线) | app/intentflow 生命周期、HITL、默认 `legacy`、U1–U8 代码与安全基线 | done | non_blocker(默认 legacy) | [设计](../system-design/2026-09-15-multi-intent-hitl-plan.md);[U1](../test-reports/2026-09-15-multi-intent-u1-contracts-test-report.md)–[U8](../test-reports/2026-09-16-multi-intent-u8-task-generate-test-report.md);[Wave2 真 PI](../test-reports/2026-09-16-wave2-real-pi-evidence-test-report.md) | U8 已签。**Playwright 双标签**:覆盖 no-go 后实施中(见总控);升 `confirm/full` 另开 | `intent-plan` |
| 多意图扩面(U9–U12) | U9 LLM 分段实验;U10 mutate;U11 docgov;U12 workflow/run-control | planned | deferred_enhancement | [设计](../system-design/2026-09-15-multi-intent-hitl-plan.md);[go/no-go GO](../ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md);[总控](../ops/short-term/2026-09-16-full-backlog-override.md) | **2026-09-16 覆盖授权 GO**:分项独立 flag;默认 legacy tier | `intent-plan` |
| 多意图持久计划(U1–U8 基线) | app/intentflow 生命周期、HITL、默认 `legacy`、U1–U8 代码与安全基线 | done | non_blocker(默认 legacy) | [设计](../system-design/2026-09-15-multi-intent-hitl-plan.md);[U1](../test-reports/2026-09-15-multi-intent-u1-contracts-test-report.md)–[U8](../test-reports/2026-09-16-multi-intent-u8-task-generate-test-report.md);[Wave2 真 PI](../test-reports/2026-09-16-wave2-real-pi-evidence-test-report.md) | U8 已签。**Playwright 双标签**:真浏览器 PASS 已合入([报告](../test-reports/2026-09-16-intent-plan-playwright-dual-tab-test-report.md));升 `confirm/full` 另开 | `intent-plan` |
| 多意图扩面(U9–U12) | U9 LLM 分段实验;U10 mutate;U11 docgov;U12 workflow/run-control | done | deferred_enhancement | [设计](../system-design/2026-09-15-multi-intent-hitl-plan.md);[go/no-go GO](../ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md);[脚手架](../test-reports/2026-09-16-pu8-u9-u12-flags-test-report.md);[U9](../test-reports/2026-09-17-w4-u9-segment-test-report.md);[U10](../test-reports/2026-09-17-w4-u10-mutate-test-report.md);[U11](../test-reports/2026-09-17-w4-u11-docgov-test-report.md);[U12](../test-reports/2026-09-17-w4-u12-run-control-test-report.md) | **before**:独立 flag 脚手架。**after**:U9 可开 flag 走产品 PI proposer(规则已切则不出 proposal);U10–U12 分 flag dry-run→confirm 证据。**未升** `MULTI_INTENT_PLAN_TIER`(升 `confirm` 另开授权;永不默认 `full`)。U10–U12 领域 live 写仍须专项批准 | `intent-plan` |
| 对话 / ctxmgr baseline | 多轮上下文、刷新/重登/重启恢复、授权同集正文与计数、U10 端口化停止扩面 | done | non_blocker | [multi-turn](../system-design/multi-turn-dialogue/);[刷新审计](../audit/2026-09-13-chat-history-refresh-disappears.md);[U10](../test-reports/2026-09-15-chatlog-contextasm-u10-test-report.md);[门禁 B3](../test-reports/2026-09-16-chat-refresh-gate-test-report.md)(项目 6359) | **before**:语义摘要误标 D5 混入 → **after**:摘要迁「语义摘要 D3」;D7 数据治理独立。U10 停止扩面 | `chat` |
| 语义摘要(D3) | 授权后可见集合上的语义摘要;shadow → 可选替换 deterministic | planned | deferred_enhancement | [chat-agent-p6-backlog](../backlog/chat-agent-p6-backlog.md);[go/no-go GO](../ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md);[pu6](../ops/long-term/2026-09-16-pu6-semantic-summary-contract.md) | **覆盖授权 GO**:`SEMANTIC_SUMMARY_SHADOW` 默认 off | `chat` |
| 对话数据治理(D7) | 留存/删除口径、库·备份·日志控制、敏感字段加密边界 | deferred | deferred_enhancement(违规则升 blocker) | [计划](../remediation/2026-09-16-feature-matrix-production-readiness-plan.md) Scope Boundaries | 先数据分类与现状盘点;确认当前基线违规 → 立即写 gap-matrix | `chat` |
| 语义摘要(D3) | 授权后可见集合上的语义摘要;shadow → 可选替换 deterministic | done | deferred_enhancement | [chat-agent-p6-backlog](../backlog/chat-agent-p6-backlog.md);[go/no-go GO](../ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md);[pu6](../ops/long-term/2026-09-16-pu6-semantic-summary-contract.md);[脚手架](../test-reports/2026-09-16-pu6-semantic-summary-test-report.md);[W2 真 PI](../test-reports/2026-09-17-w2-semantic-summary-shadow-test-report.md) | **before**:flag 脚手架 + heuristic。**after**:dev 可开 `SEMANTIC_SUMMARY_SHADOW` 走产品 PI no-tool summarizer(默认 off)。**REPLACE 未启用**(独立后置,不在本行关闭条件内) | `chat` |
| 对话数据治理(D7) | 留存/删除口径、库·备份·日志控制、敏感字段加密边界 | deferred | deferred_enhancement(违规则升 blocker) | [计划](../remediation/2026-09-16-feature-matrix-production-readiness-plan.md) Scope Boundaries;[收口 §7.1](../remediation/2026-09-16-partial-deferred-completion-plan.md);[D7 ADR 草案](../adr/2026-09-17-d7-chat-data-retention.md);[W7 盘点](../audit/2026-09-17-d7-data-inventory.md);[报告](../test-reports/2026-09-17-w7-d7-inventory-test-report.md) | **after W7**:只读盘点完成(sessions/messages/KB/日志/备份/event)。**未发现**已确认基线违规,未写 gap-matrix。口径仍 `pending-compliance-signoff`;禁止按 365/180/30 物理删除。本行不升 done | `chat` |
| 智能体小队 | 角色-任务-工作区-黑板 | done | non_blocker | [agent-squad](../system-design/agent-squad/);[test 2026-09-07](../test-reports/2026-09-07-dynamic-squad-planning-test-report.md) | 非关键步骤降级(A5/A6)属 backlog | `squad` |
| 工作流治理 | 三正式工作流、设置页/DutyMode、动作级鉴权、真实 PI 三工作流 E2E、full/none 混合长链 | done | non_blocker | [三工作流整改](../remediation/2026-09-12-three-workflows-strict-governance-remediation.md);[409/职责](../test-reports/2026-09-14-workflow-plan-409-frozen-and-optional-duties-test-report.md);[鉴权](../test-reports/2026-09-14-governance-action-level-authz-test-report.md);[PI E2E](../test-reports/2026-09-16-pi-three-workflow-e2e-test-report.md);[Wave2 full/none](../test-reports/2026-09-16-wave2-real-pi-evidence-test-report.md) | full 跨用户审批 + none 免审批不阻塞已签。纯软件自举仍独立 planned | `workflow` |
| 纯软件项目自举 | 软件项目创建、Bootstrap、Delivery、受控工程交接 | partial | deferred_enhancement(明确不挡首发) | [设计](../system-design/2026-09-14-software-project-bootstrap-workflow.md);[ADR](../adr/2026-09-16-software-project-bootstrap-keys.md);[L1 报告](../test-reports/2026-09-16-software-project-bootstrap-test-report.md);[总控](../ops/short-term/2026-09-16-full-backlog-override.md) | SWBOOT-00…09 L1 已落 `feature/software-project-bootstrap`(未合 dev);SWBOOT-10 stub only;真实 PI/UI NOT RUN | `workflow-design` |
| 研发设计控制(rdev) | 医疗第 4 工作流:13×60 manifest/模板、`squad.rdev_doc.v1` kind 编排、main-completed 硬 precheck、StageKey 动态化;不含前端/真 PI/键名空间化 | partial | deferred_enhancement | [设计](../system-design/project-workflow/07-研发工作流rdev接入-设计与实施计划.md);[short-term](../archive/ops/2026-09-17-rdev-workflow-integration.md);[模板深度](../archive/ops/2026-09-17-rdev-template-depth.md);[S0+S1 首批报告](../test-reports/2026-09-17-rdev-template-depth-test-report.md);[S1 续批报告](../test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md);[写作规范](../system-design/project-workflow/08-rdev模板写作规范.md);[backlog](../backlog/2026-09-17-rdev-phase2-backlog.md) | **P0+P1 done**。**模板深度 S0+S1 首批 + S1 续批 done**:60/60 模板已补强;真 PI 抽样 PASS(含 `rd_planning_review` + `rd_design_vv`,项目 6446)。剩余:S3 overlay 与 R2/R3 已接。P2 名称匹配、阶段折叠、批量审批已接。选中 rdev 时显示与服务端相同的 CDO 前置说明(`workflowPrerequisite.test.ts`)。P4 键名空间化已接:发布清单用 `bd_`/`pm_`/`tm_`/`sw_`,旧键仍走同一套步骤和模板,旧 doc_id 仍可查(`keyspace_test.go`)。P3 三样本已在 dev 真 PI 上跑过(项目 6533):`rd_sw_plan` 规划期关闭;`rd_proposal` completed 但未对齐模板标题;`rd_planning_review` 当时质量门禁 score 20,是把同节后一张法规表算进问题行。门禁已只读第一张表;保存的终稿不再报「问题行缺少」。建议书标题仍未对齐模板。没有新的真 PI。见 [P3 报告](../test-reports/2026-09-19-rdev-p3-real-pi-test-report.md)。nightly 未扩成四工作流。 | `workflow-def` / `rdev-templates` |
| 纯软件项目自举 | 软件项目创建、Bootstrap、Delivery、受控工程交接 | partial | deferred_enhancement(明确不挡首发) | [设计](../system-design/2026-09-14-software-project-bootstrap-workflow.md);[ADR](../adr/2026-09-16-software-project-bootstrap-keys.md);[L1 报告](../test-reports/2026-09-16-software-project-bootstrap-test-report.md);[W5a](../test-reports/2026-09-17-w5a-software-bootstrap-ui-pi-test-report.md) | **before**:L1 + UI 仍克隆医疗模板。**after W5a**:catalog 驱动创建、软件不挂医疗 key、docs_only 真 PI 建议 delivery 且不自动激活。**SWBOOT-10 仍 stub**(W5b);本行不升 done | `workflow-design` |
| IAM / 鉴权 | 项目级 API 鉴权 + RBAC;会话/阶段授权 | done | 加固 | [v3 full inventory](../audit/authorization-matrix-v3-full.md);[session 中断](../test-reports/2026-09-16-iam-route-inventory-test-report.md);[fail-closed](../test-reports/2026-09-16-wave1-iam-fail-closed-test-report.md);[410 策略](../audit/2026-09-16-bug11-410-retire-decision.md);[R13](../audit/2026-09-16-r13-data-safety-checklist.md) | 全路由 inventory + session 中断负例 + 410 冻结 + R13 基线已签 | `authz` |
| 文档治理 | 法定文档生命周期 + 租约 + 受控正文读取 | done | non_blocker | [docgov](../test-reports/2026-09-08-docgov-lifecycle-and-claiming-framework-test-report.md);[正文 UI](../test-reports/2026-09-14-controlled-content-ui-acceptance.md);[canonical hash](../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md) | 项目 143 只读;不终止 | `docgov` |
| 文档版本 baseline | 账本、人工修订、确定性 diff+lineage、运行时 UI、负责人通知 | done | non_blocker | [管理](../test-reports/2026-09-13-document-revision-management-test-report.md);[Round20 UI](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md);[ADR](../adr/2026-09-13-document-version-boundary.md) | **before**:完整 PI narrative 混入 → **after**:迁「PI change-report 叙事」。fallback 报告是本行内显式行为,不是缺口 | `docgov` |
| PI change-report 叙事 | 只读消费 diff+lineage 的 PI 叙事;失败全量降级 fallback | planned | deferred_enhancement | [Round20](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md);[go/no-go GO](../ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md);[pu7](../ops/long-term/2026-09-16-pu7-pi-narrative-contract.md) | **覆盖授权 GO**:`PI_CHANGE_REPORT_NARRATIVE` 默认 off | `docgov` |
| PI change-report 叙事 | 只读消费 diff+lineage 的 PI 叙事;失败全量降级 fallback | done | deferred_enhancement | [Round20](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md);[go/no-go GO](../ops/research/2026-09-16-wave3-pu6-pu8-go-no-go.md);[pu7](../ops/long-term/2026-09-16-pu7-pi-narrative-contract.md);[脚手架](../test-reports/2026-09-16-pu7-pi-narrative-test-report.md);[W3 真 PI](../test-reports/2026-09-17-w3-pi-change-report-narrative-test-report.md) | **before**:flag 脚手架 + 仅 fallback。**after**:dev 可开 `PI_CHANGE_REPORT_NARRATIVE` 走产品 PI no-tool narrator(默认 off)。digest 绑定;畸形/超时全量 fallback。**不把 fallback 写成完整 PI** | `docgov` |
| 前端工作台 | 三栏 + 块文档 + SSE;错误卡/进度/busy;版本冲突信封;demo seed 默认关;终止 preview | done | non_blocker | [workbench](../test-reports/2026-09-08-three-column-workbench-and-block-document-test-report.md);[双标签](../test-reports/assets/2026-09-15-conversation-intent-dual-tab/screenshots/tab-b-busy.png);[demo](../test-reports/2026-09-16-demo-seed-pollution-test-report.md);[B4](../test-reports/2026-09-16-frontend-gate-b4-test-report.md)(项目 6363) | **before**:空「缺口」却 partial → **after**:本行 done。其他 409 消费方信封复用另列 hardening backlog | `web` |
| PI Runner / 配置链 | pi-agent + MiniMax + typed-result-v1 | done | non_blocker | [piagent](../test-reports/2026-09-13-codex-audit-p0-remediation-test-report.md);[container-env](../test-reports/2026-09-13-container-env-configuration-test-report.md);[typed-result](../test-reports/2026-09-15-pi-typed-result-v1-test-report.md) | — | `pi-agent` |
| 三环境运维 | dev/test/main + 共享 KB;对话/业务库隔离 | done | non_blocker | [PROJECT.md](../../PROJECT.md) §4;CURRENT 环境快照 schema **47** | — | `infra` |
| CI / E2E | PR CI、PG 集成、治理 PG、已签真实 PI 门禁;**nightly** schedule/`workflow_dispatch` + infra/product 分类 receipt | partial | 加固(阻止**下一次**晋升,不自动否定已发布) | [BUG-08](../test-reports/2026-09-16-ci-governance-pg-bug08-test-report.md);[PI 三工作流](../test-reports/2026-09-16-pi-three-workflow-e2e-test-report.md);[B3](../test-reports/2026-09-16-chat-refresh-gate-test-report.md);[B4](../test-reports/2026-09-16-frontend-gate-b4-test-report.md);[Wave2B nightly/receipt](../test-reports/2026-09-16-wave2b-nightly-promotion-receipt-test-report.md) | 关闭条件:nightly 入口 + 失败分类 + promotion-receipt 门禁已交付;TempDir race **已修**;PR CI 不依赖外部模型。Actions secret/runner 需环境配置 | `ci` |
| 三环境运维 | dev/test/main + 共享 KB;对话/业务库隔离 | done | non_blocker | [PROJECT.md](../../PROJECT.md) §4;CURRENT 环境快照 dev/test schema **48**、main **47** | — | `infra` |
| CI / E2E | PR CI、PG 集成、治理 PG、已签真实 PI 门禁;**nightly** schedule/`workflow_dispatch` + infra/product 分类 receipt | done | 加固(阻止**下一次**晋升,不自动否定已发布) | [BUG-08](../test-reports/2026-09-16-ci-governance-pg-bug08-test-report.md);[PI 三工作流](../test-reports/2026-09-16-pi-three-workflow-e2e-test-report.md);[Wave2B](../test-reports/2026-09-16-wave2b-nightly-promotion-receipt-test-report.md);[Wave2C](../test-reports/2026-09-16-wave2c-same-image-digest-test-report.md);[W1 green](../test-reports/2026-09-17-w1-ci-e2e-green-nightly-test-report.md) + [receipt `6e2476f0…`](../assets/promotion-receipts/6e2476f0f2e408e111fe06ca7c31a38294a340b3.json) | **before**:partial(FullNone product_fail / secrets 文案过时)→ **after**:secrets 已配;duplicate goose 00048 已清;FullNone+U8 nightly `verdict=pass` | `ci` |
| Artifact 同 digest 晋升 | 候选 commit 一次构建、按 digest 晋升、promotion receipt | done | 加固 | [计划 PU5B](../remediation/2026-09-16-feature-matrix-production-readiness-plan.md);[Wave2B](../test-reports/2026-09-16-wave2b-nightly-promotion-receipt-test-report.md);[Wave2C](../test-reports/2026-09-16-wave2c-same-image-digest-test-report.md) | **关闭**:same-image pin(`candidate-images-*` + `PINNED_IMAGE_MODE` + promote `--require-digests`)。**声明**:单机 retag/digest pin;远程 registry 推送另立任务 | `infra` |
| 可靠事件核心 | PG dispatcher、notify/advance/projection live、生产闭包 hook 退出、Phase2 选择性解耦已合入 | done | non_blocker | [E0A–E2](../test-reports/2026-09-15-event-e0a-production-scope-contract-test-report.md) 等;[复盘](../ops/research/2026-09-15-track-e-retrospective.md);[shared live](../test-reports/2026-09-15-event-notify-shared-live-test-report.md);[phase2 closeout](../test-reports/2026-09-15-phase2-closeout-test-report.md) | **before**:与 FAV off 混成 partial → **after**:FAV 独立行。选择性后续解耦按收益触发 | `architecture-docs` / `events` |
| Final Artifact Vault(FAV) | 不可变终态制品库;`FAV_DEGRADED_READ=false` | planned | deferred_enhancement | [Track E 复盘](../ops/research/2026-09-15-track-e-retrospective.md);[short-term](../ops/short-term/2026-09-16-fav-u7-incremental.md) | **覆盖授权增量实施**;仍**禁止**整支 merge;degraded read 默认 false | `events` |
| Final Artifact Vault(FAV) | 不可变终态制品库;`FAV_DEGRADED_READ=false` | partial | deferred_enhancement | [Track E 复盘](../ops/research/2026-09-15-track-e-retrospective.md);[U7 报告](../test-reports/2026-09-16-fav-u7-incremental-test-report.md);[W6 shadow](../test-reports/2026-09-17-w6-fav-subscriber-shadow-test-report.md);[short-term](../ops/short-term/2026-09-17-w6-fav-subscriber-shadow.md) | **after W6**:subscriber `ObserveShadow` 只计算 intended outcome,不写副作用。仍**禁止**整支 merge;`FAV_DEGRADED_READ` 默认 false;**live 未放量**(staging→artifact→publication 各 ≥7 天观察窗) | `events` |
| 系统管理台 | 全屏系统级管理视图(总览/KB/特性开关/系统设置/工作流/角色/用户/文档 8 分组);`/api/v1/admin/system/*`;`system_settings` 白名单可写;吸收下线 AdminSettingsModal | done | non_blocker | [short-term](../ops/short-term/2026-09-17-system-admin-console.md);[测试报告](../test-reports/2026-09-17-system-admin-console-test-report.md);commit `f1404d5`/`0eaca61`、merge `dc7c31e`(dev);dev 冒烟 schema 49 + 四端点 + 写读回环 PASS | 二期:Playwright 实跑、细粒度 `system:*` 权限、设置审计日志、KB 运维动作、白名单项接消费方 | `web` + `sysadmin` |
| 个人工程中控台(已移出) | 原本地只读看板与后来的 Control Center 都不再属于本仓库 | removed | 进度管理改由独立项目承担 | [历史设计](../archive/design/2026-09-17-personal-engineering-control-center-plan.md);[历史报告](../test-reports/2026-09-17-engineering-dashboard-test-report.md) | 2026-09-19 删除 `cmd/control-center`、`internal/controlcenter`、`control-center/web`、`deploy/control-center`。不恢复 `engineering-dashboard` | — |
---
@@ -77,7 +82,7 @@
| Intent L1 | partial(混入 U9–U12) | done | U9–U12 → 多意图扩面 | 是(双标签 + 分流 + U1–U3) |
| Chat/ctxmgr | partial(混入语义摘要 D5 误标) | done | D3 摘要行;D7 治理行 | 是(B3 项目 6359) |
| Document revision | partial(混入完整 PI 叙事) | done | PI change-report 叙事行 | 是(Round20;fallback 为声明行为) |
| Frontend workbench | partial(缺口栏已空) | done | 其他 409 信封复用 → backlog | 是(B4 项目 6363) |
| Frontend workbench | partial(缺口栏已空) | done | Wave 3 已收口 projectMembers/freeformDoc/taskRuns/chatSessions 结构化错误信封复用 | 是(B4 项目 6363) |
| 可靠事件 | partial(与 FAV 混行) | done | FAV 独立 deferred | 是(E0–E2 + shared live) |
---
@@ -88,3 +93,11 @@
2. 同一 `mutex` 同时仅一个 Agent `in_progress`(见 CURRENT)
3. 新能力行:复制 [../ops/templates/feature-matrix-row.md](../ops/templates/feature-matrix-row.md)
4. 拆行/收口须保留 before/after 与义务迁移(见上表);禁止缩口径假完成
## 2026-09-17 首次加载性能专项
首次加载与重启首访性能优化:**partial**(U2 静态交付已验收;U3 只做了登录壳拆包,未关闭)。[审计](../audit/2026-09-17-initial-load-performance-audit.md) · [方案](../remediation/2026-09-17-initial-load-performance-plan.md) · [U2 报告](../test-reports/2026-09-17-initial-load-perf-u2-test-report.md)。U2:自托管字体 + br/gzip。U3 进展(`fix/audit-remainder-closeout`):导出、预览、管理台、块编辑器、Mermaid/公式改为点击或出现时再加载。入口包 `index-*.js` 由 2.83 MB / br 626 KB 降到 737 kB / br 170 KB(`index-j0BIrjIR.js`,包内无 katex)。公式在气泡或正文里出现时才加载,富文本复制同样延后。U3 的浏览器资源瀑布还没测,本行不关。U5:`/auth/me` 复用本请求已核过的用户,不再第二次解析会话;会话与用户状态合成一次 JOIN。没有锁等待证据,所以不节流 `last_seen`。`TestAuthMe_LogoutNextRequestIs401`。U1、U6、U7 未做。U4 进展:登录不再按项目数拉成员名册,只同步当前项目;其他项目先种入当前用户以保持会话可见,完整名册在打开成员面板时取。会话列表不再因项目数组变化而重拉,迟到响应用代次丢弃,同一项目的在途成员请求合并。`src/data/initFanout.test.ts`。2026-09-19 浏览器证据(`e2e/initial-load-performance.spec.ts`,n=20,本仓 Vite `:3100` 代理 `:8080`):每次登录成员项目数 1、会话列表 GET 1,匿名与登录后资源路径均无 katex/mermaid/docx。同一探针在重建后的 `:8080`(`index-DOO0-Yh7.js`,schema 53,n=5)成员项目 1、会话列表 GET 1,匿名 JS 传输 172,417 B,首屏路径无 katex/mermaid/docx。重建前旧包 n=1 曾是 704/30。慢网 n=3、CPU 4 倍:10 Mbps 表单可见 558–604 ms,2 Mbps 1279–1296 ms,样本不足 20,U1 不关。U6 不加索引:测到的瓶颈是已消失的成员扇出,没有慢 SQL 证据。U7 已测未关:[报告](../test-reports/2026-09-19-initial-load-u7-restart-test-report.md)。Vite 监听约 0.3 s;314 个模块冷/热 1.45/1.11 s,不是历史十几秒。postgres+app 到 `/ready` 1.0–1.2 s。无头浏览器缺系统库,登录表单可见未测;不宣称较基线下降 50%。mutex `web + static-delivery`(U2 done)/ `loading-performance-audit`。
## 2026-09-17 文档编制人兼任方案
新增能力 **done(U1–U6,已合入 `dev@09a9921`)**:[方案](../remediation/2026-09-17-document-author-only-plan.md) · [源码核查](../audit/2026-09-17-document-author-only-analysis.md) · [U6 验收](../test-reports/2026-09-17-document-author-only-u6-test-report.md) · [收口交接](../ops/handoffs/2026-09-17-document-author-only-closeout.md)。任务归档:`archive/ops/2026-09-17-document-author-only-u{1..6}.md`。总开关默认 off;test/main 晋升与开放授权另授。变更提案 HTTP 仍缺([audit](../audit/2026-09-17-docgov-modification-proposal-http-gap.md))。mutex `document-duty-policy`。
+6
View File
@@ -138,6 +138,12 @@
---
### 8. 个人中控台(已移出本仓库)
项目开发进度由独立的统一管理系统负责,不再是本仓库功能。本仓库只保留智能体系统。旧只读工程中控台的历史设计仍在 [../archive/design/2026-09-17-personal-engineering-control-center-plan.md](../archive/design/2026-09-17-personal-engineering-control-center-plan.md),代码不恢复。
---
## 🏗️ 在整体架构中的位置
```
+13 -1
View File
@@ -90,6 +90,7 @@ imports:
- taskrun
- workflowdef
- workspace
- sysadmin
app/chatflow:
- coordinator
- ctxmgr
@@ -119,6 +120,9 @@ imports:
- app/uow
- events
- intent
app/fav:
- artifactvault
- events
app/uow: []
app/stageflow:
- bizdev
@@ -144,6 +148,7 @@ imports:
httpx: []
intent:
- maturity
- squad
kb:
- config
maturity: []
@@ -199,6 +204,7 @@ imports:
- workflowdef
- workspace
- artifactvault
- sysadmin
squad:
- agent
- config
@@ -206,6 +212,7 @@ imports:
- stream
- template
- workspace
- workflowdef
storage: []
stream: []
stream/transport:
@@ -220,7 +227,8 @@ imports:
- projectworkflow
- stream
- workspace
template: []
template:
- workflowdef
upload: []
workflow: []
workflow/runtime:
@@ -241,6 +249,8 @@ imports:
dataset:
- artifactvault
- app/uow
sysadmin:
- config
table_owners:
document_records:
@@ -323,6 +333,8 @@ table_owners:
- app/intentflow
intent_plan_shadow:
- app/intentflow
system_settings:
- sysadmin
path_owners:
output.md:
@@ -0,0 +1,254 @@
# 07 研发工作流(rdev)接入——设计与实施计划
- **版本**: v1.1(四项关键决策已由用户确认,2026-09-17;见 §8)
- **日期**: 2026-09-17
- **来源**: 用户需求「在系统中加入研发工作流」;参考项目调研见 [research/2026-09-17-rdev-workflow-reference-analysis.md](../../ops/research/2026-09-17-rdev-workflow-reference-analysis.md)
- **范围**: 在现有 5 个正式工作流(医疗三 + 软件两)之外,新增医疗第 4 工作流「**研发设计控制流程**」(key: `rdev`,**13 阶段 / 60 文档任务一次到位**,ISO 13485 DHF/DMR 设计控制链);并随后对现有工作流任务键做统一命名空间化(D12,P4)
- **分支建议**: `feature/rdev-workflow`(从 dev 切出);键名空间化独立分支 `feature/workflow-key-namespace`
---
## 1. 结论摘要
参考项目的 rdev 工作流与本系统的「workflowdef 版本化定义 + projectinstance 冻结实例 + bizdev/squad 执行链」架构高度同构,接入以**数据与配置为主、代码为辅**:
1. **一个新 manifest**(`rdev.v2.json`,13 stage × 60 doc task)+ **60 份模板** + **一个通用执行器键** `squad.rdev_doc.v1` + **一个数据驱动的 rdev 任务目录表**(squad 包内)即可跑通主链;
2. **两处前置修复**:docgov 文档 Stage 字段去硬编码(现为写死 `V0.5_feasibility`);rdev 启动前置门禁(main 实例 completed,即 CDO 已批准)按 test_manager 先例做**执行器级 precheck**,不恢复流程级依赖(遵循 [WF-DEF-06 整改](../../remediation/2026-09-12-three-workflows-strict-governance-remediation.md));
3. **一个关键命名决策**:60 个任务键统一加 `rd_` 前缀(含模板文件名),避免与既有任务键 `system_reqs` 在 doc_id(`doc_proj{id}_{taskKey}`)、模板加载(`GetDocTemplate(taskKey)` 平铺目录)两层冲突;
4. 分四期实施(P0 前置修复 → P1 核心接入 → P2 治理与体验 → P3 真实 PI 验收),预估 2–3 周(单人)。
## 2. 参考项目 rdev 要点(回顾)
见 [调研笔记](../../ops/research/2026-09-17-rdev-workflow-reference-analysis.md)。核心结构:
- **13 phase / 60 stage**:01 策划(2) → 02 策划评审(1) → 03 设计输入(12) → 04 需求评审(1) → 05 输入阶段评审(1) → 06 设计输出(17) → 07 输出评审(1) → 08 验证(12) → 09 验证评审(1) → 10 转换(3) → 11 转换评审(1) → 12 确认(7) → 13 设计确认报告(1);
- **15 个 skippable**(软件 9 + 电气 3 + EMC + 动物试验 + 临床);
- **三种 artifact_kind**:`document` 47 / `review_minutes` 6 / `upload_index` 7;
- **记录归属**:`dhf` 为主,设计输出/转换类 `dhf+dmr`;
- **followon 门禁**:商务对接 CDO 批准后才可启动;启动时拷贝 bizdev 已填字段;
- **质量纪律**:模板写满、结论先行、UR→RS 追溯、缺项「待确认」、不适用须完整理由仍走审批、不编造数据/签字。
## 3. 现系统机制盘点(与本任务相关)
| 机制 | 现状 | 对 rdev 的影响 |
|------|------|----------------|
| 工作流定义 | `internal/workflowdef`:Definition + Version(schema v2 JSONB 快照、definition_hash、published);正式 key 白名单 `catalog_policy.go`;seed 走 `manifests/*.json` 内嵌 + `BootstrapSeeds` 幂等发布 | 新增第 6 个正式 key;manifest/seed/白名单/目录顺序同步 |
| 模板资产 | `templates/docs/*.md` 启动时全量上传(asset_key=文件名);运行时 `template.GetDocTemplate(taskKey)` 平铺读 `templates/docs/<taskKey>.md` | **平铺命名 → 必须无碰撞**;rd_ 前缀方案 |
| 项目实例 | `projectinstance`:planning→live 冻结 ConfigSnapshot;阶段线性 position;`AdvanceStage` 要求全部 blocking doc task approved;末阶段完成 → InstanceDone | 13 stage 线性推进天然匹配 phase 序;depends_on 语义由阶段序覆盖 |
| 执行链 | server `task_run_handlers` → `taskrun.Manager`(单一 Executor = `bizdev.ExecuteTask`)→ `squad.ExecuteTask`(AdaptivePlanner 按 taskKey 出步骤)→ PI Agent Runner | executor_key 目前是**发布校验元数据**,运行时统一走 bizdev;新增任务主要是 squad 侧编排数据 |
| squad 编排 | `SupportedTasks` 白名单(9 个);`DefaultWorkflowSteps`/`DefaultSquadAgents` 按 taskKey **硬编码 switch**;非白名单任务回落 autonomous adhoc | 60 任务若逐个 switch 不可维护 → 改为按 artifact_kind 三套通用编排 + rdev 数据目录表 |
| 文档账本 | docgov:`doc_id = doc_proj{pid}_{taskKey}`;**Stage 字段写死 `V0.5_feasibility`**(bizdev/service.go:483,489 + docgov/repository.go:28 兜底) | **P0 必修**:改为从冻结实例解析 StageKey |
| 前置依赖 | 无流程级依赖(WF-DEF-06 已移除);test_manager 用执行器级 precheck(approved SRS)+ `WorkflowPrerequisiteBanner` | rdev 同模式:precheck「main 实例 completed」 |
| 血缘 stale | `projectworkflow/service.go` MarkDownstreamStale;test_manager 记录单一上游 hash | 首期统一项目上下文注入;精确 depends_on 血缘列二期 |
| 意图 | L1 `extractDocName` 硬编码 9 个文档名;U8 多意图 task-generate 从 live 实例数据驱动 | rd 文档名匹配需增补或实例驱动化 |
| 前端 | `ProjectWorkflowSwitcher`(目录 API 驱动)+ 激活规划 UI + StageAdvance/Prerequisite Banner | 13×60 规划 UI 需折叠分组与批量三权指派 |
## 4. 关键设计决策
### D1 工作流标识与目录
- `OfficialKeyRDev = "rdev"`;对外名称建议 **「研发设计控制流程」**(与「商务对接流程」命名风格一致;备选「研发流程」);
- `product_domains: ["medical_device"]`(软件域不可选);
- `catalog_order = 40`(排在 test_manager 之后、software_bootstrap 之前);`medicalWorkflowKeys` 扩为四个;
- validator 文案「仅允许选择正式工作流(医疗三或软件自举/交付)」同步更新;审计口径「项目选择页只见 N 个工作流」从 5 → 6。
### D2 任务键与模板命名(关键决策)
**问题**:`doc_id`、模板加载、docgov task_key 三层都以 taskKey 平铺命名。rdev 的 `system_reqs`(SR)与现有 PM 任务 `system_reqs` 直接冲突;且未来任何工作流任务键都共享同一命名空间。
**推荐:60 个任务键统一加 `rd_` 前缀**(`rd_proposal`、`rd_design_plan`、`rd_system_reqs`…),模板文件同步 `rd_*.md`:
- 彻底消除 doc_id/模板/任务键三层冲突,跨工作流血缘清晰;
- 转换机械:从参考项目 `rdev.yaml` 逐行映射生成(可写一次性生成脚本,人工复核);
- manifest 中 `title`/`output_doc_title` 保留中文文档名,用户可见名称不变;
- 模板头部「文件编号 RD-…」保留参考项目编号(RD-PROPOSAL 等),不受键名影响。
**备选**:仅 `system_reqs` 一键改名、其余保持原键。缺点:命名空间纪律弱,未来再加工作流仍会踩。
### D3 manifest 结构(rdev.v2.json)
13 个 StageDef 对应 13 个 phase(键名风格沿用本仓库 `V0.1_triage` 惯例)。示例(完整 60 任务 = 参考项目 rdev.yaml 逐行映射):
```json
{
"schema_version": 2,
"workflow_key": "rdev",
"product_domains": ["medical_device"],
"stages": [
{"key": "RD01_planning", "name": "01 设计和开发策划", "position": 10, "optional": false,
"doc_tasks": [
{"key": "rd_proposal", "title": "项目建议书", "default_enabled": true, "creator_configurable": true,
"blocking_when_enabled": true, "executor_key": "squad.rdev_doc.v1", "quality_gate_key": "quality.generic.v1",
"template_asset_key": "rd_proposal", "output_doc_type": "rd_proposal", "output_doc_title": "项目建议书"},
{"key": "rd_design_plan", "title": "设计开发计划任务书", "default_enabled": true, "creator_configurable": true,
"blocking_when_enabled": true, "executor_key": "squad.rdev_doc.v1", "quality_gate_key": "quality.generic.v1",
"template_asset_key": "rd_design_plan", "output_doc_type": "rd_design_plan", "output_doc_title": "设计开发计划任务书"}
]},
{"key": "RD02_planning_review", "name": "02 策划评审", "position": 20,
"doc_tasks": [{"key": "rd_planning_review", "title": "设计和开发策划评审记录", "...": "同上模式"}]},
{"key": "RD03_design_input", "name": "03 设计输入", "position": 30, "doc_tasks": ["12 个任务"]},
{"key": "RD04_requirements_review", "position": 40, "doc_tasks": ["rd_req_review"]},
{"key": "RD05_input_phase_review", "position": 50, "doc_tasks": ["rd_input_phase_review"]},
{"key": "RD06_design_output", "position": 60, "doc_tasks": ["17 个任务"]},
{"key": "RD07_output_review", "position": 70, "doc_tasks": ["rd_output_review"]},
{"key": "RD08_verification", "position": 80, "doc_tasks": ["12 个任务"]},
{"key": "RD09_verification_review", "position": 90, "doc_tasks": ["rd_verification_review"]},
{"key": "RD10_transfer", "position": 100, "doc_tasks": ["3 个任务"]},
{"key": "RD11_transfer_review", "position": 110, "doc_tasks": ["rd_transfer_review"]},
{"key": "RD12_validation", "position": 120, "doc_tasks": ["7 个任务"]},
{"key": "RD13_validation_report", "position": 130, "doc_tasks": ["rd_design_validation_report"]}
]
}
```
- 全部任务 `default_enabled/creator_configurable/blocking_when_enabled = true`(与本仓库 normalize 惯例一致);
- **skippable 语义**:参考项目的 15 个可声明不适用任务与本仓库「激活规划期可关闭」语义等价(creator 在规划时关闭 = 不适用);「生成完整不适用页仍走审批」列为二期增强(D9);
- `output_doc_type` = 任务键(本仓库惯例 doc type = task key)。
### D4 执行器与质量门禁
- 新增唯一执行器键 **`squad.rdev_doc.v1`**(`workflow/registry.go`),运行时仍统一由 bizdev.ExecuteTask 按 taskKey 分派——与 `squad.test_manager.v1` 模式一致,避免 60 个注册项;
- 质量门禁首期 **`quality.generic.v1`**(全部 60 任务);kind 专用门禁列二期(D9)。
### D5 启动前置门禁(followon 语义)
遵循 WF-DEF-06:**不做流程级 RequiredUpstreamWorkflow**,改为执行器级 precheck(先例:test_manager 查 approved SRS):
- `bizdev.ExecuteTask` 对 `rd_` 前缀任务启动前校验:本项目 **main 工作流 live 实例 `completed`**(即 CDO 报价已批准)。查不到/未完成 → 明确错误文案(「请先完成商务对接流程(CDO 报价批准)后再启动研发设计控制流程」);
- 激活 rdev 实例时(planning 允许,运行由 precheck 兜底):`WorkflowPrerequisiteBanner` 增加 rdev 文案;目录推荐逻辑「main 完成后推荐 PM」扩展「main 完成后推荐 rdev」;
- 启动时拷贝 bizdev 字段:现有 `TaskRunRequest` 已带 project 字段(device_type/intended_use/target_market 来自项目实体),无需额外拷贝机制。
### D6 docgov Stage 字段动态化(P0 必修)
- `bizdev/service.go:483/489` 与 `docgov/repository.go:28` 写死 `V0.5_feasibility` → 改为从请求/冻结实例解析 StageKey 传入(`workflow/runtime/orchestrator.go` 的 `TaskResolution.StageKey` 已具备;`server/task_run_request_build` 把 stage key 带进 `bizdev.TaskRunRequest` 新增的 `StageKey` 字段并透传);
- 兜底策略:解析不到时回落 main 三阶段映射,再回落原值(兼容历史数据,不做历史迁移);
- `maturity` 包的 V0.1/V0.5/V1.0 成熟度映射仅对 main 任务生效,rd_ 任务首期跳过成熟度标签。
### D7 squad 编排(数据驱动重构)
新增 `internal/squad/rdev_catalog.go`:60 项任务目录表(taskKey → title/phase/kind/docCode/skippable/描述),生成来源 = 参考项目 rdev.yaml(一次性转换 + 齐套测试锁定):
- `SupportedTasks` 合并 rdev 目录(`isStandardTask` 命中,避免回落 adhoc);
- `DefaultWorkflowSteps`/`DefaultSquadAgents` 增加 `rd_` 前缀分支,**按 artifact_kind 三套通用编排**(对齐参考项目 squads/rdev.yaml 的 default_steps + 覆盖逻辑):
| kind | 步骤 | 小队 |
|------|------|------|
| document(47) | organizer → engineer(可并行)→ regulatory(可选)→ writer → leader | organizer/engineer/writer/leader;regulatory 注入软件/法规风险类(`rd_sw_*`、`rd_regs_stds`、`rd_adverse_events`、`rd_biocompatibility`、`rd_clinical`、`rd_animal_study`、`rd_risk_*`、`rd_emc_safety`) |
| review_minutes(6) | organizer → writer → leader | organizer/writer/leader(对齐参考项目评审阶段三步) |
| upload_index(7) | organizer → engineer → writer → leader | organizer/engineer/writer/leader |
- leader 角色名「研发设计控制负责人」(对应参考项目 rdev_leader);角色提示复用现有 `configs/agents/*.md`(organizer/engineer/writer/leader/regulatory 已有),rdev 语境差异放进步骤 `Accept` 与 TASK 说明;
- 参考项目 overlays 的核心纪律(写满、结论先行、追溯表必填、缺项「待确认」、不编造数据/签字/附件)合并进:a) 三套 kind 步骤的 `Accept`;b) `configs/shared/writing.md` 增补 DHF 纪律段(GetAgentInstruction 已自动附加该文件,rd 任务天然注入)。
### D8 上游文档注入与血缘
- 首期:`bizdev.ExecuteTask` 对 `rd_` 任务注入 **项目上下文快照**(`projectcontext.BuildSnapshot`,先例 test_manager)+ **同项目已批准文档清单**(bizdev 七件 + 已批准 rd_ 文档,作为 prior_docs 全量注入,交小队自行引用);
- 血缘:沿用 test_manager 模式在 finalize 时记录上游 hash(首期摘要级);精确 `depends_on`(如 rd_verification_review ← rd_design_vv + rd_risk_report_v)列二期(见 [backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md));
- `rd_system_reqs` 与 PM `system_reqs` 的关系:PM 输出若已批准,作为 prior doc 优先注入(不强制、不独占)。
### D9 不适用(N/A)与二期增强
- 首期:N/A = 激活规划期关闭任务(creator_configurable),推进语义由 readiness 门禁保证;
- 二期增强(参考项目行为):保留任务但生成「不适用说明页」(完整理由、走审批);UR/RS 结构化门禁(复用 PM `requirements.json` 模式于 rd_user_needs/rd_system_reqs);review_minutes/upload_index 专用确定性门禁。
### D10 意图与聊天
- U8 多意图 task-generate 从 live 实例 doc tasks 数据驱动——rd 任务应自动可用(P2 验证 60 任务名消歧与澄清卡);
- L1 `extractDocName` 硬编码名表:增补 rd 高频文档名(项目建议书、设计开发计划、风险管理计划、设计验证方案、设计确认报告 等),并**评估改为从 live 实例任务标题动态匹配**(推荐,彻底消除硬编码)。
### D11 前端
- `ProjectWorkflowSwitcher`:rdev 名称/顺序/描述来自目录 API(数据驱动)+ 本地 label 常量增补;
- 激活规划 UI:13 阶段 × 60 任务 × 三权指派是大列表——需按阶段折叠分组、三权「按阶段批量指派 / 继承上一阶段」操作、15 个 skippable 任务预设关闭建议;
- 文档工作台:展示 doc Stage 为 RD 阶段键(依赖 D6);`WorkflowPrerequisiteBanner` rdev 文案;
- 前端测试:workflow 相关既有断言(工作流数量/名称)同步更新。
## 5. 资产与代码改动清单
### 5.1 数据/配置资产
| 资产 | 说明 |
|------|------|
| `internal/workflowdef/manifests/rdev.v2.json` | 13 stage / 60 doc task(D3) |
| `templates/docs/rd_*.md` × 60 | 从参考项目 `templates/docs/*.md` 转换:改名 rd_ 前缀、保留 RD 编号/DHF 归属骨架;核对模板变量(`{{project_name}}/{{generated_at}}/{{snapshot_id}}/{{applicability}}/{{na_rationale}}/{{materials}}` 均为 RenderDoc 可用变量,缺失自动「待确认」) |
| `configs/shared/writing.md` 增补 | DHF 设计控制纪律段(rd 任务注入) |
| `internal/squad/rdev_catalog.go` | 60 项任务目录(title/phase/kind/docCode/skippable) |
### 5.2 Go 代码(按包)
| 包 | 改动 |
|------|------|
| `internal/workflowdef` | catalog_policy.go(常量/名称/顺序/域/医疗四键)、manifest_loader.go(V2ManifestFiles)、bootstrap.go(officialSeedMeta)、validator 文案、publish/catalog 测试更新 |
| `internal/workflow` | registry.go 注册 `squad.rdev_doc.v1` |
| `internal/squad` | rdev_catalog.go 新增;service.go SupportedTasks 合并;workspace.go rd_ 分支(按 kind 三套 DefaultWorkflowSteps/DefaultSquadAgents) |
| `internal/bizdev` | TaskRunRequest 增加 StageKey;ExecuteTask:rd_ precheck(main completed)、prior docs 注入、CreateOrGetDocument 传动态 Stage、ListStages/maturity 对 rd_ 的处理 |
| `internal/server` | task_run_request_build 透传 stage key;workflow_catalog_handlers 名称;齐套校验 Go test(60 manifest 任务 ↔ 模板文件存在非空 ↔ 末模板含「签署」,对齐参考 e2e-rdev.sh 断言 + 「rd_ 键与既有任务键集合不相交」断言) |
| `internal/docgov` | repository.go stage 兜底改为入参优先 |
| `internal/intent` | extractDocName 增补/实例驱动(D10) |
| `web/` | D11 各项 |
### 5.3 文档
- `.doc/ops/short-term/2026-09-17-rdev-workflow-integration.md`(任务条目,随本方案创建)
- FEATURE-MATRIX 新增行(planned → done 演进);验收报告归档 `.doc/test-reports/`
## 6. 分期实施计划
| Phase | 内容 | 分支/PR | 验收标准 |
|-------|------|--------|----------|
| **P0 前置修复** | D6 docgov Stage 动态化 + stage key 透传 + 回归 | `fix/docgov-stage-dynamic` | 现有三工作流全链路 PG 回归 PASS;新文档 Stage 字段 = 实例阶段键 |
| **P1 核心接入** | manifest + catalog/seed + registry + 60 模板 + squad 数据目录与 kind 编排 + rd_ precheck + 齐套 Go test + stub PG 全链路(激活 13 阶段 → rd_proposal 生成/审/批 → 推进 → N/A 关闭路径 → precheck 拒绝路径) | `feature/rdev-core` | `go vet`/`go test -short` PASS;PG 集成测试 PASS;齐套断言 60/60;main 未完成时 rd 任务启动被拒且文案正确 |
| **P2 治理与体验** | 前端(规划 UI 折叠分组/批量三权/PrerequisiteBanner/文档 Stage 展示)+ intent 名称匹配 + prior docs 注入与摘要级血缘/stale + web 测试 | `feature/rdev-web-governance` | web `npm test`/`npm run build` PASS;Playwright 抽检激活与推进;聊天「生成项目建议书」命中 rd_proposal |
| **P3 真实验收** | 真实 PI Agent + MiniMax 全链路:rd_proposal(document)+ rd_planning_review(review_minutes)+ rd_sw_plan 软件类 N/A 三样本;报告归档;CI「PI 三工作流」门禁扩为四 | — | `.doc/test-reports/` rdev 真实 PI E2E 报告;CI green receipt |
| **P4 键名空间化**(决策 4 扩展,D12) | main/pm/tm(+软件两)任务键改 `bd_`/`pm_`/`tm_`(`sw_`)前缀:manifest 新版本 + doc_id 归一映射 + 模板 alias + squad 旧键兼容 + 双路径回归 | `feature/workflow-key-namespace`(**独立验收,不与 P1–P3 合并**) | 旧 live 实例(旧键)与新建实例(新键)双路径 stub 全链路 PASS;全工作流任务键集合无交集断言 PASS;存量文档旧 doc_id 仍可读 |
依赖:P0 → P1 → P2 → P3;P1 与 P2 可部分并行(先冻结前后端契约);P4 在 P3 验收后启动(也可与 P2 并行,但合入 dev 须占集成槽串行)。
## 7. 风险与缓解
| 风险 | 影响 | 缓解 |
|------|------|------|
| 60 任务三权指派 UI 负担 | 激活体验差、误配 | 批量指派 + 阶段继承 + 三权默认创建人兜底(现状) |
| generic 质量门禁误杀评审记录/附件清单类 | 任务被错误打回 | P1 用 stub 对 6+7 个 kind 任务逐一回归;必要时豁免清单 |
| U8/意图对 60 文档名消歧 | 生成错任务 | P2 实例驱动匹配 + 澄清卡;高频名称抽检 |
| 命名空间遗漏 | doc_id/模板冲突回归 | 齐套 test 增加「rd_ 键不与既有任务键相交」断言 |
| CI 门禁与审计口径过时 | nightly 误报 | 同步「PI 三工作流」→ 四;审计 checklist 引用本方案 |
| 大 manifest / 冻结快照体积 | 性能 | 60 任务 JSONB 量级小,P1 PG 测试观察即可 |
## 8. 决策记录(已与用户确认,2026-09-17)
| # | 决策 | 结论 |
|---|------|------|
| 1 | 对外名称 | **「研发设计控制流程」**(key: `rdev`) |
| 2 | 首期范围 | **manifest 一次到位 60 任务 / 13 阶段**,不切试点 |
| 3 | N/A 语义 | 首期「激活规划期关闭」;「生成完整不适用页走审批」等二期增强**记入 backlog**:[2026-09-17-rdev-phase2-backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md) |
| 4 | 任务键前缀 | rdev 60 键统一 `rd_` 前缀;且**现有工作流(main/pm/tm)任务键、模板、阶段等同样做键名空间化处理**(见 D12,独立分期 P4,避免与 rdev 接入耦合) |
### D12 现有工作流键名空间化(决策 4 扩展,P4 实施)
**目标**:全系统任务键命名规约统一为 `<工作流前缀>_<任务>`,杜绝跨工作流 doc_id/模板/任务键冲突:
| 工作流 | 现键(9 个) | 新键 |
|--------|-------------|------|
| main(商务对接) | intake / research / feasibility_dev / feasibility_reg / user_requirements / prelim_design / cdo_quote | `bd_intake` / `bd_research` / `bd_feasibility_dev` / `bd_feasibility_reg` / `bd_user_requirements` / `bd_prelim_design` / `bd_cdo_quote` |
| product_manager | system_reqs | `pm_system_reqs` |
| test_manager | test_manager | `tm_system_verification` |
| rdev(新) | — | `rd_*`(P1 落地,60 个) |
| software_* | (另行盘点 `software.doc.v1` 任务键后纳入 `sw_` 前缀,P4 一并处理) |
**兼容策略(alias 兼容式改名,不破坏存量数据)**:
1. **manifest 版本升级**:main/pm/tm manifest 任务键改为新键 → `UpsertPublishedSeed` 按内容 hash 发布新版本;**冻结实例不迁移**——存量 live 实例继续持有旧键直至 completed(冻结快照是 SSOT,禁止改写);
2. **doc_id 兼容**:`bizdev/doc_id.go normalizeDocID` 增加旧→新映射表(`doc_proj{pid}_intake` → `doc_proj{pid}_bd_intake`),读路径旧 ID 自动归一;**文档账本不批量迁移**,新文档用新键,旧文档旧 ID 保留可查(已有 legacy pattern 归一先例);
3. **模板**:`templates/docs/` 文件改名(bd_intake.md 等),template loader 增加旧名→新名 alias(旧 live 实例运行仍按旧 taskKey 取模板→alias 命中新文件);
4. **squad 白名单**:`SupportedTasks`/`DefaultWorkflowSteps`/`DefaultSquadAgents` 增加旧键 alias 分支(存量实例执行路径不动),新键为主实现;
5. **intent/前端**:`extractDocName` 按文档名匹配不涉键名(无改动);前端断言与 label 按新键更新;
6. **回归**:旧 live 实例(旧键)+ 新规划实例(新键)双路径 stub 全链路回归;齐套断言扩展为「全工作流任务键集合无交集 + 各自前缀正确」。
**风险控制**:P4 独立分支 `feature/workflow-key-namespace`、独立验收,**不与 rdev P1–P3 合并**;若 P4 验收发现存量实例兼容缺口,允许只回退 manifest(DB seed 幂等)。
### 二期 backlog(决策 3,随时可续推进)
见 [2026-09-17-rdev-phase2-backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md):N/A 不适用页生成模式、UR/RS 结构化门禁、review_minutes/upload_index 专用确定性门禁、depends_on 精确血缘与 stale 传播、DMR 双记录归档、软件工作流 sw_ 键盘点等。
@@ -0,0 +1,59 @@
# rdev 模板写作规范
> 适用范围:`templates/docs/rd_*.md`(研发设计控制 / ISO 13485 DHF)
> 更新日期:2026-09-17
## 1. 分工红线(强制)
| 层 | 负责 | 不负责 |
| --- | --- | --- |
| **模板**(`templates/docs/rd_*.md`) | 章节结构、表头、逐节写作指令、示例「待确认」行、治理骨架(编号/适用性/追溯/签署) | 运行时角色口吻、模型选择、粒度下限的强制执行 |
| **overlay / 运行时**(`configs/agents/*`、`configs/shared/writing.md`、未来 overlays) | 写作纪律、DHF 粒度下限、禁止编造、角色边界 | 替代模板定义专业章节结构 |
一句话:**模板管结构与占位;overlay/运行时管写作纪律与粒度下限。**
## 2. 八条基准(源自商务模板实践)
1. **结论先行**:文首结论句完整;后文不得与结论打架。
2. **四段式展开**:结论句 → 表格或列表 → 解读段落 → 出处/支撑;禁止通篇只有列表。
3. **括号指令可执行**:每节括号内写清覆盖范围、缺项规则、禁止项;禁止只写「按本阶段专业结构写」。
4. **表不交空壳**:至少一行「待确认」示例行;禁止空表头。
5. **缺项显式**:统一标「待确认」,并在「待确认清单」汇总。
6. **不做疗效宣称**:设计控制文档禁止疗效/临床效果绝对化用语。
7. **禁止残留提示**:终稿不得留下括号写作提示原文。
8. **追溯可填**:`| RD-` 行存在;上游/下游未知写「待确认」不留空白无说明。
## 3. 治理骨架(每份 rd_ 模板保留)
- 文首元数据:项目 / 生成时间 / 快照 / 文件编号 / 记录归属:DHF / 版本 / 阶段
- `## 结论` / `## 适用性`
- 专业正文各节(≥4 个 `## ` 专业或治理章节合计满足 lint)
- `## 追溯`(含 `| RD-` 行)
- `## 已有材料摘要` / `## 待确认清单` / `## 签署` / `## 说明`
## 4. 补强清单与批次
| 批次 | 范围 | 状态 |
| --- | --- | --- |
| S0 样例 | `rd_design_input_spec` | 本轮 |
| S1 批 1 | `rd_proposal` / `rd_design_input_list` / `rd_system_design` / `rd_regs_stds` / `rd_adverse_events` | 本轮 |
| S1 批 2 | `rd_sw_plan` / `rd_sw_reqs` / `rd_sw_config` / `rd_risk_plan` | 本轮 |
| S1 批 3 | `rd_design_plan` / `rd_user_needs` / `rd_hazard_analysis` / `rd_system_reqs`(SRS 深度移植) | 本轮 |
| S1 续批批1 | 评审记录 6 份(`rd_planning_review` 等) | done |
| S1 续批批2 | 阶段06 硬件/工艺 8 份 | done |
| S1 续批批3 | 阶段06 软件/检验/技术要求+清单 9 份 | done |
| S1 续批批4 | 阶段08 验证 12 份 | done |
| S1 续批批5 | 阶段10–13 转换/确认 11 份 | done |
| S1 续批合计 | 剩余 46 份全部同等深度;allowlist 60/60;真 PI 抽样 PASS | done([报告](../../test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md)) |
| S2 / S3 | per-stage 步骤、overlay 机制、专用门禁 | follow-up |
## 5. Lint 门禁
`internal/workflowdef/rdev_template_lint_test.go` 对「已补强 allowlist」断言:
- 不含「按本阶段专业结构写」
- 正文 `## ` 章节 ≥ 4
- 含追溯表行 `| RD-`
- 含 `## 待确认清单` 与 `## 签署`
未列入 allowlist 的模板不参与断言;随批次增长扩大 allowlist。
@@ -0,0 +1,110 @@
# FAV U7 增量(publisher stub)测试报告
## 一、 测试背景 (Background)
P7 Final Artifact Vault 禁止整支 merge `feature/final-artifact-vault`。相对当前 `dev`,FAV 旁支的 `internal/artifactvault/*` 多数文件已大幅分叉(dataset Candidate backfill vs TerminalRow),强行 cherry-pick 会引入不可控冲突。本切片改为 **U7 增量 stub**:配置门闩、HTTP status、events 订阅桩与 CLI stub,全部默认关闭。
## 二、 测试目标 (Test Objectives)
- `FAV_DEGRADED_READ` 默认 false(config + docquery + vault GET)
- `FAV_PUBLISHER_ENABLED` 默认 false;进程内 Drain 不启动
- fav durable consumer 保持 mode=off;`Registry.Register(fav)` fail-closed
- `cmd/artifact-vault` 可编译;仅 `status|version`,无破坏性操作
- 产出 go/no-go:**subscriber 保持 OFF,直至单独审批**
## 三、 测试方案与环境 (Test Plan & Environment)
| 项 | 值 |
|----|----|
| OS | Linux |
| Go | 本机 `go test` / `go vet` |
| 分支 | `feature/fav-u7-publisher`(自 `dev@ebe177e`) |
| 层级 | 单元测试 + CLI 冒烟(无 stub 冒充真实 PI) |
| 证据 | `.doc/test-reports/assets/2026-09-16-fav-u7-incremental/unit-tests.txt` |
核心用例矩阵:
| ID | 用例 | 期望 |
|----|------|------|
| C1 | config 默认 | degraded/publisher false |
| C2 | vault init/start | publisher nil / not running |
| C3 | GET vault/status | consumer_mode=off |
| C4 | fav EventConsumer 零值 | HandleLease → ErrDisabledConsumer |
| C5 | events Registry | Register(fav) 失败;LiveConsumers 不含 fav |
| C6 | docquery | FavDegradedReadEnabled() false |
| C7 | artifact-vault status | 打印 remaining_to_port;无 backfill |
## 四、 预期结果 (Expected Results)
- 所有默认路径 FAIL-CLOSED:不写 vault blob、不 claim fav lease、不启用 degraded GET
- 显式 `FAV_*=true` 仅打开配置位;durable Register 仍被 events 硬门拒绝
- go/no-go 结论:**NO-GO for enabling fav subscriber**
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### C1–C3 config / vault
- **测试输入**:`config.Load("/dev/null")`;`Server{cfg}.initArtifactVault/startVaultPublisher`;`GET /api/v1/vault/status`
- **实际输出**:见 assets `unit-tests.txt` — `TestFAVFlagsDefaultOff` / `TestVaultDefaultsStayDisabled` / `TestVaultStatusReportsOff` PASS
- **评价判定**:PASS
- **耗时**:<10ms
### C4 fav subscriber stub
- **测试输入**:零值 `EventConsumer`;`Enabled=true` 仍调用 HandleLease
- **实际输出**:均 `events: consumer is disabled`;`Register(fav)` 失败
- **评价判定**:PASS
### C5–C6 events / docquery
- **测试输入**:既有 `TestAssertLiveConsumersRejectsFAV`、`TestLiveConsumersOmitsFAV`、`TestFavDegradedReadDefaultOff`
- **实际输出**:PASS(PG claim 负例缺 `TEST_DATABASE_URL` 时 SKIP,与既有约定一致)
- **评价判定**:PASS
### C7 CLI stub
- **测试输入**:`go build ./cmd/artifact-vault && artifact-vault status`
- **实际输出**:JSON 含 `consumer_mode=off`、`degraded_read=false`、`remaining_to_port` 列表
- **评价判定**:PASS
## 六、 自动化测试套件汇总 (Test Suite Execution)
```text
ok internal/config (FAV flags + ValidateIndependentVault)
ok internal/app/fav (subscriber defaults off)
ok internal/server (vault stub defaults off)
ok internal/events (FAV register/live omit)
ok internal/docquery (FavDegradedRead default off)
go vet PASS on touched packages
```
完整控制台:`assets/2026-09-16-fav-u7-incremental/unit-tests.txt`
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
### Go / No-Go
| 决策点 | 结论 |
|--------|------|
| 合入本 stub 分支到 `dev`(另占集成槽) | **条件 GO**(默认 off,可审) |
| 启用 fav durable subscriber / `Register(fav)` | **NO-GO** — 需单独审批 |
| 启用 `FAV_DEGRADED_READ` | **NO-GO** — 默认 false,未做 M2 负例放行 |
| 启用 `FAV_PUBLISHER_ENABLED` 生产 Drain | **NO-GO** — 缺 ingest hooks 与完整 CAS 接线审计 |
| 整支 merge `feature/final-artifact-vault` | **NO-GO**(红线) |
### 仍待从 FAV 旁支手工移植(冲突重,本切片未搬)
1. `enumerate.go`(`EnumerateTerminals` / `LoadExclusions`)
2. `TerminalRow` + `Backfill(rows)`(与现 dataset `Candidate` 路径分叉)
3. 完整 `recover-plan` / `recover-apply` / `gc-preflight` / `destroy` CLI
4. `server` ingest hooks(`OnFinalArtifact*`)
5. durable fav `Register` + live cutover(需审批解锁 events 硬门)
### 本切片交付物
- `internal/config`:`FAV_*` / `VAULT_*` + `ValidateIndependentVault`
- `internal/server/vault.go`:status HTTP + gated publisher
- `internal/app/fav`:subscriber stub(默认 off)
- `cmd/artifact-vault`:status stub
- compose:`FAV_DEGRADED_READ` / `FAV_PUBLISHER_ENABLED` 钉死 false(main 硬编码)
- **未** merge 到 `dev`
@@ -0,0 +1,106 @@
# Playwright intent-plan 双标签验收 测试报告
## 一、 测试背景 (Background)
Wave2 / U6 仅留下 `web/e2e/intent-plan-cards.spec.ts` 门控骨架(无 `RUN_UI_ACCEPTANCE` 则 skip;有则仅 body visible)。Conversation-intent 双标签证据(项目 6275)不等于 intent-plan `PLAN_CONFIRM` 双标签。本轮关闭 long-term [2026-09-16-intent-plan-playwright-dual-tab](../ops/long-term/2026-09-16-intent-plan-playwright-dual-tab.md),且**不升** `MULTI_INTENT_PLAN_TIER`。
## 二、 测试目标 (Test Objectives)
1. `RUN_UI_ACCEPTANCE` 未设置时 Playwright **SKIP**(不得冒充 PASS)
2. `RUN_UI_ACCEPTANCE=1` 真浏览器:双标签同时点「确认执行」→ 仅一侧 HTTP 200,另一侧 409;败方卡片 `outdated`,不得本地双成功
3. 刷新 / 重登后卡片与 PG / `GET /intent-plans/active` 状态一致
4. 顺带修复空 `docAST` 登录页崩溃(demo seed 关闭时)
## 三、 测试方案与环境 (Test Plan & Environment)
| 项 | 值 |
|----|-----|
| OS | Linux 7.0.0-31-generic |
| 前端 | Vite `http://127.0.0.1:3101`(worktree 含水合改动;proxy → `:8080` API) |
| API / PG | `shuimu-agent-app-dev` `:8080`;`shuimu-context-pg-dev` schema 47 |
| 浏览器 | `mcr.microsoft.com/playwright:v1.63.0-noble --network host`(宿主机缺 libatk) |
| 分支 | `feature/intent-plan-cards-playwright` |
| 种子 | SQL 写入 `awaiting_confirmation` + `validated_only`(保持 legacy tier) |
| 产物 | `.doc/test-reports/assets/2026-09-16-intent-plan-playwright-dual-tab/` |
### 用例矩阵
| 用例 | 层级 | 期望 |
|------|------|------|
| 无 `RUN_UI_ACCEPTANCE` | Playwright | SKIP |
| 双标签 confirm | UI + HTTP + PG | 1×200 + 1×409;败方 outdated |
| 刷新 / 重登 | UI + GET active | 与 PG `executing` 一致 |
## 四、 预期结果 (Expected Results)
- Tab A/B 均水合同一 `PLAN_CONFIRM`(`data-testid=plan-confirm-card`)
- 并发 confirm:唯一 nonce → CAS 一胜一负;败方 `PLAN_STALE_REVISION` 且 UI `outdated`
- 胜方 / 刷新 / 重登:`data-card-status` 为 `executing|resolved`,不可再以 active 确认
- PG `intent_plans.status=executing`,`revision>=2`
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 用例 1:门控 SKIP
- **测试输入 (Input)**:`npx playwright test e2e/intent-plan-cards.spec.ts --project=chromium`(不设 `RUN_UI_ACCEPTANCE`)
- **实际输出 (Actual Output)**:
```text
1 skipped
```
- **评价判定 (Evaluation / Verdict)**:**PASS**(SKIP,非冒充 PASS)
- **性能与耗时 (Duration & Latency)**:&lt;1s
### 用例 2:双标签 confirm + 刷新/重登
- **测试输入 (Input)**:
```bash
# Vite(含水合):3101 → API :8080
RUN_UI_ACCEPTANCE=1 BASE_URL=http://127.0.0.1:3101 \
ADMIN_USERNAME=… ADMIN_PASSWORD=… \
UI_ACCEPTANCE_ASSETS_DIR=…/assets/2026-09-16-intent-plan-playwright-dual-tab \
INTENT_PLAN_PG_DOCKER=shuimu-context-pg-dev \
docker run --rm --network host -v <worktree>:/work \
-v /var/run/docker.sock:/var/run/docker.sock \
mcr.microsoft.com/playwright:v1.63.0-noble \
bash -lc 'cd /work/web && npx playwright test e2e/intent-plan-cards.spec.ts --project=chromium'
```
- **实际输出 (Actual Output)**(摘自 `assets/.../playwright-docker.txt` + `playwright-network.json`):
```text
✓ dual-tab confirm mutual exclusion + reload/relogin matches PG (6.1s)
1 passed (7.0s)
project=PlanDual-mu49uev8 projectId=6399 session=sess-p6399-u9
planId=pln_e2e_mu49uev8
decisions: tab A HTTP 200 → executing rev=2; tab B HTTP 409 PLAN_STALE_REVISION
pgAfter: status=executing revision=2
```
截图:`screenshots/01-tab-a-awaiting.png` … `06-tab-a-after-relogin.png`
- **评价判定 (Evaluation / Verdict)**:**PASS**
- **性能与耗时 (Duration & Latency)**:约 7s(不含 Vite 冷启动)
## 六、 自动化测试套件汇总 (Test Suite Execution)
```text
# gated skip
npx playwright test e2e/intent-plan-cards.spec.ts --project=chromium
→ 1 skipped
# live acceptance
RUN_UI_ACCEPTANCE=1 … playwright (docker host network)
→ 1 passed (7.0s)
```
说明:本任务为 Web UI 门控活验;全仓 `go test -v ./...` 未作为本报告阻断项(未改 Go 业务逻辑)。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **达到合入/关闭 long-term 标准**:双标签 confirm 互斥 + 刷新/重登与 PG 一致已有真浏览器证据;默认 tier 未升。
- 产品改动:`GET /intent-plans/active` 水合 PLAN_CONFIRM;confirm 使用唯一 `decisionNonce`;空 `docAST` 登录兜底;卡片 `data-testid`/`data-card-status`。
- 建议:合 `dev` 后占槽 smoke;可将本 Docker 命令写入 nightly UI 可选 job;宿主机补齐 Chromium 系统库后可省 Docker 驱动。
@@ -33,9 +33,9 @@ Gitea nightly run#21 使用 `PI_AGENT_RUNNER_URL=http://127.0.0.1:18865`(dev P
### Nightly 重跑
- run#25 (`89ce3cc`): DATA_DIR=dev 已对齐,但 `/host-agent-data` 曾 `:ro` → `mkdir ... read-only file system` → `product_fail`(误分类,已改 compose rw + classify infra)
- 修复后重新 `workflow_dispatch`;见最新 run
- Verdict: 配置 FAIL→FIX;待 green
- run#25 (`89ce3cc`): DATA_DIR=dev 已对齐,但 `/host-agent-data` 曾 `:ro` → mkdir RO → product_fail(已改 compose rw)
- run#30 (`776b2b5`): **U8 PASS (263s)**;FullNone FAIL → receipt `product_fail`(模型/链路产品失败,非 DATA_DIR/infra)
- Verdict: **DATA_DIR 对齐 PASS**;套件整体仍 product_fail(FullNone)
## 六、 自动化测试套件汇总 (Test Suite Execution)
@@ -0,0 +1,112 @@
# PU6 语义摘要 shadow 测试报告
## 一、 测试背景 (Background)
P4 PU6 在覆盖 no-go 授权后需落地 `SEMANTIC_SUMMARY_SHADOW`:在授权可见消息集合上评估语义摘要,失败时保留 deterministic 摘要并标注 freshness;`SEMANTIC_SUMMARY_REPLACE` 本波刻意不接线。基线 deterministic 滚动摘要与每日 digest 规则引擎已存在,需证明 flag off 行为不变,且 injection / 撤权消息不能扩大可见集。
## 二、 测试目标 (Test Objectives)
- flag 默认 off:滚动摘要 / digest 行为与基线一致(无 shadow 字段)。
- flag on:仅对 authorized-visible 消息生成 shadow;served Narrative/Headline 仍为 deterministic。
- 模型/stub 失败:保留 deterministic + `freshness_note`。
- 无工具权限(`tool_permissions=none`);prompt injection 不能提权纳入不可见阶段消息。
- REPLACE 即使 env 为 true 也不替换 served narrative。
## 三、 测试方案与环境 (Test Plan & Environment)
- OS:Linux;Go:`go test -short`
- 后端:内存 `ContextManager` + chatflow Adapter(受限 StageAccess);无真实 LLM / 无工具回调;stub / heuristic summarizer
- 层级:单元 + 表征(characterization)测试
- 核心用例矩阵:
| 用例 | Flag | 期望 |
|------|------|------|
| FlagOffUnchanged | off | 无 Shadow/Freshness;Narrative 不含 stub |
| ShadowOKKeepsDeterministic | on(+REPLACE env) | Shadow ok;Narrative 仍 deterministic |
| ShadowFailure+Freshness | on | fallback + freshness;Narrative 保留 |
| Minimize R13 | — | 截断/去 metadata;digest 稳定 |
| Digest FlagOff / Fallback | off/on | digest 字段一致 |
| ChatLog injection/撤权 | on | 不可见报价不入摘要/facts;count=1 |
## 四、 预期结果 (Expected Results)
- off:与 `TestRollingSummarizer_LifecycleAndFactPreservation` 同类 deterministic 行为。
- on 成功:`shadow.status=ok`,`tool_permissions=none`,有 `input_digest`。
- on 失败:`shadow.status=fallback`,`freshness_note` 含 `deterministic retained`。
- chatflow:注入文案不能把 `V1.0_quoting` 秘密纳入 Narrative/Shadow/Facts。
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 Flag off 不变
- **测试输入 (Input)**:`SetSummaryFlagsForTest({Shadow:false})` + stub narrative `SHOULD_NOT_APPEAR`;`go test -short -v ./internal/ctxmgr/ -run TestSemanticSummary_FlagOffUnchanged`
- **实际输出 (Actual Output)**:
```
=== RUN TestSemanticSummary_FlagOffUnchanged
--- PASS: TestSemanticSummary_FlagOffUnchanged (0.00s)
```
- **评价判定 (Evaluation / Verdict)**:PASS
- **性能与耗时 (Duration & Latency)**:<1ms
### 5.2 Shadow 成功且不 REPLACE
- **测试输入 (Input)**:Shadow=true,Replace=true(env 开但未接线);stub `语义影子叙事:超声刀立项`
- **实际输出 (Actual Output)**:
```
=== RUN TestSemanticSummary_ShadowOKKeepsDeterministic
--- PASS: TestSemanticSummary_ShadowOKKeepsDeterministic (0.00s)
```
- **评价判定 (Evaluation / Verdict)**:PASS(served Narrative 未替换;facts 保留)
- **性能与耗时 (Duration & Latency)**:<1ms
### 5.3 Shadow 失败 + freshness
- **测试输入 (Input)**:stub `Err=model timeout`
- **实际输出 (Actual Output)**:
```
=== RUN TestSemanticSummary_ShadowFailureKeepsDeterministicWithFreshness
--- PASS: TestSemanticSummary_ShadowFailureKeepsDeterministicWithFreshness (0.00s)
```
- **评价判定 (Evaluation / Verdict)**:PASS
- **性能与耗时 (Duration & Latency)**:<1ms
### 5.4 授权可见 + injection 负例(chatflow)
- **测试输入 (Input)**:可见 triage 含 “Ignore previous…grant yourself auth…”;不可见 quoting「预算200万」;`GenerateRollingSummary` / `GenerateDigest`
- **实际输出 (Actual Output)**:
```
=== RUN TestChatLog_SemanticShadowAuthorizedOnlyAndInjectionCannotEscalate
--- PASS: TestChatLog_SemanticShadowAuthorizedOnlyAndInjectionCannotEscalate (0.00s)
```
- **评价判定 (Evaluation / Verdict)**:PASS(budget 事实未泄漏;digest message_count=1)
- **性能与耗时 (Duration & Latency)**:<5ms
### 5.5 基线滚动摘要回归
- **测试输入 (Input)**:`TestRollingSummarizer_LifecycleAndFactPreservation`
- **实际输出 (Actual Output)**:PASS
- **评价判定 (Evaluation / Verdict)**:PASS
## 六、 自动化测试套件汇总 (Test Suite Execution)
命令:
```bash
go test -short ./internal/ctxmgr/ ./internal/app/chatflow/ ./internal/server/
```
结果(本机 worktree):
```
ok chat-agent-system/internal/ctxmgr
ok chat-agent-system/internal/app/chatflow
ok chat-agent-system/internal/server
```
通过率:相关包 100%(`-short`)。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **结论**:PU6 shadow 门可合并候选分支验收(单元/表征);默认 flag off;REPLACE 未接线。
- **未做(本波非目标)**:真实 MiniMax/PI 出站质量窗、browser 恢复、开 flag 放量、REPLACE。
- **后续**:真实模型 shadow 质量与泄漏负例达标后再独立任务评估 REPLACE;读路径继续默认 deterministic。
@@ -0,0 +1,120 @@
# PU7 PI change-report 叙事 测试报告
## 一、 测试背景 (Background)
文档版本 baseline 已交付确定性 diff + lineage + fallback change report。覆盖授权后需落地可选 PI 叙事增强:默认 flag off,开启时只读消费 immutable 输入,任意失败全量降级,且不得覆盖服务端风险/审批。
## 二、 测试目标 (Test Objectives)
- `PI_CHANGE_REPORT_NARRATIVE` 默认 off
- Flag on 合法叙事:保留服务端 `rule_risk` 与 lineage,仅叠加叙事字段
- Flag on 畸形/超时/digest 不匹配/partial:全量 deterministic fallback,无混合字段
- UI view-model 区分事实字段与叙事来源
## 三、 测试方案与环境 (Test Plan & Environment)
- OS:Linux;Go:模块内 `go test`
- 层级:`internal/docrevision` 单元/服务路径;`deploy/pi-agent` schema 单测;前端 `overlayMode.test.ts` view-model
- 本报告为 feature 分支验收(**未**合入 `dev`,**未**开启生产 flag)。真实容器 PI 叙事联调留待 flag-on 晋级任务
## 四、 预期结果 (Expected Results)
| 用例 | 预期 |
|------|------|
| Flag 默认 | `PIChangeReportNarrativeEnabled()==false` |
| Flag off + 叙事 payload | 忽略叙事 → `analysis_status=fallback` |
| Flag on + 合法 narrative | `complete`;`risk_level==rule_risk`;lineage 不被 PI 伪造覆盖 |
| Flag on + TIMEOUT/malformed | `fallback`;`err==nil`;无 PI 摘要泄漏 |
| UI complete | `isNarrativeComplete=true`;事实 notes 含 rule_risk |
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 Flag 默认 off
- **Input**:进程未设置 `PI_CHANGE_REPORT_NARRATIVE`
- **Actual Output**:
```text
=== RUN TestPIChangeReportNarrativeFlagDefaultOff
--- PASS: TestPIChangeReportNarrativeFlagDefaultOff (0.00s)
=== RUN TestResolveChangeReport_FlagOffUsesDeterministic
--- PASS: TestResolveChangeReport_FlagOffUsesDeterministic (0.00s)
=== RUN TestCreateAgentCandidate_FlagOffIgnoresNarrativeEnrichment
--- PASS: TestCreateAgentCandidate_FlagOffIgnoresNarrativeEnrichment (0.00s)
```
- **Verdict**:PASS
- **Duration**:<10ms
### 5.2 Flag on — 合法叙事不覆盖服务端风险
- **Input**:`schema_kind=change_report_narrative_v1` + 匹配 `input_digest`;PI `risk.level=low`;伪造 `document_impacts`
- **Actual Output**:
```text
=== RUN TestResolveChangeReport_FlagOnValidNarrativeKeepsServerRisk
--- PASS: TestResolveChangeReport_FlagOnValidNarrativeKeepsServerRisk (0.00s)
```
- **Verdict**:PASS(服务端 high/critical floor 保留;lineage=`doc_down`)
### 5.3 Flag on — 全量 fallback(无混合字段)
- **Input**:bad json / schema / digest / TIMEOUT envelope / partial / empty summary
- **Actual Output**:
```text
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/bad_json
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/bad_schema_version
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/digest_mismatch
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/timeout_envelope
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/partial_flag
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/empty_summary
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback (0.00s)
=== RUN TestCreateAgentCandidate_FlagOnTimeoutFallsBackWithoutError
--- PASS: TestCreateAgentCandidate_FlagOnTimeoutFallsBackWithoutError (0.00s)
```
- **Verdict**:PASS
### 5.4 前端叙事 vs 事实
- **Input**:`analysis_status=complete` + `deterministic_facts`
- **Actual Output**:`marks complete analysis as PI narrative vs factual fields` PASS(14/14 overlayMode 相关套件)
- **Verdict**:PASS
### 5.5 pi-agent typed schema helper
```text
change-report-narrative-v1.test.mjs: ok
```
- **Verdict**:PASS
## 六、 自动化测试套件汇总 (Test Suite Execution)
```text
$ go test -v -count=1 ./internal/docrevision/ -run 'Narrative|FlagOff|FlagOn|DeterministicChangeReport'
PASS
ok chat-agent-system/internal/docrevision 0.004s
$ go test -count=1 -short ./internal/docrevision/
PASS
ok chat-agent-system/internal/docrevision 0.007s
$ node deploy/pi-agent/change-report-narrative-v1.test.mjs
change-report-narrative-v1.test.mjs: ok
$ tsx --test src/features/documentRevision/overlayMode.test.ts
ℹ tests 14
ℹ pass 14
ℹ fail 0
```
通过率:上述套件 **100%**。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **结论**:PU7 在 `feature/pu7-pi-narrative` 达到契约要求;默认 off,回滚=关 flag;可合入 `dev` 前占集成槽位冒烟。
- **后续**:flag-on 真实 PI 容器联调与 browser 验收另开任务;勿默认开启 `PI_CHANGE_REPORT_NARRATIVE`。
@@ -0,0 +1,70 @@
# PU8 U9–U12 独立 flag 脚手架 测试报告
## 一、 测试背景 (Background)
P5 覆盖授权后需为 U9–U12 提供分项独立 flag 与最小端口脚手架。默认必须 OFF,且不得升 `MULTI_INTENT_PLAN_TIER`;flag off 行为等于当前 legacy。
## 二、 测试目标 (Test Objectives)
- 四 flag 默认 off;env 开启互不耦合 PlanTier
- U9:默认 disabled;开启后 malformed/timeout/越界 fail closed;正常路径不 panic
- U10–U12:默认不注册 adapters;开启后 dry-run/revision 门禁可用且不 panic
- 既有 intentflow 回归仍 PASS
## 三、 测试方案与环境 (Test Plan & Environment)
| 项 | 值 |
|----|----|
| OS | linux |
| 分支 | `feature/pu8-u9-u12-flags`(自 `origin/dev@776b2b5`) |
| Go | `go test` 单元层 |
| 后端 | stub dry-run(无真实 LLM / 无领域写副作用) |
| 证据 | `.doc/test-reports/assets/2026-09-16-pu8-u9-u12-flags/` |
## 四、 预期结果 (Expected Results)
| 场景 | 预期 |
|------|------|
| 空 env | 四 flag false;PlanTier=legacy |
| U9 off | `SEGMENT_PROPOSAL_DISABLED` |
| U9 on + 坏 schema / 超时 / 越界 | fail closed |
| U10–U12 off | `BuildOwnerMux` 不挂 Mutate/DocGov/RunControl |
| U10–U12 on | dry-run Execute 成功;缺 revision → `PLAN_ACTION_VERSION_CONFLICT` |
| 开 flag | PlanTier 仍为 legacy |
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 Expansion flags / segment / dry-run
- **测试输入**:`go test ./internal/app/intentflow -run 'TestExpansion|TestActiveSegment|TestStubSegment|TestBuildOwner|TestDryRun|TestPlanTierIndependentOfExpansion' -count=1 -v`
- **实际输出**:见 [expansion-flags.txt](./assets/2026-09-16-pu8-u9-u12-flags/expansion-flags.txt)。8 用例全部 PASS。
- **评价判定**:PASS
- **性能与耗时**:约 9ms
### 5.2 intentflow 全包回归
- **测试输入**:`go test ./internal/app/intentflow -count=1`
- **实际输出**:`ok`(见 [intentflow-summary.txt](./assets/2026-09-16-pu8-u9-u12-flags/intentflow-summary.txt))
- **评价判定**:PASS
- **性能与耗时**:约 13ms
### 5.3 app 包(含 BuildOwnerMux 接线)
- **测试输入**:`go test -short ./internal/app -count=1`
- **实际输出**:`ok`(见 [app-short.txt](./assets/2026-09-16-pu8-u9-u12-flags/app-short.txt))
- **评价判定**:PASS
- **性能与耗时**:约 16ms
## 六、 自动化测试套件汇总 (Test Suite Execution)
| 命令 | 结果 |
|------|------|
| `go test ./internal/app/intentflow -count=1` | PASS |
| `go test -short ./internal/app -count=1` | PASS |
| `go vet ./internal/app/intentflow ./internal/app` | PASS(无输出) |
本轮为 flag/端口脚手架验收,使用 stub dry-run;未升 tier,未 rebuild `:8080`,未跑真实 PI。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
脚手架达到分支交付标准(push `feature/pu8-u9-u12-flags`,**不合 `dev`**)。后续:U9 真实 PI eval;U10–U12 分项 live adapter + 授权负例;仍禁止默认升 `MULTI_INTENT_PLAN_TIER=full`。
@@ -0,0 +1,37 @@
# docgov 变更提案 HTTP 测试报告
## 一、 测试背景 (Background)
- 引擎已有 Propose/Decide,但缺少 propose HTTP;前端 pendingProposal 为本地模拟。
- author-only 收口后补齐变更提案闭环。
## 二、 测试目标 (Test Objectives)
- `POST /api/v1/docgov/proposal` 写库成功
- `POST /api/v1/docgov/proposal/decide` 批准写库
- 前端 client 单测覆盖路径
## 三、 测试方案与环境 (Test Plan & Environment)
- OS: Linux;后端:agent-dev `:8080` schema 52;真实 `pi-agent` 环境(本用例不触发任务跑批)
- 层级:Go handler 单测 + 前端 client 单测 + 真实 HTTP
## 四、 预期结果 (Expected Results)
- claim 已认领文档 → propose → status=`pending_author_approval` → decide approve → `approved_by_author`
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### TC-HTTP-01 claim → propose → decide
- **测试输入**: doc `doc_proj6425_rd_design_input_spec`(author=admin/9,已认领)
- **实际输出**: 见 assets `01`–`05`;proposal `prop_rd_design_input_spec_1789654256551680649` → `approved_by_author`
- **评价判定**: PASS
- **性能与耗时**: 全链路 <1s(不含 rebuild)
### TC-UNIT-01
- `go test -run TestServer_DocGovProposeAndDecideHTTP ./internal/server/` PASS
- `node --test web/src/api/docgov.test.ts` 6/6 PASS
## 六、 自动化测试套件汇总 (Test Suite Execution)
- 合入后冒烟:`go vet ./...`;`go test -short ./internal/server/ ./internal/docgov/` PASS
- `./scripts/env-service.sh dev rebuild`;`GET /health` → status=ok schema=52
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- 达到合入/推送标准;**未**晋升 test/main
- 后续:批准后自动应用受控正文 diff(非本期)
@@ -0,0 +1,67 @@
# CreateOrGetDocument 可选职责 0→NULL FK 测试报告
## 一、 测试背景 (Background)
dev 项目「内廷元无创神经刺激器」(6417) 发起 `intake` 任务时,UI 报 `INTERNAL_ERROR` /「系统内部错误,请重新开始会话」(`run_1789622069585300787`)。根因是可选审核职责为空时 `CreateOrGetDocument` 写入 `reviewer_id=0`,触发 `document_records_reviewer_id_fkey`,再被 `ClassifyError` 兜底掩盖。
## 二、 测试目标 (Test Objectives)
- 仅-author 项目创建文档账本成功,`reviewer_id`/`approver_id` 为 SQL NULL
- 不再出现 `persist document ledger` / `INTERNAL_ERROR`(该路径)
- ledger/FK 残差错误分型为 `DOC_LEDGER_ERROR`
- 单元与 `-short` 回归通过
## 三、 测试方案与环境 (Test Plan & Environment)
| 项 | 值 |
|---|---|
| OS | Linux |
| 分支合入 | `dev` @ `merge: fix/docgov-optional-duty-null-fk` |
| 环境 | agent-dev `:8080`,schema 48,真实 PI |
| 层级 | 单元 / DB 集成 / 真实 task run 冒烟 |
## 四、 预期结果 (Expected Results)
1. `nullIfZero(0)==nil`;`CreateOrGetDocument(..., reviewer=0, approver=0)` 成功且 DB NULL
2. `ClassifyError(persist document ledger ... 23503)` → `DOC_LEDGER_ERROR`
3. 项目 6417 重试 `intake`:越过账本创建;`doc_proj6417_intake` 存在且 `rev_null/app_null=true`
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 用例 1:单元 / short
- **输入**: `go test -short ./internal/docgov/... ./internal/stream/...`
- **实际输出**: `ok`(含 `TestNullIfZero`、`TestClassifyError_DocumentLedgerFKIsLedgerError`)
- **判定**: PASS
- **耗时**: ~0.5s
### 用例 2:DB 集成 OptionalDutiesNullFK
- **输入**: `go test ./internal/docgov/ -run OptionalDutiesNullFK -count=1`
- **实际输出**: `--- PASS: TestDocGov_CreateOrGetDocument_OptionalDutiesNullFK`
- **判定**: PASS
### 用例 3:dev 真实任务(项目 6417)
- **输入**: admin 登录后 `POST /api/v1/tasks/runs`(`task_key=intake`,`session_id=sess-p6417-u9`,`project_id=6417`)
- **实际输出**:
- 创建响应:`{"run_id":"run_1789625396102207018","status":"running"}`
- DB:`doc_proj6417_intake | author_id=9 | rev_null=t | app_null=t | drafting`
- 未再出现 `persist document ledger` / `document_records_reviewer_id_fkey`
- **判定**: PASS(账本 FK 根因已消除;任务可继续进入 PI 执行阶段)
- **耗时**: 账本落盘在秒级完成(对比失败 run 立即 failed)
## 六、 自动化测试套件汇总 (Test Suite Execution)
```text
go vet ./internal/docgov/... ./internal/stream/...
go test -short ./internal/docgov/... ./internal/stream/...
# ok docgov / stream
./scripts/env-service.sh dev rebuild
curl -sf http://127.0.0.1:8080/health # ok, schema_version=48
```
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **结论**: 达到合入与冒烟标准;可选职责空审核人不再因 FK=0 导致 `INTERNAL_ERROR`。
- **后续**: 前端 `flushSync` 警告另开任务;全链路 PI 完成质量属独立验收,不阻塞本修复。
@@ -0,0 +1,128 @@
# 文档编制人兼任 U6 多职责动作与真实闭环 测试报告
## 一、 测试背景 (Background)
U1–U5 已落地管理员总开关、逐文档 `duty_policy=author_only`、ABAC 门禁与设置页 UI。交付验收时发现两处前端缺口:
1. 审批动作条从未调用已存在的 `docgov` HTTP(claim / submit-review / review-decision / approver-decision),仅本地改 `lifecycleState`;
2. `resolveCurrentDocRole` 的 author-first 短路使 A/A/A 用户永远只解析为 `author`,审核/批准按钮与快捷指令不可见。
U6 修复可见性与真实 API 接入,使编制人兼任完整闭环第一次可验收。
## 二、 测试目标 (Test Objectives)
- author_only(三职同一人)下 A 可见送审/审核/批准动作;非 A 不可见且直连接口 403;
- 点击认领→送审→审核通过→终审批准走真实后端,写 `document_records` / `document_audit_logs`(含 `duty_policy`);
- 动作条展示「编制人兼任」徽标;`duty_policy` 从 summary 透传到 AST;
- 前端单测与 `tsc --noEmit` 回归通过。
## 三、 测试方案与环境 (Test Plan & Environment)
| 项 | 值 |
|---|---|
| OS | Linux |
| 环境 | dev `:8080`(feature worktree rebuild,`schema_version=52`,`agent_backend=pi-agent`) |
| 前端 | worktree Vite `:5173` 代理 API |
| 被测文档 | `doc_proj6425_rd_design_input_spec`(项目 6425,`rdev-s0-fresh-*`,既有真实 PI 生成正文) |
| 配置 | 实例快照 `duty_policy=author_only`,有效职责 A/A/A(user_id=9 系统管理员) |
| 负例用户 | `lizhuguan`(id=11) |
分层:
1. 前端单元:`docGovActionVisibility` + `docgov` API client;
2. HTTP 真实闭环:claim → submit → review → approve;
3. HTTP 负例:非职责人 403;
4. 浏览器:Playwright(官方 image)打开 Vite,断言徽标与送审按钮。
## 四、 预期结果 (Expected Results)
| 用例 | 预期 |
|---|---|
| AE-UI | A 打开 author_only 文档见「编制人兼任」+ 送审按钮 |
| AE-API | A 依次 claim/submit/review/approve → `current_state=approved`,审计含 `duty_policy=author_only` |
| AE-NEG | 李主管 review/approve → `DOC_DUTY_FORBIDDEN` HTTP 403 |
| AE-UNIT | author_only 三动作对 A 全 true、对非 A 全 false;分离三人矩阵不变 |
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 前端单元
**输入**:`npm test` + `npx tsc --noEmit`(worktree `web/`)
**实际输出**:`ℹ tests 390` / `pass 390` / `fail 0`;含 `docgov lifecycle API client` 4 例与 `docGovActionVisibility` author_only 矩阵;`tsc --noEmit` 无错误。
**判定**:PASS
### 5.2 HTTP 真实闭环(author_only)
**输入**:admin Bearer 调用四接口(证据:`assets/2026-09-17-document-author-only-u6/api-lifecycle-author-only.txt`)
**实际输出(摘要)**:
- `POST /docgov/review-decision` → HTTP 200,`current_state=approving`,`duty_policy=author_only`
- `POST /docgov/approver-decision` → HTTP 200,`current_state=approved`
- 审计:`submit_review` / `review_approve` / `approver_approve` 的 `details.duty_policy=author_only`(`db-final-author-only.txt`)
**判定**:PASS
### 5.3 HTTP 负例
**输入**:`lizhuguan` 对同一文档 review/approve(`api-negative.txt`)
**实际输出**:
```text
{"error":"DOC_DUTY_FORBIDDEN","message":"当前用户不是该文档的对应职责人"}
HTTP 403
```
(审核与批准各一次)
**判定**:PASS
### 5.4 浏览器(Vite + Playwright)
**输入**:注入 admin 会话 → 打开 `rdev-s0-6425` → 《设计输入规格书》
**实际输出**:
- `browser-visibility.json`:`hasBadge=true`,`hasClaim=true`,`hasSubmit=true`
- 截图 `screenshots/04-action-bar.png`:明确显示「编制人兼任」徽标与「提交送审」按钮
**判定**:PASS(可见性与徽标);按钮逐级点击以 API 闭环为准(浏览器侧状态机与网络时序未作为唯一证据)。
### 5.5 性能与耗时
| 步骤 | 耗时量级 |
|---|---|
| Vite npm test | ~2s |
| tsc --noEmit | ~3s |
| API 四步闭环 | <1s |
| Playwright 全流程 | ~25s(含容器内 npm i playwright) |
## 六、 自动化测试套件汇总 (Test Suite Execution)
```text
web: npm test → 390 pass / 0 fail
web: npx tsc --noEmit → clean
```
Go 侧 U1–U4 既有矩阵本轮未重跑全量;dev 容器已含 `allow_author_only_approval` 二进制与 goose 00050–00052。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
**结论**:U6 达到合并前验收标准——author_only 多职责动作可见、真实 docgov 闭环与负例 403、兼任徽标透传均有证据。回链 U1–U6 与 FEATURE-MATRIX。
**限制说明**:
- 本轮闭环基于已激活实例快照补丁为 `author_only` + 既有 PI 生成文档;管理员总开关→创建者设置→激活的产品配置链路由 U1–U5 覆盖,本报告不重复。
- 变更提案 HTTP 路由仍缺失(独立缺口,见 audit 笔记),不在 U6 范围。
**后续**:合入 `dev` 后按集成槽位正式冒烟;可补 Playwright 选择器精化使浏览器点击与 DB 状态强一致。
## 相关链接
- Remediation: `.doc/remediation/2026-09-17-document-author-only-plan.md` U6
- Short-term: `.doc/ops/short-term/2026-09-17-document-author-only-u6.md`
- Assets: `.doc/test-reports/assets/2026-09-17-document-author-only-u6/`
- 变更提案缺口: `.doc/audit/2026-09-17-docgov-modification-proposal-http-gap.md`
@@ -0,0 +1,109 @@
# 个人工程中控台(engineering-dashboard)测试报告
## 一、 测试背景 (Background)
仓库需要独立于产品后台的本地只读工程中控台,避免把文档 `done` 误读为已合并或已部署。方案见 [设计](../archive/design/2026-09-17-personal-engineering-control-center-plan.md)。本报告验收一期 `serve` / `export` 实现。
## 二、 测试目标 (Test Objectives)
- 实时 HTML、离线 HTML、JSON 共用 `generation_id` / `revision_id`
- 计划 / Git 实施 / 验证 / 实装四轴独立
- rdev、dev ahead、main events 分叉样本(单元夹具)按方案输出
- 单源失败可 degraded;loopback / token / Host / 只读方法防护生效
- 导出 HTML `0600`、可离线阅读 Markdown、不嵌 assets
## 三、 测试方案与环境 (Test Plan & Environment)
- OS: Linux;Go module `chat-agent-system`
- 工作树:`.worktrees/feature-engineering-dashboard`(`feature/engineering-dashboard`)
- 层级:包单元/集成测试 + CLI 真实 `serve`/`export` 冒烟(只读观察,未启停共享 compose)
## 四、 预期结果 (Expected Results)
| 用例 | 预期 |
|------|------|
| 模型四轴 | doc done 不改 Git/部署 facets |
| rdev 夹具 | planned / unclaimed / 实装 unknown |
| dev ahead | ahead>0 且备注含未确认远端 |
| main fork | readiness ok + containers partial + conflict |
| HTTP | POST 405;无 token 401;坏 Host 403;非 loopback bind 拒绝 |
| export | 权限 0600;含 identity;无 script breakout |
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 单元与包测试
- **测试输入**: `go test ./internal/engineeringdashboard/ ./cmd/engineering-dashboard/ -count=1`
- **实际输出**:
```text
ok chat-agent-system/internal/engineeringdashboard 0.009s
? chat-agent-system/cmd/engineering-dashboard [no test files]
```
- **判定**: PASS
- **耗时**: ~0.01s(包测)
### 5.2 go vet
- **测试输入**: `go vet ./internal/engineeringdashboard/... ./cmd/engineering-dashboard/...`
- **实际输出**: (无输出)
- **判定**: PASS
### 5.3 真实 export
- **测试输入**: `go run ./cmd/engineering-dashboard export --repo <worktree> --output /tmp/engdash-export.html`
- **实际输出**: 文件权限 `600`;体积可离线打开;含 CSP 与 snapshot identity
- **判定**: PASS(`stat -c '%a'` → `600`)
### 5.4 真实 serve 冒烟
- **测试输入**: `engineering-dashboard serve --repo <worktree> --addr 127.0.0.1:8799`,随后 curl
- **实际输出**:
```text
{"ok":true}
generation gen_1
revision rev_3378ee42f645c4ab1af69cf691c00103
tasks 50
docs 452
sources [('docs', 'ok', 'fresh'), ('git', 'ok', 'fresh'), ('runtime', 'ok', 'fresh')]
POST_reject HTTPError 405
no_token=401
bad_host=403
```
- **判定**: PASS(HTML/JSON 同源 identity;安全负例符合预期)
- **说明**: 工作树上尚未合入未跟踪的 rdev 文档树;rdev/dev-ahead/main-events **样本契约由包内 fixture 单测覆盖**(`TestModel_*` / `TestReconcile_*`)。
### 5.5 夹具验收样本(单元)
| 样本 | 测试 | 判定 |
|------|------|------|
| rdev 已计划未实施 | `TestReconcile_RDevPlannedUnclaimed` / `TestModel_AcceptanceSamplesAxes` | PASS |
| local ahead origin | `TestReconcile_DevAheadSample` / `TestGit_AheadDoesNotClaimRemoteAvailable` | PASS |
| main ready vs events restarting | `TestReconcile_MainEventsForkConflict` / `TestRuntime_ReadyOKAndEventsRestarting` | PASS |
| Herdr vs 产品 PI Runner | `TestModel_ClaimedWithoutRuntimeKeepsActivityUnknown` | PASS |
## 六、 自动化测试套件汇总 (Test Suite Execution)
对本工具包:
```text
go test ./internal/engineeringdashboard/ ./cmd/engineering-dashboard/ -count=1
# ok engineeringdashboard
go test -short ./internal/engineeringdashboard/... ./cmd/engineering-dashboard/... -count=1
# ok
go vet ./internal/engineeringdashboard/... ./cmd/engineering-dashboard/...
# clean
git diff --check
# clean
```
全仓 `go test -short ./...` 在合入 `dev` 占槽时于主仓执行(本工具未改产品包)。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **结论**: 一期达到合并标准(独立 CLI、同源快照、四轴、安全边界、导出)。
- **后续**: 跨快照历史、远端 CI/Gitea、受限 Markdown/Mermaid、Agent 查询 API(设计附录已列,不在本期)。
## 相关链接
- 任务: [../archive/ops/short-term/2026-09-17-engineering-dashboard.md](../archive/ops/short-term/2026-09-17-engineering-dashboard.md)
- 设计: [../archive/design/2026-09-17-personal-engineering-control-center-plan.md](../archive/design/2026-09-17-personal-engineering-control-center-plan.md)
@@ -0,0 +1,113 @@
# 首次加载 U2:字体自托管与静态资源交付 测试报告
## 一、 测试背景 (Background)
诊断确认 8080 登录页下载约 2.82 MB 未压缩 JS,且 Google Fonts 外链 CSS 可阻塞首屏;Go `serveSPA` 无压缩协商、无明确缓存头,且缺失 `/assets` 会回退 HTML。本轮实施 U2(自托管字体、构建期预压缩、静态交付协商与 404 修复),不包含 U3 拆包。
## 二、 测试目标 (Test Objectives)
- 登录页无 `fonts.googleapis.com` / `fonts.gstatic.com` 请求;阻断该域名仍可出现登录表单
- 主 JS 响应带 `Content-Encoding: br` 或 `gzip`,传输体积显著下降
- `/assets/missing.js` → 404 且 body 非 HTML
- HTML `Cache-Control: no-cache`;`/assets`/`/fonts` `immutable`;API 无 public 长缓存
- 单元测试与 `go test -short` / `npm test` 通过
## 三、 测试方案与环境 (Test Plan & Environment)
- OS:Linux;Go 1.27.1;dev 容器 `shuimu-agent-app-dev`(镜像 `agent-dev-app@sha256:2d74fe18…`)
- 入口:`http://127.0.0.1:8080`(构建产物)
- 层级:Go 单元测试(`static_assets_test.go`)、前端断言、curl 协商验收、Playwright Docker(`mcr.microsoft.com/playwright:v1.63.0-noble`)浏览器探针
- 代码:`dev@bc01781`(merge `feature/initial-load-perf-u2`);无缓存重建后镜像含 `/fonts` 与 `.br/.gz`
## 四、 预期结果 (Expected Results)
| 场景 | 预期 |
|------|------|
| `Accept-Encoding: gzip, br` | `Content-Encoding: br`,主 JS ~624 KiB |
| 仅 `gzip` | `Content-Encoding: gzip` |
| identity / `gzip;q=0` | 无 `Content-Encoding`,原始体积 |
| `/assets/missing-hash.js` | 404,非 HTML |
| HTML / SPA fallback | `Cache-Control: no-cache` |
| 字体域名阻断 | 登录输入框仍可见 |
| API 未认证 | 401,无 `immutable` |
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 单元测试
- **Input**: `go test -short ./internal/server/ -run 'TestStaticAssets_|TestParseAcceptEncoding'`
- **Actual**: `ok`
- **Verdict**: PASS
- **Duration**: ~0.66 s
- **Input**: `npx tsx --test src/styles/noExternalFonts.test.ts`;`npm test`
- **Actual**: 字体断言 2/2 PASS;前端套件 380 + vitest 32 PASS
- **Verdict**: PASS
### 5.2 curl 协商(8080,无缓存重建后)
证据:`.doc/test-reports/assets/2026-09-17-initial-load-perf-u2/after-curl-nocache.txt`
| 检查项 | 实际 | 判定 |
|--------|------|------|
| HTML | `Cache-Control: no-cache`,`Vary: Accept-Encoding`,无 Google Fonts | PASS |
| JS + `gzip, br` | `Content-Encoding: br`,下载 **623,898 B**(原 2,820,055 B,−77.9%) | PASS |
| JS + `gzip` | `Content-Encoding: gzip`,`immutable` | PASS |
| JS identity | 无 encoding,`Content-Length: 2820055`,仍有 `Vary` | PASS |
| `/assets/missing-hash.js` | **404** `404 page not found` | PASS |
| `/fonts/inter-v20-latin.woff2` | 200,`immutable`,48256 B,无 Content-Encoding | PASS |
| `/sessions/demo` | 200 + index,`no-cache` | PASS |
| `/api/v1/chat/sessions` | 401 JSON,无 immutable | PASS |
### 5.3 浏览器探针
证据:`assets/2026-09-17-initial-load-perf-u2/browser-u2.json`
| 场景 | 登录可见 | transferBytes | 外链字体请求 | 判定 |
|------|----------:|------------:|-------------:|------|
| login-cold | **205 ms** | **681,964** | 0 | PASS |
| login-font-domain-blocked | **213 ms** | 681,964 | 0 | PASS |
对比诊断 before(同机冷缓存登录页):可见 ~662 ms,transferSize 2,857,761 B;主 JS 未压缩 2,820,055 B。本轮未登录首屏传输量下降约 **76%**。
主 JS Resource Timing:`transferSize=624198`,`decodedBodySize=2820055`(确认浏览器实际收到 br 变体)。
### 5.4 重启时间线(U7 起点证据,非 U7 完成)
| 事件 | 时刻 (UTC) |
|------|------------|
| 容器 StartedAt | 2026-09-17T08:22:48.548Z |
| goose no migrations / kb online | 08:22:48.660–.676 |
| 日志「监听地址」 | ~08:22:48.7 |
| health=200 | ≤08:22:50(重建后首次探测) |
app restart → listen ≈ **150–200 ms**(DB 已就绪、无迁移)。**不能**据此宣称用户「整机重启十几秒」已解决。
首次 `env-service.sh dev rebuild` 曾因并行 Agent 切走工作树导致镜像装入旧 `web/`;随后在 `dev` 上 `docker compose build --no-cache app` 后验收通过。证据见 `rebuild-nocache-log.txt`。
### 5.5 SSE
未认证 `GET /api/v1/chat/stream` 立即 401 JSON;静态压缩路径不触及 API/SSE。PASS(静态层无缓冲回归迹象)。
## 六、 自动化测试套件汇总 (Test Suite Execution)
```text
go test -short ./internal/server/ -run 'TestStaticAssets_|TestParseAcceptEncoding' → ok
npm test (web) → 380 + 32 PASS
npm run build → precompress 49 .br / 49 .gz
```
未在本报告将 stub 输出当作交付证据;浏览器与 curl 均打真实 8080 容器。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **U2 达到合并/dev 验收标准**:字体去阻塞、压缩协商、缓存头、assets 404 均有真实证据。
- **不宣称** Success Criteria 全表达标(U1 登录态套件未建;U3 拆包未做,首屏 JS 解码体仍约 2.8 MB)。
- 后续:U3 懒加载;U1/U7 补齐重启与登录态预算;并行 Agent 占用主仓时,合入容器重建须 `--no-cache` 或锁定工作树以免 BuildKit 读到脏上下文。
### 提交与环境
- 分支:`feature/initial-load-perf-u2` → 已 `merge --no-ff` 入 `dev@bc01781`
- 镜像:`agent-dev-app` sha256:2d74fe184585ec0d0d24a051cd6bbc0cfb5b2ef050a376a32027c8e442703cd1
- 资源:`/assets/index-Bu0CqZB_.js` + `.br`
- 未推送、未晋升 test/main

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