Refine repository guidance

Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
Loren Eteval
2026-09-09 14:20:16 +08:00
parent 721b3e7207
commit c2f9d8efc9
27 changed files with 120 additions and 54 deletions
+4 -2
View File
@@ -19,8 +19,10 @@ exceptions; it does not define the source test suite or imply that every package
## Workflow engineering
- Keep packaging declarations synchronized with `Deploy.py`, `pyproject.toml`, `setup.py`, and `requirements.txt`.
Default-to-newest dependencies still need deterministic assertions at ABI/feature boundaries; pin or checksum external
build tools where the workflow establishes a supply-chain boundary.
The Python floor advertised by package metadata is a separate claim from the interpreter versions exercised by CI;
newer matrix rows cannot prove that floor. Likewise, successful Qt imports do not prove event-loop or binding-call
compatibility. Default-to-newest dependencies/assets still need recorded provenance and deterministic assertions
at ABI/feature boundaries; pin or checksum external build tools where the workflow establishes that boundary.
- The workflow default shell is Bash, including Windows jobs. Select PowerShell explicitly for native Windows paths,
process APIs, or PowerShell syntax, and keep OS/architecture conditions on the step that owns the difference.
- Flatpak checks run inside the installed sandbox, inspect the application's required native closure rather than every
+5 -2
View File
@@ -95,6 +95,8 @@
- Match evidence to the contract: round trips/migrations for models and repositories; exact transitions/signal counts
for controllers; stale/cancel/rollback/cleanup paths for services; partial startup and resource reaping for runtimes;
mocked OS branches for host helpers; import/discovery and packaged checks for compiler-sensitive changes.
Test a resource that refuses cleanup as well as one that exits normally. A terminal flag, cleared reference, or
elapsed timeout is not evidence of native resource release; distinguish that observation from the intended guarantee.
- Report source inspection, executed tests, mocked platform evidence, and packaged validation separately. A passing
source suite does not prove native distributions or every declared Python/Qt floor. Release import checks do not
replace behavioral tests; record untested targets and compatibility gaps explicitly.
@@ -111,8 +113,9 @@
current architecture, tests, verified runtime behavior, explicit design, or an intentional refactor completed in the
same change.
- Put a rule at the narrowest scope where it helps future decisions; let child guides specialize rather than repeat
parents. Remove obsolete content inside files, distinguish preferred architecture from compatibility paths, and
preserve every established file path while doing so.
parents. For each local rule, identify the decision it protects and the implementation or test that could disprove
it. Remove obsolete content inside files, distinguish preferred architecture from compatibility paths, and preserve
every established file path while doing so. A guidance audit must not turn an observed defect into a required design.
- After significant architectural work, re-read the applicable hierarchy as a fresh agent: can it identify the
owner, invariant, failure boundary, and relevant tests without relying on conversation history? Challenge rules
likely to become stale, circular references, and wording that freezes incidental structure.
+3
View File
@@ -49,6 +49,9 @@ domain, persistence, orchestration, platform integration, and presentation; nest
every asynchronous workflow. Page visibility may control rendering, never ownership of collection or draining.
- Preserve unknown/forward-compatible fields through model, repository, backend editor, and serialization changes.
Compatibility normalization must be narrow, intentional, and tested separately from observational loading.
A dict-like profile exposes its connection document through the mapping interface, not its complete persistence
record. Choose the explicit profile, metadata, or connection representation required by each boundary; generic
mapping conversion is not a profile backup.
- Import, clipboard, share-link, file, and QR paths reuse the owning plugin codecs and validation. QR is a presentation
transport, not a second protocol parser; construct a complete neutral result before repository mutation and never log
the secret-bearing payload.
+7 -4
View File
@@ -8,9 +8,10 @@ presentation without becoming a workflow authority.
- 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.
- Share a `QAction` across menus/buttons when command target, owner lifetime, and shortcut scope are the same.
Distinct window/tray contexts may need separate actions that observe the same controller; do not force one global
action across incompatible lifetimes. Keep checked/enabled state and translation consistent, and 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
@@ -25,7 +26,9 @@ presentation without becoming a workflow authority.
diagnostic excerpts and never log or echo a complete secret-bearing payload merely to explain a parse failure.
- Screen capture and QR decoding currently run synchronously; batching the resulting imports does not make capture
interruptible. If moved to workers, transfer data through an owned GUI-thread continuation without retaining
transient windows. QR export generation belongs to its result window, not a parallel action-owned exporter.
transient windows. Each screen-capture action owns a separate native capture handle, including separate tray/page
instances; type-deduplicated cleanup must not leave one open. QR export generation belongs to its result window,
not a parallel action-owned exporter.
- Small profile imports use the direct bulk path; large imports yield between bounded batches. Preserve captured
input and one operation context until completion/cancellation, reject deferred calls after teardown, and retain
already committed batches when cancellation stops later work. A parser call itself is not preempted by a batch.
+7 -4
View File
@@ -5,16 +5,19 @@ child-process supervisor and the inner application event loop.
- `Furious.__main__` and `AppMainProcess` own the outer process/crash boundary; `DesktopApplication` owns the inner Qt
composition. Keep those responsibilities separate and preserve semantic exit codes and original failure context.
- Startup stages begin after singleton election. Plugins are available before repository restoration
interprets persisted profiles; controllers and presentation consume those initialized owners. Register cleanup as
each acquisition succeeds, and preserve these dependencies when changing stage order.
- Plugin, storage, and UI initialization follows singleton election; the Qt application and its initial resource
owners already exist during election. Plugins are available before repository restoration interprets persisted
profiles. Register cleanup as each acquisition succeeds, including election-failure paths, and preserve these
dependencies when changing stage order.
- Partial startup, normal exit, signals, and event-loop failure converge on one reverse-order, failure-isolating,
idempotent cleanup path. `exit()` requests Qt termination; action/window/session handlers do not run cleanup directly.
- A stage that fails before its cleanup callback is registered must release its own partial acquisitions. The outer
cleanup stack releases completed stages; it cannot discover half-built controllers, UI, logging handlers, or
native listeners. Restore logging configuration as well as closing handlers. Run service shutdown while its
owners remain valid; scheduling `deleteLater()` is not evidence that workers or native resources have finished.
Review cooperative pool drains separately from the cleanup stack's ordering guarantees.
Review cooperative pool drains separately from the cleanup stack's ordering guarantees. The application pool's
timed wait logs unfinished work, whereas subscription preparation waits synchronously after its diagnostic timeout.
Neither policy can be inferred from reverse cleanup order or from the name of a shutdown method.
- Singleton election serializes cooperating candidates, re-probes after waiting, recovers only a confirmed stale
endpoint, and fails closed when ownership is uncertain, including privilege handoff. A successful Windows
local-server listen alone does not establish exclusivity; command delivery and endpoint ownership are separate
+3 -2
View File
@@ -32,8 +32,9 @@ scope adds rules shared by all bundled proxy backends without making the richest
must be bounded, idempotent, and safe after partial acquisition. Report incomplete reaping explicitly; reaching a
deadline or changing logical execution state does not prove that native resources have exited.
- Runtime factories follow the current plugin contract: fully prepare and return one owned launch whose zero-argument
start is separate from readiness observation. Do not hide readiness waits, Boolean success channels, or controller
policy inside a backend runtime.
start is separate from readiness observation. If preparation fails before a valid launch transfers to the caller,
the factory must release its own partial resources; the caller cannot dispose a runtime it never received. Do not
hide readiness waits, Boolean success channels, or controller policy inside a backend runtime.
## Backend scopes
+4 -2
View File
@@ -34,5 +34,7 @@ the intentionally different direct-subprocess scope for user-selected executable
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. Start with
`tests/test_external_core.py` and `tests/test_backend_editor_contract.py`. A failed final reap is a cleanup
failure to report; elapsed stop deadlines alone do not prove that the OS process or all descendants have exited.
`tests/test_external_core.py` and `tests/test_backend_editor_contract.py`. Exercise a child that remains alive
after escalation and readers/watchers that outlast their joins. A failed final reap is a cleanup failure to report;
clearing the runtime's process/thread references must not be used as evidence that those resources exited.
Direct-child exit also does not prove that descendants closed inherited pipes.
+5 -3
View File
@@ -13,9 +13,11 @@ preserve Hysteria 1's legacy flat schema and lifecycle without importing assumpt
- 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.
- Routing ACL/MMDB launch inputs remain distinct from the stored connection JSON. A prepared runtime advertises its
local HTTP readiness endpoint separately from child liveness. The built-in factory has no statistics provider;
shared UI must handle that absence instead of treating it as a failed connection.
- Routing ACL/MMDB launch inputs remain distinct from the stored connection JSON. Optional files are read into
launch data before the child starts; a missing/unreadable file is logged and falls back to empty input. Preserve
that observable fallback unless deliberately changing the contract, and include this synchronous file work in
preparation responsiveness review. A prepared runtime advertises its local HTTP readiness endpoint separately
from child liveness. The built-in factory has no statistics provider; shared UI handles that absence.
- 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. Use `tests/test_hysteria1_protocol.py`,
+4 -3
View File
@@ -17,9 +17,10 @@ Hysteria 2's nested upstream document, native-TUN capability, statistics, and ed
- 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. Managed preparation currently resolves server addresses synchronously; do not describe the whole native-TUN
stage as event-driven merely because connection readiness is asynchronous.
requires the backend’s privilege and server-route-exclusion guarantees. The application's Linux privilege-helper
path does not grant an embedded native-TUN core the same privileges. Test these availability decisions separately.
Probe/download copies always remove native TUN. Managed preparation currently resolves server addresses
synchronously; do not describe the whole native-TUN stage as event-driven merely because readiness is asynchronous.
- The statistics provider is a process-lifetime capability; the runtime captures a configured server-API target and
sampling owns its monitor/query lifetime. API URL, client ID, and authorization secret are distinct from client
connection credentials. Keep requests bounded, validate counters, and never log the secret or infer statistics
+6 -1
View File
@@ -28,7 +28,12 @@ full JSON preservation, routing/assets/statistics, and protocol/transport/TLS pr
usable file. Distinguish this updater from `Deploy.py --download`, whose download/integrity behavior must be
inspected separately; shared filenames do not make the two mechanisms equivalent.
- Routing selection IDs, user routing documents, and translated built-in labels are different contracts. Preserve
custom document content and named-profile identity while composing runtime routing/API statistics.
custom document content and named-profile identity while composing runtime routing/API statistics. Trace the
selected repository routing document separately from the connection's own routing branch; neither may be mutated
as a side effect of preparing a launch.
- Statistics preparation is optional and may leave a valid runtime without a statistics target. Preserve that
distinction from connection failure; later sampling uses the target captured for this runtime, not newly edited
settings or an assumption based solely on the backend name.
- 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. Use `tests/test_xray_asset_download.py`,
+3 -2
View File
@@ -20,8 +20,9 @@ transitions. Services own execution resources; existing prompts are presentation
are not generic connection errors.
- `RoutingController` owns available capability options plus selected/persisted routing. Distinguish a newly
selected repository profile from the active-profile reference and the independent runtime document; changes use
controlled reconnect, not mutation of the running document. User-defined routing labels are semantic data, not
translatable UI literals.
controlled reconnect, not mutation of the running document. Capability refresh prefers the active profile and
otherwise the repository's activated profile. Normalizing the displayed option does not itself persist a new
preference; explicit selection owns that mutation. User-defined routing labels are not translatable UI literals.
- `SettingsController` is the shared policy path used by Home, Settings, tray, and platform integration. Startup
registration persists only after host success; other preferences may apply immediately or on the next connection.
Preserve each setting's actual application timing instead of imposing one transaction order on all preferences.
+7 -4
View File
@@ -11,10 +11,13 @@ This scope owns reusable embedded execution machinery and application tun2socks;
- `CoreRuntime` execution state, typed terminal exit, and readiness are separate contracts. A process becoming alive is
not proof that its proxy/TUN endpoint is ready, while a readiness timeout must not overwrite an already observed typed
exit.
- A runtime owns and reaps its exact child, process handle, monitor/drain timers, queues, callbacks, and feeder resources.
Stop is bounded, escalates only that child when needed, closes handles, and is safe after partial start or repetition.
- Process-backed runtimes monitor and reap their own child, interpret a raw exit exactly once, and publish one typed exit
event. `isRunning()` is a passive execution-liveness query and must not consume or dispatch lifecycle events.
- Required cleanup covers the exact child, process handle, monitor/drain timers, queues, callbacks, and feeder
resources. Stop must bound waits, escalate only the owned child, and remain safe after partial start or repetition.
A join timeout or failed handle close is not a successful reap. Verify actual child liveness before describing a
terminal execution state as complete resource release; include failed escalation in ownership tests.
- Process-backed runtimes own exit monitoring and interpretation: publish one typed terminal event per execution,
preserving the raw exit and whether stop was requested. `isRunning()` is a passive liveness query and must not
consume or dispatch lifecycle events.
- Child targets never touch Qt widgets. Output transport is non-blocking and bounded in message size, pending volume, and
per-turn drain work; draining continues independently of Log-page visibility and backs off only when idle.
- Parentless timers are acceptable only with a durable runtime owner and explicit disposal. Leaving the manager pool
+4 -2
View File
@@ -5,8 +5,10 @@ application-data or settings directory.
## Boundary and provenance
- This directory ships application assets, not user state: Xray GeoIP/geosite data, Hysteria MMDB/ACL data, the local
MapLibre endpoint map, and the bundled font. Settings, subscriptions, caches, and temporary downloads belong elsewhere.
- This directory ships Xray GeoIP/geosite data, Hysteria MMDB/ACL data, the local MapLibre endpoint map, and the
bundled font. It is not a home for settings, subscriptions, or general caches. The Xray updater currently replaces
assets at the package-resolved data paths, so these files are not necessarily immutable at runtime. Review source,
installed, and packaged write permissions separately; an application refresh may appear as a source-tree change.
- Preserve upstream licenses, provenance, binary/text formats, filenames, and paths consumed by constants, backends,
tests, setuptools package data, and Nuitka. Do not incidentally reformat generated ACLs or replace binary assets.
- Markdown files in this directory are repository metadata, not runtime data. Keep top-level and nested Markdown files
+5 -3
View File
@@ -17,9 +17,11 @@ host-shipped non-runtime plugins and must not gain private authority merely beca
all shared parser state and caches, not merely absence of widgets in the immediate method. Worker preparation also
requires the selected protocol handlers to opt in; a safe envelope decoder cannot authorize an unsafe downstream
parser. Preserve the GUI compatibility fallback for unclassified capabilities.
- Decoder output is descriptive, not a repository transaction. It cannot assign live profile identity, mutate a
subscription group, cancel tests, reconnect, or publish UI state; those decisions remain at the import/manager commit
boundaries.
- Decoder output is descriptive, not a repository transaction. Supplied names and upstream IDs are input to profile
construction, not permission to overwrite local identity or grant remote ownership. It cannot mutate a group,
cancel tests, reconnect, or publish UI state; those decisions remain at the import/manager commit boundaries.
Test recognized-empty, wholly unsupported, and mixed-validity payloads separately so decoder matching is not
confused with successful profile import or authorization to clear an existing group.
- 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
+2
View File
@@ -14,6 +14,8 @@ human-reviewed translations.
- Preserve existing translation-key and language-field order. The generator retains dictionary order rather than
enforcing a universal sort; source traversal can affect newly discovered entries. Do not sort the catalog as cleanup.
`source` contains deduplicated fully qualified modules and is rebuilt by extraction rather than manually curated.
Changing a source literal changes catalog identity: extraction may remove the old reviewed entry and introduce a
new unreviewed one. Review wording changes as translation migrations, including reused keys in other modules.
- Inspect the full diff. Preserve deliberate translations/review flags, HTML/newline semantics, and natural RU/ZH
meaning. Curated, verified translations need `isReviewed` set to the string `'True'`, as the generator compares that
literal; a Python Boolean is not equivalent. Review applies to the entry, so inspect its other language values too.
+3 -1
View File
@@ -18,7 +18,9 @@ for unrelated application orchestration to accumulate in a broad helper namespac
failure, and None when policy deliberately leaves host settings unchanged. Startup registration and some routing
helpers return Booleans; script-mode startup registration intentionally does nothing. Preserve these distinctions
at callers instead of treating absence of an exception as confirmed host state. Check every native command result,
including each enabled macOS network service, and bound host-command waits at this boundary.
including each enabled macOS network service, and bound host-command waits at this boundary. A per-command timeout
is not a deadline for a loop over services or routes. Multi-step host mutation may be partial when a later command
fails; a False result does not establish that earlier effects were rolled back.
- Prefer argument vectors over shell strings. Each caller owns any responsiveness/cleanup timeout appropriate to its
context; build-time commands and GUI-time host mutation do not share one universal timeout policy.
- Windows proxy calls, Linux desktop settings/host bridging, and macOS network-service operations are distinct
+3 -1
View File
@@ -25,7 +25,9 @@ satisfy without importing application composition or concrete backends.
contracts.
- Runtime liveness is observational: querying it must not consume an exit, transfer ownership, or dispatch
callbacks. A zero process exit can still be an unexpected connection failure; requested stop and raw exit success
are different facts. Keep semantic startup errors separate from process codes and readiness timeouts.
are different facts. Keep semantic startup errors separate from process codes and readiness timeouts. Define
cleanup-failure semantics without assuming every runtime owns a subprocess; bounded stop/dispose requirements
must remain meaningful for an in-process implementation as well as a child process that resists termination.
- 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. Start with `tests/test_interface.py` and
+2 -1
View File
@@ -9,7 +9,8 @@ Qt presentation, plugin discovery, or workflow execution.
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.
distinct and preserve useful context through callers. Successful generic mapping construction is not protocol
validation: backend acceptance belongs to the selected capability, and serializability is a separate check.
- `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
+5 -2
View File
@@ -8,8 +8,11 @@ capability definitions, atomic registration, dispatch, and plugin lifecycle; bac
- `Plugins.API` defines independently composable capabilities for protocols/editors, subscription decoding, runtime
factories, routing/TUN/probes, statistics, settings, actions, and navigation. Extend the owning capability instead of
adding backend-name branches or a parallel registry.
- The registry normalizes and validates a plugin's complete contribution before committing indexes. Duplicate IDs or
schemes, incompatible API versions, invalid descriptors, and initialization failure leave existing providers intact.
- The registry normalizes and validates a plugin's complete contribution before changing indexes. Initialization
runs with the contribution indexed; if it fails, shutdown is attempted and those indexes are removed. This is
rollback of registry publication, not a transaction over arbitrary plugin side effects. Plugins must clean their
own partial acquisitions even when initialization fails. Duplicate IDs/schemes and invalid versions/descriptors
must leave existing providers intact.
- Host plugin types register before external entry-point discovery. Bundled registrations are explicit for source,
wheel, and Nuitka inclusion. External entries currently follow metadata enumeration order; do not promise sorted
discovery or rely on it for precedence. Registration is atomic per plugin, not across a multi-plugin entry point.
+5 -2
View File
@@ -10,7 +10,9 @@ primitives; pages and services consume them without creating parallel registries
- Reuse `Furious.Qt` `AppQ*` controls, `AppStyleSheet`, translation/theme mixins, and shared dialog/window infrastructure.
Do not create parallel style, theme-transition, translation, or lifetime registries. Shared control styling belongs
in the application stylesheets; component-specific overrides are valid parts of stylesheet composition.
in the application stylesheets; component-specific overrides are valid parts of stylesheet composition. Check
selector specificity for disabled, hover, and selected states: a general disabled-label rule may lose to an
object-name rule even when the widget's enabled state is correct.
- Controls that retranslate retain source text; semantic/user-defined values stay untranslated. Preserve keyboard focus,
shortcut scope, accessibility, translated-text growth, responsive layout, high-DPI behavior, and both themes.
- Application-owned theme transitions commit destination state immediately; snapshots are non-interactive presentation
@@ -27,7 +29,8 @@ primitives; pages and services consume them without creating parallel registries
`finished` ends interaction, not native lifetime; operation context may be released then only if later callbacks
do not need it.
- `AppQDialog`/`AppQMainWindow` registries bridge asynchronous presentation/visibility; they are not substitute
application owners. Registry cleanup captures opaque tokens, never the object being released.
application owners. Cleanup captures a unique lifetime token, never the object being released or a reusable
numeric object ID. A delayed destruction callback must not evict a newer wrapper from the registry.
- A Qt parent alone does not prove the Python wrapper or logical feature lifetime. Bare Qt `.show()` does not retain
an unparented wrapper; `AppQMainWindow.show()` adds its own visible-window retention until accepted close. Do not
solve ambiguity by global retention, indiscriminate delete-on-close, routine `gc.collect()`, or broad
+3 -1
View File
@@ -11,7 +11,9 @@ This scope owns restoration, migration, ordering, and persistence; workflows and
- 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.
- 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.
fallback; only an explicit successful replacement may do so. Root decoding, individual-record hydration, and later
serialization are separate failure boundaries. Test malformed records inside a valid root as well as malformed
roots; the existing root fallback is not a guarantee that every record error is recoverable.
- Stage fallible decode/migration before live mutation. Subscription reconciliation currently belongs to
`Service/SubscriptionSync.py` and commits through the compatibility live collection: matched managed profiles
retain object/profile identity and local metadata, removed profiles become stale, and unrelated groups remain
+8 -2
View File
@@ -33,6 +33,8 @@ for lifetime primitives. This scope owns multi-stage workflows and temporary res
replacing the runtime callback. Worker-thread exits are queued to the router's Qt thread, delivered at most once, and
suppressed after release. Execution liveness and endpoint/TUN readiness remain separate observations. A readiness
timeout never replaces a typed exit after execution has already stopped, even when that exit is still queued.
Lease release currently logs stop/dispose errors and completes logical callback release; this is not evidence that
the underlying resource was reaped. Changes to cleanup-failure reporting must cover both runtime and lease owners.
- `HttpGetManager` owns reply/error/timeout cleanup. DNS recursion and external-input caches are bounded. Update,
connectivity, endpoint, subscription, and asset requests own their exact reply and reject stale generations.
- Subscription stages remain separate: decoders return neutral items; import constructs profiles/metadata;
@@ -52,14 +54,18 @@ for lifetime primitives. This scope owns multi-stage workflows and temporary res
- Log transport, traffic collection, and metric history remain bounded and independent of page visibility. Rendering may
be lazy; collection/draining ownership is not.
- Logging accepts concurrent producers through one globally ordered model with count, total-character, and per-entry
limits. Whole-stream clearing swaps generations; retired entries are reclaimed in bounded batches under retention
budgets. Selective category clearing can cost O(k); do not claim every clear is constant-time.
limits. Batch input conversions are validated before mutation; compatibility per-entry signals observe the fully
committed batch. Presenters consume coalesced changes/cursors rather than replaying those signals as a second log.
Whole-stream clearing swaps generations; retired entries are reclaimed in bounded batches under retention budgets.
Selective category clearing can cost O(k); do not claim every clear is constant-time.
- Log cursors are opaque and filter-specific. A generation change requires a reset; retention-only eviction supplies
a new first-retained sequence so presenters can prune their prefix without rebuilding history. Capture entries and
the next cursor atomically, and coalesce notifications without losing producer updates.
- Metrics sampling owns its worker/future generation and rejects results after disconnect, disablement, replacement,
or shutdown. Cancellation cannot stop an already-running plugin query: monitor contracts must bound blocking work.
Normalize cumulative-counter resets before history aggregation; clearing usage must not erase speed history.
History contains finite values for registered metrics on a monotonic timeline. A missing metric sample is not a
measured zero; preserve that distinction when adding providers or aggregating sparse series.
## Profile testing
+4 -3
View File
@@ -14,9 +14,10 @@ general-purpose utility bucket.
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.
- Shared crash status is a synchronized Boolean plus the child's semantic exit result; diagnostic text is written to
a file and may include retained logs plus a traceback. Do not describe the complete crash file as size-bounded by
the Boolean channel. Redaction and crash-write failure are separate from application-exit correctness.
- Shared crash status is a synchronized Boolean plus the child's semantic exit result; set the flag only after the
diagnostic file is written successfully. Text may include retained logs plus a traceback, so the Boolean channel
does not bound the crash file's size or sanitize its contents. Keep crash-write failure separate from the primary
exit result, and test reporting both with and without a constructed application/log manager.
- Fallback presentation runs in the parent after a nonzero child result. It constructs a Qt application for the
report but does not call the ordinary application `run()` initialization. Keep that constructor dependency in
failure-path tests, and preserve the original result when evolving reporting failures rather than adding a supervisor.
+4 -2
View File
@@ -13,8 +13,10 @@ some service owners; that construction detail does not make every view an indepe
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.
- Sorting/filtering/reordering must retain logical selection and keyboard focus. Capture domain IDs before yielding
to a dialog or event-loop turn; an ordinary QModelIndex/source row may become invalid or refer to another item.
Map the resolved current object back through the proxy when restoring focus. Recursively scope table-owned menu
shortcuts as `WidgetShortcut` so focused editors and other surfaces keep their own shortcut semantics.
## Workflow and lifetime boundaries
+3 -2
View File
@@ -10,8 +10,9 @@ This scope owns persistent page composition and top-level presentation, not shar
Preserve application-facing forwarding APIs until their consumers migrate deliberately. Bulk profile forwarding
must retain the bulk mutation boundary through Home and its model, without expanding into per-profile refreshes.
- 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.
Apply availability and interaction gating to both a control and its associated label, on initial composition and
later state changes. Disabling presentation does not clear a stored preference or authorize a duplicate host side
effect; preserve the controller's platform/capability policy.
- 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.
+3 -1
View File
@@ -13,7 +13,9 @@ resource-manifest contract; it does not govern general UI layout.
environment's `pyside6-rcc Resources.qrc -o Furious/Frozenlib/AppResources.py`. Never hand-edit generated resource
code; inspect compiler-version churn separately from the intended alias/asset change.
- Treat the alias as the application-facing identity and the source path as an implementation detail. Search both before
replacement so an apparently unused file is not removed while still generated or consumed through an alias.
replacement so an apparently unused file is not removed while still generated or consumed through an alias. Selecting
an already bundled Bootstrap icon normally changes its consumer only; it does not require regeneration or another
SVG copy. Compare the glyph's visible bounds at the actual control size, not only its nominal SVG canvas.
- Verify alias uniqueness and source/package resolution, then inspect the actual control or tray use under both
themes, high DPI, relevant sizes, disabled/selected states, and platform packaging where applicable. Deployment
icons also have direct filesystem consumers in `Deploy.py`; a resource alias search alone cannot prove a PNG is
+8 -2
View File
@@ -33,8 +33,11 @@ and test-tier selection; test convenience never weakens a production invariant.
Rendering regressions may assert targeted pixel/alpha or geometry properties under explicit themes and scaling.
Stylesheet selector counts are not rendering invariants: shared rules and component overrides can both be valid.
- Prefer exact state, signal counts, destroyed signals, weak references, registry/child counts, thread/process/handle
ownership, and final exit status. RSS/handle trends and repeated lifecycle batches belong in stress tiers;
`gc.collect()` is diagnostic at batch boundaries, never a production fix or per-cycle requirement.
ownership, and final exit status. A mock cleared from its owner does not prove termination: failure-to-reap tests
must independently retain and inspect the fake process. For Qt API compatibility, a permissive Python fake cannot
validate a real binding's accepted argument types; exercise a harmless real object at that boundary.
RSS/handle trends and repeated lifecycle batches belong in stress tiers; `gc.collect()` is diagnostic at batch
boundaries, never a production fix or per-cycle requirement.
## Tiers and maintenance
@@ -42,6 +45,9 @@ and test-tier selection; test convenience never weakens a production invariant.
tests -v` for full source-suite discovery (opt-in tests still skip). The runner is unittest, not pytest. Run the
narrow module first, then the affected tier documented in `tests/README.md`. The release-confidence tier is
explicitly opt-in with `FURIOUS_VERY_HEAVY_TESTS=1`; packaged/manual smoke work uses disposable environments.
The historical log comparison additionally requires `FURIOUS_LOG_MANAGER_BASELINE` naming a trusted, compatible
local Git revision; it loads that revision's implementation. Report this opt-in and any skips separately rather
than assuming the very-heavy switch alone executes every discovered case.
- Source-only tests and an offscreen platform do not prove a packaged Qt runtime. Compiler-sensitive changes need
the relevant native lifecycle module and a separate compiled probe; report skipped or unavailable targets
explicitly. The release workflow currently builds/checks artifacts without running this source behavioral suite.