mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-09-22 23:08:08 +03:00
docs: restore scoped repository guidance
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# Action guidance
|
||||
|
||||
## Command boundary
|
||||
|
||||
- Actions adapt one user command to presentation. Resolve live controller/repository state when triggered, delegate the
|
||||
operation to its owner, and render the result; an action is not a second connection, routing, subscription, or
|
||||
persistence authority.
|
||||
- Prefer one shared `QAction` for one semantic command across menus and buttons so checked/enabled state, shortcut,
|
||||
callback, and translation cannot diverge. A host widget may narrow shortcut context; do not make menu shortcuts
|
||||
application-wide when focused editors or other controls own the same keys.
|
||||
- Routing and connection actions render the shared controllers. Rebuilding a dynamic menu releases the old actions,
|
||||
action group, and callbacks before publishing the new snapshot; user-defined labels remain untranslated.
|
||||
- Existing import actions still combine capture/file/clipboard presentation with incremental repository insertion. Treat
|
||||
that as a compatibility path, not a service template. Reuse plugin protocol parsing, construct a complete valid result
|
||||
before each mutation, and keep batched GUI work cancellable and bounded per event-loop turn.
|
||||
|
||||
## Lifetime, input, and verification
|
||||
|
||||
- `AppQAction.callback` is a deliberate strong reference. The action owner must not outlive a captured receiver, and a
|
||||
transient/repeated receiver uses the weak named-method facilities required by `Furious/Qt/AGENTS.md`.
|
||||
- Clipboard text, files, QR images, share links, and plugin results are untrusted and may contain credentials. Bound
|
||||
diagnostic excerpts and never log or echo a complete secret-bearing payload merely to explain a parse failure.
|
||||
- Verify command state and delegation, cancellation/error presentation, shortcut scope in the real focused widget, menu
|
||||
rebuild cleanup, and repeated dialog/capture/action lifetimes. When this command boundary changes intentionally, update
|
||||
this guide and remove superseded compatibility wording in the same change.
|
||||
@@ -25,22 +25,13 @@
|
||||
- A runtime owns its exact process/thread/readers/monitors and publishes an actionable start error. Stop/dispose is
|
||||
bounded, idempotent, and correct after partial acquisition.
|
||||
|
||||
## Backend-specific invariants
|
||||
## Backend scopes
|
||||
|
||||
- **Xray:** preserve the full JSON document, including unrelated inbounds/outbounds, routing, logging, extensions, and
|
||||
unknown transport/security data. Tagged protocol/transport/TLS editors and URI codecs alter only their projection.
|
||||
Compatibility transport-alias migration must be explicit. Xray also owns routing/assets/API statistics and its asset
|
||||
environment contract; asset replacement is digest-verified and atomic.
|
||||
- **Hysteria 1:** retain its legacy flat schema/share-link semantics and tolerated upstream values. Do not import
|
||||
Hysteria 2 nested documents, obfuscation, statistics, or native-TUN policy. It uses application tun2socks when needed
|
||||
and owns the MMDB/ACL assets consumed by its runtime.
|
||||
- **Hysteria 2:** preserve the native nested client document, unknown future values, optional-group absence, and tagged
|
||||
obfuscation siblings. Its runtime factory owns native-TUN privilege/address/route-exclusion policy and statistics
|
||||
capabilities; registries retain descriptors/providers, not request-lifetime monitors/dialogs.
|
||||
- **External Core:** model a user-selected executable, not a protocol binding. Validate absolute executable/working
|
||||
directory, argument/environment types and NULs, endpoints, bounded shutdown timeout, and optional application-TUN
|
||||
metadata before spawn. Execute an argument vector with `shell=False`; never log environment/arguments or search by
|
||||
process name. The runtime owns one exact `Popen`, readers, watcher, buffering, termination escalation, and reaping.
|
||||
- Read the selected backend's nested guide before changing its configuration, editor, protocol codec, runtime, TUN,
|
||||
routing, asset, statistics, or process behavior. Those child guides own backend-specific compatibility details; keep
|
||||
this parent focused on rules that every backend must satisfy.
|
||||
- A shared backend-contract change must be checked against Xray, Hysteria 1, Hysteria 2, and External Core rather than
|
||||
making the most feature-rich backend the implicit default for the others.
|
||||
|
||||
## Verification
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# External Core guidance
|
||||
|
||||
## Structured executable boundary
|
||||
|
||||
- External Core represents one user-selected local executable, not an embedded protocol binding. Keep executable path,
|
||||
optional working directory, argument vector, environment overrides, HTTP/SOCKS endpoints, shutdown timeout, remote
|
||||
TUN address, and application-tun2socks opt-in distinct while preserving unknown top-level fields.
|
||||
- Loading is observational: do not silently absolutize or rewrite relative paths. Validation before spawn owns path
|
||||
existence/type, argument and environment types/NULs, endpoint requirements, and a finite bounded shutdown timeout.
|
||||
- Execute an argument vector with `shell=False`. Never concatenate a shell command, search or kill by process name, or
|
||||
log arguments/environment values that may contain credentials.
|
||||
|
||||
## Runtime and TUN ownership
|
||||
|
||||
- One runtime owns its exact `Popen`, stdout/stderr pipes and readers, watcher, partial-line buffer, exit callback, and
|
||||
reaping path. Shutdown terminates that process, uses only platform-specific escalation for its PID when necessary,
|
||||
kills as a last resort, joins readers, and remains bounded and idempotent after partial startup.
|
||||
- Application tun2socks is an explicit profile capability. It requires a usable SOCKS endpoint and a separate remote
|
||||
server address for bypass routing; an executable path is never a network destination, and this backend never invents
|
||||
native core TUN support. Subscription decoding must continue to reject executable profiles.
|
||||
- Verify unknown-field and editor round trips, path/argument/environment validation, paths with spaces, immediate-exit
|
||||
failure, complete and partial output, exact callback/reader/watcher cleanup, repeated stop/dispose, TUN opt-in and
|
||||
remote-address handling, subscription rejection, and transient editor destruction. Update this guide when the process
|
||||
contract evolves rather than preserving today’s implementation mechanically.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Hysteria 1 guidance
|
||||
|
||||
- Hysteria 1 is the legacy flat client schema and `hysteria://` share-link backend. Do not import Hysteria 2 nested
|
||||
documents, obfuscation, statistics, realm, or native-TUN semantics merely because the upstream names are related.
|
||||
- Preserve tolerated legacy types, upstream field names, absent defaults, and unknown combo values. Loading and an
|
||||
untouched editor/URI/mapping round trip are observational; explicit user edits may normalize only the represented
|
||||
field.
|
||||
- Subscription import is allowed only through supported Hysteria 1 protocol handlers. Subscription identity and test
|
||||
metadata stay in `ServerProfile`, and validation diagnostics never disclose passwords or complete links.
|
||||
- Runtime and download-test preparation use independent configuration copies. This backend uses application tun2socks
|
||||
when global TUN requires it and owns the MMDB/ACL inputs used by its routing launch; it does not gain native TUN by
|
||||
falling through another backend’s policy.
|
||||
- Verify legacy/current URI and mapping compatibility, unknown/tolerated values, stored-copy isolation, MMDB/ACL
|
||||
absence or malformed paths, asynchronous readiness and rollback, core-exit translation, application-TUN policy, and
|
||||
repeated editor/runtime cleanup. Revise this guide with an intentional schema evolution instead of freezing quirks.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Hysteria 2 guidance
|
||||
|
||||
## Native document and editor projection
|
||||
|
||||
- The persisted Hysteria 2 client document is authoritative and is submitted to the embedded runtime. The GUI is a
|
||||
partial projection, not an Xray-shaped compiler or a general upstream-schema normalizer.
|
||||
- Preserve upstream names, optional-group absence, unknown siblings, and future string values. Effective defaults such
|
||||
as `realm.ipMode` are presented without materializing them during an untouched save; editing one leaf changes only
|
||||
that leaf.
|
||||
- `obfs.type` selects tagged subtype data. Unknown types remain visible and survive untouched. An explicit switch to a
|
||||
known type may remove incompatible subtype branches, but never unrelated document branches.
|
||||
|
||||
## TUN, statistics, and lifecycle
|
||||
|
||||
- Managed native TUN replaces only the runtime copy’s `tun`. Disabled management preserves any explicit `tun`, including
|
||||
malformed data for the core to reject; only absence permits application tun2socks. Linux native TUN requires the
|
||||
backend’s privilege and server-route-exclusion guarantees. Probe/download copies always remove native TUN.
|
||||
- Traffic-statistics targets, setting descriptors, and action providers are process-lifetime plugin capabilities;
|
||||
monitors, replies, dialogs, and runtimes created from them are request/transient objects and are never registry-owned.
|
||||
- Verify nested sibling/default preservation, known and unknown values, obfuscation switching, URI/document equality,
|
||||
every native/application-TUN and resolution case, probe stripping, readiness/exit cleanup, statistics cancellation,
|
||||
and repeated transient editor/settings-dialog destruction. Keep this guide synchronized with verified upstream schema
|
||||
changes rather than treating current field lists as permanent.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Xray guidance
|
||||
|
||||
## Full-document preservation
|
||||
|
||||
- The complete Xray JSON document is authoritative. Protocol, transport, TLS, local-endpoint, logging, routing, and TUN
|
||||
editors are partial projections; preserve unrelated inbounds/outbounds, extensions, unknown security/transport data,
|
||||
and unrepresented siblings.
|
||||
- Loading is observational except for narrow tested compatibility migrations. Legacy transport aliases such as `http`,
|
||||
`gun`, and `mkcp` may map to their supported current representation, but do not expand this into general normalization
|
||||
of unknown future values.
|
||||
- URI codecs round-trip only their supported projection without erasing the source document. Keep Shadowsocks plugin
|
||||
metadata and SOCKS/VMess/VLESS/Trojan semantics distinct; malformed input returns controlled validation rather than a
|
||||
plausible different profile.
|
||||
|
||||
## Runtime-specific capabilities
|
||||
|
||||
- Logging paths, selected routing, statistics API, local test endpoints, and TUN are prepared on an independent runtime
|
||||
copy. Managed native TUN replaces runtime TUN inbounds; disabled management preserves explicit valid or malformed TUN
|
||||
and suppresses tun2socks. Proxy/download tests replace inbounds with their proxy-only test surface.
|
||||
- Xray owns routing profiles/options, geo assets, API statistics, and the `XRAY_LOCATION_ASSET` environment contract.
|
||||
Asset replacement remains digest-verified and atomic; action providers retain reusable routing/asset windows only
|
||||
through the created action owner and create transient settings dialogs per request.
|
||||
- Verify full-document and URI preservation, aliases and unknown values, runtime-copy isolation for routing/log/TUN/tests,
|
||||
multiple TUN inbounds, asset integrity/failure, statistics and process cleanup, compiled-safe UI callbacks, and
|
||||
repeated editor/window destruction. Update this scope when an upstream or plugin capability changes intentionally.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Controller guidance
|
||||
|
||||
## Shared state authorities
|
||||
|
||||
- Controllers own process-lifetime shared state and transition policy. They coordinate injected repositories/services
|
||||
and publish structured Qt signals; they do not own transient widgets, network replies, core processes, or worker pools.
|
||||
- `ConnectionController` is the sole connection state machine. A GUI start remains `Connecting` while one generation-
|
||||
checked `ConnectionManager` transaction acquires readiness/TUN resources; System Proxy and the active-profile commit
|
||||
occur only after success. Disconnect/reconnect cancels the exact in-flight generation and ignores stale completion.
|
||||
- Preserve state and signal ordering, interaction gating, the exact selected `ServerProfile`, runtime snapshots,
|
||||
reconnect preference, and rollback after validation, runtime, TUN, System Proxy, cancellation, or unexpected-exit
|
||||
failure. Worker/native callbacks cross to the controller’s Qt thread before transition.
|
||||
- `RoutingController` owns available capability options plus selected/persisted routing. Distinguish a newly selected
|
||||
repository profile from the profile snapshot already owned by a live connection; changes use controlled reconnect,
|
||||
not mutation of the running document. User-defined routing labels are semantic data, not translatable UI literals.
|
||||
- `SettingsController` is the shared policy path used by Home, Settings, tray, and platform integration. Validate
|
||||
availability and complete host effects before persisting success; UI surfaces render its signals rather than keeping
|
||||
duplicate preference state.
|
||||
|
||||
## Verification and evolution
|
||||
|
||||
- Test exact states and signal counts for async success, invalid input, supersession, cancellation, partial acquisition,
|
||||
System Proxy failure, unexpected exit, routing refresh/reconnect, startup restoration, failed host settings, missing
|
||||
partial-startup dependencies, and repeated shutdown. If ownership moves deliberately, update this guide and the
|
||||
affected controller tests instead of keeping a compatibility controller as a second authority.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Bundled extension guidance
|
||||
|
||||
- `Extensions` contains host-shipped plugins that are not proxy runtimes. They register through the same public API and
|
||||
lifecycle as entry-point plugins and receive no private repository, controller, or UI side channel.
|
||||
- `StandardSubscriptionPlugin` owns format recognition and decoding only. A decoder returns an immutable neutral
|
||||
`SubscriptionResult`; profile construction/metadata belongs to `SubscriptionImportService`, and group reconciliation,
|
||||
request generations, timers, persistence, and post-commit effects belong to the subscription service/repository path.
|
||||
- Decoder probing is priority-ordered and failure-isolated. Return `None` when a format does not match, validate the
|
||||
declared result shape, preserve useful names/upstream IDs, and never log a complete payload or link. Current standard
|
||||
formats are linear plain/Base64 share-link envelopes; introduce explicit size/depth/work limits before adding richer
|
||||
recursive or nested formats.
|
||||
- Keep bundled registration deterministic, side-effect-light, and discoverable in source, wheel, and Nuitka builds.
|
||||
Test format selection/fallback, malformed and secret-bearing input, duplicate occurrence identity, unsupported
|
||||
subscription protocols, registration rollback, and absence of repository/UI mutation during decoding. Evolve this
|
||||
guide with the decoder contract rather than giving bundled formats permanent special treatment.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Interface guidance
|
||||
|
||||
- This package defines dependency-light contracts shared across layers. It does not import Qt presentation,
|
||||
controllers, services, repositories, plugins, or concrete backends; a contract may depend on a small model/constant
|
||||
only when that does not trigger application construction or registration.
|
||||
- Contracts specify observable ownership, lifecycle, mutation, serialization, callback, and failure semantics. Search
|
||||
every representative implementation and contract test before changing one; an implementation may strengthen a
|
||||
guarantee but cannot silently weaken it.
|
||||
- `CoreRuntime` is mechanism-neutral: embedded multiprocessing, direct `subprocess`, or an in-process binding can satisfy
|
||||
it. Preserve actionable `startError()`, callback/exit behavior, runtime identity, serialization diagnostics, and a
|
||||
bounded idempotent stop/dispose path. Process/child terminology belongs only to implementations that own one.
|
||||
- `StorageBackend.data()` deliberately exposes a live mutable collection for compatibility. Do not reinterpret it as a
|
||||
snapshot or introduce a second authoritative cache. Editor bindings map input to configuration and back; they do not
|
||||
decide runtime, persistence, or host policy.
|
||||
- `ApplicationRunner.ExitCode` is a process-boundary protocol. Shared encoders and non-throwing configuration
|
||||
construction preserve their distinct diagnostics so callers do not collapse every empty result into the same error.
|
||||
- Verify cheap/import-independent contracts plus representative runtime, storage, editor, application-exit, encoding,
|
||||
and configuration implementations. Update this guide when a contract intentionally changes, together with all
|
||||
implementers and compatibility tests.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Model guidance
|
||||
|
||||
## Domain shape and identity
|
||||
|
||||
- Models are core-neutral Python data and transformations. Do not import Qt, globals, repositories, services,
|
||||
controllers, plugin registries, or concrete backends into this layer.
|
||||
- `CoreConfiguration` is a dict-like connection document whose construction is deliberately non-throwing: unsupported
|
||||
or malformed input becomes an empty object with `constructionError()`. Keep construction and serialization errors
|
||||
distinct and preserve useful context through callers.
|
||||
- `ServerProfile` composes an independent connection document with `ProfileMetadata`. Display name, stable profile ID,
|
||||
subscription ownership/key, latency, speed, annotations, and local flags never become core-configuration fields.
|
||||
- Preserve unknown metadata and legacy aliases across load/save. `independentCopy()` creates a manual profile with a new
|
||||
ID and no subscription owner; a runtime `deepcopy()` preserves identity while isolating mutable preparation.
|
||||
- `ensureProfile()` normalizes rather than clones: metadata arguments update an existing profile. Use an independent
|
||||
copy for a new stored item and a runtime copy when logical identity must survive without mutating persistence.
|
||||
- Profile ID, object identity, subscription source/key, connection fingerprint, display text, and row position answer
|
||||
different questions. Fingerprints require deterministic JSON-compatible connection data and fail explicitly.
|
||||
|
||||
## Compatibility and verification
|
||||
|
||||
- Protocol construction/export belongs to plugin capabilities. Compatibility shims may remain while callers migrate,
|
||||
but new protocol-name branches do not belong in core models.
|
||||
- Verify malformed/current/legacy/unknown-field round trips, metadata/connection separation, copy/identity semantics,
|
||||
deterministic fingerprints, construction/serialization diagnostics, and capability-based import/export. Revise this
|
||||
guide with intentional domain changes; do not preserve a legacy identity rule after migration replaces it.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Outer process guidance
|
||||
|
||||
- `Utility` owns the child-side wrapper used by the outer application process and crash/exit translation. It is not a
|
||||
miscellaneous helper namespace and does not own application composition, repositories, runtimes, or UI policy.
|
||||
- `AppMainProcess` owns one exact Qt application child and one small synchronized crash-log result. Do not add a
|
||||
`multiprocessing.Manager` or auxiliary child merely to communicate status, and preserve the platform’s explicit spawn
|
||||
behavior.
|
||||
- Exception and signal handling must work before and after application construction. Preserve semantic
|
||||
`ApplicationRunner.ExitCode` values, original exception/traceback context, and best-effort crash logging; a log-write
|
||||
failure never replaces the primary failure.
|
||||
- The parent entry point joins only the child it created and shows the fallback Qt report only for a nonzero result.
|
||||
Never discover or terminate processes by name, and keep normal/source/packaged command-line entry points equivalent.
|
||||
- Verify normal return, exception, assertion, signal, pre-application failure, crash-log failure, command dispatch,
|
||||
cross-platform spawn, exact child joining, and absence of manager servers or orphaned resources. If this process
|
||||
topology changes intentionally, rewrite this guide rather than layering another supervisor over the old one.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Reusable widget guidance
|
||||
|
||||
## Presentation and identity
|
||||
|
||||
- Widgets present state below pages/windows. Prefer explicit controller/service/repository inputs and do not add new
|
||||
application-global reach-through or a duplicate state cache; existing global access is compatibility debt, not a
|
||||
template.
|
||||
- Table/list models wrap live repository collections. Bracket mutations with correct begin/end or layout notifications,
|
||||
keep index/deleted compatibility fields synchronized, and map proxy indexes to source objects before acting. Stable
|
||||
profile/subscription IDs—not display text, object row, or current sort order—preserve selection, focus, activation, and
|
||||
async write-back.
|
||||
- Sorting/filtering/reordering must retain logical selection and keyboard focus. Recursively scope table-owned menu
|
||||
shortcuts as `WidgetShortcut` so a focused editor or another surface keeps its own shortcut semantics.
|
||||
|
||||
## Workflow and lifetime boundaries
|
||||
|
||||
- The server and subscription views share one subscription workflow owner. Subscription UI issues commands and renders
|
||||
sync state; it does not duplicate download, decode, reconciliation, timer, persistence, or post-commit behavior.
|
||||
- `ServerTableView` owns selection and cell repaint for profile tests, while `ProfileTestManager` owns scheduling,
|
||||
concurrency, temporary runtimes, cancellation, stable-target validation, and latency/speed mutation. Repository or
|
||||
subscription changes are forwarded as invalidation boundaries; stale results never write by row.
|
||||
- Models, delegates, headers, menus, actions, animations, spinners, WebEngine/map objects, timers, workers, and replies
|
||||
each need one owner. Persistent widgets connect once and refresh state; visibility may pause rendering/animation, not
|
||||
application-level log draining, traffic collection, or other service ownership.
|
||||
- Verify sorted/filtered commands, notification ranges, identity-preserving move/delete, real keyboard focus and nested
|
||||
shortcuts, subscription/test cancellation, hidden-page rendering, exact cell updates, optional WebEngine fallback,
|
||||
and repeated cleanup to baseline. Update this guide when ownership moves; never move service orchestration back into
|
||||
a widget just to preserve historical wording.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Window and page guidance
|
||||
|
||||
## Composition and shared state
|
||||
|
||||
- `MainWindow` owns the persistent built-in page tree and navigation; plugin pages enter through the plugin navigation
|
||||
service. Pages adapt shared controllers/services/repositories and must not become competing state authorities.
|
||||
Preserve application-facing forwarding APIs until their consumers migrate deliberately.
|
||||
- Home, Settings, tray actions, and reusable dialogs render the same connection, routing, and settings controllers.
|
||||
Platform/capability availability affects presentation but does not authorize an unsupported persisted value or a
|
||||
duplicate host side effect.
|
||||
- The current page composition shares one subscription workflow between server and subscription presentation, records
|
||||
traffic into one history, and derives metrics/endpoint presentation from owned services. These exact locations may
|
||||
evolve, but a refactor retains one durable owner, one scheduler/request path, and one signal path.
|
||||
- Home remains the initial page and navigation expansion/selection is session-local unless a product decision adds a
|
||||
persisted migration. Plugin ordering and bottom settings placement remain declarative navigation concerns.
|
||||
|
||||
## Visibility, lifetime, and geometry
|
||||
|
||||
- Long-lived pages construct persistent controls, models, timers, services, and connections once. Page visibility may
|
||||
coalesce log/graph painting or deliberately gate a lazy endpoint lookup, but it never owns log collection/draining,
|
||||
traffic sampling, subscription schedules, or an already-started request.
|
||||
- One-shot editors/prompts use managed transient dialogs and weak compiled-safe continuations. Reusable windows such as
|
||||
the text editor and parent-owned settings dialogs retain one explicit owner, reset on reopen, and use normal close
|
||||
semantics; do not convert every top-level surface to delete-on-close or global retention.
|
||||
- Use normal layouts and `AppQ*` controls. Restore top-level geometry only after persistent composition and through the
|
||||
canonical first-show path; never-shown Qt fallback geometry must not overwrite a prior user decision.
|
||||
|
||||
## Verification and evolution
|
||||
|
||||
- Verify initial/plugin navigation, shared Home/Settings/tray state, service ownership, lazy rendering versus continuous
|
||||
collection, async continuation cleanup, unsaved-close behavior, translation/theme changes, geometry migration, and
|
||||
repeated open/show/hide/destroy stability with real Qt input where semantics depend on it. Keep this guide as current
|
||||
architectural memory: change it with intentional page ownership, not after forcing new code through stale structure.
|
||||
Reference in New Issue
Block a user