diff --git a/AGENTS.md b/AGENTS.md index ad6f947..e49f478 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,17 @@ call/runtime path; implement at the owning boundary; test real behavior; then re-evaluate the architectural model. - When guidance says A and code appears to do B, inspect the call path and tests. Decide whether B is intentional evolution, compatibility debt, or a bug; preserve the intended invariant and update either code or the narrowest - applicable guidance. Do not encode speculation, experiments, or incidental class names as durable rules. + applicable guidance. Never resolve the contradiction by deleting the scoped guidance file. Do not encode speculation, + experiments, or incidental class names as durable rules. + +## Preserve the guidance hierarchy + +- Every existing `AGENTS.md` and `AGENTS.override.md` path is an established documentation scope. During ordinary + guidance maintenance, do not delete, rename, relocate, merge, consolidate, or change the kind of any existing file. + Improve a seemingly redundant scope in place by making its inherited and local rules more precise. +- Add a new AGENTS file only when verified architecture has a durable uncovered scope that no existing file can + represent. A new scope never makes an existing one disposable. Keep override files explicit about which inherited + assumption they replace and why. ## Operating model @@ -81,11 +91,13 @@ ## Maintaining this guidance -- AGENTS files contain durable decision rules, not inventories or frozen recipes. Update guidance only when supported by +- AGENTS files are maintained architectural memory, not immutable truth. Update durable rules only when supported by 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 rules and distinguish preferred architecture from compatibility paths. + 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. Do not update AGENTS for temporary implementation + 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. diff --git a/Furious/AGENTS.md b/Furious/AGENTS.md index 536732b..889b5fe 100644 --- a/Furious/AGENTS.md +++ b/Furious/AGENTS.md @@ -1,5 +1,8 @@ # Furious package guidance +Inherit repository-wide rules from the root `AGENTS.md`. This file preserves the package-level boundary between +domain, persistence, orchestration, platform integration, and presentation; nested guides specialize it in place. + ## Responsibility boundaries - `Application` is the composition root. Elsewhere depend on the narrowest model, repository, service, controller, or @@ -49,4 +52,5 @@ - Read the applicable specialized guide for application composition, embedded core processes, platform helpers, repositories, plugins, services, backends, Qt ownership, translations, or bundled data. A missing child guide means - this file and the root guide are sufficient; do not recreate one merely to restate them. + this file and the root guide are sufficient; do not recreate one merely to restate them. Existing child guides are + established scopes: clarify inheritance or local invariants rather than deleting or consolidating them. diff --git a/Furious/Actions/AGENTS.md b/Furious/Actions/AGENTS.md index bb62d16..0741ae6 100644 --- a/Furious/Actions/AGENTS.md +++ b/Furious/Actions/AGENTS.md @@ -1,5 +1,8 @@ # Action guidance +Inherit the root and `Furious/AGENTS.md`; this scope adds rules for translating user gestures into owned commands and +presentation without becoming a workflow authority. + ## Command boundary - Actions adapt one user command to presentation. Resolve live controller/repository state when triggered, delegate the @@ -20,6 +23,9 @@ 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. Yield large GUI insertions or + QR rendering in bounded event-loop batches, reject callbacks after cancellation/destruction, and publish output only + while the operation context and its owned snapshot remain current. - Verify command state and delegation, cancellation/error presentation, shortcut scope in the real focused widget, menu rebuild cleanup, and repeated dialog/capture/action lifetimes. When this command boundary changes intentionally, update this guide and remove superseded compatibility wording in the same change. diff --git a/Furious/Application/AGENTS.md b/Furious/Application/AGENTS.md index 480570c..a138250 100644 --- a/Furious/Application/AGENTS.md +++ b/Furious/Application/AGENTS.md @@ -1,11 +1,17 @@ # Application composition guidance +Inherit the root and package guides. This scope owns process-lifetime Qt composition and the boundary between the outer +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. - 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. +- Register cleanup immediately after each successful acquisition, before the next fallible stage. Cleanup code must + tolerate a partially composed application and must not assume later repositories, controllers, UI, tray, or host + integration were created. - Singleton election is atomic: serialize candidates, re-probe after waiting, recover only a confirmed stale endpoint, and fail closed when ownership is uncertain, including privilege handoff. - Native session callbacks cross to the GUI thread before touching Qt-owned state. Tray, dock, System Proxy daemon, diff --git a/Furious/Backends/AGENTS.md b/Furious/Backends/AGENTS.md index d652570..18667cf 100644 --- a/Furious/Backends/AGENTS.md +++ b/Furious/Backends/AGENTS.md @@ -1,5 +1,8 @@ # Backend guidance +Inherit the root, package, plugin, model, and service contracts. This scope adds rules shared by all bundled proxy +backends without making the richest backend the generic default. + ## Common backend contract - A backend plugin owns its configuration/document types, parsing/export, validation, editor factories, runtime factory, @@ -24,6 +27,9 @@ than permission to 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. +- 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. ## Backend scopes diff --git a/Furious/Backends/ExternalCore/AGENTS.md b/Furious/Backends/ExternalCore/AGENTS.md index 75ed86b..ef6f6b4 100644 --- a/Furious/Backends/ExternalCore/AGENTS.md +++ b/Furious/Backends/ExternalCore/AGENTS.md @@ -1,5 +1,8 @@ # External Core guidance +Inherit the backend and plugin rules. This file preserves the intentionally different direct-subprocess scope for +user-selected executables. + ## Structured executable boundary - External Core represents one user-selected local executable, not an embedded protocol binding. Keep executable path, @@ -15,6 +18,8 @@ - One runtime owns its exact `Popen`, stdout/stderr pipes and readers, watcher, partial-line buffer, exit callback, and reaping path. Shutdown terminates that process, uses only platform-specific escalation for its PID when necessary, kills as a last resort, joins readers, and remains bounded and idempotent after partial startup. +- Keep execution liveness, configured proxy endpoints, and semantic readiness distinct. An immediate or later exit is + interpreted once at this runtime boundary and retains actionable code/reason context for the shared startup workflow. - Application tun2socks is an explicit profile capability. It requires a usable SOCKS endpoint and a separate remote server address for bypass routing; an executable path is never a network destination, and this backend never invents native core TUN support. Subscription decoding must continue to reject executable profiles. diff --git a/Furious/Backends/Hysteria1/AGENTS.md b/Furious/Backends/Hysteria1/AGENTS.md index 7aff971..bda7549 100644 --- a/Furious/Backends/Hysteria1/AGENTS.md +++ b/Furious/Backends/Hysteria1/AGENTS.md @@ -1,5 +1,8 @@ # Hysteria 1 guidance +Inherit the common backend and plugin rules. This scope exists to 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 @@ -10,6 +13,8 @@ - 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. - Verify legacy/current URI and mapping compatibility, unknown/tolerated values, stored-copy isolation, MMDB/ACL absence or malformed paths, asynchronous readiness and rollback, core-exit translation, application-TUN policy, and repeated editor/runtime cleanup. Revise this guide with an intentional schema evolution instead of freezing quirks. diff --git a/Furious/Backends/Hysteria2/AGENTS.md b/Furious/Backends/Hysteria2/AGENTS.md index f881cdb..4532b30 100644 --- a/Furious/Backends/Hysteria2/AGENTS.md +++ b/Furious/Backends/Hysteria2/AGENTS.md @@ -1,5 +1,8 @@ # Hysteria 2 guidance +Inherit the common backend and plugin rules. This scope owns Hysteria 2's nested upstream document, native-TUN +capability, statistics, and editor projection. + ## Native document and editor projection - The persisted Hysteria 2 client document is authoritative and is submitted to the embedded runtime. The GUI is a @@ -17,6 +20,8 @@ backend’s privilege and server-route-exclusion guarantees. Probe/download copies always remove native TUN. - Traffic-statistics targets, setting descriptors, and action providers are process-lifetime plugin capabilities; monitors, replies, dialogs, and runtimes created from them are request/transient objects and are never registry-owned. +- 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 verified upstream schema diff --git a/Furious/Backends/Xray/AGENTS.md b/Furious/Backends/Xray/AGENTS.md index 10297d4..98dea91 100644 --- a/Furious/Backends/Xray/AGENTS.md +++ b/Furious/Backends/Xray/AGENTS.md @@ -1,5 +1,8 @@ # Xray guidance +Inherit the common backend and plugin rules. This scope owns Xray's full JSON preservation, routing/assets/statistics, +and protocol/transport/TLS projections. + ## Full-document preservation - The complete Xray JSON document is authoritative. Protocol, transport, TLS, local-endpoint, logging, routing, and TUN @@ -20,6 +23,8 @@ - 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. +- Asset downloads stage bytes and digest verification before replacing the live file. A failed request, checksum, or + write leaves the prior usable asset intact and reports the failure without pretending an update succeeded. - Verify full-document and URI preservation, aliases and unknown values, runtime-copy isolation for routing/log/TUN/tests, multiple TUN inbounds, asset integrity/failure, statistics and process cleanup, compiled-safe UI callbacks, and repeated editor/window destruction. Update this scope when an upstream or plugin capability changes intentionally. diff --git a/Furious/Controllers/AGENTS.md b/Furious/Controllers/AGENTS.md index 092305c..6167282 100644 --- a/Furious/Controllers/AGENTS.md +++ b/Furious/Controllers/AGENTS.md @@ -1,5 +1,8 @@ # 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. + ## Shared state authorities - Controllers own process-lifetime shared state and transition policy. They coordinate injected repositories/services @@ -10,6 +13,9 @@ - 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. - `RoutingController` owns available capability options plus selected/persisted routing. Distinguish a newly selected repository profile from the profile snapshot already owned by a live connection; changes use controlled reconnect, not mutation of the running document. User-defined routing labels are semantic data, not translatable UI literals. diff --git a/Furious/Core/AGENTS.md b/Furious/Core/AGENTS.md index 5dc7287..78c0457 100644 --- a/Furious/Core/AGENTS.md +++ b/Furious/Core/AGENTS.md @@ -1,10 +1,16 @@ # Embedded runtime guidance +Inherit the root, package, interface, and service rules. This scope owns reusable embedded execution machinery and +application tun2socks, while 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. - A launch spec describes only validated child construction, never semantic connection readiness. Runtime preparation completes before construction; the asynchronous connection transaction observes endpoints/process survival and commits later. Keep any synchronous waiting isolated as an explicit compatibility path. +- `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 diff --git a/Furious/Data/AGENTS.md b/Furious/Data/AGENTS.md index 75dbb4b..9ea6273 100644 --- a/Furious/Data/AGENTS.md +++ b/Furious/Data/AGENTS.md @@ -1,5 +1,8 @@ # Bundled runtime data guidance +Inherit the root and package guides. This scope exists for shipped runtime assets and their provenance; it is not an +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 diff --git a/Furious/Extensions/AGENTS.md b/Furious/Extensions/AGENTS.md index c2aa2a0..75074ac 100644 --- a/Furious/Extensions/AGENTS.md +++ b/Furious/Extensions/AGENTS.md @@ -1,5 +1,8 @@ # Bundled extension guidance +Inherit the root, package, and plugin guides. This scope covers 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 and receive no private repository, controller, or UI side channel. - `StandardSubscriptionPlugin` owns format recognition and decoding only. A decoder returns an immutable neutral @@ -9,6 +12,9 @@ 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. +- 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. - 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 diff --git a/Furious/Externals/AGENTS.md b/Furious/Externals/AGENTS.md index 2b5a90e..a3e985f 100644 --- a/Furious/Externals/AGENTS.md +++ b/Furious/Externals/AGENTS.md @@ -1,5 +1,8 @@ # Translation catalog guidance +Inherit the root and package guides. This scope preserves the split between extracted catalog structure and +human-reviewed translations. + ## Source and generation contract - `Furious/Externals/GenTranslation.py` is generator-managed, but its language values and `isReviewed` flags are curated @@ -28,3 +31,5 @@ - Run extraction for every affected language, review collisions/stale removal/order and the catalog diff, then run it a second time to prove stability. Exercise runtime lookup and affected UI retranslation under explicit locales. +- Translation generation is a scoped repository mutation: do not run it as an incidental formatter, and do not accept + broad catalog churn without tracing each changed source literal or intentional stale-key removal. diff --git a/Furious/Frozenlib/AGENTS.md b/Furious/Frozenlib/AGENTS.md index 9f92e71..e0a8ac6 100644 --- a/Furious/Frozenlib/AGENTS.md +++ b/Furious/Frozenlib/AGENTS.md @@ -1,5 +1,8 @@ # Platform and compatibility guidance +Inherit the root and package guides. This scope contains compatibility and host-integration boundaries, not a license +for unrelated application orchestration to accumulate in a broad helper namespace. + - `Frozenlib` is the low-level settings, platform, compatibility, and broad export surface. Keep imports cheap, cross-platform, and free of application/UI construction; preserve curated wildcard exports until consumers and public-import tests migrate together. @@ -11,6 +14,9 @@ - Keep proxy, DNS, routing, TUN, startup registration, session callbacks, external commands, and platform detection here or behind a runtime boundary so tests can replace them completely. Windows, macOS, Linux, Flatpak, AppImage, and older platform paths are distinct capabilities; never generalize from the current host. +- A host mutation returns success only after the actual platform operation completed. The owning controller/service + decides rollback and persistence; low-level helpers do not silently update shared UI state or convert an unsupported + platform into a successful no-op. - 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. - Own exact native threads/processes/handles and clear stale daemon references. Externally keyed caches are bounded and diff --git a/Furious/Interface/AGENTS.md b/Furious/Interface/AGENTS.md index 16424ea..56ee576 100644 --- a/Furious/Interface/AGENTS.md +++ b/Furious/Interface/AGENTS.md @@ -1,11 +1,17 @@ # Interface guidance +Inherit the root and package guides. This file preserves dependency-light contracts that multiple implementations can +satisfy without importing application composition or concrete backends. + - This package defines dependency-light contracts shared across layers. It does not import Qt presentation, controllers, services, repositories, plugins, or concrete backends; a contract may depend on a small model/constant only when that does not trigger application construction or registration. - Contracts specify observable ownership, lifecycle, mutation, serialization, callback, and failure semantics. Search every representative implementation and contract test before changing one; an implementation may strengthen a guarantee but cannot silently weaken it. +- Keep versioned contract changes explicit. Reject unsupported shapes at the registration/boundary layer, update every + bundled implementation and compatibility export together, and avoid adapters that let two conflicting ownership + models coexist indefinitely. - `CoreRuntime` is mechanism-neutral: embedded multiprocessing, direct `subprocess`, or an in-process binding can satisfy it. It owns execution only: zero-argument start, passive liveness, typed terminal events, and bounded idempotent stop/dispose. Preparation, serialization, readiness, and startup transactions belong outside this contract. Bind its diff --git a/Furious/Models/AGENTS.md b/Furious/Models/AGENTS.md index d4ace15..36faad8 100644 --- a/Furious/Models/AGENTS.md +++ b/Furious/Models/AGENTS.md @@ -1,5 +1,8 @@ # Model guidance +Inherit the root and package guides. This scope owns dependency-light domain shape and identity, never live persistence, +Qt presentation, plugin discovery, or workflow execution. + ## Domain shape and identity - Models are core-neutral Python data and transformations. Do not import Qt, globals, repositories, services, @@ -11,6 +14,9 @@ subscription ownership/key, latency, speed, annotations, and local flags never become core-configuration fields. - Preserve unknown metadata and legacy aliases across load/save. `independentCopy()` creates a manual profile with a new ID and no subscription owner; a runtime `deepcopy()` preserves identity while isolating mutable preparation. +- Treat serialized and plugin-provided mappings as untrusted values. Normalize only documented compatibility aliases, + retain unknown forward-compatible fields, and keep construction diagnostics available without mutating repositories + or invoking a backend runtime. - `ensureProfile()` normalizes rather than clones: metadata arguments update an existing profile. Use an independent copy for a new stored item and a runtime copy when logical identity must survive without mutating persistence. - Profile ID, object identity, subscription source/key, connection fingerprint, display text, and row position answer diff --git a/Furious/Plugins/AGENTS.md b/Furious/Plugins/AGENTS.md index 28dbe7b..76ee743 100644 --- a/Furious/Plugins/AGENTS.md +++ b/Furious/Plugins/AGENTS.md @@ -1,5 +1,8 @@ # Plugin guidance +Inherit the root, package, and interface guides. This scope owns capability definitions, atomic registration, dispatch, +and plugin lifecycle; concrete backend policy remains in each implementation. + ## Contracts and registry - `Plugins.API` defines independently composable capabilities for protocols/editors, subscription decoding, runtime @@ -25,6 +28,9 @@ entry-point plugins; do not give bundled code hidden repository/UI side channels. - Evolve contracts additively when practical. Before a breaking change, inspect external discovery, compatibility exports, every bundled implementation, tests, and compiled inclusion; do not infer compatibility from built-ins alone. +- A capability contract is generic only when an external plugin can satisfy it without importing private application + 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. diff --git a/Furious/Qt/AGENTS.md b/Furious/Qt/AGENTS.md index ecb79de..1cc1a3a 100644 --- a/Furious/Qt/AGENTS.md +++ b/Furious/Qt/AGENTS.md @@ -3,6 +3,9 @@ Use the `manage-qt-pyside6-lifetimes` skill for QObject ownership, transient/reusable UI, signal retention, or packaged PySide6 lifetime work. +Inherit the root and package guides. This scope owns reusable Qt presentation, translation/theme behavior, and lifetime +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. @@ -37,6 +40,8 @@ PySide6 lifetime work. intentional. `AppQAction.callback` is strong by design, so the action owner cannot outlive the captured receiver. - Every `QNetworkReply` has one manager/context owner, one freshness rule, and one terminal deletion path. Do not attach ad-hoc attributes to third-party Qt objects or multiply timers/connections across show/hide cycles. +- Queued delivery never transfers ownership implicitly. The sender may finish before delivery, so callbacks resolve a + still-valid receiver and current generation in the receiver's Qt thread before touching widgets, models, or wrappers. ## Geometry and verification diff --git a/Furious/Repository/AGENTS.md b/Furious/Repository/AGENTS.md index f7736d1..3e13ba7 100644 --- a/Furious/Repository/AGENTS.md +++ b/Furious/Repository/AGENTS.md @@ -1,5 +1,8 @@ # Repository guidance +Inherit the root, package, interface, and model guides. This scope owns restoration, migration, ordering, and durable +collection commits; workflows and presentation remain outside it. + - Repositories restore, migrate, order, and persist profiles, subscriptions, routings, and TUN settings. They do not own network workflows, controller state, test schedulers, or presentation. - `Storage` owns one application-lifetime backend per collection and exposes live mutable collections for compatibility. @@ -12,6 +15,8 @@ - Stage fallible decode, migration, or reconciliation before deterministic mutation of the live collection. A subscription commit changes only that group: matched managed profiles retain stable object/profile identity and local metadata, removed profiles are marked stale, and indexes/order update atomically. +- Persistence is part of the repository commit contract, not evidence that later host/controller side effects succeeded. + Callers report post-commit failures separately and must not claim the durable mutation rolled back when it did not. - 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 3be7bd5..45775c8 100644 --- a/Furious/Service/AGENTS.md +++ b/Furious/Service/AGENTS.md @@ -1,5 +1,8 @@ # Service guidance +Inherit the root, package, model, repository, plugin, core, and Qt lifetime rules. This scope owns multi-stage workflows +and temporary resources, never durable collections, shared transition authority, or presentation. + ## Workflow ownership - Services own workflows and temporary resources; controllers own shared state, repositories own durable collections, @@ -33,6 +36,9 @@ Post-commit reconnect/test invalidation failure is reported without undoing the committed profiles. - 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 bounded ordered model; runtime-only clearing and retention cannot + block producers with unbounded synchronous traversal. Metrics sampling owns its worker/future generation and discards + results after disconnect, disablement, replacement, or shutdown. ## Profile testing @@ -53,3 +59,5 @@ - Cover success plus invalid, stale, superseded, timeout, cancellation, partial acquisition, hidden-page, reentrant, and repeated-shutdown paths. Assert current identity at write-back and exact cleanup of pools, threads, sockets, replies, timers, ports, runtimes, callbacks, and host mutations. +- Test pre-commit failure with unchanged live/persisted state separately from post-commit side-effect failure. Never use + a broad rollback assertion to conceal which boundary actually committed. diff --git a/Furious/Utility/AGENTS.md b/Furious/Utility/AGENTS.md index 46fc1ae..cfae2b9 100644 --- a/Furious/Utility/AGENTS.md +++ b/Furious/Utility/AGENTS.md @@ -1,5 +1,8 @@ # Outer process guidance +Inherit the root and package guides. This scope preserves the exact outer child-process/crash protocol and is not a +general-purpose utility bucket. + - `Utility` owns the child-side wrapper used by the outer application process and crash/exit translation. It is not a miscellaneous helper namespace and does not own application composition, repositories, runtimes, or UI policy. - `AppMainProcess` owns one exact Qt application child and one small synchronized crash-log result. Do not add a @@ -10,6 +13,9 @@ 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. +- Crash reporting transports only bounded diagnostic text and a semantic result from the owned child. Failure to render + or save the fallback report must not spawn another supervisor, mutate application state, or replace the original exit + status. - 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 bf3feb9..d6060ed 100644 --- a/Furious/Widget/AGENTS.md +++ b/Furious/Widget/AGENTS.md @@ -1,5 +1,8 @@ # Reusable widget guidance +Inherit the root, package, and Qt guides. This scope covers reusable controls and model/view adapters below page +composition; it does not own application workflows. + ## Presentation and identity - Widgets present state below pages/windows. Prefer explicit controller/service/repository inputs and do not add new @@ -22,6 +25,9 @@ - Models, delegates, headers, menus, actions, animations, spinners, WebEngine/map objects, timers, workers, and replies each need one owner. Persistent widgets connect once and refresh state; visibility may pause rendering/animation, not application-level log draining, traffic collection, or other service ownership. +- Model notifications describe the smallest real source mutation. Never use a reset or full repaint to hide incorrect + proxy/source mapping, stale indexes, or missing stable-identity restoration after insert, delete, move, filter, or + sort. - Verify sorted/filtered commands, notification ranges, identity-preserving move/delete, real keyboard focus and nested shortcuts, subscription/test cancellation, hidden-page rendering, exact cell updates, optional WebEngine fallback, and repeated cleanup to baseline. Update this guide when ownership moves; never move service orchestration back into diff --git a/Furious/Window/AGENTS.md b/Furious/Window/AGENTS.md index 0181e51..2749101 100644 --- a/Furious/Window/AGENTS.md +++ b/Furious/Window/AGENTS.md @@ -1,5 +1,8 @@ # Window and page guidance +Inherit the root, package, Qt, widget, controller, and service guides. 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 @@ -19,6 +22,9 @@ - Long-lived pages construct persistent controls, models, timers, services, and connections once. Page visibility may coalesce log/graph painting or deliberately gate a lazy endpoint lookup, but it never owns log collection/draining, traffic sampling, subscription schedules, or an already-started request. +- A page that creates a service must make its process-lifetime or page-lifetime ownership explicit and expose one + cleanup path through the containing window/application. Moving a service between pages must not duplicate schedules, + histories, requests, or controller connections during the transition. - One-shot editors/prompts use managed transient dialogs and weak compiled-safe continuations. Reusable windows such as the text editor and parent-owned settings dialogs retain one explicit owner, reset on reopen, and use normal close semantics; do not convert every top-level surface to delete-on-close or global retention. diff --git a/Icons/AGENTS.md b/Icons/AGENTS.md index c5f958d..7b4a95b 100644 --- a/Icons/AGENTS.md +++ b/Icons/AGENTS.md @@ -1,5 +1,8 @@ # Icon source guidance +Inherit repository-wide rules from the root `AGENTS.md`. This top-level scope governs icon source/provenance and the +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. @@ -7,5 +10,7 @@ - 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 compatible PySide6 resource compiler. Never hand-edit generated resource code. +- 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. - 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. diff --git a/tests/AGENTS.md b/tests/AGENTS.md index 0f7722c..b295298 100644 --- a/tests/AGENTS.md +++ b/tests/AGENTS.md @@ -1,5 +1,8 @@ # Furious test guidance +Inherit repository-wide rules from the root `AGENTS.md`. This scope specializes isolation, evidence, resource ownership, +and test-tier selection; test convenience never weakens a production invariant. + ## Isolation is a product invariant - Tests must not affect a running Furious instance, production settings/data, desktop windows, tray, system proxy, DNS, @@ -10,6 +13,8 @@ cleanup targets only those resources. Normal suites require neither network access nor installed proxy cores. - Tests may exercise real Qt event loops, subprocesses, and compiled probes when that boundary is the defect, but use a 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. ## Test the contract @@ -30,6 +35,8 @@ - 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. +- 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. - 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, shared