diff --git a/.github/AGENTS.md b/.github/AGENTS.md index e3b1af9..8abaeb5 100644 --- a/.github/AGENTS.md +++ b/.github/AGENTS.md @@ -35,6 +35,7 @@ exceptions; it does not define the source test suite or imply that every package gates. When a target cannot run locally, add a narrow CI assertion that fails before publication with a useful reason. - The current workflow performs packaging/import/native checks but does not run the unittest behavioral suite. Do not call an artifact build a regression-test pass; use `tests/README.md` for source verification. Check actual - `needs` and tag gates rather than assuming a downstream publish job runs on every build. + `needs` and tag gates rather than assuming a downstream publish job runs on every build. Follow each publication + dependency back to its required artifact checks; upload success alone does not establish release eligibility. - Revalidate version/architecture claims against the current matrix instead of duplicating all pins here. When build topology intentionally changes, update this scope and follow every consumer through upload and publication. diff --git a/AGENTS.md b/AGENTS.md index 17f6643..85bf289 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,7 +48,8 @@ controllers/models; they do not copy connection, routing, System Proxy, TUN, subscription, or test state. - Treat persisted profiles and plugin documents as input. Prepare runtime, routing, probe, and TUN state on explicit copies unless an API deliberately mutates storage. A failed pre-commit stage leaves persistence unchanged; a failed - post-commit side effect is reported without pretending the commit rolled back. + post-commit side effect is reported without pretending the commit rolled back. Identify the unit of commit: + cancellation of a batched operation may preserve completed batches rather than roll back the entire command. - Use stable domain identity, not table rows, proxy indexes, display text, or object position. Async results additionally prove that the target generation/fingerprint is still current before mutation. - Distinguish profile identity, subscription membership, remote synchronization ownership, and execution snapshots. @@ -98,8 +99,8 @@ 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. - Use real Qt semantics when focus, selection, keyboard modifiers, proxy mapping, event delivery, queued callbacks, - geometry, or QObject destruction matters. Prefer semantic state and destroyed/resource counts over pixel snapshots or - arbitrary sleeps/RSS thresholds. + geometry, or QObject destruction matters. Prefer semantic state and destroyed/resource counts; use targeted + rendering assertions when pixels are the defect, without relying on whole-window snapshots or arbitrary sleeps. - Before handoff, review for duplicate authorities, persisted-data mutation during preparation, stale async write-back, swallowed diagnostics, unowned resources, unbounded external-input caches, plugin-specific branches in shared code, and source-only assumptions at packaging boundaries. @@ -112,11 +113,9 @@ - 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. -- After significant architectural work, ask what durable fact was learned, whether guidance now misleads, and whether a - future agent would choose the correct owner and test boundary. Re-read the applicable hierarchy as a fresh agent, - challenge rules most likely to become stale or freeze implementation, and do not record temporary implementation - details. -- In each affected scope, distinguish observed behavior from design requirements and identify tests/consumers that - can challenge the rule later. Re-read the hierarchy for circular references and rules that freeze incidental - structure. During guidance-only work, record code defects separately instead of changing production code to - satisfy the prose. +- 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. +- Distinguish observed behavior from design requirements and name tests/consumers that can challenge a local rule. + A known limitation is not a desired invariant. During guidance-only work, report code defects separately instead + of changing production code to satisfy the prose. diff --git a/Furious/AGENTS.md b/Furious/AGENTS.md index 4e3db1a..fc99f0c 100644 --- a/Furious/AGENTS.md +++ b/Furious/AGENTS.md @@ -38,7 +38,9 @@ domain, persistence, orchestration, platform integration, and presentation; nest - Controllers publish shared state and coordinate resource-owning services. New service APIs publish outcomes for UI consumers rather than create presentation. Existing update-service dialogs and settings/controller prompts are compatibility paths, not evidence of a strict UI-free service/controller layer; preserve callers until - deliberately separating those responsibilities. Widgets should not absorb new workflow orchestration. + deliberately separating those responsibilities. Some shared managers are currently constructed under persistent + widgets/pages. Construction location does not transfer workflow authority to every view: moving an owner must + preserve one scheduler, result boundary, and cleanup path. Widgets should not absorb new workflow orchestration. - Plugin registries index process-lifetime plugins, descriptors, and capabilities. Created editors and active runtimes transfer to explicit UI/workflow owners. A capability may own a reusable service, such as asset updating, but that service still needs a cleanup boundary. Built-ins use the public capability contract; existing diff --git a/Furious/Actions/AGENTS.md b/Furious/Actions/AGENTS.md index 9c6c810..9cec579 100644 --- a/Furious/Actions/AGENTS.md +++ b/Furious/Actions/AGENTS.md @@ -23,10 +23,15 @@ presentation without becoming a workflow authority. 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. -- Long-running capture/import/export presentation owns one cancellable operation context. Screen capture/decoding - workers return data for GUI-thread insertion and retain no transient windows. Yield large insertions in bounded - batches, reject callbacks after cancellation/destruction, and retain the captured input until terminal cleanup. QR - result generation belongs to its window; actions delegate instead of retaining a parallel exporter. +- 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. +- 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. +- Batch limits bound work between event-loop yields; the minimum progress interval throttles status refreshes at + those boundaries. It is not an independent paint timer. Keep terminal feedback accurate and choose scale policies + from measured responsiveness rather than freezing a batch count into the command contract. - Snapshot the intended profile identities before an asynchronous confirmation or editor opens. On acceptance resolve those targets again; do not apply the original gesture to whatever selection happens to exist when the dialog closes. diff --git a/Furious/Application/AGENTS.md b/Furious/Application/AGENTS.md index b2d6af5..fb85e0c 100644 --- a/Furious/Application/AGENTS.md +++ b/Furious/Application/AGENTS.md @@ -5,13 +5,16 @@ 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 acquires singleton ownership before composing process-lifetime repositories, plugins, controllers, logging, - host integration, UI, and optional restored connection. Register cleanup as each acquisition succeeds. +- 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. - 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, and keep thread-pool cleanup bounded. + 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. - 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 diff --git a/Furious/Backends/AGENTS.md b/Furious/Backends/AGENTS.md index 96c0ad0..f64c424 100644 --- a/Furious/Backends/AGENTS.md +++ b/Furious/Backends/AGENTS.md @@ -1,8 +1,7 @@ # Backend guidance Inherit the root and package guides. Consult Plugins/Models/Service for the contracts consumed by this scope. This -scope adds rules shared by all bundled proxy -backends without making the richest backend the generic default. +scope adds rules shared by all bundled proxy backends without making the richest backend the generic default. ## Common backend contract @@ -13,7 +12,8 @@ backends without making the richest backend the generic default. independent runtime copy; failed preparation must not mutate the stored profile. - Structured editors are partial projections. Loading is observational except for a narrow documented migration; untouched save preserves unknown fields/values and absent defaults. Editing one represented leaf preserves unknown - siblings and unrelated branches. + siblings and unrelated branches. URI export represents the codec's supported projection, not a lossless backup + of every document field; exporting must leave the source document unchanged. - Malformed external input returns controlled validation with backend context. Do not create a plausible but different profile, and do not log credentials, complete URIs, or documents. - Configuration/runtime modules stay importable without constructing Qt editors. Plugin registration remains literal @@ -28,8 +28,9 @@ backends without making the richest backend the generic default. - Supported proxy/download-test preparation explicitly strips native TUN from the copied document. The generic `proxyModeOnly` request does not sanitize arbitrary plugin configuration by itself. Required managed-native-TUN rejection raises `TUNPreparationError`; do not silently switch implementations. -- 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. +- A runtime owns its exact process/thread/readers/monitors and publishes an actionable start error. Stop/dispose + 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. diff --git a/Furious/Backends/ExternalCore/AGENTS.md b/Furious/Backends/ExternalCore/AGENTS.md index a2c0325..ca4aa79 100644 --- a/Furious/Backends/ExternalCore/AGENTS.md +++ b/Furious/Backends/ExternalCore/AGENTS.md @@ -1,8 +1,7 @@ # External Core guidance Inherit the root, package, and common backend guides; consult Plugins for capability contracts. This file preserves -the intentionally different direct-subprocess scope for -user-selected executables. +the intentionally different direct-subprocess scope for user-selected executables. ## Structured executable boundary @@ -27,7 +26,8 @@ user-selected executables. - This is a mapping-only protocol: its explicit type discriminator selects local executable configuration, it declares no URI schemes, and portable URI/QR export may return no result. Shared import/export UI must preserve that capability absence. Endpoint readiness checks the configured proxy; it does not validate an arbitrary - executable's remote service. + executable's remote service. Endpoint metadata does not configure the executable or cause it to open a listener; + users remain responsible for matching that metadata to the executable's own configuration. - 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 diff --git a/Furious/Backends/Hysteria1/AGENTS.md b/Furious/Backends/Hysteria1/AGENTS.md index f695e2c..8684971 100644 --- a/Furious/Backends/Hysteria1/AGENTS.md +++ b/Furious/Backends/Hysteria1/AGENTS.md @@ -1,21 +1,18 @@ # Hysteria 1 guidance Inherit the root, package, and common backend guides; consult Plugins for capability contracts. This scope exists to -preserve Hysteria 1's legacy flat schema and lifecycle -without importing assumptions from Hysteria 2. +preserve Hysteria 1's legacy flat schema and lifecycle without importing assumptions from Hysteria 2. - 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. +- Preserve tolerated legacy types, upstream field names, absent defaults, and unknown combo values through mapping + and untouched-editor round trips. URI round trips cover supported share-link fields only. Explicit user edits may + normalize the represented field; runtime validation may reject values that observational loading must preserve. - 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. -- Treat tolerated legacy values as input compatibility, not as permission to rewrite the persisted document during - inspection. Runtime validation may reject what observational editor loading must still preserve. - 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. diff --git a/Furious/Backends/Hysteria2/AGENTS.md b/Furious/Backends/Hysteria2/AGENTS.md index b428b8e..b35c29c 100644 --- a/Furious/Backends/Hysteria2/AGENTS.md +++ b/Furious/Backends/Hysteria2/AGENTS.md @@ -1,8 +1,7 @@ # Hysteria 2 guidance Inherit the root, package, and common backend guides; consult Plugins for capability contracts. This scope owns -Hysteria 2's nested upstream document, native-TUN -capability, statistics, and editor projection. +Hysteria 2's nested upstream document, native-TUN capability, statistics, and editor projection. ## Native document and editor projection @@ -24,12 +23,13 @@ capability, statistics, and editor projection. - 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 - from merely having a running Hysteria2 process. + from merely having a running Hysteria2 process. The configured server statistics target is separate from the + client's local readiness endpoint; capability availability does not imply a usable target was configured. - Capability presence is independent: native TUN, statistics, actions, settings, routing, and protocol editing must continue to work or fail through their own declared contracts rather than being inferred from the runtime type. - 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 + projection preservation, 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. Start with `tests/test_hysteria2_compatibility.py`, `tests/test_native_tun_semantics.py`, and `tests/test_backend_editor_contract.py`. diff --git a/Furious/Backends/Xray/AGENTS.md b/Furious/Backends/Xray/AGENTS.md index 79cb4c7..1c37de5 100644 --- a/Furious/Backends/Xray/AGENTS.md +++ b/Furious/Backends/Xray/AGENTS.md @@ -1,8 +1,7 @@ # Xray guidance Inherit the root, package, and common backend guides; consult Plugins for capability contracts. This scope owns Xray's -full JSON preservation, routing/assets/statistics, -and protocol/transport/TLS projections. +full JSON preservation, routing/assets/statistics, and protocol/transport/TLS projections. ## Full-document preservation @@ -23,8 +22,8 @@ and protocol/transport/TLS projections. malformed TUN and suppresses tun2socks. Proxy/download preparation replaces inbounds with its test surface. Verify the prepared document rather than assuming `proxyModeOnly` alone removes user TUN from every factory input. - 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. + Action providers retain reusable routing/asset windows through the created action owner and create transient + settings dialogs per request; the capability registry does not become a transient-window owner. - Runtime asset updates stage bytes and digest verification before atomic replacement. Failure preserves the prior 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. diff --git a/Furious/Controllers/AGENTS.md b/Furious/Controllers/AGENTS.md index 4a22802..b59c527 100644 --- a/Furious/Controllers/AGENTS.md +++ b/Furious/Controllers/AGENTS.md @@ -1,22 +1,23 @@ # Controller guidance Inherit the root and package guides. This scope preserves controllers as process-lifetime authorities for shared -transitions, not owners of execution resources or presentation objects. +transitions. Services own execution resources; existing prompts are presentation compatibility paths. ## 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. + and publish structured Qt signals. New behavior delegates presentation and execution resources to their owners; + existing host-setting prompts do not justify moving network replies, core processes, or pools into controllers. - `ConnectionController` is the sole connection state machine. A GUI start remains `Connecting` while one - generation- checked `ConnectionManager` transaction acquires readiness/TUN resources. The selected live profile is + generation-checked `ConnectionManager` transaction acquires readiness/TUN resources. The selected live profile is exposed during `Connecting`; successful runtime commit precedes System Proxy setup and `Connected`. Failure resets the active profile. 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. -- A startup completion must belong to the current controller generation before it can change state, active profile, - System Proxy, or interaction gating. Typed runtime failures keep their semantic reason; cancellation and supersession - are not rewritten as generic connection errors. +- The active live profile is not the prepared document used by an already-started runtime. Resolve identity and + generation before changing state or host effects, and preserve typed runtime failures; cancellation and supersession + 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 diff --git a/Furious/Core/AGENTS.md b/Furious/Core/AGENTS.md index 8010b6e..b67b998 100644 --- a/Furious/Core/AGENTS.md +++ b/Furious/Core/AGENTS.md @@ -1,8 +1,7 @@ # Embedded runtime guidance Inherit the root and package guides. Consult Interface for runtime contracts and Service for connection ownership. -This scope owns reusable embedded execution machinery and -application tun2socks, while connection policy remains outside it. +This scope owns reusable embedded execution machinery and application tun2socks; connection policy remains outside it. - `Core` supplies shared multiprocessing runtime machinery, bounded output transport, and application tun2socks. External Core owns its separate direct `subprocess.Popen`; neither layer owns controller, repository, UI, or protocol policy. @@ -19,7 +18,8 @@ application tun2socks, while connection policy remains outside it. - 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 - must not leave timers, callbacks, queues, or process handles alive. + must not leave timers, callbacks, queues, or process handles alive. Stopping execution is not QObject destruction: + disposal must also release monitors and output infrastructure, including for a runtime that was never started. - Verify invalid target/serialization, failed spawn, early exit, readiness compatibility, burst output bounds/backoff, normal and forced stop, repeated disposal, and absence of residual children, handles, timers, queues, or callbacks. Start with `tests/test_runtime_lifecycle.py` and `tests/test_connection_startup_async.py`; diff --git a/Furious/Data/AGENTS.md b/Furious/Data/AGENTS.md index c795ce1..860b24d 100644 --- a/Furious/Data/AGENTS.md +++ b/Furious/Data/AGENTS.md @@ -12,7 +12,8 @@ application-data or settings directory. - Markdown files in this directory are repository metadata, not runtime data. Keep top-level and nested Markdown files excluded consistently from setuptools package data and Nuitka inclusion while preserving them in the source tree. - `Deploy.py --download` performs a networked refresh and may rewrite large, time-varying assets. Run it only when that - mutation is explicitly in scope; review source, checksums, exact changed files, and existing user modifications. + mutation is explicitly in scope; inspect its actual integrity checks, provenance, exact changed files, and existing + user modifications. A backend's digest-verified runtime updater does not establish this build downloader's guarantees. ## Local endpoint map diff --git a/Furious/Extensions/AGENTS.md b/Furious/Extensions/AGENTS.md index 89653f9..aaf00b7 100644 --- a/Furious/Extensions/AGENTS.md +++ b/Furious/Extensions/AGENTS.md @@ -1,8 +1,7 @@ # Bundled extension guidance Inherit the root and package guides; consult Plugins for capability and registration contracts. This scope covers -host-shipped non-runtime plugins and must not gain -private authority merely because the code is bundled. +host-shipped non-runtime plugins and must not gain private authority merely because the code is bundled. - `Extensions` contains host-shipped plugins that are not proxy runtimes. They register through the same public API and lifecycle as entry-point plugins. New extension contracts must be usable without private @@ -15,7 +14,9 @@ private authority merely because the code is bundled. 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. Standard decoders opt into worker execution; that declaration covers - all shared parser state and caches, not merely absence of widgets in the immediate method. + 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. diff --git a/Furious/Externals/AGENTS.md b/Furious/Externals/AGENTS.md index ab77297..3aaf334 100644 --- a/Furious/Externals/AGENTS.md +++ b/Furious/Externals/AGENTS.md @@ -11,12 +11,13 @@ human-reviewed translations. extraction/update. It rebuilds source membership, drops stale keys, preserves reviewed target text, and reports collisions. Automatic translation is currently disabled: unresolved/unreviewed target values may be replaced with the source text. Review the diff before treating the command as a harmless refresh, especially with `--ignore`. -- Existing dictionary order is generally preserved; the generator does not enforce a universal field order and - source traversal can affect newly discovered entries. Keep diffs stable without claiming canonical sorting. +- 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. - Inspect the full diff. Preserve deliberate translations/review flags, HTML/newline semantics, and natural RU/ZH - meaning; mark an entry reviewed only after a human has verified it. Do not hand-maintain the generated `source` module - list. + 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. + Do not clear approved review flags or hand-maintain the generated `source` module list. ## Extractable source text diff --git a/Furious/Frozenlib/AGENTS.md b/Furious/Frozenlib/AGENTS.md index e80506d..edd2337 100644 --- a/Furious/Frozenlib/AGENTS.md +++ b/Furious/Frozenlib/AGENTS.md @@ -26,8 +26,9 @@ for unrelated application orchestration to accumulate in a broad helper namespac responsiveness review. - Own exact native threads/processes/handles and clear stale daemon references. Externally keyed caches are bounded and no cache/weak pool captures QObject instances or bound methods accidentally. -- `CleanupOnExit` and translation/theme/connection pools are registries, not owners. Their legacy de-duplication behavior - is a compatibility constraint; resource-owning repeated instances need an explicit owner/cleanup stage. +- `CleanupOnExit` and translation/theme/connection pools are weak registries, not owners. Cleanup normally + de-duplicates by type; repeated instances with separate resources require per-instance cleanup registration or an + explicit containing cleanup stage. Registry membership neither retains a wrapper nor proves every instance drained. - `AppResources.py` is generated from `Resources.qrc` and referenced assets. Change the manifest/input files and regenerate with the compatible PySide6 resource compiler; never hand-edit generated resource code. - Verify every affected OS branch with mocked host calls, plus persistence-on-failure, bounded cleanup, import-time diff --git a/Furious/Interface/AGENTS.md b/Furious/Interface/AGENTS.md index 8b49c73..5fd7079 100644 --- a/Furious/Interface/AGENTS.md +++ b/Furious/Interface/AGENTS.md @@ -24,7 +24,8 @@ satisfy without importing application composition or concrete backends. construction deliberately captures diagnostics; do not impose one blanket exception convention on those different contracts. - Runtime liveness is observational: querying it must not consume an exit, transfer ownership, or dispatch - callbacks. Keep semantic startup errors separate from raw process codes and readiness timeouts. + 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. - 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 diff --git a/Furious/Models/AGENTS.md b/Furious/Models/AGENTS.md index 3d91d33..6b8c84d 100644 --- a/Furious/Models/AGENTS.md +++ b/Furious/Models/AGENTS.md @@ -22,7 +22,8 @@ Qt presentation, plugin discovery, or workflow execution. - Profile ID, object identity, subscription source/key, connection fingerprint, display text, and row position answer different questions. Fingerprints cover only the connection document, not user metadata; they require deterministic JSON-compatible values and reject non-finite numbers. A metadata edit need not invalidate connection - testing. + testing. Equal fingerprints do not imply equal profile IDs: independently stored profiles may describe identical + connections. Do not merge their metadata, ownership, or selection merely to deduplicate execution work. - Subscription membership (`subscriptionSource`) and remote ownership (`subscriptionManaged` plus its matching key) are separate. Legacy migration may infer ownership where the flag was absent; current locally grouped profiles must remain local. Preserve that distinction through copies, moves, and metadata aliases. diff --git a/Furious/Plugins/AGENTS.md b/Furious/Plugins/AGENTS.md index a70a524..35e30c1 100644 --- a/Furious/Plugins/AGENTS.md +++ b/Furious/Plugins/AGENTS.md @@ -1,8 +1,7 @@ # Plugin guidance Inherit the root and package guides; consult Interface guidance for runtime/storage contracts. This scope owns -capability definitions, atomic registration, dispatch, -and plugin lifecycle; concrete backend policy remains in each implementation. +capability definitions, atomic registration, dispatch, and plugin lifecycle; backend policy remains in each implementation. ## Contracts and registry @@ -34,10 +33,10 @@ and plugin lifecycle; concrete backend policy remains in each implementation. state. Backend-specific defaults, settings keys, document branches, and host assumptions stay behind the provider rather than becoming undeclared registry requirements. - API-version-3 runtime factories return `PreparedRuntime` directly. The runtime is fully prepared before return, - starts with zero arguments, raises typed startup failures, and exposes readiness separately; do not add legacy - launch adapters, Boolean startup side channels, or alternate factory-result shapes. The registry's existing - synchronous `startCoreRuntime()` wrapper separately returns runtime/success for compatibility; preserve ownership - on start failure. + starts with zero arguments, raises typed startup failures, and exposes readiness separately. An alternate result + shape requires an explicit contract/version migration, not an implicit adapter inferred from built-in factories. + The registry's existing synchronous `startCoreRuntime()` wrapper separately returns runtime/success for + compatibility; preserve ownership on start failure. - `TUNPreparationError` is the explicit terminal native-TUN failure contract. Other provider exceptions currently log and return an unhandled result; required TUN rejection must use the typed error rather than assume all exceptions stop fallback. Optional capabilities may be absent; an External Core need not implement statistics or diff --git a/Furious/Qt/AGENTS.md b/Furious/Qt/AGENTS.md index 4af4809..9df7189 100644 --- a/Furious/Qt/AGENTS.md +++ b/Furious/Qt/AGENTS.md @@ -9,7 +9,8 @@ primitives; pages and services consume them without creating parallel registries ## Canonical presentation - 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. + 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. - 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 @@ -55,9 +56,13 @@ primitives; pages and services consume them without creating parallel registries - Top-level windows use canonical first-show preparation. Save geometry/state only after a native presentation; a never-shown Qt fallback must not overwrite persisted user geometry. Do not call overridable geometry hooks from constructors or manipulate private first-show state. +- A stylesheet border radius paints a rounded frame but does not clip child viewports or table headers. Padding + can protect the corners while introducing a visible inset; assess both effects before changing shared view styles. + Popup native-window transparency is a separate boundary from in-window child painting. - When behavior depends on focus, selection, proxy mapping, modifiers, shortcuts, queued delivery, animation, geometry, - or destruction, construct real widgets and use `QTest` plus the real event loop. Test semantic state and lifecycle, - not private coordinates or pixel-perfect screenshots. + or destruction, use real widgets, `QTest`, and the event loop. Prefer semantic assertions; for rendering defects, + test the affected border/background/alpha behavior under explicit themes and scale factors instead of relying on + selector counts or whole-window pixel equality. - For lifetime-sensitive changes, repeat open/close/accept/reject paths and assert destroyed signals, weak wrappers, registries, timers, callbacks, replies, threads, handles, and child counts return to baseline. Run a representative Nuitka probe when compiled callback retention or packaged-only behavior is part of the defect. diff --git a/Furious/Repository/AGENTS.md b/Furious/Repository/AGENTS.md index aa6d16f..8b3099b 100644 --- a/Furious/Repository/AGENTS.md +++ b/Furious/Repository/AGENTS.md @@ -19,6 +19,8 @@ This scope owns restoration, migration, ordering, and persistence; workflows and - 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. - Moving a profile between subscription displays does not automatically make it remotely managed; preserve the explicit distinction between local membership and synchronization ownership. - Verify legacy/current/unknown-field round trips, malformed roots, restore-failure preservation, ordering/stable diff --git a/Furious/Service/AGENTS.md b/Furious/Service/AGENTS.md index 02a4212..a537fe3 100644 --- a/Furious/Service/AGENTS.md +++ b/Furious/Service/AGENTS.md @@ -10,12 +10,14 @@ for lifetime primitives. This scope owns multi-stage workflows and temporary res still creates update dialogs as a compatibility path; preserve its public behavior until presentation is deliberately moved to a UI owner. - Give each QObject service, worker, reply, timer, pool, thread, runtime, process, cache, and callback context one durable - owner and bounded idempotent cleanup. Construct Qt services only after an application exists. + owner and explicit idempotent cleanup. Cancellation can suppress a result without stopping the underlying work; + distinguish deadline-bounded teardown from cooperative drains, and retain resources until their users finish. + Construct Qt services only after an application exists. - Inject repositories/providers/clients/runtime factories where practical. Stage results, prove freshness, and commit through the owning repository/controller rather than creating a parallel authoritative collection. - Every async workflow defines supersession and one terminal path. Generation/version or exact target identity rejects - stale completion; terminal cleanup aborts/finishes once, deletes replies/Qt objects in their owning thread, and cannot - retain a shut-down manager. + stale completion. Terminal cleanup runs once and deletes replies/Qt objects in their owning thread. Release callback + contexts when execution no longer needs them; late delivery must not revive a shut-down manager or mutate live state. ## Connection and network workflows @@ -39,9 +41,9 @@ for lifetime primitives. This scope owns multi-stage workflows and temporary res unclassified plugin parsers stay on the GUI compatibility path. The manager's synchronous shutdown closes admission, cancels work, and retains the pool/relay until workers finish. A slow-shutdown warning is diagnostic, not a deadline that permits destroying running workers; a non-returning plugin can still block shutdown. - Workers never read live repositories or Qt models; - the GUI thread verifies the full source signature and group revision, commits while preserving live profile - identity/local metadata, then publishes coalesced status/structure. Post-commit reconnect/test invalidation + Workers never read live repositories or Qt models. The GUI thread verifies the full source signature and group + revision, commits while preserving live profile identity/local metadata, then publishes coalesced status/structure. + Post-commit reconnect/test invalidation failure is reported without undoing the committed profiles. Here commit means live reconciliation; repository flush and status persistence are separate boundaries, not one disk transaction. - Provider-reported subscription usage/expiry metadata is untrusted advisory input. Parse it with strict bounds at the diff --git a/Furious/Utility/AGENTS.md b/Furious/Utility/AGENTS.md index 59c6366..6e22fd0 100644 --- a/Furious/Utility/AGENTS.md +++ b/Furious/Utility/AGENTS.md @@ -17,9 +17,9 @@ general-purpose utility bucket. - 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. -- Fallback presentation runs in the parent after a nonzero child result and does not rerun normal application - startup. Preserve the original result when evolving error-reporting failures rather than adding another - supervisor. +- 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. - 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. diff --git a/Furious/Widget/AGENTS.md b/Furious/Widget/AGENTS.md index 9bb65df..acc83ce 100644 --- a/Furious/Widget/AGENTS.md +++ b/Furious/Widget/AGENTS.md @@ -1,8 +1,8 @@ # Reusable widget guidance Inherit the root and package guides; consult `Furious/Qt/AGENTS.md` for shared lifetime/presentation contracts. This -scope covers reusable controls and model/view adapters below page -composition; it does not own application workflows. +scope covers reusable controls and model/view adapters below page composition. Persistent widgets currently host +some service owners; that construction detail does not make every view an independent workflow authority. ## Presentation and identity @@ -29,6 +29,11 @@ composition; it does not own application workflows. - Model notifications describe the real source mutation. Structural replacement may legitimately use a model reset; metadata-only test results should update the exact cell. Do not use resets/full repaints to mask broken mapping or missing identity restoration. Test selected identities and the current keyboard index independently. +- Bulk profile mutations validate/prepare a batch before beginning structural notifications. Resolve captured IDs + again after confirmation and between deferred batches, report actual source ranges, and preserve activation before + observers see completed removal. Forward bulk insert/delete operations through the model instead of replaying a + single-item notification/reconciliation path for every profile. Small direct operations and deferred large ones + share these identity rules; batch yields and throttled progress updates serve different responsiveness purposes. - Endpoint lookup belongs to `EndpointInfoService`; the map renders validated results and has a no-WebEngine fallback. Optional WebEngine import failure must not prevent importing the widget/package, and hidden presentation must not retarget a queued lookup. diff --git a/Furious/Window/AGENTS.md b/Furious/Window/AGENTS.md index f14a5e5..631a183 100644 --- a/Furious/Window/AGENTS.md +++ b/Furious/Window/AGENTS.md @@ -1,14 +1,14 @@ # Window and page guidance Inherit the root and package guides. Consult Qt/Widget for presentation and Controllers/Service for shared owners. -This scope owns persistent page composition and -top-level presentation, not shared domain state. +This scope owns persistent page composition and top-level presentation, not shared domain state. ## 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. + 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. diff --git a/Icons/AGENTS.md b/Icons/AGENTS.md index 6df6c49..1973936 100644 --- a/Icons/AGENTS.md +++ b/Icons/AGENTS.md @@ -5,8 +5,9 @@ resource-manifest contract; it does not govern general UI layout. - Reuse an existing semantic icon before introducing a new asset. SVG sources stay compact vectors without scripts, remote resources, embedded rasters, editor metadata, or hard-coded page backgrounds. -- Follow the established monochrome/current-color convention so the shared `AppQ*` presentation layer can tint icons. - Add a theme-specific variant only when semantic tinting cannot express the design, and do not rely on color alone. +- Use the shared icon helpers and the bundled monochrome/default and white variants as appropriate. An SVG's + `currentColor` alone does not establish Qt theme behavior; verify how `Furious/Qt/QtGui.py` resolves and masks the + chosen asset. Reuse that path instead of adding control-specific recoloring, and do not rely on color alone. - Preserve license/provenance and the `Resources.qrc` alias contract. Any add, removal, rename, or alias change updates all consumers and the manifest, then regenerates `Furious/Frozenlib/AppResources.py` with the selected environment's `pyside6-rcc Resources.qrc -o Furious/Frozenlib/AppResources.py`. Never hand-edit generated resource diff --git a/tests/AGENTS.md b/tests/AGENTS.md index 590e838..66bcec1 100644 --- a/tests/AGENTS.md +++ b/tests/AGENTS.md @@ -15,6 +15,8 @@ and test-tier selection; test convenience never weakens a production invariant. hermetic child, temporary settings, disabled singleton/tray/restoration, and mocked host mutation. - Import order is part of isolation: select the offscreen Qt platform and temporary settings identity before importing modules that can create Qt/application globals. A late patch is not equivalent to preventing the side effect. + A temporary QSettings namespace does not reset already-cached `Storage` collections: explicitly isolate and restore + live repository fixtures as well as persisted settings, especially when exercising cleanup or partial startup. ## Test the contract @@ -28,6 +30,8 @@ and test-tier selection; test convenience never weakens a production invariant. duplicate endpoints, bounded scheduling, and unrelated-work preservation rather than relying on row positions. - Qt behavior involving focus, selection, proxy mapping, shortcuts, queued delivery, geometry, animation, or destruction uses real widgets and `QTest`. Localized-text tests choose an explicit language inside `isolatedSettings()`. + 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. @@ -41,8 +45,9 @@ and test-tier selection; test convenience never weakens a production invariant. - 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. -- Benchmarks report scale and latency but are not correctness gates. Keep deterministic scale assertions in normal or - stress tests and avoid machine-dependent elapsed-time thresholds unless the test is explicitly diagnostic. +- Separate deterministic correctness/scale assertions from performance measurements. Opt-in stress tests may gate + relative scaling or resource bounds; document the measured contract and environment rather than treating one + machine's absolute timing as a portable product requirement. - Update `tests/README.md` when coverage ownership, modules, commands, tiers, opt-ins, or environment requirements change. The final unittest status and process exit code are authoritative even when negative paths intentionally log errors. - Review new tests for production-state mutation, live network dependence, process-name cleanup, unbounded waits,