feat: harden support, localize knowledge and add operator availability [skip ci]
Source-only publication of reviewed commit 64e96a7f423673dc29ad56485be9fc79bce8af1c.
Passed in isolation: focused frontend/backend tests, race checks, TypeScript typecheck, lint, Go compilation, Flowgram build, and deterministic SDK build/tests.
Not accepted as a production release: Next.js export/native assembly remains blocked by environment memory limits; browser interaction and MySQL staging acceptance remain unverified. No production server, database/schema, runtime configuration, deployment, release tag, or workflow execution was performed.
Expected source tree: 0a4a7528e9.
This commit is contained in:
62
docs/hardening/SETUP_PREVIEW.md
Normal file
62
docs/hardening/SETUP_PREVIEW.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Reviewed setup repairs
|
||||
|
||||
The existing authenticated `POST /api/dashboard/setup/quick_fix` endpoint now uses a two-phase contract. It does not write configuration unless the caller explicitly applies a current preview.
|
||||
|
||||
## Contract
|
||||
|
||||
1. Request a preview with `action` and, for an existing agent/channel/team, its `entity_id`. Omit `apply` or set it to `false`.
|
||||
2. Review `changes`. Each entry names the entity, operation, and exact operational fields before and after. New linked entities are identified by their proposed names until IDs are assigned. Audit timestamps and acting-user metadata are maintained automatically.
|
||||
3. Submit the same action and target with `apply: true` and the returned `preview_token`.
|
||||
|
||||
The response includes:
|
||||
|
||||
- `applied`: whether an explicit apply request completed. An empty `applied_actions` array means no configuration writes were needed.
|
||||
- `changes`: the reviewed plan; an empty array is a valid no-op, not a claim that setup is complete.
|
||||
- `preview_token`: a fingerprint of the acting user, action, target, proposed changes, and current setup configuration.
|
||||
- `applied_actions`: committed operation/entity identifiers, empty on preview.
|
||||
- `warning_codes`: manual follow-up requirements or post-commit failures.
|
||||
- `readiness`: the refreshed diagnostic, omitted if refreshing failed.
|
||||
|
||||
Old callers that omit `apply` receive a read-only preview. Callers must not interpret any HTTP success as a successful mutation. There is deliberately no compatibility path that silently applies an unreviewed repair.
|
||||
|
||||
## Authorization and freshness
|
||||
|
||||
The handler authenticates every request. Setup checks the principal's resolved permission list, matching the normal authorization service. An `admin` or `super_admin` role name alone does not bypass missing permissions. Every planned create or field update also checks its specific permission.
|
||||
|
||||
Apply rebuilds the plan inside one transaction and verifies the fingerprint before writing. A stale preview is rejected and must be reviewed again. Transactional reads use separate GORM statements, preserving row locks without leaking a prior query's table or filters. Updates also compare the target's previous update timestamp. The fingerprint is a freshness/intent check, not an authentication credential or signed authorization grant.
|
||||
|
||||
## Deliberately narrow behavior
|
||||
|
||||
- Broad setup only creates missing defaults. It never rewrites existing configuration, moves existing operators to another team, expands an agent's team pool, or rebinds existing channel routes.
|
||||
- Deleted records are not update candidates and are never restored. Disabled records and zero-rollout settings are preserved. A targeted “enable my profile” action can enable the authenticated user's non-deleted profile only when the preview explicitly shows the change and the required permissions are present.
|
||||
- A targeted handoff change affects only the named eligible agent. Missing teams, route choices, disabled configurations, and rollout changes must be chosen in their existing editors.
|
||||
- Quick fixes never create or modify shifts. Missing schedules and off-hours schedules are distinct diagnostics. Working hours must be entered explicitly in the existing schedule editor.
|
||||
- A newly created default agent is unpublished. Setup does not publish agents. A default channel can be created only after an eligible agent has a published revision, matching the normal channel editor's publication guard. Readiness reports unpublished agents as incomplete.
|
||||
|
||||
Therefore a broad repair is not a promise of a production-ready routing path. Publishing, deliberate routing choices, and explicit schedules may still be required.
|
||||
|
||||
## Transactions and dispatch
|
||||
|
||||
All configuration writes in an apply operation share one transaction. A failed write rolls back the entire repair. Pending dispatch begins only after the configuration transaction commits.
|
||||
|
||||
A dispatch failure produces `dispatch_failed`; it does not undo committed changes or return an error implying that the configuration write should be retried. A diagnostic refresh failure similarly produces `readiness_refresh_failed`. The UI displays these warnings and requires a fresh preview for a subsequent repair.
|
||||
|
||||
The pending-queue query now reports database read errors and applies its existing batch limit in SQL. Its existing newest-first priority and periodic retry semantics are unchanged. This repair does not redesign queue fairness.
|
||||
|
||||
## Simulation
|
||||
|
||||
The simulator is read-only and sends no customer message. `candidate_operators` is always an array, including missing-channel responses; the client also normalizes legacy null values.
|
||||
|
||||
`bypass_ai: true` is explicitly rejected because the service does not implement AI bypass. AI-only paths remain blocked. AI-first/unknown service modes and partial channel rollout are reported as unverified, never as successful operator delivery. Only an eligible, published, full-channel-rollout, human-only route can produce a positive current-eligibility result. That result is a point-in-time diagnostic, not a delivery guarantee or an end-to-end AI execution test.
|
||||
|
||||
## Validation status
|
||||
|
||||
Focused regression tests cover preview-only behavior, explicit apply, stale previews, atomic rollback, deleted/disabled/zero-rollout preservation, named-target scope, off-hours versus missing schedules, role-name permission bypass, status-only permissions, empty arrays, simulation limitations, publication requirements, and post-commit failures.
|
||||
|
||||
The focused setup regressions and their race-enabled run passed in the isolated
|
||||
2026-10-16 integration baseline. Go formatting/compilation, declared-dependency
|
||||
frontend typecheck and Node regression tests were also executed. The remaining
|
||||
combined-tree validation, frontend release build, actual MySQL upgrade and browser
|
||||
acceptance gates are recorded in [VALIDATION.md](VALIDATION.md). No production
|
||||
configuration or data was changed. Passing isolated tests does not establish
|
||||
production readiness or authorize an upgrade.
|
||||
Reference in New Issue
Block a user