diff --git a/AGENTS.md b/AGENTS.md index c720e44e..185accef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,22 +15,23 @@ - Prefer the simplest design that makes ownership, state transitions, failure, and side effects explicit. Readability and one canonical path beat clever indirection or parallel implementations. -- Keep policy close to the layer that owns it: models describe data, repositories persist it, services perform - workflows, controllers own application state/orchestration, plugins/backends own protocol-specific behavior, and UI - adapts those APIs. +- Keep policy close to the layer that owns it: models describe data, repositories persist domain collections, + `AppSettings` persists preferences, services perform workflows, controllers own shared runtime state/orchestration, + plugins/backends own protocol-specific behavior, and UI adapts those APIs. - Make invalid states and boundary failures visible with specific return values, result objects, or exceptions. Catch broadly only at a genuine isolation boundary, log actionable context, and do not silently convert explicit user input into a different behavior. -- Bound external work: network requests, subprocess startup/shutdown, thread joins, and host commands need timeouts or a - documented non-GUI execution context. Cleanup must be idempotent and own exact resources, never search by process - name. +- Bound external work where the workflow requires responsiveness: network requests, subprocess startup/shutdown, + thread joins, and host commands need caller-chosen timeouts or a documented non-GUI execution context. Low-level + wrappers such as `runExternalCommand()` intentionally do not invent a universal timeout. Cleanup must be idempotent, + own exact resources, and never search by process name. - Prefer immutable metadata, pure transformations, dependency injection, and explicit runtime copies. Avoid global mutable state, hidden mutation, duplicated caches, and UI-owned business state. ## Repository invariants -- Treat persisted user configuration as input. Connection, routing, testing, logging, and statistics preparation operate - on explicit runtime copies unless an API is documented as mutating storage. +- Treat persisted user configuration as input. Connection, routing, testing, logging, TUN, and statistics preparation + must not mutate it implicitly; use explicit runtime/derived state unless an API is documented as mutating storage. - Prefer plugin capabilities/factories over protocol or core conditionals in shared managers. Registries store classes, factories, descriptors, and immutable metadata—not transient UI instances. - `CoreRuntime` means one managed proxy-core lifecycle regardless of whether its implementation uses a subprocess, diff --git a/Furious/AGENTS.md b/Furious/AGENTS.md index 97bba8d6..638f5c49 100644 --- a/Furious/AGENTS.md +++ b/Furious/AGENTS.md @@ -2,9 +2,10 @@ ## Layering and state -- `Models` and `Interface` define core-neutral data and contracts. `Repository` owns persistence, `Service` owns - workflows/resources, `Controllers` own shared application state, `Plugins`/`Backends` own protocol behavior, and - `Application` composes the runtime. `Qt`, `Widget`, and `Window` present that state. +- `Models` and `Interface` define core-neutral data and contracts. `Repository` owns persisted domain collections, + `AppSettings` owns preferences, `Service` owns workflows/resources, `Controllers` own shared runtime state, + `Plugins`/`Backends` own protocol behavior, and `Application` composes them. `Qt`, `Widget`, and `Window` present that + state. - Existing UI code has compatibility paths that reach repositories or application globals. Do not extend that coupling when a controller/service API can be introduced cleanly; migrate incrementally rather than creating a second state authority. diff --git a/Furious/Application/AGENTS.md b/Furious/Application/AGENTS.md index 02a4aa85..f1e1182e 100644 --- a/Furious/Application/AGENTS.md +++ b/Furious/Application/AGENTS.md @@ -1,7 +1,8 @@ # Application composition guidance -- `DesktopApplication` is the composition root. It creates and durably owns application-lifetime controllers, - repositories, services, pages, main window, tray, thread pool, IPC server, and plugin registry integration. +- `DesktopApplication` is the composition root. It creates or acquires and durably owns application-lifetime + controllers, repository access, services, pages, main window, tray, thread pool, singleton IPC endpoint, and plugin + registry integration. - Keep bootstrap order explicit: environment/plugins and storage before consumers, controllers/services before UI, and restoration only after all dependencies exist. Accessors must tolerate partial startup and cleanup. - Each successful startup stage registers its exact cleanup immediately. Partial startup and final shutdown use the diff --git a/Furious/Externals/AGENTS.md b/Furious/Externals/AGENTS.md index 1b4d2f77..370e8fa7 100644 --- a/Furious/Externals/AGENTS.md +++ b/Furious/Externals/AGENTS.md @@ -4,8 +4,8 @@ or the translation data and regenerate. - Each catalog entry uses this key order: `source`, supported language keys in the generator's canonical order, then `isReviewed`. -- `source` is a sorted, deduplicated list of fully qualified Python module names that contain the extracted source text. - Remove stale sources through regeneration, not manual cleanup. +- `source` is a deduplicated list of fully qualified Python module names discovered by the generator. Preserve generated + ordering and remove stale sources through regeneration, not manual cleanup. - `_()`/`gettext()` extraction accepts static literals. The only f-string exception consists exclusively of bare names defined in `Furious.Frozenlib.Constants`; the extractor substitutes those values before catalog lookup. - Do not put runtime values, attribute expressions, calls, format specifications, `.format(...)`, or ordinary brace diff --git a/Furious/Frozenlib/AGENTS.md b/Furious/Frozenlib/AGENTS.md index cdf04341..96376f59 100644 --- a/Furious/Frozenlib/AGENTS.md +++ b/Furious/Frozenlib/AGENTS.md @@ -11,7 +11,9 @@ ## Platform and process safety - Host mutation (proxy, DNS, startup registration, session, routing) is platform-isolated, returns/logs actionable - failure, uses bounded commands/joins, and can be fully mocked. Never test against real host state. + failure, and can be fully mocked. `runExternalCommand()` intentionally delegates timeout policy to each caller; + callers that require bounded execution must pass a timeout or run in a documented non-GUI context. Never test against + real host state. - Own exact daemon threads/processes. Clear dead references so restart is possible; cleanup is bounded and idempotent. Do not suppress a failed shutdown or leave persisted state claiming success. - `parseHostPort` and other externally keyed caches must be bounded. Unbounded caches are limited to finite application @@ -29,6 +31,7 @@ ## Code review rules -- Flag GUI/high-level imports, unbounded host commands or joins, state persisted after host failure, broad process-name - cleanup, sensitive logging, unbounded external-input caches, and globals holding transient objects. +- Flag GUI/high-level imports, caller paths that can block the GUI or shutdown without an intentional bound, state + persisted after host failure, broad process-name cleanup, sensitive logging, unbounded external-input caches, and + globals holding transient objects. Do not add a universal timeout to `runExternalCommand()`. - Run direct mocked platform/helper tests plus affected controller/service tests. diff --git a/Furious/Interface/AGENTS.md b/Furious/Interface/AGENTS.md index af4edfd1..a32b34f1 100644 --- a/Furious/Interface/AGENTS.md +++ b/Furious/Interface/AGENTS.md @@ -8,8 +8,8 @@ callback order, serialization behavior, and bounded stop expectations. - Do not introduce mechanism-specific aliases for `CoreRuntime` or mistake the semantic runtime contract for an operating-system process. -- Serialization uses the shared `Furious.Models` encoders. Preserve supported dict subclasses such as `CoreConfiguration`; - return/raise behavior must be documented and failures must retain useful diagnostics. +- Serialization uses the shared `Furious.Models` encoders. Preserve supported dict subclasses such as + `CoreConfiguration`; return/raise behavior must be documented and failures must retain useful diagnostics. - Storage contracts intentionally expose live mutable collections. State that explicitly—do not label them copies—and keep persistence/ordering semantics in concrete repositories. - Editor bindings translate between widgets and configuration but do not decide process/runtime policy. diff --git a/Furious/Qt/AGENTS.md b/Furious/Qt/AGENTS.md index 70e3c4c0..80d7ef26 100644 --- a/Furious/Qt/AGENTS.md +++ b/Furious/Qt/AGENTS.md @@ -37,9 +37,10 @@ Use the `manage-qt-pyside6-lifetimes` skill for any Qt ownership or lifecycle ch ## Network replies and presentation -- Give each reply one manager/context owner, reject stale generations, handle success/error/abort exactly once, and call - `deleteLater()` on every terminal path. Do not attach ad-hoc application attributes to third-party Qt objects when a - manager mapping suffices. +- Give each reply one manager/context owner. Where a newer request supersedes an older one, use a generation/version or + equivalent identity check; independent requests do not need a synthetic generation. Handle success/error/abort once + and call `deleteLater()` on every terminal path. Do not attach ad-hoc application attributes to third-party Qt + objects when a manager mapping suffices. - Preserve keyboard, focus, shortcuts, accessibility, light/dark theme, layout responsiveness, and translated-text growth. diff --git a/Furious/Repository/AGENTS.md b/Furious/Repository/AGENTS.md index 4debca7b..b805e9d0 100644 --- a/Furious/Repository/AGENTS.md +++ b/Furious/Repository/AGENTS.md @@ -1,7 +1,8 @@ # Repository guidance -- Repositories are the only persistence authority for profiles, subscriptions, routing, and TUN settings. Keep - Qt/UI/workflow concerns out of repository implementations. +- Repositories are the persistence authority for domain collections and documents such as profiles, subscriptions, + routing configurations, and TUN settings. Application preferences and current selections may use `AppSettings` at + their owning controller/application boundary. Keep Qt/UI/workflow concerns out of repository implementations. - Preserve stable IDs, ordering, unknown compatible fields, legacy migrations, and subscription ownership. Display names and row indexes are not identities. - Subscription synchronization may update only profiles explicitly managed by that subscription and identified by stable diff --git a/Furious/Service/AGENTS.md b/Furious/Service/AGENTS.md index 4b8d4496..473c6401 100644 --- a/Furious/Service/AGENTS.md +++ b/Furious/Service/AGENTS.md @@ -20,10 +20,11 @@ ## Async, network, and background work -- Each asynchronous request has an explicit generation/context. Partial results may publish independently, while - stale/aborted replies are ignored and deleted exactly once. -- Timeouts apply to network, DNS, executor, process, and host work. Executor callbacks must not retain a manager forever - after shutdown; GUI updates cross via signals. +- Each asynchronous workflow defines one explicit ownership and supersession policy: a generation/version where stale + completion is possible, or exact reply/future ownership where requests are independent. Partial results may publish + independently; terminal reply paths abort or finish once and schedule deletion once. +- Bound network, DNS, process, host, and worker work where the provider permits it. Executor callbacks use weak or + otherwise bounded ownership and must not retain a manager forever after shutdown; GUI updates cross via signals. - Logging and metrics collect while pages are hidden but avoid hidden-page rendering. Raw time-series samples are immutable; stable timestamp buckets are derived display data. - Log retention is owned by `LogManager`, not a text document. Category pruning/reset notifications must keep lazy UI diff --git a/Furious/Widget/AGENTS.md b/Furious/Widget/AGENTS.md index e328148b..3e9e6824 100644 --- a/Furious/Widget/AGENTS.md +++ b/Furious/Widget/AGENTS.md @@ -7,12 +7,14 @@ - Models, delegates, menus, actions, spinners, animations, timers, and network-backed helpers need explicit owners. Persistent page widgets are constructed once; refresh/show cycles toggle state rather than recreate/connect indefinitely. -- Table selection operates on stable repository IDs, not visual rows after sort/filter. Keep model begin/end - notifications, timer collections, and repository order synchronized. +- Resolve table/list actions through the model mapping that is current after sort/filter. Use stable repository IDs for + persisted or cross-refresh identity; preserve existing row-index compatibility only where the repository contract + still requires it. Keep model begin/end notifications and repository ordering synchronized. - Use `AppQ*` controls and responsive layouts. Preserve translated-text growth, shortcuts, focus, accessibility, theme changes, high-DPI rendering, and hidden-page lazy behavior. -- Expensive parsing, syntax highlighting, map/network work, metrics aggregation, and subscription synchronization must - not freeze the GUI. Publish results through owned signals and reject stale generations. +- Expensive parsing, map/network work, metrics aggregation, and subscription synchronization must not freeze the GUI. + Batch, defer, or offload work according to the Qt API involved; publish worker results through owned signals and + reject stale completions where requests can be superseded. - Transient editors/progress dialogs use managed `open()` lifetime; reusable top-level windows retain one explicit owner. diff --git a/tests/AGENTS.md b/tests/AGENTS.md index e379b3a2..f6a0fc78 100644 --- a/tests/AGENTS.md +++ b/tests/AGENTS.md @@ -38,8 +38,8 @@ event loop, request shutdown through the public path, and assert the child process exits normally. Repeat the cycle when the defect is intermittent. - A lifecycle child must be hermetic: bypass single-instance discovery and IPC, use temporary settings and application - identity where relevant, disable tray and startup restoration, mock all host/network integrations, and never attach to, - signal, inspect, or change a potentially running Furious instance. + identity where relevant, disable tray and startup restoration, mock all host/network integrations, and never attach + to, signal, inspect, or change a potentially running Furious instance. - Child-process tests own only the windows, threads, handles, and processes they create. Give every wait and child a bounded timeout, capture diagnostics, and terminate only that exact child on timeout. Never use process-name cleanup. - Visible diagnostic windows are for an explicit manual smoke procedure only. Automated tests always use the offscreen