From af8e5a5205c9927725bad05abd9c9003e31501b0 Mon Sep 17 00:00:00 2001 From: Loren Eteval Date: Thu, 8 Oct 2026 17:38:59 +0800 Subject: [PATCH] Refine repository guidance Signed-off-by: Loren Eteval --- .github/AGENTS.md | 3 +++ AGENTS.md | 11 ++++++++--- Furious/AGENTS.md | 2 ++ Furious/Actions/AGENTS.md | 3 ++- Furious/Application/AGENTS.md | 4 +++- Furious/Backends/AGENTS.md | 4 +++- Furious/Backends/ExternalCore/AGENTS.md | 4 +++- Furious/Backends/Hysteria1/AGENTS.md | 3 ++- Furious/Backends/Hysteria2/AGENTS.md | 4 +++- Furious/Backends/Xray/AGENTS.md | 3 +++ Furious/Controllers/AGENTS.md | 2 ++ Furious/Core/AGENTS.md | 6 ++++-- Furious/Data/AGENTS.md | 2 ++ Furious/Extensions/AGENTS.md | 5 +++-- Furious/Externals/AGENTS.md | 2 ++ Furious/Frozenlib/AGENTS.md | 2 ++ Furious/Interface/AGENTS.md | 2 ++ Furious/Models/AGENTS.md | 2 ++ Furious/Plugins/AGENTS.md | 3 ++- Furious/Qt/AGENTS.md | 6 ++++-- Furious/Repository/AGENTS.md | 2 ++ Furious/Service/AGENTS.md | 7 ++++--- Furious/Utility/AGENTS.md | 6 ++++-- Furious/Widget/AGENTS.md | 3 +++ Furious/Window/AGENTS.md | 3 +++ Icons/AGENTS.md | 6 +++++- tests/AGENTS.md | 3 +++ 27 files changed, 81 insertions(+), 22 deletions(-) diff --git a/.github/AGENTS.md b/.github/AGENTS.md index 939a965a..d49a7a64 100644 --- a/.github/AGENTS.md +++ b/.github/AGENTS.md @@ -64,6 +64,9 @@ Read `.github/workflows/deploy-pypi.yml` with `tests/README.md`; paths are relat interpreter-version checks. The latter use compatible Qt/native wheel pins, dependency consistency, native-binding imports without starting runtimes, application compilation, cold imports and real compatibility behavior. These checks do not certify the entire suite on every version. + Default source discovery includes regular stress but leaves the explicitly enabled very-heavy classes skipped. + Standalone benchmarks and compiled lifecycle probes are separate entry points; neither runs merely because the + source job or binary matrix succeeds. Check `tests/README.md` for the effective opt-ins and invocation boundaries. The reusable workflow is a required dependency of PyPI publication through `workflows/deploy-pypi.yml`, so its version matrix must also pass. It can run manually. Hourly binary builds retain their separate artifact scope. Source tests do not establish packaged behavior or Python/Qt floors beyond their matrix. Do not call an artifact build a regression-test pass; use `tests/README.md` for diff --git a/AGENTS.md b/AGENTS.md index 9b2d82f3..477636ac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,8 @@ ## Learn before changing -- Treat the checked-out tree, tests, build configuration, and verified runtime behavior as the immediate source of truth. +- Treat the checked-out tree, tests, build configuration, and verified runtime behavior as the immediate source of + truth. Existing guidance is a maintained model, not an authority that can make itself true. - If `.codegraph/` exists, use CodeGraph before broad text searches for structural questions; use `rg` for exact follow-up. Inspect callers, tests, persisted formats, platform branches, and packaging consumers before changing a @@ -65,7 +66,8 @@ 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. 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 +- 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. Moving a profile into a group does not transfer remote ownership; a running core uses its prepared document even @@ -101,7 +103,8 @@ - Centralize supported standard-library API differences in `Frozenlib.PythonCompatibility`; select implementations once and preserve result/error semantics. Keep pure domain imports independent of the Qt-backed foundation by using minimum-compatible typing/runtime APIs at that boundary. Verify both legacy API shapes and actual supported - interpreters; `tests/test_python_compatibility.py` anchors the shared behavior, not a complete minimum-version guarantee. + interpreters; `tests/test_python_compatibility.py` anchors the shared behavior, not a complete minimum-version + guarantee. - Generated and curated artifacts have separate sources of truth: never hand-edit `Furious/Frozenlib/AppResources.py`; update `Resources.qrc`/resource inputs and regenerate it. Follow `Furious/Externals/AGENTS.md` for the translation catalog and `Furious/Data/AGENTS.md` for bundled assets. @@ -158,4 +161,6 @@ path as well as its successful caller; a test name is an investigation anchor, not proof of unexercised behavior. Keep run-specific counts, versions, diagnostic experiments, and defect inventories in the work report; guidance retains the required invariant and a source/test anchor. Do not repeatedly append symptoms to a local guide. + Separate an implemented safeguard from a required but unfulfilled contract. Documentation must neither claim + a missing safeguard exists nor redefine the defect as intended behavior merely because its tests currently pass. During guidance-only work, report defects separately instead of changing production code to satisfy the prose. diff --git a/Furious/AGENTS.md b/Furious/AGENTS.md index 006a1597..69de61a8 100644 --- a/Furious/AGENTS.md +++ b/Furious/AGENTS.md @@ -22,6 +22,8 @@ Read `Furious/__init__.py` with `tests/test_public_api.py`; paths are relative t separately. Importability means preserving the actual side-effect boundary, not merely avoiding a syntax error. Python export aliases, distribution names, native-module names, and persisted identifiers serve different consumers; inspect each affected surface before renaming one. An import alias does not migrate stored data or transfer ownership. + Standard-library imports and child-only native binding imports have different side-effect boundaries. Moving one + import must preserve both cold package import and actual spawned-child execution, not only a mocked factory path. ## State, data, and ownership diff --git a/Furious/Actions/AGENTS.md b/Furious/Actions/AGENTS.md index 4f38b94f..aa4d89ac 100644 --- a/Furious/Actions/AGENTS.md +++ b/Furious/Actions/AGENTS.md @@ -47,7 +47,8 @@ Read `Furious/Actions/Import.py` with `tests/test_qt_interactions.py`; paths are - Native action destruction also releases its screen-capture handle through the same idempotent cleanup path as application shutdown. Destruction callbacks retain plain resource state, not the action. Failed close is diagnosed and retains the handle while that state has a surviving owner; native destruction does not provide a retry scheduler. - A top-level progress widget borrowed by an action needs explicit native deletion when that action dies. + An action-created top-level progress widget is owned by that action even though a QAction cannot be its QWidget + parent. Native action destruction must schedule its deletion; ordinary progress close remains reusable. Verify native teardown while intentionally retaining action wrappers/bound methods. - Small profile imports use the direct bulk path; large imports yield between bounded batches. One operation owns captured input and its continuation through completion/cancellation; teardown rejects deferred calls. A parser call diff --git a/Furious/Application/AGENTS.md b/Furious/Application/AGENTS.md index a16263e0..db99f3e6 100644 --- a/Furious/Application/AGENTS.md +++ b/Furious/Application/AGENTS.md @@ -11,7 +11,9 @@ relative to this source tree's root. owners already exist during election. Plugins are available before repository restoration interprets persisted profiles. Register cleanup as each acquisition succeeds, including election-failure paths, and preserve these dependencies when changing stage order. -- Partial startup, normal exit, signals, and event-loop failure converge on one reverse-order cleanup path. +- Once `DesktopApplication.run()` is entered, partial startup, normal exit and event-loop failure converge on one + reverse-order cleanup path. Constructor failures and signals before handler installation need separate outer-process + evidence; do not extend the run-loop cleanup guarantee to acquisitions it never reached. `aboutToQuit` and the event-loop `finally` may both reach it; repeated entry must not repeat registered stages. One callback failure does not skip later stages, but the stack consumes that callback and does not retry it. Its successful `close()` return means this invocation ran the stack, not that every resource was released. diff --git a/Furious/Backends/AGENTS.md b/Furious/Backends/AGENTS.md index 488524e0..7bcfe5a1 100644 --- a/Furious/Backends/AGENTS.md +++ b/Furious/Backends/AGENTS.md @@ -26,7 +26,9 @@ tree's root. owns the editable snapshot, acceptance validation, identity resolution, and eventual write-back. Runtime factories likewise transfer fresh execution resources to the workflow owner. Editor acceptance and runtime readiness are different validations; neither may silently rewrite stored data to make a later stage succeed. Backend factories - may deliberately defer editor/native imports for discovery and process boundaries; do not hoist those imports + can return no prepared launch for an unsupported operation. Preserve that outcome without treating a missing + launch as execution success or silently selecting another backend. + Factories may deliberately defer editor/native imports for discovery and process boundaries; do not hoist those imports solely for uniform style without checking cold imports and the spawned-child construction path. - `Furious/Plugins/Runtime.py` checks that serialization yields nonempty text and carries structured diagnostics on failure; it does not parse pre-serialized strings or validate a backend's complete schema. Keep serialization success, diff --git a/Furious/Backends/ExternalCore/AGENTS.md b/Furious/Backends/ExternalCore/AGENTS.md index f14849eb..7b714e53 100644 --- a/Furious/Backends/ExternalCore/AGENTS.md +++ b/Furious/Backends/ExternalCore/AGENTS.md @@ -10,7 +10,9 @@ source tree's root. - External Core represents one user-selected local executable, not an embedded protocol binding. Keep executable path, optional working directory, argument vector, environment overrides, HTTP/SOCKS endpoints, shutdown timeout, remote TUN address, and application-TUN opt-in distinct while preserving unknown top-level fields. -- Loading is observational: do not silently absolutize or rewrite relative paths. Validation before spawn owns path +- Loading is observational: do not silently absolutize or rewrite relative paths. An explicitly chosen file may + be resolved by the editor, while opening a stored document must preserve its path text. The chooser's nested + event loop also requires a surviving native field tree before write-back. Validation before spawn owns path existence/type, argument and environment types/NULs, endpoint requirements, and a finite bounded shutdown timeout. Reject NaN, infinities, Booleans, and integer-to-float overflow before process wait APIs. Preserve the accepted finite interval and prove rejection behavior directly; equivalent-looking comparisons are not a substitute diff --git a/Furious/Backends/Hysteria1/AGENTS.md b/Furious/Backends/Hysteria1/AGENTS.md index 4de741ca..a79e2b8c 100644 --- a/Furious/Backends/Hysteria1/AGENTS.md +++ b/Furious/Backends/Hysteria1/AGENTS.md @@ -15,7 +15,8 @@ source tree's root. host routing or connection commit. Keep the factory's unsupported routing/TUN combination rejection before execution acquisition; do not silently substitute Global routing or borrow native TUN from Hysteria 2. Keep MMDB/ACL launch preparation here and application-TUN acquisition/rollback with that workflow. The existing - rejection prompt is a compatibility path, not a requirement that runtime factories own UI. + rejection prompt and absent prepared launch are compatibility outcomes, not a requirement that runtime factories + own UI. Test refusal before acquisition separately from a typed runtime failure after ownership transfers. - Routing ACL/MMDB launch inputs remain distinct from the stored connection JSON. Optional files are read into launch data before the child starts; a missing/unreadable file is logged and falls back to empty input. Preserve that observable fallback unless deliberately changing the contract. The serialized client document and these diff --git a/Furious/Backends/Hysteria2/AGENTS.md b/Furious/Backends/Hysteria2/AGENTS.md index ee772844..c011fab7 100644 --- a/Furious/Backends/Hysteria2/AGENTS.md +++ b/Furious/Backends/Hysteria2/AGENTS.md @@ -30,7 +30,9 @@ this source tree's root. make that preparation interruptible. Test resolved addresses and explicit route exclusions as separate inputs to the exclusion guarantee; a resolution failure alone does not prove that valid manual exclusions are absent. DNS failure and insufficient Linux privilege are independent preparation failures. Manual exclusions can satisfy - the former route-input requirement but do not grant the latter privilege or prove remote connectivity. + the former route-input requirement but do not grant the latter privilege or prove remote connectivity. Native + TUN ownership is decided from the prepared document, before application-engine selection; a later preference change + must not reinterpret the running core's ownership. - 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 diff --git a/Furious/Backends/Xray/AGENTS.md b/Furious/Backends/Xray/AGENTS.md index a5b5c862..4256383d 100644 --- a/Furious/Backends/Xray/AGENTS.md +++ b/Furious/Backends/Xray/AGENTS.md @@ -38,6 +38,9 @@ source tree's root. download path and does not inherit runtime staging or checksum guarantees. Hash jobs receive copied bytes and return through the updater's Qt-thread boundary; closing the updater must release request and hash-callback contexts independently, including native destruction without a normal reply completion. + Checksum workers own copied bytes and opaque job identity, not a download callback or transient Qt receiver. + Resolve result context on the updater's Qt thread and discard it at shutdown; a completed hash is not permission + to revive a retired download. `tests/test_xray_asset_download.py` covers the blocked-worker destruction case. - Routing selection IDs, user routing documents, and translated built-in labels are different contracts. Preserve custom document content and named-profile identity while composing runtime routing/API statistics. Trace the selected repository routing document separately from the connection's routing branch and prepared diff --git a/Furious/Controllers/AGENTS.md b/Furious/Controllers/AGENTS.md index b6c672ba..5004c7e9 100644 --- a/Furious/Controllers/AGENTS.md +++ b/Furious/Controllers/AGENTS.md @@ -45,6 +45,8 @@ source tree's root. - `SettingsController` is the shared policy path used by Home, Settings, tray, and platform integration. Startup registration persists only after host success; other preferences may apply immediately or on the next connection. Preserve each setting's actual application timing instead of imposing one transaction order on all preferences. + Presentation can queue a checkbox request to let Qt's native setter unwind. The controller remains authoritative + when that request is delivered; queued UI timing is not a second preference state or a delayed persistence policy. TUN mode, application-engine preference, and the active runtime's captured choice are separate values. A preference change affects a subsequent attempt; it neither replaces a live engine nor overrides proxy-core native TUN. Registration/defaults and selection signals belong here, while customization storage and host work keep their owners. diff --git a/Furious/Core/AGENTS.md b/Furious/Core/AGENTS.md index 03459d7c..526f7386 100644 --- a/Furious/Core/AGENTS.md +++ b/Furious/Core/AGENTS.md @@ -48,8 +48,10 @@ relative to this source tree's root. queues, or callbacks. Start with `tests/test_runtime_lifecycle.py` and `tests/test_connection_startup_async.py`; output/process stress lives in the tiers documented by `tests/README.md`. Review output admission and draining together when changing backpressure. -- `SingTUN` imports the Go binding only in a spawned child. Its bounded status pipe establishes native readiness - and the actual device name independently of diagnostic output and process liveness. Cooperative stop is followed +- `SingTUN` imports the Go binding only in a spawned child. Exercise the real child import path independently of + an injected test engine when import or metadata plumbing changes. Distribution-version lookup must not start + the native engine. Its bounded status pipe establishes native readiness and the actual device name independently + of diagnostic output and process liveness. Cooperative stop is followed by exact-child reap and attempt-local host recovery; retain the lease when either fails. Never infer Go cleanup from forced termination. Its `SingTUNHostPlan` remains attached through host-worker drain and restoration; tests in `tests/test_sing_tun.py` cover startup cancellation, validated status with binding-provided failure reasons, diff --git a/Furious/Data/AGENTS.md b/Furious/Data/AGENTS.md index 0c16f60b..e99e4a64 100644 --- a/Furious/Data/AGENTS.md +++ b/Furious/Data/AGENTS.md @@ -11,6 +11,8 @@ tree's root. bundled font. It is not a home for settings, subscriptions, or general caches. The Xray updater currently replaces assets at the package-resolved data paths, so these files are not necessarily immutable at runtime. Review source, installed, and packaged write permissions separately; an application refresh may appear as a source-tree change. + A pre-existing asset diff may belong to the user or the runtime updater. Preserve its bytes during source/guidance + work instead of treating it as disposable generated output or including it in an unrelated documentation commit. - Preserve upstream licenses, provenance, binary/text formats, filenames, and paths consumed by constants, backends, tests, setuptools package data, and Nuitka. Do not incidentally reformat generated ACLs or replace binary assets. - Markdown files in this directory are repository metadata, not runtime data. Keep top-level and nested Markdown files diff --git a/Furious/Extensions/AGENTS.md b/Furious/Extensions/AGENTS.md index 15e3c044..6553d2ae 100644 --- a/Furious/Extensions/AGENTS.md +++ b/Furious/Extensions/AGENTS.md @@ -13,8 +13,9 @@ relative to this source tree's root. belongs to `SubscriptionImportService`, and group reconciliation, request generations, timers, persistence, and post-commit effects belong to the subscription service/repository path. - Automatic detection probes decoders by priority. An explicit decoder ID restricts dispatch to that decoder; - an unknown ID or a mismatch must not silently resume automatic detection. Return `None` for a mismatch. Recognizing - a share-link envelope does not validate its URI schemes or protocols; the importer owns that decision. + an unknown ID or a mismatch must not silently resume automatic detection. Return `None` for a mismatch; + an empty `SubscriptionResult` instead describes recognized input and reaches a different import/reconciliation + policy. Recognizing a share-link envelope does not validate its URI schemes or protocols; the importer owns that decision. Preserve useful names/upstream IDs and never log a complete payload or link. Standard plain/Base64 decoding materializes input before per-item import can be cancelled; linear parsing is not a size or responsiveness bound. Review decoded size and work limits at this boundary before adding richer formats. diff --git a/Furious/Externals/AGENTS.md b/Furious/Externals/AGENTS.md index 81f3c607..dacb7889 100644 --- a/Furious/Externals/AGENTS.md +++ b/Furious/Externals/AGENTS.md @@ -45,6 +45,8 @@ tree's root. brace placeholders is extractable: translate it first, then interpolate with `.format()` outside `_()`. - Keep runtime interpolation outside the translatable expression. Translate UI language, not identifiers, protocol values, user-defined names, persisted values, paths, or diagnostic payloads. + Translate application-owned validation categories through static catalog keys while preserving native diagnostic + text and user JSON keys. Do not make localization depend on an upstream exception's exact English wording. - When a control stores source text for later retranslation, update that source instead of manually translating one rendered instance. Adjacent static literals and multiline literals still form one source key; preserve their exact whitespace/newlines when changing layout or formatting. Verify extraction and rendered retranslation diff --git a/Furious/Frozenlib/AGENTS.md b/Furious/Frozenlib/AGENTS.md index 1d9645bb..0552a785 100644 --- a/Furious/Frozenlib/AGENTS.md +++ b/Furious/Frozenlib/AGENTS.md @@ -21,6 +21,8 @@ Read `Furious/Frozenlib/AppSettings.py` with `tests/test_frozenlib.py`; paths ar - `Mixins.qObjectIsValid` checks native QObject validity and deliberately accepts non-QObjects, including `None`. Check required presence and plain resource state separately; a Python editor binding needs checks of its Qt fields. Neither one-object nor grouped validity checks provide ownership, thread affinity, or generation freshness. + Use the Qt scope's boundary rule before adding checks to a caller. This helper supplies a predicate, not a reason + to check every method; pure reads and computations do not invalidate an already-valid receiver. - `AppSettings` keys include preferences and encoded repository blobs. Preserve names, defaults, string/binary encodings, migrations, and import-time registration. `AppSettings.get()` can persist a default or repair an invalid preference; it is not an observational reader like a copied customization projection. Distinguish diff --git a/Furious/Interface/AGENTS.md b/Furious/Interface/AGENTS.md index c9fdba74..8d91414b 100644 --- a/Furious/Interface/AGENTS.md +++ b/Furious/Interface/AGENTS.md @@ -30,6 +30,8 @@ Read `Furious/Interface/Runtime.py` with `tests/test_interface.py`; paths are re - `ApplicationRunner.ExitCode` is the outer application process protocol; it is not interchangeable with a core's raw exit code or `RuntimeExitReason`. Preserve the meaning at each boundary instead of translating every nonzero value into one generic failure. + Declaring the exit enum does not route exceptions into it. Verify the concrete process boundary separately from + an exception hook's mapping; bootstrap interception can bypass that hook. - Model encoders may raise, while configuration construction deliberately captures diagnostics. Callers must inspect the contract they consume; successful construction alone proves neither serialization nor backend acceptance. Preserve `RuntimeStartError`'s reason/code/details and `RuntimeExit`'s typed meaning across adapters; exception text diff --git a/Furious/Models/AGENTS.md b/Furious/Models/AGENTS.md index 38c765da..a87dac63 100644 --- a/Furious/Models/AGENTS.md +++ b/Furious/Models/AGENTS.md @@ -17,6 +17,8 @@ root. or malformed input becomes an empty object with `constructionError()`. Keep construction and serialization errors distinct and preserve useful context through callers. Successful generic mapping construction is not protocol validation: backend acceptance belongs to the selected capability, and serializability is a separate check. + Profile/configuration `isValid()` methods validate domain data, not QObject lifetime. Keep these checks distinct + from native-wrapper guards when auditing similarly named calls or changing a validation contract. - `ServerProfile` separates connection data from `ProfileMetadata`. `fromConfiguration()` copies a bare configuration but returns an already-supplied profile unchanged; the direct dataclass constructor does not imply copying. A type conversion is therefore not an isolation boundary. Choose explicit copy semantics before independent editing or diff --git a/Furious/Plugins/AGENTS.md b/Furious/Plugins/AGENTS.md index 2e058266..c5eb89a2 100644 --- a/Furious/Plugins/AGENTS.md +++ b/Furious/Plugins/AGENTS.md @@ -48,7 +48,8 @@ tree's root. state. Backend-specific defaults, settings keys, document branches, and host assumptions stay behind the provider. Capability presence advertises an operation, not a configured target or successful execution; callers must handle absence, unavailable configuration, and operation failure separately (notably statistics, export, and probes). -- API-version-3 runtime factories return `PreparedRuntime` directly. The runtime is fully prepared before return, +- Runtime factories admitted by the current plugin API return `PreparedRuntime` directly. The API version is owned + by `Plugins.API`, not by a duplicated literal in this guide. The runtime is fully prepared before return, 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 diff --git a/Furious/Qt/AGENTS.md b/Furious/Qt/AGENTS.md index 42f8ec98..852518fd 100644 --- a/Furious/Qt/AGENTS.md +++ b/Furious/Qt/AGENTS.md @@ -64,9 +64,11 @@ Use the `manage-qt-pyside6-lifetimes` skill for source lifetime work when availa that owner, when more native work follows. Name the actual boundary and trace its callers/observers rather than assuming every function can destroy arbitrary UI. If the check already passed and the intervening code only reads or computes data, do not repeat it. Keep callback-specific checks inside the branch that invokes that callback. - Qt receiver disconnection and `connectWeakly()` protect delivery entry, so an immediately repeated receiver check + Qt-connected QObject slots and `connectWeakly()` protect delivery entry, so an immediately repeated receiver check adds nothing; they do not protect continuation after reentrant delivery. Required workflow-generation checks remain - separate. Existing callback, modal, borrowed-object and peer-destruction cases in `tests/test_qt_lifetime.py`, + separate from validity. A plain callback retained outside Qt's receiver context needs its own lifetime contract; + do not extend QObject-slot disconnection guarantees to arbitrary Python callables. Existing callback, + modal, borrowed-object and peer-destruction cases in `tests/test_qt_lifetime.py`, `tests/test_frozenlib.py`, and `tests/test_service_runtime.py` challenge these distinctions. - Only the GUI thread mutates widgets/live GUI models. Slots do not sleep or perform unbounded file, host, process, or network work; split work into bounded event-loop units or an owned worker and reject stale results on return. diff --git a/Furious/Repository/AGENTS.md b/Furious/Repository/AGENTS.md index af26695c..b14ba61a 100644 --- a/Furious/Repository/AGENTS.md +++ b/Furious/Repository/AGENTS.md @@ -20,6 +20,8 @@ to this source tree's root. migration deliberately changes it; do not treat every duplicate key as interchangeable. Connection JSON export is not a profile-store backup. Verify durable metadata through storage-record/backend round trips, including identity, favorites and remote ownership, rather than connection serialization alone. + Favorite mutation updates local metadata on the existing profile. Rendering a star must not rewrite the remark, + connection document, subscription matching key, or profile identity merely to display that persisted flag. - A restore failure remains observable. Automatic cleanup must not replace unreadable persisted bytes with an empty fallback; only an explicit successful replacement may do so. Root decoding, complete-collection hydration, live replacement, and later serialization are separate failure boundaries. Byte preservation does diff --git a/Furious/Service/AGENTS.md b/Furious/Service/AGENTS.md index 409132ae..2d5d91cd 100644 --- a/Furious/Service/AGENTS.md +++ b/Furious/Service/AGENTS.md @@ -30,9 +30,10 @@ source tree's root. and release contexts only when execution no longer needs them. Late delivery must not revive a shut-down manager or mutate live state. A terminal result ends an operation's publication contract, not necessarily its execution: a replacement may be admitted only under the scheduler's resource bounds while cancelled work still occupies a slot. - Provider calls, reply aborts, and grouped notifications are reentrancy boundaries too. Recheck native ownership - and the captured generation before continuing a stage, restarting a timer, admitting another request, or - publishing the next result; a check at callback entry alone cannot establish freshness afterward. + External provider callbacks, reply aborts and signal publication can be reentrancy boundaries. Trace the specific + callback/observer contract before adding continuation guards; pure preparation is not a destruction boundary. + Recheck native ownership and the captured generation before continuing a stage, restarting a timer, admitting + another request, or publishing the next result; a check at callback entry alone cannot establish freshness afterward. ## Connection and network workflows diff --git a/Furious/Utility/AGENTS.md b/Furious/Utility/AGENTS.md index 53f7585c..2230e753 100644 --- a/Furious/Utility/AGENTS.md +++ b/Furious/Utility/AGENTS.md @@ -10,13 +10,15 @@ source tree's root. - `AppMainProcess` owns one exact Qt application child and one small synchronized crash-log result. Do not add a `multiprocessing.Manager` or auxiliary child merely to communicate status, and preserve the platform’s explicit spawn behavior. -- Exception reporting must work before and after application construction. The child runs the supplied application - factory; the parent must not construct a Qt application to pass across the process boundary. Signal handlers are +- Required exception reporting covers failures before and after application construction. The child runs the supplied + application factory; the parent must not construct a Qt application to pass across the process boundary. Signal handlers are installed only after the factory returns, so pre-construction signals are outside this wrapper's handler coverage. Preserve semantic exit codes and original exception/traceback context; crash-log failure is secondary. Verify this through a real spawned child: multiprocessing bootstrap can intercept an uncaught factory/run failure before `sys.excepthook`. Direct hook tests prove its mapping only, not dispatch from every child failure path; compare the actual exit and crash flag before claiming supervision coverage. + The current wrapper installs the hook but does not explicitly catch exceptions escaping the supplied factory + or `application.run()`. Keep this coverage gap visible instead of describing hook installation as complete dispatch. - The parent entry point joins only the child it created and shows the fallback Qt report only for a nonzero result. That join follows the GUI session lifetime; it is not a short startup-readiness deadline. Tests must bound their own waits and reap their exact child if the fixture fails. A child stuck in cooperative worker cleanup can diff --git a/Furious/Widget/AGENTS.md b/Furious/Widget/AGENTS.md index 9ed036ee..2a905322 100644 --- a/Furious/Widget/AGENTS.md +++ b/Furious/Widget/AGENTS.md @@ -59,6 +59,9 @@ source tree's root. keep connection/remote ownership intact. Favorites, search, and subscription filters intersect in the existing proxy model; a favorite mark is persisted metadata, while the filter is presentation state. The profile mutation and Home workflow cases in `tests/test_qt_interactions.py` cover these boundaries. + Favorite SVG decoration follows the remark's foreground and selected-text roles, including privilege-dependent + connection colors. Use the shared color authority and view palette rather than a dark/light test; keep selected + icon and text behavior aligned. The selected-rendering cases in `tests/test_qt_interactions.py` are the pixel anchor. - 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 481aa74f..81f8c95d 100644 --- a/Furious/Window/AGENTS.md +++ b/Furious/Window/AGENTS.md @@ -24,6 +24,9 @@ Read `Furious/Window/MainWindow.py` with `tests/test_ui_behavior.py`; paths are silently normalizing storage, importing tun2socks preferences, or launching a native engine just to open settings. The application JSON editor is another view of that same candidate, not a second configuration authority. Validate the merged candidate at acceptance; editor syntax checking does not replace model validation. + Checkbox requests that can destroy their card use queued delivery after the native setter unwinds. Destroying + a card before delivery cancels its request; tests must process the event turn before asserting committed settings. + Keep this presentation boundary separate from the controller's synchronous policy and repository commit. Translate semantic application validation categories here, preserving technical diagnostics and user JSON keys. Do not classify failures by matching exact English exception text. - The current page composition shares one subscription workflow between server and subscription presentation, records diff --git a/Icons/AGENTS.md b/Icons/AGENTS.md index 199d68e1..3316787f 100644 --- a/Icons/AGENTS.md +++ b/Icons/AGENTS.md @@ -9,7 +9,11 @@ Read `Resources.qrc` with `tests/test_public_api.py`; paths are relative to this remote resources, embedded rasters, editor metadata, or hard-coded page backgrounds. - 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. + chosen asset. Theme-only controls reuse that path. Per-item decorations may mask an existing SVG into a native + QIcon using the view's foreground and selected-text colors; profile connection/privilege colors are not determined + by dark mode alone. `Furious/Widget/ServerTableView.py` and the favorite rendering tests in + `tests/test_qt_interactions.py` anchor this exception. + Preserve accessible text and do not rely on color alone. Mask/opacity helpers cache shared icon values: keep cache size bounded and keys independent of widgets, and avoid mutating a cached icon as if it belonged to one control. - Preserve license/provenance and the `Resources.qrc` alias contract. Any add, removal, rename, or alias change diff --git a/tests/AGENTS.md b/tests/AGENTS.md index 5e47f74f..6db8bf60 100644 --- a/tests/AGENTS.md +++ b/tests/AGENTS.md @@ -87,3 +87,6 @@ Read `tests/support.py` with `tests/README.md`; paths are relative to this sourc the contract. For guidance-only changes, verify path preservation, changed-file scope, referenced commands/tests, and contradictory claims; run existing behavior tests only to resolve architecture uncertainty rather than adding tests of prose. + For a blank-line-only cleanup, compare the AST, executable tokens and nonblank lines, compile touched files, + and check formatter/diff output. This proves the promised structural equivalence without creating new behavioral + tests or repeating a full resource campaign solely for visual spacing.