mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-08 06:48:09 +03:00
5.5 KiB
5.5 KiB
Repository guidance
Inherit the nearest parent guide. This scope owns restoration, migration, ordered collections
and persistence. Prepared candidates, live mutation, serialization and disk flush have separate failure
boundaries. Read Furious/Repository/Storage.py with tests/test_repository_contracts.py; paths are relative
to this source tree's root.
- Repositories restore, migrate, order, and persist profiles, subscriptions, routings, and TUN settings. They do not own
network workflows, controller state, test schedulers, or presentation. A repository method name does not imply
serialization: trace its mutation and
sync()/cleanup calls to locate the actual persistence boundary. Storageowns one application-lifetime backend per collection and exposes live mutable collections for compatibility. Do not add a second cache/snapshot authority. Prefer named repository mutations so validation and commit boundaries can move behind the repository over time. Cached backends retain their restored collections independently of the current QSettings identity; tests or migrations that change namespaces must also account for those owners before reading, flushing, or cleaning up a collection.- Preserve stable profile/subscription IDs, subscription ownership/key, ordering, unknown fields, and legacy schemas.
Active row/index and display text are compatibility/presentation state, not identity. Record-shape dispatch and
metadata precedence are migration behavior: legacy
UserServeraliases override nested metadata, and explicit top-level current fields then override those aliases. Preserve this order and unknown extras unless a tested migration deliberately changes it; do not treat every duplicate key as interchangeable. Connection JSON export is not a profile-store backup. Verify durable metadata through storage-record/backend round trips, including identity, favorites and remote ownership, rather than connection serialization alone. - A restore failure remains observable. Automatic cleanup must not replace unreadable persisted bytes with an
empty fallback; only an explicit successful replacement may do so. Root decoding, complete-collection
hydration, live replacement, and later serialization are separate failure boundaries. Byte preservation does
not authorize using a partial collection. Test malformed records inside a valid root as well as malformed
roots. Profile and subscription hydration publishes only a complete collection; an invalid record must not
expose a partially restored prefix that cleanup can serialize over the original document. The
restore-failure guard protects automatic cleanup, not an arbitrary explicit
sync()call. Do not flush an empty fallback merely to inspect or acknowledge a load failure; test the original persisted bytes through the cleanup path. - Stage fallible decode/migration before live mutation. Subscription reconciliation currently belongs to
Furious/Service/SubscriptionSync.pyand commits through the compatibility live collection: matched managed profiles retain object/profile identity and local metadata, removed profiles become stale, and unrelated groups remain intact. The source revision rejects connection/ownership changes during preparation, while newer local metadata is preserved from the live matched profile at commit. Do not replace that merge with the worker's entire snapshot or add a second reconciliation algorithm here merely because persistence belongs to this scope. - Distinguish a live-collection commit from serialization/flush and subsequent controller effects. The compatibility collection can change before it is flushed; a successful in-memory synchronization is not proof of an atomic disk transaction. Preserve explicit flush/cleanup behavior and report failures at the boundary that actually failed. Batched UI commands may commit several live mutations; cancellation prevents later batches without restoring already committed ones. Do not impose whole-command atomicity without changing callers and failure semantics.
- Engine settings have separate repository keys and owners.
replaceSingTUNSettings()validates and serializes a candidate before changing its live document; a later QSettings flush failure reports an in-memory commit, not a rollback. Empty persisted customizations and effective model defaults are distinct; reading defaults must not populate either engine's repository or modify the other's key.tests/test_sing_tun.pycovers this boundary. - Moving a profile to another subscription makes it a local member and clears its remote matching key; unchanged membership does not demote an already-managed profile. Removing a group definition alone does not delete profiles, cancel requests, or stop timers. Callers coordinate those effects through existing workflow boundaries; do not hide cascades inside a low-level repository operation.
- Verify legacy/current/unknown-field round trips, malformed roots, restore-failure preservation, ordering/stable
identity, group isolation, reconciliation commit behavior, and persistence in temporary QSettings namespaces. Use
tests/test_repository_contracts.pyandtests/test_subscription_sync.pyto revalidate this scope. Reordering a filtered view must preserve hidden slots, selected relative order, and unrelated profiles, then relocate activation by profile ID. Test the complete repository order as well as the visible projection; a correctly painted view can conceal a wrong persisted ordering.