Refine repository guidance

Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
Loren Eteval
2026-09-19 11:41:29 +08:00
parent 5b1699c9d0
commit 3831e6e017
27 changed files with 159 additions and 106 deletions
+8 -6
View File
@@ -14,9 +14,10 @@ exceptions; it does not define the source test suite or imply that every package
- Treat each matrix row as a supported product target with explicit runner OS/architecture, Python, Qt/PySide source,
native-binding toolchain, compatibility floor, `Deploy.py` output, and upload pattern. Artifact names and architecture
checks must agree; never infer target architecture from the host label alone.
- Current target-specific assertions are intentional: Linux proves an Essentials-only/no-WebEngine application and its
Flatpak sandbox dependencies; macOS verifies its WebEngine frameworks, helpers, resources, relocation, and signing;
Windows verifies native imports and every packaged PE machine type, with a separate Windows 7 compatibility toolchain.
- Current target-specific checks are intentional: Linux checks the Essentials-only/no-WebEngine build and its
Flatpak native dependency closure; macOS checks WebEngine frameworks, helpers, resources, relocation, and signing;
Windows checks native imports and packaged PE machine types, with a separate Windows 7 compatibility toolchain.
These assertions establish artifact properties, not complete application behavior on those platforms.
Change an exception only with evidence from the affected target. Binary jobs filter shared requirements before
installing target-specific Qt/native bindings; copying the ordinary package dependency list into those jobs can
reintroduce Addons on Linux or replace a compatibility build. Review the effective installed set, not just the
@@ -42,10 +43,11 @@ exceptions; it does not define the source test suite or imply that every package
source/native import checks, Nuitka/installer output, packaged architecture/dependency checks, artifact upload, and tag
gates. When a target cannot run locally, add a narrow CI assertion that fails before publication with a useful reason.
- `workflows/source-tests.yml` runs isolated source unittest discovery on Windows, Linux, and macOS and is a
required dependency of PyPI publication through `deploy-pypi.yml`. It can also run manually. Daily binary
required dependency of PyPI publication through `workflows/deploy-pypi.yml`. It can also run manually. Daily 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
source verification. Check actual `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.
source verification. Follow actual `needs` and tag gates back to required checks; upload success alone does not
establish release eligibility. A diagnostic Nuitka build that changes compiler/runtime flags is separate evidence
from the ordinary release configuration; record and exercise the latter before claiming a packaged defect resolved.
- 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.
+7 -4
View File
@@ -28,7 +28,9 @@
scopes in place.
- Inheritance follows directory ancestry. Name the nearest governing guide when clarifying a scope; a sibling guide
identifies a contract to consult, not another parent. Verification and self-evolution here apply to every descendant
scope without repeating the same maintenance checklist in each file.
scope without repeating the same maintenance checklist in each file. Ignored comparison checkouts retain their own
scopes and toolchains; their manifests and local guides govern their code, not Furious's Python/Qt recipes.
Git diff alone cannot verify ignored guides: compare their paths and contents with the initial inventory too.
## Operating model
@@ -124,6 +126,7 @@
- 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.
- Distinguish requirements, observed implementation, and verified gaps. State the evidence boundary: a test name is an
investigation anchor, not proof that every failure path is covered. Keep run-specific counts, versions, and diagnostic
experiments in the work report; put only durable constraints in guidance. During guidance-only work, report defects
separately instead of changing production code to satisfy the prose.
+5 -3
View File
@@ -1,7 +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.
domain, persistence, orchestration, platform integration, and presentation; nested guides specialize it in
place.
## Responsibility boundaries
@@ -53,8 +54,9 @@ domain, persistence, orchestration, platform integration, and presentation; nest
record. Choose the explicit profile, metadata, or connection representation required by each boundary; generic
mapping conversion is not a profile backup.
- Import, clipboard, share-link, file, and QR paths reuse the owning plugin codecs and validation. QR is a presentation
transport, not a second protocol parser; construct a complete neutral result before repository mutation and never log
the secret-bearing payload.
transport, not a second protocol parser. Decoding a transport envelope, validating a protocol, and committing a
profile are separate boundaries: a recognized envelope is not permission to clear a group or import an unsupported
protocol. Construct a complete valid result for each commit unit and never log the secret-bearing payload.
## Local guides
+6 -5
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor; this scope adds rules for translating user gestures into
owned commands and presentation without becoming a workflow authority.
## Command boundary
@@ -29,9 +29,10 @@ presentation without becoming a workflow authority.
transient windows. Each screen-capture action owns a separate native capture handle, including separate tray/page
instances; type-deduplicated cleanup must not leave one open. QR export generation belongs to its result window,
not a parallel action-owned exporter.
- Small profile imports use the direct bulk path; large imports yield between bounded batches. Preserve captured
input and one operation context until completion/cancellation, reject deferred calls after teardown, and retain
already committed batches when cancellation stops later work. A parser call itself is not preempted by a batch.
- 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
itself is not preempted by a batch. Keep preparation and insertion distinct so a failed batch cannot publish a
partially validated result.
- 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.
+6 -4
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. 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.
@@ -26,8 +26,10 @@ child-process supervisor and the inner application event loop.
observations.
- Native session callbacks cross to the GUI thread before touching Qt-owned state. Tray, dock, System Proxy daemon,
Flatpak/AppImage, and no-tray behavior are explicit platform capabilities.
- The application owns the top-level window/tray wrappers; `MainWindow` owns the persistent page tree. Do not let dynamic
menus, sockets, theme snapshots, workers, or partial startup owners outlive their registered cleanup stage.
- The application owns the top-level window/tray wrappers; `MainWindow` owns the persistent page tree. Cleanup order
follows dependencies: consumers stop while the plugins, repositories, and Qt objects they need are still valid.
A registered cleanup callback establishes responsibility, not proof that its menus, sockets, snapshots, or workers
were released. Verify partial composition as well as a fully constructed application.
- Verify each acquisition failure, reverse/repeated cleanup, singleton races/commands, queued session shutdown,
tray-present/absent close policy, restored connection, and exact child/thread-pool ownership with host effects
mocked. Start with `tests/test_architecture_refactors.py`, `tests/test_application_process.py`, and
+5 -3
View File
@@ -1,7 +1,8 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. 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.
## Common backend contract
@@ -19,7 +20,8 @@ scope adds rules shared by all bundled proxy backends without making the richest
- Configuration/runtime modules stay importable without constructing Qt editors. Plugin registration remains explicit
enough for compiled discovery. An editor factory returns a fresh projection, not a repository commit: the caller
owns the editable snapshot, acceptance validation, identity resolution, and eventual write-back. Runtime factories
likewise transfer fresh execution resources to the workflow owner.
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.
## TUN and runtime policy
+6 -5
View File
@@ -1,7 +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.
Inherit `Furious/Backends/AGENTS.md` and its ancestors; consult Plugins for capability contracts. This file
preserves the intentionally different direct-subprocess scope for user-selected executables.
## Structured executable boundary
@@ -36,6 +36,7 @@ the intentionally different direct-subprocess scope for user-selected executable
`tests/test_external_core.py` and `tests/test_backend_editor_contract.py`. Exercise a child that remains alive
after escalation and readers/watchers that outlast their joins. A failed final reap is a cleanup failure to report;
clearing the runtime's process/thread references must not be used as evidence that those resources exited.
Direct-child exit also does not prove that descendants closed inherited pipes. Current stop/join paths can clear
references after unsuccessful waits; treat that as a cleanup-contract gap, not a guarantee of reaping. A repair must
retain observable outstanding resources and coordinate failure semantics with the consuming runtime lease.
Retain an independent reference in failure tests so an empty runtime field cannot make the test pass. Direct-child
exit also does not prove that descendants closed inherited pipes. `Process.py` currently clears references after
unsuccessful waits; this is a cleanup-contract gap. A repair must retain observable outstanding resources and
coordinate failure semantics with `Furious/Service/RuntimeLease.py`, without broad process-name cleanup.
+6 -5
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/Backends/AGENTS.md` and its ancestors; consult Plugins for capability contracts. 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.
@@ -17,9 +17,10 @@ preserve Hysteria 1's legacy flat schema and lifecycle without importing assumpt
launch data before the child starts; a missing/unreadable file is logged and falls back to empty input. Preserve
that observable fallback unless deliberately changing the contract, and include this synchronous file work in
preparation responsiveness review. A prepared runtime advertises its local HTTP readiness endpoint separately
from child liveness. The built-in factory has no statistics provider; shared UI handles that absence. Download
preparation replaces the HTTP listener and removes SOCKS on a copy; do not route test traffic through a stored
listener or apply host System Proxy/TUN merely because the ordinary profile enables it.
from child liveness.
- Capability absence is deliberate: this factory supplies neither native TUN nor a statistics provider. Shared UI
must not infer either from Hysteria 2 support. Download preparation replaces the HTTP listener and removes SOCKS
on a copy; test traffic must use its owned endpoint without applying ordinary connection host effects.
- Verify legacy/current URI and mapping compatibility, unknown/tolerated values, stored-copy isolation, MMDB/ACL
absence or malformed paths, asynchronous readiness and rollback, core-exit translation, application-TUN policy,
and repeated editor/runtime cleanup. Use `tests/test_hysteria1_protocol.py`,
+6 -4
View File
@@ -1,7 +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.
Inherit `Furious/Backends/AGENTS.md` and its ancestors; consult Plugins for capability contracts. This scope
owns Hysteria 2's nested upstream document, native-TUN capability, statistics, and editor projection.
## Native document and editor projection
@@ -19,8 +19,10 @@ Hysteria 2's nested upstream document, native-TUN capability, statistics, and ed
including malformed data for the core to reject; only absence permits application tun2socks. Linux native TUN
requires the backend’s privilege and server-route-exclusion guarantees. The application's Linux privilege-helper
path does not grant an embedded native-TUN core the same privileges. Test these availability decisions separately.
Probe/download copies always remove native TUN. Managed preparation currently resolves server addresses
synchronously; do not describe the whole native-TUN stage as event-driven merely because readiness is asynchronous.
Failure to establish required managed server-route exclusions is terminal: use `TUNPreparationError` so registry
dispatch cannot interpret it as permission to fall back to another TUN path. Probe/download copies always remove
native TUN. Managed preparation currently resolves server addresses synchronously; asynchronous readiness does not
make that preparation interruptible.
- 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
+5 -3
View File
@@ -1,7 +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.
Inherit `Furious/Backends/AGENTS.md` and its ancestors; consult Plugins for capability contracts. This scope
owns Xray's full JSON preservation, routing/assets/statistics, and protocol/transport/TLS projections.
## Full-document preservation
@@ -40,7 +40,9 @@ full JSON preservation, routing/assets/statistics, and protocol/transport/TLS pr
so owner destruction also ends pending confirmation callbacks.
- Statistics preparation is optional and may leave a valid runtime without a statistics target. Preserve that
distinction from connection failure; later sampling uses the target captured for this runtime, not newly edited
settings or an assumption based solely on the backend name.
settings or an assumption based solely on the backend name. `configureXrayStats()` merges the required API service
and counter policy into the runtime copy, preserving unrelated valid API/policy fields. Do not replace a user's
entire API or policy branch merely to enable counters; test both the merged launch and unchanged stored document.
- Verify full-document and URI preservation, aliases and unknown values, runtime-copy isolation for
routing/log/TUN/tests, multiple TUN inbounds, asset integrity/failure, statistics and process cleanup,
compiled-safe UI callbacks, and repeated editor/window destruction. Use `tests/test_xray_asset_download.py`,
+6 -4
View File
@@ -1,7 +1,8 @@
# Controller guidance
Inherit the root and package guides. This scope preserves controllers as process-lifetime authorities for shared
transitions. Services own execution resources; existing prompts are presentation compatibility paths.
Inherit `Furious/AGENTS.md` and its root ancestor. This scope preserves controllers as process-lifetime
authorities for shared transitions. Services own execution resources; existing prompts are presentation
compatibility paths.
## Shared state authorities
@@ -17,8 +18,9 @@ transitions. Services own execution resources; existing prompts are presentation
failure. Worker/native callbacks cross to the controller’s Qt thread before transition.
- 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. Progress completion ends the presentation interval; it is not a success result.
Consumers use connection state and structured error/notification signals to distinguish failure from Connected.
are not generic connection errors. Runtime commit, host-effect success, and visible connection state are distinct
observations. Progress completion only ends the presentation interval; consumers and tests use connection state,
structured errors/notifications, and host results to establish the outcome.
- `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. Capability refresh prefers the active profile and
+6 -2
View File
@@ -1,7 +1,8 @@
# 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; connection policy remains outside it.
Inherit `Furious/AGENTS.md` and its root ancestor. Consult Interface for runtime contracts and Service for
connection ownership. 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.
@@ -17,6 +18,9 @@ This scope owns reusable embedded execution machinery and application tun2socks;
resources. Stop must bound waits, escalate only the owned child, and remain safe after partial start or repetition.
A join timeout or failed handle close is not a successful reap. Verify actual child liveness before describing a
terminal execution state as complete resource release; include failed escalation in ownership tests.
`MultiprocessingRuntime._closeProcess()` currently discards its process reference even when handle close fails.
This is a cleanup-contract gap, not a permissible ownership transfer: a fix must preserve observability of the
outstanding child/handle and agree with the service lease's cleanup-failure semantics.
- Process-backed runtimes own exit monitoring and interpretation: publish one typed terminal event per execution,
preserving the raw exit and whether stop was requested. `isRunning()` is a passive liveness query and must not
consume or dispatch lifecycle events.
+5 -4
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. This scope exists for shipped runtime assets and their
provenance; it is not an application-data or settings directory.
## Boundary and provenance
@@ -34,5 +34,6 @@ application-data or settings directory.
- Verify the real consuming backend/widget, source and packaged path resolution, package-data/Nuitka inclusion,
integrity and failure behavior, and license presence. Tests use fixtures or mocked downloads, never live asset
refreshes. `tests/test_endpoint_info.py` and `tests/test_public_api.py` cover map/resource consumers; release
artifacts require their own inclusion checks. Revalidate provenance/network claims when an asset provider or
loader changes.
artifacts require their own inclusion checks. Check actual artifact contents, including nested Markdown exclusions,
rather than only the presence of package-data patterns. Successful inclusion does not prove runtime write access or
optional WebEngine availability. Revalidate provenance/network claims when an asset provider or loader changes.
+8 -7
View File
@@ -1,7 +1,8 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor; 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.
- `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
@@ -13,11 +14,11 @@ host-shipped non-runtime plugins and must not gain private authority merely beca
- Automatic detection probes decoders by priority; explicit selection does not authorize format substitution. Return
`None` for a mismatch. 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. 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. 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.
standard formats are plain/Base64 share-link envelopes; linear parsing is not an input-size bound. Introduce
explicit size/depth/work limits before adding richer recursive or nested formats.
- Worker safety is a property of the whole preparation path. Standard decoders opt in, but the selected protocol
handlers must also opt in after their shared state, caches, and Qt use are audited. Preserve the GUI compatibility
fallback for unclassified capabilities; a safe envelope decoder cannot authorize an unsafe downstream parser.
- Decoder output is descriptive, not a repository transaction. Supplied names and upstream IDs are input to profile
construction, not permission to overwrite local identity or grant remote ownership. It cannot mutate a group,
cancel tests, reconnect, or publish UI state; those decisions remain at the import/manager commit boundaries.
+5 -4
View File
@@ -1,7 +1,7 @@
# Translation catalog guidance
Inherit the root and package guides. This scope preserves the split between extracted catalog structure and
human-reviewed translations.
Inherit `Furious/AGENTS.md` and its root ancestor. This scope preserves the split between extracted catalog
structure and human-reviewed translations.
## Source and generation contract
@@ -20,8 +20,9 @@ human-reviewed translations.
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. Runtime lookup reverse-maps
translated text to a source key, so collisions can change retranslation behavior even when extraction succeeds.
Exercise colliding translations at lookup time rather than treating the diagnostic as cosmetic.
translated text to a source key through a shared reverse index across languages. Equal translations for different
source keys can therefore affect later retranslation, including after a language switch. Exercise lookup and
retranslation under explicit locales rather than treating collision diagnostics as cosmetic.
## Extractable source text
+5 -3
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. 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
@@ -10,7 +10,9 @@ for unrelated application orchestration to accumulate in a broad helper namespac
isolated tests, or teardown; do not add fallback global owners that create competing lifecycles.
- `AppSettings` keys include preferences and encoded repository blobs. Preserve names, defaults, string/binary
encodings, migrations, and import-time registration. Distinguish desired preferences from confirmed host effects;
startup-registration success is persisted only after its helper reports success.
startup-registration success is persisted only after its helper reports success. Settings storage and cached
repository objects are distinct lifetimes: changing a QSettings identity does not reconstruct `Storage` backends.
Tests that replace settings must isolate both boundaries before exercising cleanup or restoration.
- 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.
+5 -4
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. 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
@@ -27,8 +27,9 @@ satisfy without importing application composition or concrete backends.
- Runtime liveness is observational: querying it must not consume an exit, transfer ownership, or dispatch
callbacks. A zero process exit can still be an unexpected connection failure; requested stop and raw exit success
are different facts. Keep semantic startup errors separate from process codes and readiness timeouts. Define
cleanup-failure semantics without assuming every runtime owns a subprocess; bounded stop/dispose requirements
must remain meaningful for an in-process implementation as well as a child process that resists termination.
cleanup-failure semantics without assuming every runtime owns a subprocess. Bounded stop/dispose is a contract to
verify, not a guarantee supplied by the base class: third-party work may be non-cooperative. Report known violations
at their implementation/owner boundary rather than weakening the interface to bless an unreleased resource.
- 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
+6 -4
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. This scope owns dependency-light domain shape and identity,
never live persistence, Qt presentation, plugin discovery, or workflow execution.
## Domain shape and identity
@@ -12,8 +12,10 @@ Qt presentation, plugin discovery, or workflow execution.
distinct and preserve useful context through callers. Successful generic mapping construction is not protocol
validation: backend acceptance belongs to the selected capability, and serializability is a separate check.
- `ServerProfile` 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. Choose explicit copy semantics before independent editing or worker handoff. Display name,
profile ID, subscription ownership/key, latency, speed, annotations, and local flags never become core fields.
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
worker handoff. Display name, profile ID, subscription ownership/key, latency, speed, annotations, and local flags
never become core 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,
+6 -4
View File
@@ -1,7 +1,8 @@
# 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; backend policy remains in each implementation.
Inherit `Furious/AGENTS.md` and its root ancestor; consult Interface guidance for runtime/storage contracts.
This scope owns capability definitions, atomic registration, dispatch, and plugin lifecycle; backend policy
remains in each implementation.
## Contracts and registry
@@ -34,8 +35,9 @@ capability definitions, atomic registration, dispatch, and plugin lifecycle; bac
- 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.
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,
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.
+7 -4
View File
@@ -3,8 +3,8 @@
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.
Inherit `Furious/AGENTS.md` and its root ancestor. This scope owns reusable Qt presentation, translation/theme
behavior, and lifetime primitives; pages and services consume them without creating parallel registries.
## Canonical presentation
@@ -53,8 +53,9 @@ primitives; pages and services consume them without creating parallel registries
arbitrary worker calls to the GUI thread; choose an explicit queued owner-thread delivery boundary. A surviving
Python wrapper can already be natively invalid, so callback freshness and `shiboken6.isValid()` address different
failure modes. Neither replaces the strong owner required while asynchronous UI remains active.
- `AppQAction.callback` is strong by design, so the action owner cannot outlive the captured receiver. An action
also owns a submenu supplied without a QWidget parent and schedules its native deletion when the action dies;
- `AppQAction.callback` is strong by design, so its owner must not outlive the captured receiver; construction alone
does not enforce that requirement. An action also owns a submenu supplied without a QWidget parent and schedules
its native deletion when the action dies;
`QAction.setMenu()` alone does not establish parent ownership. Explicitly parented menus retain their chosen owner.
- Every `QNetworkReply` has one manager/context owner, one freshness rule, and one terminal deletion path. Request
context must also be released when native destruction skips `finished`, including manager-first teardown with
@@ -78,6 +79,8 @@ primitives; pages and services consume them without creating parallel registries
- 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.
Retained Python wrappers may already be invalid: count native destruction independently, including owner-first
teardown. A pass under diagnostic compiler flags does not establish behavior under ordinary release flags.
Start with `tests/test_qt_lifetime.py`, `tests/test_dialog_geometry.py`, and `tests/test_main_window_geometry.py`;
use the `tests/fixtures/editor_lifetime_probe.py` fixture for compiled investigation. Treat unrun packaged probes
as unverified, and update these rules when measured ownership or the toolchain changes.
+7 -3
View File
@@ -1,7 +1,8 @@
# Repository guidance
Inherit the root and `Furious/AGENTS.md`. Consult the Interface and Models guides when changing their contracts.
This scope owns restoration, migration, ordering, and persistence; workflows and presentation remain outside it.
Inherit `Furious/AGENTS.md` and its root ancestor. Consult the Interface and Models guides when changing their
contracts. This scope owns restoration, migration, ordering, and persistence; 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.
@@ -9,7 +10,10 @@ This scope owns restoration, migration, ordering, and persistence; workflows and
Do not add a second cache/snapshot authority. Prefer named repository mutations so validation and commit boundaries
can move behind the repository over time.
- Preserve stable profile/subscription IDs, subscription ownership/key, ordering, unknown fields, and legacy schemas.
Active row/index and display text are compatibility/presentation state, not identity.
Active row/index and display text are compatibility/presentation state, not identity. Record-shape dispatch and
metadata precedence are migration behavior: legacy `UserServer` aliases override nested metadata, and explicit
top-level current fields then override those aliases. Preserve this order and unknown extras unless a tested
migration deliberately changes it; do not treat every duplicate key as interchangeable.
- 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, individual-record hydration, and later
serialization are separate failure boundaries. Test malformed records inside a valid root as well as malformed
+8 -5
View File
@@ -1,7 +1,7 @@
# Service guidance
Inherit the root and package guides. Consult Models/Repository for data contracts, Plugins/Core for execution, and Qt
for lifetime primitives. This scope owns multi-stage workflows and temporary resources.
Inherit `Furious/AGENTS.md` and its root ancestor. Consult Models/Repository for data contracts, Plugins/Core
for execution, and Qt for lifetime primitives. This scope owns multi-stage workflows and temporary resources.
## Workflow ownership
@@ -68,10 +68,13 @@ for lifetime primitives. This scope owns multi-stage workflows and temporary res
a new first-retained sequence so presenters can prune their prefix without rebuilding history. Capture entries and
the next cursor atomically, and coalesce notifications without losing producer updates.
- Metrics sampling owns its worker/future generation and rejects results after disconnect, disablement, replacement,
or shutdown. Cancellation cannot stop an already-running plugin query: monitor contracts must bound blocking work.
Normalize cumulative-counter resets before history aggregation; clearing usage must not erase speed history.
or shutdown. Normalize cumulative-counter resets before history aggregation; clearing usage must not erase speed
history.
History contains finite values for registered metrics on a monotonic timeline. A missing metric sample is not a
measured zero; preserve that distinction when adding providers or aggregating sparse series.
measured zero; preserve that distinction when adding providers or aggregating sparse series. Closing executor
admission or cancelling a future does not terminate a query already inside plugin code; test stale-result suppression
separately from worker completion. Monitor contracts must bound blocking work; report non-returning providers as a
shutdown limitation, not successful cancellation.
## Profile testing
+4 -3
View File
@@ -1,7 +1,7 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. 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.
@@ -17,7 +17,8 @@ general-purpose utility bucket.
- Shared crash status is a synchronized Boolean plus the child's semantic exit result; set the flag only after the
diagnostic file is written successfully. Text may include retained logs plus a traceback, so the Boolean channel
does not bound the crash file's size or sanitize its contents. Keep crash-write failure separate from the primary
exit result, and test reporting both with and without a constructed application/log manager.
exit result: the flag proves only that a file write completed, not that the child succeeded or the report can be
parsed as an exit protocol. Test reporting both with and without a constructed application/log manager.
- Fallback presentation runs in the parent after a nonzero child result. It constructs a Qt application for the
report but does not call the ordinary application `run()` initialization. Keep that constructor dependency in
failure-path tests, and preserve the original result when evolving reporting failures rather than adding a supervisor.
+8 -5
View File
@@ -1,8 +1,9 @@
# 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. Persistent widgets currently host
some service owners; that construction detail does not make every view an independent workflow authority.
Inherit `Furious/AGENTS.md` and its root ancestor; consult `Furious/Qt/AGENTS.md` for shared
lifetime/presentation contracts. This 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
@@ -17,8 +18,10 @@ some service owners; that construction detail does not make every view an indepe
to a dialog or event-loop turn; an ordinary QModelIndex/source row may become invalid or refer to another item.
Resolve a multi-target confirmation independently for each captured ID: targets may move or disappear while it is
open, and later selection must not change the command. Map resolved objects back through the proxy when restoring
focus. Recursively scope table-owned menu
shortcuts as `WidgetShortcut` so focused editors and other surfaces keep their own shortcut semantics.
focus. Recursively scope table-owned menu shortcuts as `WidgetShortcut` so focused editors and other surfaces
keep their own shortcut semantics. Selection identity, current keyboard index, and selection painting are separate:
keeping targets highlighted while a command button/menu has focus must not change selection or steal editor focus.
Exercise the button-focus interval before popup display as well as the open menu to catch highlight flicker.
## Workflow and lifetime boundaries
+7 -5
View File
@@ -1,7 +1,8 @@
# 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.
Inherit `Furious/AGENTS.md` and its root ancestor. 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.
## Composition and shared state
@@ -40,9 +41,10 @@ This scope owns persistent page composition and top-level presentation, not shar
secret-bearing QR content. Reuse plugin export semantics and never log the encoded URI.
- Search debounce belongs to the persistent page: clear/submit cancels pending work, hide stops it, and show applies
only the current query. Find shortcuts are page-scoped; document editing shortcuts stay with their document widget.
- LogPage's optional Pause/Resume Updates control and logic are currently commented out. Its restoration notes and
the two retained pause tests in `tests/test_ui_behavior.py` describe the intended contract if re-enabled: freeze
presentation/filters only, keep collection bounded, and resume from retained entries after clear/eviction/navigation.
- Optional log freezing is presentation policy, not a collector lifecycle. Pause/Resume Updates is currently disabled
in source; its restoration notes and commented cases in `tests/test_ui_behavior.py` are design references, not
executed coverage. If restored, verify frozen presentation/filter behavior and catch-up after clear, eviction, and
navigation while collection stays bounded. Do not present disabled behavior as an active product guarantee.
- Log views keep per-filter cursors and catch up on visibility; metrics pages derive series from shared raw history.
Switching pages, ranges, or filters must not reset collection or create a second history. Metric buckets use the
shared monotonic timeline: moving the visible range must not regroup unchanged historical samples. Preserve missing
+2 -1
View File
@@ -11,7 +11,8 @@ resource-manifest contract; it does not govern general UI layout.
- 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
code; inspect compiler-version churn separately from the intended alias/asset change.
code. Editing the bytes of an existing manifest input also requires regeneration even if its path and alias stay
unchanged. Inspect compiler-version churn separately from the intended asset change.
- Treat the alias as the application-facing identity and the source path as an implementation detail. Search both before
replacement so an apparently unused file is not removed while still generated or consumed through an alias. Selecting
an already bundled Bootstrap icon normally changes its consumer only; it does not require regeneration or another
+4 -2
View File
@@ -51,8 +51,10 @@ 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
native lifecycle tests and the compiled fixture documented in `tests/README.md`, including accept/reject/close
and owner-first teardown. An unavailable private Nuitka counter is unknown, not measured zero; combine toolchain
inspection with native destruction, weak-wrapper and registry evidence. Report skipped/unavailable targets.
Release artifact checks do not execute this source behavioral suite.
inspection with native destruction, weak-wrapper and registry evidence. Record the interpreter, binding/compiler,
target, and relevant build flags with results: diagnostic flags can change the failing behavior and are not a
substitute for the ordinary release build. Report skipped/unavailable targets and distinguish commented test
examples from discovered tests. Release artifact checks do not execute this source behavioral suite.
- 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.