Files
LorenEteval_Furious/Furious/Utility/AGENTS.md
T
2026-10-11 18:55:26 +08:00

5.2 KiB
Raw Blame History

Outer process guidance

Inherit the nearest parent guide. This scope owns the outer application-child and crash-result protocol, not miscellaneous helpers. Fallback presentation preserves the original application result. Read Furious/Utility/AppMainProcess.py with tests/test_application_process.py; paths are relative to this source tree's root.

  • Utility owns the child-side wrapper used by the outer application process and crash/exit translation. It is not a miscellaneous helper namespace and does not own application composition, repositories, runtimes, or UI policy.
  • AppMainProcess owns one exact Qt application child and small shared shutdown/crash scalars. Do not add a multiprocessing.Manager or auxiliary child merely to communicate status, and preserve the platform’s explicit spawn behavior.
  • 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. The wrapper explicitly routes non-exit exceptions escaping the factory or runner through its reporting hook before multiprocessing bootstrap intercepts them, then exits the child with the semantic code. Qt callback exceptions instead request event-loop shutdown. Preserve intentional SystemExit and other BaseException control flow. A partially constructed QApplication may lack its log manager; save the traceback without assuming full composition. Spawned cases in tests/test_application_process.py verify classification, original diagnostics, the shared crash flag, unavailable crash output and intentional exits, separately from direct hook mapping.
  • The parent entry point waits through waitForExit() for only the child it created. The child's shutdown signal, exception hook, signal handler, or runner completion arms one monotonic deadline before final cleanup or interpreter finalization. Ordinary operation has no deadline; repeated shutdown notifications cannot extend the grace period. At the shutdown deadline the parent kills and boundedly reaps that exact child, even if Qt or Python's GIL is blocked. Keep the duration in the implementation and exercise expiry without a production-length test wait. Keep this watchdog in the existing parent: a timer/thread in the child cannot enforce that contract. Never discover or terminate processes by name, and keep normal/source/packaged entry points equivalent. Forced exit preserves the requested semantic result, so an intentional quit does not open a crash dialog solely because the OS reports a killed process. The fallback report still handles nonzero semantic results. Forced application exit is not proof of runtime/helper termination, saved data, or host-network restoration; remaining cleanup may be interrupted. tests/fixtures/shutdown_probe.py proves exact child reaping for stuck workers, cleanup and GIL-holding calls, alongside normal and recovered cleanup. Tests retain their own failsafe.
  • Shared crash status is a lock-free 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: 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. Shutdown scalars are also lock-free so killing a child cannot strand the parent on a lock held by that child. Preserve the child's original exit classification even when writing or opening the secondary crash report fails; report presentation is not permission to restart the application or its managed runtimes.
  • 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. Treat this as a separate composition path in tests, not a second attempt to restore the user's connection. Do not assume plugin, storage, controller, or main-window initialization occurred merely because the fallback has a Qt application. Keep its constructor dependencies in failure-path tests and preserve the original result when evolving reporting failures.
  • Verify normal return, exception, assertion, signal, pre-application failure, crash-log failure, command dispatch, cross-platform spawn, exact application-child joining, and absence of manager servers. Verify backend children and elevated helpers separately; an application-child reap cannot establish their release. If this process topology changes intentionally, rewrite this guide rather than layering another supervisor over the old one. tests/test_application_process.py and tests/test_interface.py are the contract anchors.