swayfx-mosaic/docs/design/STEP20C_MANDATORY_CLIP_OOM_POLICY_OPTIONS.md

7 KiB
Raw Permalink Blame History

STEP20C — options de politique OOM pour clip obligatoire

EXPERIMENTAL — édition du 2026-10-14, avant audit final et publication. Ticket SWAYFX_MOSAIC_STEP20C_CORE_RECOVERY_OOM_AND_DCC_QUALIFICATION_BATCH_V1. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT_YET_SUPPORTED ; PRODUCTION_AUTHORIZED=FALSE. Aucun contrat production, UX ou package adopté.

LAB désigne /home/fy59/swayfx-mosaic-core-recovery-qmhckba5, hors Git. Le dossier V3, la fixture source-only, ses résultats compacts et sa provenance fixent les identités, budgets et limites. Les chemins LAB sont des références locales ; les binaires, PNG et traces restent privés. Aucun résultat historique n’est réécrit.

Résultat et portée

CORE_OOM_C_TESTS=PARTIALLY_FEASIBLE ; CORE_OOM_ALTERNATIVES_REVIEW=ACCEPTED ; CORE_PRODUCTION_OOM_POLICY=UNDECIDED. L’acceptation porte sur une étude C privée limitée, pas sur la disponibilité d’une session réelle. A reste OOM_ABORT_EXPERIMENTAL et PRODUCTION_AVAILABILITY_NOT_APPROVED. L’abort est un blocage P1 pour intégration, sans modifier le CORE29baf31.

La fixture OOM conserve les patches privés A/B/C, extraction, bindings et harnais. Le reçu indépendant ultérieur accepte la portée limitée ; les mentions NOT_PROVEN de handoff/README antérieurs reflètent leur date de pré-revue. Ils ne sont pas réécrits pour simuler une approbation production.

Comparaison A/B/C

Option Échec d’allocation Disponibilité / ownership Coût / ABI privée Preuve restante
A, arrêt abort sur allocation sidecar ciblée Fail-closed par mort du processus ; session perdue 56 octets par arbre clippé ; setter parent inchangé Récupération session NOT TESTED
B, bool + masque Setter désactive synchroniquement l’arbre et retourne false Owner décide admission ; popup OOM reste masqué, aucune récupération automatique 56 octets par arbre clippé ; déclaration privée void→bool,11 callers audités Damage complet et admission native NOT PROVEN
C, préallocation Réserve sidecar avant publication ; libère arbre si réservation échoue Create retourne NULL avant init/listener ; setter n’alloue plus 64 octets sur chaque arbre créé ; aucun champ struct installé ajouté, signature conservée Tous callers create et survie session NOT PROVEN

A utilise les vrais corps parent byte-identiques ; six injections premières/deuxièmes allocations donnent-6/SIGABRT en normal/UBSan/ASan, sans core dump (RLIMIT_CORE=0). Le fait de refuser un clip absent ne constitue pas une politique production acceptée de perte du compositeur.

B audite11 appels setter dans transaction.c : deux tiling et neuf popup. Chaque échec est traité. Le setter ne réactive pas l’arbre ; le propriétaire garde l’autorité d’activation. Le risque de réactivation fading-out est protégé par probe_clip_enable_tiling(ws, desired), dont le vrai corps et la statement fading exacte sont compilés. NULL standard peut être admis ensuite par la demande upstream ; un clip vide reste valide et sans hit. Un popup OOM demeure désactivé même après succès/retour standard : recovery reste un contrat futur, pas un choix UX implicite.

Le vrai enabled extrait transmet l’ancienne région visible au callback réduit avant disabled/update. Cette transmission est testée, mais les supports scene_node_visibility/update ne sont pas le moteur SceneFX complet. Ni visibility/damage réel, ni pixels périmés, ni effets/animation/present n’en sont prouvés.

C réserve après allocation arbre et avant scene_tree_init : échec de la seconde allocation n’expose ni parent/listener ni arbre partiellement publié. Le setter active/réutilise la réservation, NULL la rend inactive, zéro reste actif et destroy la libère. Les walkers/get ignorent les réservations inactives. Les arbres externes/embarqués ne sont pas couverts ; le root embarqué ne passe pas par create et ne peut être donné à ce setter C. Aucun appel Mosaic actuel ne clippe ce root, mais la généralisation n’est pas acquise.

Les tailles56/64 viennent de la déclaration sidecar exacte compilée avec vrai wlr_box et wl_listener, pas des structs réduits du harnais. C ajoute une allocation et retient64 octets sur tous les arbres jusqu’au destroy, plus un overhead allocateur non mesuré ; A/B allouent seulement aux arbres clippés. Aucun sizeof struct publique futur ni ABI installée n’est changé ou garanti par ces mesures.

Validation C et revue

Les40 commandes attendues comprennent neuf builds normal/UBSan/ASan,27 exécutions defined/injections1/2, deux builds et deux exécutions mémoire. B/C sortent0 ; A produit les six abort attendus. Wayland listes/listeners/signaux et régions Pixman sont natifs ; le compositeur complet et les bibliothèques ne sont pas compilés sous sanitizer ici.

Six mutants sont tous rejetés : admission ignorée, abort retiré, false sans masque, réactivation setter, publication avant réservation, clip actif supprimé. Codes bruts -6,99,-6,-6,-6,-6. Les assertions des mutants restent distinctes des abort A attendus. Une première extraction fading trop large échouait à compiler ; LAB/oom/attempt-4/ conserve les erreurs, corrigées par resserrement du marqueur à la statement exacte. Aucun échec transitoire de setup n’est caché.

La revue indépendante reproduit40/40 et6/6 dans un nouveau répertoire privé. Le manifeste fixture est 4a6dfda4f61d9c9f5a13588fe7ed7ac6ec6d9720cf2167a82e5f7c39f52d0c35, sources 59207af208d13c43d0bb0aa3a1669dae697d22d20ba1199ece12817d754d9c1c, slices 6c7092197a5055136356f1fad113f213b37dfea189c024eaebd437d2819c592e. Les25 bindings exacts et neuf sources prototypes complètes sont vérifiés. Les scènes natives saved/GPU ne sont pas exercées par ces tests.

Recommandation technique et décision humaine

C mérite l’étude native future pour éviter une allocation à l’exposition, sous réserve de son coût sur tous les arbres et des obligations create/NULL. B reste une alternative si admission/recovery est qualifiable. Ce conseil n’adopte ni C ni B, et ne tranche pas disponibilité contre fail-closed. La politique production reste UNDECIDED.

Un futur scope unique devra tester les allocations réelles, session survival, old/new damage, hide/return/fullscreen, popups nested/grabs, saved timeout, reparent/destroy, animations, retour standard, input/applied transaction/present, pixels périmés/FX et shutdown. Les harnais ne prouvent ni complete native damage, ni native reparent/saved, ni lifetime GPU. Aucune intégration, aucun build compositeur ni run OOM natif n’est autorisé par ce rapport.