mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-30 10:42:09 +08:00
41 lines
2.5 KiB
Markdown
41 lines
2.5 KiB
Markdown
# Backend Architecture Guardrails
|
|
|
|
These rules supplement the repository's root `AGENTS.md`.
|
|
|
|
1. **Keep configuration ownership in `config`.** Configuration writes must use
|
|
its draft and persistence APIs. Patch orchestration must use
|
|
`feat/effects.rs` and `feat/executor.rs`; refresh notifications must use
|
|
`core::notify::announce` after successful persistence and commit. This keeps
|
|
rolled-back transactions from publishing state. If runtime and memory state
|
|
are already committed and cannot be rolled back, announce that state even
|
|
when persistence fails, while preserving the persistence error. Independent
|
|
transactions retain their boundaries and announce their own committed
|
|
results; runtime-only profile activation announces after successful
|
|
application. Cross-layer operations must preserve these ownership and
|
|
transaction boundaries.
|
|
2. **Register every new `IVerge` field.** Register the field in the
|
|
exhaustive effect registry, including an explicit `NoEffect` where
|
|
appropriate, and preserve its platform attributes. Manual field-to-flag
|
|
chains hide missing effects and are forbidden.
|
|
3. **Use `utils::retry` for bounded retries.** Do not introduce handwritten retry
|
|
loops, including `loop` plus `sleep`; preserve attempt budgets, delays and
|
|
terminal errors. Permanent watchers are the exception and must document
|
|
their exit conditions. Traversal of distinct data or port candidates is not
|
|
a retry policy.
|
|
4. **Keep notifications typed.** Send notice statuses through `NoticeStatus` and
|
|
use `Arc<str>` for notice message payloads. Preserve the event names and
|
|
status strings as a shared wire contract. Contract changes must keep
|
|
frontend consumers and backend producers aligned.
|
|
5. **Preserve lock order.** The order is `config_write` before
|
|
`config_update_in_progress` before `lifecycle_lock`. Patch callers must use
|
|
the executor's guarded claim instead of independently combining these locks;
|
|
this preserves Busy rejection and prevents inverted acquisition. Existing
|
|
lifecycle and independent port transactions keep their established locking
|
|
boundaries. A new lock requires registering its position in this rule before
|
|
introducing acquisition sites.
|
|
6. **Prefer reconciliation.** Express new effects as idempotent `ensure`
|
|
operations in `EFFECT_ORDER` so repeated application converges on the same
|
|
state. A trigger chain is an exception only with a code comment explaining
|
|
why the operation cannot be idempotent. Configuration rollback does not
|
|
authorize reverse OS effects.
|