docs: 补齐财务身份验收窗口规约(09-05-error-explainability-payment-readiness)
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-09-05 22:04:32 +08:00
父节点 a43df86712
当前提交 492920cd75
@@ -2807,6 +2807,9 @@ helper dry-run -> actions=[] and safe target
- Required evidence fields: `stage`, `loginAttempts`, `loginHttpStatus`, - Required evidence fields: `stage`, `loginAttempts`, `loginHttpStatus`,
`sampleCategory`, `sampleCount`, `businessMutationCount`, and the relevant `sampleCategory`, `sampleCount`, `businessMutationCount`, and the relevant
endpoint-specific request count such as `terminatePostCount`. endpoint-specific request count such as `terminatePostCount`.
- A finance smoke window additionally records `authorizationRef`, `accountAlias`,
`observedRoleCodes`, `disableReason`, `disableAuditRef` and `postDisableStatus`.
Use aliases and redacted references, never credentials or full identifiers.
### 3. Contracts ### 3. Contracts
@@ -2834,10 +2837,60 @@ helper dry-run -> actions=[] and safe target
- Recheck any state-based rollback window before and after the browser run. - Recheck any state-based rollback window before and after the browser run.
Missing samples and a still-open window remain independent facts. Missing samples and a still-open window remain independent facts.
#### Finance-role acceptance checklist
1. Resolve exactly one configured OA-only finance smoke in the isolated test
department. Before login, read its `status`, `employment_status`,
`archived_at`, `last_working_date`, lock state and effective role grants.
Require exactly `employee + finance`, with no extra roles or wildcard grant.
The database uses `status=archived` for disabled accounts; employees have no
`left_at` field. A disabled account is a blocked acceptance prerequisite,
not permission to weaken the login guard.
2. Obtain explicit authorization for the complete enable -> acceptance ->
disable window before any account write. Record the operator alias, purpose,
deadline and abort/cleanup responsibility. Re-read status and role grants
after enabling. Neither an earlier window nor an unexpectedly active account
grants permission for a new window or permanent activation.
3. Run the approved checks as that finance actor. Administrator results prove
only administrator behavior: wildcard privileges cannot establish finance
visibility, projections or action boundaries. A different read-only actor
likewise cannot replace exact finance-role acceptance. Stop at the precise
failed stage; do not replace the actor and mark the finance criterion PASS.
4. Immediately disable the smoke through the approved account-management path
when checks finish or abort. Read back `status=archived`, non-null
`archived_at` and target session revocation, and link the disable audit event.
A failed cleanup or missing verification leaves the window unclosed and must
be handed off explicitly; it is not a successful closeout. Do not submit an
extra login merely to prove that disabling worked.
- Record a concrete disable reason, such as `finance_acceptance_complete` or
`finance_acceptance_aborted`, linked to the authorization and disable event.
Current `server/src/routes/users.js` writes `SYSTEM_USER_DISABLED` with
`extra: {}`: audit-native reason persistence is **not implemented**. Until a
separately approved code change adds it, retain the reason in controlled
acceptance evidence linked to the audit reference, operator alias and event
time. Do not claim the audit row contains a reason, invent historical reasons,
or directly patch audit rows to satisfy this checklist.
- Do not treat a permanently active read-only finance account as an account-only
shortcut. Current grants are fixed by `RoleCode`/`EmployeeRole` and
`resolvePermissionsForRoles`, not arbitrary per-account permission strings;
there is no finance-read-only role, and `employee` itself includes writes.
Both payment candidates and combination readiness require
`payment.batch.manage`; `expense.view_all` alone cannot cover them. A future
read/write permission split needs separate approval and projection/denial
verification. Read-only access still exposes confidential financial data and
is not a zero-risk standing identity.
### 4. Validation & Error Matrix ### 4. Validation & Error Matrix
- Login fails once -> stop with the authentication stage and re-read lock/failure - Login fails once -> stop with the authentication stage and re-read lock/failure
state; no second login. state; no second login.
- Finance smoke is disabled -> record the prerequisite as
`PAUSED(finance_account_disabled)`; finance-role acceptance remains unverified.
If login was attempted, distinguish `403/AUTH_003` at `/api/auth/login` from
`403/PERM_001` at a later protected endpoint; never infer the layer from 403 alone.
- Disable reason, linked audit reference or post-disable state proof is missing
-> acceptance-window closeout is incomplete, even when all UI checks passed.
- Login succeeds but the required sample count is zero -> authentication PASS, - Login succeeds but the required sample count is zero -> authentication PASS,
sample-dependent UI checks `PAUSED`, mutation counters must remain zero. sample-dependent UI checks `PAUSED`, mutation counters must remain zero.
- Runner label differs from the current shared product mapping -> runner - Runner label differs from the current shared product mapping -> runner
@@ -2875,6 +2928,9 @@ helper dry-run -> actions=[] and safe target
and mutation listeners installed before the first application navigation. and mutation listeners installed before the first application navigation.
- Evidence review must reconcile login attempts with session/audit changes and - Evidence review must reconcile login attempts with session/audit changes and
reconcile every unexecuted UI assertion with its sample count and stage. reconcile every unexecuted UI assertion with its sample count and stage.
- For a finance window, verify the unique actor and exact grants before login,
and the reason/audit linkage, disabled state and session revocation afterward.
Administrator or alternative-role checks must not satisfy finance-role criteria.
- Production execution still requires explicit approval, pre/post rollback - Production execution still requires explicit approval, pre/post rollback
window snapshots, sensitive-content scanning and a read-only reviewer. window snapshots, sensitive-content scanning and a read-only reviewer.