diff --git a/.i18n-state.json b/.i18n-state.json index 288fb23b96b..e0e8470d940 100644 --- a/.i18n-state.json +++ b/.i18n-state.json @@ -6,7 +6,7 @@ "bs": { "source_hash": "5e4e8946cf0946c08f2dc7d3a728913fc77d956c4d21f186528be4a6c18b774f", "target_hash": "fbb2df318b8aa03ad14888149e4e16de2e909ca078208f699b18ced770250c15", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -16,132 +16,132 @@ "ar": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "4f0f31b7b5b4c0212ab608ef6868c6a4c95d3d1e7bbc520dc15f50903a9f4e64", - "updated_at": "2026-10-02T09:42:37.015Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "8de5f9d4a4bfc157b554d2f90f995df7dc45a31a84d1343b9919f8589eb7ab0f", - "updated_at": "2026-10-02T09:42:37.343Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "0228c3dd63aa11e99f47c02189af16bc4adcabe1a9c9088a3773f2c0ba50b9ef", - "updated_at": "2026-10-02T09:42:37.748Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "becccce910a805bbf0d108aa2a6845499810b147abb3f317af9e0fc416fce791", - "updated_at": "2026-10-02T09:42:38.064Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "cd2325debc5e66dc9392e57de1d15ace3a3ffa9d1602c70619eb83979893d090", - "updated_at": "2026-10-02T09:42:38.704Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "7035b148c44a5f89cd5a12055782ff70d6ad50c6a4a738bd06a7c2db3506ebed", - "updated_at": "2026-10-02T09:42:39.089Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "d40a5356643085426d2069ef63d7c14113132060d651ddc91c749f30cb52f95c", - "updated_at": "2026-10-02T09:42:39.377Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "ce174acbfd6e0106e489dc99a14904589f498d0487288f84d7bdb20d0c6a55ba", - "updated_at": "2026-10-02T09:42:40.039Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "b848ec940568283cf3384f2a3b0c18361a31ddaac7c35efb64bb0d1fc7b7b7dc", - "updated_at": "2026-10-02T09:42:40.638Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "0b6071b714ed1991cdf932b02563b955f97b11f533c66679c683bf4523738e16", - "updated_at": "2026-10-02T09:42:40.959Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "c7355de71246a8adaf8561b316bcc6fcfa0bfaa5d477d5755d7d9b9be4b7cfb5", - "updated_at": "2026-10-02T09:42:41.315Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "105f929d1bc0320c5f7fb5eee393c663773b1865fb0118375bd5fb9e5283ef9e", - "updated_at": "2026-10-02T09:42:41.907Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "11acffd9e3bc123d70b2b80e7f7dc524013d96bccb57517647a257a5b17cd08a", - "updated_at": "2026-10-02T09:42:42.523Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "50e0fa5f89ef52cc8032251a1e24c27d56d7b6f544f6a914453fbe4b93ff25d3", - "updated_at": "2026-10-02T09:42:42.841Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "4c387c109a43869bcfaa6f21df7cec89ccc87ca30b18161bb246db28db4c27ba", - "updated_at": "2026-10-02T09:42:43.460Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "cf27fb82cb1d2df99e8ec4e335e6af193ab790bed8333ba709f8882d725ec721", - "updated_at": "2026-10-02T09:42:44.089Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "c57c8b14bbe139fa39a5276bec8253829144a7c7eba8167d309de432a0310a10", - "updated_at": "2026-10-02T09:42:44.703Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "b8b6e080989c98ad488943c4751836a943785f2f2da9053d07371e69aa5bd66a", - "updated_at": "2026-10-02T09:42:45.057Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "70ffdf7413083bfdd2fe07297c7f76f96f8ef167625eeafd2d404e75dd3f0aba", - "updated_at": "2026-10-02T09:42:46.537Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "5b2a7673a4ea0eb98e5b3616cc9d1dff92297079a21f355afca509c8b693dd73", - "updated_at": "2026-10-02T09:42:47.795Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "66e377001c22f7497669f39c3c582e95e8b2d3099b06bc06627533349a948a72", - "updated_at": "2026-10-02T09:42:48.246Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "c68f18c747506bd8ed3311714b353215daafdc98c927872db8a5dafd90c121b0", - "updated_at": "2026-10-02T09:42:49.503Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "120b7b8937593132d68ff3a7ed2902051c04f222a60e66c63c5b299553ed8266", - "updated_at": "2026-10-02T09:42:49.796Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "1b8ad76b8bc7407bb8173ed4f638777b1eba37110a434211714bda9f4b3dd76a", - "updated_at": "2026-10-02T09:42:50.776Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "3f83a42132e4e007b9d3f821084d50a0e2a6db555ef30c1f4fea8d6eeffc2468", - "updated_at": "2026-10-02T09:42:51.053Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "bf48cdb294cd0792fc3840ce171ae9edea2e62c1f006f49fcad06e084aed1a34", - "updated_at": "2026-10-02T09:42:51.348Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -154,17 +154,17 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "c505c451fd56facc051da2be60167441cbb6bfc44a2fcd68c7b344fd8bdabd72", - "updated_at": "2026-10-02T09:42:52.041Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "722e2e48288a019329d1a4a717a930d732823509eb103255169551c84a11e828", - "updated_at": "2026-10-02T09:42:52.337Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -177,32 +177,32 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "804d61035d21c723ee1bf484c2a627192c48c1d36204c54dd07c6f6c99b4efed", - "updated_at": "2026-10-02T09:42:53.891Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "e49f8ed10352ecce6bd9e062dd82309b41b447ad7fbf83022b11ebbe17fcc28a", - "updated_at": "2026-10-02T09:42:54.259Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "fce647aadc913533b71dd8156e6ee30d80a6491d8cf64e6353352a35a7104d93", - "updated_at": "2026-10-02T09:42:54.713Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "0195593f2edc5b1dcf50aa9c4544ab64c42857637554fefe26f97336002af6ce", - "updated_at": "2026-10-02T09:42:55.233Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "af28e78d0b9bfe476f40e4c24ada41ea3228c54309ca6f871ea5c1991edb338f", - "updated_at": "2026-10-02T09:42:55.634Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -215,32 +215,32 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "2848fab49070328c40c9878f838fb0178283161cba5543b15f4e7e279b1e9907", - "updated_at": "2026-10-02T09:42:56.597Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "81359bf6c7dda25b8adac5c7c90135004fd4d551351cee77495958cdf4434ac7", - "updated_at": "2026-10-02T09:42:57.041Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "2efbb793e2c0002d7ba67239c31eec9d31e540dc429ddbff87b8d161ae6079d8", - "updated_at": "2026-10-02T09:42:57.633Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "cff5af47ef70ec1a44c1b36872569999ea99a20bbf80859c7a4990129fc396f8", - "updated_at": "2026-10-02T09:42:58.640Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "a45b13520001af3e719d40a550836bead7c459b8321ad31f38cb12c0f0345a40", - "updated_at": "2026-10-02T09:42:59.011Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -253,7 +253,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -266,7 +266,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -279,7 +279,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -292,7 +292,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -305,7 +305,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -318,7 +318,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -331,7 +331,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -344,12 +344,12 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "e19e648bb2a2648dfdfc7995393aeea058a9f2cb1741154ff01d0b3595960c2d", - "updated_at": "2026-10-02T09:42:41.595Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -362,7 +362,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -375,7 +375,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -388,7 +388,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -401,7 +401,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -414,7 +414,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -427,7 +427,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -440,7 +440,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -453,7 +453,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -466,7 +466,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -479,7 +479,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -492,7 +492,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -505,7 +505,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -518,7 +518,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -531,7 +531,7 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", @@ -544,12 +544,12 @@ "0230edb63f1f", "067f0a1d366e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "b90b22873977a250f16576a05ee3eae11b4a6be0882674d3d368985032201a88", "target_hash": "1acf3f8f2b5ef67f4c4f612d1ef19d096ac126cd8c7aaaf464c381be54f3980d", - "updated_at": "2026-10-02T09:42:38.370Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -568,7 +568,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -582,7 +582,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -596,7 +596,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -610,7 +610,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -624,7 +624,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -638,7 +638,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -652,7 +652,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -666,7 +666,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -680,7 +680,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -694,7 +694,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -708,7 +708,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -722,7 +722,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -736,7 +736,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -750,7 +750,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -764,7 +764,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -778,7 +778,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -792,7 +792,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -806,7 +806,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -820,7 +820,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -834,7 +834,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -848,7 +848,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -862,7 +862,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -876,7 +876,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -890,7 +890,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -904,7 +904,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -918,7 +918,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -932,7 +932,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -946,7 +946,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -960,7 +960,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -974,7 +974,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -988,7 +988,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1002,7 +1002,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1016,7 +1016,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1030,7 +1030,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1044,7 +1044,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1058,7 +1058,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1072,7 +1072,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1086,7 +1086,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1100,7 +1100,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1114,7 +1114,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1128,7 +1128,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1142,7 +1142,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1156,7 +1156,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1170,7 +1170,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1184,7 +1184,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1198,7 +1198,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1212,7 +1212,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1226,7 +1226,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1240,7 +1240,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1254,7 +1254,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1268,7 +1268,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1282,7 +1282,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1296,7 +1296,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1310,7 +1310,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1324,7 +1324,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1338,7 +1338,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1352,7 +1352,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1366,7 +1366,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1380,7 +1380,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1394,7 +1394,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1408,7 +1408,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1422,7 +1422,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1436,7 +1436,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1450,7 +1450,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1464,7 +1464,7 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "151cd0ae57fb50b8a7363c084ecc4593f59c6bf73f7ef632c077e7b8c41923ea", @@ -1478,136 +1478,424 @@ "d792555d879c", "ac0e8fd4868e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, "CONTRIBUTING.md": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", "locales": { "ar": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "ce174bb3eb60960ece0b2589d9b80ac891dac79d9201be2023ab7ee290c76070", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "ed6ae10fd58301c4ea60514aa3c56e77c7ca896014220a30690cc0229f96467f", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "14b3eb09cb7d248cd1cb2aa95e7a3223f527ae3bdad30443c591865da70d5ab2", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "40cf6880fcf0cc2f4112892d267bb73737a4b27652dec088d7b819ecf7d040af", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "23d4837e002f673d0a6b0f40ccb2d19cc7d15143cd8be4aca95f8463e0bccf1d", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "1067c34529521ef5a552cdccc8b387fb491f2b152e7a28050be39b1fe542b83f", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "afa7c485773ed42eed512cd332d1c93a0920ee10f690d3002d77922ce0c6605c", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "6b5dc712820137a7258e832fd2cf46d03e871d04e91885bc3c102d150bf1ecac", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "cca0c06836f11d634514b4ff6dc21a8ef41c5c04c5b05cdc5a665a322141119f", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "d8eb0d6511bcc18e26808f769793e757d32a80842be6f262ab15f6728e80daa0", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "d37720e7aa9eeb475dee6efe8bab36f93865e6a45af91cd5884a9467a05a5437", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "7999f0491361342d13d88381b7ef3e5144b9e6dfbe092eb90ceb874b471802b7", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "f679222b7fde53c0a212e9fa2363029ffb21580a16cb68315ca64a0eb3d76cb7", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "625cc613ddeb3251f3a31088117ea564c455f9278f3c26301cd0949743dd6778", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "da051268cb42dacae70dfc1173eaa23244c8ffc7cc1a808fdb30582ca047cb6d", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "19909eaf36ebcd2737cd08c4ac6934d18ba88b733c1ce6b9d19fdfe81e83b02b", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "7a817b44949f1b5bdd090f868538b520bd9454294af6b0e294240a6e7da08bd7", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "1fb994f52d8d7d5ad2f3915b9f1897bd3e9671cce41dd7e218fd929b553e17cc", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "733ed1453eb66c989f4cac1e429fe626696ddd3c6963c9b0ee302767a681f140", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "ab5439ff2ddf2455bd6c71455d1cf374d8f455605abc2a0deb37fc6b059c0357", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "906083f14c19acea7f66db64fb79e8586917416092d3a1e7c9cd203d4be3a3c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "f5d5758dc8e5abe2da32028ee4210849770c4ce636ca7987cd0a7266461b8a57", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "2ee50b221295a7db477efb76457925980bb293f19a802518144474e5b10e541a", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "975c5431c17c21ef8a2219c8fd8fd4e671dfb122b46fd9bba8680b467d15cb9c", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "2fc437644f4dc8f0c1b1f2f631de74ea81daecaea9d72238d82a59d45afb4c1d", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a8bacc17a9f0448d3a680976321b0a35b0a9bbbac7e22916002d3e5ae9d0e68a", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "4dc6f88bbc238dd9f0ef5f1364b4d4fa6b32250f947d64da8129e301f938efd9", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "cc27850aae7adba5d1ddffff1c50ae6872a9a69358db09bd4fd0df18d39ec6da", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "4dcd3b0f8f886b8d243d29f16f993b1d8e61ca7ccc9ecee8b6f39299ad5f3c95", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "8fb3d369f7da1500aff16c39de126ef71703f4cef321617a83ec0be2ab4e945e", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "504bb048b7ec87bd8369d5aa51ec4568785cf8e680c6ec22805950070accdf69", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "2e2533e3451e5f53a0e0938eae9063b971895ce31bd2b176bbfc249525ee0353", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "d564d3a880e04edeb79b2e11679ca178f6cfd32d7cb098a10f5cc63243b16d02", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a2a618da88417896bf8b437a462e2cdb42f27f923e4eabad176189f597eb7aa6", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "663a22061c48a46380f89175a99f815d6f7ed4f7c1b489d33fd88c595772a8f3", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "e6aa5e821498e21c91d3ccfcdfd668c22513997f7bee3a1218a0b799d30a82f0", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "c2e7cdeceed51ab7f42531686fe412e59e29b4ca664703c1c41f83aa154dbedf", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a4ad117a86df80e7467bc9a2e7bbb43a1ba26fb7a14bf02d4aaebfb5c2f233f3", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "23e0320854ead5f46c2538a83ceedb0793d1de85a4a855fa352e74b6ba09ca97", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "779f4808adbc7d563483ed05bcf23fc1c44e528835348e1cf87a827f6f8614e5", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "2de4e0c8cc37a0bd26c328cf6063cb25d44cd6b7f296ee34bd831b1e8432a197", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a31c707b0809c957feda31a052b2401bc7fb2d916e921a02c0e686ab188cae58", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "6e39f0b8767ab226ac20a2138d5c7f671de87a67aae75f056cc4d87624cce322", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "0306117c853a189ca47022b29c7793eda37319d1dfcad6907e375467c4daff53", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "138c3d12dc067d18dd860a6d252604c84883ee43013cfef6ba69bc2ffe04844a", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "de2b4cc81ad78aa9b0e2f7471b83997e19582ba00948855332e0bad952bac453", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "e45af8a391429d12526075ac725e71df704b2e0fe86c7df8052caa7dceaed0d1", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "f04801ee034aa201f2b7322ec69ce2cf736d45672b8dbacec2730c27a976aebc", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "04c84625322e2f8a37a78a72cd968a58851912abd5aeb827dfc264719b1fb364", + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "d2bc953b9bc3155ad82e0996a355dcd47ba742feeb433102b609854ce027cb93", "section_hashes": [ "b02037e2c3b4", "bd62ad738622", @@ -1616,65 +1904,185 @@ "0f100572a3e2", "1325f364c550", "9d26c940c8a4", - "1e3d267afedf", + "693ce9e8849e", "ecfaa4a13490", "9c5e3db8efe2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "2cbff6d67f5c8a4b955038fabba41a931342df178ed1f42beae37e73c74f7625", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "5823dbac7d347adee78b00410222d2a56f081f62edfdecea13b565ae92f03a10", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "7d78b838eebdf089ad2d3dbba6efc07fd1069cc36d76328a1aa586d7179afcf3", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "312f71dd5c35619853c89ef9ab53ac7bf11adae233c10eef6954a31e26c65509", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "3b6668afa54a987c456c5905277994dba89669754d3b203ca7e030cf22c2f26e", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "fbeaa9df80958a5929093eae7f4b4297a7762e89dd1d52542b06b4b3d38bc5db", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "21c950a74c3ea2e381dc4135366e004cdd0a0a490ec14cf9cb11876a98629b38", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "ea5d69e9d6eb02a243399c4405180401a7e47a7041ee0008a2d9eb247d94990a", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "5b9c41c7bc9250bef56fe56b17802c04db3868ebeadd6325ae053b1a211df500", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a07e8cf4c63450e51605e1803a202de2eacf12bcb75c59c9379dc29baee947ad", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "ae5834fba39f63a24a30189408de1d3a07695c8cf7ccfd3cef6943e712d5e2c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "64fa832dc8faf569b5b9acf4a022d8c4441b8da4a162286e895e2921ecf3b610", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "c3190238c6873673344d81718a7ca3c60d768aeaf87e799a6e8ba00da413ff10", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "bdb5d1b9804ccd1e1c729ff8d8172572263d386f57450cfd87c48fc29e71078f", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "54c4e3b86e8ee39ced8380751025b6b8317b52b41c0633d9fa9434a0764dde42", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "52f06bd140e475cde0cab817e9da341164223dc68e076392ddcf65b57ebe5878", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "34cf9e920237c7584c975e32c7ead609f92d427f84311dc6c86433538e4501cb", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a9b6816840db0860486b51ee3ec877772c77ea8fc2890efe60650fd92395b9ae", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "e399bf9e47c3951b8e6d27a9754c83611ff28b311b7c5a4fbccd3c769d26b2d5", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "e3b2fce77fe2d4319638960b9794e5b8f97952f4578849e727ebb06be88acc32", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "2d93638fbe8b3d8a7de4d73bd1302cd0c6edb26db8a6f445b389e7d20de4eaea", + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "c81984e8895bd5cc58f1256c73dbab020afccc20ef428dabcdd5e4071acac27b", "section_hashes": [ "b02037e2c3b4", "bd62ad738622", @@ -1683,30 +2091,66 @@ "0f100572a3e2", "1325f364c550", "9d26c940c8a4", - "1e3d267afedf", + "693ce9e8849e", "ecfaa4a13490", "9c5e3db8efe2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "8cb92d89003fc7524211c239ef9403a9d56ab34a3b797c5545386543005bc260", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "3394a3bc83234c943dbea2c62fd847a78ebf1e14efc50065c62f5e8e713d8ed6", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "5b4aa19706b3f58a9d49f23696bdf31703d7561e77d282a5b8d0dbd4b8cdea5d", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "6458b64238e8cddfd36830501cef8fe240f1ffc9958bdac3709b226239d2654d", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "7668b254b67cc5b793477dfaa82029c8dc5dfc757306f9d4ddaa58647cd4841c", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "2fe5da84e3acec289ac1b74bd4b57f4dba61360fa8d697337f3542ea0debb433", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "7beae5f17d69a8dbb0fdcd656a63feae5048170baa265de51094f4a4c415749d", + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "f0c3f9ae736b6aaa1e3cd28fb9c19834912f8c992cceec8db0daa101790a0f7d", "section_hashes": [ "b02037e2c3b4", "bd62ad738622", @@ -1715,15 +2159,15 @@ "0f100572a3e2", "1325f364c550", "9d26c940c8a4", - "1e3d267afedf", + "693ce9e8849e", "ecfaa4a13490", "9c5e3db8efe2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "c349c421a665ea22b3b8067e36a2d300babd5b451edf259b4621b571162f0e73", + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "2eeac88ae0054aaef6f7d53ccdab8003c05dd534427247df3fd93e9ca2ddc32c", "section_hashes": [ "b02037e2c3b4", "bd62ad738622", @@ -1732,55 +2176,151 @@ "0f100572a3e2", "1325f364c550", "9d26c940c8a4", - "1e3d267afedf", + "693ce9e8849e", "ecfaa4a13490", "9c5e3db8efe2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "08d928654d50fb20606ca1283f303be1edad4a578d41007096f79a457a98f609", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "4a1e8c15cf67a994b6a1ddf702958208efb597ac2d59015e7665010d2e531e5e", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "e0461fc84a567a7e330b882dd382f8df7ca6c74b889452d240acf085b50cfabf", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "fc739273adae641159ce47d982c826aa0528f9e5a6f3b8eb4972f860ae7d9635", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "334ab4b0be862588dffc2073dccbcdc5c9d3fc50d5c61cc46a3854c88a4b6e65", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "fcdcc324b0ad1c98e131228231e7cb5212efd750e294ed4c8ffef586126475a1", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "324699402260a74b322f654f58ccf04e15f260ce5e9b2cdf266489d2e77487fa", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "4f5a93297ded66aa7d33e9fe71c150beb0861ccb2221b4857e0b0d6bc3bacc4a", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "c75857a116bc2e5e2d47fe61284aea36172c2acb650b79293c11abd514162572", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "b1269b1471cf5795b5166767b8246af4baced362e104036e4e2cf1d4d25c3ba3", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "eda56dc2c6c9f3713e94d9d3fe63d18f9dad964fdafacdba3be0110edaa94978", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "14ce11f1289201600ead11275dae000f55c302d7a9ca6ac22e7ad4193e92b64a", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "85fe2cbb59de96b8c8583cf800df9cbef3abdf2cdc5a4e78981f3efd5c66aa10", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "bbb991f30ad9960da4b5653dc678fb5895cdb2a116efc04440973834140682cf", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "8f451ed4f4a652a0af4ad47e5d0f60e7cd9fbc7ea3204ada11e979f1f3c6c7d7", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "cf30574c6226f7566230663b20646ca6caa806aa448036f95df721c48415a8cb", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "dc3f0ef5a6e42072f0b73e54e11ed08538934ff92f5aa8b886e566cb51c8584f", + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "a6e33dea4f793d07a43a5ba75b3c73b86530c55ed78dc0ce6b57d6a61018dcdf", "section_hashes": [ "b02037e2c3b4", "bd62ad738622", @@ -1789,91 +2329,283 @@ "0f100572a3e2", "1325f364c550", "9d26c940c8a4", - "1e3d267afedf", + "693ce9e8849e", "ecfaa4a13490", "9c5e3db8efe2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "bdccd6eb2c7e840f53b78e19937cc823959085533743a0f2c2f1de2b628d9901", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "2b605c8884592e1e5aa1f28b404b43cb11a8706b3858bde85846ac8aa0dd2051", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "a981f438b79550a2094523c078a1e093b84b73ce9584755b3d791a513c56dd02", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "30b9b133f5e99c341ce187d9547c6c1743945e307224c0eec0a9a82be924f42d", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "8daa8020d21accb65535f9ff19ea753ed3a72b07b01b0cd02ce4c20bbfc1585e", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "042d144312fdeae0dd68db7c72afce7b9df9f09b9fbd7826f8a14d8566151688", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "5ae57afe7aa6efe1809b5a7c8c0946f11f57d8f01bf1d3391e10667f380a1ad4", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "5cfad4e47e4d9eee92bd1c5748b808c0991fec7be9ac83e7268a2a0a6a9c493e", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "aee927731d833651c2dc882cedba9ccd56323bda6c0179617e482cf323b48bdb", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "6b730bca2f1819dec82a4b8f836b16216f5d0ba5645fffdacec5a2f92913d937", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "1d451dd7be81133662e432c3de793aaa719cf58ec8a40f927a7b9e21f98e42de", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "c87f9e2b660b2d3616f367d4c0f13a2b25350e62fc6c6aae45a65a83dfbc2257", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "15b0d515f5b170faf17582c537a1c756f133bbc0ecbba6857d9821350be3b438", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "66f4644d080504bd7ba8ffabfffd572e87d448ce2cc8c9184605df4f20fd7761", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "5b4d2109bc9d40ef0109a5f4c081f63fc2e5e3f2482367ef99680623c8c39913", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "7559d01ece5d07b6cba81de96c027dbadee9fa87f11afdda3e6a1015c00b07c5", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "38a249bca954a7f503a7b14e0c0bb06f15104eff19010eed89aa1b24638135eb", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "0ffcc3fee8ef30416b289e29c09e52433bfa072803251b080535742129d4f637", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "29dd140f3c62ca8339c113a3a588bee9241599416bb0a7a3946cb02a57a087d1", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "9d9af89798f16d9282e398fb4711394d236a3072367a8cf4622862808fd6061d", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "d8128e982bef46b44a3a13d8fef2d8046e2716708af0173d0b3ce5c0daf0731f", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "623052e9bfce2ef5d98302437f4c327a36240856754a5fb460a40d080615411d", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "2da8b37d6f513457ba606d7170577acdaeff349c8723afdba37528a97278e2ed", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "1dc2f2ade0593b9623a7f05a6d5d7239e2decbb1d8bb665b4c0aadacee91b9ca", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "0b09496656e4826b22d829331ee4ca64b2cfe339d8e49bd6d5d6a06081cb6608", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "b1b099be4748c02750207354e1d7ab0e991584586ea6d759071687f7ef6ebdcb", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "13887af54863f3f5f9f3033e5c7e212c162950e93236c23615a26ba17d3b1d38", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "50cdbc998df48ffe256be2b69341e729525b43437a7e1413308f9325d7a5f08d", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "b42256d732bd9f9e85b8d3340ea4ac126c3cd591995a9fc241a4990440f203b0", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "028c8431bee80cdc897a508940be795bafa741f4dc36cc3d23b2da8a15997185", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { - "source_hash": "491d19cc41c8a7036a4d44f98fc6f487a12f0b9dc212e17e881f948b2c3c0078", - "target_hash": "05e92e85b705c89f70340cb50af050e25b345504c075d28cca10eb79a4432ac2", - "updated_at": "2026-10-02T07:07:52.756Z" + "source_hash": "d102a87d79ae29150c8884d9e5df5aa054d0fe53f7c22ddb5eb930edbccac80d", + "target_hash": "056f56983f138438ac58e3541fb289e322288476a040b044b561c0717c431f84", + "section_hashes": [ + "b02037e2c3b4", + "bd62ad738622", + "0aaf8cbdbf9f", + "0273a7b0a44e", + "0f100572a3e2", + "1325f364c550", + "9d26c940c8a4", + "693ce9e8849e", + "ecfaa4a13490", + "9c5e3db8efe2" + ], + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -1884,394 +2616,394 @@ "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "8393bd10d30059c4cdff7ff6360abfdaf1f82d9ed9f00f574b33e5d0e135b5dc", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "bdccc5f6905d67a6fad2c082f3fa2cc26c4eb9786e5ef9e8259a8dd6c9170fd0", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "29f55cb97fc23f3f5b92bd08f4b623d8c97e96385f987578f6c0b7d7cc12a9e0", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "e743b06ae20916bebc8ac1b271759db8b49b7f0ba5178fb4382fafd997d930ca", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "e6d3394e25af79cc1052d3434eaaed6573a915b7224b5ffb599dfad5b371e0ef", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "9eed6bd975c951c595102347a6c848edb2565b143da75872809008715a4c2f11", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "fc586eb01c421831cb1023105f284895f5857e35c87065410b466598595f43d5", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "3c89b53619cd22f0301b76de5b177a2786de056aea87a4be411c4f09c5193f12", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "c13502d9200f2bd49395e833bac9b6d746e9d635a817f5cf0d0c41f8bb48e63b", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "a1fc39423ba1b9c58a811634936de163f52e9febd246983550b6aaaed82b1c19", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "75409f66edd7e3e65953af59aa4cc3223013ff5430f84995124ce87be1918788", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "622bcdc41f56aa7a0eefd4a0d2a71409cb1913d4e1f7ea01aeda48f275d9db2e", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "86b6d6df9446675390d2cd328e61815d7d2178e2885edca8803c79a7e5e09ff5", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "838acb03935e24352239f37986c203e16bea751d617d6d11b0bb9199c1a58d6b", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "6d4d82817dd8a1a039ed99da3f373b12457ad73c0bcde71bb1d6feab957afdbd", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "26a7f8e4e8495fca6428a9a7b5b6c5be87eed3ffdc9f03c08b8d637d7c06e2c8", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "16ff8b0578d04b83d7ba9853b905f2c0b6fab2c8d731c7ef0243c415427abed1", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "f9399236b3666c87ccfc4a13dc16cb0570fdde7eccbbe4b9e33c8b5d92eb41f2", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "fad9d4a5da76d2fbf0e928e56ced1ac32f13537a274e88d66660c7a5db8bbfba", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "1d53c5cf5006fd37d88990ae69c7d2a6e4a7738940719ced3583408810900858", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "a0d30915d2f828ed7b107ea896a1c883adcbf83cdafaedb8d7c41292ed44e4b1", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "c5e7e02ccf2d256c849f83d646e714782673d856e4db4a76129933c03195e14a", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "51622d32ad04268713cd290dd7e28bee9657863294c89527f9e523f567f02a03", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "8324bc06577ee1df84e10943219f3903381424cc0f28b3bd0ebb3c6346562504", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "73670c81e75c834fef18f3cd38e6297db5cab9a93a683aa48868af70dbcb75fc", - "updated_at": "2026-10-02T09:42:51.053Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "89313e08e45f81bd7c2521c904904d7b7f665158854dc74afb9929f306f0c1e4", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "c953a2298561c0aac8c3d9ce79f9baef87578093f1d375721513e9ec95f6e598", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "9e8bf3106270a095e47470704f0eb7c7d2bd359e81c14e51bde720e8809ae3b2", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "ca3e945fecd3c957f3470ca112068a30cbefcd4f60be7a6fd27ec85cc8691238", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "e6721b2f0a9bbe9f663567020bbbb5ff289f7de1983e693fa786300371730eff", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "b3173977d298e7dc519576ec2dfd1e1fd6c3dd44672f278d0bacb53768ea1544", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "6b5514325b0a0d47227a18defb160e39a29671a665545e5555e7123597668b61", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "101a010cca9851e2149c38a515fb30e721e6baff9412a9396c215ecbe4b32460", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "bed1ef3e436487853aff00f931491fd0551aba1b70a8b71a9cfaf68c19448377", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "115c60c7c310a897fc05832a5b3921cc0113c22321fa96a1df4a72294d47fc6a", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "ece05f792486fddb17967819bac3b4397b4a62adad2c70525ba8799c6af3e0dd", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "cd22e56a7157acac1ca243d8b29a87dab1f57cdaafa8e7d04a61db7b344e124c", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "1197f2fc4abb1772b7a16f745ef3f6e05489eee371c9223396924248088eb342", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "9bca33b3d93f8445c77dbc2c8b8e1639fd7e83eaff984996b0692b3702c45c03", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "2c460af294fbd5f9b691797c97d26fa0d4244e6ed3ffefa9e8c7127acda4676c", - "updated_at": "2026-10-02T09:42:58.640Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "db99eee937ebc21867e94db1189403df8b8c4545bddd9b5799aa3b61e556e3c3", - "updated_at": "2026-10-02T09:42:59.011Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "a10232fe78df4dfab3689ef36d089078df5dc46f443ea97f174e069179e3765c", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "f48c99968502c3eee2959f2522d81fb30ae550b66b4c869b2b2340dbe6780a5f", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "76230aa5374fc1510777e2456203fe70b6b03d257fae1656978b0559170a2012", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "6bd25b48ca1beb81702802c707dea909aa3ebf63d583c34e6e324bcb4a05ca33", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "3b4a820dd3606eca6781ee8a0b400d9050401e6219f22cd83e13ed6e167f931f", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "7a3f9c31d86b36fbd1df733995165476e02173ed11123f7b9b99e4c9e9556f89", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "6b9f773e30563fc35e8ffa20233e090e1b62c779343d1ef6ca975b51f580d05a", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "c3ba30662c2812c1912946bca9b17f7c86c5ee07b6b44082b297d24c25170b87", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "a631a06dd18f2b44092b3eb3338e5a5e1765a0eaea6ad40beadeabc7dc13a7c9", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "b66adeeb3171fc9f0561c81e563f4ca10c4360790d2206773520eaf8f9a36e2f", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "c0dd8d0c07cbb5c674a67e6579609228c440535db9c0fc3d5b707c008d621588", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "760a2b2822762f089824ace7f46e7c052e42aa161446ce09cd92f4bfb8b7a93f", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "dbeaa0bce924ee5b2e5ad2f008975cc02389d33f2063cf4cebddcac9a523deaf", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "6dfdc4669324e0eae97a486b18bd0df8b091d08b72a01363c5ba766d147063a6", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "272208b51eac814bd99e8d732ba1c8136c30bc16086cb8f1379a2c59cbc9e9d2", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "5027ca9917df9d11597d17414c526c0f857e693feff3ea5ed9c7b1b7493a2387", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "fffc59f0bcf8b8572ae480820f7fdeb2ecfafefae8e043f954fa80b7633ce4f9", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "44fc0269e2aba43d8e4a745363d85f35b5abacf873c36ad61dcde1f31d11cd83", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "4ae72338a63b9afd5dad5ce6126fb77cd3ebdff1601a189aa8e9f34ded2f388e", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "b8dd20c7405bafa97a74dd926f045dcaff6591343be51daab328ab762050fb5b", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "e9f71767182fece8ddc093f06e02f102dcfd3e950377e2a20c7ae3dc8addca21", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "428096f6a3178b94b9780de7a63ebfa7b6d143221ff8c4791ed2d4fc0d7d5d83", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "6ac7a0a2f9aeb1275515de76cc9958925a9e23b8155900f6fdec89ee44240651", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "07dfe09a4a0c9361135b74dd936e87fd309ac483c5e9c62e3b0e4f635941bf05", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "8ce18538a6fafc686015b9d5c69e0f9f0f9ec4465173b96d09f5502067abaf1e", "target_hash": "3c0e55090ae04d6f60a9ac135a7e57580762a816ef4af319bb07e80f71ace7c7", "section_hashes": ["5f35908464cf"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -2281,332 +3013,332 @@ "ar": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "cab6ee32d19716326a98b56c84c3cf5c5e6e80db70794d716d906894579434ed", - "updated_at": "2026-10-02T09:42:37.015Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "c4686e545fb70b9f3f1fbe4c5c1201ccc135b2123e599db942be6dc56ee8c0ee", - "updated_at": "2026-10-02T09:42:37.343Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "b682ba94ec6d6418f1da5e2d89b696426b6ed5960627eb76d165e6c98e98e1cf", - "updated_at": "2026-10-02T09:42:37.748Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "c01eb33babbd3e0762392ccc53fbdc1a8ff7af6aecc105ec5c26bd369446d427", - "updated_at": "2026-10-02T09:42:38.064Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "1c23c35ccb3560d5e9757d1cbdfe5f680bf9ea1255939005bb1df7e46f9f3d24", - "updated_at": "2026-10-02T09:42:38.704Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "eaed8e04f7fa2638e83167ec6222be160393647bac756d84606bdd3165f46b98", - "updated_at": "2026-10-02T09:42:39.089Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "a7d3601396506bdc08fab3355860159a2a7e5ed67323cfcb8516307417e5e971", - "updated_at": "2026-10-02T09:42:39.377Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "b884647ffda8cacaa4a755d7d86c9f68c383119398b62e5b34b3eb87f6d35ad1", - "updated_at": "2026-10-02T09:42:40.039Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "244d1da17c1b7126a2c0e22b873b29679390cbbae23e94fe00fbb14586228159", - "updated_at": "2026-10-02T09:42:40.638Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "356c1705ce89927865434c23ebb6d57ec4cb581579484a9412d6b41a5335b7ff", - "updated_at": "2026-10-02T09:42:40.959Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "abd4e122ae22d6eb67a501b1bdf05974363ed44aa335a9c684c9d427a81d02b3", - "updated_at": "2026-10-02T09:42:41.315Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "3ff7fb79dee0b3496ac101e42a84431820dd9c161925e78ad164d905ef0db67a", - "updated_at": "2026-10-02T09:42:41.907Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "93bf0921abbb4da442f25fb7c09f0a39c39d52863eb5a141bfd90dc279aeecc4", - "updated_at": "2026-10-02T09:42:42.523Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "d6d32fa4276705f515fe3f9bd909d7ec4c7543905d2327f0fd4f5a7e5971f39c", - "updated_at": "2026-10-02T09:42:42.841Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "ee4c876a980cddfa85d7e4c7cd0999fc139aee93d4f89315a435cbf9d7128f32", - "updated_at": "2026-10-02T09:42:43.460Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "56ddda1186a93da960fe049c211c8899f994167ea2939658e509bc2d13798363", - "updated_at": "2026-10-02T09:42:44.089Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "df9efe96eebc44a2e3127aaf138d158b90882300adb48034d18e1f180ac38b87", - "updated_at": "2026-10-02T09:42:44.703Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "10741e59a44fc8860e7ae26803bb93ae919cc81b0f3f298cc5009a47a84b6eeb", - "updated_at": "2026-10-02T09:42:45.057Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "06631ee10a9f8f936c74f029eca6f93bab212606ba34f076e770dabb315aa889", - "updated_at": "2026-10-02T09:42:46.537Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "b682180a2dc8375f82cdf75b377d170836ecc45a9f7fa654f104a8d0d560d7c9", - "updated_at": "2026-10-02T09:42:47.795Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "e4253c91d95b31736b6d091acda8bbafe156ea1ae923033bb8b0fe60b4898799", - "updated_at": "2026-10-02T09:42:48.246Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "21d138030b0c8994d4eb5b5bd074caa0a0734c7a87f5e223b3096c08ad999807", - "updated_at": "2026-10-02T09:42:49.503Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "a0513cc76a7a92d90ef6f865d9d1f2b8e06449c846e547a3fc23ec1993d55bc7", - "updated_at": "2026-10-02T09:42:49.796Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "9bbe1dca5e47f5f74831157916f861d247f0cdb04845b368efd8f9eed4d49bb7", - "updated_at": "2026-10-02T09:42:50.776Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "ef058c7437dac8b520b55441e0f1fec217b38ba682826860ce7bde862527aceb", - "updated_at": "2026-10-02T09:42:51.053Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "33d691043c025628fa5f0db352ece6fdd93131293a1084549e70f6f0489471e2", - "updated_at": "2026-10-02T09:42:51.348Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "4ea34d95fffec4304e2a63fab05b887051aed0b1f23ed370871a01147c45cf85", - "updated_at": "2026-10-02T09:42:51.687Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "0f2529addd4a159c87ca6bd5704bffc46667d31a0306ac384faadc6c6916f4ce", - "updated_at": "2026-10-02T09:42:52.041Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "a4531b52684018c94d2b71982f788064a0269c3235feeb0ecc624549a007638f", - "updated_at": "2026-10-02T09:42:52.337Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "018ecb61cdbb73e79fd22087c03445f303f76e5c4c11e8710a413362b95b4941", - "updated_at": "2026-10-02T09:42:53.027Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "3f3d77ec27a18f162a76ff9a7d02c83055eb59afeb0e69672f8c836903daf7b6", - "updated_at": "2026-10-02T09:42:53.891Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "6f531e07d11dea4017af33021047b6945188174aeb33273eca0734eba8e00d85", - "updated_at": "2026-10-02T09:42:54.259Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "0746ec10085448dec8f965912ebf4b0c3e7a23c6e2fd4c97d5466b225cfbee3c", - "updated_at": "2026-10-02T09:42:54.713Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "952cf00e23229b6df08dc03f63a6ee0a86bbbe959ae83dd7d87af113cb326c92", - "updated_at": "2026-10-02T09:42:55.233Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "bd9b7c782b8bd348c0194f2ef1c625aa9716ba0c95fd741885a79b1f7d92f265", - "updated_at": "2026-10-02T09:42:55.634Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "dab3ff7b6264feeaef0d21a096866da63bd978b1945b71a6c10f49a7ecfff7f2", - "updated_at": "2026-10-02T09:42:55.980Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "acd71206000f003b7ffdbbaefccc6df9cb7bc16f80b256eb8ea8c692c3cb97db", - "updated_at": "2026-10-02T09:42:56.597Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "d1bcf55b8b497e79a383c4fb0acb28323feae5e79489803a7383c2aa8cb11dbc", - "updated_at": "2026-10-02T09:42:57.041Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "229471054251672cb042ae16f61cae525e4c3a4076d8d7d454bce1aa511ef793", - "updated_at": "2026-10-02T09:42:57.633Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "660dfd19ed9bf1e300232b0cff26d909e42139ca1bdd0e53383ca5c34676bffc", - "updated_at": "2026-10-02T09:42:58.640Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "37314f1f235c941b2c963a62adc5aeb0dba38fb36892851797ee9d4efbd43d52", - "updated_at": "2026-10-02T09:42:59.011Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "acf0e131ab1cfe343639de6648e082540185dd6e7b2e80e49f40de6a9d210f76", - "updated_at": "2026-10-02T09:42:39.752Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "1a87dda408797347cca368f2f531b36995d68e9f3c36db7d9f81057fcf077a0c", - "updated_at": "2026-10-02T09:42:43.142Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "aa0c78371e05f140c22819ed471a6475083b2e72532af6aa5ba867e621b6d37a", - "updated_at": "2026-10-02T09:42:53.601Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "9a98bef99a65fdacba05e2908b122091ebf53e05cb1fbefa22e4262f7ce4410a", - "updated_at": "2026-10-02T09:42:46.846Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "c4f2473991aada0688cef2d9279a89c11cbe10aece2d5092768e180b211f15bb", - "updated_at": "2026-10-02T09:42:40.339Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "5a4820d06e79c3f8b644caa23c14f8460e720fd5cb06f271e5615dbd624c867a", - "updated_at": "2026-10-02T09:42:47.172Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "db8453b814c264352031e1376965ae2412ed856854db2ee4d0a1583541cddd6a", - "updated_at": "2026-10-02T09:42:53.304Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "92f592af9133f15cac03426196a0e2888e80678e2cb37c8f27daf554c3fcea3f", - "updated_at": "2026-10-02T09:42:48.595Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "1d3d2009face9c354c2e736227641511cf404432f18f73324a366fbb1a0d2864", - "updated_at": "2026-10-02T09:42:41.595Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "563f5e62ebdb11bc55222256781c47ab42813ae03e64540372cfbbd97cb55bfd", - "updated_at": "2026-10-02T09:42:46.142Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "783994532a029004381301da48048e7a886b4407ac88b9074e4a2c3f044a9df6", - "updated_at": "2026-10-02T09:42:47.491Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "7c7e1db8c9b20f0b76698a68bb0c5f1754ede657ac0520695354834b56c190e7", - "updated_at": "2026-10-02T09:42:50.108Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "f3cda59d0b39b6524a579cc21421af3fbb416b7c3f8b352dbc3f2275457374e9", - "updated_at": "2026-10-02T09:42:50.446Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "7fe3447784aadfc0e1853982344eafaedadc262f98c41f24ad119f71513b3338", - "updated_at": "2026-10-02T09:42:49.201Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "cfc71dd5eddad9674c815b2abeaae0172a83ac91ba605645447d2d83e24cdbe9", - "updated_at": "2026-10-02T09:42:52.747Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "69169c793f22a09a723ac974a344c518d32196a2148e6b3eb58d0434b90fc7a7", - "updated_at": "2026-10-02T09:42:48.873Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "18b9dae4c3b6b86c0c7413b32ce4a175b38aa90bd172d5049cd3374185b729c0", - "updated_at": "2026-10-02T09:42:45.808Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "86ef9a149758112b9de44db2c0c64e92bcd33d4c0db592735efee2ed147e21b1", - "updated_at": "2026-10-02T09:42:42.215Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "6a2fe0b2cbbb7501ef32ed3c0900fbf674f173a84d1349a7094ccc78491138bd", - "updated_at": "2026-10-02T09:42:58.138Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "ced92ddf4068d9a6fc6cfcade06b8728fa56c543651c4c80e64ecab1c250687a", - "updated_at": "2026-10-02T09:42:44.362Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "ee0e9cc5199ef9f8c0e5d5ed40a7a9d7e869ed69afee51f6e71f4b4f43396ddb", - "updated_at": "2026-10-02T09:42:36.672Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "8e9e57285845544d348ccb31b48877e63c1eb54f7d56f3a5a20edabc47b08ef5", - "updated_at": "2026-10-02T09:42:57.330Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "a65653aad737eb0807ee26907b8f292ff867e51c7e8e7964a5302943d64051e1", - "updated_at": "2026-10-02T09:42:45.416Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "2f6bcfcaf3a0b938a5a0a0d31e6ac88ce1324176a0ce0f3b7a5bc3ae9d06594b", - "updated_at": "2026-10-02T09:42:43.784Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "64768029327b60fb281f2bbbd8325bc267aad08b6bbd8b7458118fe6070f6ed9", "target_hash": "56af81870eead22ca2f5ffe207f7e19a389f287b74d3abb3303809c5262b0b03", - "updated_at": "2026-10-02T09:42:38.370Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -2628,7 +3360,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2645,7 +3377,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2662,7 +3394,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2679,7 +3411,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2696,7 +3428,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2713,7 +3445,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2730,7 +3462,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2747,7 +3479,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2764,7 +3496,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2781,7 +3513,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2798,7 +3530,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2815,7 +3547,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2832,7 +3564,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2849,7 +3581,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2866,7 +3598,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2883,7 +3615,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2900,7 +3632,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2917,7 +3649,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2934,7 +3666,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2951,7 +3683,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2968,7 +3700,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -2985,7 +3717,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3002,7 +3734,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3019,7 +3751,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3036,7 +3768,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3053,7 +3785,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3070,7 +3802,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3087,7 +3819,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3104,7 +3836,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3121,7 +3853,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3138,7 +3870,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3155,7 +3887,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3172,7 +3904,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3189,7 +3921,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3206,12 +3938,12 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", "target_hash": "0ea2a72ba015a38091ecd950894e8de53a01e2a59c7997735194e9c4c66453ba", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3228,7 +3960,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3245,7 +3977,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3262,7 +3994,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3279,7 +4011,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3296,7 +4028,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3313,7 +4045,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3330,7 +4062,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3347,7 +4079,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3364,7 +4096,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3381,7 +4113,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3398,7 +4130,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3415,7 +4147,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3432,7 +4164,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3449,7 +4181,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3466,7 +4198,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3483,7 +4215,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3500,7 +4232,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3517,7 +4249,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3534,7 +4266,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3551,7 +4283,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3568,7 +4300,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3585,7 +4317,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3602,7 +4334,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3619,7 +4351,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3636,7 +4368,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3653,7 +4385,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3670,7 +4402,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3687,7 +4419,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3704,7 +4436,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "66fac7b0f9f34ac357594dd3c394616281d5c0cb31ffaf96d2722ea277a3971d", @@ -3721,7 +4453,7 @@ "62b1ad888029", "9ddd813b41e7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -3738,7 +4470,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3750,7 +4482,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3762,7 +4494,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3774,7 +4506,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3786,7 +4518,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3798,7 +4530,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3810,7 +4542,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3822,7 +4554,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3834,7 +4566,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3846,7 +4578,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3858,7 +4590,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3870,7 +4602,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3882,7 +4614,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3894,7 +4626,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3906,7 +4638,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3918,7 +4650,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3930,7 +4662,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3942,7 +4674,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3954,7 +4686,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3966,7 +4698,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3978,7 +4710,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -3990,7 +4722,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4002,7 +4734,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4014,7 +4746,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4026,7 +4758,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4038,7 +4770,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4050,7 +4782,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4062,7 +4794,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4074,7 +4806,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4086,7 +4818,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4098,7 +4830,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4110,7 +4842,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4122,7 +4854,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4134,7 +4866,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4146,7 +4878,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4158,7 +4890,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4170,7 +4902,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4182,7 +4914,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4194,7 +4926,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4206,7 +4938,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4218,7 +4950,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4230,7 +4962,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4242,7 +4974,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4254,7 +4986,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4266,7 +4998,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4278,7 +5010,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4290,7 +5022,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4302,7 +5034,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4314,7 +5046,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4326,7 +5058,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4338,7 +5070,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4350,7 +5082,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4362,7 +5094,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4374,7 +5106,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4386,7 +5118,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4398,7 +5130,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4410,7 +5142,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4422,7 +5154,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4434,7 +5166,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4446,7 +5178,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4458,7 +5190,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4470,7 +5202,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4482,7 +5214,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4494,7 +5226,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4506,7 +5238,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6fe1440747e67daef474f4fd1c869e1a8623cd178641a83a4099085829dbf084", @@ -4518,7 +5250,7 @@ "0ba973060355", "98731b3c0167" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -4538,7 +5270,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4553,7 +5285,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4568,7 +5300,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4583,7 +5315,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4598,7 +5330,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4613,7 +5345,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4628,7 +5360,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4643,7 +5375,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4658,7 +5390,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4673,7 +5405,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4688,7 +5420,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4703,7 +5435,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4718,7 +5450,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4733,7 +5465,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4748,7 +5480,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4763,7 +5495,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4778,7 +5510,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4793,7 +5525,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4808,7 +5540,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4823,7 +5555,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4838,7 +5570,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4853,7 +5585,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4868,7 +5600,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4883,7 +5615,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4898,7 +5630,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4913,7 +5645,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4928,7 +5660,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4943,7 +5675,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4958,7 +5690,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4973,7 +5705,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -4988,7 +5720,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5003,7 +5735,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5018,7 +5750,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5033,7 +5765,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5048,7 +5780,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5063,7 +5795,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5078,7 +5810,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5093,7 +5825,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5108,7 +5840,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5123,7 +5855,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5138,7 +5870,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5153,7 +5885,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5168,7 +5900,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5183,7 +5915,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5198,7 +5930,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5213,7 +5945,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5228,7 +5960,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5243,7 +5975,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5258,7 +5990,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5273,7 +6005,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5288,7 +6020,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5303,7 +6035,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5318,7 +6050,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5333,7 +6065,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5348,7 +6080,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5363,7 +6095,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5378,7 +6110,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5393,7 +6125,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5408,7 +6140,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5423,7 +6155,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5438,7 +6170,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5453,7 +6185,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5468,7 +6200,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5483,7 +6215,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5498,7 +6230,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "440546e20dc2217adcab9d68378cc95488e40669400fde7e5d1f13dfafaab1bc", @@ -5513,7 +6245,7 @@ "2f04adfe418d", "7a512a6354a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -5524,397 +6256,397 @@ "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "72d77194af16afaf3cdcc33f0670cafec245f5e23a3ad84dc2ab05f6d0acfb68", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "0b592581d70c62467f7dbd5b32ee65ab3599006d89a00b53ff45fc5dcdcdd76c", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "5ee1ca838ea6deba52280824f108b33172b267f3f6fcb70eaa97775338e97f49", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "80076b7c2b501a47f0aeb5b2f9df86768b8c90b0f35c54ebd045702450f1bc25", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "8fdc0d8fbc386d61795502fe9b3387eb457a5c815b103a6a4fefc51fcfe5adb7", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "3331b0ed700590ab6798971f4f59641c1c24303319215374a243696788f31fdb", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "a72e5ee15fd7b2bbd9553175d78c2bd68513745faa3b35202624b76da6d2b155", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "ed90c941fd126908f53cc402afc903d3c5a14f65c431a3e36b630a63ed35c6d5", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "53c936217c3d50248036b7150195ec29a1c6599588f1fb8081273dbe19a29300", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "d1b6ed59d5cf7cd562d0e8e90e5a48fdc6be0641a92d319b16e53bac4036eea8", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "58890b545bdfe849da1890fbe35bee4f769d869095d0cadfefe9089031d2e8aa", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "5c379a7ffc5ae8cce9864f0d1dff599332c7a216d64c99c6fefd63d0ab2ef227", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "1bf9c2668b2a8ed5ca9f6bb2fc0b0b0420d7a0c4d4e056c5d3e312794676b302", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "04960348089428ab312ecbfdb6ed2220649688f5377e6b96d502d406a87ca0b4", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "074925f69d9611488cb063b7da7423d7815ae7f4f8f45eb17645247078828942", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "1c045e88c0bba9a7c5420404d5bc8f05165cc917235f77ad3e7e8c44ce2ce9ac", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "357cb060eea1542e1fd9fef63a9536f2a6bbab5ae03a523b5c24f3f26c1c73ae", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "0fda10d0e6278a38ba3a6ccc50999ad44a7100a9cdba78ff0d76e22d31000f29", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "3b5b88e47664800e3cc6517513bf7c7a8d6305129580ecaad69caf8c410ae038", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "22894ee5d2b35e4905bef1c08a926c551b85b54ebe673f75cae73e035cdac296", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "e5693eb3ecb74b714c6fe4161e8cce85d91636412c178dbe3fc71278ed4bb496", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "c84fd0f897b353cf669e8641f62147632182701e1a1094fd32f95edbdc24a2f1", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "0209588690e45dca916c4deef97f21f06a48f6e7df69c074d39ab8b33936ed1d", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "55b5019965fce99a5d23ae0fe522497eef5d599f36c806bd1d7dc862778863e5", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "daf81e495a5495a97f48a7aa59ce6665f5aa3f05581a94f83fe9353a12432d6c", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "db71545058cd116ee932f35359a5215cd6032b25a8ff6fb87dc8259b55c8856c", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "8992cdfcf34cdd3a1e78a14efa433c60e6b86aba4480e975f15e6c58e5798441", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "b1a08795db57e05e789d6518770394d45a149fcf3d0b5df93d6b7ef034d63b19", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "36311aaf521116e656430d70f8e9d4895d5aeeeeab5a939b93ad2680aa90f12f", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "cf308a4bb32863c533d0d4d3ebb7750469ed28ea49d0b780b8d3b0f0c1af8f38", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "047fcfd64a25e7fd8a1d396fd6cb97fd7a2efa5e7c0a373f1916d49c93a0aae1", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "834f1b29653486f9f0ff714620b334b39a632f05c5d7615fa5c376f83e4cd88d", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "ea8a1a4783996206a972bf851707dc73441504c6d63f8e37d3ccdf0e845e29bb", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "e498aef195dfda31ef105abbef98cb3848f821eeda3137366392ebdd489e34fd", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "ce5b662c5bed233fb7540215b3fff5a27e5c596d57ffe396fd0a43504aab3fe0", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "80005fa486466da29f121653e7afe72d4d976555e72ae272164818afdf877aa1", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "325a28172f03a19c78ffd0c0e4bb5dd4c2fd479365918ad14d57811e14687486", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "dad5d4e5b20c6128d81c4253296a9e4d5d2b92942caaee65e76818812dad84b8", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "d76205798bcd70e1477d461782ba22cdf765f41571b80dd9b7445f1b79aa6113", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "c6450b79a97c8fad55bd909dbe165982a983d97329e915023ca4f14b8337b4bf", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "8293fae572fc577e18b6fb720d7a758c3dd1e7601cc5c8b4e6615d1a81fa82ff", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "f111136b7ba8118b7bd583f32b070959da36743dadc8ffbf4e036eb5af8e55e4", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "9af7a8f916737c94568c04ae1952c44cb8701ae15e1eca43ed435d5b59bdff77", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "d64560be11121f3bcbf1202e85a534883785bf885e9f94c7f66643a40f8cf5ac", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "3173479820eccfedf19c37c1410f07f747b651058eff331f70fdfffdc2b75c6c", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "6a74aeb65bad4282f052e9167d66adfa9088402f1825fcaa521608c7f482d09d", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "41775ecb7653d0a3667078e84bc8e76fc5aefa836b0dc9dc198c187e53b6d6d1", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "e3d04a6eecdbb5a05a95413bda60d940c37c825eca8351c989f3a31947a5aadd", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "9be4887056bf1d15d33cf923d5b97f33006dd0be9b64da534a3560ea5ca7adb1", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "2c6aa1e6ef3222d0ea8512a59d83eccb7ab37e7d40b3cbe404edcf262f9eaf09", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "d9ed138e79658bde71bac4f3486ec51512d358fa7d9a3c8e60e9384777ed5957", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "9b93a569e7aa6e8897e96c92fc86aba6c6ff16aebc031f3e0bdbfcdb5fb508fa", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "434a9f02b47c95fa2b7b6d1762b445dde7e5f58ee6a9cd2f3ba8b4e487c0e59c", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "fe818b2f7fada1399c09489b7e623049c08633a8176368939448da6efac16bde", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "3f6771524600d145c6fb9d776661a1ee5d70d1db3785bcbf649d5cbaa775606d", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "dd5242b1da7c8d2fbe5ca5e5ce50e969298181248bd76a2e96da6242dbac516a", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "8146a6036d70ac00d6f9ceb51ec9c442f9eccca070a38fbacf2f97a89b2fcdde", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "663e0174fd641df78dd76e9a0153fad77004d83e658d9c6b9b6bc6019971b381", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "9bdd25921f7a33cc99e36797c0d11ede2e657c8cccb71893e0c5d45d937a31f7", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "c24668db2c83039d6d9ac497c72b1a4f7a021961bb0fcb792eb7c2a96a68335e", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "2a16db8a1362a7c31f263551c6c7f1b23f2437e5adc4bc9a7397c0743af7f5f6", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "360c2e7a3e4623167b56e664ec5d94b5edb36f9461e6f7e12b0ef2fc6d939822", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "2aaf0de14b8987db4c35f72a15205c792e27d0710b57bd2b26eba4d69ef4b430", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "beea90c2e50ea97200100332118e0735c55db5f90e4e96011061f7ff5807b04a", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "e0cb8124c0a22d0456e8c5b2b92a421e8abc4ac01c3361fa4485272bbf44951b", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "8cd564ba6ac1124ffeb9d814aca1f48474abfb4769831d34f6669dc6297f2ee7", "target_hash": "942725904181fb9fb45dbec8fe63f8e74f3ad250ab40263a02c33f26d0a4fddf", "section_hashes": ["11f1da7d820b"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -5925,397 +6657,397 @@ "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "0170f40aa1081f4a01abe9d38469a8a0ace716d5973fec1686c7ecfafa061208", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "b70a0e953cf0cffd56a42803e792ccba02fad1bfe688c4990265b2b5aa10eb94", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "63f2845895ff3360ae2e0d75e7fe278416b441020287f8c179e937c87a8cb817", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "17c096470c655b922f8e1aadb0409c83080c5912b94063a954b3b3a3f0c5c351", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "fcbdeb6ff3a30c012f30fb73daa4c6eb58ca3019fb6309229b93ae319039b431", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "deaa1feb26438424e08bda52e89147f752467653268c7684d09be156af72b52f", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "c952c94184ac7caf5c8fb594a9eb34e5da9991f1ef8e0925d3679d0d7eb065de", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "bf0f39c473f842ac928ed323a617f0b84226633e7d4b1a302acf22e5588692fd", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "5cc40886c34c26c8001abe04d2dba008b531443f33e9955bea7601b47138558c", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "bca0821a75133a50d39f5fa8339d7eac7e11112fe4ca3dc01b809b7f8581dc6b", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "db1192ad6b2a4df15fe24de91f02060c37dec2829574dc0ab40611ca867c4107", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "e17aebcfacb7cf10d09d516305345dafc0f537716e02848ba6b380d1ce8b0446", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "e89e28b1b4b6cb6bf24cc8116ae0bfbd5f7f9405482e4468ccd1c3ab0b920c2f", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "8797533b11f4e6020c8459fecef1a1bbd83684ea84aa363f61d01f335f497091", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "705a95b623dc51cad228cf9b9d842f4a7825b276611fb8fb8af23d87a43a1926", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "81c256a1dbe1186288d6fbb75f14117975d83a8eced9960fb9bb5123f273c487", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "1d5ab447b4ee70f0b0871eb1327b7b905ab9f4b6f05c8206ecb6d1999d46c42f", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "eae294416a84e820536c48e7e48642ecfbe1841b6cf05537af765ec04a45e2bd", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "22d2417d4913f1deb195bb49fff3cf86a0eaa2a7aca5167ed5ee69d441aa2e91", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "53a555c2865035fa79b4b7a96f4dbeca1bf456f0be772f550cf664c58a90679f", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "a97c3ce9543da309cf792d7cbad26a1e63e4c356ce29af274a9960d570306afa", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "107787fa9e0fb3d96d1077540930268dcf229b25c824a3d779908bc30bc8bb48", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "8e14424647dcdfff4741eece1a317244fa636f71e31f9baf90993430cfa2cfc6", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "e7d52e7ae6ebee1b95bd979c45ff6fda7c4647841b747ea696c0daa68d68533b", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "05053a1222c617467b502deaf913e91e5b2cb74c092595e8c4e610edc8881ae6", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "07d1ed30c5858db30a868e9fbda3dc23cd9035cede42d1ac449c9ca342f7f388", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "7aef2c0840df5773cca82abff8f8e90b9701eefc0749a7536dec29b5ee781127", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "fb782027b4fa9ccf197d49500b69842ffab767d525cbeb1353e6e5b644baba83", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "027b800d27d3feebcf56d29e921fc16ca12ef2f1ec8f0ec20c2eaa2593362e2a", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "bffa5a7bde9e8fa1736ae72943b83ee859f05eff815c3bca53ab194aca38a266", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "22b24843702dc54a6cbd88bffcae881c6bb51ad31b521708c7df2f1b4b6f9977", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "a688947ca3a817891b616fb7d65bcacc112ca5a099b962c06be3d0ae80530a9c", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "d5f8dbe14d32a4fe7ba19bb5fa4264ebae4b8a19f9cc037cab5380fea1ad4bd7", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "39fb0e2e6ddc812b0aed2832c4baaf67181403f4323f3600386874007540f484", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "93035cd5144d85bcac263aba84ad4e26965bcd0a995f4a02c6bf8e8a4151922d", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "0ba09a4ce2b14553c00a643caaae6e06093dfacf46bcb9a2a5356324196b0bee", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "a747ddc401fe27e053d9106da9d93132d06079cd7eeca5e93d5766af90650169", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "569516195e7a1319d0b00aeffd87648cbbe00a4ddad050ab23069eb0f14e55db", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "8d4876609b6b4039343e97aca5bd9aebdbe756e4e142ed33809b8e42c0e6e9f3", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "48c47fd8a587ae752ed16c811f860331cc008d6871717d847c8d23eaee6715f0", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "7c881ee70d87c9ec91c74adb81976f7f182bcc3c47ee73c48207899caee67901", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "4329313f4fdd9d95930a4e783db7ce2a754095f7de3c75e6b39fd6594f113562", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "b0ec351a23e03dd86ad926f83503b4a69318f8217280c8ab674e3c1808770940", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "f38d558e15c19a4fe1f1a1cd6203b009e9e9236fffe0d60b3e5cc3ffa3bf0966", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "7f0a5680556b04b42f0a696e1f6029be2eb5d611cfb7ffb744dac23088ae3ee0", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "427774bad31a442b716eb823cab5bc46e20b642ea0eab38373f436bf2aa90cd8", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "b3a156676f6fc649b5fa2aecf1e1d8b75758c8f2ccd2f9b0110aadb3f96781d1", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "04c827a0586815e0aa7be1f1d09783f85df18502da21f43210916f075a330ed0", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "c3fa09415a579f67758c4c8464d0614cc28ce1b0c0c69cccc6a312636396665a", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "4d190d77aa6aa2dd53644189810d9b5ee97171cdfb5e76172b39b49da17df2c6", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "a893a84e4420b2d54d91a205e70bd5756f17897ca0ec2724d2e4be4375a87a8c", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "f3ce80e122e33690ecdf7e4fcac3be47840e0c4a8e067b78f918acd8e2c243f2", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "3681c1ae3ba5f750ca21774eab3974e46eac492f21bbe8334ac3bd21f672d16f", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "afd10e247aa12bd2e122ef9f2fbf8430a2c5aaaa8dd2fe9fc3d340841ca15c28", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "debd4582decc85e7499c06e6c4b49f7a0b52f3bd76e80ef2dfdd30eaaae98e27", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "54564f29a1d8cde0a839b2958af248dcbccf0a9c96357dc72160fb158ccf01bf", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "165ce6c303977cfb3291d744d0bd462c9ea9f11e7c7bc9f4535b7d07466b11e6", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "3e84ff15851c6730fe3dc5aa787a2bed68344f4657b213fe3c4119c56e121156", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "9296d414f6ea0772c9bebb0604d8c9d27743dfdf3634f7491b31b2a95c78965a", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "430e362767fe2eaee5085cfb318115c9c4b57e68851120ff3ee5d5c946693f3c", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "ecb016c3d93972fd56f3d59a6c5dbf101c5b5b7c0ee6b3285495f797a26111dc", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "61972bdc613c8c4fbba34b89f8c659467e5835df383a03bb7dc05ac65705cb3f", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "769f0d6cfd2d9121a43261fb9409beb6e6ec789c030aeefc1ccf6b0886c4313a", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "2889a55cc455601777a0a5ad160e1767e9f440b35bfa2a1ac294461a8b19f07e", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "649e4fab0b29b4f35158dcd8522d0c63791b9b4b3e7390d49c92224c0aa8debf", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6fa6e3b466b9a682ef9e9591d03cf4e6c6affc2c02da5d7b7569a142d55a0b43", "target_hash": "6b4840da91e64df0da142c0c15fc804442967a183c59f97745db74fbe3b127b0", "section_hashes": ["0eae750fc7c6"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -6326,397 +7058,397 @@ "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "301a346a1e670a052fb34cda32c6ecbddf2e90f54abf23e3f867d234ce29783c", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "114974515a145aad220d53a6df21f59548d3319d7f0a06d31d5c66d9fead83a5", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "9798c80754df695d5afe8214ce6e742b1e010acab8eb407578e1085bb8758f6e", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "b66bce3a9e0614a3c401bf6e990b4563c69b695dfd3d280397a0fce57317f2ab", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "447361d617b0696a966db093e0455b27d3ba09a3e4608302fc52dcb58455b0d6", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "1d1b8733e03bdeaa7207a1712a3ce60e3267d34fb33df9c34d7aed0a78a4489b", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "769be177dbec8dca855aac6c536a7fa3ab4a49f320cf1cf9e0d63a8efab72fcb", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "f5a1449634a46693752f18833204bce371a763fa9881fd44f134cf811ace2ca8", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "5cd06fff94266be602954931ee9395640f8bd1f8db3e5d2862ed6cf1bae99b80", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "271bc8239b9214d9d14b7ab728917262c3ef6f367b6cbc58a6128c2755784ba9", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "7a699d2d4acd68f8e5939837d4ce66385d71b6dc9fcadcaca7e5ba4b5b1c7840", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "7a03ee76cdd2ee7c555859ea5381dc3a697322c3f2a5dabeb8433de5d729092b", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "1744b856ea149fb130161326be58c8d419522577c8f4fd85510c378241f6cab7", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "7fc990b4fc33465264b18b40e0d6f59d8e1230fa4ef2a4fa0f581724e010783d", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "4980c32500518352978738044138e2fc76d056a84ae39479b5b18125d4c124c6", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "52dea6ad296a4ae99e4fe0d63c850744152672361da28ec190dfe6c6be5c6151", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "da10a632f1347e30206d925ba429815263fe5632c16d2bc6c32c7f0b75b7bfdc", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "932dc684bf7af579dcf95da90fbe13e08d701ef602983304c699e8cfaf6850dc", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "9f9da95fa5d83cf9f845d42f79fd50228e5d32acab974be625daddc6c7c04252", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "8f37c3ed7b089c66681cd1d032ecda20ee45b6b231e92eb2bcbdee4502379f82", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "b721d6684b0faa7b98aae2e7f9781b89994eaa003f4af2ad6e4047499dfe3521", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "5d2708d84145e241da99a6ec285347483459877d41e8bf6cddd71ab779f4c31c", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "23292a7a32eac0c778d27f2c40a6de3cefaa4cde3a2e34cc204ce2b0e626c83f", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "26c66e383ba7137d83601bc150e5d1dacf69aa1f1772df7a56f2819759504eaf", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "5937d5ca46f6b845fa11a736d1127908f3e3b948449f86b1c3bdfa92f5a5fc27", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "9a329ae3f556d76da74818a9b996a6916e5fb605a0a541ae396b76fc5f4118a3", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "4fc25463894b483253b4a6e67bfe73138f59526a8706ab930423bbda9d1f73bd", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "22d93f56ab96628f2d432ade0c33514158aee56aa61a2031bb401dd834193fab", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "19ab3a3f849fa60f3b5dd3f57a3947074aa6832d081961c807d88e1aab8aaa6c", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "81e1830f12b2a46324fd9e197137bfff96cce27c6aa05e1d40edec5f665a0a54", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "1569651b7d0b97611ac9a2c705ea11878b76ff065e72f41779ce5d2c00cf8830", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "3283be7bf74aa1ed9505819e1e6f1d0732127a23abca48f6cc04761e98408904", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "4fc6d9476c0fb65734eb223086a4b75622d3047a03564998f88b824daa950c79", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "dc0acf03b8c9af0038670b7f5ad4f836f3b18025d641d2c167cc98930e025475", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "62875823e684781a756a79d52d8361ba89e1b32f79c2ddf22bdac0aa9401b505", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "ffbd273fb65eee34880ef771b325dbc234730cd752ca75b072abfdd45fc9cf41", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "faaafceab992b6728951415f13216b4a9e91d6cf3a0fcac5d7b24b932b83d042", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "3f53494ba4789170cec07558f32320e66a3cc32b6dbb7383f6cbc0c9484161c5", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "828e8d57c0f60185e082c7d16b5fb02637fe12334db3ac66fb3e943a5386c2ea", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "dd7cd72f5fb9cb3f2407f658555bc5623298249b59fa8049b9105d3e50b55c1b", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "d8bd5fdadbdd4a3057c0bf2f67997722611785ff4cc05eee50133726ca082fe2", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "5001ed2f98d05635ce4ceef5fa0c86f1b12bf9c0b45793b909aaa3249b8f93f0", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "151b3214e16291cec9d542c986f6b2cc78462219e734f12120eb3e551ef16477", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "39ca233ae0430705e1977eede907a75999d8cbbbd11d7eeeec7eef6c1b73a9d6", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "53ec95c3c0aa02767083853de97e7a2943f702a2c3fa95e2e3b4c08d743114ab", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "9b636d1dd28f2a889214b68e09fdeb9be03d7c0b33e7e4e76c5e4cb03dc6099b", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "f45bf126c0d43af885602823eb944d5a4f985676a007254f2cd0578738611ca3", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "811c447efd67f6c6bffc45190524a40a0b339eead109999e3b12e02dabc13107", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "4cef88d531d6c481b7efe55517aeb10f40ce5267bcbe92ad40948a4a944e22f5", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "d81c7e96053bd8d477a3fb570f849776d1e563f152ce779c771e8491bacc641f", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "4579aea6f1b15f5691d98aac0b813ec97d3c40dfb16ad0897631575d116b7304", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "5a3262115f1f4fd977a965bd6da5b02770db24aa6483a409b20caacd6491b0b5", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "cef3769fe509dd166f7897552c6b06cd087d520e074e97e2079970f5131eafa5", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "30cfcbfeeb434135ef7071618317aa3ba78fc367fb74055bbe50b51fa0db7b71", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "e892534352a7f0a0df4b0c464993514cc623fc41a492e391a3404753aa1cd770", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "901e97c7dd7d1de7d79293c865e61f8f7854aed3f4c9b286052d6e514a96984f", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "694db7abb1f9ddb91283d5a5e0389b8997c76a8b42ce593b45141073e1870dd7", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "6af8d1588272c3f3c12d59bdbe05440a1727b6a4da0ce5b4117c627e0e625d20", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "a92651a620b01fa40fa45cc842d37ab641603585c5042a4a2899ee0b73ced57b", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "437bc5650a1d3b028d60bc0f9427334f9b2a3129953e9dc0e7fa97eb79fa77f0", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "c803a26fac56a33619e45c08a848838fbd171a6e570824325d7fe5d31ae6a731", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "c40491290243ea12a1d452cb37a07608115b2143ec8f54e538542449a24d67e0", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "55598d9621fe53548b5094270701ba338db31f443f77eb78e952c8828200effa", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "d60f94529e9a1bd1cd46e199de66ad8788f12e7fb9d29e381a115929703fbd04", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "0a1d9bc90539aef5f3b88f54561c043a4846a2f2ffca0f994487d5adb1769354", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6a4983441e4d0f21d61de35841d265d96668153938f633650fbf6bee96d473a4", "target_hash": "4a52193641b223663d2eebf8cc757ec59c787d1aea7336958590056aa2ceb1b0", "section_hashes": ["010ee2af3ddc", "a553945446f7"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -6727,397 +7459,397 @@ "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "dfff0502ce815157c60cf3340c65799e7990d829809b7d6f4c96cfe5c6d307c1", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "eb7cccbbb6319c04abd934459ea558dde4d2e154ee8331de311c68031543f958", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "abe7465c2a2013eda1bb73ed4dad59c8230a10e6aadc7dcc2eeca7527bcb2cc0", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "88d486cd9e6509a0c1063ed099e3cae306d61ba66029cc87e061887005552569", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "36dc0bda117d40dd90b60d5f5682e69821afeddc02f4f408c6628b7d491ea72b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "c53ead374378e7cffcb11c480fd9b478d000795585e7b20b4b75e0711ec6519b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "5f516d9551cd053d036dc16773c3d65f5b8027971141fc281964586cd0f75926", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "abbecf6184f3dac2a0b426026950a44ed6c4dfa5df567a449f7cc37b298382c3", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "94ea9a9e6eb7cf07beea2aef8d856211d6b6124d9d809b99d8aa1a2cbad6797b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "debc50cafc5667ca8572534d8c342be8d8bef4a2103a7187f1a25590f77feddd", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "5066608f356dbc4af05a7b51021ad449d87ecb880a3d72d2cbf568eba0e2bc18", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "7fa20fe980f0d7df36f5e7e3491df7e67128e1de5f72878883a3e1bb84304e34", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "4048ea381daea496d92a249cef46280c35d72a6bc99402e9c4e1bb2d40fa74f5", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "113e7fc397af1802e561a9250258ec72fe32f2c5d9bc978c06edb6cbf3c20534", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "0f10ae4497d44fd5bf587764c518fa251b3b3c75129804c1fdcb298ff904c9db", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "3be9b1a02d05a158c609b206cc8d5e1d6b3229312044b2a97e766f66f757e6f6", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "d40f67b70a8756d1e6b1f9930ccfff3465ffa047c46b2eef23c5d7d51f7505ff", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "383c4b30b4f8f7866c8adb4635904278e44dee7e627dc863a859dfeaf20f920d", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "a8312d98bc21debddba55d136e035d427128256a7a88a0043dba309dcdb41c07", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "50e578cbc0c0d97faf25bdc209f51b631aec68142c8abbc1a87b9779d3a7f8d9", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "5dc7eb621dbc6fae4024f53b8d32a247acd98169819c5ea0a2cdb2da5b81cddd", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "78f3a97f1149e93c22a85454166f001e69eae946aaa8a3107b6948f53575f80b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "53fe0606c20ab7e377f29d740b3fff458fae9a997b45248e9e01f3547d63d0f9", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "1160d08228907784700efa1ad07516fa0004fa7e96e197aa563bdf1ab5061455", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "0e6cdbd14391bb9195da7874a913e7f77904a5ed4c3ef7e3882c1fece4a0a912", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "63b94ae40d909edb61e41c5496b59c806c5ac979144a56762c9ea4098216f81a", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "2a3fd7a0f8f84837eefecdff273c0d7dc8c2698c28902e52d34cc023a65b4c74", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "6ce2c6227848aff4071982145963283dfdf48483050cdeee50ecbe56e30ca044", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "a73de84736d797cd557cb819cd6d600c221fe79ba37ab2f0b44025fcc7550748", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "51fbc7deca895d39979585e17204c814d9d1c3453b8d461395d4cd11d3974efc", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "3fd8cba02fc01ae180f0e384daba2342bcc99f1b127254d9eb4d8d8fd5768bff", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "73c206817550cdcdc5939e0bd8eb693de9e4732e38fae6025538d1550e998f38", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "812f864defa34e1e875d01034bd5c9184554704c8866c2ba78dd5180617e4550", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "d89282be92ec150795f7b82a0fd573ffa1f28dffb3f5955860e4ddc5561b5787", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "2561370a482e112eeefca2c38529700d664f2b55ef6baeeb838a1e8c032b9584", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "432e91f8b5a5f8261e59effbf1902914b8fc392409f030f367dc30d506402e28", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "215944c37a03b89256b14b32638be8557dc5207ba62f2aeb80cdab315f7638e6", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "6cad8c8033d9adfdedc49d556f174c3cb98e2f9154e308bc796f751a53e26a2f", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "4ba487b4304c8f05f18dd2e34bf0ae6c5bf4a021175acd80359b070cbb05bb22", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "47e8e7d17ae4619fae9e68086d05b452267f56a0755b2208ebab88b29c6c969e", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "52293c883f3d455ccb29a618010f5dc04c87c9dd68eaf6eada40fdc7f60b5e90", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "ab7b09af6e138e0e46c1006449382955ec87eb7ac7166fa54ed59a926d22f1d8", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "003daa5e00becb450ccd48342faae76d8d86881c78e2c8b7e14f2a9156923e82", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "37e25abcd2cffea490bca64597ec008c0bb215ad2a5da256c7e1df86265f3c46", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "2ec8ebb262849658faa80c1d35386430685acb372a27bf55d27bbea7ae152305", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "1e09c055368f7ceed038de0f1734b8d83761164536941e77b59bfca9e9f01718", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "b4c902c68c3e980737080de32b79c42be28cdd0aa748aed3f30b2f2dae371fea", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "2c3e333788e87e1310f55daa7c99aefb6ff6781d4a3f4ba60548191725d1ed2c", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "42236be0676866259bf6aecfa2843735967164fc1f124b49d2c9b2c16d534a2b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "a91ebd57fad92d065609ce94d8f4b73c585e11e2039985b6b786eed1b5b5410f", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "7488820251fa7dfa494b952b3800a7f1819cf1c96e30b2f263ad56ff6c6efdeb", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "2d1e1f9af504a2e6787dc8d9f7b038671b8cf2c5091803dc8513a12d3daaf384", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "c1221aed31afa20a9ec2f705d31963f0345b33b4678db468d1f4b0837c9f267c", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "87c3d270d2ce54ed8b5a29b5eae22a91a598f21d804f77eb1e43bfe653c2edb7", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "5b12a19b34ef9231c9441233f5ce39fa1159ed8af0c8d298ae7afb7119528c3b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "bcdfbbde90a8b0fdb6125b7294144293fc04b88b70da86e9f89d4eaa40a090cd", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "e67ced1f1888e26fee7fa59582698b68fcba706b276ec612ed2dd2d8e800d161", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "ff1dee82271093572f8d0e83676d3424ad22c66569812511a0234b4f0f8e25f1", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "85def269d7ae4d3e551fe7b5b97dc5acfa0625f7aa3c3cbd6ade6853986b837b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "de9550c69bda30443052fe9ab32a677c30bb1a80d7faac98776ce6418a11ab31", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "618f1ec4702293ec2a48c48ca238f813389785d386d7d7549ddb56f46c011335", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "dfa6ea166a0b518644e47c5bc80aadcd769c82dd0296492d3ec3107512e2fdbe", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "ddf4fb0629d6c3002a3130665e1d293694ac76e094050205769d953dfef7f24b", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "22c9bd1dff8abbbfc4c6f150d579b42e1e97787990c1dea3cfac9ecd182fe495", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "9a303ceacf6f1c9d0600e04a10192b5ccbc61c4010b1026320c18f7d19b398f3", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0415e6018749665e40b55a5374340126a793e616c1df2b35a3e9c13464014feb", "target_hash": "550a048d7702aedc6f8eeefb803a54bcf9ffdf70355b546194ac49e44a7b56be", "section_hashes": ["84275b597d7e"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -7141,7 +7873,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7160,7 +7892,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7179,7 +7911,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7198,7 +7930,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7217,7 +7949,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7236,7 +7968,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7255,7 +7987,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7274,7 +8006,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7293,7 +8025,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7312,7 +8044,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7331,7 +8063,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7350,7 +8082,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7369,7 +8101,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7388,7 +8120,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7407,7 +8139,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7426,7 +8158,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7445,7 +8177,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7464,7 +8196,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7483,7 +8215,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7502,7 +8234,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7521,7 +8253,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7540,7 +8272,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7559,7 +8291,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7578,7 +8310,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7597,7 +8329,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7616,7 +8348,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7635,7 +8367,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7654,7 +8386,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7673,7 +8405,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7692,7 +8424,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7711,7 +8443,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7730,7 +8462,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7749,7 +8481,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7768,7 +8500,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7787,7 +8519,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7806,7 +8538,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7825,7 +8557,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7844,7 +8576,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7863,7 +8595,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7882,7 +8614,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7901,7 +8633,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7920,7 +8652,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7939,7 +8671,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7958,7 +8690,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7977,7 +8709,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -7996,7 +8728,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8015,7 +8747,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8034,7 +8766,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8053,7 +8785,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8072,7 +8804,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8091,7 +8823,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8110,7 +8842,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8129,7 +8861,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8148,7 +8880,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8167,7 +8899,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8186,7 +8918,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8205,7 +8937,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8224,7 +8956,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8243,7 +8975,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8262,7 +8994,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8281,7 +9013,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8300,7 +9032,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8319,7 +9051,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8338,7 +9070,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8357,7 +9089,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4e2bb669321a2c6dfba9dc165c00ca185be7e051d56d3119d9c65a869538ae3d", @@ -8376,7 +9108,7 @@ "15e9a542ec1e", "56d0c07efd61" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -8386,327 +9118,327 @@ "ar": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "28a25267ee50c850c1fe9cd4171c83628a5be964fb639045760137690e3d0917", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "a3d11fa560af7af96a8a7961d06e559e88729b7c3aa6421e792537550927c1c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "0c5e0e4e1a32f250b7742a36bc14f9da2ee8c3a043871caa199fee19d1c5a274", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "fef8cf8fb2d311ad2892f8f418d05cca82d9460943bb78eb16eb9e08bbf83bc9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "019e6fe80ca6617a4b3c46047487a6206811b78b349b70dc371eb6fde03e2158", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "e336370bd5a69d88f401e2198a0fa41706e1338d2218c922e8a03f9fdb5e625a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "a21da4ed26ae403fb1db318bd4e2f35b4eded7c3e8c2677df02687e4b427809f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "e341b95f7df054b06c5163f3537f1d749d2773d19a3dac0e7aaa8d0f8e55f238", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "03e004560fc7b28663535784fd9640bb095bfe7b51dafb877481f05c0a283adb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "1c57ac3a3a757028ad723769e259712475d4313d3c9201021e4ddb97d4347db1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "eed98d719b634dce248289e18625298ce6b8119a9b0acfe12085b1c425dc0b2b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "7ef1377edb90142509482650053216f692ef2486181efa6250035a02fdea9860", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "198ca71989665b8fd7671fd3aadcfcfce1dbc7ce6bff51a49decef3ee196d401", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "94c9b2397a599426a01ca9092a60b1251fb29813ae69ac0909e3293100051634", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "6019eb161852e7a2d39208a3797c48e9f72b1ed891f34323b477265656446284", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "8a91e194529c78a8aa83d59203dbd7749f81d40049060e9dd86e4a3462ea11ab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "c724765e374483fcd4b8a0ea6841000759ca2cecbb1c12e438247139417e1808", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "49be489bbbc7857f78bc802137863050332d930a797fa326526b5541cdc17e5e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "c54f8a8523c5d8ab761ea69b2985e16fd035fad15528f59c0cf5693f0ffaecde", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "522ed9628fa881c5416ad313b50304233b2a8b6922e09fa59f5d356cf7c6ecfa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "f06c735ea863616d0cb0ac782a5d8fa8fdbda94cd3abbef7c43644559677eb87", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "c09eaf8d337b542c6ab71e764badbbd25695a0c903d6bc99398ef399c367d5a3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "1eb303f31eb517193ca61cdc3e11049d164e9676193d6a6cae0cf157c23206f4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "90909f4b74e47c9359079df5d382acc467a8b37158e42f37a99c23e4b7ff596c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "ac40192346248c48b82c9b67b8e4a4cfbadb06df7d0aa8846bbeae8049e1eca4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "681dd81aca7b3fd9dd0f4e735cd79080f519fe182072be2308faca7ce7c6d392", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "94b72e74856dd1dde435144fd18ec5b9ba04445ca6f2e3de7c822c19a04c99af", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "cc01979c9629bd2ddc4f14e3400414f488180318a61269d2745721cfccc15d9d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "b5956a873313a61717b3147aa9c5ef7f862283734803f5a7ba29ca7e86c236ce", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "41d0c73837353b049bf43a8eb2149aa1a5b5aebfe0444132bb95d187808c86d4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "10c009f7f645ae696bc5eacc6ae28641ebc50f33b29f7809c15748b604e9daa7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "38d004f4193aad3ccaef582cf072a6b95a1d0207f6a808acaa22373005c2f5e4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "ad458f4c3fce109b968548229c96a4d06e18b6412713c1aad738601a16ea609f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "d8a831d70274e00063982dbdec55d4527d847add0726bce6daaa2ec5332ef0ed", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "ede50d8fa60ac425f05aa4f871852a10beeda6d321dda8788e0dc9db24769415", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "19f64cb15ae7271a39a28e83cfe4d0c4326d4f87c875a4d68ddb98b3965d93ce", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "29ec8f5a8d76db4cb539f660d0654c6c467e1de59236358e090135222e9b8144", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "fa9e67d02b9f1597197afc69d135e66af15e05db3cc5706d924f1cd35ff53123", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "f04ed116eda0bb7aa5996c13912183d00ee98709c590fb6885f611933abdf222", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "6adca4f386093e2de5866b33cba220120c91029d96160c7966eb1b0734fc4ba9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "0d53cf0ad50d27541aa6c70f716c9bf5332020f28ee982251655da2897d6eca8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "cb7d1c2cce57b70d2db874d6d55148176094974db800f4900dc13b304cc5246e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "575477ea9f6b9140b313b12f303685579ffe9e43f187cde063549b1aa7958103", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "59eab7f5fd72bea77091de6e21bb6c92a195447a562e64f818830d11ca6f1c42", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "68552abfe7f2306cfd07c561d26b27cb9eaa4fcdcc0d7f0447c7ef033e6bec73", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "1348ff87d3c60546469bc613dd28e2193c846f8bec59379bdeba0c0df1308d3c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "360686f6a8d4291b6d49f3b5476480ff3c4fd53137afbbcc0d841abcf72679e8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "7a2590eae0b133356e5d73aec453aed38067bd6c5391b4526dfdda28940ab162", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "42a8d506e749fa7346746bdc796dbfed770fc226b8d1a5e6ad930b0bed2ffc63", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "07ac2557fffd9d0c4f08a23528f84e45b43c5a6888cdd3153b0b6965f8de9dfb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "6315348a57caaf6e730a0385cae4d44df197a1513f0d5aab2d37229644650a87", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "2ac74a97c0a83f46ee00bf203d5ebea1cc0ebc6b8fd21b09e41b4f16a8908c1c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "be1ff5a2c5b5b069ae8dbc9bb92f42fc1ce9b35eac845da1d5f893dc029630af", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "5af53ebfd13b9bf8c5b1298b43fcd3ec3da3077818d8acc9e10a271c55de0d5a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "0a205fd31d9c0127db6be355f7c3bd2da10b7d3040b2eb29eecd138a1a817241", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "3e2a8e01703eabdd4fda1cc8fe823a41eacadfc367dfc9d674c038ae3c49cef0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "69186eae8c5f6f81957071634a5c619fdd2d377977f62805f6c21250f5a4c767", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "fdd8e30dd92a96f4cdec88f1f4c3f73e5e9bf2b44ab25d1c84ee997eedf5e77f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "7b9defd2fc421f82a41c552e3e374602bf20263f14892f6451b583952d1d4ed1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "bca2412c29cc165f9d6ebd0a2118971f8ee545105d2acdfbf1679abb1bf6a40d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "04f80ad61c7bf0f047bbc5ad571734f0b870f3301e2ce26de342da74f09ab091", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "7b3f686c0b8a5ace062b1ccc2de1398a6a2dd462bd6e4707025109f1bd1d2fb2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "cab7ee53becc7d4ee9ecf7f07a7ba5836a6b86cbbc6ff74aa5dfebf796ec5373", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "e59c38e4bd8381e28c336d50801982fcf70c7895805c7739e19e62c154f79e37", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", "target_hash": "60d34b1ecf17e89dbdff2e8d5921256aeed9e4306991ad3ad33ca3a44aaa2cbd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "f74f1f2897a2573c7f28d5db437eef478a5504c88b2bfdd660e304b78c593603", @@ -8752,7 +9484,7 @@ "e9a2c22593a2", "f5e0bf887df9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -8762,332 +9494,332 @@ "pl": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "4df3289c20c64467e1ba93a588adbb856f93beb399270eab23fa2a1007878c21", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "dc76f91a7539dcd1c9ade932f2dca8dc3e1c971999107c15c033f0e898b283f6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "b4c9b3bfcd6590f5b17e43abf9bbaef310eaba3c0526dd1779724c2d7092796a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "aff5be513d7c21faa8c5cbde7a32211aa59b6902eab25ed219c234ee3f8e3b1d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7c77b34f327ce254b2d317be331c43b281354fb3305388ed0c1ef211c9e96384", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7b5eecc60b8714366f9e380c01517af581a1a5ff00ce79b21bc8c7d66b327b35", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "34cef20c58fcc49f12defa6a109227b4c845ded159339efa7e33ed0dfb6f9859", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "251dd878bd31610900b2e21680422d5eaf61d7f0021dac54681a88d73f2b0bfb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "2cd0e0b00ebb3353db32afc48615f1a2e7a6848d4fcde71344ecf3816f51b25d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "a23430536bef6ad00811f36ca6bd860a7d4c4c3579cbc74b41f849dbf8e7380a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "1836e699aefa5c54ca24bc12404fdb04305c975ad811a36db38e497c509c09b4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "2a007949c73a2f013987ab1cc00fa5fd7bb6dd81ab14dab47d249db0e812b607", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7787747e7d17854ed14aa0728168eaf7411eaed38908d691b4685be4da25882a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "b56085494eb857c32e3a92c1bb5f7cf42d44ac72c705d1d5b4a6e98a2d79a32f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "4f01e546d27c6aaa93d59a9d8231529e79f56b31fd7f7ea250ca9ecc0b6ef611", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "1a0992a13f6156affe7493a539dfd99224bf5e5b2e9b995a6881edda6a917c18", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "104fe7e8655f0100def3dc159bf5360c58e6b164c314e957055ae95db99b9014", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "dd70deb3bf4c01657d7547daa681bc5a6e8007a45d99771abd8b07f690702e8c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "f2cff698dc73d3ba7d3cb43df8d1fc0c9eed70d1a738d41f94367ba57d5968f5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "89705e2a509d386cefa6c0b22869f215c2a883ffbeb386fb428d31065061fc32", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "714d46fc5c5341797c8864719d194d65d51cc1f2598277479a9ce1b1545a7aaa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "95eb0981d922cc1d62cefa950dea6ff47438fe8340f6352f28b1d56422b0f760", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "43dbc415dbfc2ad295e68379385dfa0cf8394a5b176cdff6ceb90db8509f3df3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "3c0ba303b53f7b69d85e705bec0567e56e8fd1ccb922f1bf2454f86e36af971b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "30fa193f553d509f63d70cc2c0757418ecd0522e54094c28ce239119e2812832", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "1d971eac67b46d5e85ab99401700fef48ec04ba057bfb3efd4461545b4a9976a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "5b654c2dd6e906fd2f56e0165e49e251597ea944fb759dab4b85ec8e02d37e33", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "2d2123483e32f03bea59dbeffb9b60438c74fd5c0a0570119d1c17e6d807bf96", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "64db4f40d13ef1fd9f9641de362b1aa4998da76fd0fbd2cb205c5795e66e00f6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "9090dc6377e35a52b39e28728a7e5244751da2a59f70ea9028b7557331719478", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "96ccb7f294032a83a6b630ad1af4e7887e011f4fe43c8787d8f6c52ae6c857fb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7d4bef85a3ba36142389d56b270929306d14361176f3513484414b74d978c5db", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "448e4d48a011eadd9bb92518be51f9f7c7a109e0029736aa66f7c44030b8f130", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "c9e7cc42ccce02d8a4cb4b4a66fd7cdacd143ceda55438121d4fcf6b2c2eba8e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7c76434ac6430a65bd25896025afb35cd2139d2d3c400edafac3074f043da941", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "1ad7f2435eb8c940b2c0e5204ba6e50551b213f9cd3f7f93da8a571be6e6d495", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "c96fea490112efe68010e98d309cee79ee941f6071976d0ff31865af5ee746f1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "36840f51774d5cd4b2929617ce214142001c472883e0cfb45eaade954951b71f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "05cc9e29136999898d9dca0302b9239a8f9444c7253e1b35fd5322f9fd0e63b1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "e2f9165f97c116a0a2da5cd87b7ef57c4ff80576fd2fc046f1e416280fadac2b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "8bf3f857fe2abf78a46bd38e21eeffb18edb3d123219ec57a0e3e830a6c5890a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "6d4a3a01a10bb5000511655333e1d8d101ddf48801cc60505c260c1e8797b6d8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7099047de43fc330d5bf163ff45155437f75202e6ef2a433922592412810fdec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "89c0a4de053f9961561f456f4c146b7e985a154d98de070976a910c620d9e49f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "6beb72b94f420a8cb67d68245707f0ed67d391e44bde524df9861463eed53fa3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "1d453617e1a506d9ad09764b6942700e0e5e4302a3dfed5aa08ba5715a296267", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "4f31ff147682c1ab7dc615930253b6c8b6a974b387840fd7e95ce19d9bf9884d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "37328322640f45e856174526db72aa4bb9a1f17d392f910f04c1069d3cb20443", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "5f60be52c06e6258a79dd3dfa8d95e913939f90799d323e0718056a1e7dda677", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "7ee1a04a8d0703f3078f299197805cd88c0c9c009946848ebe26c99cd62b3eb0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "8c80a39320c63e0ca63d85e1239626b47394fb9c1f363e02b14b5de141826aa3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "0f0e9e1feca80b1f45f334cdef97c637c713b8f6172cd14c3a70f17aa526142d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "9f5aeda4bb3a522030aedbdfbeaa3c7066a9a1c98c7c29db9e9ba73ab1797f18", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "e6c32f88d25a9ff7fcaa3c3646b763fcdd5147cdeed243db9cec62bcd094471b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "0def0cc02e432502efda52762482dd48e8f228d6c648ba9b05df85e44872f091", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "5ee0e49e7f9562b397d2150b3731f006fd2c132ca4713833c1ce1cae198219d3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "d70ee52cf8f6acac3a32c30e82b2881ec046a4ee7991b65f2ef0de3d2f0f958b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "dadc878fa1784e5a0f5f36a49681d285f5677e03a13131b867420df105daead1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "30eb917652f2449ff09e7a3f953e7f97b27a1a8653d055e5a9a067d8de186caf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "571c35f752d4d506e7197cf21b2705b77caa24562023551d0e4f576a9452fd65", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "d164f4e56aedd3ae30228f908c08a402b0f47f6945bb2b52ab885acc62d33d50", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "6d04495a97c0804f87c33b9c5e4c21b761b98b9445ae811c17acd3bb1f679ce5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "e9417964670d2f2445749bd564efddbd869f610fe6f43b3aa95da45d79a48ace", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "89633ae302569fc5f959285a5bdd7346b7528cf2aa413fcd0ae5702e2040230a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "f7c36b640b26880e83314921f91f95dee10433406f0e0cf286d75da7e4b440f8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4cae38d64a892c3e918c1885d587efc65b1c9ffbc4a67c46dc6da63c68c29b01", "target_hash": "1ed304523631c8d8bd83b633e1c3b13d0bbf56d589a2cc1561c6ad27a4a47585", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -9113,7 +9845,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9134,7 +9866,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9155,7 +9887,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9176,7 +9908,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9197,7 +9929,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9218,7 +9950,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9239,7 +9971,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9260,7 +9992,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9281,7 +10013,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9302,7 +10034,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9323,7 +10055,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9344,7 +10076,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9365,7 +10097,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9386,7 +10118,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9407,7 +10139,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9428,7 +10160,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9449,7 +10181,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9470,7 +10202,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9491,7 +10223,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9512,7 +10244,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9533,7 +10265,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9554,7 +10286,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9575,7 +10307,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9596,7 +10328,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9617,7 +10349,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9638,7 +10370,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9659,7 +10391,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9680,7 +10412,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9701,7 +10433,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9722,7 +10454,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9743,7 +10475,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9764,7 +10496,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9785,7 +10517,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9806,7 +10538,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9827,12 +10559,12 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", "target_hash": "2a67f32d95d67749f9e93bb2b99ad1305e0ff9c8f2588a5a34d56283618e0c01", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9853,7 +10585,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9874,7 +10606,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9895,7 +10627,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9916,7 +10648,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9937,7 +10669,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9958,7 +10690,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -9979,7 +10711,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10000,7 +10732,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10021,7 +10753,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10042,7 +10774,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10063,7 +10795,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10084,7 +10816,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10105,7 +10837,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10126,7 +10858,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10147,7 +10879,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10168,7 +10900,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10189,7 +10921,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10210,7 +10942,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10231,7 +10963,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10252,7 +10984,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10273,7 +11005,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10294,7 +11026,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10315,7 +11047,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10336,7 +11068,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10357,7 +11089,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10378,7 +11110,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10399,7 +11131,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10420,7 +11152,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10441,7 +11173,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "974aac2e0936294e56987cb3145752e1caa19d10c743dfb99d4253ce48a5c2ef", @@ -10462,7 +11194,7 @@ "bdadf4401c7c", "f231837e6c99" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -10472,7 +11204,7 @@ "pl": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", "target_hash": "9dc80c4a3bbd7eda751dea3ebbff069ba57de54decbd8600146eed9989e61464", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10490,7 +11222,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10508,7 +11240,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10526,7 +11258,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10544,7 +11276,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10562,7 +11294,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10580,7 +11312,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10598,7 +11330,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10616,7 +11348,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10634,7 +11366,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10652,7 +11384,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10670,7 +11402,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10688,7 +11420,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10706,7 +11438,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10724,7 +11456,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10742,7 +11474,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10760,7 +11492,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10778,7 +11510,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10796,7 +11528,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10814,7 +11546,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10832,7 +11564,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10850,7 +11582,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10868,7 +11600,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10886,7 +11618,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10904,7 +11636,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10922,7 +11654,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10940,7 +11672,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10958,7 +11690,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10976,7 +11708,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -10994,7 +11726,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11012,7 +11744,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11030,7 +11762,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11048,7 +11780,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11066,7 +11798,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11084,7 +11816,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11102,7 +11834,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11120,7 +11852,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11138,7 +11870,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11156,7 +11888,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11174,7 +11906,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11192,7 +11924,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11210,7 +11942,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11228,7 +11960,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11246,7 +11978,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11264,7 +11996,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11282,7 +12014,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11300,7 +12032,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11318,7 +12050,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11336,7 +12068,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11354,7 +12086,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11372,7 +12104,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11390,7 +12122,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11408,7 +12140,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11426,7 +12158,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11444,7 +12176,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11462,7 +12194,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11480,7 +12212,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11498,7 +12230,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11516,7 +12248,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11534,7 +12266,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11552,7 +12284,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11570,7 +12302,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11588,7 +12320,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11606,7 +12338,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11624,7 +12356,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "911b4488c619a45208d8d8882243837de750b5f2da1eaf4580411f66bad2c90a", @@ -11642,7 +12374,7 @@ "cc0674b08670", "d956dad6ebe1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -11661,7 +12393,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11675,7 +12407,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11689,7 +12421,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11703,7 +12435,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11717,7 +12449,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11731,7 +12463,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11745,7 +12477,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11759,7 +12491,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11773,7 +12505,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11787,7 +12519,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11801,7 +12533,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11815,7 +12547,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11829,7 +12561,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11843,7 +12575,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11857,7 +12589,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11871,7 +12603,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11885,7 +12617,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11899,7 +12631,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11913,7 +12645,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11927,7 +12659,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11941,7 +12673,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11955,7 +12687,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11969,7 +12701,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11983,7 +12715,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -11997,7 +12729,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12011,7 +12743,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12025,7 +12757,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12039,7 +12771,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12053,7 +12785,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12067,7 +12799,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12081,7 +12813,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12095,7 +12827,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12109,7 +12841,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12123,7 +12855,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12137,7 +12869,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12151,7 +12883,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12165,7 +12897,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12179,7 +12911,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12193,7 +12925,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12207,7 +12939,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12221,7 +12953,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12235,7 +12967,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12249,7 +12981,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12263,7 +12995,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12277,7 +13009,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12291,7 +13023,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12305,7 +13037,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12319,7 +13051,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12333,7 +13065,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12347,7 +13079,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12361,7 +13093,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12375,7 +13107,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12389,7 +13121,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12403,7 +13135,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12417,7 +13149,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12431,7 +13163,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12445,7 +13177,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12459,7 +13191,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12473,7 +13205,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12487,7 +13219,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12501,7 +13233,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12515,7 +13247,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12529,7 +13261,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12543,7 +13275,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12557,7 +13289,7 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6fd77dec23610f04069de935de6b5e19dcfe68fc334fdf06f414f93debc92741", @@ -12571,19 +13303,19 @@ "84489153dc0a", "a031a223bfae" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, "docs/architecture/QUALITY_GATES.md": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", "locales": { "pl": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "4f56ec8af3a50a70ecc3f5bc0ade08f9dcbd1b6678bc321745a1795652d82e2e", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "7bd245b93a4a9c45f10535a899e05fb747af4730cd0f9b05584547c1014712e5", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12592,17 +13324,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "a3ca72a6bf8388d3d0ef45d26e37e0fcf088a2af4943269a01b0547ececf2a65", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "28140157ce6e24334ab470b55ca8e0c5c898091b6dd09b63fe9d2c30ba702ee5", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12611,17 +13343,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "7cfc96629aed632608359238f21c129112343c69a723b61d5a2ac9a22a7c9923", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "aaa7a1f41b888b46f09de36943857570688c7b4014211031b16fb030bdeddd49", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12630,17 +13362,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "69c168438f2b70ba158cd063f37bad5a5ee6fff11311c19effb43265a4d35a88", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "40fd0a74ff93c240584dbf51a1e62e47fdd060c2460af8356e6c2023beb3ee17", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12649,17 +13381,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "08b9b82bbf6377b112bffec745ade641c70abb5b052331410cc17219a602303f", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "3f1d976030789c4f4729c0ebce62ea9e26e4d9e78f21d90ac92c60cd5b70b4d4", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12668,17 +13400,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "1be6b0f0a742214ba640285a92b159b776d96392272c4e16427c6adf1374e671", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "e7d08c0f54704c09657926c02585544435e0fa7d719269523dced00ade44ece3", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12687,17 +13419,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "b7e60162cd27bf0597ac4a8293ac7e4acba641af7eed354d7c2937f6bfbbe360", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "7d1db53a5907a2d64ed02bc24571ef36c5e357b8ffb696950025d24ac3f1b8a5", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12706,17 +13438,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "1e9c960c710e257117ed915c98fb0ab07b56e8e279bfa984b309b8bf23b8a9f7", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "60db403a046234b32f3153db2f933e1b3f78da01234cc6ef5f2ece49a863dff3", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12725,17 +13457,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "53d0fb17cbd98cb8fb68f93a03c3a93579eaa6988a71a65471533a1d9d729e71", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "168636f31ac0368c597ebff3d55d91a520269bde4f02f3d89101efe380292aa0", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12744,17 +13476,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "f9e49767833a222a7e0c0ceddd6a993b5391ea0d8893f32b14a0b194d8963c8a", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "b4370021d43a5b4f5cad67ab0b13d310528bb11f393b30a05dac84439fff9713", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12763,17 +13495,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "16372a5475a089419b498a08be9f085b2f5f8336c6be4023ef1c1849441cb086", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "cd4854048f2a13e557808126c3338cdfc2be4fd6ca6a27b1d8fa302f9b9ed45e", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12782,17 +13514,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "99b876649a3653501dcca7486290ab3ba487b9eb8a96fa4d6250e40d5854379a", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "e0b09de33e5d6edfdc41b4f3bb520489a3f7f9845a3f7fc8fa2a3a1c76112e6e", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12801,17 +13533,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "095d64c78af69118722c2b64a933ec94464ea908da9b406ecc3ebdc51a5b2167", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "7f2789ef2a2985b46aedb954442bf9726189d146f884471967b6088f7ac45e2b", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12820,17 +13552,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "eddf9de15e93aa0ab42262c3267d1d04f9dae4a6949b81f0d65230a37cb21230", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "db9b3239ea7b532342aa46a90f520c91674d55e41faad31104e270917b2bd7ba", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12839,17 +13571,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "cc69ceef35a2a4f3b9ce803e490198b5f89d110cd03dadfd7bd1dfcf52181bc3", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "06669c1fb1ce5d846ba867a2aa2d18662c79a9ee573e99add267a7059db6f038", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12858,17 +13590,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "d7130b6ef433b2217f5c1325c31b77cf27d3d9cce37dc13bfb7efe28267b64ef", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "79b010198295dedfb9f05be2713403913c0b554b69b3560c033dd16d8ca7f538", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12877,17 +13609,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "c78ff37b4c266c004170a0243a798216ec86ea7329237f8925dd9cb11843024b", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "d9ed9c21d20b9a7042891e4d88627f262dbb902702d0f02abb8bd6521de8f477", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12896,17 +13628,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "a088c0443b439474b401180ed4894deebae63d7d808c132eb58839debc08d64e", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "eb41e422845da5a30a2fbf68c317b1760b2b7eeb26893240b373d3dadf6dddc8", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12915,17 +13647,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "78c358d8dbc6f94d8b0110807d8a79146e009e06a969ae8554a3c077e915635c", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "349ad6267732e21d44594b9b4396f47803cce57a53fea67922a280cffbcc4e26", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12934,17 +13666,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "65343b482c7d88ef6ee2084a70f0648dbb3dd133ece9b0612003ce813617b8ac", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "65a9acb75cd7c3f9268cb092df14424add9b3e6c1ac441cf9686ef76d9f7f053", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12953,17 +13685,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "eb0046a00b12985871bf6491a9f61bb2c9fc427b9a41041f9ed79fcff4c25f09", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "cfc5a2c6abe1a202eeeb1467aa4070b6eb61af1a6ddd57dd798bbee17f3d1783", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12972,17 +13704,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "dd4b046ec1fb1dbeb63d5e5a304820457dc2ffda12ae33a7c4f2fef17ef2e3a1", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "c1fbb06c1ec09a728b5e321844f6eaf4fe23ae993c0422aa70567b9e18a01e4d", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -12991,17 +13723,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "584f95511ffe84c848c89115f7c57d699e4f19322822b273244777bcca2861be", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "a02b72ea7fafbd5069d228cfb1b278d10ea64f82a80a86fcaff454c3b604b887", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13010,17 +13742,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "2f940087c60d7a0fef27911c62e52b48cbd54c35218f570f91340eea6a973e06", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "9d1b07a3691305e3f9c957996fb1cce8d7d43f328c120908e90fe1153b23c799", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13029,17 +13761,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "3e4a13354a4b24c064ce22df34c03339973534e329ff4ec27c9fb5b9f1b3e888", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "c8b5fc24682c514834849f01d5ca3e3509960d37da0bbda3e2b854184e5f6852", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13048,17 +13780,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "0be301652bc0ba0009c42d3c6f800fac497abb066c7c4a823fcd5ac6e4f6e54d", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "4b869d7d0d77a65760c20f189eae30636fd9daf050c84f9546511a4da57686c8", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13067,17 +13799,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "a8de56f6f25f85f94597e06d4a12691467aa7760f5e002a27ef134af360e52fa", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "3ad3c8fb3d9394ae5fd3382465cea2ae29da9136a80c4937d04c051abe180285", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13086,17 +13818,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "7a31dbdaf13e5e592037335ba73c291735ee7d6fa3a5c2e2c9d85d2e8ac465be", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "c3e6d4f38853b6680f71b9969f5b80b4ac5cd68fa390bc8031c31ae2f2b8ac58", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13105,17 +13837,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "c93724590cb451bb8faacd737ff860d8fd7d40e40aa8108af6189e93030fca4a", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "705077408fd0164d3bbd9cdbfe127c08d0726f28dcc548adaeca58e06d655b1e", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13124,17 +13856,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "ad9b1206f2a785db0bb9650e5e40f4dbd5ecf1965c41011ca7a425b093dcbb6c", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "fa53dae4eeb157f0a298e0dfe4e30c8281061f00df4e39a95d128baf90614187", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13143,17 +13875,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "bfad2dd50e6b0d654eedb1023b7d245d1f8c851cf96a5fef866478c7a10ab0c0", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "6df4371b831ac7a9261165a0ae914810fe2ee657e38352ec3d2a67d76a9a419a", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13162,17 +13894,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "0d1e59f7b1a0a9e61da66aa7c2a29eb685a04bb54f6d8d7037a20bf2f90fdd8a", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "ec117d0aed84a85b20a7ce603587426f34aec26645264e858d6bd66f038112e8", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13181,17 +13913,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "93bd6f2410cf2d0022612c2aa8b85a99a073ef2aca09aba1869b07bcf57917bf", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "3dfd03aed16d4219cf2eefd49047330a3850ab050a2317662ed17c59a37c5951", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13200,17 +13932,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "78d3c541415459e9737c8433a289646519629e2faec7dca638a4d908f6f74c46", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "7b6b6c2615bb2864d73d9b15673c7ad7f316c12c066ac78e8955b41697f089bb", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13219,17 +13951,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "449f4beb748551a533e87059d271ec6903c8dd1aa793194f17bc95b35856e083", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "36408d012ec0ec66204875184b5f1efc725d9beb0b69633b97d4a60b89a183d1", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13238,17 +13970,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "2c0d65664133fe17110a7030ba9cee1f061d2d8601f331ee4a81d029ee6c843b", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "9e56b5e4260ad7b708e5e3169ae92236e49a9b3b3be10e1a497e2686fbb89159", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13257,17 +13989,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "743f056595747b17d5cb37e279adaefc862fd92e41782dd493f5c33057b0222f", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "8c8a8e135930dca1c2388cdd331b0c4d2560ccf7d3d6b3e45589bdd59c960ff3", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13276,17 +14008,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "be2d01e5710e4fe1cf17ee40e9d67a509fac0794dbd0933c61973c3b603d6ae6", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "2e953d0c940430dc8895b1ab8cbd04721b26d1b7f34504172e140951317c48ff", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13295,17 +14027,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "b8c81981bc2c9267475de53b2003abfc33acb7e015cc2d40f9e41f753df33957", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "68d872d2607d229987c035778fc512cd180dda689a92e8961ec77808711c66f6", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13314,17 +14046,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "dede7f62eb31e8a3f61fcf7520cf03e8b4541aa749d57f7baba621b5e3f5d07e", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "90bd4f4351beeec23aa85cbca1a79877c163b2b9da8994e434f67ca92c452a0e", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13333,17 +14065,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "7b7d247984990bae61f836c7f385a8e8ab324efc3a011141314299c4d81d4cd6", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "88aa5cafae59ce0fae10e25a20eecbfecdfbbed398c6fb5e829290016eb25ed8", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13352,17 +14084,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "370e22e3cb9b1e66b8885a1eee664d5cfc94cd6bf28498a514bdd383683ac369", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "7d1c43cc3a00228ecb6b0640f28ed9983eaa1373be0c4422d3fd3bc843508359", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13371,17 +14103,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "6c47d661e0a771e20333bd105737f9c51fc4fdeb7660cf4932634ef39aeaa5e7", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "e246ba7ad9c5ea354df3f45b10873ce7f659ffd1974f015c92945c54bdabe4b1", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13390,17 +14122,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "ef10520e96d522e42452dc72b7ec85fb4d77695ef549bf18083fe921fb53a9c1", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "39d73602e871791a38aeebd90806747ea90e9fca452d6ee627aedc1d2ea6a086", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13409,17 +14141,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "96c7ebbeb936732191017f1acb1fc30b53e2a246b8e1cbffce4708989b2b09f9", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "6ce06636e6321cfc0ba6275c9d4314e90e7aaaa2714ec126b6109a04c1ba346d", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13428,17 +14160,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "49eba49a09e64d4e7dab2b31f99f04861ec4332aead1bba08baaac418d729f0d", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "6304442b949751fbfbb322ea42cc2e79bee5d50dea0867446abdcf4164d773b1", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13447,17 +14179,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "456079497870a2fe372bf3b48fd1bc206c2c2d20336fd28cd757988c144f0edc", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "6099798576c3ce5e6ed3f2dfd54b364764ded4a79a2775a37a7462cf987a9288", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13466,17 +14198,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "d37d7d0a9b8a614fbf4101af441f78ac296fb443d773cacf1caad4057945eb06", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "61def0e8d22896df3aa17b4bae86cc17f2a2bf5b0804f340d08256b9a072ecf4", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13485,17 +14217,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "87fc0c6ea86bd0e4f24ba6210e1e6d154b6449977040f272869ed451fa662847", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "70a28045df1edd11217cedbc46e4f86c075c873b69c4e018018c8211163bf1a8", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13504,17 +14236,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "3b49dae463429466053d7b940cef27509d65289df129f3f88406ce87a1e3a70a", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "004c6b35e212e9a576bc497dd754e02ab47c6dd40f45b63d878ac638e5041d98", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13523,17 +14255,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "c5203a2a672f3e751002ce1d7ea39fcc44cd4c43ff29ab0009437ca8b8d6af7d", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "8f21695b4148161723d4c1b09443d65bae4b8f5ad945c02935643c38e59b4eab", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13542,17 +14274,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "8bc4fa1bee511c6c8e083f163a845b79224c68fe38bc220288b139b10f50e8d3", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "a898ee9b56d084ef40fc7d9276ab440e810f74848ee9c0b7adaafa3bd17679f2", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13561,17 +14293,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "236770d16f3ea896ff8384f11652a29895abc2377a34dd8d3face0a11aa38ddc", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "458f1bdc61828c78d50dfccf8ed3c39ecd5819ed84c3828c54998f8add4680f7", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13580,17 +14312,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "70b3b8bc2fd9547e94aa3086dda990c828ac48aaf1492059f346f5c38e6c93e8", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "0d651d3a7a6a8ec0a350696fd1dd6d49b3b5dd9c45e031c9779537966d09ccd3", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13599,17 +14331,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "52d6c211e805f914849949f6e70fc98daa0e018c9f26532d94c4b0cd50ef14dd", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "efdb55dba7f69de079b666c33708cbca0a45711d0256bc2c22eb48e1d2afb315", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13618,17 +14350,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "ab27b8ea348f266c4eede8a09d37349b5ba6605a46d0b507381cc7dd310f74a2", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "ce5e35b0660917e99dbfa0b2050eca8d548e108eafc301d8c5fc20191e4db8e7", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13637,17 +14369,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "231d2300995b72902411d5183a5343c6af1c9332c031dc64074559003fb566d4", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "45467b5838da74271a6ef9d1f31329db12b5ca8145ea86dbd59bce2e061f9398", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13656,17 +14388,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "13b2231cbb4b719da8f2fe87b652a9382bd1e49667e475647f662405b0362d09", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "a7c0f7624cae4f89b0d08759fc04038eb4a8bd4dcd4bedb4b54685aaa75172bc", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13675,17 +14407,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "442fc4c4c4f923e7f3e98457b2fea41f19fe3b81efb4c76b78d78ba4ce704802", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "5397e3be2e3fa97018f6d15f2e57edea139598f9be332ed1d66c14e72edc1cc3", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13694,17 +14426,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "5ab287a7f218999c00f501a909a01ea347822d9369c98e0379ca535c82381705", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "9aaba070694fdf048f6e7ee99c7b9b75ab5244fd6097d403141d7ec0b7bda0d0", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13713,17 +14445,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "fc837d6bf5ad4c2f1acd87c95e977738146d01031c16f6730b3821928120dabf", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "693ceead1eb1346822a62287492957d02f877e9e876797d44dd44bfd6e0b7dd3", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13732,17 +14464,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "500aff2942d17fc25785e91e6bb81ba9d70353b870e68a2308644af341046537", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "4adb31c55addf81c4319c2632c5c8ea9844cb275312b95915cdae0e4f65ebbe6", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13751,17 +14483,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "b0b0dcb42ea8752c42c66c9021b089654f32a27118f106a2f8f85038463973d3", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "e9db27a4c42c2a5e2c98f318763965eb6b4afbcae73a0650fc7857a3a10e016e", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13770,17 +14502,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "b90712981315f27ec60a7660f1db14f59fb044942c13b3f764af45cafd56c79d", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "0dcc4a10d81d28042c33ab830361eb3c55bb2dda7211db326a6739fb6947c293", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13789,17 +14521,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "a86dee5ad73fdc3c96fec071f6e666ab812e4280afd9643be154de43d1daab44", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "10e8d1f043b04077e2aae885d93c3fc4d432fca581ffd8ab1b1b7fe345ca6f73", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13808,17 +14540,17 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { - "source_hash": "c3c1be1cce796f05d916c2f3f698b21bfa5d957df9a1f51fcf14da23bd39a6b0", - "target_hash": "03d8a0f8b4dd7b2ba06e482be24bfaff835e5a039a4777184199a02a9ccc2156", + "source_hash": "be8874de41d521fb9fbb7e2a8c8a866da28be3ecf1a1d929f7ece87c06e69bdb", + "target_hash": "2fa3922aeae49e2ce595977d9bf1ea1d6960ddffc478ff482b3e73751ea51a47", "section_hashes": [ "67dc4021ab63", - "90957c0a6d55", + "05f2eaef987a", "d3f1d46376fb", "7f330c18c808", "786d5af09ecf", @@ -13827,10 +14559,10 @@ "c0afde5aa4fc", "8617961bec5d", "718f11b3dbb4", - "f78b02ca82d4", + "f837c3522c9f", "00edca0fcda6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -13840,332 +14572,332 @@ "pl": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "9043e565e04c280442685e854099e38e1a00a393861293f09dddf19df9bb4102", - "updated_at": "2026-10-02T09:42:51.053Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "403a5a9c21d47f077e0e3c66c6ab6ba4b471b725ca8263efbfde323df475a51d", - "updated_at": "2026-10-02T09:42:37.015Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "f724ee4bb54d87b107371cf2db9573e6bf1d8a408adff7e24241d9075f5d5330", - "updated_at": "2026-10-02T09:42:38.704Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "88624c46f8cd10516be2a04044699c859289868ca7545b8524cb8cbf9d3d8113", - "updated_at": "2026-10-02T09:42:37.748Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "2405288b2d981b13ab40a71cf04352e7b22ba062d31de9a8d7eedaf3baaad06b", - "updated_at": "2026-10-02T09:42:38.064Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "127957b6e1d8002fd01a220a319703ec5b5cea8d495dfa232d742873e9e31ee8", - "updated_at": "2026-10-02T09:42:37.343Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "a63c76904d163a5828218ccc74a25775cda5a9716974b2a77e531cee11637072", - "updated_at": "2026-10-02T09:42:39.089Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "dbf99453c0e6dce62858ee8b5f1c66b0b50385e8a6ea27717f26ec531c61607d", - "updated_at": "2026-10-02T09:42:39.377Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "9d6337c1236bd6859d7c25023aeffbef3e4576b8edc9591c108abee3d29b766a", - "updated_at": "2026-10-02T09:42:40.039Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "ddec572ecf2658f78a333700418393d3abb3f34f1d8f1cffe903516ef71faba4", - "updated_at": "2026-10-02T09:42:40.339Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "e38b9da1f5b7771998eba7e79a656ea6581f94cc75e4a883b0aea0f00184e153", - "updated_at": "2026-10-02T09:42:39.752Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "5d75a35a0c1115ab393bfa55d6709f47bd7e2e6d736497f36b77d22406f20d78", - "updated_at": "2026-10-02T09:42:36.672Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "0ea5f768a82516833898add5dd060c7b13846f51fb899d8b411f322ab8d01121", - "updated_at": "2026-10-02T09:42:41.315Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "d96fa79999e461bef6dbb1bf6787262906502c60c1989316904bbb2df1779762", - "updated_at": "2026-10-02T09:42:40.638Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "7c4e9a82944d083ea5daf35faa28ebb7809abdd2b82db815d05978386f1e5f64", - "updated_at": "2026-10-02T09:42:40.959Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "73230e5c53fbd80af27163cf4ae563efbbae53fd0c0045190dfc164b13ea66d3", - "updated_at": "2026-10-02T09:42:41.595Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "608c656b6f52df51a4ce078e69916ffd6654a459a7eea7fadc54c5589537e531", - "updated_at": "2026-10-02T09:42:41.907Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "dcbd486279cb31261199f8b95e461583a5cb0c2e6f47778dfb30fce251a9e424", - "updated_at": "2026-10-02T09:42:42.215Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "3178692fcb8ae4fd4cc9ab6fab8ed14c61e9c2c2f384e03bf99ac9684b5d1cf0", - "updated_at": "2026-10-02T09:42:42.523Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "b0e028e9193f499e3b515f1b5804aad5f891cbeb8eb6ceb493d881a7a56b2994", - "updated_at": "2026-10-02T09:42:42.841Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "d98051b36705076a4037a3a5a9c0d247c940e684be0b47015b8027fef7cc5108", - "updated_at": "2026-10-02T09:42:43.142Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "8294a3310e658e8f72a08f2388d699fffa4a186995e7d46ed8a0dc2b7ceb2bd4", - "updated_at": "2026-10-02T09:42:43.460Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "8f74fc7807b8ff18b103d6da08022cd7b9c197215bda32326771aa94011d0989", - "updated_at": "2026-10-02T09:42:43.784Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "da8d7f307406171552992f262893fb2f26780a77cf6c7395a6aade5a5d27c673", - "updated_at": "2026-10-02T09:42:44.089Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "24616abe25ee6b435848a2486bde70edb3053c70a9cddd91b3a3bf562d8e9038", - "updated_at": "2026-10-02T09:42:44.703Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "54d88d84726339404ae4a07e0fcafbc5fe18a734d456748fef09ed3ec7e5b648", - "updated_at": "2026-10-02T09:42:44.362Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "0bd0bbb308d524c158ec236b38832e0dfc340a0a4782177b0def3528db4532f3", - "updated_at": "2026-10-02T09:42:45.057Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "f8e0647b386d144a4472bcbf4f1a5ae68e733d12ef1ddf4bdb1b9dad12f6ddc3", - "updated_at": "2026-10-02T09:42:45.416Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "5222596042c0417df036c3e08d05fa1133245789909858a390948001056e7593", - "updated_at": "2026-10-02T09:42:46.537Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "d5ac84a9ee498604cee3b88352178d4dfb613bbd0a837bb3fa36f92b11f4f01c", - "updated_at": "2026-10-02T09:42:46.142Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "fd84d18bd3bfbf55bfec24eef483c65c4780ca66203177b851a886b776092236", - "updated_at": "2026-10-02T09:42:45.808Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "b01eb7315b69ae7fb3aee38d4cc2efa7e57adfd444dbfc73387f251cd50f0a79", - "updated_at": "2026-10-02T09:42:46.846Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "c3d1990bfef3dfbb460bf37bead4201d37b47bf0f7935e905dc7d343dd0cb777", - "updated_at": "2026-10-02T09:42:47.172Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "a6e48da7f145bdc913b7b31cdcef5d9ae14a6c0090b14f063266d33696101aca", - "updated_at": "2026-10-02T09:42:47.491Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "0a8a4f4d623a4603562f2e899041d1e598e5a50be43f62f31d05f549c6cc3a4f", - "updated_at": "2026-10-02T09:42:48.246Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "f5d9454f28e6b5787a611064259d45c0021f833adbd268c8e538184cc2bb8d05", - "updated_at": "2026-10-02T09:42:47.795Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "389d5c4c0541236c9bba775e404006ea8e1cb5ed8c123e6c0bd76cfd4fd959a8", - "updated_at": "2026-10-02T09:42:48.595Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "759e7a84a7de9ea902e8365e3f6c1d54b1f6659e0c8fe6403070b64db2f072c7", - "updated_at": "2026-10-02T09:42:49.201Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "50e5665610326cdddddf6b066783946078854260beb28698f4130c20b493eda1", - "updated_at": "2026-10-02T09:42:48.873Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "dcc22b6eaeaa3d587496d1562b716a697ed693fcfb3d841bef43e6eb791853ae", - "updated_at": "2026-10-02T09:42:49.503Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "23d00ca3408c57c2e265fc85fa7eaa2f24c3775e24599b6eca3007ab5a8cc868", - "updated_at": "2026-10-02T09:42:49.796Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "b0c0ddfed227e0cc83fd2004a6c0b125a503411feda1188147fb0fbc666e0593", - "updated_at": "2026-10-02T09:42:50.776Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "cfd1f3d3b038472c54147c95bda57f5006dbf553a26ee1b2932534e467ebf10e", - "updated_at": "2026-10-02T09:42:51.687Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "71a06475283972542308b29d1f034f43092dfd67294f0331aeadeee6d3701fc1", - "updated_at": "2026-10-02T09:42:51.348Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "80f42269e2c45cd43b403df2babcc5822e74be57f336c5b43d4ee33a43cdc15c", - "updated_at": "2026-10-02T09:42:50.446Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "32e99a93f163a88e42e0be8d6c7e6fddf0d371f000dd6d56f4160f7b96ca1272", - "updated_at": "2026-10-02T09:42:52.041Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "e74c0e0785f8ebd1ddc8e592b7eb72e5729ad0b1ff360f65b42364780f538e20", - "updated_at": "2026-10-02T09:42:50.108Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "3d990af680f4acbf2c4c1ded3a74c5b2a7ebfe1280478f8d61bb67124d966b55", - "updated_at": "2026-10-02T09:42:52.337Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "44d6d694d8874555722ad1a36d7bc7d0c0521a1e51113014846b94f64d981760", - "updated_at": "2026-10-02T09:42:53.027Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "1ab59d2c9d92e4be9c695d4081f9b4a58dae366083cf147c3e0219e205dca9b3", - "updated_at": "2026-10-02T09:42:52.747Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "c4e981c86a1cde369cee5cda61182b13de42a51054eccf7ed2bc1eabe89861e8", - "updated_at": "2026-10-02T09:42:53.304Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "4f45a316c409c721afb9df3b964f5fb8d7e1b4665d509687c93e047eee5e8217", - "updated_at": "2026-10-02T09:42:53.891Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "9f0fd5bffb2b100a41aa57d87b8c0d8d9bd62a1600fc79b810040806aa58058d", - "updated_at": "2026-10-02T09:42:53.601Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "e546da373f6d7200320445af3184142d6375ed88095b383d8c9157a8c5b90ad9", - "updated_at": "2026-10-02T09:42:54.259Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "d0abaff236db7d23cd52d63f54537b6839b7b92c18a36d16880af07c768d12a0", - "updated_at": "2026-10-02T09:42:54.713Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "715ef9ccec511f169332c4c46a2b701af82a7030bf27365e93eb2fa92608939a", - "updated_at": "2026-10-02T09:42:55.233Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "bc0360ed283a53b354d659121ed3b785dd8069d4253beb93fe3510a0c7ab3919", - "updated_at": "2026-10-02T09:42:55.634Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "0ecd271667f2ee956c4d7cc794f28bae5b1bec325688c9eefc75c38dc8709f05", - "updated_at": "2026-10-02T09:42:55.980Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "2d53fc04eea8cfd6c3ba349cee6d3d82eff5439e4d13724431a55ea9634b52ae", - "updated_at": "2026-10-02T09:42:56.597Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "9d61f110af893b6d47530cd0177d16d54654167490d7d8c59221296c7f25b8eb", - "updated_at": "2026-10-02T09:42:57.041Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "5b454c380dbfae64cba89eff7a9f6164f18fb122b9af03eab599c874a49cc647", - "updated_at": "2026-10-02T09:42:57.633Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "e837b718c36578a2a55364d4bbb06db233783537d29fa14d0a6cd58002b6dcd0", - "updated_at": "2026-10-02T09:42:58.640Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "2d50c9137c3f132ffccc3b449394730d9f5e67d378d925f7590c8dbd22d12a8d", - "updated_at": "2026-10-02T09:42:57.330Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "75d0b96c4ba8fa9d82bcecb62c2a17e140e152ccc611a144fd9345ea88372d1d", - "updated_at": "2026-10-02T09:42:59.011Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "ebeaa6ece3718f1bbf2ba2e35ba93efb662289680d3ab127bf77c63e65f40339", - "updated_at": "2026-10-02T09:42:58.138Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "64c35b9c2ed70f5a5c47d65e5110aafb5fb5a6893c625e692f1b343ff8ada75f", "target_hash": "c617c11f2fa377a33ffeac71ae83d4fdabd854d3bee7bc5ceedb93865008208e", - "updated_at": "2026-10-02T09:42:38.370Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -14190,7 +14922,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14210,7 +14942,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14230,7 +14962,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14250,7 +14982,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14270,7 +15002,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14290,7 +15022,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14310,7 +15042,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14330,7 +15062,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14350,7 +15082,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14370,7 +15102,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14390,7 +15122,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14410,7 +15142,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14430,7 +15162,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14450,7 +15182,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14470,7 +15202,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14490,7 +15222,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14510,7 +15242,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14530,7 +15262,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14550,7 +15282,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14570,7 +15302,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14590,7 +15322,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14610,7 +15342,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14630,7 +15362,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14650,7 +15382,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14670,7 +15402,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14690,7 +15422,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14710,7 +15442,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14730,7 +15462,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14750,7 +15482,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14770,7 +15502,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14790,7 +15522,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14810,7 +15542,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14830,7 +15562,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14850,7 +15582,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14870,7 +15602,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14890,7 +15622,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14910,7 +15642,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14930,7 +15662,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14950,7 +15682,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14970,7 +15702,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -14990,7 +15722,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15010,7 +15742,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15030,7 +15762,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15050,7 +15782,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15070,7 +15802,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15090,7 +15822,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15110,7 +15842,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15130,7 +15862,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15150,7 +15882,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15170,7 +15902,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15190,7 +15922,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15210,7 +15942,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15230,7 +15962,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15250,7 +15982,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15270,7 +16002,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15290,7 +16022,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15310,12 +16042,12 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", "target_hash": "d9549521b5e2c1d9b223b5203861413b97073e3d461a4fc370b7c424e5e05e81", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15335,7 +16067,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15355,7 +16087,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15375,7 +16107,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15395,7 +16127,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15415,7 +16147,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15435,7 +16167,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15455,7 +16187,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "1e0a398f8473ed435b20a9f17cc553587125fcf9c9a9252e44b3e28931eb6bb1", @@ -15475,7 +16207,7 @@ "07e2d767adb6", "c710e1078ad5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -15485,7 +16217,7 @@ "pl": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", "target_hash": "8bf837b12b508520ce83ceec3bba236f1b6c65ecf1bb64b2d62cc8a57fb2d6bf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15499,7 +16231,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15513,7 +16245,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15527,7 +16259,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15541,7 +16273,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15555,7 +16287,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15569,7 +16301,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15583,7 +16315,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15597,7 +16329,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15611,7 +16343,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15625,7 +16357,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15639,7 +16371,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15653,7 +16385,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15667,7 +16399,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15681,7 +16413,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15695,7 +16427,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15709,7 +16441,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15723,7 +16455,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15737,7 +16469,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15751,7 +16483,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15765,7 +16497,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15779,7 +16511,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15793,7 +16525,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15807,7 +16539,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15821,7 +16553,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15835,7 +16567,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15849,7 +16581,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15863,7 +16595,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15877,7 +16609,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15891,7 +16623,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15905,7 +16637,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15919,7 +16651,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15933,7 +16665,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15947,7 +16679,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15961,7 +16693,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15975,7 +16707,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -15989,7 +16721,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16003,7 +16735,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16017,7 +16749,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16031,7 +16763,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16045,7 +16777,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16059,7 +16791,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16073,7 +16805,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16087,7 +16819,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16101,7 +16833,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16115,7 +16847,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16129,7 +16861,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16143,7 +16875,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16157,7 +16889,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16171,7 +16903,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16185,7 +16917,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16199,7 +16931,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16213,7 +16945,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16227,7 +16959,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16241,7 +16973,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16255,7 +16987,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16269,7 +17001,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16283,7 +17015,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16297,7 +17029,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16311,7 +17043,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16325,7 +17057,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16339,7 +17071,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16353,7 +17085,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16367,7 +17099,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16381,7 +17113,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "62f7caad8677dc65e86eb57e61db8dcbf0055b45299c318b27967581a28c2106", @@ -16395,7 +17127,7 @@ "11ad4b7fb589", "d66fdc49bc54" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -16405,332 +17137,332 @@ "ar": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "86263c3204f1e9a56dd7b8981b2e2474baded2145e038459f06702618755fe0e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "1392b32d8644a64f4fe06426f2cb5c891241f1a4f8cfd9511d7b46d37036b368", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "ea2d2b673bfae9719f2c223c8327689d159803a9d7760dd8fee68693cce750d3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "9cd9fbb3b890b5d9ce30aa3f0119625083a694e51c153c38c3492f9eb708052d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "4f878045aad3559155c8faf808127506b07c0480ae3b55001884eef03473bdc3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "9165423a4359e8d3036e99f1f62e9b832f938cb68339abcd366dbe25bfcf251d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "64a377a18d8394ee3b1f59541465b5580af354992b026592b77c852db924729d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "905ff259866d1946dde81b6bd90d1bafb21c98c218366235c6da7b2a9bef9aca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "566c657bd9e0d61eff6595b33d408e4de3404cc3087aef5a274f0ed58d629cd8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "ee35d4e81a2d8e7814ebb5a55882448e4651e4dfb95ec577a8b902492663017a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "2d92db27a237e36a052f8e6972d5cdbb4ed636962e656a5931b0d4aef4d203fc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "46eb5d2842b7e4907c04f759549497a7206cf8cfbd0de981993c85ab191a7d8a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "408608ba198c4fbb5fe19c0911f8fe37c02ec4fbd545d6224678f33ab237bed3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "e8626b9e05ffe19858c3ef4f3580f9362e03f0e36ef7528c7206b8b4794fcb2d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "bf111135b8296c982adae9bf5ed7023535b39f5c2fb978746488d1d6fe3e1f95", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "b26a7ca397792543affce479b90e8a62e20c8148be2054d400f5140a0c8a5e6c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "538f6821f26b3112ee17f425f0df11f57374346b52dd87fc22f2ad77b55dc147", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "628da35399a6ebe72e4da5ccea7e450ac7a7a15501f59116981f22f13c1ad6f7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "dc2ac07ee05a057ba7a6eb1cc124475c4f9eb4cc67ab131d080772bd92106c73", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "0a4d7136a39e4aa577b02fc78be601c22f9c74e40d7fffe9780f423c4c7af4a2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "b3e57a2c3117e80faa52b6d220eeabd7d34db4bf763b70a0b88ba3e50012442b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "098e921fac0088ed7cf47780591846cf983991a25de87faf53e896cc18a30804", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "43a2ae2de788a3403a1558c2311b4ac547263a96a359a4caebae2e249330cf8e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "16fa77c2e4c16fa03229aec328224867eaf9459ba9b0b4f935149ffa6b22f40d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "c941a65969dbbc4d2af704ae44c87f31a9d487058fd181a646631ebb4490596b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "fa1e9a4ac89ebaa6f6c863519bb9d72ac683285fc9b88306409d155c8b9a54c2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "6fe982ef2767282892adadc4980fda79ed002a2bc5cebfdc303271e9fa8626e4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "ff1610ede8687ca1e6ac3b1d676edf8d5f5e3973b8b100290e4f9b2daa7adf04", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "f015e7b9ef03620c326d99f387f06ca5b4923b28479ea25684644b40848c130e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "10b18045cc0ffbb173a55d1e2e5b289535c47c68b17fb5c84fe0ce152db96afa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "7bc027b63529101e74b8ba294367a60ded7b48589d217ccd4ee132c1e3142d1e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "3bd2dfe382a116399945717abd51b52160e2ec97654c1c19f976311e63056647", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "0c5d4c89e91f390dc7588f10b9ab31a8ad010adcbd0842ca2e70fe86e8aca71f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "af81f9bf35f6ae7eeac28d02cf74797f1d18f9d793dea2693ab5de8b1d5adbd3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "828d6183439bf2e4defe2c21906c26a8104af46639779fb5e1260808d724792a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "316738d01a6d24ee5d071a15fd9759d601a3a98328aa8a53e80dd31d1cf9320c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "91093d5bc3b07a37118ef0eb140d6a2b02b3b03a0057a9e0eeeec8e089f7dae8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "2ec44827257e05f5ce8de8a433c97d7860a746561b34319027b1d1ce86f553f9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "59fb6c37ce2be21cdb208155d6a16be975dc5549f212ef10d5447e2cc9f37834", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "c07b2a09f2a5a0ccf5beff3e1ec11093a9aef27aa16abac97b663b7d7896c54b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "a904ab5a4db9de6c642a746eb8ae95b03262f06443711285ebce4dbc72df8d86", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "b5ab9168a08c161c6414865f3c4a940c75af13efbdabc2103c3e7adb23757175", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "e7fb428f99fcfdfc700c825f10cfcc8a671059e575d31a89b8fccd3addcab21e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "8d72930c01bb027a8d67464206118b1cb64118a2dcde645eaed4f90e00b68d8a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "11e63f96f966f44f32c2e10d9b0f8be72b14dfc8b5c0cc7851c300e793c0c98c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "20cabaa5910c9df0e7f1fccef9f223cb7eb75f11ad2781b71272d469843bde5a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "eca2d2a2d99b7da560227657a55791f1d6bfd9f9867ce990bae147760399b6fa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "4502ef85a2ba2958a6627d3f1939b5964394ef3b2c6ab866af43bd90e2ce9cc9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "0faadff53717df6f9b670ae516a47d0576f75b4cf3aee846951c774e46526f83", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "182bd6d302bf30fd3e76c402cc7a14bfa74194d9e83001db4fa2d9a512c7a28c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "252d1d193a77b4add734698d0a0633c013f8fbed4105d838fb8e307858daf062", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "841467b849d8e6d30c56df63a4966271b52157a676243f10f69b11920741456e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "95ccce48cb6abb490a6c9fadeb95d77e9defee2e54d2a21675006066ddafcb66", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "15f25eebbb3002c95fcff00dd44690689e5da601b145200098a9c6f1aa70cab8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "15451058c43a1691c09ec2b75e511c10d3fba67dc4c2c51ee6475bd6dfba7412", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "492673c1056148ffe42f37242982f7ed8e5b09717b638d3550c70cbeb82882f5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "10000439343040cc22b4f09e126c452d166915895ecb699b8f577bb42c5d54cf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "4792f46b4195aad6663a714de81926499234f02b787368099ab043362f7bada5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "82b33d3d686f7e9e7ccbeaf6b3e14fc6050c3687f3366c2e42b3045cffee92ec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "ddb7a3685717d60b135fbe1b8734451e845f2e5896e9cb7bab9d0612166adc5e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "923344d47277def93d45c550997270093f2c769323a4b24a50e15ae125928232", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "df60c4d20bb02bf85ac2c18722ffaa2ac83cfe41bb3a409731c5ba61485302ac", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "84440a872da24eb0c992af2051e819f4ce43218270179be284a8022a404354b1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "d8c017dc8c2ce3fe407f0c60078a5a188facc09715231fdcde85bb65f3099a4f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "17ae063bf81189a0e0e6100f4871d9fa7cfe7dc4d956f4d3e42096e14bc2125b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "234462bd2df075fd28c4338fa4e8c318a90428199ad8f3747b041bd6a57dd497", "target_hash": "aa72998a538a1bf477d6910e9132e325dc3f187a7056b7855080870372e5a9c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -16740,7 +17472,7 @@ "pl": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", "target_hash": "302929df77d66358c89b5ad3910a77a70b346a18b937975c09baddacfbd25a05", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16754,7 +17486,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16768,7 +17500,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16782,7 +17514,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16796,7 +17528,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16810,7 +17542,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16824,7 +17556,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16838,7 +17570,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16852,7 +17584,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16866,7 +17598,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16880,7 +17612,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16894,7 +17626,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16908,7 +17640,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16922,7 +17654,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16936,7 +17668,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16950,7 +17682,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16964,7 +17696,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16978,7 +17710,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -16992,7 +17724,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17006,7 +17738,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17020,7 +17752,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17034,7 +17766,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17048,7 +17780,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17062,7 +17794,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17076,7 +17808,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17090,7 +17822,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17104,7 +17836,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17118,7 +17850,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17132,7 +17864,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17146,7 +17878,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17160,7 +17892,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17174,7 +17906,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17188,7 +17920,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17202,7 +17934,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17216,7 +17948,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17230,7 +17962,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17244,7 +17976,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17258,7 +17990,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17272,7 +18004,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17286,7 +18018,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17300,7 +18032,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17314,7 +18046,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17328,7 +18060,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17342,7 +18074,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17356,7 +18088,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17370,7 +18102,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17384,7 +18116,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17398,7 +18130,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17412,7 +18144,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17426,7 +18158,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17440,7 +18172,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17454,7 +18186,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17468,7 +18200,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17482,7 +18214,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17496,7 +18228,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17510,7 +18242,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17524,7 +18256,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17538,7 +18270,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17552,7 +18284,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17566,7 +18298,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17580,7 +18312,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17594,7 +18326,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17608,7 +18340,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17622,7 +18354,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17636,7 +18368,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "b2e7d6083e4ffc08b95a94df5bf1ed87b819b94fc8a70cc7808a87a82589d27c", @@ -17650,7 +18382,7 @@ "68f4c0dffe08", "cb9f2ed94589" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -17660,7 +18392,7 @@ "pl": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", "target_hash": "0171e8b37aa6c56fabf90eb1863359be3e1add09a309d628b65ae483fe3995df", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17680,7 +18412,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17700,7 +18432,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17720,7 +18452,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17740,7 +18472,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17760,7 +18492,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17780,7 +18512,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17800,7 +18532,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17820,7 +18552,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17840,7 +18572,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17860,7 +18592,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17880,7 +18612,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17900,7 +18632,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17920,7 +18652,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17940,7 +18672,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17960,7 +18692,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -17980,7 +18712,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18000,7 +18732,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18020,7 +18752,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18040,7 +18772,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18060,7 +18792,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18080,7 +18812,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18100,7 +18832,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18120,7 +18852,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18140,7 +18872,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18160,7 +18892,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18180,7 +18912,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18200,7 +18932,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18220,7 +18952,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18240,7 +18972,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18260,7 +18992,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18280,7 +19012,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18300,7 +19032,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18320,7 +19052,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18340,7 +19072,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18360,7 +19092,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18380,7 +19112,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18400,7 +19132,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18420,7 +19152,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18440,7 +19172,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18460,7 +19192,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18480,7 +19212,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18500,7 +19232,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18520,7 +19252,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18540,7 +19272,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18560,7 +19292,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18580,7 +19312,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18600,7 +19332,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18620,7 +19352,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18640,7 +19372,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18660,7 +19392,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18680,7 +19412,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18700,7 +19432,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18720,7 +19452,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18740,7 +19472,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18760,7 +19492,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18780,7 +19512,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18800,7 +19532,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18820,7 +19552,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18840,7 +19572,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18860,7 +19592,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18880,7 +19612,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18900,7 +19632,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18920,7 +19652,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18940,7 +19672,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "82f765990f98f3bca598d75452ff7a3a02a5ddfd1489a74ab9ecd475c9dbc772", @@ -18960,7 +19692,7 @@ "7e65b884f0c8", "dca529342543" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -18977,7 +19709,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -18989,7 +19721,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19001,7 +19733,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19013,7 +19745,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19025,7 +19757,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19037,7 +19769,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19049,7 +19781,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19061,7 +19793,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19073,7 +19805,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19085,7 +19817,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19097,7 +19829,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19109,7 +19841,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19121,7 +19853,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19133,7 +19865,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19145,7 +19877,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19157,7 +19889,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19169,7 +19901,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19181,7 +19913,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19193,7 +19925,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19205,7 +19937,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19217,7 +19949,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19229,7 +19961,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19241,7 +19973,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19253,7 +19985,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19265,7 +19997,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19277,7 +20009,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19289,7 +20021,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19301,7 +20033,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19313,7 +20045,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19325,7 +20057,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19337,7 +20069,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19349,7 +20081,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19361,7 +20093,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19373,7 +20105,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19385,7 +20117,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19397,7 +20129,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19409,7 +20141,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19421,7 +20153,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19433,7 +20165,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19445,7 +20177,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19457,7 +20189,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19469,7 +20201,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19481,7 +20213,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19493,7 +20225,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19505,7 +20237,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19517,7 +20249,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19529,7 +20261,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19541,7 +20273,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19553,7 +20285,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19565,7 +20297,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19577,7 +20309,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19589,7 +20321,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19601,7 +20333,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19613,7 +20345,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19625,7 +20357,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19637,7 +20369,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19649,7 +20381,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19661,7 +20393,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19673,7 +20405,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19685,7 +20417,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19697,7 +20429,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19709,7 +20441,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19721,7 +20453,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19733,7 +20465,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19745,7 +20477,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "aae288a51e3df2b8a5386bb53711148e0e8783dfdf93ce4e105c87b282e10bc8", @@ -19757,7 +20489,7 @@ "75f2e38ee4db", "8e693a8a3c94" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -19783,7 +20515,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19804,7 +20536,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19825,7 +20557,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19846,7 +20578,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19867,7 +20599,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19888,7 +20620,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19909,7 +20641,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19930,7 +20662,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19951,7 +20683,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19972,7 +20704,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -19993,7 +20725,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20014,7 +20746,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20035,7 +20767,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20056,7 +20788,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20077,7 +20809,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20098,7 +20830,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20119,7 +20851,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20140,7 +20872,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20161,7 +20893,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20182,7 +20914,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20203,7 +20935,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20224,7 +20956,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20245,7 +20977,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20266,7 +20998,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20287,7 +21019,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20308,7 +21040,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20329,7 +21061,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20350,7 +21082,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20371,7 +21103,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20392,7 +21124,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20413,7 +21145,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20434,7 +21166,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20455,7 +21187,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20476,7 +21208,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20497,7 +21229,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20518,7 +21250,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20539,7 +21271,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20560,7 +21292,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20581,7 +21313,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20602,7 +21334,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20623,7 +21355,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20644,7 +21376,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20665,7 +21397,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20686,7 +21418,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20707,7 +21439,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20728,7 +21460,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20749,7 +21481,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20770,7 +21502,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20791,7 +21523,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20812,7 +21544,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20833,7 +21565,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20854,7 +21586,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20875,7 +21607,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20896,7 +21628,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20917,7 +21649,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20938,7 +21670,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20959,7 +21691,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -20980,7 +21712,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21001,7 +21733,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21022,7 +21754,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21043,7 +21775,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21064,7 +21796,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21085,7 +21817,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21106,7 +21838,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21127,7 +21859,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "2ec77520a2d622acea9be604f49442b4d9c4e92f9b8bc53f96c7c6e0c0f255e5", @@ -21148,7 +21880,7 @@ "5b792221aa25", "c320591509c9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -21173,137 +21905,137 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "98d496235dbace9a5d623bedeb34c943c523291d3c12e0c0d605f6d959fc3d84", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "966e367f5cc6762a39859cff8da26ea4ac5308d0bc0889e06be4302786caf065", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "eabf5f9c7ff04da8abfa1534d24742e534bfd1b3075352b05d6c1b459ab914f4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "1ae0ec89342f0e110d7c5568b39b53548cfb6966d6895550a1937de0e101bcd3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "3b0f8ce326afef0560a4e1b1e6c79ff06b4f9425ba159810025b73a453668068", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "89dd25e9cf90aef233d6bb67850bc29ba31477949e68d0d4086175aede9ec22f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "2a266db13ba53851893bd83a556335fc93161f38e3b4a3257bd84aeb4499bb64", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "4e323128cf2ea2f61096d4781a88a91296cf34bfe84c32611bede3da41ad5ffd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "6a82b6b82eac5e6e56a5bd66bede35371369b86795d4beb35df61faebeb07615", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "595527c9ea087598f7ba3c94e55ed571886b59a332f661bf57a46e9b2a0cda73", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "d1267a87248771d082ee66126c2fe814f9200f8d1784e3e7412cc052f82a6335", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "0e9e4cd1905355aedca5fc9ce41171a1d71c6d2a1c69338618af725afb5e6063", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "2a38fdbf51210a80e3437ab1be12488e0c2bc9d32a8893b63cd6bbf0944c646c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "90878c3bb7068929027cdfaf456196a44d8e537a3cec1d3044bcb81b9e8fe128", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "7d86f26aabf329dcee33cff8aed016838a877d5c8213dc7b428e9f260e4c84b2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "f61ae66c57356a6cffc7527a5ab2b0c7f2e661c7fb3d2cf33b9f23bc6d7a9165", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "73908a2ad282464be6770a6479182d3bdcc9f304c83a984fa145598904805123", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "afc122441fca7e08128702cc4a4356fe7120207da28d2dfcc1ea2e99d1c85eaa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "d55137fa819d5ef169c75db4f7b571c33a7221eaf65ad4c2d2e26f1180c34c45", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "13a05852018f0f06d9cea6bab10b8dc6a97a191fdcf8869a8d412dd98b41434b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "c9eaab73a7ac7bc33ebfe52376e298789da3076f26d531cf9acf401d32b04466", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "856b50530a9eff3402051063f38e602d0f716afc797c68f58157f0f007af1c07", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "0099897eb4ebbab1ab868b3b4d907a50e1367f108bfa53088bccaea1f78bec81", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "7825a6f74fa40448b1f9b134e989c636294afc85227fb0af8c37dad341538651", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "4d907e30f1d35b16befc322b0f0875b1882b7b68a83cf2e55d29abab62a8bf1c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "7c054ab0ad72c8a253c117617fd65cc328b68a59faa7a3121ed28cbe71abe46e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21323,12 +22055,12 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "d06425fec9f5f9178548239d6b90099a7ae995426e30604befa0bf3adfb3abff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21348,7 +22080,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21368,7 +22100,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21388,7 +22120,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21408,7 +22140,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21428,12 +22160,12 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "6ad455593c78dce56f302e35b175dcb59a9e812f6a3e51e01c4212b6543c728d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21453,7 +22185,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21473,7 +22205,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21493,7 +22225,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21513,7 +22245,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21533,7 +22265,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21553,7 +22285,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21573,7 +22305,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21593,7 +22325,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21613,7 +22345,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21633,7 +22365,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21653,7 +22385,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21673,7 +22405,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21693,7 +22425,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21713,7 +22445,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21733,7 +22465,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21753,7 +22485,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21773,7 +22505,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21793,7 +22525,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21813,7 +22545,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21833,7 +22565,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21853,7 +22585,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21873,7 +22605,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21893,7 +22625,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21913,7 +22645,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21933,7 +22665,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21953,7 +22685,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21973,7 +22705,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -21993,7 +22725,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -22013,7 +22745,7 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", @@ -22033,12 +22765,12 @@ "f8488ea7e911", "1f90083224fc" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "b95ed090c47a7f8ac93432ed9fcb6f9eb55a6850fa2d05379ecf16c137aca17f", "target_hash": "9171936199eeb9e4b533748f18658267ec17483b5ed537740177101d119e681e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -22048,7 +22780,7 @@ "pl": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", "target_hash": "6890e165fef9642d07a0539290c37c367e8791754fef478abaa991d5e8413d46", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22063,7 +22795,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22078,7 +22810,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22093,7 +22825,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22108,7 +22840,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22123,7 +22855,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22138,7 +22870,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22153,7 +22885,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22168,7 +22900,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22183,7 +22915,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22198,7 +22930,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22213,7 +22945,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22228,7 +22960,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22243,7 +22975,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22258,7 +22990,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22273,7 +23005,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22288,7 +23020,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22303,7 +23035,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22318,7 +23050,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22333,7 +23065,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22348,7 +23080,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22363,7 +23095,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22378,7 +23110,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22393,7 +23125,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22408,7 +23140,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22423,7 +23155,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22438,7 +23170,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22453,7 +23185,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22468,7 +23200,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22483,7 +23215,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22498,7 +23230,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22513,7 +23245,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22528,7 +23260,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22543,7 +23275,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22558,7 +23290,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22573,7 +23305,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22588,7 +23320,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22603,7 +23335,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22618,7 +23350,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22633,7 +23365,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22648,7 +23380,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22663,7 +23395,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22678,7 +23410,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22693,7 +23425,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22708,7 +23440,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22723,7 +23455,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22738,7 +23470,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22753,7 +23485,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22768,7 +23500,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22783,7 +23515,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22798,7 +23530,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22813,7 +23545,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22828,7 +23560,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22843,7 +23575,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22858,7 +23590,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22873,7 +23605,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22888,7 +23620,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22903,7 +23635,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22918,7 +23650,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22933,7 +23665,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22948,7 +23680,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22963,7 +23695,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22978,7 +23710,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -22993,7 +23725,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -23008,7 +23740,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "5a8920f8cffdd9778556e6d34a3b3158737ad4de3756b049ad58c44c671b54fe", @@ -23023,7 +23755,7 @@ "bacefc4db261", "38c7b6aa54aa" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -23033,7 +23765,7 @@ "pl": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", "target_hash": "948f668f138f45a66b0afa9c28406b466eae72a72f573ebadb5b2a373fb3e86e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23045,7 +23777,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23057,7 +23789,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23069,7 +23801,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23081,7 +23813,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23093,7 +23825,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23105,7 +23837,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23117,7 +23849,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23129,7 +23861,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23141,7 +23873,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23153,7 +23885,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23165,7 +23897,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23177,7 +23909,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23189,7 +23921,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23201,7 +23933,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23213,7 +23945,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23225,7 +23957,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23237,7 +23969,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23249,7 +23981,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23261,7 +23993,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23273,7 +24005,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23285,7 +24017,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23297,7 +24029,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23309,7 +24041,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23321,7 +24053,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23333,7 +24065,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23345,7 +24077,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23357,7 +24089,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23369,7 +24101,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23381,7 +24113,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23393,7 +24125,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23405,7 +24137,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23417,7 +24149,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23429,7 +24161,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23441,7 +24173,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23453,7 +24185,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23465,7 +24197,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23477,7 +24209,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23489,7 +24221,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23501,7 +24233,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23513,7 +24245,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23525,7 +24257,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23537,7 +24269,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23549,7 +24281,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23561,7 +24293,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23573,7 +24305,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23585,7 +24317,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23597,7 +24329,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23609,7 +24341,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23621,7 +24353,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23633,7 +24365,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23645,7 +24377,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23657,7 +24389,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23669,7 +24401,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23681,7 +24413,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23693,7 +24425,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23705,7 +24437,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23717,7 +24449,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23729,7 +24461,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23741,7 +24473,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23753,7 +24485,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23765,7 +24497,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23777,7 +24509,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23789,7 +24521,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23801,7 +24533,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "fcd863fd55fae0163c17289ba1216739f2311a19dd21bf83b9e512ad1179c872", @@ -23813,7 +24545,7 @@ "76ab2a7cda32", "ab6ae78eb1d3" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -23823,7 +24555,7 @@ "pl": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", "target_hash": "8d1905e504c106c3701de2c8f1575b035742d827bdca64ef80f606039b820e5f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23838,7 +24570,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23853,7 +24585,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23868,7 +24600,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23883,7 +24615,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23898,7 +24630,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23913,7 +24645,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23928,7 +24660,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23943,7 +24675,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23958,7 +24690,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23973,7 +24705,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -23988,7 +24720,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24003,7 +24735,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24018,7 +24750,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24033,7 +24765,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24048,7 +24780,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24063,7 +24795,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24078,7 +24810,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24093,7 +24825,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24108,7 +24840,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24123,7 +24855,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24138,7 +24870,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24153,7 +24885,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24168,7 +24900,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24183,7 +24915,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24198,7 +24930,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24213,7 +24945,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24228,7 +24960,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24243,7 +24975,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24258,7 +24990,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24273,7 +25005,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24288,7 +25020,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24303,7 +25035,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24318,7 +25050,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24333,7 +25065,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24348,7 +25080,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24363,7 +25095,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24378,7 +25110,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24393,7 +25125,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24408,7 +25140,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24423,7 +25155,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24438,7 +25170,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24453,7 +25185,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24468,7 +25200,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24483,7 +25215,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24498,7 +25230,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24513,7 +25245,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24528,7 +25260,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24543,7 +25275,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24558,7 +25290,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24573,7 +25305,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24588,7 +25320,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24603,7 +25335,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24618,7 +25350,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24633,7 +25365,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24648,7 +25380,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24663,7 +25395,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24678,7 +25410,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24693,7 +25425,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24708,7 +25440,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24723,7 +25455,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24738,7 +25470,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24753,7 +25485,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24768,7 +25500,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24783,7 +25515,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "9d2d68507d41f8eac88b7ad2b56949571bbf62e38f5c6ce064069e04b06f08e9", @@ -24798,7 +25530,7 @@ "975e5da49a31", "4a448398f4b0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -24819,7 +25551,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24835,7 +25567,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24851,7 +25583,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24867,7 +25599,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24883,7 +25615,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24899,7 +25631,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24915,7 +25647,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24931,7 +25663,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24947,7 +25679,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24963,7 +25695,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24979,7 +25711,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -24995,7 +25727,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25011,7 +25743,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25027,7 +25759,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25043,7 +25775,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25059,7 +25791,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25075,7 +25807,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25091,7 +25823,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25107,7 +25839,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25123,7 +25855,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25139,7 +25871,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25155,7 +25887,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25171,7 +25903,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25187,7 +25919,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25203,7 +25935,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25219,7 +25951,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25235,7 +25967,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25251,7 +25983,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25267,7 +25999,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25283,7 +26015,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25299,7 +26031,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25315,7 +26047,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25331,7 +26063,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25347,7 +26079,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25363,7 +26095,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25379,7 +26111,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25395,7 +26127,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25411,7 +26143,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25427,7 +26159,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25443,7 +26175,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25459,7 +26191,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25475,7 +26207,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25491,7 +26223,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25507,7 +26239,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25523,7 +26255,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25539,7 +26271,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25555,7 +26287,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25571,7 +26303,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25587,7 +26319,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25603,7 +26335,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25619,7 +26351,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25635,7 +26367,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25651,7 +26383,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25667,7 +26399,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25683,7 +26415,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25699,7 +26431,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25715,7 +26447,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25731,7 +26463,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25747,7 +26479,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25763,7 +26495,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25779,7 +26511,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25795,7 +26527,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25811,7 +26543,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25827,7 +26559,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25843,7 +26575,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "a86e0a8b88711283623c64d053fadf8959feb198db4504f402d87bf6eb9dbc67", @@ -25859,7 +26591,7 @@ "9c18a09154ae", "d1071fec39fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -25869,7 +26601,7 @@ "pl": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", "target_hash": "b5ac5489f327fdc39433bd7c58a44738445b0be508370c01f07e1fe5da8489fd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -25893,7 +26625,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -25917,7 +26649,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -25941,7 +26673,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -25965,7 +26697,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -25989,7 +26721,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26013,7 +26745,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26037,7 +26769,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26061,7 +26793,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26085,7 +26817,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26109,7 +26841,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26133,7 +26865,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26157,7 +26889,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26181,7 +26913,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26205,7 +26937,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26229,7 +26961,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26253,7 +26985,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26277,7 +27009,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26301,7 +27033,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26325,7 +27057,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26349,7 +27081,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26373,7 +27105,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26397,7 +27129,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26421,7 +27153,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26445,7 +27177,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26469,7 +27201,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26493,7 +27225,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26517,7 +27249,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26541,7 +27273,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26565,7 +27297,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26589,7 +27321,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26613,7 +27345,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26637,7 +27369,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26661,7 +27393,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26685,7 +27417,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26709,7 +27441,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26733,7 +27465,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26757,7 +27489,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26781,7 +27513,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26805,7 +27537,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26829,7 +27561,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26853,7 +27585,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26877,7 +27609,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26901,7 +27633,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26925,7 +27657,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26949,7 +27681,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26973,7 +27705,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -26997,7 +27729,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27021,7 +27753,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27045,7 +27777,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27069,7 +27801,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27093,7 +27825,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27117,7 +27849,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27141,7 +27873,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27165,7 +27897,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27189,7 +27921,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27213,7 +27945,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27237,7 +27969,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27261,7 +27993,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27285,7 +28017,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27309,7 +28041,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27333,7 +28065,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27357,7 +28089,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27381,7 +28113,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27405,7 +28137,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ab00069d9b51d071b2ce0b9ec82c70d94f681333af0add67f3bcf4aed0ca86dd", @@ -27429,7 +28161,7 @@ "0e168864fe85", "8c654c6bc81d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -27453,7 +28185,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27472,7 +28204,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27491,7 +28223,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27510,7 +28242,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27529,7 +28261,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27548,7 +28280,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27567,7 +28299,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27586,7 +28318,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27605,7 +28337,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27624,7 +28356,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27643,7 +28375,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27662,7 +28394,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27681,7 +28413,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27700,7 +28432,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27719,7 +28451,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27738,7 +28470,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27757,7 +28489,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27776,7 +28508,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27795,7 +28527,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27814,7 +28546,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27833,7 +28565,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27852,7 +28584,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27871,7 +28603,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27890,7 +28622,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27909,7 +28641,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27928,7 +28660,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27947,7 +28679,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27966,7 +28698,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -27985,7 +28717,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28004,7 +28736,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28023,7 +28755,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28042,7 +28774,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28061,7 +28793,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28080,7 +28812,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28099,7 +28831,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28118,7 +28850,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28137,7 +28869,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28156,7 +28888,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28175,7 +28907,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28194,7 +28926,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28213,7 +28945,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28232,7 +28964,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28251,7 +28983,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28270,7 +29002,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28289,7 +29021,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28308,7 +29040,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28327,7 +29059,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28346,7 +29078,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28365,7 +29097,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28384,7 +29116,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28403,7 +29135,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28422,7 +29154,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28441,7 +29173,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28460,7 +29192,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28479,7 +29211,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28498,7 +29230,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28517,7 +29249,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28536,7 +29268,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28555,7 +29287,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28574,7 +29306,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28593,7 +29325,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28612,7 +29344,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28631,7 +29363,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28650,7 +29382,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28669,7 +29401,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "9c132a2f85f7d809acfc51d38efc7f5c077ad83f3b162f68e0d470c2fcff74c1", @@ -28688,7 +29420,7 @@ "b8f202acbf51", "62984457af2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -28707,7 +29439,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28721,7 +29453,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28735,7 +29467,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28749,7 +29481,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28763,7 +29495,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28777,7 +29509,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28791,7 +29523,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28805,7 +29537,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28819,7 +29551,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28833,7 +29565,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28847,7 +29579,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28861,7 +29593,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28875,7 +29607,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28889,7 +29621,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28903,7 +29635,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28917,7 +29649,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28931,7 +29663,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28945,7 +29677,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28959,7 +29691,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28973,7 +29705,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -28987,7 +29719,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29001,7 +29733,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29015,7 +29747,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29029,7 +29761,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29043,7 +29775,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29057,7 +29789,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29071,7 +29803,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29085,7 +29817,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29099,7 +29831,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29113,7 +29845,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29127,7 +29859,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29141,7 +29873,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29155,7 +29887,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29169,7 +29901,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29183,7 +29915,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29197,7 +29929,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29211,7 +29943,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29225,7 +29957,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29239,7 +29971,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29253,7 +29985,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29267,7 +29999,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29281,7 +30013,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29295,7 +30027,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29309,7 +30041,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29323,7 +30055,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29337,7 +30069,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29351,7 +30083,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29365,7 +30097,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29379,7 +30111,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29393,7 +30125,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29407,7 +30139,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29421,7 +30153,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29435,7 +30167,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29449,7 +30181,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29463,7 +30195,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29477,7 +30209,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29491,7 +30223,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29505,7 +30237,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29519,7 +30251,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29533,7 +30265,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29547,7 +30279,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29561,7 +30293,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29575,7 +30307,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29589,7 +30321,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29603,7 +30335,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "db286775d5d8a9ab9f815f640337c9a3667d8f8d8c2e064865295aa61843cc95", @@ -29617,7 +30349,7 @@ "a7a0d3495c80", "cbb9bcb4728e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -29641,7 +30373,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29660,7 +30392,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29679,7 +30411,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29698,7 +30430,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29717,7 +30449,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29736,7 +30468,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29755,7 +30487,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29774,7 +30506,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29793,7 +30525,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29812,7 +30544,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29831,7 +30563,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29850,7 +30582,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29869,7 +30601,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29888,7 +30620,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29907,7 +30639,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29926,7 +30658,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29945,7 +30677,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29964,7 +30696,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -29983,7 +30715,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30002,7 +30734,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30021,7 +30753,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30040,7 +30772,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30059,7 +30791,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30078,7 +30810,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30097,7 +30829,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30116,7 +30848,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30135,7 +30867,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30154,7 +30886,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30173,7 +30905,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30192,7 +30924,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30211,7 +30943,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30230,7 +30962,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30249,7 +30981,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30268,7 +31000,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30287,7 +31019,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30306,7 +31038,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30325,7 +31057,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30344,7 +31076,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30363,7 +31095,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30382,7 +31114,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30401,7 +31133,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30420,7 +31152,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30439,7 +31171,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30458,7 +31190,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30477,7 +31209,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30496,7 +31228,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30515,7 +31247,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30534,7 +31266,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30553,7 +31285,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30572,7 +31304,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30591,7 +31323,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30610,7 +31342,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30629,7 +31361,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30648,7 +31380,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30667,7 +31399,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30686,7 +31418,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30705,7 +31437,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30724,7 +31456,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30743,7 +31475,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30762,7 +31494,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30781,7 +31513,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30800,7 +31532,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30819,7 +31551,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30838,7 +31570,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30857,7 +31589,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e79de0d778a47847cb9d91a1b9834f467e82f87ac09625500abb4ae24e97dc76", @@ -30876,7 +31608,7 @@ "13174f7647ce", "a485057194db" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -30897,7 +31629,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -30913,7 +31645,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -30929,7 +31661,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -30945,7 +31677,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -30961,7 +31693,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -30977,7 +31709,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -30993,7 +31725,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31009,7 +31741,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31025,7 +31757,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31041,7 +31773,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31057,7 +31789,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31073,7 +31805,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31089,7 +31821,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31105,7 +31837,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31121,7 +31853,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31137,7 +31869,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31153,7 +31885,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31169,7 +31901,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31185,7 +31917,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31201,7 +31933,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31217,7 +31949,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31233,7 +31965,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31249,7 +31981,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31265,7 +31997,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31281,7 +32013,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31297,7 +32029,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31313,7 +32045,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31329,7 +32061,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31345,7 +32077,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31361,7 +32093,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31377,7 +32109,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31393,7 +32125,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31409,7 +32141,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31425,7 +32157,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31441,7 +32173,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31457,7 +32189,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31473,7 +32205,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31489,7 +32221,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31505,7 +32237,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31521,7 +32253,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31537,7 +32269,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31553,7 +32285,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31569,7 +32301,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31585,7 +32317,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31601,7 +32333,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31617,7 +32349,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31633,7 +32365,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31649,7 +32381,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31665,7 +32397,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31681,7 +32413,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31697,7 +32429,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31713,7 +32445,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31729,7 +32461,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31745,7 +32477,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31761,7 +32493,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31777,7 +32509,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31793,7 +32525,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31809,7 +32541,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31825,7 +32557,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31841,7 +32573,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31857,7 +32589,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31873,7 +32605,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31889,7 +32621,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31905,7 +32637,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31921,7 +32653,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "15a5069bf3d7f2d3fc9a91e0b36497102d52c2dccf683dbed5cf74a381b6ac16", @@ -31937,7 +32669,7 @@ "9295329348f0", "c72fde4b840b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -31960,7 +32692,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -31978,7 +32710,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -31996,7 +32728,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32014,7 +32746,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32032,7 +32764,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32050,7 +32782,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32068,7 +32800,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32086,7 +32818,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32104,7 +32836,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32122,7 +32854,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32140,7 +32872,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32158,7 +32890,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32176,7 +32908,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32194,7 +32926,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32212,7 +32944,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32230,7 +32962,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32248,7 +32980,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32266,7 +32998,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32284,7 +33016,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32302,7 +33034,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32320,7 +33052,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32338,7 +33070,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32356,7 +33088,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32374,7 +33106,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32392,7 +33124,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32410,7 +33142,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32428,7 +33160,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32446,7 +33178,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32464,7 +33196,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32482,7 +33214,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32500,7 +33232,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32518,7 +33250,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32536,7 +33268,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32554,7 +33286,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32572,7 +33304,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32590,7 +33322,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32608,7 +33340,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32626,7 +33358,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32644,7 +33376,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32662,7 +33394,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32680,7 +33412,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32698,7 +33430,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32716,7 +33448,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32734,7 +33466,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32752,7 +33484,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32770,7 +33502,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32788,7 +33520,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32806,7 +33538,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32824,7 +33556,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32842,7 +33574,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32860,7 +33592,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32878,7 +33610,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32896,7 +33628,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32914,7 +33646,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32932,7 +33664,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32950,7 +33682,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32968,7 +33700,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -32986,7 +33718,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33004,7 +33736,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33022,7 +33754,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33040,7 +33772,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33058,7 +33790,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33076,7 +33808,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33094,7 +33826,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33112,7 +33844,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "b6cdf3f3b3ef2a5775c6c7a60e1b464650b69bc004438c4c9b3aceaaa130504f", @@ -33130,7 +33862,7 @@ "df09c6a633a1", "69f5b6175dd2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -33140,332 +33872,332 @@ "pl": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "b87d0844cfe94a36f6e321ecfdb51e5fba7e65f0cf663ceaa966659a0b6a825e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "d980d3a16d52c9de1ce24a5c4ba7b7cbc6f1615161949b2ae550fb6b143445ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "0baba33605a207d734f10f8a6e45da75bb2d045883e135fd26dcfeb6a580611a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "07d3341f49d9532a424fafeeebfc0c0e32c4945d6a7f288b2bd5d7fd9dfdca0d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "8acbad6f254f09d36ff07d5ab5e3449c863b4fb53e99138267ab2aaec954fd99", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "1772c21d25f2df6261e29223130dab5d62e2932b5d141fb166820c781974f540", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "a880a72e1a45f3003d6e85f70c75fe3e782f751b7b3bae07d2a9348a3b9e79b0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "65bfda84561b7d6bba7d195135a004d41de2097974c7066d7fc3c3aafb005ade", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "73d698529fae08c105b3c0a3df7150df5dc6a270a63c3c5030549dae85faf7d9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "da33ec7afc5222a947543c905ab0e6d0b43836e653da4ba46ad19d33bb2c1896", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "6cf3745daadd62f80289deb916b93ef8d53996885cd2b7c8b2a3138e7da9d2ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "e01c6037527044687e07fa6bea55914ba9a3ed60aa79e133965c967d027ef92a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "59957ee84cf0f751581353763bb05b679afc63b7c493795d734cc4b5ce6e674c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "999b4af7297809b778d5b56d9e057f1338378b0cb35ce74c9db988e9c808d5a2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "c17cfbbc29679c37c1ba10e291d8ec8da54802d8c195483cae283c3b2121b9f6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "1f999b3a934a0c6fa4a50f0aec41ef2bc62d85a3dcb71e7715b8a1c25660bdab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "5476788d3e62913715ca0e1dcc8a4b89b8b085d89a05e76fe84c0061afddb072", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "1c16ddcc5ed3404b4bcbae215c744c18214082ea2ca754f601b451a393539a09", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "9f50e7d9061344bdb38c3476bf462abbbbd037b16a90b552e268c793f8ab5f8f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "5bf879328c8eef5eec5952f5b0f779766cef4d98eab3b8abf90b174600c49962", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "82dec385b58a5c3fc71cfd182975bbefee2771a740a97a52ddbcbe8645538af6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "2fb31d228ac2bb963f9b74539df6fc9fc05e8cbf7e7152b09f51f400267769ca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "5210073ec8ce2b8a0ab34f25bd538cb26dac5f7f7915a06d68d777685fa2ebcf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "f69b0588aa215a5dbae0cc2514e58af1b9194913a9d6408d7a928f89c4632c3e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "84b6b3f6f31e11ae5bdc094ad9f08701fd2a0ffd3517541da14854729ce236f7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "6e85af5e20bb5e24d531e7c449374f759819fe34cd44c5fd6dec99e427f912f6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "8d731aba56467e8b47f18c63584219366282185c4222efeba2bc4474d552cf4a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "6eaac3d4788e3a73ec93a80142a99b59a4bb3c63e11e624c205ec89b747df3bd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "9aa63af90267a0a3d2acf9eee770f7d97138eb5dc6c26e4c5515af2149f75fce", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "81edc86fe3ec7a96f0d6f7bc712697880809a70c2c49c88ead23af3a94872c07", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "dcbb95b0d5f42a3f16a8704207e3cb213bef8ace5ceaaf22e690a72a08da4cbc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "95a222351b400d5dbb291ca9debaaa49535edda4f1b17a6d7720989e67c8a846", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "418737bf6838b574c94846c0d36edcfcabc5e371cd6c96d36b1cf94b94c809d5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "7aa0765b1b8a2dc922e8a2d4f1b5ba6563e01db2a15264aeb7b8770fbec48bde", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "e9eff8659ada52bc467b1f1b184b296ec30ac9c37ec0c14e39eaaffcef2c9393", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "33026cdcc53c5652ab8dca7a4d9ba7ffb3ba92bc6c1ba494c0fb82f57182191e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "d4ffae986699999fb322ac5e615b2b79f3aff5851924716d000917ca14f85306", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "2a45e9eaba65ef2db9d220531fe46b9aa92cf4135c6b42135db4c4a73af4f32c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "7ae969ba4ed111b58187c0c1f0b8d2b8717af15f6d541f5375f4cf7a2a11519c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "2faa3d38c38bbd157ed7e90c2c47ca082274028abca0f2103a6a990442c1164b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "cc47c55e217006065b0f12af15c0b47a857c187beaabb88cb57124069533ea7d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "24ec09088d0e8eafa371cefeaae9b20a3ac8db4e8a7b9aa649bd392e5c6d0fbc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "8d81fb2b198f4d01f200d647652f27585c51ceb1a7f982af12739c7fcd65b50f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "3de090ae0ed912c4e312ab911cf44a48a11613ace0cee2c51ece82113119754b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "6205d7fc18aff2893f4e794178d95dfca7fa66aa728661eda7c38a4232006dda", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "d890c6b5f2102045d2bc8b207eea01c6e3de11567fd5e2b92859409218eb9fa5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "95ad1b4b056a5937dab412fb72d7268257b49497b4c4bdd9f79bbadab7fcafa3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "7e1876a17545ca44175b6e1de446d4db6a659f7f5dc0c228aaba55931576042f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "0b74854733222d07c31ff326e6944f84a372c211e5332976aab9a4c4b5e407ed", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "5eb236258390c13772f52ed5993931392d22ae3567ddf4c8cad723438d072cff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "e92afaf7e8bc44a007f5f496e0a11c42e0d9f1205e7a0f47f1179fe5253ad3b7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "02682a49d3a1e9c848bee5520bf6989ed3ec2257f3eb2185c9fbaf084bc60bdf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "2051aa07e83546f659c9df11cb7e6dc3d37d911364019aedd72d787436afddf9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "aaf1367daf220413817c637f558f225fb05543ca789ce23683feefe51f426967", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "c6edb30eb8ffd1b9e1df90c7e9216ce19d018df41006f170578119736560cee5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "3630da14c5677f44845b3ae526fd48414d0e44b9c597d88e7c07d524c78c67fa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "cd399f88e2a3670d81574df4c7714e525660c4628f752a7fd9af8c2fa40c6aad", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "d36a507da7d8730ee4c4e63c4f0cffaa1105778fa7973de1023f2c1a05a50266", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "3f9c9081b8861d6e3d1c673da7335a3cca0274dc70aa024c0f5795b6b1803bfa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "bd7550316fc6f1026b9cd454aef6137d740456e0023b6fa6b9168a93b477364c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "70bd7fe7dd5722ececcb90973dd0568deefb73bd2d9425d0e447099ed532b993", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "8139c2a72b36f6b1f5987029613985b7c65205a4a945e68b8feffc2a33af8feb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "e204c01be2e52abf26613a805e8e2ed6f2d6576f35c77a5d47094621eaed2e7b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "060c78cddc5eccad31efa0c15954e5754b292e98c41714c0ab1187b2a0b84690", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "d2619ad8ab092d959d12191f399188b295b8c618f9e2f0ad2f8582c75fc1c3e7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "77e3f17de9a41057cf05da24abb68bd2f1c8e8831b1b0b455d28e91815bfaf74", "target_hash": "45d49bfa75193bfe3906b4761ec0f48cdd9917287dbc36c84cbb7aa57f5a17b8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -33488,7 +34220,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33506,7 +34238,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33524,7 +34256,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33542,7 +34274,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33560,7 +34292,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33578,7 +34310,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33596,7 +34328,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33614,7 +34346,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33632,7 +34364,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33650,7 +34382,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33668,7 +34400,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33686,7 +34418,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33704,7 +34436,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33722,7 +34454,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33740,7 +34472,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33758,7 +34490,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33776,7 +34508,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33794,7 +34526,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33812,7 +34544,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33830,7 +34562,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33848,7 +34580,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33866,7 +34598,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33884,7 +34616,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33902,7 +34634,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33920,7 +34652,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33938,7 +34670,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33956,7 +34688,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33974,7 +34706,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -33992,7 +34724,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34010,7 +34742,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34028,7 +34760,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34046,7 +34778,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34064,7 +34796,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34082,7 +34814,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34100,7 +34832,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34118,7 +34850,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34136,7 +34868,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34154,7 +34886,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34172,7 +34904,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34190,7 +34922,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34208,7 +34940,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34226,7 +34958,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34244,7 +34976,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34262,7 +34994,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34280,7 +35012,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34298,7 +35030,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34316,7 +35048,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34334,7 +35066,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34352,7 +35084,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34370,7 +35102,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34388,7 +35120,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34406,7 +35138,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34424,7 +35156,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34442,7 +35174,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34460,7 +35192,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34478,7 +35210,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34496,12 +35228,12 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", "target_hash": "24c3d7bcabb5b9f028ec47f8ef7544d8d7cf75ef8177298cd7fbd36413082b69", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34519,7 +35251,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34537,7 +35269,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34555,7 +35287,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34573,7 +35305,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34591,7 +35323,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34609,7 +35341,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34627,7 +35359,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "19a2881aa00f2636c5df51fa1f26d87a84adad1ea95fb47d89965549625240a0", @@ -34645,7 +35377,7 @@ "ffa17c5ac309", "b68bf7eedc90" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -34655,7 +35387,7 @@ "pl": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", "target_hash": "a6e1aa14e6f570900e9d1916ca8a1c54d8885bf2986df7325791ae5442fae34e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34673,7 +35405,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34691,7 +35423,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34709,7 +35441,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34727,7 +35459,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34745,7 +35477,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34763,7 +35495,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34781,7 +35513,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34799,7 +35531,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34817,7 +35549,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34835,7 +35567,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34853,7 +35585,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34871,7 +35603,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34889,7 +35621,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34907,7 +35639,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34925,7 +35657,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34943,7 +35675,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34961,7 +35693,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34979,7 +35711,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -34997,7 +35729,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35015,7 +35747,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35033,7 +35765,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35051,7 +35783,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35069,7 +35801,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35087,7 +35819,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35105,7 +35837,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35123,7 +35855,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35141,7 +35873,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35159,7 +35891,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35177,7 +35909,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35195,7 +35927,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35213,7 +35945,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35231,7 +35963,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35249,7 +35981,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35267,7 +35999,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35285,7 +36017,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35303,7 +36035,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35321,7 +36053,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35339,7 +36071,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35357,7 +36089,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35375,7 +36107,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35393,7 +36125,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35411,7 +36143,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35429,7 +36161,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35447,7 +36179,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35465,7 +36197,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35483,7 +36215,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35501,7 +36233,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35519,7 +36251,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35537,7 +36269,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35555,7 +36287,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35573,7 +36305,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35591,7 +36323,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35609,7 +36341,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35627,7 +36359,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35645,7 +36377,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35663,7 +36395,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35681,7 +36413,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35699,7 +36431,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35717,7 +36449,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35735,7 +36467,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35753,7 +36485,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35771,7 +36503,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35789,7 +36521,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35807,7 +36539,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "5f289d55d0335b6751e54c52f185649193a2e1d923d19b0b22a69c2a6742e064", @@ -35825,7 +36557,7 @@ "43ecc9840055", "392de54fa699" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -35858,7 +36590,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -35886,7 +36618,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -35914,7 +36646,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -35942,7 +36674,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -35970,7 +36702,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -35998,7 +36730,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36026,7 +36758,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36054,7 +36786,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36082,7 +36814,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36110,7 +36842,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36138,7 +36870,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36166,7 +36898,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36194,7 +36926,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36222,7 +36954,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36250,7 +36982,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36278,7 +37010,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36306,7 +37038,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36334,7 +37066,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36362,7 +37094,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36390,7 +37122,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36418,7 +37150,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36446,7 +37178,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36474,7 +37206,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36502,7 +37234,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36530,7 +37262,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36558,7 +37290,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36586,7 +37318,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36614,7 +37346,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36642,7 +37374,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36670,7 +37402,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36698,7 +37430,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36726,7 +37458,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36754,7 +37486,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36782,7 +37514,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36810,7 +37542,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36838,7 +37570,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36866,7 +37598,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36894,7 +37626,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36922,7 +37654,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36950,7 +37682,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -36978,7 +37710,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37006,7 +37738,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37034,7 +37766,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37062,7 +37794,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37090,7 +37822,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37118,7 +37850,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37146,7 +37878,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37174,7 +37906,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37202,7 +37934,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37230,7 +37962,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37258,7 +37990,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37286,7 +38018,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37314,7 +38046,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37342,7 +38074,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37370,7 +38102,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37398,7 +38130,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37426,7 +38158,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37454,7 +38186,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37482,7 +38214,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37510,7 +38242,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37538,7 +38270,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37566,7 +38298,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37594,7 +38326,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37622,7 +38354,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37650,7 +38382,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e86df45bc47aaecf1cf4d9cd539dbf04a2643e754b3c217097ac287c4da97684", @@ -37678,7 +38410,7 @@ "2fcf669a6c24", "4e1a9c6a0860" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -37688,7 +38420,7 @@ "pl": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", "target_hash": "ff498afa7762ec16b404c99c13986824344cbae6ec248c731e3de0a66487b5da", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37701,7 +38433,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37714,7 +38446,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37727,7 +38459,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37740,7 +38472,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37753,7 +38485,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37766,7 +38498,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37779,7 +38511,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37792,7 +38524,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37805,7 +38537,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37818,7 +38550,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37831,7 +38563,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37844,7 +38576,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37857,7 +38589,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37870,7 +38602,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37883,7 +38615,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37896,7 +38628,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37909,7 +38641,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37922,7 +38654,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37935,7 +38667,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37948,7 +38680,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37961,7 +38693,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37974,7 +38706,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -37987,7 +38719,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38000,7 +38732,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38013,7 +38745,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38026,7 +38758,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38039,7 +38771,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38052,7 +38784,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38065,7 +38797,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38078,7 +38810,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38091,7 +38823,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38104,7 +38836,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38117,7 +38849,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38130,7 +38862,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38143,7 +38875,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38156,7 +38888,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38169,7 +38901,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38182,7 +38914,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38195,7 +38927,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38208,7 +38940,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38221,7 +38953,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38234,7 +38966,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38247,7 +38979,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38260,7 +38992,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38273,7 +39005,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38286,7 +39018,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38299,7 +39031,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38312,7 +39044,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38325,7 +39057,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38338,7 +39070,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38351,7 +39083,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38364,7 +39096,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38377,7 +39109,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38390,7 +39122,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38403,7 +39135,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38416,7 +39148,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38429,7 +39161,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38442,7 +39174,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38455,7 +39187,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38468,7 +39200,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38481,7 +39213,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38494,7 +39226,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38507,7 +39239,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38520,7 +39252,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "a878e8f648fae9e28b18340c1812cfa587c5d15656ffbcb9dc8c528c694712ca", @@ -38533,7 +39265,7 @@ "e1b48218032e", "117617930abd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -38552,7 +39284,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38566,7 +39298,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38580,7 +39312,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38594,7 +39326,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38608,7 +39340,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38622,7 +39354,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38636,7 +39368,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38650,7 +39382,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38664,7 +39396,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38678,7 +39410,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38692,7 +39424,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38706,7 +39438,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38720,7 +39452,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38734,7 +39466,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38748,7 +39480,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38762,7 +39494,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38776,7 +39508,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38790,7 +39522,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38804,7 +39536,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38818,7 +39550,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38832,7 +39564,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38846,7 +39578,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38860,7 +39592,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38874,7 +39606,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38888,7 +39620,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38902,7 +39634,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38916,7 +39648,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38930,7 +39662,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38944,7 +39676,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38958,7 +39690,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38972,7 +39704,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -38986,7 +39718,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39000,7 +39732,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39014,7 +39746,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39028,7 +39760,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39042,7 +39774,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39056,7 +39788,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39070,7 +39802,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39084,7 +39816,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39098,7 +39830,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39112,7 +39844,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39126,7 +39858,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39140,7 +39872,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39154,7 +39886,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39168,7 +39900,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39182,7 +39914,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39196,7 +39928,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39210,7 +39942,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39224,7 +39956,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39238,7 +39970,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39252,7 +39984,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39266,7 +39998,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39280,7 +40012,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39294,7 +40026,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39308,7 +40040,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39322,7 +40054,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39336,7 +40068,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39350,7 +40082,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39364,7 +40096,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39378,7 +40110,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39392,7 +40124,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39406,7 +40138,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39420,7 +40152,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39434,7 +40166,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39448,7 +40180,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "fab37611a2115ee5edbc00da9bc68356b58b0320d27c3cb70e3e68923845144f", @@ -39462,7 +40194,7 @@ "3f1c98e24bcb", "dca1281a49a7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -39496,7 +40228,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39525,7 +40257,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39554,7 +40286,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39583,7 +40315,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39612,7 +40344,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39641,7 +40373,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39670,7 +40402,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39699,7 +40431,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39728,7 +40460,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39757,7 +40489,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39786,7 +40518,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39815,7 +40547,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39844,7 +40576,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39873,7 +40605,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39902,7 +40634,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39931,7 +40663,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39960,7 +40692,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -39989,7 +40721,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40018,7 +40750,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40047,7 +40779,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40076,7 +40808,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40105,7 +40837,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40134,7 +40866,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40163,7 +40895,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40192,7 +40924,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40221,7 +40953,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40250,7 +40982,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40279,7 +41011,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40308,7 +41040,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40337,7 +41069,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40366,7 +41098,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40395,7 +41127,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40424,7 +41156,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40453,7 +41185,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40482,7 +41214,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40511,7 +41243,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40540,7 +41272,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40569,7 +41301,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40598,7 +41330,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40627,7 +41359,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40656,7 +41388,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40685,7 +41417,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40714,7 +41446,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40743,7 +41475,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40772,7 +41504,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40801,7 +41533,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40830,7 +41562,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40859,7 +41591,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40888,7 +41620,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40917,7 +41649,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40946,7 +41678,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -40975,7 +41707,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41004,7 +41736,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41033,7 +41765,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41062,7 +41794,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41091,7 +41823,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41120,7 +41852,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41149,7 +41881,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41178,7 +41910,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41207,7 +41939,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41236,7 +41968,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41265,7 +41997,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41294,7 +42026,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41323,7 +42055,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41352,7 +42084,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e6dad5fa6e9eb6c0c7484edebc4d008255a04bd6058e0cf36464a26dbe114130", @@ -41381,7 +42113,7 @@ "a130004a15b9", "106955b9a8bd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -41418,7 +42150,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41450,7 +42182,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41482,7 +42214,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41514,7 +42246,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41546,7 +42278,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41578,7 +42310,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41610,7 +42342,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41642,7 +42374,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41674,7 +42406,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41706,7 +42438,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41738,7 +42470,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41770,7 +42502,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41802,7 +42534,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41834,7 +42566,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41866,7 +42598,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41898,7 +42630,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41930,7 +42662,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41962,7 +42694,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -41994,7 +42726,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42026,7 +42758,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42058,7 +42790,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42090,7 +42822,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42122,7 +42854,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42154,7 +42886,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42186,7 +42918,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42218,7 +42950,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42250,7 +42982,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42282,7 +43014,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42314,7 +43046,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42346,7 +43078,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42378,7 +43110,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42410,7 +43142,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42442,7 +43174,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42474,7 +43206,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42506,7 +43238,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42538,7 +43270,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42570,7 +43302,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42602,7 +43334,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42634,7 +43366,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42666,7 +43398,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42698,7 +43430,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42730,7 +43462,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42762,7 +43494,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42794,7 +43526,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42826,7 +43558,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42858,7 +43590,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42890,7 +43622,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42922,7 +43654,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42954,7 +43686,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -42986,7 +43718,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43018,7 +43750,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43050,7 +43782,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43082,7 +43814,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43114,7 +43846,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43146,7 +43878,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43178,7 +43910,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43210,12 +43942,12 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", "target_hash": "1655ff07a2b3850f65b7054639375d30495e1c2cd76635413e2935f94b4cd6c6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43247,7 +43979,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43279,7 +44011,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43311,7 +44043,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43343,7 +44075,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43375,7 +44107,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43407,7 +44139,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43439,7 +44171,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "2817788aa9f196d3b87963859d07c92b4bee4c97c2e9f97af18432ac371c2b4d", @@ -43471,7 +44203,7 @@ "edfd46050340", "dee403844efb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -43481,7 +44213,7 @@ "pl": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", "target_hash": "6e9eef7faf4c53380d560a957f0be6b66107235f2c0f22ddd843d3ac6f150931", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43495,7 +44227,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43509,7 +44241,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43523,7 +44255,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43537,7 +44269,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43551,7 +44283,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43565,7 +44297,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43579,7 +44311,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43593,7 +44325,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43607,7 +44339,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43621,7 +44353,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43635,7 +44367,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43649,7 +44381,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43663,7 +44395,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43677,7 +44409,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43691,7 +44423,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43705,7 +44437,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43719,7 +44451,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43733,7 +44465,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43747,7 +44479,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43761,7 +44493,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43775,7 +44507,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43789,7 +44521,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43803,7 +44535,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43817,7 +44549,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43831,7 +44563,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43845,7 +44577,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43859,7 +44591,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43873,7 +44605,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43887,7 +44619,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43901,7 +44633,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43915,7 +44647,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43929,7 +44661,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43943,7 +44675,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43957,7 +44689,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43971,7 +44703,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43985,7 +44717,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -43999,7 +44731,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44013,7 +44745,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44027,7 +44759,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44041,7 +44773,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44055,7 +44787,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44069,7 +44801,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44083,7 +44815,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44097,7 +44829,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44111,7 +44843,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44125,7 +44857,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44139,7 +44871,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44153,7 +44885,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44167,7 +44899,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44181,7 +44913,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44195,7 +44927,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44209,7 +44941,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44223,7 +44955,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44237,7 +44969,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44251,7 +44983,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44265,7 +44997,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44279,7 +45011,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44293,7 +45025,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44307,7 +45039,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44321,7 +45053,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44335,7 +45067,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44349,7 +45081,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44363,7 +45095,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44377,7 +45109,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "d8f943bc9b0125c9d959ddb577002891d6a7a119819019990e08981dce06899b", @@ -44391,7 +45123,7 @@ "7713c07e26db", "d5bfa2107cbf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -44401,7 +45133,7 @@ "pl": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", "target_hash": "fbcf22755d31250d43e09b6a566c850a009cb2a5d4179a953bd0279b1f46ff4e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44415,7 +45147,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44429,7 +45161,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44443,7 +45175,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44457,7 +45189,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44471,7 +45203,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44485,7 +45217,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44499,7 +45231,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44513,7 +45245,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44527,7 +45259,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44541,7 +45273,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44555,7 +45287,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44569,7 +45301,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44583,7 +45315,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44597,7 +45329,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44611,7 +45343,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44625,7 +45357,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44639,7 +45371,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44653,7 +45385,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44667,7 +45399,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44681,7 +45413,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44695,7 +45427,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44709,7 +45441,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44723,7 +45455,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44737,7 +45469,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44751,7 +45483,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44765,7 +45497,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44779,7 +45511,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44793,7 +45525,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44807,7 +45539,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44821,7 +45553,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44835,7 +45567,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44849,7 +45581,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44863,7 +45595,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44877,7 +45609,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44891,7 +45623,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44905,7 +45637,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44919,7 +45651,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44933,7 +45665,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44947,7 +45679,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44961,7 +45693,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44975,7 +45707,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -44989,7 +45721,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45003,7 +45735,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45017,7 +45749,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45031,7 +45763,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45045,7 +45777,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45059,7 +45791,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45073,7 +45805,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45087,7 +45819,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45101,7 +45833,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45115,7 +45847,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45129,7 +45861,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45143,7 +45875,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45157,7 +45889,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45171,7 +45903,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45185,7 +45917,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45199,7 +45931,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45213,7 +45945,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45227,7 +45959,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45241,7 +45973,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45255,7 +45987,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45269,7 +46001,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45283,7 +46015,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45297,7 +46029,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "80a20416af055577b2fca2469678346c4eb478e747bcafe4b90d4d526dbe0f6b", @@ -45311,7 +46043,7 @@ "bd3284ce64bf", "e11d01773c74" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -45321,7 +46053,7 @@ "pl": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", "target_hash": "98ab603e1b66b166ff2f2cfae90cce573c2b85880132f1c773f01d9efec54ca1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45337,7 +46069,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45353,7 +46085,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45369,7 +46101,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45385,7 +46117,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45401,7 +46133,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45417,7 +46149,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45433,7 +46165,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45449,7 +46181,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45465,7 +46197,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45481,7 +46213,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45497,7 +46229,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45513,7 +46245,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45529,7 +46261,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45545,7 +46277,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45561,7 +46293,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45577,7 +46309,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45593,7 +46325,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45609,7 +46341,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45625,7 +46357,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45641,7 +46373,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45657,7 +46389,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45673,7 +46405,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45689,7 +46421,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45705,7 +46437,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45721,7 +46453,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45737,7 +46469,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45753,7 +46485,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45769,7 +46501,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45785,7 +46517,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45801,7 +46533,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45817,7 +46549,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45833,7 +46565,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45849,7 +46581,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45865,7 +46597,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45881,7 +46613,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45897,7 +46629,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45913,7 +46645,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45929,7 +46661,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45945,7 +46677,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45961,7 +46693,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45977,7 +46709,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -45993,7 +46725,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46009,7 +46741,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46025,7 +46757,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46041,7 +46773,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46057,7 +46789,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46073,7 +46805,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46089,7 +46821,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46105,7 +46837,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46121,7 +46853,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46137,7 +46869,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46153,7 +46885,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46169,7 +46901,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46185,7 +46917,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46201,7 +46933,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46217,7 +46949,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46233,7 +46965,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46249,7 +46981,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46265,7 +46997,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46281,7 +47013,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46297,7 +47029,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46313,7 +47045,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46329,7 +47061,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46345,7 +47077,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "bde6f6774b0df7509efd52d127ccfb4e521c952aa07aeecb929e025954c1ca65", @@ -46361,7 +47093,7 @@ "c9825236dfe8", "731ca3efba46" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -46386,7 +47118,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46406,7 +47138,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46426,7 +47158,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46446,7 +47178,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46466,7 +47198,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46486,7 +47218,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46506,7 +47238,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46526,7 +47258,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46546,7 +47278,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46566,7 +47298,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46586,7 +47318,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46606,7 +47338,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46626,7 +47358,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46646,7 +47378,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46666,7 +47398,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46686,7 +47418,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46706,7 +47438,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46726,7 +47458,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46746,7 +47478,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46766,7 +47498,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46786,7 +47518,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46806,7 +47538,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46826,7 +47558,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46846,7 +47578,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46866,7 +47598,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46886,7 +47618,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46906,7 +47638,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46926,7 +47658,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46946,7 +47678,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46966,7 +47698,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -46986,7 +47718,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47006,7 +47738,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47026,7 +47758,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47046,7 +47778,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47066,7 +47798,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47086,7 +47818,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47106,7 +47838,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47126,7 +47858,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47146,7 +47878,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47166,7 +47898,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47186,7 +47918,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47206,7 +47938,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47226,7 +47958,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47246,7 +47978,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47266,7 +47998,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47286,7 +48018,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47306,7 +48038,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47326,7 +48058,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47346,7 +48078,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47366,7 +48098,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47386,7 +48118,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47406,7 +48138,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47426,7 +48158,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47446,7 +48178,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47466,7 +48198,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47486,7 +48218,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47506,7 +48238,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47526,7 +48258,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47546,7 +48278,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47566,7 +48298,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47586,7 +48318,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47606,7 +48338,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47626,7 +48358,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47646,7 +48378,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47666,7 +48398,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0eb0405cc3dac44f4cdab64763f46818f2ca159d6f9da1eb4e9f1a077a660cf1", @@ -47686,7 +48418,7 @@ "e5e60acd9d0c", "1372aec9223f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -47696,332 +48428,332 @@ "pl": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "7c65557ccb822dff2e9c7dd5d2896f310f4cb88007046a19f1ef7f224788e0f6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "b0f5fc07ac746e139f1780691528b2d52017cdbc2331324218799f29057c150f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "78794c0bb690a90bf32423f3d444a70d32aac6e2b90136a590bd56accc73b595", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "2b718ed08da05888dae4f269c709f4c7cbbdb8e5f21c9db464babcb8877561ec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "a01932b994ed8f7db7fa9bd442250f7c324079409907b5078d315e261249e4ef", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "c94db52c5365333c631560718d9a91f98882c31c0ae43e3a177a15745665f165", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "a1d274df2b274b757a595fb68122ff16f02207ecad5a23e44f9b6fd119c43d8a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "5d14826cc213c7cc72416a958729b508ce7cac87aa94a64702b6cd23e7f610e3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "9c5c1076545d4fc4aaa8b5037130a594f6cc7233916a6cf28b5d17cf1382fa8a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "b6b9bedd2cc74c560261acb525dd5100079d262f2b5d465fa3fa038b2d5a4603", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "90991aa44f9d19b36eac81504caec9e409277058aca69a736a8dd342d447072b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "9f94bd93914ec793fb00aff19866d32981a3c52d61991576749c164b8f7be238", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "bc784736cd3788f7ac69d223dc074d1bab02794d70ae570c6bf621e450d80fbd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "22ce03efe86bbba19f26de5a824d03349ad7001c77f1c6dcb0481c7e68e6fa47", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "89117b9246ab121333760cf4ec77e343c053d02b54cdad7ad4fe8949123f3bd3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "a812c9e7150a546aaa9c95056a4134483ebbe7ca7bcc29851050e3423495569b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "e7766f19ae6869f167a7836d44e55f65f372e0d80be69ce15f151c5f9889a8ba", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "6fd23da0cff4099cdb86a2b5fe23dd6b3b24b13d47d9f6245b8e24c6e462976b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "6b0eed0fe99e0d7aa02f187206b0f4ac7503d167d5f50e828db56179f4b72f93", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "36ecb6a65372a06860b11aa5be4c43e55a210a518a625d5182b0cb4805121c96", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "7b0dd3e2fb113ffb4705e568375ce14497ebb14c867ad491b7a6468bc4e8f216", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "66812ae106b0defe4f4c4bab0d8595f3657ef14922a651848d94966807b0ba65", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "569faec69890e8c19270eb8047c1440a674380024f5b15487f1343d16cc304c6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "960dad1b18eabd13e66b7fc5e0d86bcbe7358dd2ff0b9f216b3322b27dff0eb6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "6219ad560eead4b3a798e12eb42006fef4be9b46a343c397901ff921ab55c9a8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "7ac8751a18a6f8153dec596bf50b97b4e6a2f5652f66cf2ac153c6bcc27ace49", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "141a8f2f28494f8c692a9143f420c78878590c88d5ffbc6bafa95e3085ed7935", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "a6ce8988a5d01d5309a81a9006258322082ceedef64ece71d1698aa73ebf2e21", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "c5deeca5f991c3f9ad648b2399f27d4eb238e9ab83c49adf8dd2222a00ff20ca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "a30b910b7a3d34fb524d6743f9503b719f1891851fcf63667e42afd45c737116", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "808aa1c3681cca6db73224ecbcf9e50fb2bdd23bdc88d673845fedb8c7a9c615", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "50093aed3aa96c46469a6f2eb4fc17d763650b60ad4f8aa075ab374211138c39", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "219936f9b15d241dc4f704bba5819f32aa5bd655398653f4a4b050df07665bea", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "423047a36250edf7b11b2e27e482d5e96ce8aef098f9b1bbdbb31e2b42b81469", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "0448fb18214a83349f59c68ea2d16de292a6d6b1ecc439c0d837b136994a6afe", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "217088e01a1afa15183be4292f4e935f5d0049c5815b6e3dd616b08527789dc5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "0848bdd8fbba8cac64551a3a2acc5b266280cbcb6fe873ec6f5ab7f39658eaf7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "79b024b748e51a1f3db0af7e97688b14be700a2557e9a7f4687fbd93fa3669f4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "afa0368bb7b8ab1c31cf10ea8cc7d8e28909e08c22e4983f5d5587e0f84cb0a4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "f01c7e931d11fb5ef1589a981f73a096dda3eda8818ed3d6edec340cb0a86ede", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "0d176a2ffa7bf8c933c08155d5cb3a9a2c76d9279dd4fc7499ebb05a21e56ca3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "27f927fa2541a07fdcd23088998d464f7c00ce03c43b8cbefe42b118e49247cc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "67b4ceade77d43992ec7238c926b7deff51c7a493d7d321c2ff517865c5daf0b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "7ed3d355c079809763bcb18bb6d4c52c41d87b080ee8d695fd4e59eef45dcde5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "79d16c61ae8a2898685e252fca33364343fbf22d4ad64cfb771c50ef4a22cc74", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "45868c0eef6e3fbc93fe2a42d8c52a440c162265b427f34b411a15dc327a39e8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "551dadd707948376d7c59e162b408724b5c21a931992bf109574aa6e54bc904f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "e89880ff8be812a55267ab9fdb2700803ab892cd0b1d628deeac162e1fe9f9d0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "a834c64318120ce6ac304f221dca2742adcb88b5298a751f36948ab56304b640", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "c9c102924d9a0034bbca9c5025bb63504123b05e97bc11c9d99283feca6122ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "88d8325bb9d0f9e459fd6c4f1ebbc5a637584059ba14fa7cbb5d302fde70bd2b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "17df65ea67d01c580296003d7b31db1deeed0d187304f086ce354f2921f3192b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "94d4badca141e94102b726d6cbb2941e4ec86a28fc30825885229e3d2bfcd009", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "1efb959c34a9f410a0365f777cad3b62b749b5171b6d3a3b96432d42626821f3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "49cf221bcff8834c2789ce32acb4d8380bdbb4eb31d87dd72e7bb89552e81f81", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "114557a33d86a59bd4c52b580f308e554e8569e7ef747a9a1931e51ec61243a2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "77dff1bc875bda37d5d293adb6a3b36cdc27f0b1820879ab6d420fc04fb1c55c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "374d4c66cd3c5a7c3de651b1560411d947b2658d29070891818389ba6d250968", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "b19bd77254ea31f733e40bd9b983a78e53d9321f9536fd7bb92e1acf101958c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "12d32682779a825d200f80b77e8c0ac0f89db9d336a0c4d7fd3d808053b9ad6c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "ad11bccaa7deed258ce97de09b2c256889767758f62a5e139361e146300b4ebd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "f8d119f3339a733eb0f71f5aec1f9c91d1eddca8ac22114849db3b3185818d2d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "9255c7cf6571dc1e971f474a35c2610d0bcb2fc87805385cd5f4e1ac7eea2f69", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "48fc9f610235890606afdf6ca0e0c7f6d39058b534f636dcd7cd11bd01baf8c4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "12ab0a2f28d4d897ec9aff6b80dbf73c0254449b0aac1a949caa7bf6fd131dd8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "fc8637dabff473b3c31ad2a15c4d0048efeaa74b39d0f8c719d2b0adc9060459", "target_hash": "5f218a68a57ce28451818572cf256ca602b5f2903883376467a25dc720e086af", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -48031,7 +48763,7 @@ "pl": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", "target_hash": "2c46c285df877d403b39853dcadf0251d587bc9350f746bcad28a84861eaefca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48046,7 +48778,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48061,7 +48793,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48076,7 +48808,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48091,7 +48823,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48106,7 +48838,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48121,7 +48853,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48136,7 +48868,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48151,7 +48883,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48166,7 +48898,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48181,7 +48913,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48196,7 +48928,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48211,7 +48943,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48226,7 +48958,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48241,7 +48973,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48256,7 +48988,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48271,7 +49003,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48286,7 +49018,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48301,7 +49033,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48316,7 +49048,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48331,7 +49063,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48346,7 +49078,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48361,7 +49093,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48376,7 +49108,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48391,7 +49123,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48406,7 +49138,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48421,7 +49153,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48436,7 +49168,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48451,7 +49183,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48466,7 +49198,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48481,7 +49213,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48496,7 +49228,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48511,7 +49243,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48526,7 +49258,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48541,7 +49273,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48556,7 +49288,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48571,7 +49303,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48586,7 +49318,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48601,7 +49333,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48616,7 +49348,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48631,7 +49363,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48646,7 +49378,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48661,7 +49393,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48676,7 +49408,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48691,7 +49423,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48706,7 +49438,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48721,7 +49453,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48736,7 +49468,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48751,7 +49483,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48766,7 +49498,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48781,7 +49513,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48796,7 +49528,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48811,7 +49543,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48826,7 +49558,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48841,7 +49573,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48856,7 +49588,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48871,7 +49603,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48886,7 +49618,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48901,7 +49633,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48916,7 +49648,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48931,7 +49663,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48946,7 +49678,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48961,7 +49693,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48976,7 +49708,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -48991,7 +49723,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ab8c80915c28d29dc3984d7d8d4ff383074cef646562f0f83b03ea46f7d5dc87", @@ -49006,7 +49738,7 @@ "c1bb92f207fb", "0b75b76b8da0" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -49016,7 +49748,7 @@ "pl": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", "target_hash": "8049e42b2bf98e6234b6f554bace424bc563c0bee8ed274df05ca67931388ec4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49034,7 +49766,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49052,7 +49784,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49070,7 +49802,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49088,7 +49820,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49106,7 +49838,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49124,7 +49856,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49142,7 +49874,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49160,7 +49892,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49178,7 +49910,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49196,7 +49928,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49214,7 +49946,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49232,7 +49964,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49250,7 +49982,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49268,7 +50000,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49286,7 +50018,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49304,7 +50036,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49322,7 +50054,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49340,7 +50072,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49358,7 +50090,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49376,7 +50108,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49394,7 +50126,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49412,7 +50144,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49430,7 +50162,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49448,7 +50180,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49466,7 +50198,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49484,7 +50216,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49502,7 +50234,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49520,7 +50252,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49538,7 +50270,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49556,7 +50288,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49574,7 +50306,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49592,7 +50324,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49610,7 +50342,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49628,7 +50360,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49646,7 +50378,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49664,7 +50396,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49682,7 +50414,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49700,7 +50432,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49718,7 +50450,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49736,7 +50468,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49754,7 +50486,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49772,7 +50504,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49790,7 +50522,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49808,7 +50540,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49826,7 +50558,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49844,7 +50576,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49862,7 +50594,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49880,7 +50612,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49898,7 +50630,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49916,7 +50648,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49934,7 +50666,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49952,7 +50684,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49970,7 +50702,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -49988,7 +50720,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50006,7 +50738,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50024,7 +50756,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50042,7 +50774,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50060,7 +50792,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50078,7 +50810,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50096,7 +50828,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50114,7 +50846,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50132,7 +50864,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50150,7 +50882,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50168,7 +50900,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "54d8f4d4829910ffbffe2a3606ca290e0009aa7fbd2df3ebc40dacbf7ad66c2f", @@ -50186,7 +50918,7 @@ "f6f09ffc8ecd", "dab7444d3863" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -50196,7 +50928,7 @@ "pl": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", "target_hash": "c7f32ca9455aaed5972948a18892e466c111b20a910b1601c680abd6f7d0d003", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50211,7 +50943,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50226,7 +50958,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50241,7 +50973,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50256,7 +50988,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50271,7 +51003,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50286,7 +51018,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50301,7 +51033,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50316,7 +51048,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50331,7 +51063,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50346,7 +51078,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50361,7 +51093,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50376,7 +51108,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50391,7 +51123,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50406,7 +51138,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50421,7 +51153,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50436,7 +51168,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50451,7 +51183,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50466,7 +51198,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50481,7 +51213,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50496,7 +51228,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50511,7 +51243,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50526,7 +51258,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50541,7 +51273,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50556,7 +51288,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50571,7 +51303,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50586,7 +51318,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50601,7 +51333,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50616,7 +51348,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50631,7 +51363,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50646,7 +51378,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50661,7 +51393,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50676,7 +51408,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50691,7 +51423,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50706,7 +51438,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50721,7 +51453,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50736,7 +51468,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50751,7 +51483,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50766,7 +51498,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50781,7 +51513,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50796,7 +51528,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50811,7 +51543,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50826,7 +51558,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50841,7 +51573,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50856,7 +51588,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50871,7 +51603,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50886,7 +51618,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50901,7 +51633,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50916,7 +51648,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50931,7 +51663,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50946,7 +51678,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50961,7 +51693,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50976,7 +51708,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -50991,7 +51723,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51006,7 +51738,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51021,7 +51753,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51036,7 +51768,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51051,7 +51783,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51066,7 +51798,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51081,7 +51813,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51096,7 +51828,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51111,7 +51843,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51126,7 +51858,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51141,7 +51873,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51156,7 +51888,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "30acec62f3d5c0a44fed23e0d011ee8953182ac8f28811a0aae4eccd993efe3f", @@ -51171,7 +51903,7 @@ "a97a5de28b90", "2202cae42ea4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -51199,7 +51931,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51222,7 +51954,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51245,7 +51977,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51268,7 +52000,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51291,7 +52023,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51314,7 +52046,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51337,7 +52069,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51360,7 +52092,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51383,7 +52115,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51406,7 +52138,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51429,7 +52161,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51452,7 +52184,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51475,7 +52207,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51498,7 +52230,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51521,7 +52253,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51544,7 +52276,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51567,7 +52299,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51590,7 +52322,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51613,7 +52345,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51636,7 +52368,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51659,7 +52391,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51682,7 +52414,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51705,7 +52437,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51728,7 +52460,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51751,7 +52483,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51774,7 +52506,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51797,7 +52529,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51820,7 +52552,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51843,7 +52575,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51866,7 +52598,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51889,7 +52621,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51912,7 +52644,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51935,7 +52667,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51958,7 +52690,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -51981,7 +52713,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52004,7 +52736,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52027,7 +52759,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52050,7 +52782,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52073,7 +52805,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52096,7 +52828,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52119,7 +52851,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52142,7 +52874,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52165,7 +52897,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52188,7 +52920,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52211,7 +52943,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52234,7 +52966,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52257,7 +52989,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52280,7 +53012,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52303,7 +53035,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52326,7 +53058,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52349,7 +53081,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52372,7 +53104,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52395,7 +53127,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52418,7 +53150,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52441,7 +53173,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52464,7 +53196,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52487,7 +53219,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52510,7 +53242,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52533,7 +53265,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52556,7 +53288,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52579,7 +53311,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52602,7 +53334,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52625,7 +53357,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52648,7 +53380,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52671,7 +53403,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "c2b293bf2def1b9e429e78d4aa908f1bd76b35e1985eb117ab930f4e0cbd1067", @@ -52694,7 +53426,7 @@ "3a657a6baaff", "3e44493d657d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -52717,7 +53449,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52735,7 +53467,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52753,7 +53485,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52771,7 +53503,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52789,7 +53521,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52807,7 +53539,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52825,7 +53557,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52843,7 +53575,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52861,7 +53593,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52879,7 +53611,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52897,7 +53629,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52915,7 +53647,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52933,7 +53665,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52951,7 +53683,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52969,7 +53701,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -52987,7 +53719,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53005,7 +53737,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53023,7 +53755,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53041,7 +53773,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53059,7 +53791,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53077,7 +53809,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53095,7 +53827,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53113,7 +53845,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53131,7 +53863,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53149,7 +53881,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53167,7 +53899,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53185,7 +53917,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53203,7 +53935,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53221,7 +53953,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53239,7 +53971,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53257,7 +53989,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53275,7 +54007,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53293,7 +54025,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53311,7 +54043,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53329,7 +54061,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53347,7 +54079,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53365,7 +54097,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53383,7 +54115,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53401,7 +54133,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53419,7 +54151,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53437,7 +54169,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53455,7 +54187,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53473,7 +54205,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53491,7 +54223,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53509,7 +54241,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53527,7 +54259,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53545,7 +54277,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53563,7 +54295,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53581,7 +54313,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53599,7 +54331,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53617,7 +54349,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53635,7 +54367,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53653,7 +54385,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53671,7 +54403,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53689,7 +54421,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53707,7 +54439,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53725,7 +54457,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53743,7 +54475,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53761,7 +54493,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53779,7 +54511,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53797,7 +54529,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53815,7 +54547,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53833,7 +54565,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53851,7 +54583,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53869,7 +54601,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4d7d18abb0225f17e6a844dbac1b7759b56d714210f79b7ce28da3f544adbd19", @@ -53887,7 +54619,7 @@ "909faa98ca90", "1a5b8b2bb7a8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -53897,7 +54629,7 @@ "pl": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", "target_hash": "e75fbd54811dba15872799e8e916e16928902da70bc5574ee733b8c874c3fb9c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -53920,7 +54652,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -53943,7 +54675,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -53966,7 +54698,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -53989,7 +54721,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54012,7 +54744,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54035,7 +54767,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54058,7 +54790,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54081,7 +54813,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54104,7 +54836,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54127,7 +54859,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54150,7 +54882,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54173,7 +54905,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54196,7 +54928,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54219,7 +54951,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54242,7 +54974,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54265,7 +54997,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54288,7 +55020,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54311,7 +55043,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54334,7 +55066,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54357,7 +55089,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54380,7 +55112,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54403,7 +55135,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54426,7 +55158,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54449,7 +55181,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54472,7 +55204,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54495,7 +55227,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54518,7 +55250,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54541,7 +55273,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54564,7 +55296,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54587,7 +55319,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54610,7 +55342,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54633,7 +55365,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54656,7 +55388,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54679,7 +55411,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54702,7 +55434,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54725,7 +55457,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54748,7 +55480,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54771,7 +55503,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54794,7 +55526,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54817,7 +55549,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54840,7 +55572,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54863,7 +55595,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54886,7 +55618,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54909,7 +55641,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54932,7 +55664,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54955,7 +55687,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -54978,7 +55710,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55001,7 +55733,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55024,7 +55756,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55047,7 +55779,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55070,7 +55802,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55093,7 +55825,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55116,7 +55848,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55139,7 +55871,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55162,7 +55894,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55185,7 +55917,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55208,7 +55940,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55231,7 +55963,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55254,7 +55986,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55277,7 +56009,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55300,7 +56032,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55323,7 +56055,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55346,7 +56078,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55369,7 +56101,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "28a01227b43d4bd03a30354fced80cb04806e95fda984df28afbdd98d841f018", @@ -55392,7 +56124,7 @@ "7a1a198d2f76", "f547e8224895" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -55413,7 +56145,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55429,7 +56161,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55445,7 +56177,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55461,7 +56193,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55477,7 +56209,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55493,7 +56225,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55509,7 +56241,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55525,7 +56257,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55541,7 +56273,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55557,7 +56289,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55573,7 +56305,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55589,7 +56321,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55605,7 +56337,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55621,7 +56353,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55637,7 +56369,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55653,7 +56385,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55669,7 +56401,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55685,7 +56417,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55701,7 +56433,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55717,7 +56449,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55733,7 +56465,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55749,7 +56481,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55765,7 +56497,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55781,7 +56513,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55797,7 +56529,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55813,7 +56545,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55829,7 +56561,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55845,7 +56577,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55861,7 +56593,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55877,7 +56609,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55893,7 +56625,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55909,7 +56641,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55925,7 +56657,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55941,7 +56673,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55957,7 +56689,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55973,7 +56705,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -55989,7 +56721,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56005,7 +56737,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56021,7 +56753,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56037,7 +56769,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56053,7 +56785,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56069,7 +56801,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56085,7 +56817,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56101,7 +56833,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56117,7 +56849,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56133,7 +56865,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56149,7 +56881,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56165,7 +56897,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56181,7 +56913,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56197,7 +56929,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56213,7 +56945,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56229,7 +56961,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56245,7 +56977,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56261,7 +56993,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56277,7 +57009,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56293,7 +57025,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56309,7 +57041,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56325,7 +57057,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56341,7 +57073,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56357,7 +57089,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56373,7 +57105,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56389,7 +57121,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56405,7 +57137,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56421,7 +57153,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56437,7 +57169,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "62779038dd1b2c49fbf21e7ac0a3aaf7f730bec129d271d56fb9c5b31f6df4a0", @@ -56453,7 +57185,7 @@ "ad2eadc559af", "a84c9ef97872" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -56476,7 +57208,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56494,7 +57226,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56512,7 +57244,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56530,7 +57262,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56548,7 +57280,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56566,7 +57298,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56584,7 +57316,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56602,7 +57334,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56620,7 +57352,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56638,7 +57370,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56656,7 +57388,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56674,7 +57406,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56692,7 +57424,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56710,7 +57442,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56728,7 +57460,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56746,7 +57478,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56764,7 +57496,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56782,7 +57514,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56800,7 +57532,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56818,7 +57550,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56836,7 +57568,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56854,7 +57586,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56872,7 +57604,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56890,7 +57622,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56908,7 +57640,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56926,7 +57658,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56944,7 +57676,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56962,7 +57694,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56980,7 +57712,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -56998,7 +57730,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57016,7 +57748,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57034,7 +57766,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57052,7 +57784,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57070,7 +57802,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57088,7 +57820,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57106,7 +57838,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57124,7 +57856,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57142,7 +57874,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57160,7 +57892,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57178,7 +57910,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57196,7 +57928,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57214,7 +57946,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57232,7 +57964,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57250,7 +57982,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57268,7 +58000,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57286,7 +58018,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57304,7 +58036,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57322,7 +58054,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57340,7 +58072,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57358,7 +58090,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57376,7 +58108,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57394,7 +58126,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57412,7 +58144,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57430,7 +58162,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57448,7 +58180,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57466,7 +58198,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57484,7 +58216,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57502,7 +58234,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57520,7 +58252,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57538,7 +58270,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57556,7 +58288,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57574,7 +58306,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57592,7 +58324,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57610,7 +58342,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57628,7 +58360,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "20ebdc7341ead4a9a33efc0e2a00210cdd3bc617382595c703292425ef1ce3fc", @@ -57646,7 +58378,7 @@ "2850c6c2b018", "7466a8efcac6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -57669,7 +58401,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57687,7 +58419,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57705,7 +58437,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57723,7 +58455,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57741,7 +58473,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57759,7 +58491,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57777,7 +58509,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57795,7 +58527,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57813,7 +58545,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57831,7 +58563,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57849,7 +58581,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57867,7 +58599,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57885,7 +58617,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57903,7 +58635,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57921,7 +58653,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57939,7 +58671,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57957,7 +58689,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57975,7 +58707,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -57993,7 +58725,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58011,7 +58743,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58029,7 +58761,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58047,7 +58779,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58065,7 +58797,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58083,7 +58815,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58101,7 +58833,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58119,7 +58851,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58137,7 +58869,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58155,7 +58887,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58173,7 +58905,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58191,7 +58923,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58209,7 +58941,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58227,7 +58959,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58245,7 +58977,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58263,7 +58995,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58281,7 +59013,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58299,7 +59031,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58317,7 +59049,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58335,7 +59067,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58353,7 +59085,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58371,7 +59103,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58389,7 +59121,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58407,7 +59139,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58425,7 +59157,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58443,7 +59175,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58461,7 +59193,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58479,7 +59211,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58497,7 +59229,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58515,7 +59247,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58533,7 +59265,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58551,7 +59283,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58569,7 +59301,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58587,7 +59319,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58605,7 +59337,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58623,7 +59355,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58641,7 +59373,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58659,7 +59391,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58677,7 +59409,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58695,7 +59427,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58713,7 +59445,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58731,7 +59463,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58749,7 +59481,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58767,7 +59499,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58785,7 +59517,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58803,7 +59535,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58821,7 +59553,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "113d282921cf4bb189d7d444727e0a752aedd39c9574cd7cd48cffe4b1563296", @@ -58839,7 +59571,7 @@ "a3d8d77bacf5", "6b98b1d33d63" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -58861,7 +59593,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58878,7 +59610,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58895,7 +59627,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58912,7 +59644,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58929,7 +59661,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58946,7 +59678,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58963,7 +59695,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58980,7 +59712,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -58997,7 +59729,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59014,7 +59746,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59031,7 +59763,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59048,7 +59780,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59065,7 +59797,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59082,7 +59814,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59099,7 +59831,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59116,7 +59848,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59133,7 +59865,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59150,7 +59882,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59167,7 +59899,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59184,7 +59916,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59201,7 +59933,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59218,7 +59950,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59235,7 +59967,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59252,7 +59984,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59269,7 +60001,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59286,7 +60018,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59303,7 +60035,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59320,7 +60052,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59337,7 +60069,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59354,7 +60086,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59371,7 +60103,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59388,7 +60120,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59405,7 +60137,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59422,7 +60154,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59439,7 +60171,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59456,7 +60188,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59473,7 +60205,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59490,7 +60222,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59507,7 +60239,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59524,7 +60256,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59541,7 +60273,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59558,7 +60290,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59575,7 +60307,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59592,7 +60324,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59609,7 +60341,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59626,7 +60358,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59643,7 +60375,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59660,7 +60392,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59677,7 +60409,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59694,7 +60426,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59711,7 +60443,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59728,7 +60460,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59745,7 +60477,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59762,7 +60494,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59779,7 +60511,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59796,7 +60528,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59813,7 +60545,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59830,7 +60562,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59847,7 +60579,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59864,7 +60596,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59881,7 +60613,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59898,7 +60630,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59915,7 +60647,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59932,7 +60664,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59949,7 +60681,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "f60be16d7b8a96d812a8286b0547323d57585c1dd8666ffd922dc3da967e7ca0", @@ -59966,7 +60698,7 @@ "485d9591da7f", "e1a7bb007ec2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -59989,7 +60721,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60007,7 +60739,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60025,7 +60757,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60043,7 +60775,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60061,7 +60793,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60079,7 +60811,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60097,7 +60829,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60115,7 +60847,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60133,7 +60865,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60151,7 +60883,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60169,7 +60901,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60187,7 +60919,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60205,7 +60937,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60223,7 +60955,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60241,7 +60973,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60259,7 +60991,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60277,7 +61009,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60295,7 +61027,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60313,7 +61045,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60331,7 +61063,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60349,7 +61081,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60367,7 +61099,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60385,7 +61117,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60403,7 +61135,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60421,7 +61153,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60439,7 +61171,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60457,7 +61189,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60475,7 +61207,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60493,7 +61225,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60511,7 +61243,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60529,7 +61261,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60547,7 +61279,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60565,7 +61297,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60583,7 +61315,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60601,7 +61333,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60619,7 +61351,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60637,7 +61369,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60655,7 +61387,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60673,7 +61405,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60691,7 +61423,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60709,7 +61441,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60727,7 +61459,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60745,7 +61477,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60763,7 +61495,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60781,7 +61513,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60799,7 +61531,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60817,7 +61549,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60835,7 +61567,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60853,7 +61585,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60871,7 +61603,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60889,7 +61621,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60907,7 +61639,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60925,7 +61657,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60943,7 +61675,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60961,7 +61693,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60979,7 +61711,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -60997,7 +61729,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61015,7 +61747,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61033,7 +61765,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61051,7 +61783,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61069,7 +61801,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61087,7 +61819,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61105,7 +61837,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61123,7 +61855,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61141,7 +61873,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "df59bd25a1c05b789bb269b9fc273ea3a183431eadd72b13f051df617fdd7a02", @@ -61159,7 +61891,7 @@ "caac010b6088", "1247a72b9a47" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -61180,7 +61912,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61196,7 +61928,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61212,7 +61944,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61228,7 +61960,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61244,7 +61976,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61260,7 +61992,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61276,7 +62008,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61292,7 +62024,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61308,7 +62040,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61324,7 +62056,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61340,7 +62072,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61356,7 +62088,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61372,7 +62104,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61388,7 +62120,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61404,7 +62136,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61420,7 +62152,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61436,7 +62168,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61452,7 +62184,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61468,7 +62200,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61484,7 +62216,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61500,7 +62232,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61516,7 +62248,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61532,7 +62264,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61548,7 +62280,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61564,7 +62296,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61580,7 +62312,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61596,7 +62328,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61612,7 +62344,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61628,7 +62360,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61644,7 +62376,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61660,7 +62392,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61676,7 +62408,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61692,7 +62424,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61708,7 +62440,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61724,7 +62456,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61740,7 +62472,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61756,7 +62488,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61772,7 +62504,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61788,7 +62520,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61804,7 +62536,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61820,7 +62552,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61836,7 +62568,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61852,7 +62584,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61868,7 +62600,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61884,7 +62616,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61900,7 +62632,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61916,7 +62648,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61932,7 +62664,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61948,7 +62680,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61964,7 +62696,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61980,7 +62712,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -61996,7 +62728,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62012,7 +62744,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62028,7 +62760,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62044,7 +62776,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62060,7 +62792,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62076,7 +62808,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62092,7 +62824,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62108,7 +62840,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62124,7 +62856,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62140,7 +62872,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62156,7 +62888,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62172,7 +62904,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62188,7 +62920,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62204,7 +62936,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ee65b3f0ec8185f56eb4a73c32d4fd54330ae340430fdb7783790c73b8937492", @@ -62220,7 +62952,7 @@ "477a489925d4", "21bab737a900" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -62241,7 +62973,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62257,7 +62989,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62273,7 +63005,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62289,7 +63021,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62305,7 +63037,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62321,7 +63053,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62337,7 +63069,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62353,7 +63085,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62369,7 +63101,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62385,7 +63117,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62401,7 +63133,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62417,7 +63149,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62433,7 +63165,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62449,7 +63181,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62465,7 +63197,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62481,7 +63213,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62497,7 +63229,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62513,7 +63245,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62529,7 +63261,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62545,7 +63277,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62561,7 +63293,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62577,7 +63309,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62593,7 +63325,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62609,7 +63341,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62625,7 +63357,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62641,7 +63373,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62657,7 +63389,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62673,7 +63405,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62689,7 +63421,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62705,7 +63437,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62721,7 +63453,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62737,7 +63469,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62753,7 +63485,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62769,7 +63501,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62785,7 +63517,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62801,7 +63533,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62817,7 +63549,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62833,7 +63565,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62849,7 +63581,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62865,7 +63597,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62881,7 +63613,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62897,7 +63629,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62913,7 +63645,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62929,7 +63661,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62945,7 +63677,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62961,7 +63693,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62977,7 +63709,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -62993,7 +63725,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63009,7 +63741,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63025,7 +63757,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63041,7 +63773,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63057,7 +63789,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63073,7 +63805,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63089,7 +63821,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63105,7 +63837,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63121,7 +63853,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63137,7 +63869,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63153,7 +63885,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63169,7 +63901,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63185,7 +63917,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63201,7 +63933,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63217,7 +63949,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63233,7 +63965,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63249,7 +63981,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63265,7 +63997,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "a8345a135d8724a4f938bb19cb2bd4385a5f78744bda09b2819f0b4b640621b9", @@ -63281,7 +64013,7 @@ "e19283a03c34", "b25789910d2d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -63301,7 +64033,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63316,7 +64048,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63331,7 +64063,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63346,7 +64078,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63361,7 +64093,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63376,7 +64108,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63391,7 +64123,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63406,7 +64138,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63421,7 +64153,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63436,7 +64168,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63451,7 +64183,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63466,7 +64198,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63481,7 +64213,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63496,7 +64228,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63511,7 +64243,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63526,7 +64258,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63541,7 +64273,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63556,7 +64288,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63571,7 +64303,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63586,7 +64318,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63601,7 +64333,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63616,7 +64348,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63631,7 +64363,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63646,7 +64378,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63661,7 +64393,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63676,7 +64408,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63691,7 +64423,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63706,7 +64438,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63721,7 +64453,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63736,7 +64468,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63751,7 +64483,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63766,7 +64498,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63781,7 +64513,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63796,7 +64528,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63811,7 +64543,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63826,7 +64558,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63841,7 +64573,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63856,7 +64588,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63871,7 +64603,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63886,7 +64618,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63901,7 +64633,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63916,7 +64648,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63931,7 +64663,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63946,7 +64678,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63961,7 +64693,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63976,7 +64708,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -63991,7 +64723,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64006,7 +64738,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64021,7 +64753,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64036,7 +64768,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64051,7 +64783,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64066,7 +64798,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64081,7 +64813,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64096,7 +64828,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64111,7 +64843,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64126,7 +64858,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64141,7 +64873,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64156,7 +64888,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64171,7 +64903,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64186,7 +64918,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64201,7 +64933,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64216,7 +64948,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64231,7 +64963,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64246,7 +64978,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64261,7 +64993,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4fa3fcefc35c56293d0170cb92fea1bb55fda1cf41eab1b0ee7a26ced6bd96a4", @@ -64276,7 +65008,7 @@ "c63e35271c39", "e7a8683b963f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -64286,332 +65018,332 @@ "ar": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "32f8fc922814e38457ea11a10b9ece1040ac8c81cba2f67ca313eb4e46fdbbad", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "1cb97f9f40dd82a6953139f5b8224749899150c0796457c45832fd4d048a7254", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "532d31d27cae9d37c245b2eb945f9191217ede499303d641a9b39bfee83dea30", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "dd08d9695223dde4e6cc1ce13b087f95cb49b3edf4ba6873dfe80689351ef25e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "b5852898384c19298d4653346fe7df7ab4f471540210e5aa96751db01b37a6de", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "d7d9534e94cd9dbd9df2e03e2cd86cea962da6a72cec1c5825ee7bde2a3c2915", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "5183be4c9581b87e0096f31a929b001768d315a2499e3acd6ec934a4d95e4b42", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "f8f61c38797381ff66e0b0b347500dd8844db4d3b3422fd15d85c359f7f63b6f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "7ed1e3a35887edf4301b1746cb505930a2e1311de3e01c0ae042b551e54a8cd6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "3cdea451eaecd26840cb41b4ad5775ea5f09100212f424f32943e5aed7b27ea0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "f4eb9ae1558673254a8f0095bc2e39f338017fb158a05cca9140a591b57620f1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "313ab7e9192b9d253bfb8fd3a6cb33c393879f094aec69ba70fb0b26ac56823f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "e8d25bc9c002cc049a2bbb31607827f7c780ce21d306eeb9278f8d231b34d700", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ba072bad82d6fab9792ec75b4c9ac151964c16c72dd98db356a716e95496856b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "07b3c697283553665e04db124602285ff824ca78aa82f0f12901d3764a677d24", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "0779fd004ab02e40afaf96e24de490b46af1318e65b9a5b8faab84ae679894db", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "15c4ce20ad99ce197587c97846045ce263b693db99df4ee3b72913f6dd3135b0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "21b0cd0936dc50bf5627d14cc31e8c2131916365551c699deb2547982369c74f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ae908e5e7b8f6671621a0229626c30b95cf97d9b3657a3b9503553051a365d1e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "fef6f2cfa20abca815f1d36ef7917f7db6b3e9616060cd17bece5bc84e82e768", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "b73c7c69e51d3ac92b24a25cb895b94479bd5eb1a4c6e16bcebda5b866ec2317", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "0d3ff9c1e627a58e537dd435d7e9f6b2452eae1f59b01491726e22eb4846c15c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "bd9fa93288665ceca026f246b4c133ae46a87d8773aa4994cad255428b939e4f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "2de45b75312c07fad8a5f8c6f9e8468fd70d6d6dc5672a9563a2e44a237ebf5b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "d1ab0124d6e8c242521850a353fb5eee8aed20af592cde0f9ca2593ac73dfe84", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "456513b94ff9864b1aa94911e92ead3dfc736ecde1b59c2fbd66e84fefd77edf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "255fb83edf4de6a5dd32880946a54eff4f453cee372549550d40fb5371b5b7a3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "b988eae414240fc0e47f83e9a6833985a0434a90edbd5967ac4b27d1384e93aa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "dc0cef1120df2871ca93b6f8431c0dbc30339e1e6d380710edff4cd9040e06cb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "f486349147ae2f5e572482ccfc9e2413bc52763a7b99ddb665639bf31ffff61b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ceabd13b8b097d6091baaf239c0073c58e06c06de39879cc200c43958f94ed33", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "4707e74b1f55da4c54be1004bc6981e3695fcc30b518e46756ef320cc242d93f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "5a8b5d9944f966a06662af81d32cd323e83ccec3ba25a0431347bcceeffda145", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "0e40f34d65ad225a5316925c711eb8250f5c7e4dc5cad03c89c00125d3cbb5fa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ff4b3a54f5b345d8c3927b50441ba20166c304681a1b1644d7a9c7339f8e1d39", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "21fbbbe73ff0a7a9d414daf9e49e2e8a8b5113d33db203c608bf783108df891f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "b2473d7e18260cd9086fc8ef4b102ddf5d8e9e0171f4a62340a37800b2661355", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "0d34d4b637bb7eaae29e803acd1658beb408ce83dc85c41e0d290891b17cf4c4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "71b8076e9697c0ad4b68c235bf7fc1d44ba1160b99111d63c809d738dbff8bfd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "8ccd7413b26f8e61b508f107625208abdf84803676c204e891f184709addcc06", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ce28fd94564d6f86270d849342f343a0692966718b3083e00b86c5e480c8ced0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "5c5ab0d3655c365fe44b2f2b3dfca1a20bb1382ac22c84d261f23bd48df3c270", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "97ee5d75496eb3e0952c28f6db57c0b6f0ef80afeb1e8a082cdca9f68bed2b27", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ccc9fd07141b98b47637305bf925bf4694a0174999d7466142fad8855faac316", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "6fa413ed4ca63e1ed5b5aa7b0cbcdf4493eda17e818d8e8065bf591cc26263df", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "03cdff953a64b67faf849392548a30bfa63e1f2a2f8194166e096e2c2d816bb5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "30ee2def9a8738f4bed08eea71291272cdd5b3898c86c75b0bea43575d7e8735", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "9e0ed06a7a44f5ac14c4861fda1babc05ce65bff17ec598393ac189ddfaa80ab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "210bda2d62703a02872544b8772822df882d950873e8be79d2f97b08d0e19285", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "b6545cee6a45b5f6ced5da88429ba54fa60260c4a9b3e44f04b24d526aa49130", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "e063751829a3a3f254acab25fe2ba2f4ea1b22c93611c260c9f258913cf52695", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "eeb973dc4a51fa0de0f152d2bf1214f6c68984d2cdbc6f9002019270319df22c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "49f0decb71eef83321d931966e6fcab7c3d07c2d00ae2a5ce5142bded698e3f3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "c60239550a9b1702d1169cea12deb30ec20c500c7a89078eef408220b6e4ffab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ded833cccfdb64ca2fa31899785ff93028e7302a45155f17ae351d7894089199", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "d9d682260c068af7164e7f11a4b2ff33fddcab73255a72166d62245a184a31e7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "49a24f0bb68fb1680074781d6ed087196cc653dd481aa2b1521abbd47551eb25", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "d2339b55630ba16f0941d8a462a4fb009bd7246fe69ebead9a78131f9fb6c678", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "3c790dfc9e202447c448f14ebd98463627d59eed41f7d72dc812a7c50faf8106", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "295a8a25fe7bdb39b5d3a7396327bf2fcba2830b8bbdc18557e1ee8afcd71bc8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "bad633aff7efe8193339cd07e543f2b902b46360d6a9359c3a0b964b0f4d9dce", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "ec4cb6e05e93cc4259aa9d576a5d9945799fdd12648b696278f16379918739d0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "7217c5a547be7ffe7ecebb13c11328c8348567004c3e4892007cdbee486f8e32", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "778172bdab38264210bc60ed39cb93ed2558c4d6983e8c7d34f70d2c4dd9639c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "273f40ecc53b1a78fae0537205421303d2e7c8d390a50b769fede38d148a5c5e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "8be81dfbcc2ff275a31647510f9ff12f1bd9601e3f4cb5bd28dc774f0c4af7d6", "target_hash": "d465bf484b6c39f791a1707a26a9b2c682db732019257904714a555f88bebfab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -64621,7 +65353,7 @@ "pl": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", "target_hash": "f74941eb955fc05408956bd848a56064e86bf562f1942eac58aa8a9e03819f42", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64637,7 +65369,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64653,7 +65385,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64669,7 +65401,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64685,7 +65417,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64701,7 +65433,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64717,7 +65449,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64733,7 +65465,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64749,7 +65481,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64765,7 +65497,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64781,7 +65513,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64797,7 +65529,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64813,7 +65545,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64829,7 +65561,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64845,7 +65577,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64861,7 +65593,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64877,7 +65609,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64893,7 +65625,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64909,7 +65641,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64925,7 +65657,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64941,7 +65673,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64957,7 +65689,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64973,7 +65705,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -64989,7 +65721,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65005,7 +65737,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65021,7 +65753,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65037,7 +65769,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65053,7 +65785,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65069,7 +65801,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65085,7 +65817,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65101,7 +65833,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65117,7 +65849,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65133,7 +65865,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65149,7 +65881,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65165,7 +65897,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65181,7 +65913,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65197,7 +65929,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65213,7 +65945,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65229,7 +65961,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65245,7 +65977,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65261,7 +65993,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65277,7 +66009,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65293,7 +66025,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65309,7 +66041,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65325,7 +66057,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65341,7 +66073,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65357,7 +66089,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65373,7 +66105,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65389,7 +66121,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65405,7 +66137,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65421,7 +66153,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65437,7 +66169,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65453,7 +66185,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65469,7 +66201,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65485,7 +66217,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65501,7 +66233,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65517,7 +66249,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65533,7 +66265,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65549,7 +66281,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65565,7 +66297,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65581,7 +66313,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65597,7 +66329,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65613,7 +66345,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65629,7 +66361,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65645,7 +66377,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "690bbb6faba1429b3df3066f0e42414a9d17ceb4024a2d41d2dd07795b162fd7", @@ -65661,7 +66393,7 @@ "37ffd5b69c91", "81a75836d3b1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -65683,7 +66415,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65700,7 +66432,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65717,7 +66449,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65734,7 +66466,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65751,7 +66483,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65768,7 +66500,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65785,7 +66517,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65802,7 +66534,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65819,7 +66551,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65836,7 +66568,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65853,7 +66585,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65870,7 +66602,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65887,7 +66619,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65904,7 +66636,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65921,7 +66653,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65938,7 +66670,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65955,7 +66687,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65972,7 +66704,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -65989,7 +66721,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66006,7 +66738,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66023,7 +66755,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66040,7 +66772,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66057,7 +66789,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66074,7 +66806,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66091,7 +66823,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66108,7 +66840,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66125,7 +66857,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66142,7 +66874,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66159,7 +66891,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66176,7 +66908,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66193,7 +66925,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66210,7 +66942,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66227,7 +66959,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66244,7 +66976,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66261,7 +66993,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66278,7 +67010,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66295,7 +67027,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66312,7 +67044,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66329,7 +67061,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66346,7 +67078,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66363,7 +67095,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66380,7 +67112,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66397,7 +67129,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66414,7 +67146,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66431,7 +67163,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66448,7 +67180,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66465,7 +67197,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66482,7 +67214,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66499,7 +67231,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66516,7 +67248,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66533,7 +67265,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66550,7 +67282,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66567,7 +67299,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66584,7 +67316,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66601,7 +67333,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66618,7 +67350,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66635,7 +67367,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66652,7 +67384,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66669,7 +67401,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66686,7 +67418,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66703,7 +67435,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66720,7 +67452,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66737,7 +67469,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66754,7 +67486,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66771,7 +67503,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "91d71d2f0af3a29637d28ed12b7d3e56d77d3a9603fd4aa1b050a66a7f4c1b87", @@ -66788,7 +67520,7 @@ "cea4e3637cba", "cef80c483b88" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -66806,7 +67538,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66819,7 +67551,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66832,7 +67564,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66845,7 +67577,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66858,7 +67590,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66871,7 +67603,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66884,7 +67616,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66897,7 +67629,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66910,7 +67642,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66923,7 +67655,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66936,7 +67668,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66949,7 +67681,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66962,7 +67694,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66975,7 +67707,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -66988,7 +67720,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67001,7 +67733,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67014,7 +67746,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67027,7 +67759,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67040,7 +67772,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67053,7 +67785,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67066,7 +67798,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67079,7 +67811,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67092,7 +67824,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67105,7 +67837,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67118,7 +67850,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67131,7 +67863,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67144,7 +67876,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67157,7 +67889,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67170,7 +67902,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67183,7 +67915,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67196,7 +67928,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67209,7 +67941,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67222,7 +67954,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67235,7 +67967,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67248,7 +67980,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67261,7 +67993,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67274,7 +68006,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67287,7 +68019,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67300,7 +68032,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67313,7 +68045,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67326,7 +68058,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67339,7 +68071,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67352,7 +68084,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67365,7 +68097,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67378,7 +68110,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67391,7 +68123,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67404,7 +68136,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67417,7 +68149,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67430,7 +68162,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67443,7 +68175,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67456,7 +68188,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67469,7 +68201,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67482,7 +68214,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67495,7 +68227,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67508,7 +68240,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67521,7 +68253,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67534,7 +68266,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67547,7 +68279,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67560,7 +68292,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67573,7 +68305,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67586,7 +68318,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67599,7 +68331,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67612,7 +68344,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67625,7 +68357,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67638,7 +68370,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "61b7030eadc90ca97ef26373f991ed720c3fe7d4b6a6b53884859e8b0c493de3", @@ -67651,7 +68383,7 @@ "45da7a1bfe0e", "607c54652fb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -67678,7 +68410,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67700,7 +68432,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67722,7 +68454,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67744,7 +68476,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67766,7 +68498,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67788,7 +68520,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67810,7 +68542,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67832,7 +68564,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67854,7 +68586,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67876,7 +68608,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67898,7 +68630,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67920,7 +68652,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67942,7 +68674,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67964,7 +68696,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -67986,7 +68718,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68008,7 +68740,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68030,7 +68762,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68052,7 +68784,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68074,7 +68806,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68096,7 +68828,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68118,7 +68850,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68140,7 +68872,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68162,7 +68894,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68184,7 +68916,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68206,7 +68938,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68228,7 +68960,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68250,7 +68982,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68272,7 +69004,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68294,7 +69026,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68316,7 +69048,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68338,7 +69070,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68360,7 +69092,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68382,7 +69114,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68404,7 +69136,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68426,7 +69158,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68448,7 +69180,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68470,7 +69202,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68492,7 +69224,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68514,7 +69246,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68536,7 +69268,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68558,7 +69290,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68580,7 +69312,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68602,7 +69334,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68624,7 +69356,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68646,7 +69378,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68668,7 +69400,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68690,7 +69422,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68712,7 +69444,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68734,7 +69466,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68756,7 +69488,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68778,7 +69510,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68800,7 +69532,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68822,7 +69554,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68844,7 +69576,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68866,7 +69598,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68888,7 +69620,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68910,7 +69642,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68932,7 +69664,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68954,7 +69686,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68976,7 +69708,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -68998,7 +69730,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -69020,7 +69752,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -69042,7 +69774,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -69064,7 +69796,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -69086,7 +69818,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "9023181188088b29242b3486270499fef51dc3e29e75150677e5a59536e71298", @@ -69108,7 +69840,7 @@ "cf1c62419cf7", "76103b462408" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -69118,7 +69850,7 @@ "pl": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", "target_hash": "b30bbc34a3b766bd75a9dcf601fa8d8be7f8ebcf16bf901933f23d6e48aee97c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69132,7 +69864,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69146,7 +69878,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69160,7 +69892,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69174,7 +69906,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69188,7 +69920,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69202,7 +69934,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69216,7 +69948,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69230,7 +69962,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69244,7 +69976,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69258,7 +69990,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69272,7 +70004,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69286,7 +70018,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69300,7 +70032,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69314,7 +70046,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69328,7 +70060,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69342,7 +70074,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69356,7 +70088,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69370,7 +70102,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69384,7 +70116,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69398,7 +70130,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69412,7 +70144,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69426,7 +70158,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69440,7 +70172,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69454,7 +70186,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69468,7 +70200,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69482,7 +70214,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69496,7 +70228,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69510,7 +70242,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69524,7 +70256,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69538,7 +70270,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69552,7 +70284,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69566,7 +70298,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69580,7 +70312,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69594,7 +70326,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69608,7 +70340,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69622,7 +70354,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69636,7 +70368,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69650,7 +70382,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69664,7 +70396,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69678,7 +70410,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69692,7 +70424,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69706,7 +70438,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69720,7 +70452,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69734,7 +70466,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69748,7 +70480,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69762,7 +70494,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69776,7 +70508,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69790,7 +70522,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69804,7 +70536,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69818,7 +70550,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69832,7 +70564,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69846,7 +70578,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69860,7 +70592,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69874,7 +70606,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69888,7 +70620,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69902,7 +70634,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69916,7 +70648,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69930,7 +70662,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69944,7 +70676,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69958,7 +70690,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69972,7 +70704,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -69986,7 +70718,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -70000,7 +70732,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -70014,7 +70746,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "d30f989533ba92322ee859bc5dfa4eaaa05972b24297cf7936da493f3f2f60bd", @@ -70028,7 +70760,7 @@ "c30face701df", "b619d9ca2672" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -70059,7 +70791,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70085,7 +70817,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70111,7 +70843,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70137,7 +70869,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70163,7 +70895,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70189,7 +70921,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70215,7 +70947,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70241,7 +70973,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70267,7 +70999,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70293,7 +71025,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70319,7 +71051,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70345,7 +71077,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70371,7 +71103,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70397,7 +71129,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70423,7 +71155,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70449,7 +71181,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70475,7 +71207,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70501,7 +71233,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70527,7 +71259,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70553,7 +71285,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70579,7 +71311,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70605,7 +71337,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70631,7 +71363,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70657,7 +71389,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70683,7 +71415,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70709,7 +71441,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70735,7 +71467,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70761,7 +71493,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70787,7 +71519,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70813,7 +71545,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70839,7 +71571,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70865,7 +71597,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70891,7 +71623,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70917,7 +71649,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70943,7 +71675,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70969,7 +71701,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -70995,7 +71727,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71021,7 +71753,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71047,7 +71779,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71073,7 +71805,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71099,7 +71831,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71125,7 +71857,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71151,7 +71883,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71177,7 +71909,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71203,7 +71935,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71229,7 +71961,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71255,7 +71987,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71281,7 +72013,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71307,7 +72039,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71333,7 +72065,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71359,7 +72091,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71385,7 +72117,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71411,7 +72143,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71437,7 +72169,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71463,7 +72195,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71489,7 +72221,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71515,7 +72247,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71541,7 +72273,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71567,7 +72299,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71593,7 +72325,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71619,7 +72351,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71645,7 +72377,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71671,7 +72403,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71697,7 +72429,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71723,7 +72455,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0c6aa7f2b0d941820975b8c831c5608799124a2ef44cf4435fa9b28a95cdf3d0", @@ -71749,7 +72481,7 @@ "7317b76faaaa", "c68737563e9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -71759,332 +72491,332 @@ "pl": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "407d106698a6ea864d487e9f72ba2347c7d6e1dba523897e3f49ee65966543d4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "b10ffc48d3ba53b0bb980fcb042497d7012b9cdacfd40a553fa6077ec5d90bf3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "f808178c78a8146e6acf300027ab29da42251d647a89d6516f12e5fc25e9912b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "62a46ae73d6ca97ea6d04df16124f7d7c1e06a9297b1a582326e7e27bd4ec7dd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "1aef7701f78eb1edda54823d04ad3dde0285cbb569e24cc6d228824bb78c70d8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "8442aee740ea0d92f7e9d3039d003884cdddae47588070dafa5d2d433615e861", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "042a4697e3f8e763bc6449175c34f1fada2b366bbdb2dae98b8f5c3913c84ac6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "2854d5c040724df882992adb9625e152db8ee8ac9c16134db4e9bad387a8857d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "12f7ab272a89f5df98d4dac668c8cfb84aca319fc7a14a9bb68496e3921dcf7d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "3317a66b3014a6edefaeeeff6d9b2d0fa822c14aa0430db8cb73a484d45061ef", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "bc238673f359b02a21bf26366b0a0790ec5f414aa3bc2c078a5ebd5c44c94171", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "8561ad60c5806db370cad222926ac87636b864d88dd22834cd01929ab27c7892", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "b2a6b6de7bb2fc4c1d3984ed3b4e32b10debf91050e1734e6bb44d5395922258", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "9743cdb9ae91fa9aa0648c2aa0f68e91d24d77f83c2b64f7fefef8ef2891209d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "6e6cd265a472b69a0ce71301b6bbe912f6a1e07032fdfa7eab23119f45a00ebd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "a8695e2f6ac447140bb1396f6b87db897948e9e6f1a11aea15e8c67e9a637715", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "03bfc21fac4d8fe7a9a568b70ceab86862017de63685651c6a56ac9474cca920", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "5912c3fc7c2e3e08d6ea971b255473c8cf58dc054a0d810791fbfd5d6de44ac2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "553497954d8f84bae62d9ac67c8213cf18b5752921221f0f6bd61859a95fb6bf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "e3b74ef02fad9bb66694fe28722df6bbf57e204328635bd8777bf1eb91cea6bf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "a11deb4691658a98df39c98604f0118e8096d0e45573c55a78d2646d513d31ca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "f30b5a17eda7046ad1be8669235d83921f5576cde8b57028497b3c7ed4d9a7ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "42d466934dd694db6d9dfe2215fdc53e7b2cc7d9b5869715dd859e86928c1e9a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "08bf8aa145dee37d15e1b9ba5b20e7972fd7ceb5bda6d97d3fadc185ec9db380", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "355e5a9a57331243959c2cbe74bb00593169511e23256f62ae3bc886923f4268", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "44a361c33b95bdedf91d2434c5a10970ede01c3b35912f95a77b7b95ab5ab162", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "7e2f724e72ef829909bfcc6dd018f0182a2e1e7c819cd7f9fc1557984e23d738", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "7b2534af2c10d029a39ae9628051d85ef5ec229dcdc04c4eb9f2ba8a0f7b7c85", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "7fd01b44bf388e26dd01f2020a6987aaf9055d7ca228fbd463c352a250e6acab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "81c07e440495ed390cd0be7d486a7a74e652dfffc47916655c0417affd896001", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "d717af12ba38ecaecfb334345b3720cf4699e76a1d0320457e5e066295450929", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "449e037a4124268b3bd0f50f6ac51c7dea34974453ec329a4a2df4f4fd9a67d4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "45bcbfda77d1245fce529edb6d0e43702bd0bdcec2846f10fa908b7e71928874", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "9fd82644ccf5275f9cb2265861aeabc8cb8fe1bee759a0d60640445939c4c50c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "d8c48b3e2c03e78849cb8dc9f6e2c74b7bae88418e07dbdeb61a9533dfdc91bb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "40d9e3b70a5434243d287b809bcf64c3d3df0fad78b6f76492ba3d13d93e8bb2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "021b87f89aee6f56deecde02c61401f755655b74d2bce8370ca06c85201e1cdb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "17964398d73693a15a9be0167f0fef7ff8f768fe822a6e51aa2e280ded28c293", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "c21f02ba79ee14fc4674f8969eb4f1b207e4f9c992f14de190404a7444fdae27", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "9ebc663f226f1916ebc149afb939d181099a5908565837320ce43680ffbc6700", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "7cfd2954f948992c98b369462a6bce4d5c58836fc32e4be19b4759ecef1504ac", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "a67219a572d0308ee21f3ad76383f909a29f245912ef03d4de1aedc3599a2cc0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "42bc68d191490cb25cc61a0747dad60796c84b5008fdfa77f83ab23dc2a4939b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "3af0332bb9bd52244fcaa565846f5634bdc06ef72e845aa77053ba8a21f48905", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "0c20691d317c9539b6a7bd622424f1f63ff9c31314414ad92bc314a131f74f63", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "44bc00b32f6240a29709b8f769a7d6f09947eb452802ad1b876c83c266e75505", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "d1564d1e40677eb2b3c6263b00e71d54a7c0b3d04e78ab22d633ee493246b900", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "ae7ad0f6bdc11a600d0e37fe534340b39ae27144004f984ff51c86d04c82a90d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "42ca425fe5f12b82da1eff0966842f3ef0cfdcb60a51f159cc47daa5d1a608d0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "e88bc2ac534090ed6760ea1e0a7d12a995829598442c9706281a3c8c7b8d81c7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "bd9f4481ee7c4c63ff5190fdd9285d7ac47698e920350f47b0df97487537a805", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "9ef74586c5ff7cdd5829f486d3459576b46a9a84fcccf8e472d8ee5cd10d996d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "24c29e327a60fab0e5f2ddd6572ef0df2d34791bc821a66b8f9517780caf25f2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "267c3e16408245ce5a6adbb85a9514fcce6477f311b32bdbc85ad196960b6d1b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "c73fa81c96d5ee68d87463e41799d9846e603698a42291981a35e75461ace17f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "befc44825d99b252acefc6e241615d6b57f2b42aa2d9450ade82c11f041efa75", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "f4915fe7f4f92663a81392f7d438c6a65ac759b81fd392b997463a12840be62d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "074af12d14e8adf80ea1b53d1a2b0dd66e7e788251388df0402f2f3d9489e96d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "3fa82577501cc73c2f41bb19a52b524d1c8b9c0800d8f4d806cb782d654ef5e2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "132ed36b8eeca87c876f6e6e7c6037932af723ff34c32574bdb9826fbc8ab8e6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "269a2cf4c8301c3a626a2a88d7209c76f4880a329d0e1f8aa72ac0a275b6e882", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "3eb73a3730b56260921a2b5f7bee21034d87aa195321376ec322bdbc8049e93f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "4199486726c21583817bf223d0fd75ee3acdf9bf7256fa345db978174948d15d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "5e10bbc108cc44c56d7055f57c6e2f117018fe031ac96ab3177f18bc4b435c8e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "b2a9f33c70f3ccb70cb118aa807025bda5b86d8cd8fa01a00aad56930e897eb3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4ab8b4fba5351fbcbd7bfecd99e463ccef56ca041477c402439d069acfac09a5", "target_hash": "e68d2cb171f9dea8eeb6ea8cdc80453716ec5541fe238607561305fd7fb60f09", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -72094,122 +72826,122 @@ "ar": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "df7c445b071929d402ca50ee8840204faa38e2586c40533f1629db257dd73e24", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "c57f9af5bd3d65aac3ce56b8b4b4669e8f88e8fe023ddab26c83946e07ff3311", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "fdbb0c049de4ee566ba27a9d28fc3ba6bd84144955924703e62cb37e1b589943", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "77c02c960000b7bffa0b6cffbb96bca51b4bcdca25e992f10b1095767242bcbd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "caf13952c60a566cbb46e51558d373502545d0e870d59a51d954e7d83e3405ec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "02605265853a25416278fcdd8356dd6037f44208b0846eb7b2c4ebe74e42e031", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "5b67b9b485497524428823809ff1bfc24b08f262b14170e7464fba685efad68a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "b54e5350460c9ba428ba0c2f77a8c7d9971394e97ce1834d11ac85fc7b0a3f61", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "8f4c4f33ac13cbe7152db7638e4beebde89e5efcce9f5915384ab6e39b2e70a4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "b395cf40145d1c578b2278556d427e15fd33d64d0d0b0af3a2279f85a5b3c932", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "5d82284b37d570581e6ae2bd18b77924790ba4c962854b77a4fe4e472410ab36", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "52c90e7730b04f846987afbc49f67690bf479fd1adfab65cd18755b0283b8dcc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "6e52865184b6396fed2f6a4946ab309409b6c5655b2da5339b61ea8d234f2366", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "1faf6e8c465caffab7eefa9ff71c4cebe18d9865ce9491a227a50ec999406ad8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "f53c2409c367f102f54972ee46970882f139fb0cc771b06d1906fca2a18bc6b3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "2820abb1111a4483fc87a2079583200ad1a43e029bf58f2bdef8f6c71c478cdd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "128f4982a13ce66095960a62230a972ba9d2e9a4a80f636b554921c6d045bb41", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "6aa472e14a5f851595563a1fd0ee49a53a06a0974e168237e5985f83c5aa0485", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "881ce796a3368b810c3ba1921d270aca1bc3b2832280c6754fdf2d8a3c975157", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "f02cf59806f0f3805835872aede7002945cad19315c5cf8fdb257f099632d010", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "51e5627fef91103908dc831aed671d835d55f287fb9718c7bcc01e83256e5709", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "3037c00c6e1fd9605b5d155b779d9dad3942d451875308a727fcabbf8dba649d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "c16c3539221b581fd59472be4c3f8aed726202a57408247c0dc036464f262355", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "d4d764f7100ca40d6a3e6db46467fd7252bc517edde8578df171fdb5675a400b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", @@ -72247,77 +72979,77 @@ "7c105ea32885", "3a1ce419154d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "bf8f18c912fdb9879fc711eb7637e974116c7acea478d99f239bbe22a834a376", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "be7c3ca8e5352eaccfee30835f184db793a5eab3798e3c3afca5ed4aac6dfd00", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "5120fd5ce26f78a2e42d0dc88801bfb01ed29d8ea8d8dbceb6666ec07fc90f7a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "bf3f867ee26b64a10c773e1ef016db97d332a083962f5ae55fc077e842033adf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "b1caa73b7339f1b97a0d19d0701c2fa6295f42c1b1384bf03bac263f49c7ddd8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "60d8852d1801e9f069307549a1cfca2bf426b4b99157678365b397f169c18a8d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "d6fef7b4101415a96ad1e4d73744f2dee8587c08d0d4a8696ae6e6b179638757", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "106de75bf06cbe4b92ad71d312206e02a4c28a0f3d2a7b65bb47e1fe3ece6da7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "a583130d953e0e455afc238aa7bc82813cb31775d112df563c023e9440d8be1e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "36bfb156063b103ce7f9430ecf44e1961864dd212bcad8f2db13342eea9a7580", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "8051d96ed294e5abd20eac79d6c7259636ea9bf6b3606585a6b35123138ce1cc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "2c936b9d007974cf903d3f027d34e77f0c6bd01f101bb95b791b7ff34963705a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "6759caf659f7534bb936a73afc7895e2d06fb1994f38d3358ad6d5e27c9de414", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "2491c3b562f8dd286a773393927bc2c0aac94c02dbbf09d8c81c767c70f7a378", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", @@ -72355,7 +73087,7 @@ "7c105ea32885", "3a1ce419154d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", @@ -72393,132 +73125,132 @@ "7c105ea32885", "3a1ce419154d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "083a375ad06d74e689ef92508c3f0286cbd3a766a7e982c2e9313c3f58264fbf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "0545e6f90bef06bd716487c5d0308eece6e438f80e3516be262ba8b4376b886e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "961341b36ba1f5610e723b52966db9e3d552a89981db39c93dbf93f88c4fbfe4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "f5bd7d07ef93d4e783e10bda5679407b89ea1f2088ab8a6aacdd8f31ad76fb68", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "4693dbd9a64c749b215e2eef510e29ff919df923f591237ea29a0671e42f459d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "910b8f6e0e1188eb86dea7c736401cb01e0d41f43568fc0f64426405e0a1aa77", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "efb22ff90c1d8d01ea2d1b92b7a2765562f7b1a795007da79ee87bcd3970df9f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "f1a3335db6be5c070b2cb1ced2d148763e3a8bec1b6a00ebe1c9864e13391f91", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "c510b118c0270219e668f2c161c9db573514f2e2ed3ad5dab77d28c9ad7e3a81", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "833300f0fbdeb0e323d9b73ed0419576200e8bd6f8afd343d633c94ff98b8dfc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "6ed5439f1cb984b211e001212125f8f257b7a9a1f344c036d6fd9b5f5292df2c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "0d555e4f02260506dfaa9e0104e485dc73c7fba2a571025a416a31e1699b6c61", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "f5b20de4bd24cb5247fc7fe25fa01be9cf51e56735d9d270c67d2d846fda3e45", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "7e88bf3b9e1875b783aa43aa404908a20171149ea68f51a9701882a6497d0795", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "df9afc1d45f1f4b4fa741689111bf5735ddb0d39929be3490cb5a7e964d85f46", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "11e47bdd4c456ddfcfc87a57d49dbe43d6b58f51963adc22444ab4860ecfd5d4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "8b949f0c3e63fe79991258e7f6e07b9a4ae133dc436796f5449db06f623c4747", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "ac7c26090fbd8d774d3c1fbf92c82dfa50dff472289d3ca38633fc4ac7dad906", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "b69005f7401c40503e43b03caa951d52e3673d0e9e8f0d23f1ae0b6865077b17", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "8be1bc39cd51d7ff0cbd0aa98940a3faba4ce1bb777b88703c1a4714d72f0081", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "ee1e35a23817b10cbc93da8bd14311a59e7b032c4aac73dc8620fd71633d24d8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "844bb0e5bb76f48834d37a1961067260ddab8b3765578620ac4a5d753463959e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "611dd241810083ff4b72be49df8b59a4f5e2c3d9d99bc62b9161fb8c9284dec5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "c4abb7bbe54cf06621e486e4f361a96b78b18d24d4c2770172cd9eaa831df56e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0021dbb4a682e199e0b3eb29844a78656cde465fb085c6f9c906b7c38f987e27", "target_hash": "5633a60d423f0ea529d270601bb68429042dfd7141b412a3103ab0f47dcb0c3e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -72528,7 +73260,7 @@ "pl": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", "target_hash": "f98c7c431d25642ca8a14854b6430b8019f6a93fe1b197d6132c74340e72e693", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72541,7 +73273,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72554,7 +73286,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72567,7 +73299,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72580,7 +73312,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72593,7 +73325,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72606,7 +73338,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72619,7 +73351,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72632,7 +73364,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72645,7 +73377,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72658,7 +73390,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72671,7 +73403,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72684,7 +73416,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72697,7 +73429,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72710,7 +73442,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72723,7 +73455,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72736,7 +73468,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72749,7 +73481,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72762,7 +73494,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72775,7 +73507,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72788,7 +73520,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72801,7 +73533,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72814,7 +73546,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72827,7 +73559,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72840,7 +73572,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72853,7 +73585,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72866,7 +73598,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72879,7 +73611,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72892,7 +73624,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72905,7 +73637,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72918,7 +73650,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72931,7 +73663,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72944,7 +73676,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72957,7 +73689,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72970,7 +73702,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72983,7 +73715,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -72996,7 +73728,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73009,7 +73741,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73022,7 +73754,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73035,7 +73767,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73048,7 +73780,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73061,7 +73793,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73074,7 +73806,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73087,7 +73819,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73100,7 +73832,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73113,7 +73845,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73126,7 +73858,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73139,7 +73871,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73152,7 +73884,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73165,7 +73897,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73178,7 +73910,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73191,7 +73923,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73204,7 +73936,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73217,7 +73949,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73230,7 +73962,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73243,7 +73975,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73256,7 +73988,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73269,7 +74001,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73282,7 +74014,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73295,7 +74027,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73308,7 +74040,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73321,7 +74053,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73334,7 +74066,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73347,7 +74079,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73360,7 +74092,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "b159542019e7188f4ef67bac0e1e16b00ea1842d9090fac72f41ba9f7163826c", @@ -73373,7 +74105,7 @@ "57a3af4b3dd4", "abe7d026d8d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -73383,7 +74115,7 @@ "pl": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", "target_hash": "668a046b825a253a5e08e71e0ddb42d8c51ab0b7a3f9470b09a6d52d6df26540", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73399,7 +74131,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73415,7 +74147,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73431,7 +74163,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73447,7 +74179,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73463,7 +74195,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73479,7 +74211,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73495,7 +74227,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73511,7 +74243,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73527,7 +74259,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73543,7 +74275,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73559,7 +74291,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73575,7 +74307,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73591,7 +74323,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73607,7 +74339,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73623,7 +74355,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73639,7 +74371,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73655,7 +74387,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73671,7 +74403,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73687,7 +74419,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73703,7 +74435,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73719,7 +74451,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73735,7 +74467,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73751,7 +74483,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73767,7 +74499,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73783,7 +74515,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73799,7 +74531,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73815,7 +74547,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73831,7 +74563,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73847,7 +74579,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73863,7 +74595,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73879,7 +74611,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73895,7 +74627,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73911,7 +74643,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73927,7 +74659,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73943,7 +74675,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73959,7 +74691,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73975,7 +74707,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -73991,7 +74723,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74007,7 +74739,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74023,7 +74755,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74039,7 +74771,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74055,7 +74787,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74071,7 +74803,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74087,7 +74819,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74103,7 +74835,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74119,7 +74851,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74135,7 +74867,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74151,7 +74883,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74167,7 +74899,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74183,7 +74915,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74199,7 +74931,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74215,7 +74947,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74231,7 +74963,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74247,7 +74979,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74263,7 +74995,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74279,7 +75011,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74295,7 +75027,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74311,7 +75043,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74327,7 +75059,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74343,7 +75075,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74359,7 +75091,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74375,7 +75107,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74391,7 +75123,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74407,7 +75139,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "65285718640286f05af499143cea817a9ba75c0f436d54de030f7b2c2f9c3cf5", @@ -74423,7 +75155,7 @@ "2c5b8f9dea93", "6d6f825feca2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -74442,7 +75174,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74456,7 +75188,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74470,7 +75202,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74484,7 +75216,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74498,7 +75230,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74512,7 +75244,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74526,7 +75258,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74540,7 +75272,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74554,7 +75286,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74568,7 +75300,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74582,7 +75314,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74596,7 +75328,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74610,7 +75342,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74624,7 +75356,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74638,7 +75370,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74652,7 +75384,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74666,7 +75398,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74680,7 +75412,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74694,7 +75426,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74708,7 +75440,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74722,7 +75454,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74736,7 +75468,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74750,7 +75482,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74764,7 +75496,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74778,7 +75510,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74792,7 +75524,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74806,7 +75538,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74820,7 +75552,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74834,7 +75566,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74848,7 +75580,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74862,7 +75594,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74876,7 +75608,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74890,7 +75622,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74904,7 +75636,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74918,7 +75650,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74932,7 +75664,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74946,7 +75678,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74960,7 +75692,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74974,7 +75706,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -74988,7 +75720,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75002,7 +75734,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75016,7 +75748,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75030,7 +75762,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75044,7 +75776,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75058,7 +75790,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75072,7 +75804,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75086,7 +75818,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75100,7 +75832,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75114,7 +75846,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75128,7 +75860,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75142,7 +75874,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75156,7 +75888,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75170,7 +75902,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75184,7 +75916,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75198,7 +75930,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75212,7 +75944,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75226,7 +75958,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75240,7 +75972,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75254,7 +75986,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75268,7 +76000,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75282,7 +76014,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75296,7 +76028,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75310,7 +76042,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75324,7 +76056,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75338,7 +76070,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ce38882aad0d55fe18aeaa25226cf44b18b91f9ebb1c495e0e8b091041568798", @@ -75352,7 +76084,7 @@ "53c2d848a2b9", "534644c91fa2" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -75374,7 +76106,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75391,7 +76123,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75408,7 +76140,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75425,7 +76157,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75442,7 +76174,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75459,7 +76191,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75476,7 +76208,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75493,7 +76225,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75510,7 +76242,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75527,7 +76259,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75544,7 +76276,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75561,7 +76293,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75578,7 +76310,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75595,7 +76327,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75612,7 +76344,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75629,7 +76361,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75646,7 +76378,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75663,7 +76395,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75680,7 +76412,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75697,7 +76429,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75714,7 +76446,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75731,7 +76463,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75748,7 +76480,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75765,7 +76497,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75782,7 +76514,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75799,7 +76531,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75816,7 +76548,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75833,7 +76565,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75850,7 +76582,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75867,7 +76599,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75884,7 +76616,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75901,7 +76633,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75918,7 +76650,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75935,7 +76667,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75952,7 +76684,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75969,7 +76701,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -75986,7 +76718,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76003,7 +76735,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76020,7 +76752,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76037,7 +76769,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76054,7 +76786,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76071,7 +76803,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76088,7 +76820,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76105,7 +76837,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76122,7 +76854,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76139,7 +76871,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76156,7 +76888,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76173,7 +76905,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76190,7 +76922,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76207,7 +76939,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76224,7 +76956,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76241,7 +76973,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76258,7 +76990,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76275,7 +77007,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76292,7 +77024,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76309,7 +77041,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76326,7 +77058,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76343,7 +77075,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76360,7 +77092,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76377,7 +77109,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76394,7 +77126,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76411,7 +77143,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76428,7 +77160,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76445,7 +77177,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76462,7 +77194,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "94813fd24e7e84d0e685b4dbdc2c4efce6ea3202d6e5dfa6fc529ff5da665d28", @@ -76479,7 +77211,7 @@ "673f0d2dcc2a", "13df09b1e734" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -76503,7 +77235,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76522,7 +77254,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76541,7 +77273,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76560,7 +77292,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76579,7 +77311,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76598,7 +77330,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76617,7 +77349,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76636,7 +77368,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76655,7 +77387,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76674,7 +77406,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76693,7 +77425,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76712,7 +77444,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76731,7 +77463,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76750,7 +77482,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76769,7 +77501,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76788,7 +77520,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76807,7 +77539,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76826,7 +77558,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76845,7 +77577,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76864,7 +77596,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76883,7 +77615,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76902,7 +77634,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76921,7 +77653,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76940,7 +77672,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76959,7 +77691,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76978,7 +77710,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -76997,7 +77729,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77016,7 +77748,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77035,7 +77767,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77054,7 +77786,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77073,7 +77805,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77092,7 +77824,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77111,7 +77843,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77130,7 +77862,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77149,7 +77881,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77168,7 +77900,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77187,7 +77919,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77206,7 +77938,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77225,7 +77957,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77244,7 +77976,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77263,7 +77995,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77282,7 +78014,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77301,7 +78033,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77320,7 +78052,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77339,7 +78071,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77358,7 +78090,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77377,7 +78109,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77396,7 +78128,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77415,7 +78147,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77434,7 +78166,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77453,7 +78185,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77472,7 +78204,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77491,7 +78223,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77510,7 +78242,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77529,7 +78261,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77548,7 +78280,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77567,7 +78299,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77586,7 +78318,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77605,7 +78337,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77624,7 +78356,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77643,7 +78375,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77662,7 +78394,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77681,7 +78413,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77700,7 +78432,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77719,7 +78451,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "f2bca7d3a9cfc1233e7345a8b7f5cb757abc86a3eb33bea2e618fb5a12432fc1", @@ -77738,7 +78470,7 @@ "d97d7be0b4da", "6f7a09c85a11" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -77748,7 +78480,7 @@ "pl": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", "target_hash": "08bb73bc03ff3caab4013c63d113cdd175b2ed60e1573eccd262ac5f5d08a650", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77764,7 +78496,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77780,7 +78512,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77796,7 +78528,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77812,7 +78544,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77828,7 +78560,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77844,7 +78576,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77860,7 +78592,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77876,7 +78608,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77892,7 +78624,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77908,7 +78640,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77924,7 +78656,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77940,7 +78672,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77956,7 +78688,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77972,7 +78704,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -77988,7 +78720,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78004,7 +78736,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78020,7 +78752,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78036,7 +78768,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78052,7 +78784,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78068,7 +78800,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78084,7 +78816,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78100,7 +78832,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78116,7 +78848,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78132,7 +78864,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78148,7 +78880,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78164,7 +78896,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78180,7 +78912,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78196,7 +78928,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78212,7 +78944,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78228,7 +78960,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78244,7 +78976,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78260,7 +78992,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78276,7 +79008,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78292,7 +79024,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78308,7 +79040,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78324,7 +79056,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78340,7 +79072,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78356,7 +79088,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78372,7 +79104,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78388,7 +79120,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78404,7 +79136,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78420,7 +79152,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78436,7 +79168,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78452,7 +79184,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78468,7 +79200,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78484,7 +79216,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78500,7 +79232,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78516,7 +79248,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78532,7 +79264,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78548,7 +79280,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78564,7 +79296,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78580,7 +79312,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78596,7 +79328,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78612,7 +79344,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78628,7 +79360,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78644,7 +79376,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78660,7 +79392,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78676,7 +79408,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78692,7 +79424,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78708,7 +79440,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78724,7 +79456,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78740,7 +79472,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78756,7 +79488,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78772,7 +79504,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0cfe583891c0196105a321f8763a1df90e8243a6a3b0567c37ef162aca16a129", @@ -78788,7 +79520,7 @@ "8dae03f7d8eb", "fcd3b8c89194" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -78798,7 +79530,7 @@ "pl": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", "target_hash": "a54965e9e0b6080d3213effb08b27cf16c62dd2e101e687f36b36777e2ea7dec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78814,7 +79546,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78830,7 +79562,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78846,7 +79578,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78862,7 +79594,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78878,7 +79610,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78894,7 +79626,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78910,7 +79642,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78926,7 +79658,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78942,7 +79674,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78958,7 +79690,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78974,7 +79706,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -78990,7 +79722,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79006,7 +79738,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79022,7 +79754,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79038,7 +79770,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79054,7 +79786,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79070,7 +79802,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79086,7 +79818,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79102,7 +79834,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79118,7 +79850,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79134,7 +79866,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79150,7 +79882,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79166,7 +79898,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79182,7 +79914,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79198,7 +79930,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79214,7 +79946,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79230,7 +79962,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79246,7 +79978,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79262,7 +79994,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79278,7 +80010,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79294,7 +80026,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79310,7 +80042,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79326,7 +80058,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79342,7 +80074,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79358,7 +80090,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79374,7 +80106,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79390,7 +80122,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79406,7 +80138,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79422,7 +80154,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79438,7 +80170,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79454,7 +80186,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79470,7 +80202,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79486,7 +80218,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79502,7 +80234,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79518,7 +80250,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79534,7 +80266,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79550,7 +80282,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79566,7 +80298,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79582,7 +80314,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79598,7 +80330,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79614,7 +80346,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79630,7 +80362,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79646,7 +80378,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79662,7 +80394,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79678,7 +80410,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79694,7 +80426,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79710,7 +80442,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79726,7 +80458,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79742,7 +80474,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79758,7 +80490,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79774,7 +80506,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79790,7 +80522,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79806,7 +80538,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79822,7 +80554,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ef75ca1653a5c04d7e611da6ec9ca8c418dee73477bc1bd0d24bffcfbfd51295", @@ -79838,7 +80570,7 @@ "08f5de954bfe", "fdab43c9da71" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -79857,7 +80589,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79871,7 +80603,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79885,7 +80617,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79899,7 +80631,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79913,7 +80645,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79927,7 +80659,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79941,7 +80673,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79955,7 +80687,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79969,7 +80701,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79983,7 +80715,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -79997,7 +80729,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80011,7 +80743,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80025,7 +80757,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80039,7 +80771,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80053,7 +80785,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80067,7 +80799,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80081,7 +80813,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80095,7 +80827,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80109,7 +80841,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80123,7 +80855,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80137,7 +80869,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80151,7 +80883,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80165,7 +80897,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80179,7 +80911,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80193,7 +80925,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80207,7 +80939,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80221,7 +80953,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80235,7 +80967,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80249,7 +80981,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80263,7 +80995,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80277,7 +81009,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80291,7 +81023,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80305,7 +81037,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80319,7 +81051,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80333,7 +81065,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80347,7 +81079,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80361,7 +81093,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80375,7 +81107,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80389,7 +81121,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80403,7 +81135,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80417,7 +81149,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80431,7 +81163,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80445,7 +81177,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80459,7 +81191,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80473,7 +81205,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80487,7 +81219,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80501,7 +81233,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80515,7 +81247,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80529,7 +81261,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80543,7 +81275,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80557,7 +81289,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80571,7 +81303,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80585,7 +81317,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80599,7 +81331,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80613,7 +81345,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80627,7 +81359,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80641,7 +81373,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80655,7 +81387,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80669,7 +81401,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80683,7 +81415,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80697,7 +81429,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80711,7 +81443,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80725,7 +81457,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80739,7 +81471,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80753,7 +81485,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "7c88ff18be2e76c9216e00e32ffc25e6c335dabce8e13d1501e80a059e7a5d87", @@ -80767,7 +81499,7 @@ "431cd7b7d011", "53ac591b667c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -80786,7 +81518,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80800,7 +81532,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80814,7 +81546,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80828,7 +81560,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80842,7 +81574,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80856,7 +81588,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80870,7 +81602,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80884,7 +81616,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80898,7 +81630,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80912,7 +81644,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80926,7 +81658,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80940,7 +81672,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80954,7 +81686,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80968,7 +81700,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80982,7 +81714,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -80996,7 +81728,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81010,7 +81742,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81024,7 +81756,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81038,7 +81770,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81052,7 +81784,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81066,7 +81798,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81080,7 +81812,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81094,7 +81826,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81108,7 +81840,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81122,7 +81854,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81136,7 +81868,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81150,7 +81882,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81164,7 +81896,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81178,7 +81910,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81192,7 +81924,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81206,7 +81938,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81220,7 +81952,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81234,7 +81966,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81248,7 +81980,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81262,7 +81994,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81276,7 +82008,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81290,7 +82022,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81304,7 +82036,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81318,7 +82050,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81332,7 +82064,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81346,7 +82078,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81360,7 +82092,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81374,7 +82106,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81388,7 +82120,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81402,7 +82134,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81416,7 +82148,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81430,7 +82162,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81444,7 +82176,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81458,7 +82190,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81472,7 +82204,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81486,7 +82218,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81500,7 +82232,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81514,7 +82246,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81528,7 +82260,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81542,7 +82274,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81556,7 +82288,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81570,7 +82302,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81584,7 +82316,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81598,7 +82330,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81612,7 +82344,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81626,7 +82358,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81640,7 +82372,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81654,7 +82386,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81668,7 +82400,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81682,7 +82414,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "7d08a55656e078501044a3e018a6c91adaad177a5729042637979918de70e2d8", @@ -81696,7 +82428,7 @@ "8fed20fa7764", "4759275562a5" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -81706,332 +82438,332 @@ "ar": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "d7f155ee9a9ea883df16d3f73ae3d744eab431f05d461a31ea431ddd38337d44", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "11e25286d09048f98a8ffdd027acf62cf65bba1743116c16d607279f35d0f58e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "e4eadae21f4a8b1d276f0a792c5ed9d0321ff509f0ba22c625cf38cfa7b7e5bb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "661ab323dc42944c16fe0bd0bb5d846727e3ce9265db491994b2d7f6e77ea3a0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "217017f622b1c91a08b987dafe7b0faad9c74f3e21144cbf09324f6d7191e88b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "26d5c52da00e20e18807bb9bed7b0abbd060b212ab1ef942a8d6cbf2012fcc14", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "f3aa7d909f887ea70a5743304394f1291d86a5feaa23e2436fa999a21063f9aa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "279aeaeb3e8a47456b4096b4acf60ec306b97dcade678afa238bd7484fa38029", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "f156260b377c2f016cfb31157e600421f506a362d84d05026718a4ac71a75d11", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "3703be66a9434cc846f5abc773fc4f8ac821651dcdcb0508b9abb20c11084b4f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7dcccaf49cfa5f13a9c34e7f8e2b3e258daab666b2c97a8f1a53f34a6144db73", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "f78c9c196c16e8fbe2984831abb033e58ed8efe787e0de62ca5c2d443d2b2d35", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "dbd99e2bbc79097d576179ac8827205ed5ce0daa049962674d13928fe256c505", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "d0c72aa8f322f059e6bc865f96050b1f7056ea998cb57924a29308465620726e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "ec9bdbf89829fc182e30ba82069a018c6973842be38127af873431fdc0e35de6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7b1d309929ed7ab86baf847807a5f225e126aeb1ba340de6b8a1439e3d07b54d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "b3a208405262cbd3d8f6d10351f5ab2d238a731bed89c1b2d3788ca4302a0c2d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "6783e5bb2d4bf2aa3b7041ecf81d3d94863d89267a5090873639161efeafd4c5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "6377a20ca188be09804f9e60f81440539611cd886f99c9851d77f8aa32ebfa27", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "17a1846be003fcf209ae9bc30e6f353e7f4084ed0ef6d25a8509cec50af43181", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "16ea9c1d49182d92e9880d2768530780ff82851d0b74fc15f46b304bfc1976dc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "2480b31f8cebc8dbe616cebe15acf79fa613751d31c85320f8ffdb9db3c5306f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "aa7a4c3784b1a61eebd946e61bd046b77b634378e8046650f5dc8dfb23df9833", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "9f3435aa76ccb349ade863217518a0b3e741ae2f947109bd88a68a58d7c06f58", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7c2bfc4a79ad69e5981204f3022c1afc673ac6a66a98c077a805154719462523", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7fe759d211c9bbebfa5e14c88c2d10d9f3cf83b71a91b8567aea3bbd9e55445b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "2c682a0463b7237bf6a9ddc43eb81de2dc4610f88ea88e5c6f0679a141ae5487", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "0fdac5383320a6704b7af0629781bfda6f46c45c9e5b865ceab0fe6d8b95afae", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "8e7a513763ce68c9e74a3fb9dc4ab238ba8eecd7e1573688f69f614920c14717", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "e5d4be8528df3689dc661e281a652eae729541c95a76836cb33e6ca9ce4eeb7c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "c7569abd45d482c2777fd5c0e5ac1ee8e21ff93f7bd9e35c19e0835aea8e087c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "5e88dd7670ac56d963fa94185c12300c0b4a6441cdfbc67ee258698ad69a4397", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7fb418a76354ef5d3303610488ac40f491b7d43cf4e9470204fdd27751e372bd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "3ac7c305223f4c2990b19d5b2754f43d952d75afcd4559c363543b53f73a65f3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "5801fac1010240570edff040283eca29a4a1ed853afa195b034fec1111b6fddb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "b6a316a3031e567cffc7554a64a50bc17f1d6d3ba15294421648ee9d4dfc664b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "44ab759f245f81f32368349b49bef918683415bf8f6c0aec953957470342d2bd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7307216b4e06c56381722693ddf02e4ced85048734efbb9f3fd98917142a4c54", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "2dd606a1c3624df1e8ee8a17430b4f3c5121fd621770defd5498baaf876d7abd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "f2f6985fad3f4b00552fecf117f7c6c6da5f815d883574b9fa8722506f3bf816", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "7cc249732cddbf9d7c517bb1f8fae05fc758ee9a3ce455f79e533e660c7d7f3d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "cf841390c4778ab30fae817617223a7bd48ef5efee62eada50d82144e0e6d5f6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "c95707c7a98cc8e22e74f479464811b240608123b0f334ae56c221d074a7051d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "3adb5ef1efa13576ad2b2a68ffe60e5fa50830533676d21bcf4822bf94b6ac45", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "5f22872c7982b6a25e9638b5ac9c1571c17ac3756bef988c01917b2b13d481be", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "b1f0a4b7abe909680b8ac5981b6df510b9b30ad20c39120616fe4f41f6390e12", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "b1a5eaa00646c96446459ec5e9f81389eab7be1e2224d13aafbe544960539245", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "28b969ad26c569ca202bb8507f5b16d1214dd6e84648dabf07afee30f7a311be", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "3395ab9fd7dc04989e937429a37c487fd418fd921935a742a0aec8cabd723926", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "81afd6dc79f64c3e67344af6de97b4a037584c3379bf573ad222b7a5fe8e9e09", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "057a001c3a7c5e89e07a92184c90c848ef3f41de284153afa13430e3a1242610", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "77a232e646efeba78be583426fcdda0c4e92daa83ab6fbf33fe5e1e0d316b6cd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "ca0b4668fdfe609fb25589e3986837aedaa35091c3dc84cc64a2d58c869def93", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "ebf2acfdbab499c195092e181e71ffec69bcaf747a7acc3e81ad8221e1e847af", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "627981514176ff55b14a06a9fc6283e32a76462ce3876465a082ffb15a15e6f3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "6e5e43eac75a9229a98552f84a6e5d29b0e5c3782bf3adb07131564f5cbdcb9d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "0d1d56121dc3a6376b0888fb9bbe597e1c37089525838a36838f7c3d3235996d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "8bbc62d770fd32e89e7c674df3320b949653f8a4f97773fc59cdc2719be1e8e1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "6289bdbd65d5246c8c9cb5c3ddb67d315f2b8e5963595fad18a6236285576fca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "94a5462707a7e376ce65beaacc85f9394d8fcca1b2855110b83c2e01f9107d44", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "1c533921a2f1be6e47f5e506dfb92b050f8c64f28ad0f21e911fa67fa7cb9bd0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "a44c8a9883bc0e2c40bed77831570badd87a9dd1af12e80026eebda93d241d95", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "3bcb10b7f16f3436cf8bc2166d849558833d5fa685898c8cf004b4e43cf485e5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "9b5ac1dc6c8b851773f90c11dc99c27328b4d10eeff1d2a823fbac7a8f73f488", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "82366b897e72051d85f106b4c1e3bdc9a40a47ab9442c8d1edd6917b0be46df5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "acf8f574a369e81466c72a5aedc118e37c6f84797f45a1169ff8102b91579d56", "target_hash": "f5974baa7fdfed2370e5335f7c8e08833ab203e289a0d04b57fb2ee17794af94", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -82041,242 +82773,242 @@ "ar": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "4ad64727e119b7c8bb6df2491f382696e5e12b88bd0b3fa08a347c92d0ba0d92", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "ca7ea9e6ceba58dde8c340734f9e64863b0db91d7f21b7bdfbe84d0b6b318f8b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "d8f33e5088b2bd210454548cc20c09205305cda7872eeef332ca0c9fbfdcc6d5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "77f9ac7202209136587f6b0f2e86c0b360b86228276f133acc1f877fcfad9c3d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "0e44e8e196dadc2a25e2042f61494df84db11a6ff043dfa3590ad7412ffc1ddd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "b37db69bdb052b2cfa4b52c038ca139c6ac1ea5157b6496104414b9c1504fa2d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "459729ace3c3cce569084f5a987b611098f1d139a4e7b20f80aedc126a05add3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "30542809a5a53c21819bc91cf7ced0c17a90bcc8231bceb6b331a4e2cff0a8ca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "ea0245e600fec77b214e486bab96e2439ca9f572fa640ffe8ddff6fd9198195f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "79590e38d96fd7b5c38f68df05bb1354fae1cf7c95e3bc425357549f1b6972a9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "52f4c920e0295553d605e4035e09e87f2819588ae88b7bc2a7635ca6ee41412b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "c025701b72866bab16e8608f4c4e11defe7760555241bead5b693c2291fc65ec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "e96db65be89d2be6ad62a0a201c36213d79c1ac66268b18b3cf5eda9335a80db", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "823ee834567d9f0cb7efc0a75f91333c7a3abebc6af4e685c9c9b0925ae66f11", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "151560ae5486dc7eba699c7432fa224afa72f890f5344fb2b314af829873db7e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "d5775939e4e09c91e967803c948216e92a182de6776979050319f86e3d45ab7b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "5140a265e43eaeb5cc0cab951dcc5112feadcc1c9b378ba4d2b216c95c6c6456", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "56b7b61356e17fa9801e09a79f6d877c45a1ea0a2fe57c552d604846eebc75cd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "9c94f931685f1a09dd8b8300da0b711a74f7f097af484c6aad14e56cc8fe9228", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "a1626398cdd87c007bcc0b96ee0d8588297f32a97ba7838b8cb4c07436cdc06b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "ac2e6d16493017323234275ccad7ae4ac33518ee06bc41c73e8df88e6a4a9ee0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "842d3afeeab826a8d1dba58ea999e5ff470fb88b8be478e5618f6816d8fb7882", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "6d665912cbec0df8c6942ab17140d2403a26368f1931eca297c7371f77233962", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "e99af1c3b1bcf543e894d17e80495535bb8790f42adb746647bf0c62bc806333", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "c406265d4567177a623e654d08a5f03f95bf31f791a0a85a1a58fcb78e893e7d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "79d005d134eef5edc07650719c4b75f1e338942691bbd4c58a8a4378f848e036", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "164975332c16f556bd6b329148b131c36df7bdbfeb7c44457c32cdc4e4727f08", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "b47c32e8efc47b9c983e17944b8e8ed471d85d28bf5071f45085715ee58bcd05", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "002b858fa182cf70019b08051aa8a3fa4d6ddffca66acdfb4781ecf0bb75f840", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "b8ee76f0d7400580b21e8a34be1a641ac870ecf53c0c743669074c1637a9bbc7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "8e8e95991b813537f1403c374805040f6296edd8650ad47cca9149f647783ca6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "25f943ffef6419dc2ff975d66396481d23f21362d76a58b8f82a927c6fb5e4ae", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "4b9aba0635270c886b86314793ca99267817a236ce2d28d9d9695ea2bc8b8a9b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "187f385f09027cc814a299d8122cd1c26d2f3a0916dd35387587c5940371b30e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "fafd0212c8ddf3deb97121e32767a111701250ded83fcf62d08f0a3465315d55", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "013467434dc238c8f5a511bf7feacd86f21a8bdb7fe3b66ede2ef7f2627c5d3e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "9302c18d115390e46c0f65e2cc08c75309d0d44c0bfd3878ae6dbedf3bc1e423", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "4872fa3874b5f74d59ccc72241adc2ebc32847e40ba2402ed511ff3a68edb71a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "e27a206ebb9e0534bf8188da3c3a7389d95e267bd2a6f92acb57b2a77b676fca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "193a3d9682fa293e74fb2c5ddf1d52ce613673b0a6f43d2b88ed864ca8055f83", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "b54cb9ffe724fc0e4f9983b09cc57fffa91f05efdb58ba1bb0d3c0a2e292fd24", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "9c97e129b3326912c601e5bc40f3b705367fb23c5df74ac98b438c954c58ad2b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "e00d484cf67dd90bad114bbba1e84982d4702dc2f7e943bc8bd65ce80029dfb8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "00e00e3f21e181e8a34971bf1a77d618f07c32bec5ca383e69ee35f1e86d490a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "88eda773a522e0937fde4f531fc819e3ebce35fc3fa416c30bd6f7dd8e18deb1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "bbcd24fd8c353849d14179e74e45b5d4daf1228d13c474e0f50300a718f6bce3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "6974bac16ef62bb1bda67ea044340a88ff7c11d0249c174becc1993a9a293ef3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "aae992c716b87b0c7fbb3becd5ed1da0560ec65493425b42bf70a34dbb37aae1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", @@ -82288,92 +83020,92 @@ "61d53d9c4c97", "85fb5e897f2f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "e92bafca970e00f40eccdbeb26410a3e8b394def3ca7a9f02ca6e9a7991b1af1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "d22eb925918b251b02e4d24b4f2966b6a0bd25a5c9f7272888975bef4e1235f2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "57aae3f6ef2af8d24d533b8bc00ce647c57e15b50d6c1ade86b2d59f782f95e4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "607b5a5c61711cda6804770557cd49fe7f3595345c2228ff437a574b6707d770", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "daba432c21a67902990939a9ba6fa026451a41b5171c5e3d9e062a136349f080", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "6bd553de7fdc7a75b172c62191529644a4bacbd5051b7f4d95c517c18dfeb870", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "08a4292a2e5f96b73e5a1b0a252e999e22e4b4075dc7fbd43323a00931d2661a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "de309280ab4b87b8cb485fb7af8dc5e876cfdec464280262931a2c3010be5f7b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "292941b851204b525646bd6a1c147df53cb8db705ce952d5fb114b1118abf36f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "87da7a0d211a50782b007ffb1167ba7b03076c9980cef8b495d7251fc71964af", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "57fc82977c0428a760deca9521d03437445ed419e7a849e3807f550a30795ab4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "7b8f6a9e63a920b5cf7dbcb2403f27ecc0e2e020ece1d104874a08c5dad6979a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "37789389ffb90de3047202b8e44304c23e7f5f0a92996ee5a665d1bb67e4393a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "285c881320129a443cd1851cb40c54df7addc8d73b58849b4d6bdc0bc7d82f21", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "a730b25457af5196cb4ec4dc11cee331b87bf40726e965ea399c00d152972252", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "d4ee9c8475a9170b8c22219168da6de98dc8326e4119d2efcd65915334a653ec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "82afaf3a1ea599529fe30f558ea2f1477677a8c269adfe7d95054b1c95de57c4", "target_hash": "e8d9346a0636a3313a454c7f8e35589e5f2d13333766f10edd267f0e5b350553", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -82383,7 +83115,7 @@ "pl": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", "target_hash": "4dc20653aa4492340ce36b8f511af8680f87e11a5181d801a606d0c8c872492a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82395,7 +83127,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82407,7 +83139,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82419,7 +83151,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82431,7 +83163,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82443,7 +83175,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82455,7 +83187,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82467,7 +83199,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82479,7 +83211,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82491,7 +83223,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82503,7 +83235,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82515,7 +83247,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82527,7 +83259,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82539,7 +83271,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82551,7 +83283,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82563,7 +83295,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82575,7 +83307,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82587,7 +83319,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82599,7 +83331,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82611,7 +83343,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82623,7 +83355,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82635,7 +83367,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82647,7 +83379,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82659,7 +83391,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82671,7 +83403,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82683,7 +83415,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82695,7 +83427,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82707,7 +83439,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82719,7 +83451,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82731,7 +83463,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82743,7 +83475,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82755,7 +83487,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82767,7 +83499,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82779,7 +83511,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82791,7 +83523,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82803,7 +83535,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82815,7 +83547,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82827,7 +83559,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82839,7 +83571,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82851,7 +83583,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82863,7 +83595,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82875,7 +83607,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82887,7 +83619,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82899,7 +83631,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82911,7 +83643,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82923,7 +83655,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82935,7 +83667,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82947,7 +83679,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82959,7 +83691,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82971,7 +83703,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82983,7 +83715,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -82995,7 +83727,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83007,7 +83739,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83019,7 +83751,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83031,7 +83763,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83043,7 +83775,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83055,7 +83787,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83067,7 +83799,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83079,7 +83811,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83091,7 +83823,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83103,7 +83835,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83115,7 +83847,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83127,7 +83859,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83139,7 +83871,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83151,7 +83883,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "d286daf2055a2ad6e0979ebbf3296968ef02734e8fa9a6b2dbbaae729cf2923e", @@ -83163,7 +83895,7 @@ "4f09146dc8b8", "833ac169895b" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -83173,122 +83905,122 @@ "ar": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "651dba6d31c0f3bc9d61919e00e9dcfdea0c3886320873eab6bd43f5d530eba4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "98913657004f3e5d2808e76b1c1e53e2a7ffa1c9e03041441da8991468ca13ce", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "24fa4000c59634a1c2159dc5d3fa94f4afe3d3143dd50179e698c6764dff3862", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "c3f4aa5cb20df00ed7b07d6655c6cb8fe95e50405eaac5cf41081f5b4a2c6c2e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "67b83585f74bab27cc150158a3ca2d74a7889e0c341364906761c86891436fb6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "b3ba7ac50b486b6c39da91120c2cfc66aa8bf4158cc5385192dd3c82735e9eba", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "ae4f17d41123dafed5ec6f15999c8f7cc5c477879d3c47d94906a680546d495e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "dd557dc1d01c19928d2fed81916b1de9458efd1a389b66c71b594acca9c74938", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "e2625619e80f30b9c4cbe479161d397b9771119e4ce7a4e6669dd38ed32fc9b8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "213fa5b1c1911a1e6a0a453e933de50d4a00819e8410e20ead597f1772211114", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "25ff8e71dd15daaa6f85baea81d85c89cc28521261a972681a806c54fd198d81", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "3dd48bd0140cd08a6d7a3b94d220240c086c87f64d9e8c6537ad15916c220c36", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "c9854ec305ea3b90f592160486c4d4f4395589f28d49929ef3b5873020181276", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "9ec3b42ff861c3eaaeba956ccfe67fce5b4e3d74483de724a6cc54d70dd8f0b2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "15257f00671130a74004f61ecbfa1c5daed13e8d2926208bd33fca8fa1ad31a0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "870f3f60d330157c93d12cb4e4bdefb90e1dda644f1a0e88cfebc11a9b839b4e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "e5bcad7d05bd1acfb4af5f6234ec45e84fad2c189d483058aa81e093f8275d19", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "5cf7723c2b72c87daeb7bd846e31ff0a8d11c9c8eb86a0ba24e290b1145bf9ca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "00a9db9df3ac36d0e8f1d723d29f6375c0d70336171f548ce672fc6f1af253ae", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "5c087d6214da111b11db7e78e61df1c14c956870fd84b61a4c7e932e1caa55c6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "20bdae18db0451238a1e91b0f17b2ec5488222b25360b45377b58708fd8a9def", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "8f7542383ea5ee3af0aee3fb6ee96daa7fc6c65a6d7afc42f2a6b578f6c8880a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "c4e8a52bfa4849cbabbb35becdc20ddb363529f8f7b5e97d2e7dc45a5d539318", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "c66c9ca2a1b6c008d60150c039e738778a0d03f62e4b9b1d065a3a1731ba35cd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", @@ -83314,77 +84046,77 @@ "0fe355b3aaaa", "8af1252b116a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "5468c8972d6b2b86ffe29fc70ffac08e705a4d50e8d6f3e97a6a9308560b8066", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "27bf5b8f1c4ce0b375fa149cdd9a864944688db7658119f1279e613466aad647", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "0fa0a2a03d2c577fd99d785f2ef6c73ce67620a7bf96052a2bab5c3bd420085b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "b947676ae14e33d66fbd010f8b052a65ba58212f530d47462b59c3f9df9d5d7a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "1a283e3fec407df2d5e69a622c842f1f4f5079c5d59dc2e6598d69b56398c6c9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "365186cd110cc55014aae191e73eaf58fd03e6502b12afe5fc52c74a48fa18c3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "efb1c83c832487215450bb87d5aa34f1f119252bd1219483f69e013facb28138", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "5f4f117aaa5dfd8cff611690e73de2f9a9e19e9c12f071cf5f232bf36040fc72", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "ffdf4c55384a0b993f9d11df0e11d7f4b9db8503d20972cedd635a9d36380aa6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "b2f8bc456c354f599cb53fb489937b9d2035d360ce0c0a0c0b7025e6811522c8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "b51beb258dbad9d99648e0a0c0c7ed9d1376bb4c897dba051e2153c8ffa15ae7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "2b3a4e4c86e3eee2aa10ddf5bc745a988d66bc7761da4705cae81cb114f6e376", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "fddeb616602d3fd334be57e6c29eeeb77c1c30cbf9b3e48523c13f675bcf2026", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "824f98a7219e01f8433c753d76d3574e09220d341badeecadaa97c6313034870", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", @@ -83410,7 +84142,7 @@ "0fe355b3aaaa", "8af1252b116a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", @@ -83436,132 +84168,132 @@ "0fe355b3aaaa", "8af1252b116a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "9f00d829b4929c7ae97fea6083135d71fb3ebe034631233fe8bff98554675c3b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "82d53bb66abba820bd9b464942c166eb934370a387098dbffaa76a17267e4fc4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "828948570046aa917d89a552929f5a2b8044cb39aa3f39cb32e67dce51a5e91d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "24698e323c6718a5ffccdfa6ac8c496d45cca44bd20b3521a311e33968aea130", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "eddd2466c09818629afe1f15c407f7e1ffd13f2eb82613ba6751cdf448729390", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "9c030a9bb3abb846e7848a8a01428482dc46646e97dfafe9e7cedb9a4cf853c8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "76f949ff24d84a3d0d884fe3e6fac87e59ace516ae66507a096ab7cf3b2c38b1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "447fc3e1614043f47a725000a971db53407b8f453ef4135b30846e99e8aced8e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "3a81f4f0c8ea89ba530c5493a63800b5cf9d7a281f023d430501e188ce3b5c20", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "fb8a45c52f0f46e7d55b02ff87bda06e84d91a3d17ce1ab46200d1e6ddd039f1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "ac5d49ee1277ff3bd0c1dfa54a2abcab0f87235f31db2e3eea875eb4f02405dd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "905eba818985b7170e698b87537a2f72d99ca9948b18380bb427f36c8505b3fd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "dbe3e71ee842950349415f75490f47319555919eeda712ade7193edec99adcbe", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "42340cc54bc483b50102657e649f37848947a518eff1ec86521c9b6287d2caa3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "2f3debc732723489dce70e5ba2d1c559964db7be513da6e5a33e12e3f095b264", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "7e22dbec2ae73bef9959fa93933e83359b0d72c98554cd0a18e89800714d5284", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "f40b77f1df360a40aa531395b2b5358e3a684f1369f4daf067d76dececd071f0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "481b7e97e5f5f99a21e1244db74dde75582262f4373d23ff9ebddae75ba30840", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "12344b904c3b8ca51b18218f67dd421fea960e10d2fee5d155812572fd461e2f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "6687ea328ef16c4cbefff23ee9248467da524de97501743531aee3b4aa25cac4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "58ac664954f48ab55a1fa1dfb814f169ef3b486f3a2a3ce9f762f0b305e3b198", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "856f61df0a5cfa560b571d2a7faf41060b2a8a5509f2c52eaf57981d14551ed5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "91c938ed586a349c28e3243744017d0ecbfc37238e15dcfb7b6ed336eaee0e90", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "1adc9e762e1df9a475587133bd57c0cd6fab19920094aef7647ea41fce0e2836", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6245286ac637c7e3a0ceae43a9e35b3a06dd45d1833da9b67459d53dc46e3c95", "target_hash": "5bb23d1b0c47b8696b83ddc56a744ecf4720add309dd3520a8a5d2d507080a4a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -83580,7 +84312,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83594,7 +84326,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83608,7 +84340,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83622,7 +84354,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83636,7 +84368,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83650,7 +84382,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83664,7 +84396,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83678,7 +84410,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83692,7 +84424,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83706,7 +84438,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83720,7 +84452,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83734,7 +84466,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83748,7 +84480,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83762,7 +84494,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83776,7 +84508,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83790,7 +84522,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83804,7 +84536,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83818,7 +84550,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83832,7 +84564,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83846,7 +84578,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83860,7 +84592,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83874,7 +84606,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83888,7 +84620,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83902,7 +84634,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83916,7 +84648,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83930,7 +84662,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83944,7 +84676,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83958,7 +84690,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83972,7 +84704,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -83986,7 +84718,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84000,7 +84732,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84014,7 +84746,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84028,7 +84760,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84042,7 +84774,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84056,7 +84788,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84070,7 +84802,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84084,7 +84816,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84098,7 +84830,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84112,7 +84844,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84126,7 +84858,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84140,7 +84872,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84154,7 +84886,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84168,7 +84900,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84182,7 +84914,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84196,7 +84928,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84210,7 +84942,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84224,7 +84956,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84238,7 +84970,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84252,7 +84984,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84266,7 +84998,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84280,7 +85012,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84294,7 +85026,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84308,7 +85040,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84322,7 +85054,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84336,7 +85068,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84350,7 +85082,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84364,7 +85096,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84378,7 +85110,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84392,7 +85124,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84406,7 +85138,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84420,7 +85152,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84434,7 +85166,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84448,7 +85180,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84462,7 +85194,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84476,7 +85208,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "bcf155d5508003d6e7495bf3370c5b844b6d1ed5a4efb547fbf5835de63d5816", @@ -84490,7 +85222,7 @@ "e6b8adddb94e", "76c9ca7dbe9d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -84500,7 +85232,7 @@ "pl": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", "target_hash": "b241220481a7462bfa14828420e552ca1307ba063d0e650987dce889e6e06a74", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84513,7 +85245,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84526,7 +85258,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84539,7 +85271,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84552,7 +85284,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84565,7 +85297,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84578,7 +85310,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84591,7 +85323,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84604,7 +85336,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84617,7 +85349,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84630,7 +85362,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84643,7 +85375,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84656,7 +85388,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84669,7 +85401,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84682,7 +85414,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84695,7 +85427,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84708,7 +85440,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84721,7 +85453,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84734,7 +85466,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84747,7 +85479,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84760,7 +85492,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84773,7 +85505,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84786,7 +85518,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84799,7 +85531,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84812,7 +85544,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84825,7 +85557,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84838,7 +85570,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84851,7 +85583,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84864,7 +85596,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84877,7 +85609,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84890,7 +85622,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84903,7 +85635,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84916,7 +85648,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84929,7 +85661,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84942,7 +85674,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84955,7 +85687,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84968,7 +85700,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84981,7 +85713,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -84994,7 +85726,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85007,7 +85739,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85020,7 +85752,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85033,7 +85765,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85046,7 +85778,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85059,7 +85791,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85072,7 +85804,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85085,7 +85817,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85098,7 +85830,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85111,7 +85843,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85124,7 +85856,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85137,7 +85869,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85150,7 +85882,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85163,7 +85895,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85176,7 +85908,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85189,7 +85921,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85202,7 +85934,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85215,7 +85947,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85228,7 +85960,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85241,7 +85973,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85254,7 +85986,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85267,7 +85999,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85280,7 +86012,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85293,7 +86025,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85306,7 +86038,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85319,7 +86051,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85332,7 +86064,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "aeb3c53a79cb1c6ca5b95cf409936b69d407dfef3d5d8d17e91194fb732fbb78", @@ -85345,7 +86077,7 @@ "93434f5a50f8", "2250a5c7f534" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -85355,397 +86087,397 @@ "pl": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "fd3960a9fd856c353b32469937b14e63debc07f764791144f887b5636262e880", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "eb5c1a56ca5722b9c63717925d45dffeb49f105a76d9ce31cf7a13d32f1406f2", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "1a87081ffa1f3fc513ebeff0d0dd7ffc9e5126aee6dfbf17e576e37d5f0aeadc", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "e89f1693728882014adf0038e1a60a937e9446e92f6c9d6d47e3b5faab4adc65", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "0af6aa5bac901828abf54ed57369d17b823eb47a81c138a1696e062c3cd2b978", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "7e3d9e7cfa68cb6be036968530482ff85b12e0fa7b8bcdac003474c33be6dfdb", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "dbe2f1783376b6c16f4cfc7530018d7493a8c2c4530073a42616a999655dec56", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "30c692904f3938b7400eeb2d5ec8515027fe40a06e76904d1259bbed81c9961a", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "1e074cb0243594c4b58b3f4ba3dc01ca6fe421c485ab25b7e2f201549b79bede", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "19180ca11b703a6fe4151bbc52f371c79a882350addf4f5b865c96b18e058ad5", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "d72793b2d86e66863a36e5dc5b28a037d3215c1783f3df6199d56cd8ee69b4a4", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "2da81ffb7fd5438e12590fc3f4acfba7cf8a7f74244cc2a4797cd44b06c376ce", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "96ab7c2d2ff8943a71f2acf9db0a3d2a5fb4ce957879ade478d1ceee04813708", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "e5df20420c7f532b2e2b2117f41062d0ff6c086f5be6054632c3ee3ef3ee365f", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "f9372977d6ff8db74113ab1fb026a75616aa871c0d157ea2dc10adc8f9b453d9", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "2904094a7a65efdacee310f43b246f594f4f0cc46dd1a3e1923aef0ce584eb7f", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "6718e67933862475c0a65518286a5dd313644b9c66bf07a77f870224f8e42027", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "b31e3fe65f064dc75c3c9216f5b09acb0d7956eb307dfd22b90cc6c2d2dc7911", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "59149f625bc4951f62443216f2d78786214b7fa15519cabb8d8e87e871ec9509", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "bcbc2dceeabb3e153c02a147e717dee97af74d786261e415b46537674dce708a", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "5c68f0d1d555327b5bdec818f0f47148768adf966fc81e7ffa20d23aa9376697", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "698c5657c77a15bfacc9f7b5952ae967827714d6075a2174117cc61cdae3c0c6", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "9809e444718b0eb1259443c65ad050b334401f3d5ae9e1f7330a973ee269c52b", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "51c7f89cbc6b794b6592631cc35c2deea31e6e5315e640ff2ba046794b40731e", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "33e96c28308238dc72d8ce57ab7a0aced2f98961c8c8c7c46b52989a690076ae", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "b3237bc305ca903893f3477320d615b11849d69a263f757aafa384ddc8870b77", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "3016bcd23da1150560bc413ab2d57eac16525e366684fe299583214f18d77da7", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "5b1f723950b5290b6bc42de07abbb0c366b91b371ddbfbcdbbb04b962c65daa5", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "db0b63bd2190c8077702bf6351b53ee6caef987c42245eedfd50fc89a6e7cd64", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "901d89760bcb3ce33d1369a83cc0c62aa8def221d341b421bde1b93e3e94468d", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "be3aeb2a54c965dbb3b748f27ba01045e07a01d0f850faae9eecaa1aa733528f", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "cf4fec36447b7e46add808557253a9b5061b52ccd8ecfe5fb74d801712b12534", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "9c8ad89320151f4ac7832d64ed3f6cb5f253a5067582f1f03f10c32ab1b9c4be", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "e7023ec7a98afca4ef4032c85b80ef8d6ae9720b879c737b63aa43fc38f34f27", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "ba1fbf5e661102a6f90fcf153241bc896c508dc983d6caefb24911c1bccc6d21", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "1388b857b7226c75023aadfdc242f3a8d6535908ad06aeae411d91ad461944cd", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "d751897fae6a415b35e043c99ab2125e28631147f78b8c72247cbe6372af6d8d", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "1c95817599b8bb413100ea5a1e095aeb6b5eca992041e38d5ec952ff6ff56ed6", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "8627a3ada12b0f78290c7a9e5a9f7540e3f7709f75a2ab151ff66f4d3c001aa0", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "21925b2b6ef9e1224386789301bcc699db827cf4603b83e38d0e97a7ff2fcb4e", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "93089544889a75163ee0e079e86b633d61e5adf0da84024550eeb7f76c094c36", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "34a055f80dd6bc52ae3e46c3460b114154e9b481c55e5c45af7b3f8c2211c182", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "e73ac374ebc3c2a2dab92de88960e686dae013e887e20f5bc9068d3fdc0a4d0d", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "4dd4dea2b4e062383463e0039e5e01e1a61ea7656c680a583506b2c7ba908cec", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "042572df5468ca98f0fb507658748342f46f5de4d570b064c0aa051bcdc41e6a", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "1483a0fb3bd6dde5e663faf29dd08a931c726039296f13c0c7ec71bc144ded2e", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "28589bfea9becdd613d97d5a6e9222f2a364822c6cfe45768bd608691b319fda", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "6874f1d4258b499e0e449e1166de33d5cc5d1e39ed986e9648e35bf6bb1cc7ea", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "5d06d73a44b21aa7020400b43d2227514d35ccb25aed5b18c1fd44c6dc08535c", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "268a32dd3b45b8acc5b84dfb94add101cd124b4f5403fb46e1992c190baff85d", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "e5aca9cb12478ec48a84a85b1bdccdcadeab300a9d559545aa3a24114f312b57", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "47c8f668a6c7241416f6d6141d0b0529bd63dd1e08a9c1f4dc9ee0d5f13e4703", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "0c0e0e7d1ef996205053c9c6ad1dfd9e2aa5f31fd6d4ec49e85b75ae11c6774d", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "f7490a446eb68edbf0c68f8c4614393a1312ddd39346f47f52f2bf2fcfd879ee", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "dd05ce19c2de43995699d2ac21af3a3462f30effcb433a34a3959bf51bf4d0b5", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "f35b3a5cd9cd94839cffba73feeb71e9cb597ba503b0949bf56ae02e1f9d59e3", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "9c0876586959ecb56baed51556e3de57398e4e28c03bccc9c976d3ae5ec627ae", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "d21a3c016dbd1685d90c6162ad6b7e8e99af08c15d25a0b8ddfb221fa06ec573", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "f937ea714a6ac2408269ca7427e2dd9661afddbb69033738b4248f4a3b81dcbd", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "81a494fca4969db43908617486d3560a54700e2cbc3d127c2ab660e7f649ac9d", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "64d470058150efde0ecebf2a67988600eb6cdb09e0c7c655001aa61a350e9697", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "79c182c14994d29f5aa5502171fb0c9da3f45cd39e014137c51dbbe2e75ec841", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "b18e0f1c1e7999d28c6e7e32aa7ac5f82141cb0f77c8d31ad873e057c9ec0788", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "8e3120a696515cea598e8e50300298978b98960febcc4af62e5d05ba66a286cf", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "a01f18f572f5ade11d3da309c6ca1f7786750753329c354eafd3f3531fbf5d71", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e1ce17414e65ba12c6a49d18149cf61d2b84d89a50e32df41a67a8a409f1816a", "target_hash": "7bd0fbfab234978272234861633bc6e883effc279b291558147e79faa7478e95", "section_hashes": ["8092d72df715"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -85762,7 +86494,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85774,7 +86506,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85786,7 +86518,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85798,7 +86530,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85810,7 +86542,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85822,7 +86554,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85834,7 +86566,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85846,7 +86578,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85858,7 +86590,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85870,7 +86602,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85882,7 +86614,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85894,7 +86626,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85906,7 +86638,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85918,7 +86650,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85930,7 +86662,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85942,7 +86674,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85954,7 +86686,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85966,7 +86698,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85978,7 +86710,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -85990,7 +86722,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86002,7 +86734,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86014,7 +86746,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86026,7 +86758,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86038,7 +86770,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86050,7 +86782,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86062,7 +86794,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86074,7 +86806,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86086,7 +86818,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86098,7 +86830,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86110,7 +86842,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86122,7 +86854,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86134,7 +86866,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86146,7 +86878,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86158,7 +86890,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86170,7 +86902,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86182,7 +86914,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86194,7 +86926,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86206,7 +86938,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86218,7 +86950,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86230,7 +86962,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86242,7 +86974,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86254,7 +86986,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86266,7 +86998,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86278,7 +87010,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86290,7 +87022,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86302,7 +87034,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86314,7 +87046,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86326,7 +87058,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86338,7 +87070,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86350,7 +87082,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86362,7 +87094,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86374,7 +87106,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86386,7 +87118,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86398,7 +87130,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86410,7 +87142,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86422,7 +87154,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86434,7 +87166,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86446,7 +87178,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86458,7 +87190,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86470,7 +87202,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86482,7 +87214,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86494,7 +87226,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86506,7 +87238,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86518,7 +87250,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86530,7 +87262,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "c2e19e8fc37c85ff85c24c4d638066e86bcf1eb784b06a1cc52c4ad2b51c063c", @@ -86542,7 +87274,7 @@ "0e1c707b80db", "c0414f8ead81" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -86563,7 +87295,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86579,7 +87311,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86595,7 +87327,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86611,7 +87343,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86627,7 +87359,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86643,7 +87375,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86659,7 +87391,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86675,7 +87407,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86691,7 +87423,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86707,7 +87439,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86723,7 +87455,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86739,7 +87471,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86755,7 +87487,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86771,7 +87503,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86787,7 +87519,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86803,7 +87535,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86819,7 +87551,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86835,7 +87567,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86851,7 +87583,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86867,7 +87599,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86883,7 +87615,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86899,7 +87631,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86915,7 +87647,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86931,7 +87663,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86947,7 +87679,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86963,7 +87695,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86979,7 +87711,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -86995,7 +87727,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87011,7 +87743,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87027,7 +87759,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87043,7 +87775,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87059,7 +87791,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87075,7 +87807,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87091,7 +87823,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87107,7 +87839,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87123,7 +87855,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87139,7 +87871,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87155,7 +87887,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87171,7 +87903,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87187,7 +87919,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87203,7 +87935,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87219,7 +87951,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87235,7 +87967,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87251,7 +87983,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87267,7 +87999,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87283,7 +88015,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87299,7 +88031,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87315,7 +88047,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87331,7 +88063,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87347,7 +88079,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87363,7 +88095,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87379,7 +88111,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87395,7 +88127,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87411,7 +88143,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87427,7 +88159,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87443,7 +88175,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87459,7 +88191,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87475,7 +88207,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87491,7 +88223,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87507,7 +88239,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87523,7 +88255,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87539,7 +88271,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87555,7 +88287,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87571,7 +88303,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87587,7 +88319,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "c4baff7b3acbf3851df536092938b2d75b15c1ea374a7a8d55b8a7d08f72f775", @@ -87603,7 +88335,7 @@ "0368fb6ed20e", "6d1c856e73a1" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -87631,7 +88363,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87654,7 +88386,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87677,7 +88409,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87700,7 +88432,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87723,7 +88455,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87746,7 +88478,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87769,7 +88501,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87792,7 +88524,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87815,7 +88547,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87838,7 +88570,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87861,7 +88593,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87884,7 +88616,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87907,7 +88639,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87930,7 +88662,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87953,7 +88685,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87976,7 +88708,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -87999,7 +88731,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88022,7 +88754,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88045,7 +88777,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88068,7 +88800,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88091,7 +88823,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88114,7 +88846,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88137,7 +88869,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88160,7 +88892,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88183,7 +88915,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88206,7 +88938,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88229,7 +88961,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88252,7 +88984,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88275,7 +89007,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88298,7 +89030,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88321,7 +89053,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88344,7 +89076,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88367,7 +89099,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88390,7 +89122,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88413,7 +89145,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88436,7 +89168,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88459,7 +89191,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88482,7 +89214,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88505,7 +89237,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88528,7 +89260,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88551,7 +89283,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88574,7 +89306,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88597,7 +89329,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88620,7 +89352,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88643,7 +89375,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88666,7 +89398,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88689,7 +89421,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88712,7 +89444,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88735,7 +89467,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88758,7 +89490,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88781,7 +89513,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88804,7 +89536,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88827,7 +89559,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88850,7 +89582,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88873,7 +89605,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88896,7 +89628,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88919,7 +89651,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88942,7 +89674,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88965,7 +89697,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -88988,7 +89720,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -89011,7 +89743,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -89034,7 +89766,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -89057,7 +89789,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -89080,7 +89812,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -89103,7 +89835,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "19a460c34885bacb6c2dc3494aba5da8f252b3c4bec0e51f773f8ea15e8fccc6", @@ -89126,7 +89858,7 @@ "1089ca6126f2", "86d5fe5203ea" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -89153,7 +89885,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89175,7 +89907,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89197,7 +89929,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89219,7 +89951,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89241,7 +89973,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89263,7 +89995,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89285,7 +90017,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89307,7 +90039,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89329,7 +90061,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89351,7 +90083,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89373,7 +90105,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89395,7 +90127,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89417,7 +90149,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89439,7 +90171,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89461,7 +90193,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89483,7 +90215,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89505,7 +90237,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89527,7 +90259,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89549,7 +90281,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89571,7 +90303,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89593,7 +90325,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89615,7 +90347,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89637,7 +90369,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89659,7 +90391,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89681,7 +90413,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89703,7 +90435,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89725,7 +90457,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89747,7 +90479,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89769,7 +90501,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89791,7 +90523,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89813,7 +90545,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89835,7 +90567,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89857,7 +90589,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89879,7 +90611,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89901,7 +90633,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89923,7 +90655,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89945,7 +90677,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89967,7 +90699,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -89989,7 +90721,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90011,7 +90743,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90033,7 +90765,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90055,7 +90787,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90077,7 +90809,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90099,7 +90831,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90121,7 +90853,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90143,7 +90875,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90165,7 +90897,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90187,7 +90919,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90209,7 +90941,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90231,7 +90963,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90253,7 +90985,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90275,7 +91007,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90297,7 +91029,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90319,7 +91051,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90341,7 +91073,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90363,7 +91095,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90385,7 +91117,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90407,7 +91139,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90429,7 +91161,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90451,7 +91183,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90473,7 +91205,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90495,7 +91227,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90517,7 +91249,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90539,7 +91271,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90561,7 +91293,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "bea4a7166194e8ed25e75d91deb2cff7f6e370abad1265258b60ffdcb193980a", @@ -90583,7 +91315,7 @@ "c7bc1f48d98a", "9acad70ca7b7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -90593,7 +91325,7 @@ "pl": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", "target_hash": "d060915ce0cbb2842411aae6556f4c8e9fde60e8cec8600d003422bd7d1f93e8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90607,7 +91339,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90621,7 +91353,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90635,7 +91367,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90649,7 +91381,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90663,7 +91395,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90677,7 +91409,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90691,7 +91423,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90705,7 +91437,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90719,7 +91451,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90733,7 +91465,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90747,7 +91479,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90761,7 +91493,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90775,7 +91507,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90789,7 +91521,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90803,7 +91535,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90817,7 +91549,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90831,7 +91563,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90845,7 +91577,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90859,7 +91591,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90873,7 +91605,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90887,7 +91619,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90901,7 +91633,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90915,7 +91647,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90929,7 +91661,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90943,7 +91675,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90957,7 +91689,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90971,7 +91703,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90985,7 +91717,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -90999,7 +91731,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91013,7 +91745,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91027,7 +91759,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91041,7 +91773,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91055,7 +91787,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91069,7 +91801,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91083,7 +91815,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91097,7 +91829,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91111,7 +91843,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91125,7 +91857,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91139,7 +91871,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91153,7 +91885,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91167,7 +91899,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91181,7 +91913,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91195,7 +91927,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91209,7 +91941,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91223,7 +91955,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91237,7 +91969,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91251,7 +91983,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91265,7 +91997,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91279,7 +92011,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91293,7 +92025,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91307,7 +92039,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91321,7 +92053,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91335,7 +92067,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91349,7 +92081,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91363,7 +92095,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91377,7 +92109,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91391,7 +92123,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91405,7 +92137,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91419,7 +92151,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91433,7 +92165,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91447,7 +92179,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91461,7 +92193,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91475,7 +92207,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91489,7 +92221,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0a1423feb85f8acd9debac07f716b65e06eaef8b222038d90d12b9823fe19c94", @@ -91503,7 +92235,7 @@ "010e6473d4ca", "2d8c1c27b184" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -91514,397 +92246,397 @@ "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "0ed07ba959dfe141e175af7c343ab2cc3927247383629aff0a1910fe7e04b558", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "74e59bf6db2cd4f33f743b260ba8b969ebd2e1b1de843ace7945dd264a3bd6c4", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "443725cf254c1e08e94e719c663119c742422809c6e433fdd8c808681e4b8b8c", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "5bdef00cec995a9619a7e57c7526e03926470b6b53c91196a9325352b69679c6", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "dd9d2f265f3cad7dc56f35e8c4eb1d226eb58ae8e19ad9de3c63727f333e6a29", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "2f84ab8814d1d3b9b4da36120c3af237a5cc62b90b1574eeca6426345963fb12", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "28cbe22340187c42e5f2d222d8eff27538a5de261bfcecc12454c5654358d55e", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "85dacdc0216b4311806792644f12d1c312bc76cb2cacdf4989264c4cffb73969", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "f5d1358f14a7672110e166b474382d84f68c784dc773f4498a8c217eaf75beae", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "fe8d43ab70dfd35ff8cafb385cc1265ed8eb0984b4645f85a13918359c642e18", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "2084fc814f3429d75993d9e1ee897a759ae222872aef38b22e5bbe359f7f8609", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "33862314683d0d4fa392ff8e0b8c76eacb1a3ef08e575daae030a76938aa3ca2", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "07997b94a09edd07ab69a25597e4f818f03ba8c3a0f54135ed4dd956e2397722", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "991a4ae2818a5c51a0bea5d9101a4658f40dacec57c421ef5fea0c80d1f89a06", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "7941b72842e0d2768bb758fa9e8a3f2bd7bff67d80f016b288dbd51fb5d5b57e", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "546c4881a87775fac26126e7aef42b435a7481b760d247be2f8ad7a73dbc1ce0", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "749d2224c816697ca85ef99a42dbd8a0cde8b48caf31d7551310013b56d40b7f", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "eab5868362c13541c257c0dd688e12f684ec40fcdb891d7128b56f1c3ad579ea", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "6f9602fe64c427ef4fc1aee6555d2190b94d3110a79d4900a8ae06d6d206adc5", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "b7106a0192095c2fcad19869af9ebc069db8efab7a02f941d1b72a2b3bad6ffb", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "101aa3f5adaed321c5e4cf5fffb8f1d2c773e35cb17e54c5c606a80d7638a482", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "01f080efd05e01cad1b818bc118352a3ab00f0fada169bb25da567dc9e031b73", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "22b2aa565ecda6d83dbd25a72a0ff7d3426593266359eba18afd568252db2426", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "07e59e0c2342cfad8f8a197555d5cdbb372d2f0a692d512864ea56f6d05f8405", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "b15d710d87cd1a88ef4b507b38ea55d677158c661e44451cc0a7d3aab6a42fc3", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "9bdf30fafaa85d1cc0255873480cbc739e9fb127c240ca1da3841052f54989f5", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "a573d99c1c6594683e000d5a7201125774d998ba38b51a6b3220d724fb8f198a", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "eadb6d2e8875e08721d4e18608a0f10946d614af09e6f7f562a981caf85a247f", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "654b6b6f3743f7adc78074dd6f7cfe72d6ea1849bfbab76afd25a1a1c015ec53", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "f75bcb0a7b75d26eab5282494c48ddd9162aa8169783afbfa7ecc44fc3a48699", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "16711329d51a823c289f8747ccaf0194c5f6f9460c28d2dc4818c0b985cc374c", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "4f3307ca0f4f9d6424946cce9e4b423907f1f0bf5f93e57d83e17f24ae3d56df", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "223561743d521d728cbf2ef645a93c7acf03e174382166b91c1128ab0ae61390", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "74b245f545c9bee2f26af3c8031afb09d44f6060463e462a3863357f16617a6a", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "670c8c08559d9ef82d7748c66dd33d4a0601c5550b45932aa5b09791ed5a4fb9", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "473ff28be674333fd7c922bbf915562ccb9b2c33d439062159856e678b290f65", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "b812690d930df775b90945927e970c196212c963fcdd578e55064d5ff44c6d4f", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "602a1f929ff3d50640cb9d4f4bcdb8b4078c7d8fb4245423f16d4bb7f7681ce8", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "86418a2e9a600058e33b2ce43d55caa57b55a9d4ea807cc15c99bf9387dafe0b", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "171ed3ed81707a1eeb02b1ca293ec5409b00a7a7193f8c16037d0ae41b0dc4a8", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "648f47eb5df98b7b0f91b0ce2d1f37599fc5310aeacea1274f30b50284dbe9af", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "503db5b38ad64f2302eb610e63ef018e6bcc45504668097321ac686c88b2e049", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "10f1476a3d574700aef28acb9348dcac21a4a2c07e1964e8668039a4489073e6", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "30c166bcca6dba641e86ff331088615612353ac634eaae4bc82ff2a7616383d7", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "26006b29d51a335125006729b7fbee66f2ed684f1e1a0571536946640374a6f2", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "f44d5ef99ceb13a89da9581a71455f93904c1cba1deaeab4b35593cf16f2850b", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "120e9e2912019f0eb0717638b26ab56c4b135f28691c92f60e743e4a6e4cbce4", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "e0dd8c9dd373a74b0d8fa831d5890bc709a3b1bc23f8408d99dc9d2e66500332", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "f31d1298efddeb4ec9ba3c5742b7e4e7515deedc72d62e8dc53bd5ebe09b019a", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "472cb6008d09d737424b0a0c5389cb0b066479dcbec131664140cbe681a9f4d8", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "c45b427231a6b5c8ad611168c96a566890f6c17bf6dfbc85fa67b4c5ada17d29", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "e2c1bb3a378dc3810862c891ebe508278ff99495c521f66463049077fa1912cb", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "5b39d251441512b3349293a2c1bb6334708d9a4b2443b76e20a7a1f15e979804", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "fa2079aa5495570f229137b6da9ed17c94c04db0a5a2e127b9d5680b0b21a9df", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "28c2136e8c869c4e36761bbe7571f7b6e3a29dac431897e636fed28305477617", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "03626fbda51b797b32099690bf9da9bb55f466852e70ec2e4624227861ead616", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "0c3df306fbce27dc5719bfb1f631e17e26a38c1e049eeabb293978ac30e8d5e8", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "f665696dffa1b8b9c63865cf511163d3c29d48a740c9c2d1ef2e50356c91bae4", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "aa3cb546ccadfa004e19ee808040f0ee10341e5b3d19377d63fb30675c00be1e", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "f9858b7bf4f73b18a94a57bad3a3c4260c18d79ac102793b9a23546300f6161a", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "5e206d679119568cbe744565725ea6807f1d4ea3779c2702742468ef7710ed00", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "8ce8db52b8f34ff2c3bc495463ab08551ff90d6b88865fb70a14c041ba8a6ea0", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "c99823371547e3f0721f756dcc084fa90afb78c8b47f0d88068c899993c201d4", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "863f274685307dc246209bdfc6882887aa3f821f7c4ada1ce41e75e686fdff69", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "02ff9231b1e464246407d97d1d5e174de8ca66f01ec5d32b1c347370d1038e8f", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "c29927e069170dbbce4193657763478acc9df1a6cca967a10dfc92a0f9cde721", "target_hash": "5f7c3c0e8942ac6a9ae24827d068d31100fdbb3af54209bfd71702fda10f0bf4", "section_hashes": ["0ad9c748c800", "3fd8f9692360", "0a14fa51418e", "8c083bf10fb1"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -91931,7 +92663,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -91953,7 +92685,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -91975,7 +92707,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -91997,7 +92729,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92019,7 +92751,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92041,7 +92773,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92063,7 +92795,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92085,7 +92817,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92107,7 +92839,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92129,7 +92861,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92151,7 +92883,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92173,7 +92905,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92195,7 +92927,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92217,7 +92949,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92239,7 +92971,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92261,7 +92993,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92283,7 +93015,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92305,7 +93037,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92327,7 +93059,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92349,7 +93081,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92371,7 +93103,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92393,7 +93125,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92415,7 +93147,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92437,7 +93169,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92459,7 +93191,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92481,7 +93213,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92503,7 +93235,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92525,7 +93257,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92547,7 +93279,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92569,7 +93301,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92591,7 +93323,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92613,7 +93345,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92635,7 +93367,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92657,7 +93389,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92679,7 +93411,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92701,7 +93433,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92723,7 +93455,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92745,7 +93477,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92767,7 +93499,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92789,7 +93521,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92811,7 +93543,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92833,7 +93565,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92855,7 +93587,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92877,7 +93609,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92899,7 +93631,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92921,7 +93653,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92943,7 +93675,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92965,7 +93697,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -92987,7 +93719,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93009,7 +93741,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93031,7 +93763,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93053,7 +93785,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93075,7 +93807,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93097,7 +93829,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93119,7 +93851,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93141,7 +93873,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93163,7 +93895,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93185,7 +93917,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93207,7 +93939,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93229,7 +93961,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93251,7 +93983,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93273,7 +94005,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93295,7 +94027,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93317,7 +94049,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93339,7 +94071,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "a79837793ac88b1cc25125995f9d33e98a69355b42f704e4dd95ed06efda1dee", @@ -93361,7 +94093,7 @@ "77e16a35c8f1", "a36d04952ace" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -93391,7 +94123,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93416,7 +94148,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93441,7 +94173,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93466,7 +94198,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93491,7 +94223,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93516,7 +94248,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93541,7 +94273,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93566,7 +94298,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93591,7 +94323,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93616,7 +94348,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93641,7 +94373,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93666,7 +94398,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93691,7 +94423,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93716,7 +94448,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93741,7 +94473,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93766,7 +94498,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93791,7 +94523,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93816,7 +94548,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93841,7 +94573,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93866,7 +94598,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93891,7 +94623,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93916,7 +94648,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93941,7 +94673,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93966,7 +94698,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -93991,7 +94723,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94016,7 +94748,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94041,7 +94773,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94066,7 +94798,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94091,7 +94823,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94116,7 +94848,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94141,7 +94873,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94166,7 +94898,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94191,7 +94923,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94216,7 +94948,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94241,7 +94973,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94266,7 +94998,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94291,7 +95023,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94316,7 +95048,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94341,7 +95073,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94366,7 +95098,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94391,7 +95123,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94416,7 +95148,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94441,7 +95173,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94466,7 +95198,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94491,7 +95223,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94516,7 +95248,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94541,7 +95273,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94566,7 +95298,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94591,7 +95323,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94616,7 +95348,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94641,7 +95373,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94666,7 +95398,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94691,7 +95423,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94716,7 +95448,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94741,7 +95473,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94766,7 +95498,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94791,7 +95523,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94816,7 +95548,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94841,7 +95573,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94866,7 +95598,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94891,7 +95623,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94916,7 +95648,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94941,7 +95673,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94966,7 +95698,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -94991,7 +95723,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "1fa535ab3c9dbd5324ad8de7f4f59e91c56712b94817eccea5025efd7a587e9d", @@ -95016,7 +95748,7 @@ "2cb520d2706e", "494f80016552" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -95026,7 +95758,7 @@ "pl": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", "target_hash": "f95ae3cb1c27edeb3d232919433b4f0e44c863f46e3ced1e52a9f3da52f30bde", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95041,7 +95773,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95056,7 +95788,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95071,7 +95803,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95086,7 +95818,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95101,7 +95833,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95116,7 +95848,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95131,7 +95863,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95146,7 +95878,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95161,7 +95893,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95176,7 +95908,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95191,7 +95923,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95206,7 +95938,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95221,7 +95953,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95236,7 +95968,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95251,7 +95983,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95266,7 +95998,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95281,7 +96013,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95296,7 +96028,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95311,7 +96043,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95326,7 +96058,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95341,7 +96073,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95356,7 +96088,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95371,7 +96103,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95386,7 +96118,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95401,7 +96133,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95416,7 +96148,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95431,7 +96163,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95446,7 +96178,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95461,7 +96193,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95476,7 +96208,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95491,7 +96223,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95506,7 +96238,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95521,7 +96253,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95536,7 +96268,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95551,7 +96283,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95566,7 +96298,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95581,7 +96313,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95596,7 +96328,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95611,7 +96343,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95626,7 +96358,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95641,7 +96373,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95656,7 +96388,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95671,7 +96403,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95686,7 +96418,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95701,7 +96433,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95716,7 +96448,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95731,7 +96463,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95746,7 +96478,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95761,7 +96493,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95776,7 +96508,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95791,7 +96523,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95806,7 +96538,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95821,7 +96553,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95836,7 +96568,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95851,7 +96583,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95866,7 +96598,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95881,7 +96613,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95896,7 +96628,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95911,7 +96643,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95926,7 +96658,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95941,7 +96673,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95956,7 +96688,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95971,7 +96703,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -95986,7 +96718,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e7d30fb4d962f260cb06e265b9db7a8526042a582cd8887d20eca7aa4e0a3045", @@ -96001,7 +96733,7 @@ "4b81ad79a528", "240026694b06" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -96019,7 +96751,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96032,7 +96764,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96045,7 +96777,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96058,7 +96790,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96071,7 +96803,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96084,7 +96816,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96097,7 +96829,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96110,7 +96842,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96123,7 +96855,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96136,7 +96868,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96149,7 +96881,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96162,7 +96894,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96175,7 +96907,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96188,7 +96920,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96201,7 +96933,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96214,7 +96946,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96227,7 +96959,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96240,7 +96972,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96253,7 +96985,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96266,7 +96998,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96279,7 +97011,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96292,7 +97024,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96305,7 +97037,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96318,7 +97050,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96331,7 +97063,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96344,7 +97076,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96357,7 +97089,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96370,7 +97102,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96383,7 +97115,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96396,7 +97128,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96409,7 +97141,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96422,7 +97154,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96435,7 +97167,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96448,7 +97180,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96461,7 +97193,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96474,7 +97206,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96487,7 +97219,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96500,7 +97232,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96513,7 +97245,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96526,7 +97258,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96539,7 +97271,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96552,7 +97284,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96565,7 +97297,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96578,7 +97310,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96591,7 +97323,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96604,7 +97336,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96617,7 +97349,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96630,7 +97362,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96643,7 +97375,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96656,7 +97388,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96669,7 +97401,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96682,7 +97414,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96695,7 +97427,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96708,7 +97440,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96721,7 +97453,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96734,7 +97466,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96747,7 +97479,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96760,7 +97492,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96773,7 +97505,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96786,7 +97518,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96799,7 +97531,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96812,7 +97544,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96825,7 +97557,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96838,7 +97570,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96851,7 +97583,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "f1713be4173f2fd7dd7c19f0e67b57f1018018580fb48a77b53ed01ca630eb7c", @@ -96864,7 +97596,7 @@ "70ff5c36b3c8", "74291d61a2d9" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -96886,7 +97618,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -96903,7 +97635,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -96920,7 +97652,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -96937,7 +97669,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -96954,7 +97686,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -96971,7 +97703,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -96988,7 +97720,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97005,7 +97737,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97022,7 +97754,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97039,7 +97771,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97056,7 +97788,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97073,7 +97805,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97090,7 +97822,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97107,7 +97839,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97124,7 +97856,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97141,7 +97873,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97158,7 +97890,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97175,7 +97907,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97192,7 +97924,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97209,7 +97941,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97226,7 +97958,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97243,7 +97975,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97260,7 +97992,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97277,7 +98009,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97294,7 +98026,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97311,7 +98043,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97328,7 +98060,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97345,7 +98077,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97362,7 +98094,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97379,7 +98111,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97396,7 +98128,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97413,7 +98145,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97430,7 +98162,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97447,7 +98179,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97464,7 +98196,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97481,7 +98213,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97498,7 +98230,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97515,7 +98247,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97532,7 +98264,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97549,7 +98281,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97566,7 +98298,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97583,7 +98315,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97600,7 +98332,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97617,7 +98349,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97634,7 +98366,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97651,7 +98383,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97668,7 +98400,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97685,7 +98417,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97702,7 +98434,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97719,7 +98451,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97736,7 +98468,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97753,7 +98485,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97770,7 +98502,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97787,7 +98519,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97804,7 +98536,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97821,7 +98553,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97838,7 +98570,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97855,7 +98587,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97872,7 +98604,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97889,7 +98621,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97906,7 +98638,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97923,7 +98655,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97940,7 +98672,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97957,7 +98689,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97974,7 +98706,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "52ade6827c7ee5ba9b62cf287cea4e6718ef714bea1cfd1a40b8820ae29e1e60", @@ -97991,7 +98723,7 @@ "e6a2ec2f3b4c", "426c570b8bb4" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -98001,7 +98733,7 @@ "pl": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", "target_hash": "96421fad9e1945697b1a26f35952e17aa56db6cc3932bbf9d86006c4b734642a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98015,7 +98747,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98029,7 +98761,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98043,7 +98775,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98057,7 +98789,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98071,7 +98803,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98085,7 +98817,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98099,7 +98831,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98113,7 +98845,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98127,7 +98859,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98141,7 +98873,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98155,7 +98887,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98169,7 +98901,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98183,7 +98915,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98197,7 +98929,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98211,7 +98943,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98225,7 +98957,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98239,7 +98971,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98253,7 +98985,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98267,7 +98999,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98281,7 +99013,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98295,7 +99027,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98309,7 +99041,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98323,7 +99055,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98337,7 +99069,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98351,7 +99083,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98365,7 +99097,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98379,7 +99111,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98393,7 +99125,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98407,7 +99139,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98421,7 +99153,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98435,7 +99167,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98449,7 +99181,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98463,7 +99195,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98477,7 +99209,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98491,7 +99223,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98505,7 +99237,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98519,7 +99251,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98533,7 +99265,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98547,7 +99279,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98561,7 +99293,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98575,7 +99307,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98589,7 +99321,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98603,7 +99335,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98617,7 +99349,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98631,7 +99363,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98645,7 +99377,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98659,7 +99391,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98673,7 +99405,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98687,7 +99419,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98701,7 +99433,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98715,7 +99447,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98729,7 +99461,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98743,7 +99475,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98757,7 +99489,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98771,7 +99503,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98785,7 +99517,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98799,7 +99531,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98813,7 +99545,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98827,7 +99559,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98841,7 +99573,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98855,7 +99587,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98869,7 +99601,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98883,7 +99615,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98897,7 +99629,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "2e9eb65469c90ff48e0d27c46c3346216372c63b130266a529a5ab0c11b409cd", @@ -98911,7 +99643,7 @@ "eafa6057fce9", "c48c806ad856" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -98922,397 +99654,397 @@ "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "25cf06ba31a5130725bcf222b63d5df201e2086300923a12967f5a416dcf04d7", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "1897c8a85f7564a12ae692426ee35bd6ef07b00191b29f515570015bf4ef36df", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "d729f35069e0d33f5d0a235ef6fc7c748c44c7cc07f018e7afcf4e51e2b884d0", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "09cc46f8d5a164fc9b03905bb7b97e8504221a9d65a405336e0c1e7c653efa30", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "50268a1ccac628ee235a77ff025fa736bd34beef4670702885d686e69d39ab88", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "9be9ef48dd954f5365ac247d609f81fca2b5d27f0140277de4aaa0a3f4074618", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "6898536b1ed40d80b5631554b9601c7de05eb0dbbdad4a2559171b7f98cf4b7e", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "e7492839477a63418538be93b33182f6104172b9bce61b1baec838549d0c939a", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "32641ce05dd14615eb5c592075ca287cf4204276aaa31a32ed863edb4030e6fa", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "b257a6ad89dbe60d114020f0840dedb20ffbdc1854590e8e9c58edeff036b807", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "ab79d4f65d3acfdde2fe4b7866db8c2d3ce0edfa6a7a11da91e04fa4bbcf13c6", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "1cffc2678cf27e14f2d76b004a7855047132cab60686e0cf13e9e12c3c59fe54", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "a157e6b7bfe66760162cf9dfcdddb0822363023abffbe3ca76eff003f468532b", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "20a5f7d4545268b2674bd41824d73b056e69a9c18aaf98c9b8009440e489eece", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "f6e19f6cb9d453519dd2be11aa0a133fbd5c8014f9b2b3a0a814dc1170e632ed", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "9110daf9f49944fd25931f14dc77da00355e2410e3847b78762ec40c927bf8fc", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "265e87ab90a4ba72a094a899896d0b25a48d29c7452d00fa345c155680921e61", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "d22e594286dfafa589c42318b2c795cef9ad3e1ef0f219a1740f5320c092b528", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "e6a706f68d87366c1c464d8e992c0545ed1e3f341aa631c25c4f3ae4ce8aa7df", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "ffa309a44a2ff7b017e2250acb63d358b17e65bd5b62d49513f6d89d37a2ef8a", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "7f65458e5ed738e4ac3f76d35a1dd23eb72486057aeef4d13ec29480056bdba2", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "de1e52ad55c206538b5318adda1be2d443d837b8c2f066d3bcdae36c39e1256d", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "7c244bd3b7d3942049b0594b7f2bdfbf24183d3ce89d68d6036030d6c85ef529", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "8b194eb95d1e8ad58ee407ab8ef74c3692f690855a18fc64cbc0818e528106d4", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "7609e80947cc9024d80e96d26d1285c0615db781d21e475e487d0992ac8f7e89", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "bb0162863d42462b7f549d6e91c6afad8c1586fa90c63cfa5ed4d7349e7b627c", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "ea3ab285768fc56cdd206e7e443506b1f5db3a53fa07129c2df82b5644999307", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "094d3122f7cae99664fc9a0704e2b27d0506205ebee5a023f2fe588dde089f2f", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "99c226b577aee7c6e342af9065cf27d58bed3612a1d73e5f0c3fa79673febdfa", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "a4f7871605a32ba02adc70b2e49a316aa031a871d0f7f237855b5962a761b5d8", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "fb2e7fdaa1820f96da44318782d49ee1f5d27e30e542862d455e3507beb03092", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "fe8ec553bab8925664c084d3a4c325b4a4e931d5c842ab39d14da460c46ca35f", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "a67151aea331a2277f573b73dbe5d7bc316e99845e31e04c00695bf04a4a89d5", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "cc9ee7f4498b0032e17e11f9ce343fd887ca24e10995e7369aa6f42d137260ab", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "03670af74fb62be462d489976c7650f8ce1894cf3d8fe3cc99bd5ace9fce192a", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "0fff70e1e0a7605c4cefb3f67af2b8a950671b9334dfc3066efb244acdda14c7", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "7df8db6f96e63cb0b6f404596e1019246ac8ab3b5dfd3d044c3aab292e818a71", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "1dbadb8c25eb40ac15c48a83de03b92b6ab2f099eb92edf92abe591d31f072a8", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "5a54c463b1719c0c3c3f731960003f6972c2b77ea457b86737f38cda7afe04b2", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "edb3bc81085338bec4942e5e7cccc3794ca168443dfcc99907060da855b31346", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "02cb86d73a481b3bb212a25b81094d33fdbcefc2f07a9d31332f9351c072b554", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "993e8d88f12767823356ea2b9a0c4dfdf0160d4de9c283e76cb08fa4c4ceac68", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "0919fc368e1091781e69f53cd1f21005790778f43d31ca4a1e5a2588015cf7ee", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "cc4e0a842de5e71cd07b5a04b5ff37a1580407dd427bc1728d0a26a0d4438143", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "9cbce8ceebc8084481fdb7fbfc823347a6d3fcf05a06f85fe7a8711c01e6a5a7", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "450958351e525034bac85d23544515ba68bb103b3da3f510fbb83832db487f50", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "64460da858ca7e5aed44339b422db5392819d6861b2437abb7485659965dd88d", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "e18a837a23e9637d6861917bd053908d40e691ee103c35733f0f98f0a1748be5", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "550c6f7cf0cff1e117becfd8f7952db34cdda4fe38a995d66c5de7d73f6aad76", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "2c9185a2579c02e3e51d699edc756992a9a08f13080e8bcb63a4af2d7e90c954", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "9474c5a04a793af325050665341b2ddbd22877602a5a58873b8226b9ff3940b7", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "ae05b0c90da3c5caa8adb3c85cece8012f583103807479a36ca4f78d18ded9af", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "b128980039665d5845af8909ca83ca4c5367da516fcc4e4629f811eed778281e", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "a00be16bc79b6fe8e2113c550d64b791db1f636ea320f8015ce446eb782a6571", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "a42ee8e86c50afc79f5cb5690255c7ce6c7e062580ebaf345f3ec55e85a4d0d2", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "1ccff307b4aad636dd76a627d31494a0b81e71b82c444cda716ff3414110317d", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "be173ce253128e7395b847819aa8f1a1ddf62e0b74b16d71dbd72da0db84b594", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "5fd85607af4d2d1a9491ea07bb6652f94247b25ebc5aec18370e6c042de601cb", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "89f138a40a62362f44d3950b2064bf3c8079074afeebafaed2861060012a8fb8", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "6fec7eaa7812a05b19d2effd4a6139cb1d034f0662b41393bbb2a0dd7bf14302", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "f178c9f635ae909ad626b855dd3dd0099db71035649edb27934649c08bf64ac9", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "148210f2eee6f7431b6b9fe407bd005284e218c89717c8534482b94343cc0586", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "ab77254374e36b043356e40e02cb7d4922d56fb107c566b11965e7b88867f86e", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "d479e5215d98bd56b0313467eb2d0d0e54928462d02fa2e1d8d121729d689514", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "8f1b0c10bbcfe4bbbf305f1ff9b4f96557a891158bef81d3e7d5bc2a72ed514e", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ffdb7f8695298a78f16bfc22cdb81311329d987d3f6ed657e1992a7ccb280b18", "target_hash": "58d84fb102753fdf7016a80a9d7c14a89face2a1b013331e6ecacde31763b0d9", "section_hashes": ["36cf94a9caea", "bdf253043a44", "13f84529f9da", "72df22656954"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -99322,7 +100054,7 @@ "pl": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", "target_hash": "532b407095cc885286c4eef6ed7edc175602f523409f4bce067c4cc1537cf8cf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99336,7 +100068,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99350,7 +100082,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99364,7 +100096,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99378,7 +100110,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99392,7 +100124,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99406,7 +100138,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99420,7 +100152,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99434,7 +100166,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99448,7 +100180,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99462,7 +100194,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99476,7 +100208,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99490,7 +100222,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99504,7 +100236,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99518,7 +100250,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99532,7 +100264,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99546,7 +100278,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99560,7 +100292,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99574,7 +100306,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99588,7 +100320,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99602,7 +100334,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99616,7 +100348,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99630,7 +100362,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99644,7 +100376,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99658,7 +100390,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99672,7 +100404,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99686,7 +100418,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99700,7 +100432,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99714,7 +100446,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99728,7 +100460,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99742,7 +100474,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99756,7 +100488,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99770,7 +100502,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99784,7 +100516,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99798,7 +100530,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99812,7 +100544,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99826,7 +100558,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99840,7 +100572,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99854,7 +100586,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99868,7 +100600,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99882,7 +100614,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99896,7 +100628,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99910,7 +100642,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99924,7 +100656,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99938,7 +100670,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99952,7 +100684,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99966,7 +100698,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99980,7 +100712,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -99994,7 +100726,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100008,7 +100740,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100022,7 +100754,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100036,7 +100768,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100050,7 +100782,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100064,7 +100796,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100078,7 +100810,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100092,7 +100824,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100106,7 +100838,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100120,7 +100852,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100134,7 +100866,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100148,7 +100880,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100162,7 +100894,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100176,7 +100908,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100190,7 +100922,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100204,7 +100936,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100218,7 +100950,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "059bcbb3e8bda92378de7cf56ad50f469e9ef6ddf78e014658298a844cf4be78", @@ -100232,7 +100964,7 @@ "ec8c41d7eaef", "6e56c55f0eaf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -100254,7 +100986,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100271,7 +101003,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100288,7 +101020,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100305,7 +101037,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100322,7 +101054,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100339,7 +101071,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100356,7 +101088,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100373,7 +101105,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100390,7 +101122,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100407,7 +101139,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100424,7 +101156,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100441,7 +101173,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100458,7 +101190,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100475,7 +101207,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100492,7 +101224,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100509,7 +101241,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100526,7 +101258,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100543,7 +101275,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100560,7 +101292,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100577,7 +101309,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100594,7 +101326,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100611,7 +101343,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100628,7 +101360,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100645,7 +101377,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100662,7 +101394,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100679,7 +101411,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100696,7 +101428,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100713,7 +101445,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100730,7 +101462,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100747,7 +101479,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100764,7 +101496,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100781,7 +101513,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100798,7 +101530,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100815,7 +101547,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100832,7 +101564,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100849,7 +101581,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100866,7 +101598,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100883,7 +101615,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100900,7 +101632,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100917,7 +101649,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100934,7 +101666,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100951,7 +101683,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100968,7 +101700,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -100985,7 +101717,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101002,7 +101734,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101019,7 +101751,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101036,7 +101768,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101053,7 +101785,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101070,7 +101802,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101087,7 +101819,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101104,7 +101836,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101121,7 +101853,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101138,7 +101870,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101155,7 +101887,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101172,7 +101904,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101189,7 +101921,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101206,7 +101938,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101223,7 +101955,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101240,7 +101972,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101257,7 +101989,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101274,7 +102006,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101291,7 +102023,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101308,7 +102040,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101325,7 +102057,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101342,7 +102074,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "74663d79665a1ad8ac2d8163f5ffcc6fb0eb932f659c0b3e370afa2a2841005b", @@ -101359,7 +102091,7 @@ "5d44786488ac", "d2d983469714" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -101369,247 +102101,247 @@ "ar": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "205db8b772ad2dcd546b4d87ae5531287437a984b0186f0ad3972677d9d011b3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "2ea9d1a669f1fe04eef13bf64b683f065876eca694264530b757327b273e4de0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "1f5864192650604bca3fe9f6009763cc22ee2d00c987a5c08a9462d1e5aea354", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "42018fbfcbe47bda974cb2a9c91cf94658d36c0b01c48d16200868229d79a3cf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "ff884013ee9885b4814f746727cd1721566e7d77247f6da6afc7baea03ba3984", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "cf010ea7402071ff88cacf07058f298d76b3927d724deb3593f883080a637b7e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "45078ba840c2e59c08055bd7eefed78ab5dd42c4fc769890ab446f6162f3d521", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "75015b795575249c592f3f9dd3c990e30527733788fa8bd7fdf072873c6c4656", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "6a194964330ded008707aa46d8d4b555c7c08c65739ac4c83642e643f89cc213", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "681aafb9d8bde78f7107a48f38b41dcd7a15182bd23aac92308d43d8be493246", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "2d7915cf49a0020a21d3b903e83f6834b80b880664739e2d9fa39c07b9f8fa32", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "128bbc3befbede81d06f5dda27f6f1f019c14ede7a38b093c3a84f09d6a92d09", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "707ea8a1a560a7c80aba503f17ed156736727d50a2bc9b7efe9649e9f46a3f80", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "23b7e440180fb6cd4c33422a378aa0c6afc29f832b19b22db3f57f04e9a00956", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "272283db92109b03f9ed53ac5700d0f3295c069a2af14d41c10c0d1b4fb36de0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "97f9946fac032c29546b6e4ef1c81f31758681d1a8439974a4d354494c96538c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "c2fdccd46416437d7d2066cd87cf621b4da38d6831430a5a4ca30336b7535481", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "519ce31c7e82f1b05ee505ee327f24de67a16d6e7f0dc44d07d7a085e9075744", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "8aba93c064a4c8f998f311d1b1e19adfd416033bef7b3907197a229de303cf62", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "1f55705c2daa172b7bb7e03d33fc716230bfb7a49501128674f5707dab49fc66", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "2e73338382e5add2aa407a05f55300a8b37ca1300ec0fbda718cc43f2d8a9deb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "20aac5973b7cc92d0721b3d2517a0200c8b7b7c7eef23501523d2bab1e2028df", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "ec1c57278a80095e3e927890cbad0993f7163783e2036061e7d3602b442971a0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "48fa526562c3853ea2c9d0cf53490987d2d5f72ec5574a4b87bc6bee572bd0fc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "4ff336eb00802e45035265bbbe19370ff828c9b7e41028d7d48f2ce540baa772", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "250aa5f075c9d9ebee5c9ce16d243730140d1035f73220d9373f9af2589be2e9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "f696874f0ab650ca0652ef1a5a927dfe189a5b55b06551c2952b8f129cc39c3c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "69567146f0ef127291f58e2b7f2c4844ccba7dd5c353235ac9f0c6d45d92388a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "8892caefafaa0c9a835ed527861f378f70d1c521e5a3567cfc3edb0e51fc4bd6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "2995ad54bd1a7babfd5acf281bbe6a8c7f69157bc7be04c3aba6c66ee6b0aa8d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "b19c59024d011b8ee970c636432839c4b6db0863d34a30842d2d32029ecbd154", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "30a2e68f341d3b69f758e028e4d43750a64a69a3b6a3e1bec4da40c5c375bed3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "a456daa6034e038f9c507b83c2c916b6b5324340c1a5f0acfa2d556ab85ef293", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "ce83dea85271d2c00103e4802057b90633154b82ee7838807d7565e44b187940", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "407286adc04d0bb53868745fc1a5dc2b188cc04283e8abe4929ff90f8d7984ed", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "ab8b433ec396ff2415a4949e48235ee7767fb1943fae67a9b02899666ff54c61", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "1dca7aca3cd7515220c4103249d2bb58a16e6c225bbd6e3a06376e5755a027e5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "68f9a6e53ba75fe542d96bcaf9fd13d51f77aa661f74009dd1c55e021cff73d8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "6659313f5738c3c2eaa9f2f48d62b8f185299bdbc00c92988bd96e105bea9e6e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "7a6475e4f99a442751d5c90cdd686bef67228e93202fea51c1dc78206b53079a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "6736efcbc87a4b69c0d804e20adf533ea23272f9380d31532e073687cd484be0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "359ed49efbaa29a9e4952ea4c4880c4fc5bcb98e6b60ec62c8b76694e66fadde", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "46afea60c71929c80a82f6377023501d12ddff74b61c777af6c488814aa80a07", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "5482c56ec49d94e80a3ee803b5e1bb06ca09090fdfeb7234d6f3f04bd660feae", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "a2032c8d5e0d98ddf145fe9dc3fb72f93517cd6391c04bf5ec2fe6c6470072b3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "9c3d51c6f5a974ac5853e28ebb7d9f1542b7903a68c97f0c75ce65ed12e9ef60", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "6f1567a5cd170fcc9f9cbfac60eb2dac8b6c24acbc5a667d41e6d89dd8972cc8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "73308b5cb579ff5d8029b7188790784ff616aaffb8980011ae51b1abd93b909b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "c733512d0721cb6102a2afb7921acea762011baca7b5220e701f6bb1a6f89f8a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", @@ -101627,87 +102359,87 @@ "9aa588261cf5", "f1150fc2035c" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "67942f6e73d529a6ca5abea5c17423dd6b09bc16a7c46511fdbf85f341c561e4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "31bdaa4e9fae8ac2b5b69d85b705adb72b44e71566b22d7d0a6f4434c3de2cd8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "3f6ddbe2a4de495e27bf64f2182559b32638d665271848a4260f67376c20c9f9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "e456b6ef447840ba10dce227972dff3ea569793b1537e32b8ba8dbaf6b2f1ac2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "54b232ac379e0251c73d247ad259c1cf2fe18c235efde3131455b36b30b3d281", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "09ce1ebc54ac2ac6d497587946d325ad2f77a37743d8df0523e11499c5b15e79", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "05d0e72d39196167e3c24ca1b1919c41a7376887c3dcb5904a9c5f5e5c50b1c0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "49905e7de44a33c5475b416cbf2e1d9f33a8ac8c13a850f33c3a9931189126ae", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "492876b2c3c8bf039a99e4ea8d4edddafd139e0988605f2aee379bf81a266979", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "3c186548685caa0cdfe5145ab6e5b544c3831a8f7bc0919f3d1d78f46774f588", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "35c328f58f7b7a13c4e6ab191cbd6c4b85d8a33ba250c06cef3143ddb38a9731", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "be0e31d43579f304c96a520e541bcd13cc95e0694f44f16bd504116331ccc0f9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "6a66446d17a174486920671d4332dac3d17ae3adf58a0367faf571594dcdd33f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "3bb4cf8a20316f9b0b4c91363dfa8043debf3e12b8f20661b6981aacda73c38b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "3bbe97c39332b56e90be7048349cdfefd3fb3ea9910183b7a287599eda561f66", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "c440b0ecb9c2dc60cb2bd321516a2218adad402708d26e6357e9c0d33567fe2b", "target_hash": "5556e54b011e4ba3928bf77300f8cab558b28aa613ca969c33c5abf090ba57aa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -101724,7 +102456,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101736,7 +102468,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101748,7 +102480,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101760,7 +102492,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101772,7 +102504,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101784,7 +102516,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101796,7 +102528,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101808,7 +102540,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101820,7 +102552,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101832,7 +102564,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101844,7 +102576,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101856,7 +102588,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101868,7 +102600,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101880,7 +102612,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101892,7 +102624,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101904,7 +102636,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101916,7 +102648,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101928,7 +102660,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101940,7 +102672,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101952,7 +102684,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101964,7 +102696,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101976,7 +102708,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -101988,7 +102720,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102000,7 +102732,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102012,7 +102744,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102024,7 +102756,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102036,7 +102768,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102048,7 +102780,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102060,7 +102792,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102072,7 +102804,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102084,7 +102816,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102096,7 +102828,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102108,7 +102840,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102120,7 +102852,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102132,7 +102864,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102144,7 +102876,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102156,7 +102888,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102168,7 +102900,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102180,7 +102912,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102192,7 +102924,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102204,7 +102936,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102216,7 +102948,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102228,7 +102960,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102240,7 +102972,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102252,7 +102984,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102264,7 +102996,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102276,7 +103008,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102288,7 +103020,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102300,7 +103032,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102312,7 +103044,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102324,7 +103056,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102336,7 +103068,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102348,7 +103080,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102360,7 +103092,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102372,7 +103104,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102384,7 +103116,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102396,7 +103128,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102408,7 +103140,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102420,7 +103152,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102432,7 +103164,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102444,7 +103176,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102456,7 +103188,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102468,7 +103200,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102480,7 +103212,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102492,7 +103224,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ea672d4b77b14e22e62b5485723062af6e1dbadb58e5172045df582a9ee1e0fd", @@ -102504,7 +103236,7 @@ "ba2ccf1b3b57", "777bc66520cd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -102515,397 +103247,397 @@ "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "a1c91c88c6c44d24d81ca94018534eae97a71b03e37d57af1fb9c119b2f219ab", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "d1e378203234c03c996fb0d98a3c2b9c5dedcc3c4b10481936b1621f5aba5744", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "a4ff761242e68cd7be4f212bfacc84f840dc90977d6437d98c1d46cacc10afed", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "0838a105c2df4cf40961f9f83243f852b46814f3d3f5a5864952804914dab975", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "69707dbc01505da1d6f440f1bd1323a45d6a91e3355757ae7832adee63a59dde", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "21cc075efd448b88d2a5ca8427cfd59a8eed0c86f32ff48b20c4e78161b44fd1", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "d3250b2e1bebf1935a47eaca7a55c50c1435ca40700c67e750b819762efca74b", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "e15827bbd1dd7572e8480a80f8c51157e8bd9b54e6400ea2045d1dfa4c13c1e5", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "d41fbb8e218e4524b030f989310cbae4424792fee675f25c09f63579fb4ad15d", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "66abf052549e85114a0da5308fef565b587510da03339c69ef4c77742e17af8b", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "a25f07d981869bcacbcda6084cce0810fe7a1889553f8bd5a49c441a06541853", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7a11c354d3d799cf233d4a388a63cb683ba6a0ba5a04a7b88d7206c423f07bf5", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "83a6adbdf1dcbb225c61ee439258189b1bf27d422cf6aafd3c50e420589c7abb", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "a62cae8f98487d698d7dfb7960720318e199d4f815942200984cf707100112de", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "0dcedd140b3c02ae78bbeda28b6d41256472d29ad2a806c86f5d76c4de2d0d82", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "ddbd3cce30a5ab9a33b30c20a62035302fb82be90c3b50149874d77eb2239811", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "548af64bcdc92b7e8319c35501f6dd1b0eea6fa1883759e5d8dea5badbddca20", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "014eb06745ee8ddac095e2f7179c94bc31f1896c614d5e132bba84bb3158bb92", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "dbce9bd718da7e43e849d8257cdc77a06cdc1d1e29b992f2c21903badd20ad7d", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "e09ef4ce02399f283968ec8574f7179e43d3c12c63bb19394a5cc4f14e895bdc", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "ba3021bfddcf5ecb28656698cc4866bdead78fad6d4aa9c81ea16e2b768cabaf", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "8cd299c208027952aa2d5ddea8eee33c825f16ed87e4bfe4744d7df9f5971d6b", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "e005925255f3417757ade206023c3ecbfb7ed04370eab3f0c8128c130871e8b5", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7c489a32f864ee8309e78c9e21402e72da47881e25cc8fb9fdeba3068e749e77", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "6534cf70a94c6355e20f4c9b00f5c10fa7239a418d24d6879a4580ba6bfbc9d2", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "2810a01c5dadad811ba889630ab585866c2907f6e6c4b11c0f290f782f439e34", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7b49c89945fcafd00d58d8bb309fd49cb041d912172d62f94a627713e5ed5766", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "23fc7c7d9a152a8e3de33d17a0ed1ea04a8b37ed69ba06b075720f4e09632748", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "fcfd3acd40110500bf3a13bee9a7324c163360b82112300c5c56298b7834523a", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "2f8d9e5b18c240ef5ec517a0df8b95e3bcaf2f6f84d47bc7ac4688f2d037e77c", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7a12f98e4466a2b1be07d496a8dc0ee3f3be53c911524ededcfe4ace43ff2723", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "e200248633d90ddfb74a3dec493b26bed6d78ed3fafb5fe854dfed20404e8751", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "90c45404c400377f775f84236038806e377efb2e562ff71b5ddb18ba150bd884", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "189d27ae78cd2cbfbfdb8b82a68ed6268d8265281327062be79de426cba21cd5", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "da81a766598967e9ff5324a5f31ffa1055d7b8f53d465b2d1226e23f903f00ca", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "8bf1665327b898b0f7fea51c248998d7202f3f6eb414dd022b495bfc06c28ba1", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7a38cf4c22d50ce1295c70c03e78716acebd362dcabeee3e357470f6a8ae8fef", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "3bfc26f098c71c966feeca4a7e0a0ca49e6bc101ff2bcc1fdbb48d272c403d1d", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "9b00f01a4d1eddab83a117b1173470e10a337a876f54b2e562fbf218cc1c1c68", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "33cc810208744d67942910664aee4d8a00ce5f7e653cefd95a482eb7b9cc6747", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "e2188636321fb6e59ba0498cdfb0c579534f14bcb2a25f430de71104bc230aab", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7c9f248398a58b2887425be48843b76a9f9473adbce906435560cf8d0cbb0a96", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "199f87f83df72068026872e67966ef3fcd6f749358c6d9ba22abda0ab401e515", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "da952f01704596680cf0586dba3d197411d9b908f13ced41bad74852a9936b2d", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "7ce654b1590ec608d84658880f962f720cdf3184debd721df2ca529b2a85903b", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "4162ec24fc07c432a886715be3febdf61317919a018612bec4b99372bb4b7323", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "8ed0ca75cfe3281a2f87e35964651507b377ea0603490d5f68f57151830258d2", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "b44f16ad251cbbf4eb9242c49dc02b7bb51c1d12ac4b2f5425ecff802443f0ce", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "c3a0d82799ae9e83d36a07b21ddc1434d02fbf3dd930bad5e7f2333789aa989e", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "05378fbab55f211c4bc5585d1cc694efd2a74732754bc763c784467b48606ad9", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "868af32dcd78fcf460f706420d7a6ad6eeb6a471c5c9fbb13ba44d4c98c0c9eb", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "0373d2dc5ca16dd33bbf52ef94ba9873a2f0b0e3b174dc56edf9a71f1a438da4", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "2c4eff2d4d32d2ac9106155f45e2bda7a9f1c3da93ff636b85dbf8868dfc0114", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "4247f79c7e0c65737b33c6e5eda15acfde00e59455d5593e924537875521d1e0", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "a6d70f71fb3e92a8e29f9302db01e6cdd48b50c2d97f0d2d75d967eb32ad7af3", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "1628a9128c807128c2370fe75aecb3adc7bc4fd066bb4ddf1c981502837c86a5", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "0b348f2735122ea96370f1642adf9c271031825a2b6d1ff1a0cf54ca1e836270", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "149577252eaca7c16f37fdf67b6eade45a911950d49e9b15c4ef4786261a2328", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "91db6f243ccac6387537a08239ab86709d71752b3fc7e9e6fa3d1e93c004d626", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "8ecfed2a37e47193db86150b65a2225f8debcd1155b55e0022ad3abedc493772", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "ce3f22fdd93afde61b0170225a2c791e16ce76623069135a1cdc66aa0d607e67", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "ec05a7c872a91d123181665c1a8ab81ec966a1be72310f111961c7363a6af504", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "b6f6f047da1efbb4cf0b117d7e47edb795e750719ef29e438386b6c46f46c143", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "da5a7b296e06c0cf892682c320bddaeb26529c8928f0f553b721c735e31b5be9", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "03a61d0c7c587a41071574cd54164d65f6b5bdae5cd6b4b651a813a4e3ec4991", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e495b8347ee0e1ca0674e22fbe937285581e0a5cdc9ba513481aa1e591479deb", "target_hash": "bfe10cc42cc7f59a8f5e4fcc67b8de2c468b6516ad28c8f72f612454b38528d3", "section_hashes": ["e577b41a38b8"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -102927,7 +103659,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -102944,7 +103676,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -102961,7 +103693,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -102978,7 +103710,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -102995,7 +103727,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103012,7 +103744,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103029,7 +103761,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103046,7 +103778,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103063,7 +103795,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103080,7 +103812,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103097,7 +103829,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103114,7 +103846,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103131,7 +103863,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103148,7 +103880,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103165,7 +103897,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103182,7 +103914,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103199,7 +103931,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103216,7 +103948,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103233,7 +103965,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103250,7 +103982,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103267,7 +103999,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103284,7 +104016,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103301,7 +104033,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103318,7 +104050,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103335,7 +104067,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103352,7 +104084,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103369,7 +104101,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103386,7 +104118,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103403,7 +104135,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103420,7 +104152,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103437,7 +104169,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103454,7 +104186,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103471,7 +104203,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103488,7 +104220,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103505,7 +104237,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103522,7 +104254,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103539,7 +104271,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103556,7 +104288,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103573,7 +104305,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103590,7 +104322,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103607,7 +104339,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103624,7 +104356,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103641,7 +104373,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103658,7 +104390,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103675,7 +104407,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103692,7 +104424,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103709,7 +104441,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103726,7 +104458,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103743,7 +104475,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103760,7 +104492,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103777,7 +104509,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103794,7 +104526,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103811,7 +104543,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103828,7 +104560,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103845,7 +104577,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103862,7 +104594,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103879,7 +104611,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103896,7 +104628,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103913,7 +104645,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103930,7 +104662,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103947,7 +104679,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103964,7 +104696,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103981,7 +104713,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -103998,7 +104730,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -104015,7 +104747,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "7c689b038f26dc4da2729873b2927df62a1f5b696a1d4426faef11ec0ac4dcc6", @@ -104032,7 +104764,7 @@ "88b3aa0b0274", "c1c62ed7814f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -104042,7 +104774,7 @@ "pl": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", "target_hash": "7fdae062fe9a00e533d26183f86b2c95abe6e1d5058bb2adc15bf477783c3113", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104055,7 +104787,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104068,7 +104800,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104081,7 +104813,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104094,7 +104826,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104107,7 +104839,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104120,7 +104852,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104133,7 +104865,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104146,7 +104878,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104159,7 +104891,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104172,7 +104904,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104185,7 +104917,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104198,7 +104930,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104211,7 +104943,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104224,7 +104956,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104237,7 +104969,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104250,7 +104982,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104263,7 +104995,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104276,7 +105008,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104289,7 +105021,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104302,7 +105034,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104315,7 +105047,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104328,7 +105060,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104341,7 +105073,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104354,7 +105086,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104367,7 +105099,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104380,7 +105112,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104393,7 +105125,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104406,7 +105138,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104419,7 +105151,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104432,7 +105164,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104445,7 +105177,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104458,7 +105190,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104471,7 +105203,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104484,7 +105216,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104497,7 +105229,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104510,7 +105242,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104523,7 +105255,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104536,7 +105268,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104549,7 +105281,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104562,7 +105294,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104575,7 +105307,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104588,7 +105320,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104601,7 +105333,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104614,7 +105346,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104627,7 +105359,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104640,7 +105372,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104653,7 +105385,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104666,7 +105398,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104679,7 +105411,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104692,7 +105424,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104705,7 +105437,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104718,7 +105450,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104731,7 +105463,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104744,7 +105476,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104757,7 +105489,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104770,7 +105502,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104783,7 +105515,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104796,7 +105528,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104809,7 +105541,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104822,7 +105554,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104835,7 +105567,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104848,7 +105580,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104861,7 +105593,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104874,7 +105606,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "f1c997fbde59a8c170cb2232719c769ce8d1a156138bd8ef177f7fb905b92c8b", @@ -104887,7 +105619,7 @@ "a4f02c056ff8", "c646956f7571" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -104909,7 +105641,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -104926,7 +105658,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -104943,7 +105675,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -104960,7 +105692,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -104977,7 +105709,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -104994,7 +105726,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105011,7 +105743,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105028,7 +105760,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105045,7 +105777,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105062,7 +105794,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105079,7 +105811,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105096,7 +105828,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105113,7 +105845,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105130,7 +105862,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105147,7 +105879,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105164,7 +105896,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105181,7 +105913,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105198,7 +105930,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105215,7 +105947,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105232,7 +105964,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105249,7 +105981,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105266,7 +105998,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105283,7 +106015,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105300,7 +106032,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105317,7 +106049,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105334,7 +106066,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105351,7 +106083,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105368,7 +106100,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105385,7 +106117,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105402,7 +106134,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105419,7 +106151,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105436,7 +106168,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105453,7 +106185,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105470,7 +106202,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105487,7 +106219,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105504,7 +106236,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105521,7 +106253,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105538,7 +106270,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105555,7 +106287,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105572,7 +106304,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105589,7 +106321,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105606,7 +106338,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105623,7 +106355,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105640,7 +106372,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105657,7 +106389,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105674,7 +106406,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105691,7 +106423,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105708,7 +106440,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105725,7 +106457,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105742,7 +106474,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105759,7 +106491,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105776,7 +106508,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105793,7 +106525,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105810,7 +106542,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105827,7 +106559,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105844,7 +106576,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105861,7 +106593,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105878,7 +106610,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105895,7 +106627,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105912,7 +106644,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105929,7 +106661,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105946,7 +106678,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105963,7 +106695,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105980,7 +106712,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -105997,7 +106729,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "f9a2ba781de0fb548e8bc6b8b01146406bdfca2b1788d88dcba963ae38ece09e", @@ -106014,7 +106746,7 @@ "0d42014c4e5e", "b3d7a83a33f7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -106024,397 +106756,397 @@ "pl": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "6e72f8f98ab55bfceef8856d14c83d808f4807c4d37fcdefcdaa42cd3543dc58", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "45d2cf1c4b81aec8070cffc105cbf0696a5cda9970f736b832431a07e6f58580", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "210caadfd4b8670fcec69738d8b65b26e3474d6b3d8395088c117f943fd1d028", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "1e75cdf89fba392b483d3d05656fde38b8195cdefb9b36ee5dcfa493477ae0b6", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "9ddb86b5a859e597dd755411ca5ecdf163e98e9d5241a5e99dddf297872ab3c1", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "a23d1109409e71c7764c088b646e460ee65a2de61d3564ca37f285f7ca60f566", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "3fbf030378577065b0806dfb947c7ad96815e96fae1eaab17944e19ad15263a7", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "1f515c97122f73fce81e1b0db5bc144fe9b54a0a3d24c5be7c4ab25f4fbcfef8", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "0e3cbd1b12b2746bb8e41495a52f133633d69c9235975e4e56c6fef871a27271", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "c1e4368a9df5a682982bafac207a13a3a4e1d29a081f2d3f68feafdb25052083", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "301e046e55121cffa04b16971c6f77ffe6b22d5c821a69bfa3dacbb57efcb600", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "de57055cdaec01c6f59613b391f9c480d29388347258b5cc88fab5c6d34e9e56", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "8e0f0e98ff3c8e021548428031085cbeda7dd176032d0d92227a622b45d65e71", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "e80354e49bf2a140533c2689d481163576e9f9e3023bfba8dc5ea070cd8a2be7", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "ad189010b3b2e868d84f598a8f2ef7780c28da9988228867fc5ac4dab57bcabb", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "cd885d69a264682cd6d3a0153594a740e8c0338bc3a70acf7869e8e3aefa4b42", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "d3b7aa0ca52e3da172dae7391b2e93b276599aa38c45061669e9407c218268fb", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "75893c8552021d3d34146dc5ef036b7d46ac498bed740f13f5e541d26b4fb8cf", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "bfe24794d4bb33653cdad184d58347fcee783f27b7abf66602abe6b7abbcd199", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "d2254e645ffcef5ff5b31425a75d6e7c64b67be004131f798355c5d757fd8d1c", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "7c78c46f181b08dbc2435fee97c345b33fa1e2375dfe2c35392f395b94ddea62", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "891680ad4daa710b0f254f112b52c0f8bb58ecfc9f7ab2ba0b143cdae59cded6", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "6dbe07bfe6e2c6588c0f29aede43056a401d14649fdcc22c5618fbb62d4be471", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "d56eb7b2bb0918f143ab07555975f365003b4cdd26c7e2fb5dfcac1696b1121d", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "87412c615a9c828b687aac3d4502166b548963cd1cf0a41fd8c37b30ab8a19c0", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "0410da6c68fd61435cfc0eded633dee92276fd8cde4ac7ca9bf74616239fff53", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "f8284273c2a041e9362852f490a713653931863d14acdbb87ef8c29cab5d4b37", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "1c1b961a93e23db33ac7275d6d9051d0a0baeb988dd88a2183afa9a2303ab3d6", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "d9fd76f5115433568bda2d7d9e23cffbfcfe37e0d5684c914f10e04fb7afcd86", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "2f663923bcbe7343828f013f3f8a85cd9bbc7c708e93338983028e7b6d445e44", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "631af6c4ad30f5a20f2641e250f68ae0f782683bf553375439dc5ce598d55811", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "bb57809a62ffe4866ae71bf0926cb7f61996911c3935200350a75f7eb5448fbf", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "166fec4bc4bd24849a754ef8023ab14480281c42765bd40da6911d80fc848be0", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "a93ab83a042bcb6198887eeca0d7ddc97ab1205c1a55c15b0857ce6105eaf76d", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "38a43da2b36ee2181f26da9a6e0a31a029f171f77f2a60c3b5087bd55cdf8dc0", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "ba641f284728e0d68b55d2a522a873fa45c74c54b80938315720889e2ee3dd66", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "3a64cf1ad16877d6da05cd4cb6e1d0fe8009a0149ce3c3fd159c7345dabcb983", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "75e3414024f61915bd6ee7cf18a6197dbe691f3c0738756e6ce0fb96f184a522", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "5f8b9cc0b2a0292a72b1e871c78cfeefdffcd51dd32ee48842073fc2c47593b7", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "762a8a0d7e73b49ebaecd8caf02d8ef81f20ec49e592742072dbf67ad5a568c1", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "df1b6f27034bd104d056b697cc8211f8d6555345dba3cb0c0d0227b9c84b4ca7", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "169664d690c775c629fc8689dc6b2a5c422b1c11da7d59eebff72150ab5195ac", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "43c51d98c192385ab0e29f4c6201d79318213babe6b6dd310ed89a20d8831cc8", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "5b1b1de25cf42e78335802aab828325533841ed4a1f339f8cbd6402368707312", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "c5e8c83f4893f32cf0ab2c7a929b8a62de3fba824365eee2671753963ec35f93", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "7eb12f5251a84547296a0c09a4b623689609ed568742dbc082eb448c6c17c0cd", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "4a0d730bc586671299003c36585a71b110be9632e6ead5b746abb505b88a2c51", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "3b23c715603b7542bbce5e32faeeaa8359f0001f847a1b91aa9223f204c77432", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "9935d0dfb3479a7c7edf8167fd0661ab654218d3564afdf7fbda1dd587cb4c11", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "f442c127bc208d3a1cef379e763f1ff006043a3cc0159c28d476c97719d62e2f", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "08ed9be1e807ce09d86299f0320be554c29f5a4ad88fb755b24b43fbe6a07e11", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "bcf3acfc6c32c7deb7e7fd1c6efdc2045db3203b058cb55f7541004c9299e62c", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "48650b3a801146ad69268d492d1373680d8a7d6991a350960a671d1ce4e430e7", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "8b62923e501d50febd107904b8e0f1e7f30a27fc6cbd8a20157989a4df05940e", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "32fab7c1b7723573e6162a01e6c7f74338a80b6e2a2e6249b16f4696d0545724", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "8f91a2a90df7534895ea12c1a3444f1112b8f1b94dbc152a5c7d5dda776f8b31", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "9db0726ae232ebd5eb2d8bf3a6c171b85f10247a7ad0ac6dc8e6f62ef3a8a66a", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "fdfa483ba15a4085eb9dddfbacca365f38488692e94312860bb561d581c90594", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "755a26b4fa80beb9e3b3b7949a9260196ebdf9d67468d0e57c66374d81c8612e", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "52f3f1793d3a83770a860b03295b5bff926dd8d4c92decf8bacfcf00a0e7423a", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "8dfa5fba986226f10a49bbf10984ea6a9428e3c815efabaf2cb1d1550d8c0cd8", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "3d14a73c735d48ab6e489c680b075ef265d6c3335d348fc39bbae80de0d7ce91", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "dbb63aa527ca3a2751379d4f8fa63316158a8e8770186515a1965c9063cda589", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "2b1f88c9953529cf82a2468854a552b9e2ddc2128edf935fa367ee37fc0fa2b8", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "1831bce0b716218be21415a5ae3077179f71c53d81dad2cae6aad9d05ccc1c0f", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "afe4fcfdc2128ddd524148c5816437b2a4be1e34a295d16b2bcb70aec45722a1", "target_hash": "124f890a560c9cd7f79235598347e25340f241b707d53955319df8cf76fde556", "section_hashes": ["f6eb57a75cec"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -106431,7 +107163,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106443,7 +107175,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106455,7 +107187,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106467,7 +107199,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106479,7 +107211,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106491,7 +107223,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106503,7 +107235,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106515,7 +107247,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106527,7 +107259,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106539,7 +107271,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106551,7 +107283,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106563,7 +107295,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106575,7 +107307,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106587,7 +107319,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106599,7 +107331,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106611,7 +107343,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106623,7 +107355,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106635,7 +107367,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106647,7 +107379,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106659,7 +107391,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106671,7 +107403,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106683,7 +107415,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106695,7 +107427,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106707,7 +107439,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106719,7 +107451,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106731,7 +107463,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106743,7 +107475,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106755,7 +107487,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106767,7 +107499,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106779,7 +107511,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106791,7 +107523,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106803,7 +107535,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106815,7 +107547,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106827,7 +107559,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106839,7 +107571,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106851,7 +107583,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106863,7 +107595,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106875,7 +107607,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106887,7 +107619,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106899,7 +107631,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106911,7 +107643,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106923,7 +107655,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106935,7 +107667,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106947,7 +107679,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106959,7 +107691,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106971,7 +107703,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106983,7 +107715,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -106995,7 +107727,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107007,7 +107739,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107019,7 +107751,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107031,7 +107763,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107043,7 +107775,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107055,7 +107787,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107067,7 +107799,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107079,7 +107811,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107091,7 +107823,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107103,12 +107835,12 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", "target_hash": "21cae954466b9bf3995d0e619b6c84d1b27590a4c3c0d7327f8ca6df8b149ab1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107120,7 +107852,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107132,7 +107864,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107144,7 +107876,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107156,7 +107888,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107168,7 +107900,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107180,7 +107912,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107192,7 +107924,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "9e8cdc3508e243fe2ddcbd3e556a4324f7c045041c36132ff86d58c627943804", @@ -107204,7 +107936,7 @@ "49b087f71cd8", "aaf3899beb9e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -107225,7 +107957,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107241,7 +107973,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107257,7 +107989,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107273,7 +108005,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107289,7 +108021,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107305,7 +108037,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107321,7 +108053,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107337,7 +108069,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107353,7 +108085,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107369,7 +108101,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107385,7 +108117,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107401,7 +108133,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107417,7 +108149,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107433,7 +108165,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107449,7 +108181,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107465,7 +108197,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107481,7 +108213,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107497,7 +108229,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107513,7 +108245,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107529,7 +108261,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107545,7 +108277,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107561,7 +108293,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107577,7 +108309,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107593,7 +108325,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107609,7 +108341,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107625,7 +108357,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107641,7 +108373,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107657,7 +108389,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107673,7 +108405,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107689,7 +108421,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107705,7 +108437,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107721,7 +108453,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107737,7 +108469,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107753,7 +108485,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107769,7 +108501,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107785,7 +108517,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107801,7 +108533,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107817,7 +108549,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107833,7 +108565,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107849,7 +108581,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107865,7 +108597,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107881,7 +108613,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107897,7 +108629,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107913,7 +108645,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107929,7 +108661,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107945,7 +108677,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107961,7 +108693,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107977,7 +108709,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -107993,7 +108725,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108009,7 +108741,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108025,7 +108757,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108041,7 +108773,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108057,7 +108789,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108073,7 +108805,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108089,7 +108821,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108105,7 +108837,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108121,7 +108853,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108137,7 +108869,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108153,7 +108885,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108169,7 +108901,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108185,7 +108917,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108201,7 +108933,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108217,7 +108949,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108233,7 +108965,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108249,7 +108981,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6141459487b9d9d3c17c9ea659a2e31235d5c8fc85504a9dda09618db5bc9f0f", @@ -108265,7 +108997,7 @@ "fab14aa80ee9", "241b5d10a60f" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -108284,7 +109016,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108298,7 +109030,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108312,7 +109044,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108326,7 +109058,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108340,7 +109072,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108354,7 +109086,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108368,7 +109100,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108382,7 +109114,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108396,7 +109128,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108410,7 +109142,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108424,7 +109156,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108438,7 +109170,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108452,7 +109184,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108466,7 +109198,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108480,7 +109212,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108494,7 +109226,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108508,7 +109240,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108522,7 +109254,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108536,7 +109268,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108550,7 +109282,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108564,7 +109296,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108578,7 +109310,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108592,7 +109324,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108606,7 +109338,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108620,7 +109352,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108634,7 +109366,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108648,7 +109380,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108662,7 +109394,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108676,7 +109408,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108690,7 +109422,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108704,7 +109436,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108718,7 +109450,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108732,7 +109464,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108746,7 +109478,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108760,7 +109492,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108774,7 +109506,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108788,7 +109520,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108802,7 +109534,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108816,7 +109548,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108830,7 +109562,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108844,7 +109576,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108858,7 +109590,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108872,7 +109604,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108886,7 +109618,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108900,7 +109632,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108914,7 +109646,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108928,7 +109660,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108942,7 +109674,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108956,7 +109688,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108970,7 +109702,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108984,7 +109716,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -108998,7 +109730,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109012,7 +109744,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109026,7 +109758,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109040,7 +109772,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109054,7 +109786,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109068,7 +109800,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109082,7 +109814,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109096,7 +109828,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109110,7 +109842,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109124,7 +109856,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109138,7 +109870,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109152,7 +109884,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109166,7 +109898,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109180,7 +109912,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "67be529170f43f063f35359d76704637f6505e4fe2074b0656f8d6f74dbb3a7c", @@ -109194,7 +109926,7 @@ "983f2d00dc52", "f206a6d8e1de" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -109204,7 +109936,7 @@ "pl": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", "target_hash": "e9b4983080533175eaf987e640215c6d0e4847aa6bde2f60631198fb39673e4a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109218,7 +109950,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109232,7 +109964,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109246,7 +109978,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109260,7 +109992,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109274,7 +110006,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109288,7 +110020,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109302,7 +110034,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109316,7 +110048,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109330,7 +110062,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109344,7 +110076,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109358,7 +110090,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109372,7 +110104,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109386,7 +110118,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109400,7 +110132,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109414,7 +110146,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109428,7 +110160,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109442,7 +110174,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109456,7 +110188,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109470,7 +110202,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109484,7 +110216,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109498,7 +110230,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109512,7 +110244,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109526,7 +110258,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109540,7 +110272,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109554,7 +110286,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109568,7 +110300,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109582,7 +110314,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109596,7 +110328,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109610,7 +110342,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109624,7 +110356,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109638,7 +110370,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109652,7 +110384,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109666,7 +110398,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109680,7 +110412,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109694,7 +110426,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109708,7 +110440,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109722,7 +110454,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109736,7 +110468,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109750,7 +110482,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109764,7 +110496,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109778,7 +110510,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109792,7 +110524,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109806,7 +110538,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109820,7 +110552,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109834,7 +110566,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109848,7 +110580,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109862,7 +110594,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109876,7 +110608,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109890,7 +110622,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109904,7 +110636,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109918,7 +110650,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109932,7 +110664,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109946,7 +110678,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109960,7 +110692,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109974,7 +110706,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -109988,7 +110720,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110002,7 +110734,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110016,7 +110748,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110030,7 +110762,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110044,7 +110776,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110058,7 +110790,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110072,7 +110804,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110086,7 +110818,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110100,7 +110832,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "60c679beb7e4b5e31757af38044b33ddeb718951f81c422772693d37effbf2b7", @@ -110114,7 +110846,7 @@ "989b4d77f418", "80a37ccd59f6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -110176,7 +110908,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110233,7 +110965,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110290,7 +111022,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110347,7 +111079,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110404,7 +111136,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110461,7 +111193,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110518,7 +111250,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110575,7 +111307,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110632,7 +111364,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110689,7 +111421,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110746,7 +111478,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110803,7 +111535,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110860,7 +111592,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110917,7 +111649,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -110974,7 +111706,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111031,7 +111763,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111088,7 +111820,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111145,7 +111877,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111202,7 +111934,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111259,7 +111991,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111316,7 +112048,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111373,7 +112105,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111430,7 +112162,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111487,7 +112219,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111544,7 +112276,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111601,7 +112333,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111658,7 +112390,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111715,7 +112447,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111772,7 +112504,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111829,7 +112561,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111886,7 +112618,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -111943,7 +112675,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112000,7 +112732,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112057,7 +112789,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112114,7 +112846,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112171,7 +112903,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112228,7 +112960,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112285,7 +113017,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112342,7 +113074,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112399,7 +113131,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112456,7 +113188,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112513,7 +113245,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112570,7 +113302,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112627,7 +113359,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112684,7 +113416,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112741,7 +113473,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112798,7 +113530,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112855,7 +113587,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112912,7 +113644,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -112969,7 +113701,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113026,7 +113758,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113083,7 +113815,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113140,7 +113872,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113197,7 +113929,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113254,7 +113986,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113311,7 +114043,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113368,7 +114100,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113425,7 +114157,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113482,7 +114214,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113539,7 +114271,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113596,7 +114328,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113653,7 +114385,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113710,7 +114442,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113767,7 +114499,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113824,7 +114556,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "2e76a7659d35e8920ff0afe7a06f9f0ba832c2eaf6faca64c3e2446f2f71f65c", @@ -113881,7 +114613,7 @@ "09c726593fd5", "488a77759b48" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -113909,7 +114641,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -113932,7 +114664,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -113955,7 +114687,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -113978,7 +114710,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114001,7 +114733,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114024,7 +114756,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114047,7 +114779,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114070,7 +114802,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114093,7 +114825,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114116,7 +114848,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114139,7 +114871,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114162,7 +114894,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114185,7 +114917,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114208,7 +114940,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114231,7 +114963,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114254,7 +114986,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114277,7 +115009,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114300,7 +115032,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114323,7 +115055,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114346,7 +115078,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114369,7 +115101,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114392,7 +115124,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114415,7 +115147,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114438,7 +115170,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114461,7 +115193,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114484,7 +115216,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114507,7 +115239,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114530,7 +115262,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114553,7 +115285,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114576,7 +115308,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114599,7 +115331,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114622,7 +115354,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114645,7 +115377,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114668,7 +115400,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114691,7 +115423,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114714,7 +115446,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114737,7 +115469,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114760,7 +115492,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114783,7 +115515,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114806,7 +115538,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114829,7 +115561,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114852,7 +115584,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114875,7 +115607,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114898,7 +115630,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114921,7 +115653,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114944,7 +115676,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114967,7 +115699,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -114990,7 +115722,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115013,7 +115745,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115036,7 +115768,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115059,7 +115791,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115082,7 +115814,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115105,7 +115837,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115128,7 +115860,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115151,7 +115883,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115174,7 +115906,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115197,7 +115929,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115220,7 +115952,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115243,7 +115975,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115266,7 +115998,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115289,7 +116021,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115312,7 +116044,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115335,7 +116067,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115358,7 +116090,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115381,7 +116113,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "90bf37703c4aa521bfc2ca1db423144333454294ae6fe86e8fab69dea013480e", @@ -115404,7 +116136,7 @@ "d83ab231873b", "a40207921896" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -115415,397 +116147,397 @@ "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "e7e608f046b8ec9414d496ba4075d5910e1cdbcf928856abf8223666286b99cc", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "85f8c7c7831958444fd5634a62e1d9cd005aaeb296043dac717e18f9c99969ee", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "a95a52d68f235e2dee99a072ba709861eeff77b853f679a9867b2d9f22681cde", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "281fb1435ba414d3134669de79917b6a67f0077192656b4174f148df446ba032", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "b39650e2e0c121950729bd129e21d5801dead13516e4a813c24bd8ce66f12e5b", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "58af09d0b62b1f0f4fe53cd00de09168162b4f79f7da673ebd9ad89d82c3e7f8", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "5eb2f4ae3a769a3c86b2aee7214380857b27333fc60306eec57941001936e07b", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "cb74ace588fb2b8ead3528eeee76879a5a3acfa45a00ef6aedea374aa083c7b8", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "efd806998f7036a25e640b008e2037c88661d4a24427860839c4e25d9c9b7eb5", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "7aae7138bc8c232d8a63e7a09756df593efa13c2ace159bde919f3cd83813151", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "f24e48811e29fa964686c36824750f424b5a794820eb581b21ec854ec9249075", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "dc7dc7c81621643c27f583e7b15e33ddedbcafc0013d8ac4720535da262a2009", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "b2848e2204faade50063070798195c69bf3f0f0b487bca186006b11a58a3dbb3", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "0c088bacdcf45c85d8881004e986b2d229f8063aa8600ea76acb738db7ae7d44", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "4cf76497ebe60ada58254e7bf2b4fecca5d1e7c166d76321fe2697e74f48072b", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "c285ef5a96036f629e69db6a9a4fc58f42cdf93fb129fb8e44fd6355f8220b70", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "b6c279a770363cb811e51386dbba46b4dcef859b8ea8c4801211893add98dc7f", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "039696844231584058a38e7c89a43c313a04c2fb9afbb9a6fbc53da5e3ff46f7", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "01bc7d4123b1e4a2353537f58a207f622cd682668c091015215073d5f58d60d1", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "6df0172b33462c45f111837dc7b438d534e622e9672369b83e2f2d9757f6fd44", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "396f11cabb1afebd93f7bf547b2bf3488267463f35999c8fd5cee0167817e601", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "0f54a49fe9bd9fd1d740d8055804efeb4c3eddccc839cc65c3d06dfacd417f98", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "1f78b7d4685871999917ec9a5a09758be4614c7df860b53a3577d94d9f3f9b33", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "3e11c91922857ac896fa7ba6043fc39b2eb5438fb8ec3b81d4f3c37297ed785e", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "52d850c5980e0e6f8737b57543fe99a1bd34ae88b56b21627aeee0fd04d86cea", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "2dd55de2c9b456382be5817bcea38a4b49e9ada9fcd3c20ae3dd5fe5553de464", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "00043e94f2841ef20a425e65d5af0e97e93663a5a5d46b78127bf455f1650bbe", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "f22134eed791490b1dee9aef2aa1cd4c23a999f628c4ffc0f7a91673f7063c46", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "ec7e53dc84b9b3e1b08f76de83c7cb1aaa0e98d507b86ea3fe1ef277cb4239b9", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "8046bc045010299a04d97e0e2df8c0f89a576c7c4eee763cbbb999b2911d5d15", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "596543ae0cf6e2041c38c6490e0bdb2439806a90598ff798888e805c48aedb9b", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "21bfe2780dca08b78c75d978fc77f1b092cffec6a1b3355bc690ca61163b4ee9", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "7cce302e5c947198bc0e8aabaab206656c0865a48e4d1c015cbe3abf1a8afed6", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "3712072110e83dc7131a1b62f73048d30f9387494df52c4153cb7fcf8c0ff08f", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "df29953d5165a9a75f6f326747fb179adfb0bf5cda0f7089d6a4429c117d2413", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "7390175f5af4695d760fb1e7a70e471aad2c32c8b935d3d8e12ee3c3e12b8637", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "56d7413592e0e726353d3a021171b7c73db0f79cddb8a974f8458645469180e6", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "d553ec79cae313562bf909e39d4c6632b0c5b8f48e03efea0d215eef77b3d140", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "49a446d3910e05fa0b2b1e64c3c3b97c3f83bd5e1dc57ceca147c49e6f86bebe", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "01716a2fcdc49edddd608f7465f49dfe394a864798e4b3d8b97647b97765c3b2", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "456d99cb2cda03dceb7983ca852e538fc817c1ce0260cccf6e318bc15326d29d", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "ae3688aa4c25fc6b77135237006822b672abd06979f0cc6cdcde8c49a71d55be", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "63101687225c5f31486a5e290260263b05b7dce646ca48a46479cb5ece79b204", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "d000222fa6b1665e661d36d854e414efb005304f4786c0a0b7b102a2a26cb7be", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "1d324d5e5f983cf2b79fefda101402c1d2273feb4636e3250300237999c60247", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "393c77b4cb7ab7bc2faf199f027fed2aea76a95d759defde92ae3161a19d6588", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "be3d523553687744c8035785cbf5d5f45a3d87c2fe890328b1aa338982bd0d13", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "0783ecd9d28070866cac3635747654de0ddd064ee8f17b369d9b3d9aa6903099", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "6d149b8a5eddf941f20ce0ce03382723bdf427415c378541124fa361377e542f", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "272e2cd5d2999c74d4ad0572d0ca77092c3d022e3bbc581da16afb046f4aa480", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "decdc96a444881bd49c0f8f4f57db54a13c5a1de149109f1ee1ee01a996007f5", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "a2f7894de4bcaf20a0119939ab8d26797b638a6d0a0772e686bf704af5807aba", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "e18f8227b55c4dcb8a36469decafc325f8d88677f1c1cadd12d0a3dc55bc81f1", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "f48a7041876a57d2665ae9466203afdcabc9668de51b8f595e262c889435d457", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "7afe94323085471fe5c755533aa38fc6a71862648cd9bd5ded3285070d848c36", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "ebb2cd01f47de23d7cd07ecf831696b68e2dff4c50feebbf452846c4748ba3eb", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "3191511db354cf645506f435b28bcb47b6f268edc59175ff6a94aa7ff0886870", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "87f8cdc61a319e7773a6d932fc1148bb6afb40d18550a3e879a856cb087586c3", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "cdcdbf09f8a67e4aa16d580e7abd24f2491c4b6dbd8a0fc3d014ac0563358e67", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "62fcd036da35488d045513b3792877ed28f126bf0684aa739728b4cafe1d607c", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "a7cc128a50c499da266178490c76d449b5624f2a4ea51f69eda3c975da44ddb7", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "e7e36de9f45e77472591b1399bc3a6d062307b01f59a76c832783f4c23e8e36d", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "14e19d46250daec00a096bdfe99bd4240faf60ad018710869e3e3dd3131f825f", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "f3c8fb7b6d9d090927855d373051280de32994a25ad9f416c76159c8a1b05dc5", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "6c34b20e17357578c966775d08eabed1e781af6f28a0b8597de3f377543217ad", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4c0e0e95f7bd40fdbf9732091454ce4199d76e50244e9992b349eeab11d6a7d9", "target_hash": "15b58b248dea11b0c3ffb6da3de9e0a095b8ab26cb1c6f3181040b3dd2c62e10", "section_hashes": ["0b289c723752", "31dd7985b49f", "a04f16655688", "60c73d142489"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -115855,7 +116587,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -115900,7 +116632,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -115945,7 +116677,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -115990,7 +116722,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116035,7 +116767,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116080,7 +116812,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116125,7 +116857,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116170,7 +116902,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116215,7 +116947,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116260,7 +116992,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116305,7 +117037,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116350,7 +117082,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116395,7 +117127,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116440,7 +117172,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116485,7 +117217,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116530,7 +117262,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116575,7 +117307,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116620,7 +117352,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116665,7 +117397,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116710,7 +117442,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116755,7 +117487,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116800,7 +117532,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116845,7 +117577,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116890,7 +117622,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116935,7 +117667,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -116980,7 +117712,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117025,7 +117757,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117070,7 +117802,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117115,7 +117847,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117160,7 +117892,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117205,7 +117937,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117250,7 +117982,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117295,7 +118027,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117340,7 +118072,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117385,7 +118117,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117430,7 +118162,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117475,7 +118207,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117520,7 +118252,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117565,7 +118297,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117610,7 +118342,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117655,7 +118387,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117700,7 +118432,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117745,7 +118477,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117790,7 +118522,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117835,7 +118567,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117880,7 +118612,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117925,7 +118657,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -117970,7 +118702,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118015,7 +118747,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118060,7 +118792,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118105,7 +118837,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118150,7 +118882,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118195,7 +118927,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118240,7 +118972,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118285,7 +119017,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118330,7 +119062,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118375,7 +119107,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118420,7 +119152,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118465,7 +119197,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118510,7 +119242,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118555,7 +119287,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118600,7 +119332,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118645,7 +119377,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118690,7 +119422,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118735,7 +119467,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "ac8ebeae73bb4e231d2f07fa7743f1f1da6fd0b089d4f2817521d4f22b064425", @@ -118780,7 +119512,7 @@ "f48ac62f9f6a", "e7327d596060" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -118790,332 +119522,332 @@ "ar": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "20c9e9a62cd5bf7e34a657f78840c8cb6655977790eafc44dab4e0e5921c676c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "6cd20dcc2779c10a64bc199b21569338a4076ea265cf6791e8c755ba7ab0789b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "1f2dc93c926151c59e9c5c01f0b6d5a41c7fa13978918a32d6a23f481032f62a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "819d719ba7a1a148952134321e1f8d28ecf22e4e2d86c1f0a65d9c9145600fce", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "73a46c697bb8c1f94ef73cf51cbda79d7a7c49c6a6df726d2d35702528237b8d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "884849422983e6b4b79b8ac8af7a2a01a1ca5d2533be947b3738fdbc72cc3037", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "1af89f35730d203ece8be47d88ea5ac28517079599d41f25122d7de4db09de78", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "3279ea2a7ee528bf66c3fa1e8083989435bf5141849fbb80f44dd65b317e7856", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "2adb5d5d444788187557ea64d273acd8cc7e26a796731591a899d063aea3f2d2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "2b91cfcd19440b62ed44e8c6e4f332068f4e081bddbf93a84b85a9f4b64995f7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "b85b2e33617d03196dbc254aa5377a0a70111f9537186b2dd17cf26a01f7ab9b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "739db605aac968aac54a724d01436ca423c832d84bf0f1a66cb4417f477ac9df", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "fd8d437222a05ac465b199a06aa9b1271334d0e7d075caa6ad2e483e24720cc0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "51603c459bb51c0d55e9a36f40df099f4258f51fcbc13301111454d7f22a37fd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "77e0c5f0fee9df6e68d3546c9f61647c6c674fb7085bfc4550e775bde1055d85", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "229160b2e0deeb33f08a0472cb985d45e27fcaf8b23e2222583bf262c82f6b68", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "86ca6ab6ca855e5d6e243e6f2d5ae896d51173b014d85257b0f2d70d0ce58e1a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "ff92a0d51956178ab90ea5c53070f09ec8ee1898c0c180a4687f68d0f1d945c5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "e2a0a1d4a5e2e5585c5cafdae3b5c20c6f0ba1d13b8d62fe5fbac025c7ae53bf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "b66947c8763d178c0d863a4881a23e32ab4fa4f98b5989d2571192073baec856", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "97de3e88a55ac9de236b2bfe8f5809f27be1d4d038a568ae9edd47b50b48ee53", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "b334f6830fe58a4cc570872651b436ce292fb7b4ff89f1e768232d4b784e263d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "524bc951e24c225e403224d136751960886c3462e2c83be5ed18722cab18f279", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "19a1cae906929df016ddc89d48f25d1a79f61d376c6dcd2a6fdf748eaa3044e4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "4a5ebbe1732c5d12ae709d65b2ecdfbf2e20d7c4f7092356fbd84780f023f4be", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "926a52ca5b90eec3c48e4b4d4652a74fc629f64c88c0ac8a565e5203c5a57e41", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "768ce7e0d79c36c12fd9d96d80aa2ab7aba3087998dd8b089eadb1fd09410898", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "7c9c8b3cba3f5e1badf6e443075acca9479f23d27ef91cb4f388fa885032b116", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "10319a79aec8ea19594f1e3dad8e87c59bfc5a5333bd02b1ed98ddd6e3717a1b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "3990c6a07b88855ed778edd21978c2791f57ce2c9bc4f2306afdceb57b788d72", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "cfc4394e3be19a51c9cc5468a3f2fb93ddf4c8f8cbf06ba48fdbe0611b1ecf91", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "4544efe3291de10f01d94183c5019839daa94f5dd669a64f04756e39458afda3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "0148aa8f44a39365874bd541f0788ed6dfd63e8fd7fa0f983febc514f246ce92", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "318f3b877d2566a5173996a68e3b12fec3b47e3f29ed69c4e6cfd7ff054f4307", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "4f5eb9427ec7d7fc06c987f4570495fe8c60aa9a9cde3070e579744adbf03e64", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "0dbd3749eeec6caf4f0c5dbbcd40a04060bca5357b8e3b9e8a97b2b6b4e9aeec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "f32d0872f3b99ea7c205af95d71ca8da87c95a0f5fd3cec23e34c7d26d26c4dc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "5b3463fc4a88a3d8739210fe95578a126528f308cb2ec08c1af2af020835c7d5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "7a19e7b22bfeeaa0dd37c5fc6953af052fca6aa5956f6cb73866f8c4de225170", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "2de2be6dd7323df564b615ce95e1e8ed0d326334381f8df3b6690fe20254cc05", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "f6d0b3b2ec6c399e3f830143ff429e1ceb0e85bcadf03a41df21ab236fe57300", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "d0e47092d54c9574c07b2fd8fb781898f6c5d4f42df125d9d3d7001efc22fb83", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "40dc5d49de8eda8ae8e09afbc8d098e0c99a73d50572da0edfb3d85628a96366", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "0a10f6b1f5ccb78f4583b04c7e2e9f5f69213b8a695afdcb3133d5bd19532c3b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "d007053d6e4b6fb2e780452102875097c727e412556d31a39d61a665902f3f21", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "939745bc44ccb47574b488e3a2f60d9dc1ad879c44e988943c950ed6226f7bcf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "1d7eeea2af8b20d438d00622cc0315ae88f317388937b1e6266ed368254cadab", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "f47f6554985eb6e93da2464dde2618e7454600d3f461330c12a8a937d79e2390", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "7d308aa79d2589e2a6c54499ddf7dee6df7b38d260397e1640ff86048ecd337e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "8cae5c9b925507804cd8ea3c054c68880f5c272a0aeb5cc7d0dd82c76bf46bd7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "6a29aa7eadfa65d1f6d096dbc857f8ff04e84c7076767d31f660715103b12cbc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "321def21457ffe1971552d3dbde7b3b57de5586ba8c7be4eed5e46272285d67e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "a8c1982aecfdb26a02ca2ebdb3130f69cdcc1e33bb8d2f841974c5cd17efa515", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "4b71ce5023635d9247ea42d2b323d3a703665e0d8d5abcb7ba42117027208766", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "1834b3fdebe906343f347a680ff11e2ea38214f3941ec2dc70e8489d9d7da610", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "db06f3cbacbc40e71340521cb3431c42406010d927001dd0585c00143fb75f86", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "53035e4a7fa13c77d8dca95bd4139241030166f91cf1a0c81d332e43bbc7a693", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "6dfd03572ca3e1af16dc4709807199c52ac1ace1f95b7351986925499938f3d8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "bb74908175526959c32f4c5ce945cb37908f4c5def12cce35b5621fcdfed2eba", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "4419cadecf68380eeeb7b6ce3be16536f6dbada916ee660024c1cfb063eeef76", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "5b6fd3b1d836fcad98c1b7617c1507270e65cbf78edd75569bffdc3564a790b8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "aca8a9de40f1f89d7209ae02ab5c6fe78107d16a69f53b06153e669d59785199", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "58bd8d7f13b4eff991844f4d36555889e0863a706e04891de28a2ab5d8e788b4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "ff710bc701c2ace7a4a16b748ad722aa99131214caee6c4cc88a5b055c8e4ac1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "1eb747d4aa76012bd712fe57261fa2d103cee5ae5f1369368cce84aa31aa3352", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "4ef1133a2a4d4e7e8288b3a56bbe1310225f56ed5eb39396f31052963e21fe09", "target_hash": "5f5171209d50a8bb33df7172c728160e6455fa441743f327e7d2b0393b3ef4d8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -119132,7 +119864,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119144,7 +119876,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119156,7 +119888,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119168,7 +119900,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119180,7 +119912,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119192,7 +119924,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119204,7 +119936,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119216,7 +119948,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119228,7 +119960,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119240,7 +119972,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119252,7 +119984,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119264,7 +119996,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119276,7 +120008,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119288,7 +120020,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119300,7 +120032,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119312,7 +120044,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119324,7 +120056,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119336,7 +120068,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119348,7 +120080,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119360,7 +120092,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119372,7 +120104,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119384,7 +120116,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119396,7 +120128,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119408,7 +120140,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119420,7 +120152,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119432,7 +120164,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119444,7 +120176,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119456,7 +120188,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119468,7 +120200,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119480,7 +120212,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119492,7 +120224,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119504,7 +120236,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119516,7 +120248,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119528,7 +120260,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119540,7 +120272,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119552,7 +120284,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119564,7 +120296,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119576,7 +120308,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119588,7 +120320,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119600,7 +120332,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119612,7 +120344,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119624,7 +120356,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119636,7 +120368,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119648,7 +120380,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119660,7 +120392,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119672,7 +120404,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119684,7 +120416,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119696,7 +120428,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119708,7 +120440,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119720,7 +120452,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119732,7 +120464,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119744,7 +120476,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119756,7 +120488,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119768,7 +120500,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119780,7 +120512,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119792,7 +120524,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119804,7 +120536,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119816,7 +120548,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119828,7 +120560,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119840,7 +120572,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119852,7 +120584,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119864,7 +120596,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119876,7 +120608,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119888,7 +120620,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119900,7 +120632,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "1de3f3be467f6004323c0547074622d8d8c0eaa3b5b1a50e4b86b8a338b5d66d", @@ -119912,7 +120644,7 @@ "71f0669b524e", "bc4c47c6afdd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -119935,7 +120667,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -119953,7 +120685,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -119971,7 +120703,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -119989,7 +120721,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120007,7 +120739,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120025,7 +120757,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120043,7 +120775,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120061,7 +120793,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120079,7 +120811,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120097,7 +120829,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120115,7 +120847,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120133,7 +120865,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120151,7 +120883,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120169,7 +120901,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120187,7 +120919,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120205,7 +120937,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120223,7 +120955,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120241,7 +120973,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120259,7 +120991,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120277,7 +121009,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120295,7 +121027,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120313,7 +121045,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120331,7 +121063,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120349,7 +121081,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120367,7 +121099,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120385,7 +121117,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120403,7 +121135,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120421,7 +121153,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120439,7 +121171,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120457,7 +121189,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120475,7 +121207,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120493,7 +121225,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120511,7 +121243,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120529,7 +121261,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120547,7 +121279,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120565,7 +121297,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120583,7 +121315,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120601,7 +121333,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120619,7 +121351,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120637,7 +121369,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120655,7 +121387,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120673,7 +121405,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120691,7 +121423,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120709,7 +121441,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120727,7 +121459,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120745,7 +121477,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120763,7 +121495,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120781,7 +121513,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120799,7 +121531,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120817,7 +121549,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120835,7 +121567,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120853,7 +121585,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120871,7 +121603,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120889,7 +121621,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120907,7 +121639,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120925,7 +121657,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120943,7 +121675,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120961,7 +121693,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120979,7 +121711,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -120997,7 +121729,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -121015,7 +121747,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -121033,7 +121765,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -121051,7 +121783,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -121069,7 +121801,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -121087,7 +121819,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "3c3c0a6d74c8e1e491748b9b32fd88b776c92d4683e437f727e6241162847665", @@ -121105,7 +121837,7 @@ "e41ea6d30c9f", "02571c4c19e6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -121124,7 +121856,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121138,7 +121870,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121152,7 +121884,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121166,7 +121898,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121180,7 +121912,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121194,7 +121926,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121208,7 +121940,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121222,7 +121954,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121236,7 +121968,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121250,7 +121982,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121264,7 +121996,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121278,7 +122010,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121292,7 +122024,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121306,7 +122038,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121320,7 +122052,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121334,7 +122066,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121348,7 +122080,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121362,7 +122094,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121376,7 +122108,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121390,7 +122122,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121404,7 +122136,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121418,7 +122150,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121432,7 +122164,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121446,7 +122178,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121460,7 +122192,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121474,7 +122206,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121488,7 +122220,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121502,7 +122234,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121516,7 +122248,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121530,7 +122262,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121544,7 +122276,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121558,7 +122290,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121572,7 +122304,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121586,7 +122318,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121600,7 +122332,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121614,7 +122346,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121628,7 +122360,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121642,7 +122374,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121656,7 +122388,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121670,7 +122402,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121684,7 +122416,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121698,7 +122430,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121712,7 +122444,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121726,7 +122458,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121740,7 +122472,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121754,7 +122486,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121768,7 +122500,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121782,7 +122514,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121796,7 +122528,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121810,7 +122542,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121824,7 +122556,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121838,7 +122570,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121852,7 +122584,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121866,7 +122598,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121880,7 +122612,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121894,7 +122626,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121908,7 +122640,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121922,7 +122654,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121936,7 +122668,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121950,7 +122682,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121964,7 +122696,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121978,7 +122710,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -121992,7 +122724,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -122006,7 +122738,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -122020,7 +122752,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "52f40a5bb68ad220d445ceefde16fa6ba95a7f1bc5605b9b31975f2e56aad908", @@ -122034,7 +122766,7 @@ "1fb91cbfec0e", "c16912ad6c89" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -122044,62 +122776,62 @@ "cs": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "50d3060c148903a3fce8e70b21948c02172cf4ed29845168114b2bb648f078d5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d18cbe6c4eebac072eee0a438ea918fd2e5e1aee0febe236ec0d183daf087f0f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "937fe8dc290b37d05decfde3b2db1f072b871e83ba8e7b54e7627b8602f293f8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d519eedc1e1161a4d6df9ee3d61d8cda516821fdbd6b8418ec2d3d425d5aaa27", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "f10a9753e73257a72d6e9211db09058300408bbeb309abb5a588298219a33f41", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "e675a587592d57fd418f0a1494257fe0b5c3830353df0057269dd6a2574f791d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "29a2ef83b01b01ecb9deaafd8361ae3ba475372e5c097fba803c4866aa575a32", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "ee4e1d9c1767ba4302133909d1d9e186d55097155634eb6cc0cae237975a7350", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d0d653a2074e21f58a75a12bd842ae3a2949332b6ac4acabf4776156955df2a0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "9ce7ac397e0613a4cec98fbf7bd85e3ce03f499f42be24601910ec4f0c431661", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "9d3da1d2299793ccff2de371b6623bc22a76c7bc52540b8ae293ccd4fdc73fbc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "b5187ba3113d15a62e402600640d0d0ad7922da322838c93477ab74e4bff4f1c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", @@ -122120,77 +122852,77 @@ "7d6dfe6f4cd6", "c071fec914c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "4cfe9d599f776e4a90426a0d2b75ebebbf3a504c980b5ad532ebf3f1ae4ed817", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "a8340c5e47b0f14254d205a9c75e5c83464114760c17b38437c7af89131d1ed9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d8510c52209b0bda51068a1d0bc09eda9f10559f30c3a388102c2abbf7e91499", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "3d5501509da209718ec9124aacf8aeb204513fcd24e3caf3d688bf61a49c5f09", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "5966bedec5bb521b712a38a8550dc63a7fdbc535b1e1f8eed6f318445e3a06eb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d9fe948f50d9d15b2cadbc0e1faba4626e4b724687e2253c5b0f56f105136b35", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "a8616ffc46af8c242145c94e7175dd214a429262e609f546f516ed33f7c89a39", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "be95bcf33f45079d282bdc33332f5af4d5311fc9c9a9b3ad0e0f36c59bdf1282", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "5a6ec19b605296421aa97af41238b886db6256ce9137de179c876db94760ccfa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "60899c39d25862c693a660d2ad45ccdfe524473dafb350e3e3b9f3943323e39e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "04d4d9ecc93b40a46029e5c78607a4f425c7ebc60e51b8f155e3fc12e1180857", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "6fc0bfdcbed385d33cac777d387c0dc1895b55c241af2cd46c7290f143e54815", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "4673b28572cdf8cdea1235761f98b061b66c012f07c92a2710e6b52d9fd72c01", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "cffe8cdd7b7b01f5529034911b0e282f131928ba1e90ef902274977ccfbd34c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", @@ -122211,72 +122943,72 @@ "7d6dfe6f4cd6", "c071fec914c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "1ded5fc52b12e4b4da901557bc9e028a806222b684a27f6fcb4e2a6db9268a7a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "52b12d64c32481985d60ca002465a70c067d97e5bd60c1a5ac3fef0642a33941", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "de1d4557b678e72e7225db3565e27c10c90fae5f51521ba8fd8b9c17617ee593", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "9ebada5edd38161542a337b18ea6e0dbfd6963181505195696e61a48fb1e67ef", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "2734854f6e238122bd26f6366551af5207b42bedd4a3cb6b18a6a8054ea6b0a8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "8a2d386dc1f1baa0813e2289fdd79bc19f312b9a0e7401c58fabeafeacb89ce2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "8ccc8a82ed1c599987bb3f56160fa4605d4834dd960033c2e554fc0ff4782713", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d2076e79222507790331c2d43dbcf15fc67626506ffa29d6fa3527dd453735bf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "b1deaa8c89ae172ed7ca8c824fe55f0c5725c2ee2a899a26682a5b3d571f9507", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "332006f2533861ee3f52958474460900f96eac47284efbe3cbcd6e698ebe02d9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "e87e8cf7916f59b0993d9d5f00d93fb71f0d15e63beb9e0f1179198fca4d299a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "8c207f6b969d11d90eb2d52238315f384d6f55432d63499f69201ee56ac2f264", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "c087ca23b786343e8e6abe43d89ab2bdb0c7a867a98d55281aba6d5d8ef71555", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", @@ -122297,127 +123029,127 @@ "7d6dfe6f4cd6", "c071fec914c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "15bdfe37c158ce671c5f1cbb19a4798bafcd44a5e7a3a52db359b9aadc3d6d37", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "1733738e8e218aecb52c482dcdff018728adbff2c2d5ffc7713205dd4f32da71", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "7bd842e7908963d2260866b8d092eac64d8e2e32e4e568bef9d191bf1cec9489", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "c8903cb2159bfd580956408f8f9ce08edfdbd4ec3cac1b967db5da2a7c00708f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "02d2fba256957461b2d10246afbe1f15962e6aa079b123d92a9557096fb1f2fa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "dedcd6fcbc2355f73e8b131fd561df553356e10d7ef348a1deb13aa4af583d45", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "5eb13e8d961eed9541955b5ba1272543726c65239ebfbee0a9d801c422b85bff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "ada67ef416aa81c9d7d7daee6f964678ece36f911f8c05e2f1427ca97cf14ddd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "39c363385abf9fba2ea2bbd1350656733592aa9ee1a86147f6ffa4b2a3bcf521", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "15657efd2eae5710a22a1a99e4253a1e78ab6e4f69e356417fb61ea32c70e6b8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "7c04843a228f2fd6477c55e94eda89df4276332c4a0b5b448371a4cb4e4a5a09", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "78273809e7d4c7aa3fd9c60a7a551addaca29b3773b111b0d983f824adb96c4b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "4929c42622a4b09db077529ab118901ad6f55300cb58aaf43476c7cf9ea5fd06", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "003b014e0e30b21731fc6447a5ae277ec26a3dbf24007a0a61d53b3e9e4af2d0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "f420976ebb37b11c8ac15a72515bafdcbff8491eab142e5829a96de635f6e05c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "7af506247214d0fa2ec259cfbc0d43c5e8f497d6829463e66d5a3bf31407cad6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "d4d3c626562661313f6ee46ff5b0fec4ac180734ca510dad16d974a429214314", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "bcf6ce4df5174dfb68e395f18fb23cdd54996d3b10592d2e3f7b49f3a9399978", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "cf94903c0c5c3365d393453eeaf44f3a2fdc0932be44392326508886776336c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "7e0ea57975bd4f8864d16571d5aefa4ca24597294ffeac4e9a1f7e538771c7e4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "0fbeec95ba53fbfb88d1fa5bb4ecf01e4452c12b6f9a65c5f28849b41e15a117", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "ade0e66fb64d6c3c3511e82c85f3a26040dab3edfc67c66c793abf6dcb1f9326", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "1c416040783001c2cc5cdd393857023de8204f9821758d36dcd6cd9d487d84f3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "9fe45f59da45f7d383b9f7eaee692609066b17cd343e7c9bbed4d111c3e003d0", "target_hash": "db4ebb87b71b9af69994015779addc68fdb845215acdcfc7de8cb1779623758e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -122436,7 +123168,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122450,7 +123182,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122464,7 +123196,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122478,7 +123210,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122492,7 +123224,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122506,7 +123238,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122520,7 +123252,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122534,7 +123266,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122548,7 +123280,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122562,7 +123294,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122576,7 +123308,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122590,7 +123322,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122604,7 +123336,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122618,7 +123350,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122632,7 +123364,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122646,7 +123378,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122660,7 +123392,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122674,7 +123406,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122688,7 +123420,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122702,7 +123434,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122716,7 +123448,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122730,7 +123462,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122744,7 +123476,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122758,7 +123490,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122772,7 +123504,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122786,7 +123518,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122800,7 +123532,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122814,7 +123546,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122828,7 +123560,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122842,7 +123574,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122856,7 +123588,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122870,7 +123602,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122884,7 +123616,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122898,7 +123630,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122912,7 +123644,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122926,7 +123658,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122940,7 +123672,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122954,7 +123686,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122968,7 +123700,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122982,7 +123714,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -122996,7 +123728,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123010,7 +123742,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123024,7 +123756,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123038,7 +123770,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123052,7 +123784,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123066,7 +123798,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123080,7 +123812,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123094,7 +123826,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123108,7 +123840,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123122,7 +123854,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123136,7 +123868,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123150,7 +123882,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123164,7 +123896,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123178,7 +123910,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123192,7 +123924,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123206,7 +123938,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123220,7 +123952,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123234,7 +123966,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123248,7 +123980,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123262,7 +123994,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123276,7 +124008,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123290,7 +124022,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123304,7 +124036,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123318,7 +124050,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123332,7 +124064,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "5ff245112a1246894c29de5c9f049cc92f6a74b20b55bbd322d3c10f0a15c483", @@ -123346,7 +124078,7 @@ "91b85980361d", "ea551accf008" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -123364,7 +124096,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123377,7 +124109,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123390,7 +124122,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123403,7 +124135,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123416,7 +124148,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123429,7 +124161,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123442,7 +124174,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123455,7 +124187,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123468,7 +124200,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123481,7 +124213,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123494,7 +124226,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123507,7 +124239,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123520,7 +124252,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123533,7 +124265,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123546,7 +124278,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123559,7 +124291,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123572,7 +124304,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123585,7 +124317,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123598,7 +124330,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123611,7 +124343,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123624,7 +124356,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123637,7 +124369,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123650,7 +124382,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123663,7 +124395,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123676,7 +124408,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123689,7 +124421,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123702,7 +124434,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123715,7 +124447,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123728,7 +124460,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123741,7 +124473,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123754,7 +124486,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123767,7 +124499,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123780,7 +124512,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123793,7 +124525,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123806,7 +124538,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123819,7 +124551,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123832,7 +124564,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123845,7 +124577,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123858,7 +124590,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123871,7 +124603,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123884,7 +124616,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123897,7 +124629,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123910,7 +124642,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123923,7 +124655,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123936,7 +124668,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123949,7 +124681,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123962,7 +124694,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123975,7 +124707,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -123988,7 +124720,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124001,7 +124733,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124014,7 +124746,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124027,7 +124759,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124040,7 +124772,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124053,7 +124785,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124066,7 +124798,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124079,7 +124811,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124092,7 +124824,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124105,7 +124837,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124118,7 +124850,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124131,7 +124863,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124144,7 +124876,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124157,7 +124889,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124170,7 +124902,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124183,7 +124915,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124196,7 +124928,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "aced413cdbc2974712238968976237c6c988d4b0e930d4f01d989479bc55d8ac", @@ -124209,7 +124941,7 @@ "05e650d39b28", "b4a6a5a2ece7" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -124219,332 +124951,332 @@ "ar": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "0431e027e06c208a1e36c096bc9272e4b972a360b69c0adda176683fccf5d961", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "92b4826c99a2ad9cfa8b8ddb004d1dcb5107b34470853a4aae1cf29fd9dbe088", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "b87338c8e5fcfea04d2748c81206bf86e68f7a40b3a48dd8ec7563ca8b7d39a0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "c1a1fa7b52c35a29a0c7d46b784b2294328891f642c8c63ce9d77f544614bb83", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "b4123a8f3d5c937c33de2156bef458072319c6af914ad2f9314625c9b651ac0b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "b3b209159ff35b12883a9f148b464c7fe50b67db694dee14413ba203236ba6b3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "1e34fccc582a42f79f1b1b63c84bb1ed7da81d1d27b2769f74ec775022bd1fc7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "e2cd3144995278c071980f4618fbafad4ae0552496c95f6c11ccded99cba5914", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "536a8718fd4820a9f9f790851f3b70cba923f66c8d74e3869149f9661258ec32", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "47c286baebea7c38803ac00e0388d4b5267825657fd7548a760afd3ebd71b565", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "9f6d776b2e563cee4f0e0ae0cde69dd5d4cd03266b1ce7a522941917e09080c9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "2372a686115261a2f17841f272085017ad015660a790ff2082ecb3b76ea4ed88", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "0317c679496a3cd242cda347211c5fd8e4136a590361cf16a78d275834705695", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "55da3129a67f2d8cd335635064744cbb9a80f293cbe228dbdd6fa69ecdb17b3a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "22099b03c220beb4abbff9d4d56bb3026f63193cc23dcf8f401a40b77cd84038", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "87ddc0e16f0ef833ab34a45960c785ae0be6d6c496981796719801ee4529691a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "4c37306e741152160603eefe6aa3a5494cb25affa6152964d3c17f5e3eb3cced", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "d2290dee4181706cec6b92b874f8de1708bafb22b34c52f1fd275c2fbc82b23d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "164d8c0bac6e0cf637b550123f9030c6e946fec5c931aafdb068975dd525f331", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "c6d101ee5fffa3fbcfc37ee7493e77469fc6efbd8e0cd696c66097c69e1f1373", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "5275ac9a87f3c2c59c66cd0f12ddba4628e742ee1b68e750252a2c8cf5ced3da", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "76e66e638f0c90712fc4d9a095d47005757cdf5846e44ac482cf2c9181c97052", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "a41d17cc31619fe13cb6db341398ac447e066b5df42523786a2e0aefbcb1f6e0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "ecb082a5b31ffa3902216a1b8950415190ec9814303057e02b9ee17c271bcda8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "1d502d5d3b1469e60018202eb8b8409a2332322f943c1b1fedbdca5241a7b394", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "b5d8d0fc0724ec6899bc7cc97e38b840dcfd0b7199d0892e1a34444a33a9e59a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "62ee1710baac442025636a594b983768e1bc909563e1d076b622b25ae9df9586", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "675dcb62fb6112043903a3e2de02a19d022f41b3904cc5328cf6e243fe17aa54", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "86b7e5b9cf738d437d7647cc23a4b5248a08fc8daa0061f98ef0f0570c79e585", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "2b97155d1c32d329a0d269c6b38044a3ce07c43e760528796ae31454f6bd25c7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "469c29db8becb0f87351b60e5c557e02ffa71eb163e2768eb297d4b449d1c491", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "a94f233b27cb30da04fb5271f102a9ee6bb9d843a97de6e39c8d31632740f4ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "29cff49b2498c28ad711f1158501be3b9e828f3105cd165f24580db173ca7632", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "e960541e17c8e60ce119d50302075f67b3ed8eb49b78a12b1423a558ff5467a4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "2cb78e1d4f39c494912e539a618320c38e82ba0962586d9de45c64b671597991", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "048533e9dc57ca6fbcb51ed7e9e518e0fdf150fc47b1646ab88a0c4b0aea0e51", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "97a1621b6d6646d51b98fea201bddee46d1e94c5e61bdace8c4bd8a8325ba835", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "31112a71e2d8f76c905866b8eebfcce9c85e2119108ec19eafc085351488fe77", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "83d8f7e6744c31b519aeb414c806ac505dc503cfd70cfe344f64ca204ef6040a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "91279529482fded42bb69215222d3c5d6cd0b4dfa454c7378ad590a9b3e74461", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "d8c46eb49899d7d401433565ee55120e8d4f6508b6fb64ce778aa6ef1b43e27b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "b4f9c3fff2c53e2eeb580f15b1643868987a660ab15efecd67587e92ddeac88a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "36e304845fbad2b1b9903d5e7a115fc145788c533bc54683d045998cc2716e52", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "150db3a20cce6d6d06aad9f04702a8eba0b6031f293fece4a725bcbfd098646d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "ad51945110aab9965dedb63a0abc4ecf4bcbcf0115ed8e4da7dda5b770e53b6a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "693ed52deb2c3e4b32092f26ba268ca07197f02ccc3bf306c533232c16b7f187", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "d5a0114630b2bebf149846a8879ea377c9cfcc5c17ac96a1d84e3bfa6ff853ad", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "f7ab950959fdfa36b5e40921398c93ff22652f4e02f50e8da3d07b241875dd73", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "de345f9e0b7fd1f585fc02cb6f1e1ddc594ab0bee5d5e6529a36765349b912a8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "2b7546cbe0da5b6fe5873ab1561ee34b20e85b81fd124335b801d169455d0895", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "06267c68fbb2a17670dde4eca9ecbd0595294c766bfbac338cd944e28ed6d273", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "554f469adbfa504a1044349ff5b810330d65a042f737e0d6b5743c0991627a35", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "c7a347cfe787311bc60ff50cd0dd71c6e0892381b57ff832085747e4c126ed88", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "3dd6a2c08158740401906d6366d8ff6f504111e3fd5ee1c09023ac67c740852a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "7afd216aaf4066a05bf8474a10e789a10ab6a2041d299ceff371966572f903f9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "8f2c5a309f97104b064752ecbff115e3e5e79227a00c61fd5ecabab761d86fa1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "cca9ce2984c181a95682d7e542d18ad72dbd1f33ca0cc5141c01e359f82fc70f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "3f04960ecc8bfb72b885ae69408a401cbc9cb8d319eeb161a925211f38990b46", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "70b1099cb075c748d1b6f31dc53d8359fbc25b6552c501ebf74ece4a9700bcfd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "cce6162a14c13c961176372fb7198efaed3834f17428c87c0c45fed6900879d0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "92ee1fc623ce6f8cb0ba4ae4a4ba2f6cddaa2aec4c0ef8fd5bcbc7931ee8a7da", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "63d84bb8f993a34db35f09ba70cea0dfb8553952d8d00d61e5e6c24baa60560c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "b77fc8790b3c29db2565ce533b292a74c4118346c1e5f2f43c6d9776336367a3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "35e60f8378a5f50f6f4b48613efa49087ad733373c0f1da9e541e5c59b6ebc9c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "88b8bb00e740983a605f18c96fbfa08f77c95ec5b781a164bbba6686a7dfc015", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "04125c0f794dcbf82dc751be2ba01799feaf3eafcfbc1145113226059176e27b", "target_hash": "8dbd8cb7c7cea31c0ee13306d65104bc16c55f6aa846e864d31259828957ca28", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -124561,7 +125293,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124573,7 +125305,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124585,7 +125317,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124597,7 +125329,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124609,7 +125341,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124621,7 +125353,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124633,7 +125365,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124645,7 +125377,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124657,7 +125389,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124669,7 +125401,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124681,7 +125413,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124693,7 +125425,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124705,7 +125437,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124717,7 +125449,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124729,7 +125461,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124741,7 +125473,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124753,7 +125485,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124765,7 +125497,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124777,7 +125509,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124789,7 +125521,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124801,7 +125533,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124813,7 +125545,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124825,7 +125557,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124837,7 +125569,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124849,7 +125581,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124861,7 +125593,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124873,7 +125605,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124885,7 +125617,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124897,7 +125629,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124909,7 +125641,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124921,7 +125653,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124933,7 +125665,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124945,7 +125677,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124957,7 +125689,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124969,7 +125701,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124981,7 +125713,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -124993,7 +125725,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125005,7 +125737,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125017,7 +125749,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125029,7 +125761,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125041,7 +125773,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125053,7 +125785,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125065,7 +125797,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125077,7 +125809,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125089,7 +125821,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125101,7 +125833,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125113,7 +125845,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125125,7 +125857,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125137,7 +125869,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125149,7 +125881,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125161,7 +125893,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125173,7 +125905,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125185,7 +125917,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125197,7 +125929,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125209,7 +125941,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125221,7 +125953,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125233,7 +125965,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125245,7 +125977,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125257,7 +125989,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125269,7 +126001,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125281,7 +126013,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125293,7 +126025,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125305,7 +126037,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125317,7 +126049,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125329,7 +126061,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "53fae81597c09fb2d6b607736dac18a62886c13c2afa96d711d329e89a27ceb5", @@ -125341,7 +126073,7 @@ "e5bb27e3a220", "47577ebe8144" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -125351,7 +126083,7 @@ "pl": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", "target_hash": "7ab1867332b6aac8f35f764a5c94810b5d3fdc549ef08c4c258038218941ab50", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125373,7 +126105,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125395,7 +126127,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125417,7 +126149,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125439,7 +126171,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125461,7 +126193,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125483,7 +126215,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125505,7 +126237,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125527,7 +126259,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125549,7 +126281,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125571,7 +126303,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125593,7 +126325,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125615,7 +126347,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125637,7 +126369,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125659,7 +126391,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125681,7 +126413,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125703,7 +126435,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125725,7 +126457,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125747,7 +126479,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125769,7 +126501,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125791,7 +126523,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125813,7 +126545,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125835,7 +126567,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125857,7 +126589,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125879,7 +126611,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125901,7 +126633,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125923,7 +126655,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125945,7 +126677,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125967,7 +126699,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -125989,7 +126721,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126011,7 +126743,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126033,7 +126765,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126055,7 +126787,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126077,7 +126809,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126099,7 +126831,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126121,7 +126853,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126143,7 +126875,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126165,7 +126897,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126187,7 +126919,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126209,7 +126941,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126231,7 +126963,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126253,7 +126985,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126275,7 +127007,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126297,7 +127029,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126319,7 +127051,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126341,7 +127073,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126363,7 +127095,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126385,7 +127117,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126407,7 +127139,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126429,7 +127161,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126451,7 +127183,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126473,7 +127205,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126495,7 +127227,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126517,7 +127249,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126539,7 +127271,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126561,7 +127293,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126583,7 +127315,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126605,7 +127337,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126627,7 +127359,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126649,7 +127381,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126671,7 +127403,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126693,7 +127425,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126715,7 +127447,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126737,7 +127469,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126759,7 +127491,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "3cb723ac2fb0c041c4008e91c7f5125d18541bfe494c3464018d240d559caae6", @@ -126781,7 +127513,7 @@ "7b06e46a3a12", "2eddb7dc88cb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -126802,7 +127534,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126818,7 +127550,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126834,7 +127566,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126850,7 +127582,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126866,7 +127598,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126882,7 +127614,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126898,7 +127630,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126914,7 +127646,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126930,7 +127662,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126946,7 +127678,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126962,7 +127694,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126978,7 +127710,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -126994,7 +127726,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127010,7 +127742,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127026,7 +127758,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127042,7 +127774,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127058,7 +127790,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127074,7 +127806,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127090,7 +127822,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127106,7 +127838,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127122,7 +127854,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127138,7 +127870,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127154,7 +127886,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127170,7 +127902,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127186,7 +127918,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127202,7 +127934,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127218,7 +127950,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127234,7 +127966,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127250,7 +127982,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127266,7 +127998,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127282,7 +128014,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127298,7 +128030,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127314,7 +128046,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127330,7 +128062,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127346,7 +128078,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127362,7 +128094,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127378,7 +128110,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127394,7 +128126,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127410,7 +128142,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127426,7 +128158,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127442,7 +128174,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127458,7 +128190,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127474,7 +128206,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127490,7 +128222,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127506,7 +128238,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127522,7 +128254,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127538,7 +128270,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127554,7 +128286,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127570,7 +128302,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127586,7 +128318,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127602,7 +128334,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127618,7 +128350,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127634,7 +128366,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127650,7 +128382,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127666,7 +128398,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127682,7 +128414,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127698,12 +128430,12 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", "target_hash": "e961aa4d46b4a4825a1e7a0f4988ee6318fd8cfe7c194ce2b1d916c6d759ebc8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127719,7 +128451,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127735,7 +128467,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127751,7 +128483,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127767,7 +128499,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127783,7 +128515,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127799,7 +128531,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127815,7 +128547,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "a3806ced11d379777af89907f1aac3f3d3b6a1b2efb34b846fc74e8c78185dd4", @@ -127831,7 +128563,7 @@ "06646cbc800f", "7acad1ac329e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -127841,7 +128573,7 @@ "pl": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", "target_hash": "2348e1024854cc83f1bb077a0ca23bb5b2ccb75b035568fe38fd5b3cf154159f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127854,7 +128586,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127867,7 +128599,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127880,7 +128612,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127893,7 +128625,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127906,7 +128638,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127919,7 +128651,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127932,7 +128664,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127945,7 +128677,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127958,7 +128690,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127971,7 +128703,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127984,7 +128716,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -127997,7 +128729,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128010,7 +128742,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128023,7 +128755,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128036,7 +128768,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128049,7 +128781,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128062,7 +128794,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128075,7 +128807,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128088,7 +128820,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128101,7 +128833,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128114,7 +128846,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128127,7 +128859,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128140,7 +128872,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128153,7 +128885,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128166,7 +128898,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128179,7 +128911,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128192,7 +128924,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128205,7 +128937,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128218,7 +128950,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128231,7 +128963,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128244,7 +128976,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128257,7 +128989,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128270,7 +129002,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128283,7 +129015,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128296,7 +129028,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128309,7 +129041,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128322,7 +129054,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128335,7 +129067,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128348,7 +129080,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128361,7 +129093,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128374,7 +129106,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128387,7 +129119,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128400,7 +129132,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128413,7 +129145,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128426,7 +129158,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128439,7 +129171,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128452,7 +129184,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128465,7 +129197,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128478,7 +129210,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128491,7 +129223,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128504,7 +129236,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128517,7 +129249,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128530,7 +129262,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128543,7 +129275,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128556,7 +129288,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128569,7 +129301,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128582,7 +129314,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128595,7 +129327,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128608,7 +129340,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128621,7 +129353,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128634,7 +129366,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128647,7 +129379,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128660,7 +129392,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128673,7 +129405,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "6ecb87e3fba360aa0ab8d663d61d45f4f87c2a43a9dd198ce4a13d80c0f82357", @@ -128686,7 +129418,7 @@ "073aba1471fb", "5bc103a19c8a" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -128706,7 +129438,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128721,7 +129453,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128736,7 +129468,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128751,7 +129483,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128766,7 +129498,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128781,7 +129513,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128796,7 +129528,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128811,7 +129543,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128826,7 +129558,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128841,7 +129573,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128856,7 +129588,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128871,7 +129603,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128886,7 +129618,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128901,7 +129633,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128916,7 +129648,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128931,7 +129663,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128946,7 +129678,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128961,7 +129693,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128976,7 +129708,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -128991,7 +129723,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129006,7 +129738,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129021,7 +129753,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129036,7 +129768,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129051,7 +129783,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129066,7 +129798,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129081,7 +129813,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129096,7 +129828,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129111,7 +129843,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129126,7 +129858,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129141,7 +129873,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129156,7 +129888,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129171,7 +129903,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129186,7 +129918,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129201,7 +129933,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129216,7 +129948,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129231,7 +129963,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129246,7 +129978,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129261,7 +129993,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129276,7 +130008,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129291,7 +130023,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129306,7 +130038,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129321,7 +130053,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129336,7 +130068,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129351,7 +130083,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129366,7 +130098,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129381,7 +130113,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129396,7 +130128,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129411,7 +130143,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129426,7 +130158,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129441,7 +130173,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129456,7 +130188,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129471,7 +130203,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129486,7 +130218,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129501,7 +130233,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129516,7 +130248,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129531,7 +130263,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129546,7 +130278,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129561,7 +130293,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129576,7 +130308,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129591,7 +130323,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129606,7 +130338,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129621,7 +130353,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129636,7 +130368,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129651,7 +130383,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129666,7 +130398,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0dfc46b285a6839d1603fe85a3179b085cf0cf510d67d2af1921f12cd31bbaff", @@ -129681,7 +130413,7 @@ "e0901cc271d6", "da32b48282a6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -129703,7 +130435,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129720,7 +130452,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129737,7 +130469,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129754,7 +130486,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129771,7 +130503,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129788,7 +130520,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129805,7 +130537,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129822,7 +130554,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129839,7 +130571,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129856,7 +130588,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129873,7 +130605,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129890,7 +130622,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129907,7 +130639,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129924,7 +130656,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129941,7 +130673,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129958,7 +130690,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129975,7 +130707,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -129992,7 +130724,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130009,7 +130741,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130026,7 +130758,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130043,7 +130775,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130060,7 +130792,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130077,7 +130809,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130094,7 +130826,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130111,7 +130843,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130128,7 +130860,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130145,7 +130877,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130162,7 +130894,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130179,7 +130911,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130196,7 +130928,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130213,7 +130945,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130230,7 +130962,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130247,7 +130979,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130264,7 +130996,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130281,7 +131013,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130298,7 +131030,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130315,7 +131047,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130332,7 +131064,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130349,7 +131081,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130366,7 +131098,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130383,7 +131115,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130400,7 +131132,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130417,7 +131149,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130434,7 +131166,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130451,7 +131183,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130468,7 +131200,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130485,7 +131217,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130502,7 +131234,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130519,7 +131251,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130536,7 +131268,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130553,7 +131285,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130570,7 +131302,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130587,7 +131319,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130604,7 +131336,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130621,7 +131353,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130638,7 +131370,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130655,7 +131387,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130672,7 +131404,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130689,7 +131421,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130706,7 +131438,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130723,7 +131455,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130740,7 +131472,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130757,7 +131489,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130774,7 +131506,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130791,7 +131523,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e0608dc6d37542667f459307864303dc6bf16161823e4dfd9d13d9bf0d7f0d5a", @@ -130808,7 +131540,7 @@ "efe09e2cc603", "3c930b32496d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -130828,7 +131560,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130843,7 +131575,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130858,7 +131590,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130873,7 +131605,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130888,7 +131620,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130903,7 +131635,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130918,7 +131650,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130933,7 +131665,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130948,7 +131680,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130963,7 +131695,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130978,7 +131710,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -130993,7 +131725,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131008,7 +131740,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131023,7 +131755,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131038,7 +131770,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131053,7 +131785,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131068,7 +131800,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131083,7 +131815,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131098,7 +131830,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131113,7 +131845,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131128,7 +131860,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131143,7 +131875,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131158,7 +131890,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131173,7 +131905,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131188,7 +131920,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131203,7 +131935,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131218,7 +131950,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131233,7 +131965,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131248,7 +131980,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131263,7 +131995,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131278,7 +132010,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131293,7 +132025,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131308,7 +132040,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131323,7 +132055,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131338,7 +132070,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131353,7 +132085,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131368,7 +132100,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131383,7 +132115,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131398,7 +132130,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131413,7 +132145,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131428,7 +132160,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131443,7 +132175,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131458,7 +132190,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131473,7 +132205,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131488,7 +132220,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131503,7 +132235,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131518,7 +132250,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131533,7 +132265,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131548,7 +132280,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131563,7 +132295,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131578,7 +132310,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131593,7 +132325,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131608,7 +132340,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131623,7 +132355,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131638,7 +132370,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131653,7 +132385,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131668,7 +132400,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131683,7 +132415,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131698,7 +132430,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131713,7 +132445,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131728,7 +132460,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131743,7 +132475,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131758,7 +132490,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131773,7 +132505,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131788,7 +132520,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "fa3cf700c3d0baee8b83daf06562791eb1a24c14b63e217da4304a5a5d1eddc0", @@ -131803,7 +132535,7 @@ "dc0116f4fd71", "83d7ebc3ab73" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -131813,332 +132545,332 @@ "pl": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "31f0dae7408a80838cf97d4f27f3e24fdc08592745d2a20d8cccd51be02f8097", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "7c35d1f5d459af8f598e744025765e560cf9443cf4384ec407cdc00f0176d411", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "32b879bd8b340e4c9f679c66e40f7a79bc48f0609cc8488b31305ba113bddc40", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "bad1ad6a498ada13983274c2997853b5c413630474089d2fd315e4e5ec44516d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "a63b1718e80abe06e1b6e2f819356206a936fe4b068118633993fa4f4c857446", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "6f3ee4e69a6bbc47d2b0bdfc5ad0b46628006c1886ff19ce4e499e48a7172553", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "d39065ceaab6a0ad405324f3d8023b811fb0129d5443fb06b80c305992c406db", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "2bbfb9023e73adf119ad4c8608b22662673442747e1fc71032575bf1594f1045", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "eea4049ca78edccd3b948f0e2b7c8cbf871f89ae1394f94b50f65fc09796ad99", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "710db57603c5934e438fa80df365bee889e1e3f71f6a7045d72eb17c552b1641", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "348e2209ed36367dc4b136adb9b23c21245964a4ad5b38d4b8d4b31cd49e7506", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "f79b14fbbe0966de0ac161ed1761d5909ae59778a2b92fabaf616227c5dce3f1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "540c105368481a74a43e8cabaf7cb6be7d3706a5e4f112eaa8bdb8d5124a4bca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "4a4544f941512ed51392cca5675c5a347cbf3bab6926c5d91f3d43b3fd7e4d9f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "7e14a717be60b101493bc91acf433c5fedb4b083929265e77aaef8dd39d022b7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "ba6a6fa2d1e614838e3c42d3631c7141ac243fd5ec0043aefaae2b02d6bf7e82", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "4ad6ddab54371cd861831d5bc9c983585b3ee8256348ae8a146ab7be28f4b14e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "b9fdfa54681322245b5abfbb9083b317bb1186ac57513c58f7f48fa659f1880c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "cad82e0d5500d9f3a66399831167fc8dd74c4f3e09c7b11a7bd4e8f1ef317a50", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "87fb86b144498bf5e9806a9202f667396497f1240cb9fe627de93264811fe9f0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "29280eda5a952b8e587f7879bb3ebb9df022fbd7e7558491a3d29f46b9db7ea7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "8b44dc752f3b4cf745b12fcdd45c2ddb5814731940c1cabd7ff127fa2000689f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "243e003567530a4e18da416a90a1cf5b0bdbf5d2c65a37aa4e21b6cd73dc1ff8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "fb29e43a9d268c18045292358d51617d6e38df4e3e07fc8d84245a5500dc2b35", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "ac1a91f6aad79e26ffcd6865c01856c22329a9778c135f0e948345d57e91bc36", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "97c7119740b2ef14d94ca57e13fdc938a99f0c964a73255694252b80ab4ef28b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "06518fdb00e0192ad5d602785f61177ccb26aba57f39879e5e8e209cb44fc1a0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "88298d7d2445cf224da1ae90eccf794d528b399d8a2c46b8bd9b740b8557f283", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "bb2f5f37ae21096cdb47652d47aa4cc939b3dd9cc6e6ca0fdbe9490b1f16de9b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "943d560c53be779bc5b3ca5ee916ca2e5ece20c0789b790ef2282e49b05a4c86", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "25a8bd5f49bb918248ea60cd107282cf1dbd34398651b699565985b8175e1cb3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "399acddaa120a3a7d74bb8c66c9d0fd93ceda7441af8fd24f18ce0b1a29f24a5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "d88d41e47aa4b5b933b48c3aff894d34bccc7374ca231253ecc077d47188dbfb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "d5393c7362e4407553883f372b914ca3bdabf68abc87724246186a394b8e65f7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "58d9fa127ed430b1c7feb88e41ffcc905fa4b0f3831f7a4b65e1759a0d2fdd27", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "04e8a9fd2ff77d3e9979394fcde54620ae6cef55a719dd3199108aae6d16b3fe", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "1694fb768e08b7c71a6cb0272c2f37f47f10443dfed59b3f44caf9b6620a319a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "17df0592c06c1282d527ef16752c579eab1b53e0f1d11948ccb088e34985e0c5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "4cb806a8892e40f4dbb12b41b4a8151b7d3792a2dd253d8bf2e2a7fa638c39d6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "45f1be1531f9e0c337b713b1956236bdc9944c8a6d48f61f66f3fdd632af3297", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "c895670ce3dc53fb06b2d5cf0720b02a4ecbd1bbc514db54f91a0ae3c0fd7a57", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "806279169e0e2155c6610a696fdbfeff1e54971278a8a5f2d772d85e5779ea7c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "e90dfed54ca11970095458b0f9529ac9e4f72e5ef20b5e383caec3763cd356ed", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "7b2d35bc1ea646aecd509c84960b740d26658f266bc68c5c9840ea88b3c1d481", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "d046a8800d43af84669f6b37dcdefd0f0b41fbe02b4f35f72e379388e96f8996", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "fd9b3f07b10bf0703758a91ad8ab482ea191fe5b67ea0b94dddd1262b0c6ec2d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "1a30ae8c5931ce3968bdc12cb502da0ce52ba62b348da600dd5944ec0a918a60", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "7ff887a7027b8b1b37de8b0b5c4a41c960b0201b9e0fbd41c21f892c5368fcc5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "4937451c16272274f459c048d2182ab336844c44725db860304aeaa33ad2683e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "dd908c404674e0fc9b96ba52e63535b3e2d9c7dd810a708eb19f80a67a4d4779", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "f1700c18c0b81ebad5116433a2b4ea37d72fee0b694a165ac751d7bbbb284bff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "ed4e8443a6c0b3063552c9a3bb77d0516b260570dd57fa3ceaa63ca4979ffba5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "f1832ac4afbba7ca2be1b86ae01fa8911a14b112228822d02d0e35ddef1a14f4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "35a2838fbc462e1d6285d4c02da7fa7ae54228a1b6255af1c62f4863ab3928fd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "33355e3d0511bdda80a9f2886ec8284c7de568969b6a28160d2cf6a5e5fd98b9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "956c63554f4d6f11991a9a54ebcc5c4be73fdc84278fa8afe1156bb64ab004d2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "ae451e2e6e6d58b4cf39382bde915cdce3988eabd20fcc22db8a4326d010b25e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "87e73288074e6845c7f7ae7112af21940c923d2d6b41282843d89d3b361cda35", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "1e6f35541b130b97514f3f85fc7cb171995a1fecf81677c2a5bef0061a0d57a2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "b485b7d68f44da6d684c2e0eafdb5f62a9cf9ae1d8f8140268d6c84ee3cc6f79", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "d659de61385fc000a6060a67e940f341e06b273b63264c69d7f6b52b5cbd015a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "448939e8d77cca6b4a5e5f42cf6ead7bde184a59aebf2e5c08492b5e3ae20676", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "5a67e1c72f9659fa8e41ed6642aa6bc4d421956a17f3fe5004480a4900d3df61", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "59dcb530ca0998bbb3bf532ecbe346544d3f2e41b7173a51709592d677b49c69", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "c6c0f84348a7b55497883fc414b8797ba5fab970d7451caa8486c49642d865b5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e093fec3c52df6f36ceee3deb008d60ac62a195436a3df9920cd0181607cdac5", "target_hash": "48085ad7667bdba26cddaef21ce4b24f4bd0420cd833bfde40cf922e3d213f40", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -132158,7 +132890,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132173,7 +132905,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132188,7 +132920,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132203,7 +132935,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132218,7 +132950,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132233,7 +132965,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132248,7 +132980,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132263,7 +132995,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132278,7 +133010,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132293,7 +133025,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132308,7 +133040,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132323,7 +133055,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132338,7 +133070,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132353,7 +133085,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132368,7 +133100,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132383,7 +133115,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132398,7 +133130,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132413,7 +133145,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132428,7 +133160,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132443,7 +133175,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132458,7 +133190,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132473,7 +133205,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132488,7 +133220,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132503,7 +133235,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132518,7 +133250,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132533,7 +133265,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132548,7 +133280,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132563,7 +133295,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132578,7 +133310,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132593,7 +133325,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132608,7 +133340,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132623,7 +133355,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132638,7 +133370,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132653,7 +133385,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132668,7 +133400,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132683,7 +133415,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132698,7 +133430,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132713,7 +133445,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132728,7 +133460,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132743,7 +133475,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132758,7 +133490,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132773,7 +133505,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132788,7 +133520,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132803,7 +133535,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132818,7 +133550,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132833,7 +133565,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132848,7 +133580,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132863,7 +133595,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132878,7 +133610,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132893,7 +133625,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132908,7 +133640,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132923,7 +133655,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132938,7 +133670,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132953,7 +133685,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132968,7 +133700,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132983,7 +133715,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -132998,7 +133730,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133013,7 +133745,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133028,7 +133760,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133043,7 +133775,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133058,7 +133790,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133073,7 +133805,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133088,7 +133820,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133103,7 +133835,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133118,7 +133850,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "fb659fe65202ac95adba54d3a9588453914f7abf76f686706dbb616140304994", @@ -133133,7 +133865,7 @@ "77fa66951d15", "2781dd0616bf" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -133143,7 +133875,7 @@ "pl": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", "target_hash": "0e801aaa401a0a66fa9dad8b1340f98cf4d012b03469eaba6ac029598279c09e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133160,7 +133892,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133177,7 +133909,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133194,7 +133926,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133211,7 +133943,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133228,7 +133960,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133245,7 +133977,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133262,7 +133994,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133279,7 +134011,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133296,7 +134028,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133313,7 +134045,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133330,7 +134062,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133347,7 +134079,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133364,7 +134096,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133381,7 +134113,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133398,7 +134130,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133415,7 +134147,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133432,7 +134164,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133449,7 +134181,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133466,7 +134198,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133483,7 +134215,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133500,7 +134232,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133517,7 +134249,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133534,7 +134266,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133551,7 +134283,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133568,7 +134300,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133585,7 +134317,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133602,7 +134334,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133619,7 +134351,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133636,7 +134368,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133653,7 +134385,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133670,7 +134402,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133687,7 +134419,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133704,7 +134436,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133721,7 +134453,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133738,7 +134470,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133755,7 +134487,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133772,7 +134504,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133789,7 +134521,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133806,7 +134538,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133823,7 +134555,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133840,7 +134572,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133857,7 +134589,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133874,7 +134606,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133891,7 +134623,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133908,7 +134640,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133925,7 +134657,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133942,7 +134674,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133959,7 +134691,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133976,7 +134708,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -133993,7 +134725,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134010,7 +134742,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134027,7 +134759,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134044,7 +134776,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134061,7 +134793,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134078,7 +134810,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134095,7 +134827,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134112,7 +134844,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134129,7 +134861,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134146,7 +134878,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134163,7 +134895,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134180,7 +134912,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134197,7 +134929,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134214,7 +134946,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134231,7 +134963,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "dddea3aa9ec515ef8beafd4408953b32dde8ffa9d427c0e7fd564091c7b19660", @@ -134248,7 +134980,7 @@ "dc43cac52c54", "534424b3f74d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -134258,332 +134990,332 @@ "pl": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "944f69236e633b8a9feebc3ab4ef7aa6258efa39c05dc9fd087ea16b09cf76ef", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "8fff42f6575d0f508bcb65b784782a7137f6a8e7c6d467bf9b41c998dbc81c91", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "1ab91e67880340a6239bc87ca6b9e7dbe7d011b94f60c03a927e839aa2a47ff6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "a5efcb5f9b573fa3e0efdc74d00b0e8bf29b9c12f8d2bfb51fc30765c38af1f9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "9ce83de74756097f764a55b997b537cf15de32b70a8dea311596673f66d22eaf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "0ab206e9a53b67bd973d71391812c229f46412d000066ffb3d584dcd53349f76", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "4a8bd35005d985a86a041c4bb1f36233e06db3687e81ff26880b08028128496f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "fdaec2e0c80990c26e39092b35b15b31be5594add3144effce57298496411c04", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "c67f301cae91432870e1f0257b3810020bd884499bc9ad532ae9c5fb7fd8464f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "aded39480e47c9c07ac8e9d680800da6e692b64a43071098b9f0dd711f49a8f1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "dd55af94de4d7aae142b3abfb74e683c32c7258e9df7d015b6f352fb6e482643", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "224db9dafa2e55879d3c02c151267e52d981950a3436681076e58c44c5d24af5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "8c35a60ebb2f4394e6af264fbca83a077c9ce787dce56d531019f98b00f863e9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "b2956ca945951a61aab1245ed7614623cf7db7e9ccf19a52d8623d13b35e1c6e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "df591062bcc93f881d679d113798be9cd0272d5c8bc1e328e08bcb497908bbda", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "0d7b1fa81027d0d3f58c889445b75c6c9232787a1cc498cd29631b2e21261ab8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "7bf24213e006d924638f0e84d3121f1d40ff8f7dfa4d111c8bd9bb3306982786", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "fe66b6006f8c094f307c7fb2f580ae0989a740baf9bb0c94e0a39bb9413b53c9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "2f0ae88d4bac8d0fb2353c529038a202a881c76f35c364c41e6bc176fb3436ec", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "4b43e5b6590fd82b0c5a4a40843ea24fea5b602ac51e8502eef4f4c022f2cf95", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "1753b1a54f9061905ed2df9462b39bb564ce4057069993ef12a58833a7366f54", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "e2808e4fbbd418d770da7a064e34c9961df2e095fafb1961ddf5ccc263eddfcb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "fee1b333e838ca7377eb4681e26eaf10f23467578765b6f6d7c9c1f2ca649a4e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "f00f02d32a9e153bba4338bb85276aa0712c26057dd5dd5fab7cd8ee97dd8e03", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "668ff52ccbf725cb020e49b00ed0ddb042754c25886e9934bfa448e6eea11fca", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "0f4060a9c321a2389ea806516484dfc3b399e7577d511728c9763bc8ab421760", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "5db3200d758c11283361cb82c267fd2283e042eceeb3df7449b172dea61c020d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "d2562c13148c7b8f93397c13029351c10ecbec4c84593d5a21e1c4ec651daba9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "1790d6632c0ce1c09bb7bc83efbb4855acb79f0efe76c414f38a8b27fa478966", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "ec1cae7eb127e0ce00cd9d9d1d8b9bb34bd639d01320a18712617927b3cc094c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "11b2ab34a72ef82d1278838cbb50e52646a20f69b96a922c47ef85c697702994", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "a2627aa64abf5fe23ee871290f063a17a3e3c02dce6f66ac196ca191341e9cd8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "b02921c131483eb3b624677c86b20baf204bf8600f2e1feb1027a72923d06fe6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "5fa5d329b29ed020b8aa87226fbe7370bd1d83adc2de16ed7c9b7e9ad29d1f0c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "c0ad6c7c7ea21deea10d27bc7c655faaeb2826dc969cb9750733bf015fd94442", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "c5a6ac13b718d7f09a26ead85b647ac7a1cac98905c4856ab29de278936b672f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "05edacc35daad51ebb28a5c9223104175035655b7a2cf7362cf3a917429fe4c9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "637d12a7f50785443d7703fc70d9edf9e4ba4f79a7c59fefdf3ced55adf472b4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "bc82cee9379d8c08d1dcfe5a565647e84cd39cf0bd2bc8821718c4f98cf4c2ae", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "9a10db023499c47d0df2ec3f90fa13a49b11dc5fb6e443aca58b634994652f68", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "97785eae15a4ed0d053368a31e401db0e09513323fd333b268aa863c8849499d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "846480ae20469f7a8382e3f7de2110ff1e25916c139c6ada460f33e110cd89dd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "1817e84520e2cf374582ad16198c1df4dc23419daf7fc89dcd72b85a3b075f08", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "21e8a64fa8b82b17aef2f75bdd796990347e88781089b6aaff447b32355851b6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "61dcf14d438a30dad327bc5924bf3c6c22728e094193b4ebee6516cfc61cb03e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "4fdc69420373534af3a6e5c4853d6647b3dacdbd2c1b23199b3a7acf929dbf1f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "ddc35243cbe89ece6e08679ffdd8017351f505c7fd03bb98bc1f6938e5eb0754", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "e753e68fabf0b404bf4a789167a4dc8165942af1ce105ea9ffd9dd1c2aaa43c0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "7e654208cb8320f9aacdfc310aac51ba02866eb369a9de2da45e90b90674df7f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "4be17ee4ef1e1f3d2adf49092fb8ca80b76e386893ca20a069b955725a193409", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "87d7f39d69bddf71f3c7ee9f6fb8e9b33b60ef42a4b68cfa20b51d0d9afaafd6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "fd4a92899222bef8473cd496cf033fa30d4fffafa881c0d28fb80dd96829f029", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "e75284f474902d1e591d1782e90283e6bdd9599088dd12645c9e8c46a9cd5158", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "520e971112a061f8f1e0a1a967407480f3d7caa7d91c92f242136af0386f8d83", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "3df82c82193e0751dac480fada5e37de31df078b20d375336317415e501a65a7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "4de8975d5750ce83bd399ac282c12f3b7eb7e80e084103d8fd4c930ec9c10d69", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "b1745fb857bc7191ccecb46b3133904a8d37be77ac35745baeff862dd7d0bff4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "dba1905027f595809079ec109d02d611c446ab6cba37a087d102e6c02307d1d3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "0f2eed94b401ee4fd22643bd22cf7303a2a522059d7cc2494c9ee6d9c04afbb0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "a9aac4350f2481710d91f6d65b9b5e7828bff1be4d43eb7bd95150c1c6c709db", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "ecda1b2127fe1bd8727f331836b7304a9423c5d91a0221798002aa45b09975fd", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "0e21494a1d0ba6abc26bf35e09137da119b14513e5748985ec6eb6292bbdd0de", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "18289a177da2d67331f2ed11768916cfbd011d87e6c7c76cda5d382f5269d761", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "3f9c5d8d5b01d7b9a74a084e1185749b72261fa67bd7f36dc7bedc8e9669d034", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "01d6ab5894013dad92142b9e2da60117c916aedc339157876ae456870c89f369", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "197c1803b069a9372b800e9d8e8508379217b4b37cb1cb0c74c050c461372f17", "target_hash": "bb5732f54168ec33dea4769e2a96711de8f0d45a1bc61e798e1581af3244ee77", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -134607,7 +135339,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134626,7 +135358,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134645,7 +135377,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134664,7 +135396,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134683,7 +135415,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134702,7 +135434,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134721,7 +135453,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134740,7 +135472,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134759,7 +135491,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134778,7 +135510,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134797,7 +135529,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134816,7 +135548,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134835,7 +135567,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134854,7 +135586,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134873,7 +135605,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134892,7 +135624,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134911,7 +135643,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134930,7 +135662,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134949,7 +135681,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134968,7 +135700,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -134987,7 +135719,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135006,7 +135738,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135025,7 +135757,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135044,7 +135776,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135063,7 +135795,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135082,7 +135814,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135101,7 +135833,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135120,7 +135852,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135139,7 +135871,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135158,7 +135890,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135177,7 +135909,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135196,7 +135928,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135215,7 +135947,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135234,7 +135966,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135253,7 +135985,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135272,7 +136004,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135291,7 +136023,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135310,7 +136042,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135329,7 +136061,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135348,7 +136080,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135367,7 +136099,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135386,7 +136118,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135405,7 +136137,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135424,7 +136156,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135443,7 +136175,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135462,7 +136194,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135481,7 +136213,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135500,7 +136232,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135519,7 +136251,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135538,7 +136270,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135557,7 +136289,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135576,7 +136308,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135595,7 +136327,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135614,7 +136346,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135633,7 +136365,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135652,7 +136384,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135671,7 +136403,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135690,7 +136422,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135709,7 +136441,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135728,7 +136460,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135747,7 +136479,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135766,7 +136498,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135785,7 +136517,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135804,7 +136536,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135823,7 +136555,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "e479a28f054074737f805d60e3a71d63221cd1ce9f2e0953aa4d18e73bd3ee40", @@ -135842,7 +136574,7 @@ "207dcdd907de", "66ce74b2d562" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -135862,7 +136594,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135877,7 +136609,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135892,7 +136624,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135907,7 +136639,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135922,7 +136654,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135937,7 +136669,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135952,7 +136684,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135967,7 +136699,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135982,7 +136714,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -135997,7 +136729,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136012,7 +136744,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136027,7 +136759,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136042,7 +136774,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136057,7 +136789,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136072,7 +136804,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136087,7 +136819,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136102,7 +136834,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136117,7 +136849,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136132,7 +136864,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136147,7 +136879,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136162,7 +136894,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136177,7 +136909,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136192,7 +136924,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136207,7 +136939,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136222,7 +136954,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136237,7 +136969,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136252,7 +136984,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136267,7 +136999,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136282,7 +137014,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136297,7 +137029,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136312,7 +137044,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136327,7 +137059,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136342,7 +137074,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136357,7 +137089,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136372,7 +137104,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136387,7 +137119,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136402,7 +137134,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136417,7 +137149,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136432,7 +137164,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136447,7 +137179,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136462,7 +137194,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136477,7 +137209,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136492,7 +137224,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136507,7 +137239,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136522,7 +137254,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136537,7 +137269,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136552,7 +137284,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136567,7 +137299,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136582,7 +137314,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136597,7 +137329,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136612,7 +137344,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136627,7 +137359,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136642,7 +137374,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136657,7 +137389,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136672,7 +137404,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136687,7 +137419,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136702,7 +137434,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136717,7 +137449,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136732,7 +137464,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136747,7 +137479,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136762,7 +137494,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136777,7 +137509,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136792,7 +137524,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136807,7 +137539,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136822,7 +137554,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "812bac536ad139e75539de11f3d1e1df495977f9c63d15dfedf6a40eea26d15c", @@ -136837,7 +137569,7 @@ "c0a1129fd179", "c5645e4bf6b8" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -136859,7 +137591,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136876,7 +137608,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136893,7 +137625,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136910,7 +137642,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136927,7 +137659,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136944,7 +137676,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136961,7 +137693,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136978,7 +137710,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -136995,7 +137727,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137012,7 +137744,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137029,7 +137761,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137046,7 +137778,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137063,7 +137795,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137080,7 +137812,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137097,7 +137829,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137114,7 +137846,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137131,7 +137863,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137148,7 +137880,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137165,7 +137897,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137182,7 +137914,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137199,7 +137931,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137216,7 +137948,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137233,7 +137965,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137250,7 +137982,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137267,7 +137999,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137284,7 +138016,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137301,7 +138033,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137318,7 +138050,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137335,7 +138067,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137352,7 +138084,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137369,7 +138101,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137386,7 +138118,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137403,7 +138135,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137420,7 +138152,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137437,7 +138169,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137454,7 +138186,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137471,7 +138203,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137488,7 +138220,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137505,7 +138237,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137522,7 +138254,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137539,7 +138271,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137556,7 +138288,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137573,7 +138305,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137590,7 +138322,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137607,7 +138339,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137624,7 +138356,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137641,7 +138373,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137658,7 +138390,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137675,7 +138407,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137692,7 +138424,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137709,7 +138441,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137726,7 +138458,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137743,7 +138475,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137760,7 +138492,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137777,7 +138509,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137794,7 +138526,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137811,7 +138543,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137828,7 +138560,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137845,7 +138577,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137862,7 +138594,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137879,7 +138611,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137896,7 +138628,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137913,7 +138645,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137930,7 +138662,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137947,7 +138679,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "787f26ee7c908a968e820adbf444b5e87e08eadf228e646f18945c24f4c7be26", @@ -137964,7 +138696,7 @@ "41864b605a74", "8c17200a15fd" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -137974,7 +138706,7 @@ "pl": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", "target_hash": "5e0701b9d0a306e5a6bea8f049d29913a72a37ea8592bc574a1ca96079d02168", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -137993,7 +138725,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138012,7 +138744,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138031,7 +138763,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138050,7 +138782,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138069,7 +138801,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138088,7 +138820,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138107,7 +138839,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138126,7 +138858,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138145,7 +138877,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138164,7 +138896,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138183,7 +138915,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138202,7 +138934,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138221,7 +138953,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138240,7 +138972,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138259,7 +138991,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138278,7 +139010,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138297,7 +139029,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138316,7 +139048,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138335,7 +139067,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138354,7 +139086,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138373,7 +139105,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138392,7 +139124,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138411,7 +139143,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138430,7 +139162,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138449,7 +139181,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138468,7 +139200,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138487,7 +139219,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138506,7 +139238,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138525,7 +139257,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138544,7 +139276,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138563,7 +139295,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138582,7 +139314,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138601,7 +139333,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138620,7 +139352,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138639,7 +139371,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138658,7 +139390,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138677,7 +139409,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138696,7 +139428,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138715,7 +139447,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138734,7 +139466,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138753,7 +139485,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138772,7 +139504,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138791,7 +139523,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138810,7 +139542,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138829,7 +139561,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138848,7 +139580,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138867,7 +139599,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138886,7 +139618,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138905,7 +139637,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138924,7 +139656,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138943,7 +139675,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138962,7 +139694,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -138981,7 +139713,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139000,7 +139732,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139019,7 +139751,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139038,7 +139770,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139057,7 +139789,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139076,7 +139808,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139095,7 +139827,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139114,7 +139846,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139133,7 +139865,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139152,7 +139884,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139171,7 +139903,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139190,7 +139922,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "56c3e1f4910e8e9484216e3aba9cafae5570e7fbcb45c8f4d20cf502e8456742", @@ -139209,7 +139941,7 @@ "62aef5b51f60", "2c33511fc4c6" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -139219,7 +139951,7 @@ "pl": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", "target_hash": "4788378490b19044a7ce7569360a1af42b6ef35754d637bae67342779f283ce7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139232,7 +139964,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139245,7 +139977,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139258,7 +139990,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139271,7 +140003,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139284,7 +140016,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139297,7 +140029,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139310,7 +140042,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139323,7 +140055,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139336,7 +140068,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139349,7 +140081,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139362,7 +140094,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139375,7 +140107,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139388,7 +140120,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139401,7 +140133,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139414,7 +140146,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139427,7 +140159,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139440,7 +140172,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139453,7 +140185,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139466,7 +140198,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139479,7 +140211,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139492,7 +140224,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139505,7 +140237,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139518,7 +140250,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139531,7 +140263,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139544,7 +140276,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139557,7 +140289,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139570,7 +140302,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139583,7 +140315,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139596,7 +140328,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139609,7 +140341,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139622,7 +140354,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139635,7 +140367,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139648,7 +140380,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139661,7 +140393,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139674,7 +140406,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139687,7 +140419,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139700,7 +140432,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139713,7 +140445,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139726,7 +140458,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139739,7 +140471,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139752,7 +140484,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139765,7 +140497,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139778,7 +140510,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139791,7 +140523,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139804,7 +140536,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139817,7 +140549,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139830,7 +140562,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139843,7 +140575,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139856,7 +140588,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139869,7 +140601,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139882,7 +140614,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139895,7 +140627,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139908,7 +140640,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139921,7 +140653,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139934,7 +140666,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139947,7 +140679,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139960,7 +140692,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139973,7 +140705,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139986,7 +140718,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -139999,7 +140731,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -140012,7 +140744,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -140025,7 +140757,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -140038,7 +140770,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -140051,7 +140783,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "3d0d4039ad665156ba9127ed93976b8544f9815f9739181bb4bab15a99fce6f7", @@ -140064,7 +140796,7 @@ "a7e3b91e64d4", "f1c81129d235" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -140084,82 +140816,82 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "8aaf5bbe7c4f4bee93eca8e1a5709eba72d2e2a1935eed56f63ed4cc16243f44", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "1980a703828c03c1c8cb92967a4d355af2d868002b241541de086e670eae68fb", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "89d5608c1cfa587a09b34ec019f4e08950a789f7e9ade49a33316f1f29c68ce8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "e77b48119fa059c4859b9af52c5aa09ff0c63ccbf0292f78d18c4bea84d22786", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "8be5d3360fe2c370c2168d7260edfd6326497feb3662b5f2138a8f82a38c65ea", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "c63c747abac8e047c9dbefdbe488150a2138672c731d0da8ba071aa08da433d1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "af8c7f8e1182a9d0a17b1e2b68e597cc51221075e2bb1148a172429e19000432", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "98a41988f318fea45d792574396885b28d3020c3c7496a65e261410e1093aef5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "bcc365deba749625e04b43b589c9cdf55f45e00237e73faefb88371447171921", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "55e28f5b77a66bff51344180641c8f5a4083a172bbd9994ec8a419a9c230b753", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "a5b73222f6981e674081171bae3053a80741af3a718168242f080ca8d751759f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "ad847d03da6b174eb5a9f6571f7840ae6ef2b1b8e4a2e4c2c35754e663b071b2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "c3b7211cb737e50e18cb9081fb8dc14c4cc6b84247a65499441b56f0c0719153", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "78dfd9bb658c2b89118f11a886788182cce4e326711c4b9a6d077f7ceb55211b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "407971c43916f768b0e5a0a46f75fc8ab414ee2d7facd9968f3181de75892d00", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140174,32 +140906,32 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "0e1dc345c16125e8b7cd7a795870e32af7338f0b54ec131d6894520e52457496", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "9c1698d0fd17d9f9ab7376b7cf30ff1637a6d12074ba71329fb58b763bc0a0bf", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "23ce6cca984453d887db9a5cb07f01791d53b44ea1aea8025fc01596263f298c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "d979ccb64e0ddd210b535c10f627e34d8b0f0f760edb065f3bf9e93075ca04f0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "ae0ed626b438472cfd3244c610a593a8cf02edca8fad67f69003fdcfae928639", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140214,12 +140946,12 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "98754c18ef0c1715d34fda3e3613ae7315634b6f0f06910c0d32a4637b3b50c6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140234,7 +140966,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140249,7 +140981,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140264,7 +140996,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140279,7 +141011,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140294,7 +141026,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140309,7 +141041,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140324,7 +141056,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140339,7 +141071,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140354,7 +141086,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140369,7 +141101,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140384,7 +141116,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140399,7 +141131,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140414,7 +141146,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140429,7 +141161,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140444,7 +141176,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140459,7 +141191,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140474,7 +141206,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140489,7 +141221,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140504,7 +141236,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140519,7 +141251,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140534,7 +141266,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140549,7 +141281,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140564,7 +141296,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140579,7 +141311,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140594,7 +141326,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140609,7 +141341,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140624,7 +141356,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140639,7 +141371,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140654,7 +141386,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140669,7 +141401,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140684,7 +141416,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140699,7 +141431,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140714,7 +141446,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140729,7 +141461,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140744,7 +141476,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140759,7 +141491,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140774,7 +141506,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140789,7 +141521,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140804,7 +141536,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140819,7 +141551,7 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", @@ -140834,12 +141566,12 @@ "ba950787cd3a", "b737fdacfb1d" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "0ddd67335f83435009773dfe38eb9f75dd82840714fae2627fc2016a5649f085", "target_hash": "194f80efdbbe8fcb1db92cbbce24b316a2ba5a5d0f6f65ae1f695b0b4836a0c0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -140849,332 +141581,332 @@ "pl": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "77bcd738cc8564025e6af17464a5fe899db74a67064ff6ebf9fca8b7763232a8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "4f8082c6fa04176aaf47a889223fffeafa4b6b4af8c3cab398acb59cb090e226", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "bd0b486c42f2c269093e15885a7c857c9b7abd09cc94976dade00a55b81ec553", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "c00bf9903d7f5d8f339353e3cd13ef9f0477e49fbfe54207995990d373e2e03a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "89660baa9978e8cbbdb58bd9a5d0aefef5ba61bbdef9627cd72e2eed564eca2b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "e2d3b6a1a221199c1ea8c94039b18050294185abe3e508329307630e2147ef32", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "83d8a7140b7116d2eb7cf5db28cd89a8527c327363e02126558e43b07a3f08b2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "0b4a86f6cc21328000b52486230a668ac75fef61ffe710f50c1361c0ee49c18c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "ebeaf11417fdecad5f71f6dbac0984a9120b824d165a1dc226cf2d9cbda57904", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "4f938f687a613fdc559dc902c2bcd8344bbad579189bfd9ce8b78ab67aeb241d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "fe4248469ea223ef30a0faec9d95378a1704d970192b678e0d21765a1c68e930", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "b6da0f6ca01dc074a025b3e64daa60ca3dcf955292f5386856f142a344617cf2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "ceee0cae1b894fe2b5f2bb51f8c4c9ac69f3c65ffc6ba8789e39784ce5b08b7c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "afaed746c3ced3f75b5fe0b998433db0f37ed342dbd3f8020c53b8e9d151f9ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "d93c5f374b75ac7567f7260fd6d7e2dc3c3a38ac7f342bcf24241079454c71ff", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "e3e5598292548302f785b399e3ea1c28c06894d8bf4cd78ec4bb9c47b1a7b7f4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "d5e67e59d5783cd6d1e69665c3f89ac84cdb2fab5782839a9be56cd5e61cfd59", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "f671c7247d26d2fc5861f613d228a252d143221fb9b9578bec684b51e0d6cd94", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "e3f03e7d2dfbbe68569ec43144948916e9d6cbfd650e57337229fcacb30e871c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "0f085a1a695696882738dc8b44d338c197d14633f517877dd7821acf2a6880e9", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "fbe07e738df21d4008a7d7085c271721228067b71a2dd9bb2815b5ca9abfaa9b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "1483968dc66973922522f826c5cb2f0e84a21769d22c123ab99e8abc329047c2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "cf0920f2ace5ac20c561efacb2a4109453bf2781514c48efa789c05da9995be5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "a2c46e46e57879488bf77164acc9a0be357d241f47fd9cb5c11adc60a2cb961b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "da12e19ed4fed9ef7910bc352d2f7880a955b79a2d8ce114145b5053ca822b11", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "3fe0a0cbfba390dbe40e68b78630621593f4b01e70624475c1fd4b7959875256", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "69c7e0e786fccfea38c22f62591c957d290100b6db847c3d4eefc93fa549bfb5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "dc1d990060d831867c6d0d219fd9daec3902967155dc4457316b5986eee7ac75", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "a54c820dfa72674ea3c9f5d74619ce1e633c75ae5a41ac55de4258738203747e", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "56ecded4e8e2fc15c397c43e27daad9a0e461aa1b82e891b178c106af3826ef2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "f8a2aa61db2a3fcd97838881f36718ec6d220e994afe1c83512c94da92e4e9f4", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "818428c6bd731d43b8f3bc3d97168d3ec2de3e777204cafff99c67bd98b57757", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "a5d11fffc39f5852d9a800559f77817393a7874c8e16aa7722d8cdcc8b5bdd86", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "10c51f1aa1842682e487c5b7cce3dfa648d30f8e9a3a473ef7f24128b0449b43", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "078caa83f1908d0b24f5cc688ba6977bd85fd62f87d8f8122105cca8ff4b46aa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "98b760827749b4f7293d7b67fbc54a2d9862eba418f484e7a8c93405d48de222", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "c4e0bd8ec9c865ae5ee8726c0bdbc62c96e5708fb9f63ab265a998da994484f2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "81dcdd818de12258eeb5a81935f6279bb7e9bc8add39d0fe4246d9e936ec80c1", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "427e6338755a04f3290eb3815deac2d7bcae85405d4f76b88591581ded352d99", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "1eaf9b34a74e9b275d61cc044bc0e5063dbcaaf1981c4dda5bf2fc4a0d43f7b0", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "2b0a7b852540dc2ca8a24e3fed9c4fe1175d579a6447e3a46d34ecab961972bc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "95c0c9018b1a90609310900386ec20e80f69acad7722a32a85986d61c255011b", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "02ff489693f26589fae68849d2aa1dcba05fa37782f0bfa557b50e20de66f65a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "19cc6f1cc17ac43543c84ec42a316152453cd2d176fcfcf978b06946e0760cde", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "f1645db4f8ef795101d023453c9b803898fe27805230f388d9ec7ceadeb68a22", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "bf1689e1ce7d38b95e847b69b02a777896512f3b06074604d4b76f5c9ce2ed03", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "976487708937a29fd44496476661bbd8f3a41a6bb3ecb49fc228f381cc09c3a2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "82bd70b6b1d257c84667b4a54e90781ed81d4ca74bff1ab5ccbf8fadfaed68de", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "1424baaee072e0e1b9b56aca7b3ff95b155fe17fbf9502a2a86d08f4c2e74d42", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "c44233d2a6be52bb5004560ea3012aa891e1a34c715e48cc92360316fa05c490", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "a26b50ee038cc80cd881bdea856ca923b82eef1ab27b9867787d40a66250d23d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "d80a4b9e23dd7de40308452e241e128820eca1d2094669da0a95ad5371995bb3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "f5b879eb556d3114ce33203ca812bd66065934f05f5c8ae73697f7ef0af9dcc7", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "25ebd088cb8163ea0d9acab5d50cdcc77e34650fb49141e9c67275d2a5e910b8", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "53978fde98b0cb85fe2746baec62550e92445c5a91534059f15f54178f3560fa", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "0dba0ddba3ead63ce8e3427882b2f12db0bc907f2eb7ccdf93375a6583878e2f", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "303b06d889e2cee15e4ae81b43fd038451842bbad5f8299b9c11c13166124776", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "7885d45c745e950893b4de22f1599e33a858192e4599d546e71c789db999b5b6", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "3b39fa96e1d90b8c0ff71b0c8b20c8eb397c2bd1ea4a4a0e409624c19b4bf9fe", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "d5482d648bd71dca83c3bd4daec44aef2f567f3016548bbdbfad9014eeec3907", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "7efaccf9d339bffff2843a5da4781e3d4538107e97f7feb99cfef0b1d03fb3b3", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "2ee792e0b4acda30ab881b86585f7e1585bc8a927937f7ff101f0c2c2e34a1e5", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "7918215df2e40d71f82359294d0cd2bdf0e26b15781e6cd45df256d20cd0c815", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "b7e5527dd0ca5102d80cf839d401c645893c5a3893b3f636284ee6f6bea3c5bc", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "ede743005f3b01bb5506862d18fecdba1a5957bf40b28d4777a1b94c431a9c8c", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "b7d3f25cc5e1c336a9a96e0f288b53144e05c5e75f3df9efb2a88ba595c4670e", "target_hash": "c21567577199d176fd5020635bd0755656fdc3d8b430dbc96dc1e8cc00719f7a", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -141199,7 +141931,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141219,7 +141951,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141239,7 +141971,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141259,7 +141991,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141279,7 +142011,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141299,7 +142031,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141319,7 +142051,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141339,7 +142071,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141359,7 +142091,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141379,7 +142111,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141399,7 +142131,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141419,7 +142151,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141439,7 +142171,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141459,7 +142191,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141479,7 +142211,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141499,7 +142231,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141519,12 +142251,12 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", "target_hash": "4153f836574e300123627d72acdc3e9409b2ee9a6a1b82faebe02b6c3bf628b2", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141544,7 +142276,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141564,7 +142296,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141584,7 +142316,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141604,7 +142336,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141624,7 +142356,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141644,7 +142376,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141664,7 +142396,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141684,7 +142416,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141704,7 +142436,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141724,7 +142456,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141744,7 +142476,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141764,7 +142496,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141784,7 +142516,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141804,7 +142536,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141824,7 +142556,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141844,7 +142576,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141864,7 +142596,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141884,7 +142616,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141904,7 +142636,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141924,7 +142656,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141944,7 +142676,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141964,7 +142696,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -141984,7 +142716,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142004,7 +142736,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142024,7 +142756,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142044,7 +142776,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142064,7 +142796,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142084,7 +142816,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142104,7 +142836,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142124,7 +142856,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142144,7 +142876,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142164,7 +142896,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142184,7 +142916,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142204,12 +142936,12 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", "target_hash": "910b0f971350ce2b8327f73326fc69f181e68d0916c1ce7814ea131ede22341d", - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142229,7 +142961,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142249,7 +142981,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142269,7 +143001,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142289,7 +143021,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142309,7 +143041,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142329,7 +143061,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142349,7 +143081,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142369,7 +143101,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142389,7 +143121,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142409,7 +143141,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142429,7 +143161,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142449,7 +143181,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "403438cd5bb999f088c0c0d797f097b325525301fd382d0526fdfe571ee69d99", @@ -142469,7 +143201,7 @@ "43e82f857be4", "87f4eee642eb" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -142480,397 +143212,397 @@ "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "1fe90e241c9ec2d704ade0e2a1b2e3a60dcec5b9ab02102140bdbb883b474c89", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ar": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "f753c4676bee6f4183f25ea97c4d3fca458a4a1881605039b0926549569db403", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "9039e6535e7b2160a7e1031615feea3f6fe36a4c7aa56c51b45d60db94f804f1", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "eea3b105bbff56aed73a18d2cc8e848b6ac71b21cf59ed25ed7b42a27ce5eb3a", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "2caa34a25cbf35df78f0e7f55ae99424148c7c583743200ff550d2e344169953", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "35f09aeb0dbefb7c732a1e5c9c772758e9448419cf347888b87054dd89978b88", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "6d323fc7748bb975ec235b6edc78d717c08974533fdb9b49c954b1f89574da39", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "94f1f6dd80948cf46a03d3f65fae141a7cb541961dbefcfff0f5a374a6cfc87f", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "5a0fc9e7e44aff91d2a3275d23fb74b2979fa3317a67c244e4a2cca41a1632cc", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "cfa5c84689ae970585e6cded388aadd07a3badbc1b857c01fe98ca13dc7628e4", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "795d6c8c19e554e6cfb200aca3706e14c912df93e0e7b076cae711f4b8ebc007", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "213b4fb46df62e2a10ea788baa63180b085ee9f485c45b6ae529838ac5e0682d", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "9da4ff5605ebd81f814882958ef13894a1cf07ae3c5ca7c2d2afc9cd5afc3379", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "8936ddd81cbe3f21c8c1f3de82441aa82cea7a03b4e5894749f2191036bb9e9b", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "8d39f80fd78d3eeb2e57f96611f3114974b1442e4cb6913bf273891f4d9c0ad5", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "e6a675948d4dc0d6fefe8f7dc81fa818a06c42013e440e45e0ecf4d6e92ac789", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "bc625ee4c99269d90f4033b59fe411b8846fa9c627736a5f20a09d249e9e99d8", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "bcc14bfc8d94caed7e949a8c46b0ffc7f69ed81b1162d6d92c49067e1f99ce33", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "99e99e618df3cb040d4e0d19584726cb1f44dc3f923531ab75a96b7f153a91e7", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "94441933458ef7c5a717978067a8c427ff36b977e05a686122ed6f3d3113c617", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "b35b430c39629ef49bc2ad3cfe3c23a78d7cb1b46cebba151b416f08ed86cd6d", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "7391b3c24ce902f0447a34579eecbc654df9ad6e756d281d94b35224080a3b27", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "58186659d5335db8cc9d61e214a12317aa527a7a75f67b4d61da281b7afe053d", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "00b233f53789a57a961825b44f9992e1f1c1a8dc5215cf930518bbb3fc4aa17d", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "ead4f9e57b4ee0db495218c7f2c7d895e37818544a24384b32c19d4bcfd0fccb", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "015f49a43040593b10921c86506b0823e0676491ee4ae8ada4cc6094045f6838", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "846bdac80e39320b6c21bc56dece5c491a59ea1eba22ac325f27455cd456654f", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "818c97e77fec0543ec008d7e52337483768902ad0cacfd66e4e04a87415d8b7c", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "a65632a45e481e567dccee8c40479d60775e97128bb55202e2c18c18e638bc89", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "c9495b894ddbeeed5801e6a75479c42dcb49abf1e256946717e64357459a9d09", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "29595d0ebb0726baaa5901f43d94764b4e3ac7da3fafe5eb9acc5dd4a37d1e4b", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "50faf7ccf63f5b5e5706fb88de4e57b86d24553302a5aa32a77faa6debe84d4e", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "b8faf81cca97e9d3e68f530c52b94dc407d369fa9454a1a839107acce8d332bc", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "c7b1d4f80e67d5ff798f177c160dde5dfef3c6516ffb974d49af9f7900cf0e45", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "442d1b31f9b5569728e3e0802edbfb1186280e0c582d37b221a0c6b617b284b5", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "7f02c861a56b8decd97100dfe57274b5959b2555e80f6433f450a7cad00f3d2f", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "5749388c31b673e057017e171002e098e9608be8c06638dc8d0a719bbebb6fa9", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "528420f30d06b807336987f9245226cd32cc856b8fc648d915c00ac9e3664571", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "d4a50d3a7b5cbc092e543ea67e7fd80a2d9dadd7e702313081fa06aaf39fbaca", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "8b78081cc80dc1f0297b3033a904f9c91b8ab539693e33af39a4d98c6b1a54a6", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "d029b653a4689a930f7fa398edf06bde3e9462781ae24c09ed8a166fac81c0a9", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "b112052cb8789380ce42070abe388ab311c7968541aeb751c8dfd8b5a1f2f5da", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "4010ccb69e21ead7b22127c25b847c682bc56106b2c40336c454129f176a7904", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "80aad1d3de3c3584acdb4879d19e0963f3354a262d553839f8544498b31833db", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "3b1b2f730af12ff601a0805da295b87519e6015e67cba1d84814032b9a1fcc96", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "d3eeb83f62f0a3bae48ab58636a7f6dc1e38862e44c1b2e2ea57a833009f11b2", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "28c3a7e844e2126471a225512eacfb72567af79ca36ce5de9dfccd5f86b54629", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "89d1ac8a30497a7fcc084efcc6237394cfe2e83a9e60cd4f5224f217bc39d4c8", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "25e5803a4bffd4b9bad19ec09c009e8d4567abdda11f6c03e1bb98098450e056", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "f0c1ae41938c0ee638dbe4787ba8b4af05d5e9abc8b4551f59c4831f4c52270a", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "b71d07466b2f1c078a8ddfecfb5a0e2000d6911b7ccdaafc06ca4924b67d46ba", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "8b536b8c67d2897cfc5d8b9cde6d1827822dc596cadf06c4338c876a5f2ada91", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "3b3b04d0f36f4c833aea66dfb2ce7906917c61e3c43cc5393df322e414f19d72", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "19d559b1d9f61246af2da4e3893fa7abe99f434237c705081d141bae2fa924df", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "758379b969199ce862ad30b88423bd8ba04ccaae1e2990cb7095231054ca255e", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "dfe41c12e95f017f58b44bca6c04406813f0224891385506d52d1c7ce56bfb2b", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "7cabc2f8d2622ad75655a2d16d97535920f7618eb5a02fec21b927b3bba22b60", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "bedc47cc1c2d81490f7f833eacfe65c52d4664b8de69dc95b12c6eadc34e9980", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "af8256d6285e8c0e6e8b2b496f0af92b1f20666419ff73b3d683db23fe3929c2", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "a8c20775c917665dc0fa30ad9d3330286d46f29003c4596a60ab92fe7098bf26", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "98942174a60f64f70c89b3cd9e31d1d04427f9e67e109e2ae20eb617a3a398dd", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "62a9bb7e9d03b2ffc9a7e2e5e405324dc26a32495b05b8edf690ac70502fd58f", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "cb69f5738632688477a8f3dc7920be7fe778606239db71fc46c7e2a7110f2fd7", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "e70c29617431d740d8cd9c97289cf3beb1b16586cf59ff50bab82dd85b4a10b8", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "ea0a3131a7c4275e26355d8afd9cec3eeacfa6da9800a2baaf64ff2c97ddb55a", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "136d6d9a6d9ec91f12afc2bc7a78962deaa999b5014bb0c18343d825988cce14", "target_hash": "d592593fed8a0273d6947739c9400af8117e64e02d30e1d3dbf4da691e1369c1", "section_hashes": ["49d2e9fff519", "375bc8492229", "6f84eb9669ab", "9199a77a4bb5"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -142891,7 +143623,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -142907,7 +143639,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -142923,7 +143655,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -142939,7 +143671,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -142955,7 +143687,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -142971,7 +143703,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -142987,7 +143719,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143003,7 +143735,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143019,7 +143751,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143035,7 +143767,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143051,7 +143783,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143067,7 +143799,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143083,7 +143815,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143099,7 +143831,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143115,7 +143847,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143131,7 +143863,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143147,7 +143879,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143163,7 +143895,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143179,7 +143911,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143195,7 +143927,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143211,7 +143943,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143227,7 +143959,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143243,7 +143975,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143259,7 +143991,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143275,7 +144007,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143291,7 +144023,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143307,7 +144039,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143323,7 +144055,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143339,7 +144071,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143355,7 +144087,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143371,7 +144103,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143387,7 +144119,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143403,7 +144135,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143419,7 +144151,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143435,7 +144167,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143451,7 +144183,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143467,7 +144199,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143483,7 +144215,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143499,7 +144231,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143515,7 +144247,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143531,7 +144263,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143547,7 +144279,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143563,7 +144295,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143579,7 +144311,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143595,7 +144327,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143611,7 +144343,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143627,7 +144359,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143643,7 +144375,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143659,7 +144391,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143675,7 +144407,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143691,7 +144423,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143707,7 +144439,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143723,7 +144455,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143739,7 +144471,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143755,7 +144487,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143771,7 +144503,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143787,7 +144519,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143803,7 +144535,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143819,7 +144551,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143835,7 +144567,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143851,7 +144583,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143867,7 +144599,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143883,7 +144615,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143899,7 +144631,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143915,7 +144647,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "d666da44da62ea086cfe547e44c09b8980041360e331f74a64a2bab2ecd0f44b", @@ -143931,7 +144663,7 @@ "5ac52da3109f", "b1dd5fb2d738" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -143942,397 +144674,397 @@ "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "b4fff8f171691982fc4a18d1cb19ed171c38f5c59c057bc38fbeab9950755375", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "26eb0108ff2047d80163783dc2c85b74a77f51f7aa9dbf575b6692cdffcf2220", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a95d8a18c2bb3c5f9ad6e917c4acc92d2edc825f7d451c1e638fe2c25bb1c5d1", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "c0a4696ea23bd27247e507c4010d3e869f7b02214c408b0f6c6644c76e527b82", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "62d06f8ba3841edea9de8645b6fa9cb7f0866bbc4c67856a4718160b71b23306", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a8e3caa596ba069bd07bd7270548ba83ef4546b9206cd4e75b8910a6a6410d34", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a24ffe6e7fc65efcebed4bc4f858b7ebc8c1cadfa1823c14c2d179509e589920", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "ba2d8ce2e6b75f1db5c5326e7cff36ad5665e18ad2429849a0a057b0632aff80", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "34903791abeee1c7ea092408f2670fd184e3a48149226c7a22d51798413579a3", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "211c6f93b5016a2e31681a1db09bb2f7f818297512e73bbc39da11b5b21bc72c", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "10967889ef5d782b4fb9cb77415e497b302ea5042ce79fe18b67a06c2a65c815", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "efd6f3c731ba6ec7f739c3fd1acfae47c7c9b2fd10428c66acfecc87afb3bab7", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "9b63d0e8bfa230cd2c329890594382ace1c027e089f2591658b933e815a22f1a", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "90bc6bcf90bdd6436bd3810b1af07f415d6ee99a88f6b78ddb3d39dd8e829716", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "e8385425ce6db6c0fdc3c53bd691339d9e53ae3abc12ff76103ed970471e45a8", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "e444123d17a97bdcde5ddec5c2078d27dbaa1ac0479206dbe3378bb00cbf413a", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "5f38a39bcf8f4ed4a3cd6efac62d3a49c785d9756f631425748e815821b2c8c4", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "2b2e3d8046a360e621e9e9770d7162172f5c15732430f46bee4cba5493e1739b", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "96aaa2e8d0747d186a8a74c5fa45420e733bd09e311b40349cb75d2fe55e4327", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "c9eac5e613401b009d1c3912caf5c2768506690e1d81d152617897ee6996abb5", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "b205bc8e2ca65b211d7afd6fd9ed8c5517a2ea1066a0ba9e646c062fdb232446", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a19c2976e6338e637bb89d1e89ac4385666f1911694d3f115586bfa6c513fa43", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "34997375863c863b88718cc5da3dcd92d2e397b88cbaed2d49264e8627ad51ac", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "9d6e755e94ae80e9f225503558949fe5211cc72a6a5f240f98ad7c57cf01d1d8", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "f55794f3fee691349f790778a6572f6f8cb3d9f9b32ba0fb3b992d2d615f466c", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a952ace23c69064e60de3ad7a449e1c5063b99f685748c36f4363232cc458f39", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "f4689b31d6a2707e6907b611abca3a04f6f8af530fcd7a0c0a10598c1b7e497b", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "128054118dd12649c7f1a67af0b07f1fadf39ea1ca0b8d93f60f1de11615a9bf", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "40edfc7d967cc47fc1e4a7e080beb6da83429fe33dc508f5ee4bcaf70d261485", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "633971232d39ad573995a2b2ee24221218d5288512c6bf14187d2c4577088765", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "f8fa5969d1ada820ce08fb25251e7fd3e8693b7d7f3374aec092f59ebdb00cb6", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "f95214f53cede289f8c5dd6dd85a6ac026ccf40a2028d549f13e92324e61814e", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "e214222e2c881670f16e84b2683c9482854fe943b3ad48afa6b4ba6b23364856", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "4641627ba69c18b08558119dad6f1a2b1bef2fe94cffdfb82605e1bbcc0eaf59", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "8f6b18a4a2b6a8d8709aee961614ccf2ee0470c8487b49972a86a6af39b2fe8c", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "4e37a863ac584523e7fef41ef2cb6ee037a7d675ba2e4822ca196d5af23ff84d", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "33905c2567e615588b942d48a6dcb4f5769e318a74a009afb4f5519c0f5e125a", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "f4ba952931ad879aff7bc53552d8762ced57c13d732bd39182ed986302b138e8", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "26a1a30dd8f81f59ea42cf4f8a55644d7774d7c6ba4511a14f0b604f9b59c256", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "5cfd8b7d400444b17f39db893588a293f0e91feeadbff010a86b17a141684707", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "05bb80a2c48a1eca814c5845602cad34b252d26a4b16a57765c04f3786baa0ea", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "0544c3cdddb3cc49fc6907dd917a6305be05a4465b4553aee5e311b773910880", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "76b52ed384f029aa3793bfdae6b41fbaa1f27502a3b34dd1ac82285f5fb111d0", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "119b6dbb9374c02ae131e3436893b01c7509b89c14e9f743ad65b1bc21dcf391", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "c712b369458da07e30367e3654f51bfe4dd5dcbae933d2c839f001cd5752708d", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "c69f6a32e092ff601616cf7503e625e11c09a8c6dd441306019c916ed815ef4e", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "679af7d8cd003698a0f7a2e6f71f64b0cc0710b28afc873f3f53271203287711", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "488597982b09f54e886e4dff503288e94f55a8911ce312ffa49d7cb1fc32c024", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "0abd0046fadd0c64712063353ff9a77aa5ac1a04ff9f695aed2bd0e006f9c6a4", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "5b79b7ef0916181426e2b322ade97c03b960647146cbf87acbbbbfeb6b6caf7f", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "cbf0877589d7f7c5e887e37d1d5f64c77d165b04b78693831abd65b30666ad38", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "794bd0267d3479ec97288319df8fb65586d44cd9b68589c63d29eda9e68b7be1", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "47c93410c7f8c898c303426197c60ca22f0ebcfc58773c2ebb429ab25d167c8d", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "b1f6e187f963b4eaa8a8ffd484e04131a49d61ae0b4bfafa4982598073d40c73", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "89fecfa1d5ef01295efbe0f77c12aae651233c03bc1a971304ba4f8c529c2c0e", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "1c37e80a5ef8c8ab270b6dec7e851ea51e4637ddcff947d4889bc6a7a944026f", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "efd6021a34e00942afe01026234b99996eec41c4da8e7119efced33a21b1d878", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "d45d4dfba15d486d236f2564431f48858a36eb9f4af91e3066786aa15a92a7a6", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "3a1fed92891bcc04d70e87e902f101c0c32837dc6fb8e8489453cc45c62a2c66", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a34b745d9560ec8a8581a0cbea4d57b23bd9f23207291acc42840ace53e5ebc9", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a73edf57f5db139a504cc5942741c4810ddd111ebb423d2d391c783a44c1e56e", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "c2f3746c44455459401cb00a42f27f5e1493f5cdcb6c66314941c8eb387a0daf", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "052cb530fd3905fdf8558a3e30cefa5266fe26c03bb9782fc8894924704eea7f", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "43fd87eb4f93674ab84a79d1879d9865f5ccc750fa466b32f6d9b449ea5f8118", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "e194eacb5fb5290edb7cd8c9344afd35421c8c1af256a70612b4609083da0efc", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "eb7a507afa3e74b92180a732e77f11e368dd543fb556e21c0d988aba3e20bb5d", "target_hash": "a61cff1e60e78c9303ff820d859e7867495b8171994151148bb0fd5d4f4e8682", "section_hashes": ["4d36438e84b1", "50770e75c649", "4fa9d1e70b35"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -144352,7 +145084,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144367,7 +145099,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144382,7 +145114,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144397,7 +145129,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144412,7 +145144,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144427,7 +145159,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144442,7 +145174,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144457,7 +145189,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144472,7 +145204,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144487,7 +145219,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144502,7 +145234,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144517,7 +145249,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144532,7 +145264,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144547,7 +145279,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144562,7 +145294,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144577,7 +145309,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144592,7 +145324,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144607,7 +145339,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144622,7 +145354,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144637,7 +145369,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144652,7 +145384,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144667,7 +145399,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144682,7 +145414,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144697,7 +145429,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144712,7 +145444,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144727,7 +145459,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144742,7 +145474,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144757,7 +145489,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144772,7 +145504,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144787,7 +145519,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144802,7 +145534,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144817,7 +145549,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144832,7 +145564,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144847,7 +145579,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144862,7 +145594,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144877,7 +145609,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144892,7 +145624,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144907,7 +145639,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144922,7 +145654,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144937,7 +145669,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144952,7 +145684,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144967,7 +145699,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144982,7 +145714,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -144997,7 +145729,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145012,7 +145744,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145027,7 +145759,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145042,7 +145774,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145057,7 +145789,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145072,7 +145804,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145087,7 +145819,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145102,7 +145834,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145117,7 +145849,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145132,7 +145864,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145147,7 +145879,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145162,7 +145894,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145177,7 +145909,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145192,7 +145924,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145207,7 +145939,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145222,7 +145954,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145237,7 +145969,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145252,7 +145984,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145267,7 +145999,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145282,7 +146014,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145297,7 +146029,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145312,7 +146044,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "bb5087a17bcb6411b9e566f9d4e52548241d4b39b786f32acbbb62253ceebbb2", @@ -145327,7 +146059,7 @@ "7a420ed52517", "04b36ae05b6e" ], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } }, @@ -145338,397 +146070,397 @@ "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "32b7da2e53abe31c1e2a63fa7a76691a10be3f6e04377a11da90efb13fd72df3", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "cs": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "8fd2f21d68fc2e88a384ed6b65589e7ee1bfb8221862c52c98a1a1df96439812", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bg": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "d9d6ce821aa3c8bbb661a6aa9a356505d751715680d23d89809a18e3e790b6ba", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bn": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "be4414bac9db7b5c9084001dfec08ec34c69ee9471c8f84e7366599cc2120857", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "az": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "50f3db0c7899f02681472a8cfd14c022e4a934b2cdcad2c0a13ccbe280a7d9b0", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "da": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "99d4b54fbabe16f596461b7f9a52ec1ca7cf4b4be9fe877786d545763392d081", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "de": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5d35f5d6d94e88570eb1ea4c04ca46c1b744ce1f16684f5aa85b57a9559cf3d7", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "es": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "2b9405b2b8cabac2766f4b16b21beaa6badd5d96c03ee2c1664832998d463863", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "et": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "8cb0e11da3a786e171634e816709ac3d5a255101a2b313c0a8592068e033099b", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "el": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "f5c1e76219bee2fdac0d6e4e14c14244c1e3b834ed06281e12de402d56926851", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "am": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "a25cfb4c9af5e8fd410774732367c2da4ffcb5b8a7cf122fe7df4b2836912e66", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fr": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "082d42d66fd7f9aed74de63c212707d3370d24bc377f1e6ac8c4c7f551ecdc49", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fa": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5dc6262f7995c643fc190949c7b8d297abc7d2c074524943770de25d99c763aa", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "fi": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "45c126546bc536efe051af10b57acbeb26971e39391da9265667a33b8ec6bfb6", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ga": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "6c49c96537055ece24baf22f684fe764b0b0be2fb2ad704154be0290b88aca2a", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "gu": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "cb2e0e2c6ab3a1f66fec0b1c574b41b3b16df02bffc39d13e96231e7c8b8d118", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ha": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "e33193472fa67fa48d539ea8a9464602020dd8bf7d4292f4ca5e4a40ec11cd67", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "he": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5a68d972a9f72f27cb2a6d176860453534122ff8fbe1748532e7af78d03011d0", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hi": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "4460af862051671edab77efddac65aa16964b5098146c84ab8fb24d27b7133cf", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hr": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "3e4301d0d977a01669805d563df9e6c313d0feec1ac2ced86224574e9bb39b9f", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hu": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "f53375ae3d7f039b3c194187fec59210595268f441f4ade8f7dc3b00ae07cb68", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "hy": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "714ca807ca2436a56fef89ac78ca96cf94fa52194482480949ce915d35024b4d", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "id": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "0545b8830853938208bb3cd3e30ded2a2370cf3ee6bab9173214dc3a1e138b0b", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "it": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "6b341ff42d2701f51a4a831d5af35dfff2d5ebf2883b4ca71021ecbdb111a59c", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ig": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "1e90202d8d1543a68b3d206703986133d01a4bf8410f721498df73a0ea8f9fcc", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ja": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "bbe32c79ddebada1fab562678016b6005926ac56330ff95abcc1b9209d0c6a2d", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ka": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "870dc1d8fdf7253646ff840a9474e76e1db7d44b0a1e55d28092106d3219ccbf", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ko": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "65b71466976975cdd120cb259427d7671ee95b69b288817de362de49ae99d8dd", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "kn": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "60fdc1dd7f8451519056d96fd245ce950ce083436693aac680af316e57328f41", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "km": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "fb0d8d4a1471e61f67a8aef8c24dff37a2bb24bba6aba64d78d127e3e061b191", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lt": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "43176a785ab0c7e61fa114b337ab8c97c29cd423cbd911ee251746e47fd507fc", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "lv": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "79dd10cf6b0c04aa9a2d2af9902b68714863d220d291d014284be2f4779e8c57", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ml": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "b380e7b88a5d8df149b150f53c52bf0bf06def0248b5fbaba9887cb38d42fc00", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ms": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "6ed893b89ab338320c0a33ee5adde74ffa5b716940d3117620c581c5cad3e757", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mr": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "90a2a14daec55124aaa7eb011dbf84e29823b69cd636038a20f770e0b4640854", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "mt": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "d3cb63e5f14ccb9ea074b346e9ecdb0beae151cd0caea3d91ebe88050636fe88", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ne": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "22d3b988e582a715b36d89e13e4efefd33375097f400e3eab475c475f224c142", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "my": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5aa3107db66bf3b27031da12fe2a93eba547fce257c1667d83b7b71b5c926538", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "nl": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "15c4b8735aa687eb9b8a7dea2ae9a353ce177b3bc86368d419f252c2d4eabc07", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "no": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "d9461e9da5c2d3eeb32b181ad38038a61ebe0937fa8d7cf86b6af211279df9c4", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pl": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5a5e232471890776fc161e2512275f23caa95c519c7e533d6cc9f58f4029d85e", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "phi": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "fe4b6573a1544d9b0ff09b72c7ef9c1a9d9865f5fe608d598799b4d55ab27233", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt-BR": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "e108000f3fa7d1536ceff292245b5be696619683c85926a518ca771f99aae4e5", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pt": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "eb967d4e0a62c46fdcd8c2042de22762cc9046b1bbdf99c8a3e1d09652b6c91a", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "pa": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "cb159d7746161e3073344773ab7c24651f8c347661bdb10f1e4ffe11662041e2", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ro": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "709e69dc9bdd158113387de104fa49c4462a28995ef1632e8cc120b85a4e66bd", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "or": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "db6528c543d7b72c3a7fed2a1d03da8ac95d3a5f727d77e0e908d5e84261f6b1", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ru": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "6ffafe99a8f8bf8a7bc0b7165ec3078279e88b53f7a2010cc5f45015c5519e03", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sk": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "1dc0d303620aab31ea3b27b607de0a24eee7b2763317d3e8787ddf0624207ea8", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "si": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "ed2c5300605e7e3426069e7382366ce7ad2d8e399ba1ea2d898a62b5159b5e92", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sl": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "05e79387d68b7dd74188e2b694787811d41c988ca57aa77fb96757895d3d9705", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sv": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "1d38c3f3f7381f3f2af4d5b1a62e6080922df7ff3df2f2407095babaf28bf859", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sr": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "f36484f5b2612871e7727a52bccbdef46b2fe39c0a12f7db425a4b13966a2483", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "sw": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "56b8d82be224a553dfc714a985e38a9fa3adc4a47c7d342063e85b6ebe3725e6", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ta": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "b75d5cac919d289bb1993708705d0e81fdce6bed40f6026cfe64fddedfe73db5", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "te": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "0eeeaceb1801aaf8cabd6e9965b12611a18d159bb58858c73ac0ccb5455916e8", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "th": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "9b90b628300e9b24b476ae71d499d37ebae7145106144e6aa0cca03036a947ec", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "tr": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "43bc370b89da8948d493883769f7e656486b1411235e93aaef13c1680c491170", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uk-UA": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5f8d93f91010ca06ea8d447d930f5fa2ab8c6cdcfd8b43852d2fb9da97316d35", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "ur": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "6ef235579f9732a3efe6054abc5e30d913d84fc9e13fd0153bfdfc8181ad610c", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "vi": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "9537336a934b64455d1132adf10b337f6669475688f8fa816c31e4175bc46bfc", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-CN": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "e2ba1255a03ec884e77ed3be270b564eaaad3fc7e8af370d518c7cbdb1991fc1", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "uz": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "423669a59b43bf0204d5dcddbec9d7028010c65c709f5d29f81176e9bfb0e767", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "zh-TW": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "cb444163c3494eae4e7e7192b4cddb2a9399e387fb3bc7ca9b373f18511fda35", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "yo": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "dcc02c1cdec935fddda5b6813a72c134520d861ad3df2d9528bf3ff816061797", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" }, "bs": { "source_hash": "fd7c59d293a5f1c8c7ee4aed51834f3e672715ccc50437202b1608433a26b47c", "target_hash": "5cb56e498976db79e2fe23b9e3f48b5a15c006031dc6dae0e8df8815bf8c780f", "section_hashes": ["492c0eaf722e", "e3f403671566", "7231623ee278", "5f56c9ad1c18"], - "updated_at": "2026-10-02T07:07:52.756Z" + "updated_at": "2026-10-06T15:06:31.643Z" } } } diff --git a/docs/i18n/am/CONTRIBUTING.md b/docs/i18n/am/CONTRIBUTING.md index 5b79f361671..0196ef6b87d 100644 --- a/docs/i18n/am/CONTRIBUTING.md +++ b/docs/i18n/am/CONTRIBUTING.md @@ -398,20 +398,20 @@ docs/ ## የPull Request ማረጋገጫ ዝርዝር -- [ ] Tests በትክክል ያልፋሉ (`npm test`) -- [ ] Linting በትክክል ያልፋል (`npm run lint`) +- [ ] ሙከራዎች ያልፋሉ (`npm test`) +- [ ] Linting ያልፋል (`npm run lint`) - [ ] Build ይሳካል (`npm run build`) - [ ] ለአዲስ ይፋዊ functions እና interfaces የTypeScript types ታክለዋል -- [ ] በኮድ ውስጥ በቀጥታ የተጻፉ secrets ወይም fallback values የሉም -- [ ] ይፋዊ የupstream ማረጋገጫ መረጃዎች በ`resolvePublicCred()` ተካትተዋል ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)ን ይመልከቱ)፣ ፈጽሞ እንደ literals አልተጻፉም -- [ ] የስህተት ምላሾች በ`buildErrorBody()` / `sanitizeErrorMessage()` ያልፋሉ — በresponse bodies ውስጥ ጥሬ stack traces የሉም ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)ን ይመልከቱ) -- [ ] Shell commands (`exec` / `spawn`) የruntime valuesን በstring interpolation ሳይሆን በ`env` ያስተላልፋሉ +- [ ] Hardcoded secrets ወይም fallback values የሉም +- [ ] ይፋዊ upstream credentials በ`resolvePublicCred()` በኩል ተካትተዋል ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ይመልከቱ)፤ በፍጹም እንደ literals አልተጻፉም +- [ ] የስህተት ምላሾች በ`buildErrorBody()` / `sanitizeErrorMessage()` በኩል ያልፋሉ — በምላሽ bodies ውስጥ raw stack traces የሉም ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ይመልከቱ) +- [ ] Shell commands (`exec` / `spawn`) የruntime valuesን በstring interpolation ሳይሆን በ`env` በኩል ያስተላልፋሉ - [ ] ሁሉም inputs በZod schemas ተረጋግጠዋል -- [ ] ለተጠቃሚ የሚታዩ ለውጦች Changelog **fragment** በ`changelog.d/{features|fixes|maintenance}/-.md` ስር ታክሏል ([`changelog.d/README.md`](./changelog.d/README.md)ን ይመልከቱ) — `CHANGELOG.md`ን በቀጥታ **አያርትዑ**፤ fragments በrelease ጊዜ አንድ ላይ ይሰበሰባሉ እና በPRs መካከል ፈጽሞ አይጋጩም +- [ ] በተጠቃሚ ላይ ለሚታዩ ለውጦች የChangelog **fragment** በ`changelog.d/{features|fixes|maintenance}/-.md` ስር ታክሏል ([`changelog.d/README.md`](./changelog.d/README.md) ይመልከቱ) — `CHANGELOG.md`ን በቀጥታ **አርትዕ አያድርጉ**፤ fragments በrelease ጊዜ ይሰባሰባሉ እና በPRs መካከል በፍጹም አይጋጩም - [ ] Documentation ዘምኗል (አስፈላጊ ከሆነ) -- [ ] ምንም አዲስ CodeQL / Secret-Scanning alerts አልተከፈቱም፣ ወይም እያንዳንዳቸው ተዛማጁን `docs/security/` doc በሚጠቅስ ቴክኒካዊ ምክንያት ውድቅ ተደርገዋል -- [ ] child processes የሚጀምሩ Routes (`/api/mcp/`, `/api/cli-tools/runtime/`) በ`src/server/authz/routeGuard.ts` ውስጥ እንደ `isLocalOnlyPath()` ተመድበዋል — [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md)ን ይመልከቱ -- [ ] በcommit messages ውስጥ `Co-Authored-By` trailers የሉም — commits በrepository owner Git identity ስር ብቻ መታየት አለባቸው (Hard Rule #16) +- [ ] አዲስ CodeQL / Secret-Scanning alerts አልተከፈቱም፣ ወይም እያንዳንዳቸው ተዛማጅ `docs/security/` docን በሚጠቅስ ቴክኒካዊ ምክንያት ውድቅ ተደርገዋል +- [ ] Child processes የሚጀምሩ routes (`/api/mcp/`, `/api/cli-tools/runtime/`) በ`src/server/authz/routeGuard.ts` ውስጥ እንደ `isLocalOnlyPath()` ተመድበዋል — [ጥብቅ ደንብ #15](docs/security/ROUTE_GUARD_TIERS.md)ን ይመልከቱ +- [ ] በcommit messages ውስጥ የAI/bot `Co-authored-by` trailers የሉም (ጥብቅ ደንብ #16) — ሥራቸው እንደገና ጥቅም ላይ የዋለ ሰብዓዊ collaborators በመደበኛ `Co-authored-by: Name ` trailers እውቅና ያገኛሉ --- diff --git a/docs/i18n/am/docs/architecture/QUALITY_GATES.md b/docs/i18n/am/docs/architecture/QUALITY_GATES.md index 028fbaf7cc6..4011984a257 100644 --- a/docs/i18n/am/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/am/docs/architecture/QUALITY_GATES.md @@ -15,206 +15,212 @@ --- -## የጌቶች ዝርዝር እና የአፈጻጸም መገለጫዎች +## የጌት ዝርዝር እና የአፈጻጸም መገለጫዎች -### የዕጩ ቅበላ +### የእጩ ተቀባይነት -የCI እና Quality Gates የስራ ፍሰቶች እያንዳንዳቸው የማይለዋወጥ ውሳኔ ያወጣሉ፦ `Gate / CI` እና -`Gate / Quality`። ስሪት የተሰጠው የቅበላ ፖሊሲያቸው እያንዳንዱን ቀዳሚ ስራ +የCI እና Quality Gates የስራ ፍሰቶች እያንዳንዳቸው የማይለወጥ ውሳኔ ያወጣሉ፦ `Gate / CI` እና +`Gate / Quality`። በስሪት የሚተዳደረው የተቀባይነት ፖሊሲያቸው እያንዳንዱን የላይኛው ደረጃ ስራ እንደ አስፈላጊ ወይም አማካሪ ይዘረዝራል። ተፈጻሚ የሆነ አስፈላጊ ስራ መሳካት አለበት፦ የጎደሉ፣ የተሰረዙ፣ የታለፉ፣ በመጠባበቅ ላይ ያሉ እና ያልታወቁ ውጤቶች PASSን ማረጋገጥ አይችሉም። ትክክለኛ -የdocs-only ወይም catalog-only ምደባ የኮድ መስመርን ተፈጻሚ ያልሆነ ሊያደርገው ይችላል፤ -ረቂቅ PR ተቀባይነት ያለው ዕጩ አይደለም። የ`hotfix` መለያ የማስረጃ ግዴታን አያስቀርም። +docs-only ወይም catalog-only ምደባ የኮድ መስመርን ተፈጻሚ ያልሆነ ሊያደርገው ይችላል፤ +ረቂቅ PR ተቀባይነት ያገኘ እጩ አይደለም። የ`hotfix` መለያ ማስረጃን አያስቀርም። -ሁለቱም የስራ ፍሰቶች PRዎችን፣ ወደ main/release ቅርንጫፎች የሚደረጉ pushዎችን፣ manual dispatchን እና -merge-group ክስተቶችን ይሸፍናሉ። Push፣ dispatch እና merge-group ሙሉ ምርጫውን ያስኬዳሉ። Forkዎች -እና merge groupዎች በሌላ ሁኔታ self-hosted runnerዎችን ለሚመርጡ ስራዎች hosted runnerዎችን ይጠቀማሉ፤ -ከመዘርጋቱ በፊት በቂ hosted አቅም መኖሩ መረጋገጥ አለበት። +ሁለቱም የስራ ፍሰቶች PRዎችን፣ ወደ main/release ቅርንጫፎች የሚደረጉ pushesን፣ manual dispatchን እና +merge-group ክስተቶችን ይሸፍናሉ። Push፣ dispatch እና merge-group ሙሉውን ምርጫ ያስኬዳሉ። Forks +እና merge groups በሌላ ሁኔታ self-hosted runnersን ለሚመርጡ ስራዎች hosted runnersን ይጠቀማሉ፤ +ከማሰማራት በፊት በቂ hosted አቅም መኖሩ መረጋገጥ አለበት። -እያንዳንዱ JSON ደረሰኝ የተፈተሸውን SHA፣ የስራ ፍሰት አሂድ እና ሙከራ ይለያል። -CLIው በcheckout/event SHA መካከል ያለውን አለመጣጣም ውድቅ ያደርጋል። የስራ ፍሰት ሙከራዎች የፖሊሲ አባልነትን -ከውሳኔ ስራው `needs` ዝርዝር ጋር ያስተሳስራሉ፣ ስለዚህ አዲስ ወይም የተወገደ መስመር በጸጥታ ሊጠፋ አይችልም። -ደረሰኞቹ የሚሸፍኑት የራሳቸውን የስራ ፍሰት እንጂ ህትመትን፣ deploymentን ወይም የአንድ ነባር አማካሪ scanner ውስጣዊ አሰራርን -አይደለም። ሁለቱንም የፍተሻ ስሞች በቅርንጫፍ ደንቦች ውስጥ ማንቃት የተለየ አስተዳደራዊ ለውጥ ነው፤ እነዚህን ስራዎች ማከል በራሱ ቅርንጫፍን አይጠብቅም። +እያንዳንዱ JSON ደረሰኝ checked-out SHAን፣ workflow runን እና attemptን ይለያል። +CLIው የcheckout/event SHA አለመዛመድን ውድቅ ያደርጋል። የስራ ፍሰት ሙከራዎች የፖሊሲ አባልነትን +ከውሳኔ ስራው `needs` ዝርዝር ጋር ያስተሳስራሉ፣ ስለዚህ አዲስ ወይም የተወገደ መስመር በዝምታ ሊጠፋ አይችልም። +ደረሰኞቹ የሚሸፍኑት የራሳቸውን የስራ ፍሰት እንጂ ህትመትን፣ deploymentን ወይም የነባር አማካሪ scanner ውስጣዊ +አሰራሮችን አይደለም። ሁለቱንም የcheck ስሞች በbranch rules ውስጥ ማንቃት የተለየ አስተዳደራዊ ለውጥ ነው፤ +እነዚህን ስራዎች መጨመር በራሱ ቅርንጫፍን አይጠብቅም። ### የስታቲክ ቅኝት ዝርዝር -ስሪት የተሰጠው የnpm-alias ዝርዝር እና የስታቲክ ቅኝት አባልነት በ -`config/quality/gate-manifest.json` ውስጥ ይገኛሉ። የscript ስሞችን እና ትክክለኛ ትዕዛዞችን ከ`package.json` ጋር ለማረጋገጥ -`npm run check:gate-manifest`ን ያስኪዱ፤ መጨመር፣ ማስወገድ እና -የትዕዛዝ ለውጥ በCI ውስጥ ያሉትን የአካባቢ hook እና የለውጥ-ምደባ ስራዎች ሁለቱንም እንዲወድቁ ያደርጋሉ። -alias የስራ ፍሰት ስራ፣ matrix instance ወይም test case አይደለም፦ እነዚህ ቁጥሮች -እርስ በርስ እንደሚተካኩ መቅረብ የለባቸውም። - -የተመረጡትን aliasዎች ሳያስኬዷቸው ለመመርመር `npm run quality:scan -- --list` ወይም `npm run quality:scan:fast -- --list` -ይጠቀሙ። runnerው -የnpm entrypointን ይጠራል፣ ስለዚህ runtimeው (በተዋቀረበት ቦታ Bunን ጨምሮ) እንደተጠበቀ ይቆያል። -manifestው ከእነዚያ መገለጫዎች ውጭ ያሉ aliasዎችን በተለየ ሁኔታ የሚጠሩ ብሎ ይመዘግባል፣ እና +በስሪት የሚተዳደረው የnpm-alias ዝርዝር እና የstatic-scan አባልነት በ +`config/quality/gate-manifest.json` ውስጥ ይገኛሉ። የscript ስሞችን እና ትክክለኛ ትዕዛዞችን ከ`package.json` ጋር +ለማረጋገጥ `npm run check:gate-manifest`ን ያስኪዱ፤ መጨመሮች፣ ማስወገዶች እና +የትዕዛዝ ለውጦች ሁለቱንም local hook እና በCI ውስጥ ያሉትን የchange-classification ስራዎች ያሳክታሉ። +alias የworkflow ስራ፣ matrix instance ወይም test case አይደለም፦ እነዚህ ቁጥሮች +በአንድ ዓይነት ሊቀርቡ አይገባም። + +የተመረጡትን aliases ሳያስኬዷቸው ለመመርመር `npm run quality:scan -- --list` ወይም `npm run quality:scan:fast -- --list`ን +ይጠቀሙ። runnerው የnpm entrypointን ይጠራል፣ ስለዚህ runtimeው (በተዋቀረበት ቦታ Bunን ጨምሮ) እንዳለ ይጠበቃል። +manifestው ከእነዚያ መገለጫዎች ውጭ ያሉ aliasesን በተናጠል እንደሚጠሩ ይመዘግባል፣ እና የጥገና ትዕዛዞች በread-only የቅኝት መገለጫዎች ውስጥ የተከለከሉ ናቸው። -እነዚህ መገለጫዎች የሚሸፍኑት የስታቲክ ቅኝቱን ብቻ ነው። የምርት ሙከራዎችን፣ -coverageን፣ packagingን፣ ውጫዊ ፍተሻዎችን ወይም የዕጩን ሙሉ የrelease ቅበላ አያረጋግጡም። -የስራ ፍሰት ቅበላ የተገናኙትን `config/quality/admission-policy.json` እና +እነዚህ መገለጫዎች የሚሸፍኑት የስታቲክ ቅኝትን ብቻ ነው። የምርት ሙከራዎችን፣ +coverageን፣ packagingን፣ ውጫዊ checksን ወይም የእጩን ሙሉ የrelease ተቀባይነት አያረጋግጡም። +የስራ ፍሰት ተቀባይነት የተገናኘውን `config/quality/admission-policy.json` እና `scripts/quality/admission-verdict.mjs` ይጠቀማል። የRelease-observer መገለጫዎች ተለይተው ይቆያሉ፤ -ተፈጻሚ ፍተሻዎቻቸውን እና ደረሰኞቻቸውን በተናጠል ይመርምሩ። ከታች ያለው የጽሑፍ -ዝርዝር ማጣቀሻ እንጂ አንድ ጌት በእርግጥ እንደተከናወነ ማረጋገጫ አይደለም። +ተፈጻሚ checksና ደረሰኞቻቸውን በተናጠል ይመርምሩ። ከታች ያለው ገላጭ +ዝርዝር ማጣቀሻ እንጂ አንድ gate በትክክል እንደተሰራ ማረጋገጫ አይደለም። -Scriptዎች በ`scripts/check/` (የፖሊሲ ጌቶች) እና `scripts/quality/` (ratchet engine) ስር ይገኛሉ። +Scripts በ`scripts/check/` (የፖሊሲ gates) እና `scripts/quality/` (ratchet engine) ስር ይገኛሉ። የCI ዋና የእውነት ምንጭ `.github/workflows/ci.yml` ነው። ### የRelease PR ፈጣን መንገድ (`quality.yml`) -`.github/workflows/quality.yml` በmain/release PRዎች፣ protected-branch -pushዎች፣ dispatch እና merge groupዎች ላይ CIን ያሟላል። PRዎች በpath የተጣሩ ፈጣን ፍተሻዎችን ይጠቀማሉ። በቋሚነት -የተሰናከለው የተባዛ build ተወግዷል፤ እውነተኛዎቹ የbuild/package/boot ፍተሻዎች በCI ውስጥ ይቀራሉ። +`.github/workflows/quality.yml` በmain/release PRዎች፣ ወደ የተጠበቁ ቅርንጫፎች በሚደረጉ +pushes፣ dispatch እና merge groups ላይ CIን ያሟላል። PRዎች በpath የተጣሩ ፈጣን checksን ይጠቀማሉ። በቋሚነት +የተሰናከለው የተባዛ build ተወግዷል፤ እውነተኛዎቹ build/package/boot checks በCI ውስጥ ይቀራሉ። -| ስራ | ወሰን | አጋጅ | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | -| `Docs Gates (fast-path)` | Docs/code PRዎች፤ የAPI docs refs እና docs-all | አዎ | -| `Fast Quality Gates` | የCode PRዎች፤ static checks፣ typecheck፣ dashboard typecheck፣ ተጽዕኖ ያረፈባቸው unit tests | አዎ | -| `Forgotten sibling tests` | የCode PRዎች፤ የተቀየሩ modules ወደ static consumers እና candidate sibling tests ይከታተላሉ፤ barrel እና dynamic-import paths እንደ አማካሪ diagnostics ሪፖርት ይደረጋሉ፣ ከተጠቀሱ allowlist exceptions ጋር | **አማካሪ** | -| `Vitest (fast-path)` | የCode PRዎች፤ ፈጣን vitest suite | አዎ | -| `Unit Tests fast-path` | የCode PRዎች፤ 4-shard unit suite | አዎ | -| `No new ESLint warnings` | የCode PRዎች፤ suppressions-aware lint guard | አዎ፣ forkዎችን ጨምሮ | -| `Merge integrity (changelog + generated skills)` | ረቂቅ ያልሆኑ PRዎች፤ changelog እና generated skill sync | አዎ፣ forkዎችን ጨምሮ | +| ስራ | ወሰን | አጋጅ | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `Docs Gates (fast-path)` | Docs/code PRዎች፤ የAPI docs refs እና docs-all | አዎ | +| `Fast Quality Gates` | Code PRዎች፤ static checks፣ typecheck፣ dashboard typecheck፣ ተጽዕኖ የደረሰባቸው unit tests | አዎ | +| `Forgotten sibling tests` | Code PRዎች፤ የተለወጡ modules ወደ static consumers እና candidate sibling tests ይከታተላሉ፤ barrel እና dynamic-import paths ከተጠቀሱት allowlist exceptions ጋር እንደ አማካሪ diagnostics ይመዘገባሉ | **አማካሪ** | +| `Vitest (fast-path)` | Code PRዎች፤ ፈጣን vitest suite | አዎ | +| `Unit Tests fast-path` | Code PRዎች፤ ባለ4-shard unit suite | አዎ | +| `No new ESLint warnings` | Code PRዎች፤ suppressions-aware lint guard | አዎ፣ forksን ጨምሮ | +| `Merge integrity (changelog + generated skills)` | ረቂቅ ያልሆኑ PRዎች፤ changelog እና generated skill sync | አዎ፣ forksን ጨምሮ | #### የተረሱ sibling tests ሪፖርት -`npm run check:forgotten-sibling-tests` ከtest-impact map በስተጀርባ ያለውን import resolver እንደገና ይጠቀማል። -ለእያንዳንዱ የተቀየረ production module፣ candidate -test በpull-request diff ውስጥ በማይኖርበት ጊዜ ቁርጥ የሆኑ -`changed module/symbol -> static consumer -> candidate sibling test` ሰንሰለቶችን ሪፖርት ያደርጋል። የMarkdown ማጠቃለያው እና JSON ውጤቱ ከማንኛውም አጋጅ ማስጀመሪያ በፊት ለመለኪያ -እንደ `forgotten-sibling-tests` የስራ ፍሰት artifact ተይዘው ይቆያሉ። +`npm run check:forgotten-sibling-tests` ከtest-impact map ጀርባ ያለውን import resolver እንደገና ይጠቀማል። +ለእያንዳንዱ የተለወጠ production module፣ እጩው +test በpull-request diff ውስጥ በማይኖርበት ጊዜ ወጥነት ያላቸውን `changed module/symbol -> static consumer -> candidate sibling test` ሰንሰለቶች ይመዘግባል። +የMarkdown ማጠቃለያው እና JSON ውጤቱ ማንኛውም አጋጅ ማሰማራት ከመደረጉ በፊት ለcalibration እንደ +`forgotten-sibling-tests` የworkflow artifact ተይዘው ይቆያሉ። -Barrel ዳግም-ወደ-ውጭ-መላኮች እና dynamic imports የresolution ምርመራዎች ብቻ ናቸው፤ blocking finding ፈጽሞ አይፈጥሩም። የተገመገሙ ልዩ ሁኔታዎች በ +Barrel re-exports እና dynamic imports የresolution ምርመራዎች ብቻ ናቸው፤ መቼም +የሚያግድ ግኝት አይፈጥሩም። የተገመገሙ ልዩ ሁኔታዎች በ `config/quality/forgotten-sibling-allowlist.json` ውስጥ ይገኛሉ። እያንዳንዱ ግቤት consumer-ን እና candidate -test-ን መጥቀስ፣ ዝርዝር ምክንያት መስጠት እና ወደ GitHub issue ወይም pull request ማገናኘት አለበት። ቅርጸታቸው የተበላሸ ግቤቶች -በነባሪነት ውድቅ ይደረጋሉ። ልዩ ሁኔታዎች የተሰረዘ candidate test-ን ወይም `.skip`/`.todo` የሚጨምር diff-ን -ማፈን አይችሉም፤ assertion ማዳከም እና ሌሎች masking ድርጊቶች ራሱን ችሎ blocking በሆነው -`check:test-masking` gate ሥር ይቆያሉ። +test-ን መጥቀስ፣ የተወሰነ ምክንያት መስጠት እና ወደ GitHub issue ወይም pull request ማገናኘት አለበት። ቅርጸታቸው የተበላሸ ግቤቶች +በነባሪነት ይከለከላሉ። ልዩ ሁኔታዎች የተሰረዘ candidate test-ን ወይም `.skip`/`.todo` የሚጨምር diff-ን ማፈን አይችሉም፤ +assertion weakening እና ሌሎች masking ዘዴዎች አሁንም ራሱን ችሎ የሚያግደው +`check:test-masking` gate ኃላፊነት ናቸው። ### ሥራ፦ `lint` -ወደ `main` በሚደረግ እያንዳንዱ PR ላይ ይሠራል። ካልተሳካ merge እንዳይደረግ ያግዳል። - -| ስክሪፕት (`npm run ...`) | የሚያረጋግጠው | አጋጅ | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `check:node-runtime` | የNode.js ስሪት በሚደገፈው ክልል ውስጥ መሆኑን | አዎ | -| `check:cycles` | ዑደታዊ imports — ሁሉም የ`src/` + `open-sse/` modules | አዎ | -| `check:route-validation:t06` | በሁሉም routes ላይ የZod schemas መኖር (Tier 6 policy) | አዎ | -| `check:any-budget:t11` | የ`@ts-expect-error // any` ብዛት ከተመደበው ገደብ አለማለፉን (Tier 11 catraca) | አዎ | -| `check:provider-consistency` | `providers.ts` ውስጥ ያለው እያንዳንዱ provider በ`providerRegistry.ts` ውስጥ ተዛማጅ ግቤት አለው (እና በተቃራኒውም፣ በallowlist ወሰን ውስጥ) | አዎ | -| `check:model-lifecycle` | በእጅ የሚጠበቁት ሦስቱ routing tables ከተካተተው lifecycle snapshot (#11503) ጋር ወጥነታቸውን ይጠብቃሉ፦ `FITNESS_TABLE` (`taskFitness.ts`) `REGISTRY` ሊያዞረው የሚችል retired id ለአንዳቸውም score አይሰጥም፤ እያንዳንዱ የ`BUILT_IN_ALIASES` target በ`REGISTRY` ውስጥ ይገኛል እና በretired-id snapshot ውስጥ አይገኝም፤ በ`REGISTRY` ውስጥ አሁንም ያለ እያንዳንዱ retired id ወደ ሌላ ቦታ ይተላለፋል ወይም በ`allowedRetiredInCatalog` ውስጥ ተዘርዝሯል፤ እንዲሁም በዚያ snapshot ውስጥ አንድም የ`DEFAULT_DEGRADATION_MAP` source ወይም target እንደ retired አይታይም። ይህ አንድ model በአሁኑ ጊዜ በቀጥታ upstream እየቀረበ መሆኑን አያረጋግጥም። Offline — በእጅ በ`npm run quality:refresh-model-lifecycle` (network፤ ከCI ጋር አልተያያዘም) ከሚታደሰው `config/quality/model-lifecycle.json` ጋር ያነጻጽራል። `allowedRetiredInCatalog` ቀስ በቀስ የሚቀንስ ratchet ነው፦ ግቤት የሚጨመረው ከtracking issue ጋር ብቻ ነው። | አዎ | -| `check:fetch-targets` | በclient-side `src/` ውስጥ ያለ እያንዳንዱ `fetch("/api/...")` ወደ እውነተኛ `route.ts` ይፈታል | አዎ | -| `check:deps` | በrepo ውስጥ ባለ እያንዳንዱ `package.json` ውስጥ የሚገኙ ሁሉም በ`npm install` ሊጫኑ የሚችሉ deps በ`dependency-allowlist.json` ውስጥ አሉ፤ አዲስ unpinned ወይም slopsquatted packages ምልክት ይደረግባቸዋል | አዎ | -| `audit:deps` | `npm audit` (root + electron) — high/critical advisories የሉም (ከosv `check:vuln-ratchet` ጋር ይደራረባል፤ Rationalization Backlogን ይመልከቱ) | አዎ | -| `check:lockfile` | የ`package-lock.json` integrity — https registry፣ integrity hashes፣ ምንም host overrides የሉም | አዎ | -| `check:licenses` | ለምርት ጥገኞች የSPDX ፈቃድ የተፈቀዱ ዝርዝር | አዎ | -| `check:tracked-artifacts` | ምንም የግንባታ አርቲፋክቶች / ወደ commit የተደረጉ `node_modules` symlinks የሉም (በhusky pre-commit ውስጥም ይሰራል፤ pre-push ሆን ተብሎ ቀላል ተደርጓል — #6716) | አዎ | -| `check:ai-attribution` | በPR commits፣ title ወይም body ውስጥ የAI/bot `Co-Authored-By` trailer ወይም የAI ማመንጨት footer የለም — ጥብቅ ደንብ #16 (በ`quality.yml` ፈጣን መግቢያ-ፍተሻዎች loop ውስጥ ለPR→`release/**` — የevent payloadን ያነባል፣ ከPR ውጭ ምንም አያደርግም — እንዲሁም በ`ci.yml` lint ውስጥ ለPR→`main` የPR-ብቻ step፤ በተጨማሪም የhusky `commit-msg` hook፤ ሰው co-authors ይፈቀዳሉ፤ #14436) | -| `check:vitest-exclusions` | እያንዳንዱ የVitest ማግለያ tracking issueን ይጠቅሳል እና በ`config/quality/vitest-exclusions.json` ውስጥ ይገኛል (#13204) | አዎ | -| `check:file-size` | ምንም የምንጭ ፋይል በቅጥያ የተወሰነውን ከፍተኛ ገደብ አያልፍም (ratchet፦ የታሰሩ ትልልቅ ፋይሎች በ`frozen` ዝርዝር ውስጥ) | አዎ | -| `check:error-helper` | በexecutors/handlers ውስጥ ያሉ የስህተት ምላሾች `buildErrorBody()` / `sanitizeErrorMessage()`ን ይጠቀማሉ (ጥብቅ ደንብ #12) | አዎ | -| `check:migration-numbering` | የማይግሬሽን SQL ፋይሎች ያለ ክፍተት ወይም ድግግሞሽ በተከታታይ ተቆጥረዋል | አዎ | -| `check:public-creds` | ከ`publicCreds.ts` ውጭ ቀጥተኛ የOAuth `client_id`/`client_secret` ወይም የFirebase Web ቁልፎች የሉም (ጥብቅ ደንብ #11) | አዎ | -| `check:db-rules` | ከ`src/lib/db/` ሞጁሎች ውጭ ያልተጣራ SQL የለም፤ ከ`localDb.ts` የbarrel-import ማስመጣቶች የሉም (ጥብቅ ደንቦች #2/#5) | አዎ | -| `check:known-symbols` | በdispatch ሰንጠረዦቻቸው ውስጥ የተመዘገቡ የአቅራቢ አስፈጻሚዎች፣ የማዘዋወሪያ ስልቶች እና ተርጓሚዎች በዲስክ ላይ ካሉት ፋይሎች ጋር ይዛመዳሉ—ወላጅ አልባ ወይም ያልታወጁ symbols የሉም | አዎ | -| `check:route-guard-membership` | የልጅ process የሚፈጥር እያንዳንዱ route በ`isLocalOnlyPath()` ተመድቧል (ጥብቅ ደንቦች #15/#17) | አዎ | -| `check:test-discovery` | በrepo ውስጥ ያለ እያንዳንዱ `*.test.ts` / `*.spec.ts` ፋይል ቢያንስ በአንድ test runner ይሰበሰባል (ratchet፦ በ`test-discovery-baseline.json` ውስጥ ያለው የወላጅ አልባ ፋይሎች ዝርዝር ሊያጥር ብቻ ይችላል) | አዎ | -| `check:agent-skills-sync` | የተፈጠሩ የagent-skills አርቲፋክቶች ከምንጭ ካታሎጋቸው ጋር ይዛመዳሉ (ልዩነት የለም) | -| `check:provider-asset-provenance` | የአቅራቢ አርማዎች/ንብረቶች የተመዘገበ የምንጭ መረጃ አላቸው | -| `lint:json` | የJSON ውቅር ፋይሎች በትክክል ይተነተናሉ እና የrepo lint ደንቦችን ያሟላሉ | -| `typecheck:core` | የTypeScript ማጠናቀር ያለ ስህተት (የምክር ማስጠንቀቂያዎች ብቻ) | አዎ | -| `typecheck:noimplicit:core` | ጥብቅ `noImplicitAny` — ወደፊትን ያማከለ፤ አስቀድመው የነበሩ ብዙ የጥሪ ቦታዎች አሁንም ማብራሪያዎችን ይፈልጋሉ | **የምክር** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | ለ`src/app/(dashboard)/**` ብቻ የተገደበ `tsc` (#7033) — የ`typecheck:core` በጥንቃቄ የተመረጠ ባለ27-ፋይል የፈቃድ ዝርዝር ምንም የdashboard TSX አያካትትም፣ እንዲሁም `next build` እሱን በፍጹም የዓይነት ምርመራ አያደርግበትም (`next.config.mjs` `ignoreBuildErrors: true` ያዘጋጃል)፣ ስለዚህ በዚያ ያሉ ብቸኛ-የሆኑ የመለያ መመለስ ስህተቶች (#6625/#6909) ለCI የማይታዩ ነበሩ። ከቀዘቀዘ በየፋይሉ/በየTS-code የቁጥር መነሻ መለኪያ (`config/quality/dashboard-typecheck-baseline.json`፣ እንደ `check:known-symbols` ተመሳሳይ የጊዜ ያለፈበትን የማስፈጸም ንድፍ) ጋር ልዩነቶች ይነጻጸራሉ — ከመነሻ መለኪያው ቁጥር በላይ ያሉ አዲስ ስህተቶች ብቻ መግቢያውን ያሳንፋሉ፤ አስቀድሞ የነበረ ስህተት ሲስተካከል በ`--update` በመጠቀም መነሻ መለኪያውን ዝቅ ያድርጉ። | አዎ | +ወደ `main` በሚቀርብ እያንዳንዱ PR ላይ ይሰራል። ካልተሳካ merge እንዳይደረግ ያግዳል። + +| Script (`npm run ...`) | የሚያረጋግጠው | አጋጅ | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | የNode.js ስሪት በሚደገፈው ክልል ውስጥ መሆኑን | አዎ | +| `check:cycles` | በሁሉም `src/` + `open-sse/` ውስጥ ያሉ circular imports (በAST ላይ የተመሠረተ፣ የtsconfig `paths` የተፈቱ)። ብቻውን ሲሰራ = ምክር ሰጪ ሲሆን cycles-ን ይዘረዝራል። `check:cycles:ratchet` (CI የሚያስኬደው) ብዛቱ በ`quality-baseline.json` ውስጥ ያለውን የ`metrics.cycles` ጣሪያ ሲያልፍ ያግዳል — በአሁኑ ጊዜ 14፣ `direction: down` ስለሆነ መቀነስ ብቻ ይችላል (#15159 G-01/G-02) | አዎ (ratchet) | +| `check:route-validation:t06` | በሁሉም routes ላይ የZod schemas መኖራቸውን (Tier 6 policy) | አዎ | +| `check:any-budget:t11` | የ`@ts-expect-error // any` ብዛት ከተፈቀደው budget እንደማይበልጥ (Tier 11 catraca) | አዎ | +| `check:provider-consistency` | `providers.ts` ውስጥ ያለው እያንዳንዱ provider `providerRegistry.ts` ውስጥ ተዛማጅ ግቤት አለው (እንዲሁም በተቃራኒው፣ በallowlist ውስጥ) | አዎ | +| `check:model-lifecycle` | ሦስቱ በእጅ የሚጠበቁ routing table-ዎች ከተመዘገበው lifecycle snapshot (#11503) ጋር ወጥነታቸውን ይጠብቃሉ፦ `FITNESS_TABLE` (`taskFitness.ts`)፣ `REGISTRY` route ሊያደርገው ለሚችል ከአገልግሎት የወጣ id ነጥብ አይሰጥም፤ እያንዳንዱ `BUILT_IN_ALIASES` target በ`REGISTRY` ውስጥ ይገኛል እና ከretired-id snapshot ውስጥ አይገኝም፤ አሁንም `REGISTRY` ውስጥ ያለ እያንዳንዱ ከአገልግሎት የወጣ id ወደ ሌላ ይተላለፋል ወይም በ`allowedRetiredInCatalog` ውስጥ ይዘረዘራል፤ እንዲሁም ምንም የ`DEFAULT_DEGRADATION_MAP` source ወይም target በዚያ snapshot ውስጥ ከአገልግሎት እንደወጣ አይታይም። ይህ፣ አንድ model በአሁኑ ጊዜ በቀጥታ upstream እየቀረበ መሆኑን አያረጋግጥም። Offline — በ`config/quality/model-lifecycle.json` ላይ በማነጻጸር ይሰራል፤ ይህም በእጅ `npm run quality:refresh-model-lifecycle` በመጠቀም ይታደሳል (network፤ ከCI ጋር አልተገናኘም)። `allowedRetiredInCatalog` የburn-down ratchet ነው፦ ግቤት ያክሉ ከtracking issue ጋር ብቻ። | አዎ | +| `check:fetch-targets` | በclient-side `src/` ውስጥ ያለ እያንዳንዱ `fetch("/api/...")` ወደ እውነተኛ `route.ts` ይፈታል | አዎ | +| `check:deps` | በrepo ውስጥ ባለው እያንዳንዱ `package.json` ውስጥ `npm install` ሊደረጉ የሚችሉ ሁሉም deps በ`dependency-allowlist.json` ውስጥ አሉ፤ አዲስ unpinned ወይም slopsquatted package-ዎች ምልክት ይደረግባቸዋል | አዎ | +| `audit:deps` | `npm audit` (root + electron) — ከፍተኛ/ወሳኝ advisories የሉም (ከosv `check:vuln-ratchet` ጋር ይደራረባል፤ Rationalization Backlogን ይመልከቱ) | አዎ | +| `check:lockfile` | የ`package-lock.json` ትክክለኛነት — https registry፣ integrity hashes፣ ምንም host overrides የሉም | አዎ | +| `check:licenses` | ለምርት ጥገኞች የSPDX ፈቃድ የተፈቀዱ ዝርዝር | አዎ | +| `check:tracked-artifacts` | ምንም የግንባታ ቅሪቶች / የተመዘገቡ `node_modules` ምሳሌያዊ አገናኞች የሉም (በተጨማሪም በhusky pre-commit ውስጥ ይሰራል፤ pre-push ሆን ተብሎ ቀላል ተደርጓል — #6716) | አዎ | +| `check:ai-attribution` | በPR commits፣ title ወይም body ውስጥ የAI/bot `Co-Authored-By` trailer ወይም የAI ማመንጨት footer የለም — ጥብቅ ደንብ #16 (ለPR→`release/**` በ`quality.yml` fast-gates loop ውስጥ — event payloadን ያነባል፣ PR ካልሆነ no-op ይሆናል — እና ለPR→`main` በ`ci.yml` lint ውስጥ ያለ PR-ብቻ step፤ እንዲሁም የhusky `commit-msg` hook፤ ሰብዓዊ co-authors ይፈቀዳሉ፤ #14436) | +| `check:vitest-exclusions` | እያንዳንዱ የVitest exclusion የመከታተያ issueን ይጠቅሳል እና በ`config/quality/vitest-exclusions.json` ውስጥ ይገኛል (#13204) | አዎ | +| `check:file-size` | ምንም source file በextension የተወሰነውን ከፍተኛ ገደብ አያልፍም (ratchet፦ የተቆለፉ ትልልቅ files በ`frozen` list ውስጥ) | አዎ | +| `check:error-helper` | በexecutors/handlers ውስጥ ያሉ error responses `buildErrorBody()` / `sanitizeErrorMessage()`ን ይጠቀማሉ (ጥብቅ ደንብ #12) | አዎ | +| `check:migration-numbering` | የMigration SQL ፋይሎች ያለ ክፍተት ወይም ድግግሞሽ በቅደም ተከተል ቁጥር ተሰጥቷቸዋል | አዎ | +| `check:public-creds` | ከ`publicCreds.ts` ውጭ ቀጥተኛ የOAuth `client_id`/`client_secret` ወይም የFirebase Web ቁልፎች የሉም (ጥብቅ ደንብ #11) | አዎ | +| `check:db-rules` | ከ`src/lib/db/` ሞጁሎች ውጭ ቀጥተኛ SQL የለም፤ ከ`localDb.ts` የbarrel-imports የሉም (ጥብቅ ደንቦች #2/#5) | አዎ | +| `check:known-symbols` | በdispatch ሰንጠረዦቻቸው ውስጥ የተመዘገቡ የአቅራቢ አስፈጻሚዎች፣ የማዘዋወሪያ ስልቶች እና ተርጓሚዎች በዲስክ ላይ ካሉት ፋይሎች ጋር ይዛመዳሉ — ወላጅ አልባ ወይም ያልታወጁ ምልክቶች የሉም | አዎ | +| `check:route-guard-membership` | ንዑስ ሂደትን የሚጀምር እያንዳንዱ route በ`isLocalOnlyPath()` ተመድቧል (ጥብቅ ደንቦች #15/#17) | አዎ | +| `check:test-discovery` | በrepo ውስጥ ያለ እያንዳንዱ `*.test.ts` / `*.spec.ts` ፋይል ቢያንስ በአንድ የሙከራ አስኪያጅ ይሰበሰባል (ratchet፦ በ`test-discovery-baseline.json` ውስጥ ያለው የወላጅ አልባ ፋይሎች ዝርዝር መቀነስ ብቻ ይችላል) | አዎ | +| `check:agent-skills-sync` | የተፈጠሩ agent-skills አርቲፋክቶች ከምንጭ ካታሎጋቸው ጋር ይዛመዳሉ (ልዩነት የለም) | +| `check:provider-asset-provenance` | የአቅራቢ አርማዎች/ንብረቶች የተመዘገበ የምንጭ መረጃ ግቤት አላቸው | +| `lint:json` | የJSON ውቅር ፋይሎች ያለ ስህተት ይተነተናሉ፣ እንዲሁም የrepo lint ደንቦችን ያሟላሉ | +| `typecheck:core` | የTypeScript ማጠናቀር ያለ ስህተት (የምክር ማስጠንቀቂያዎች ብቻ) | አዎ | +| `typecheck:noimplicit:core` | ጥብቅ `noImplicitAny` — ወደፊትን ያማከለ፤ ከዚህ ቀደም የነበሩ ብዙ የጥሪ ቦታዎች አሁንም ማብራሪያ ያስፈልጋቸዋል | **የምክር ብቻ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | በ`src/app/(dashboard)/**` (#7033) ላይ የተወሰነ `tsc` — የ`typecheck:core` በጥንቃቄ የተመረጠው የ27 ፋይሎች allowlist ምንም dashboard TSX አያካትትም፣ እንዲሁም `next build` እሱን ፈጽሞ type-check አያደርገውም (`next.config.mjs` `ignoreBuildErrors: true` ያዘጋጃል)፤ ስለዚህ በዚያ ያሉ የተተዉ-መለያ መመለሻ ስህተቶች (#6625/#6909) ለCI የማይታዩ ነበሩ። ልዩነቶቹ ከቀዘቀዘው የእያንዳንዱ-ፋይል/የእያንዳንዱ-TS-ኮድ ብዛት መነሻ (`config/quality/dashboard-typecheck-baseline.json`፣ ከ`check:known-symbols` ጋር ተመሳሳይ የጊዜ-ያለፈበት ማስገደጃ ንድፍ) ጋር ይነጻጸራሉ — ከመነሻው ብዛት በላይ ያሉ አዲስ ስህተቶች ብቻ በሩን ያሳንፋሉ፤ ቀድሞ የነበረ ስህተት ሲስተካከል በ`--update` መነሻውን ወደ ታች ያስተካክሉ። | አዎ | ### ስራ፦ `quality-gate` -ከ`test-coverage` በኋላ ይሰራል። ከተሳካ ውህደትን ያግዳል። +ከ`test-coverage` በኋላ ይሰራል። ካልተሳካ ውህደትን ይከለክላል። -| ስክሪፕት | የሚያረጋግጠው | አጋጅ | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | `quality-metrics.json`ን ያመነጫል (የESLint ማስጠንቀቂያዎች ብዛት፣ ከተዋሃደው shard ሪፖርት የተገኘ ሽፋን) | አዎ (ከratchet በፊት የሚከናወን) | -| `quality:ratchet` | በ`quality-baseline.json` ውስጥ ያለው እያንዳንዱ መለኪያ ወደ ኋላ አለመመለሱን ያረጋግጣል (የESLint ማስጠንቀቂያዎች ≤ baseline፤ ሽፋን ≥ baseline) | አዎ | -| `check:duplication` | የኮድ መደጋገም (jscpd@4) በ`quality-baseline.json` ውስጥ ካለው baseline እንዳይበልጥ ያረጋግጣል | አዎ | -| `check:complexity` | የፋይል ደረጃ cyclomatic complexity ከተወሰነው ከፍተኛ ገደብ እንዳይበልጥ ያረጋግጣል (ዋናው ESLint `complexity` + `max-lines-per-function`) | አዎ | -| `check:cognitive-complexity` | የcognitive complexity ratchet (`eslint-plugin-sonarjs`) — የተለየ የESLint ሂደት፤ CI ሁለቱንም አዋህዶ እንደ አንድ `check:complexity-ratchets` ደረጃ ያስኬዳል | አዎ | -| `check:dead-code` | ጥቅም ላይ ያልዋሉ exports / ፋይሎች ratchet (knip) ከbaseline ጋር ሲነጻጸር ወደ ኋላ እንዳይመለስ ያረጋግጣል | አዎ | -| `check:compression-budget` | የመጭመቂያ benchmark በጀት — ለእያንዳንዱ engine የተወሰኑት ዝቅተኛ የtoken ቁጠባ ገደቦች ወደ ኋላ መመለስ የለባቸውም | አዎ | -| `check:type-coverage` | የpercent-typed ratchet (`type-coverage`) ወደ ኋላ እንዳይመለስ ያረጋግጣል፤ በአብዛኛው `typecheck:noimplicit:core`ን ያካትታል | አዎ | -| `check:codeql-ratchet` | የተከፈቱ CodeQL ማንቂያዎች ብዛት ወደ ኋላ እንዳይመለስ ያረጋግጣል (በ`gh api` ያነባል፤ token ከሌለ ያለ ስህተት ይዘላል) — የማደሻ ድግግሞሽና በእጅ ማስጀመር፦ ከታች ያለውን "CodeQL ratchet" ይመልከቱ | አዎ | +| ስክሪፕት | የሚያረጋግጠው | የሚያግድ | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | `quality-metrics.json` ያመነጫል (የESLint ማስጠንቀቂያዎች ብዛት፣ ከተዋሃደው shard ሪፖርት የተገኘ ሽፋን) | አዎ (ከratchet በፊት የሚከናወን) | +| `quality:ratchet` | በ`quality-baseline.json` ውስጥ ያለው እያንዳንዱ መለኪያ ወደ ኋላ አለመመለሱን ያረጋግጣል (የESLint ማስጠንቀቂያዎች ≤ መነሻ መስመር፤ ሽፋን ≥ መነሻ መስመር) | አዎ | +| `check:duplication` | የኮድ መደጋገም (jscpd@4) በ`quality-baseline.json` ውስጥ ካለው መነሻ መስመር አይበልጥም | አዎ | +| `check:complexity` | የፋይል ደረጃ cyclomatic complexity ከገደቡ አይበልጥም (ዋናው ESLint `complexity` + `max-lines-per-function`) | አዎ | +| `check:cognitive-complexity` | የግንዛቤ ውስብስብነት ratchet (`eslint-plugin-sonarjs`) — የተለየ የESLint ማለፊያ፤ CI ሁለቱንም በአንድ `check:complexity-ratchets` ደረጃ ውስጥ አዋህዶ ያስኬዳል | አዎ | +| `check:dead-code` | ጥቅም ላይ ያልዋሉ exports / ፋይሎች ratchet (knip) ከመነሻ መስመሩ አንጻር ወደ ኋላ አይመለስም | አዎ | +| `check:compression-budget` | የመጭመቂያ ቤንችማርክ በጀት — ለእያንዳንዱ engine የtoken ቁጠባ ዝቅተኛ ገደቦች ወደ ኋላ መመለስ የለባቸውም | አዎ | +| `check:type-coverage` | በዓይነት የተገለጸው መቶኛ ratchet (`type-coverage`) ወደ ኋላ አይመለስም፤ `typecheck:noimplicit:core`ን በአብዛኛው ያካትታል | አዎ | +| `check:codeql-ratchet` | የተከፈቱ CodeQL ማንቂያዎች ብዛት ወደ ኋላ አይመለስም (በ`gh api` ያነባል፤ token ከሌለ ችግር ሳይፈጥር ይዘላል) — የማደሻ ድግግሞሽ እና በእጅ ማስጀመሪያ፦ ከታች ያለውን "CodeQL ratchet" ይመልከቱ | አዎ | ### ሥራ፦ `quality-extended` -ጠቅላላው ሥራ የምክር ብቻ ነው (`continue-on-error: true`)። በnpm ላይ የተመሠረቱ ratchets በተጨባጭ -ይሰራሉ፤ ውጫዊ scanners በ`gh release download` በኩል ይጫናሉ፣ binary አሁንም ከሌለም -ራሳቸውን ይዘላሉ (exit 0)። +ሙሉው ሥራ አማካሪ ነው (`continue-on-error: true`)። በnpm ላይ የተመሠረቱ ratchets በተግባር +ይሠራሉ፤ ውጫዊ scanners በ`gh release download` በኩል ይጫናሉ፣ binary አሁንም ከሌለም +በራሳቸው ይዘላሉ (exit 0)። -| ስክሪፕት | የሚያረጋግጠው | አጋጅነት | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:circular-deps` | ምንም ዓይነት ዑደታዊ dependencies አለመኖራቸውን ያረጋግጣል (dpdm) | **የምክር ብቻ** | -| `check:bundle-size` | የbundle መጠን ከተወሰነው ከፍተኛ ገደብ እንዳይበልጥ ያረጋግጣል | **የምክር ብቻ** | -| `check:secrets` | የሚስጥር መረጃ ቅኝት (gitleaks) — binary ከሌለ ይዘላል | **የምክር ብቻ** | -| `check:vuln-ratchet` | የdependency ተጋላጭነቶች (osv-scanner) ወደ ኋላ እንዳይመለሱ ያረጋግጣል — binary ከሌለ ይዘላል | **የምክር ብቻ** | -| `check:workflows` | የworkflow lint (actionlint + zizmor)፤ የጠፉ/የተበላሹ scanners፣ ልክ ያልሆኑ ሪፖርቶች ወይም የጠፋ ratchet baseline እንደ INCOMPLETE ያስከሽፋሉ። ትክክለኛ ግኝቶች የተመረጠውን strict/advisory/ratchet ፖሊሲ ይከተላሉ | ማስኬድ ያስፈልጋል፤ zizmor ratchet በCI ውስጥ አጋጅ ነው | -| `check:openapi-breaking` | በbase branch ውስጥ ካለው ጋር ሲነጻጸሩ በይፋዊው API ውል (`openapi.yaml`) ላይ ያሉ breaking changes (oasdiff) — `openapiBreaking=N`ን ያመነጫል፤ oasdiff ከሌለ ወይም base spec ሊፈታ ካልቻለ ይዘላል | **የምክር ብቻ** | +| ስክሪፕት | የሚያረጋግጠው | የሚያግድ | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:circular-deps` | ምንም ዑደታዊ dependencies የሉም (dpdm) | **አማካሪ** | +| `check:bundle-size` | የbundle መጠን ከገደቡ አይበልጥም | **አማካሪ** | +| `check:secrets` | የምስጢሮች ቅኝት (gitleaks) — binary ከሌለ ይዘላል | **አማካሪ** | +| `check:vuln-ratchet` | የdependency ተጋላጭነቶች (osv-scanner) ወደ ኋላ አይመለሱም — binary ከሌለ ይዘላል | **አማካሪ** | +| `check:workflows` | የworkflow lint (actionlint + zizmor)፤ የጠፉ/የተበላሹ scanners፣ ልክ ያልሆኑ ሪፖርቶች ወይም የጎደለ ratchet መነሻ መስመር INCOMPLETE በሚል እንዲወድቅ ያደርጋሉ። ትክክለኛ ግኝቶች የተመረጠውን strict/advisory/ratchet policy ይከተላሉ | መፈጸም ያስፈልጋል፤ zizmor ratchet በCI ውስጥ የሚያግድ ነው | +| `check:openapi-breaking` | ከመሠረታዊው branch (oasdiff) ጋር ሲነጻጸር በይፋዊው API contract (`openapi.yaml`) ላይ ያሉ አፍራሽ ለውጦች — `openapiBreaking=N` ያመነጫል፤ oasdiff ከሌለ ወይም መሠረታዊው spec ሊፈታ ካልቻለ ይዘላል | **አማካሪ** | ### ሥራ፦ `docs-sync-strict` -ወደ `main` በሚቀርብ እያንዳንዱ PR ላይ ይሰራል። ካልተሳካ ውህደትን ያግዳል። - -| ስክሪፕት | የሚያረጋግጠው | አጋጅ | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | ከታች ያሉትን 6 ንዑስ-ጌቶች በቅደም ተከተል የሚያስኬድ ዋና ጌት | አዎ | -| ↳ `check:docs-sync` | የCHANGELOG / OpenAPI / llm.txt ስሪቶች ወጥነት | አዎ | -| ↳ `check:docs-counts` | በጽሑፍ ውስጥ ያሉ ቁጥሮች (የአቅራቢዎች ብዛት፣ የሽግግሮች ብዛት፣ ወዘተ) ከትክክለኛዎቹ ቁጥሮች የratchet ክልል ውስጥ መሆናቸውን | አዎ | -| ↳ `check:env-doc-sync` | በ`.env.example` ውስጥ ያለ እያንዳንዱ env var በሰነዶች ሰንጠረዥ ውስጥ መመዝገቡን፣ እንዲሁም በተቃራኒው | አዎ | -| ↳ `check:deprecated-versions` | በሰነዶች ውስጥ የተቋረጡ የስሪት ሕብረቁምፊዎች አለመኖራቸውን | አዎ | -| ↳ `check:doc-links` | በሰነዶች ውስጥ ያሉ ውስጣዊ የmarkdown አገናኞች ወደ እውነተኛ ፋይሎች መጠቆማቸውን (`[text]`/`(path)` ቅርጸት) | አዎ | -| ↳ `check:fabricated-docs` | በሰነዶች ውስጥ የተጠቀሱ መስመሮች፣ env vars፣ የCLI ትዕዛዞች፣ የhook ስሞች እና የፋይል ዱካዎች በኮድ ማከማቻው ውስጥ መኖራቸውን። በ`--strict` በኩል ጠንካራ ጌት፤ ያለዚህ ባንዲራ ለስላሳ ውድቀት። | አዎ (በCI ውስጥ በ`--strict` በኩል) | -| `check:cli-i18n` | የCLI ትዕዛዝ ሕብረቁምፊዎች በሁሉም የi18n አካባቢ ፋይሎች ውስጥ መኖራቸውን | አዎ | -| `check:openapi-coverage` | የOpenAPI ዝርዝር መግለጫ ቢያንስ በratchet የተወሰነውን የእውነተኛ መስመሮች ዝቅተኛ ገደብ መሸፈኑን | አዎ | -| `check:openapi-security-tiers` | በ`openapi.yaml` ውስጥ ያሉ የደህንነት ደረጃ ማብራሪያዎች ከ`routeGuard.ts` ምደባዎች ጋር ወጥ መሆናቸውን | **አማካሪ** | -| `check:openapi-routes` | በ`openapi.yaml` ውስጥ ያለ እያንዳንዱ ዱካ ወደ እውነተኛ `route.ts` መጠቆሙን (ምናባዊ ፈጠራን ለመከላከል) | አዎ | -| `check:docs-symbols` | በ`docs/**/*.md` ውስጥ ያለ እያንዳንዱ የ`/api/...` ማጣቀሻ ወደ እውነተኛ `route.ts` መጠቆሙን (ምናባዊ ፈጠራን ለመከላከል) | አዎ | -| `i18n translation drift` | በi18n አካባቢ ፋይሎች ውስጥ ያልተተረጎሙ ቁልፎች — ማስጠንቀቂያ ብቻ | **አማካሪ** | +ወደ `main` በሚቀርብ እያንዳንዱ PR ላይ ይሠራል። ካልተሳካ ውህደትን ያግዳል። + +| ስክሪፕት | የሚያረጋግጠው | አጋጅ | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `check:docs-all` | ከታች ያሉትን 6 ንዑስ-ጌቶች በቅደም ተከተል የሚያስኬድ ሜታ-ጌት | አዎ | +| ↳ `check:docs-sync` | የCHANGELOG / OpenAPI / llm.txt ስሪት ወጥነት | አዎ | +| ↳ `check:docs-counts` | በጽሑፍ ውስጥ ያሉ ቁጥሮች (የአቅራቢዎች ብዛት፣ የፍልሰት ብዛት፣ ወዘተ) ከእውነተኛዎቹ ቁጥሮች የራቼት ክልል ውስጥ መሆናቸውን | አዎ | +| ↳ `check:env-doc-sync` | በ`.env.example` ውስጥ ያለ እያንዳንዱ የአካባቢ ተለዋዋጭ በሰነዶች ሰንጠረዥ ውስጥ መመዝገቡን፣ እንዲሁም በተቃራኒው | አዎ | +| ↳ `check:deprecated-versions` | በሰነዶች ውስጥ የተቋረጡ የስሪት ሕብረቁምፊዎች አለመኖራቸውን | አዎ | +| ↳ `check:doc-links` | በሰነዶች ውስጥ ያሉ ውስጣዊ markdown አገናኞች ወደ እውነተኛ ፋይሎች መድረሳቸውን (`[text]`/`(path)` ቅርጸት) | አዎ | +| ↳ `check:fabricated-docs` | በሰነዶች ውስጥ የተጠቀሱ መስመሮች፣ የአካባቢ ተለዋዋጮች፣ የCLI ትዕዛዞች፣ የhook ስሞች እና የፋይል ዱካዎች በኮድ ማከማቻው ውስጥ መኖራቸውን። በ`--strict` በኩል ጠንካራ ጌት፤ ያለ ይህ ጥቆማ ለስላሳ-ውድቀት። | አዎ (በCI ውስጥ በ`--strict` በኩል) | +| `check:cli-i18n` | የCLI ትዕዛዝ ሕብረቁምፊዎች በሁሉም የi18n አካባቢ ፋይሎች ውስጥ መኖራቸውን | አዎ | +| `check:openapi-coverage` | የOpenAPI ዝርዝር መግለጫ ቢያንስ ራቼት የተደረገ ዝቅተኛ የእውነተኛ መስመሮች ብዛት መሸፈኑን | አዎ | +| `check:openapi-security-tiers` | በ`openapi.yaml` ውስጥ ያሉ የደህንነት ደረጃ ማብራሪያዎች ከ`routeGuard.ts` ምደባዎች ጋር ወጥነት እንዳላቸው | **ምክር ሰጪ** | +| `check:openapi-routes` | በ`openapi.yaml` ውስጥ ያለ እያንዳንዱ ዱካ ወደ እውነተኛ `route.ts` መድረሱን (ምናባዊ መረጃን ለመከላከል) | አዎ | +| `check:docs-symbols` | በ`docs/**/*.md` ውስጥ ያለ እያንዳንዱ የ`/api/...` ማጣቀሻ ወደ እውነተኛ `route.ts` መድረሱን (ምናባዊ መረጃን ለመከላከል) | አዎ | +| `i18n translation drift` | በi18n አካባቢ ፋይሎች ውስጥ ያልተተረጎሙ ቁልፎች — ማስጠንቀቂያ ብቻ | **ምክር ሰጪ** | ### ሥራ፦ `i18n-ui-coverage` -| ስክሪፕት | የሚያረጋግጠው | አጋጅ | -| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check-ui-keys-coverage` (ውስጠ-መስመር) | የUI i18n ቁልፍ ሽፋን ≥ 65% መሆኑን | አዎ | -| `check-ui-value-drift` (ውስጠ-መስመር) | እንደገና የተጻፈ የእንግሊዝኛ **እሴት** የቆየ ትርጉም እንዳያስቀር | አዎ | -| `check-new-key-coverage` (ውስጠ-መስመር) | **አዲስ** የእንግሊዝኛ ቁልፍ በእያንዳንዱ አካባቢ መተርጎሙን — የ`__MISSING__:` ምልክት ውድቅ ይደረጋል | አዎ | -| `check-translation-ratio` | በእያንዳንዱ አካባቢ ያለው የእውነተኛ ትርጉም ምጥጥን (ከእንግሊዝኛ ጋር ተመሳሳይ / ቦታ-ያዥ / ከፈቃድ ዝርዝሩ ውጭ የጎደሉ ቅጠሎች) ከ`config/quality/i18n-translation-baseline.json` + የመቻቻል መጠን መብለጥ የለበትም | **አማካሪ** | +| ስክሪፕት | የሚያረጋግጠው | አጋጅ | +| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check-ui-keys-coverage` (ውስጠ-መስመር) | የUI i18n ቁልፍ ሽፋን ≥ 65% መሆኑን | አዎ | +| `check-ui-value-drift` (ውስጠ-መስመር) | እንደገና የተጻፈ የእንግሊዝኛ **እሴት** ጊዜ ያለፈበት ትርጉም እንዳያስቀር | አዎ | +| `check-new-key-coverage` (ውስጠ-መስመር) | **አዲስ** የእንግሊዝኛ ቁልፍ በእያንዳንዱ አካባቢ መተርጎሙን — የ`__MISSING__:` ምልክት ውድቅ ይደረጋል | አዎ | +| `check-translation-ratio` | በእያንዳንዱ አካባቢ ያለው የእውነተኛ-ትርጉም ጥምርታ (ከእንግሊዝኛ ጋር ተመሳሳይ / ቦታ ያዥ / ከተፈቀዱት ዝርዝር ውጭ የጎደሉ ቅጠሎች) ከ`config/quality/i18n-translation-baseline.json` + ተጨማሪ ክፍተት መብለጥ የለበትም | **ምክር ሰጪ** | -`fetch-depth: 0` ያስፈልገዋል — የvalue-drift ጌቱ `en.json`ን ከmerge base ጋር ያነጻጽራል። +`fetch-depth: 0` ያስፈልገዋል — የእሴት-ለውጥ ጌቱ `en.json`ን ከውህደት መነሻው ጋር ያነጻጽራል። -#### `check-ui-value-drift` — የቆየ-ትርጉም ጌት +#### `check-ui-value-drift` — ጊዜ ያለፈበት-ትርጉም ጌት -ሌሎቹ ጌቶች በመዋቅራዊ ሁኔታ ሊያዩት የማይችሉትን አንድ የi18n ውድቀት ይይዛል፦ አንድ የእንግሊዝኛ እሴት -እንደገና ሲጻፍ፣ ከ_ቀድሞው_ እንግሊዝኛ የተገኙት ትርጉሞች እንደነበሩ ይቀራሉ፤ በዚህም +ሌሎቹ ጌቶች በመዋቅራዊ መንገድ ሊያዩት የማይችሉትን አንድ የi18n ድግግሞሽ ስህተት ይይዛል፦ አንድ የእንግሊዝኛ እሴት +እንደገና ሲጻፍ እና ከ_ቀድሞው_ እንግሊዝኛ የተወሰዱት ትርጉሞች ሳይቀየሩ ሲቀሩ፣ እንግሊዝኛ ያልሆነ ቋንቋ ተጠቃሚዎች በእርግጠኝነት የተጻፈ ነገር ግን አሁን የተሳሳተ ጽሑፍ ማንበባቸውን ይቀጥላሉ። -ይህ በእውነት ለተጠቃሚዎች ተለቋል። የAntigravity -መግቢያ አጋዥ ሲጨመር (#5203) `oauthModal.googleOAuthWarning` እንደገና ተጻፈ፤ **ከ43 አካባቢዎች 39ኙ** -ኦፕሬተሮችን "ሙሉውን URL ገልብጠው ከታች እንዲለጥፉት" የሚነግር ጽሑፍ እንደያዙ ቀሩ — ለዚያ አቅራቢ ሊጠናቀቅ የማይችል ፍሰት። በሚከተሉት ምክንያቶች -እስከ #8463 ድረስ ሳይስተዋል ቆይቷል፦ +ይህ በእውነት ለምርት ተለቋል። የAntigravity +የመግቢያ አጋዥ ሲጨመር (#5203) `oauthModal.googleOAuthWarning` እንደገና ተጻፈ፤ **ከ43 አካባቢዎች 39ኙ** ኦፕሬተሮችን «ሙሉውን URL ገልብጠው ከታች እንዲለጥፉት» የሚነግር ጽሑፍ አቆዩ — ለዚያ አቅራቢ ሊጠናቀቅ የማይችል ሂደት። ይህም +እስከ #8463 ድረስ ሳይስተዋል ቀረ፣ ምክንያቱም፦ -- `sync-ui-keys` የሚሞላው **የሌሉ** ቁልፎችን ብቻ ነው፤ **የቆዩትን** ፈጽሞ አያዘምንም፤ -- `check-ui-keys-coverage` የቁልፎችን _መኖር_ ይቆጥራል፣ ስለዚህ የቆየ ትርጉም እንደተሸፈነ ይቆጠራል፤ -- `check-translation-drift` የ`docs/i18n//**.md` ሰነድ ነጸብራቆችን ይከታተላል — - `src/i18n/messages/*.json`ን ፈጽሞ አያነብም። ከ2026-09 ዳግም-ማመሳሰል ጀምሮ በ`docs-sync-strict` ሥራ ውስጥ አጋጅ ነው፦ ዋና ሰነድ ያርትዑ → `npm run i18n:run -- --files=` (በክፍል ደረጃ፣ አነስተኛ ወጪ ያለው)። +- `sync-ui-keys` የሚሞላው **የጎደሉ** ቁልፎችን ብቻ ነው፣ **ጊዜ ያለፈባቸውን** በፍጹም አይሞላም፤ +- `check-ui-keys-coverage` የቁልፍ _መኖርን_ ስለሚቆጥር፣ ጊዜ ያለፈበት ትርጉም እንደተሸፈነ ይቆጠራል፤ +- `check-translation-drift` የ`docs/i18n//**.md` የሰነድ ነጸብራቆችን ይከታተላል — + `src/i18n/messages/*.json`ን በፍጹም አያነብም። ከ2026-09 ዳግም-ማመሳሰል ጀምሮ በ`docs-sync-strict` ሥራ ውስጥ አጋጅ ነው፦ ዋና ሰነድን አርትዕ → `npm run i18n:run -- --files=` (በክፍል ደረጃ፣ አነስተኛ ወጪ ያለው)። -**ልዩነትን የሚያገናዝብ እንጂ በመነሻ መስመር ላይ የተመሠረተ አይደለም።** በውህደት መነሻው ላይ ያለውን `en.json` ከሥራ ማውጫው ጋር ያወዳድራል፤ የእንግሊዝኛ እሴቱ ለተለወጠ እያንዳንዱ ቁልፍ፣ አሁንም ያልተነካ ትርጉም የያዘ ማንኛውም የቋንቋ ስሪት ጊዜ ያለፈበት ነው። ይህ ሆን ብሎ **ከዚህ ቀደም ያለውን ዕዳ ያቆማል** — ልዩነት ለረጅም ጊዜ የኖረ ትርጉም ከየትኛው የድሮ እንግሊዝኛ እንደመጣ ሊያሳይ ስለማይችል፣ መግቢያ ቁጥጥሩ የአሁኑ ለውጥ የነካውን ብቻ ይገመግማል። አማራጩ (ለእያንዳንዱ ቁልፍ የሃሽ መነሻ መስመር) በእያንዳንዱ i18n PR ላይ እየተለወጠ፣ ከነባሩ ትልቁ መነሻ መስመር 3 እጥፍ የሆነ ~600 KB የመነጨ ፋይል ይጠይቃል። +**ልዩነትን የሚያገናዝብ እንጂ በመነሻ መስመር የማይደገፍ።** በውህደት መነሻው ላይ ያለውን `en.json` ከስራ ዛፉ ጋር ያወዳድራል፤ +የእንግሊዝኛ እሴቱ ለተቀየረው እያንዳንዱ ቁልፍ፣ ያልተነካ ትርጉም የያዘ ማንኛውም አካባቢያዊ ቋንቋ +ጊዜ ያለፈበት ነው። ይህ ሆን ብሎ **ቀድሞ የነበረውን ዕዳ ያቆማል** — ልዩነት +ለረጅም ጊዜ የቆየ ትርጉም ከየትኛው የቀድሞ እንግሊዝኛ እንደመጣ ማሳየት ስለማይችል፣ መግቢያ መቆጣጠሪያው +የአሁኑ ለውጥ የሚነካውን ብቻ ይገመግማል። አማራጩ (ለእያንዳንዱ ቁልፍ የhash መነሻ መስመር) ወደ +~600 KB የሚጠጋ የሚመነጭ ፋይል ይጠይቃል፤ ይህም ካለው ትልቁ መነሻ መስመር 3× ሲሆን፣ በእያንዳንዱ i18n PR ላይ ይለዋወጣል። ይህን ለማሟላት ሁለት መንገዶች አሉ፦ 1. የተነኩትን ትርጉሞች ያዘምኑ፣ ወይም -2. ወደ `__MISSING__:` ያቀናብሯቸው — ከዚያም የአሂድ ጊዜው የታረመውን እንግሊዝኛ ያቀርባል - (`src/i18n/request.ts::deepMergeFallback`, #7258) እና ቁልፉ ለትርጉም ወረፋ ይይዛል። +2. ወደ `__MISSING__:` ያቀናብሯቸው — ከዚያ runtime የታረመውን እንግሊዝኛ + (`src/i18n/request.ts::deepMergeFallback`, #7258) ያቀርባል፣ እና ቁልፉ ለትርጉም ወረፋ ይይዛል። -የሕብረቁምፊው **ትርጉም** ከተለወጠ፣ **ቁልፉን እንደገና መሰየምን** ይምረጡ፦ አዲስ ቁልፍ ጊዜ ያለፈበትን ትርጉም ሊወርስ አይችልም። #8463 የተጠቀመው ንድፍ ይህ ነው። +የሕብረቁምፊው **ትርጉም** ከተቀየረ፣ **ቁልፉን እንደገና መሰየም** ይመረጣል፦ አዲስ ቁልፍ +ጊዜ ያለፈበትን ትርጉም ሊወርስ አይችልም። #8463 የተጠቀመው ስርዓተ ጥለት ይህ ነው። ```bash npm run i18n:check-value-drift # ጥብቅ (CI የሚያስኬደው) @@ -222,47 +228,48 @@ npm run i18n:check-value-drift:warn # ሪፖርት ብቻ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -መነሻ ካታሎጉ ሊነበብ በማይችልበት ጊዜ (መነሻ ማጣቀሻው የሌለበት ጥልቀት የሌለው clone) `check-openapi-breaking`ን በመከተል፣ `SKIP reason=base-unresolved` በማሳየት በ0 ይወጣል። +መነሻ ካታሎጉ ሊነበብ በማይችልበት ጊዜ (የመነሻ ref የሌለው shallow +clone) `check-openapi-breaking`ን በመከተል፣ `SKIP reason=base-unresolved` ከሚለው ጋር በ0 ይወጣል። -### ሥራ፦ `i18n` +### ስራ፦ `i18n` -ሙሉ የi18n ማረጋገጫ ማትሪክስ (ለእያንዳንዱ የቋንቋ ስሪት አንድ ሥራ)። መላው ሥራ አማካሪ ነው። +ሙሉ የi18n ማረጋገጫ ማትሪክስ (ለእያንዳንዱ አካባቢያዊ ቋንቋ አንድ ስራ)። ሙሉው ስራ አማካሪ ነው። -| ስክሪፕት | የሚያረጋግጠው | እገዳ | -| ------------------------------- | --------------------------- | ----------------------------------------------- | -| `validate_translation.py quick` | የእያንዳንዱ የቋንቋ ስሪት የትርጉም ሙሉነት | **አማካሪ** (በመላው ሥራ ላይ `continue-on-error: true`) | +| ስክሪፕት | የሚያረጋግጠው | አጋጅ | +| ------------------------------- | ----------------------------- | ----------------------------------------------- | +| `validate_translation.py quick` | የትርጉም ሙሉነት በእያንዳንዱ አካባቢያዊ ቋንቋ | **አማካሪ** (በሙሉው ስራ ላይ `continue-on-error: true`) | -### ሥራ፦ `pr-test-policy` +### ስራ፦ `pr-test-policy` -በpull requestዎች ላይ ብቻ ይሠራል። +በpull requestዎች ላይ ብቻ ይሰራል። -| ስክሪፕት | የሚያረጋግጠው | እገዳ | -| ---------------------- | --------------------------------------------------------------------------------------------------------------- | --- | -| `check:pr-test-policy` | በ`src/`፣ `open-sse/`፣ `electron/` ወይም `bin/` ውስጥ ያለን የምርት ኮድ የሚለውጡ PRዎች ፈተናዎችን ማካተት ወይም ማዘመን አለባቸው (ጥብቅ ደንብ #8) | አዎ | -| `check:test-masking` | የተለወጡ የፈተና ፋይሎች አጠቃላይ የassert ብዛትን አይቀንሱም ወይም እንደ `assert.ok(true)` ያሉ ሁልጊዜ እውነት የሆኑ አባባሎችን አይጨምሩም | አዎ | -| `check:pr-evidence` | የPR ይዘቱ ለለውጡ የፈተና/VPS ማስረጃን ይጠቅሳል (የPR ጽሑፍን grep በማድረግ ጥብቅ ደንብ #18ን በራስ-ሰር ያስፈጽማል — ተሰባሪ ነው፣ Backlogን ይመልከቱ) | አዎ | +| ስክሪፕት | የሚያረጋግጠው | አጋጅ | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------ | --- | +| `check:pr-test-policy` | በ`src/`፣ `open-sse/`፣ `electron/`፣ ወይም `bin/` ውስጥ ያለ የምርት ኮድን የሚቀይሩ PRዎች ሙከራዎችን ማካተት ወይም ማዘመን አለባቸው (ጥብቅ ደንብ #8) | አዎ | +| `check:test-masking` | የተቀየሩ የሙከራ ፋይሎች አጠቃላይ የassert ብዛትን እንዳይቀንሱ ወይም የ`assert.ok(true)` tautologyዎችን እንዳይጨምሩ | አዎ | +| `check:pr-evidence` | የPR ይዘት ለለውጡ የtest/VPS ማስረጃን እንዲጠቅስ (የPR ጽሑፍን በgrep በመፈለግ ጥብቅ ደንብ #18ን በራስ-ሰር ይተገብራል — ደካማ ነው፣ የኋላ ስራ ዝርዝርን ይመልከቱ) | አዎ | -### ሥራ፦ `test-vitest` +### ስራ፦ `test-vitest` -ከ`build` በኋላ ይሠራል። ካልተሳካ ውህደትን ያግዳል። +ከ`build` በኋላ ይሰራል። ሲከሽፍ ውህደትን ያግዳል። -| ስብስብ | የሚያረጋግጠው | እገዳ | -| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP አገልጋይ (110 መሣሪያዎች)፣ autoCombo፣ cache — vitest runner | አዎ | -| `test:vitest:ui` | የUI አካል ፈተናዎች — vitest runner | **እገዳ ያደርጋል** — ቀድሞ የነበሩ አለመሳካቶች በ`vitest.config.ts` ውስጥ በግልጽ ተገልለዋል፤ አዲስ አለመሳካቶች ሥራውን ያሳኩታል | +| ስብስብ | የሚያረጋግጠው | አጋጅ | +| ---------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| `test:vitest` | MCP አገልጋይ (110 መሳሪያዎች)፣ autoCombo፣ cache — vitest runner | አዎ | +| `test:vitest:ui` | የUI ክፍሎች ሙከራዎች — vitest runner | **አጋጅ** — ቀድሞ የነበሩ ውድቀቶች በ`vitest.config.ts` ውስጥ በግልጽ ተገልለዋል፤ አዳዲስ ውድቀቶች ስራውን ያወድቃሉ | -### የሌሊት የሥራ ፍሰቶች (መርሐግብር የተያዘላቸው፣ አማካሪ) +### የምሽት workflows (የጊዜ ሰሌዳ ያላቸው፣ አማካሪ) -እነዚህ በcron መርሐግብር (እና `workflow_dispatch`) ይሠራሉ፣ በPRዎች ላይ ግን ፈጽሞ አይሠሩም። ሁሉም አማካሪ ናቸው። +እነዚህ በcron የጊዜ ሰሌዳ (እና `workflow_dispatch`) ይሰራሉ፣ በPRዎች ላይ በፍጹም አይሰሩም። ሁሉም አማካሪ ናቸው። -| የሥራ ፍሰት | የሚያረጋግጠው | እገዳ | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `nightly-property` | በዘፈቀደ seed እና ከፍተኛ የማስኬጃ ብዛት የሚካሄዱ fast-check ባህሪያት ፈተናዎች | **አማካሪ** | -| `nightly-resilience` | የheap ዕድገት መግቢያ ቁጥጥር፣ chaos ጉድለት ማስገባት፣ k6 የጭነት/የረጅም ጊዜ ጭነት ፈተና | **አማካሪ** | -| `nightly-llm-security` | promptfoo የማስገባት ጥቃት መከላከያ (የእገዳ ሁነታ) + garak probes (የአቅራቢ ምስጢር ከሌለ ይዘለላል) | **አማካሪ** | -| `nightly-schemathesis` | `docs/openapi.yaml`ን በመጠቀም በቀጥታ በሚሠራ OmniRoute ላይ የOpenAPI ውል fuzzing (schemathesis) — የዝርዝር መግለጫ ጥሰቶችን/ያልተያዙ 500 ስህተቶችን ያጋልጣል (Fase 8 B.4) | **አማካሪ** | -| `nightly-mutation` | በፈጣኑ የunit መስመር ላይ የStryker mutation-testing ውጤት — የሚተርፉ mutants ደካማ assertዎችን ያጋልጣሉ | **አማካሪ** | -| `nightly-compat` | በሚደገፉት `engines.node` ክልሎች ውስጥ የNode engine ተኳሃኝነት ማትሪክስ | **አማካሪ** | +| Workflow | የሚያረጋግጠው | አጋጅ | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `nightly-property` | የfast-check property ሙከራዎች ከዘፈቀደ seed እና ከፍተኛ የማስኬጃ ብዛት ጋር | **አማካሪ** | +| `nightly-resilience` | የheap ዕድገት መግቢያ መቆጣጠሪያ፣ chaos fault-injection፣ k6 የload/soak ሙከራ | **አማካሪ** | +| `nightly-llm-security` | የpromptfoo injection መከላከያ (block mode) + garak probes (የprovider secret ከሌለ ይዘለላል) | **አማካሪ** | +| `nightly-schemathesis` | `docs/openapi.yaml`ን በመጠቀም ቀጥታ OmniRoute ላይ የOpenAPI contract fuzzing (schemathesis) — የspec ጥሰቶችን / ያልተያዙ 500ዎችን ያጋልጣል (ደረጃ 8 B.4) | **አማካሪ** | +| `nightly-mutation` | በፈጣኑ unit lane ላይ የStryker mutation-testing ውጤት — የተረፉ mutants ደካማ assertዎችን ያጋልጣሉ | **አማካሪ** | +| `nightly-compat` | በሚደገፉት `engines.node` ክልሎች ሁሉ የNode engine ተኳኋኝነት ማትሪክስ | **አማካሪ** | --- @@ -528,43 +535,43 @@ diagnosticsን እንዲፈቱ ያደርጋል — የ"የተፈጠረ symbol" --- -## የማቀላጠፍ የኋላ ቀር ሥራዎች (የROI ግምገማ — ደረጃ 9 ሞገድ 3) +## የምክንያታዊ ማድረግ የኋላ ዝርዝር (የROI ግምገማ — ደረጃ 9 ሞገድ 3) -ይህ ዝርዝር በ2026-06-17 ከ`ci.yml` ጋር ተመሳክሯል (ቀዳሚው ስሪት +ይህ ንብረት ዝርዝር በ2026-06-17 ከ`ci.yml` ጋር ተመሳክሯል (ቀዳሚው ስሪት `audit:deps`፣ `check:tracked-artifacts`፣ `check:lockfile`፣ `check:licenses`፣ `check:dead-code`፣ `check:cognitive-complexity`፣ `check:type-coverage`፣ -`check:codeql-ratchet`፣ `check:pr-evidence`ን አላካተተም ነበር)። በተመሳከረው ስብስብ ላይ የተደረገ የROI ግምገማ -የሚከተሉትን የማቀላጠፍ እጩዎች ለይቷል። **ውህደቶቹ ሜካኒካዊ የCI -ለውጦች ናቸው፤ ማስገደጃ ለውጦቹ/ማስወገዶቹ ለኦፕሬተሩ የተተዉ የፖሊሲ ውሳኔዎች ናቸው።** ከታች ያለው ምንም ነገር -እስካሁን አልተተገበረም። +`check:codeql-ratchet`፣ `check:pr-evidence`ን አላካተተም ነበር)። የተመሳከረው ስብስብ የROI ግምገማ +የሚከተሉትን የምክንያታዊ ማድረግ ዕጩዎች ለይቷል። **ውህደቶቹ መካኒካዊ የCI +ለውጦች ናቸው፤ መቀየር/ማስወገድ ውሳኔዎቹ ለኦፕሬተሩ የተተዉ የፖሊሲ ውሳኔዎች ናቸው።** ከታች ካሉት ውስጥ +እስካሁን የተተገበረ የለም። -**ከላይ ያልተመዘገቡ ተጨማሪ ነገሮች** (አማካሪ፣ ዝቅተኛ ምልክት ያላቸው)፦ የ`docs-lint` ሥራ -(markdownlint + Vale፣ ሙሉው ሥራ `continue-on-error`) እና ራሳቸውን የቻሉት የስካነር የሥራ ፍሰቶች +**ከላይ ያልተመዘገቡ ተጨማሪ ነገሮችም** (አማካሪ፣ ዝቅተኛ ምልክት)፦ የ`docs-lint` ሥራ +(markdownlint + Vale፣ ሙሉው ሥራ `continue-on-error`) እና ራሳቸውን የቻሉ የስካነር የሥራ ፍሰቶች `semgrep.yml` / `codeql.yml` / `scorecard.yml`። `semgrepFindings: 0` በ -`quality-baseline.json` ውስጥ አለ፣ ነገር ግን በ`ci.yml` ውስጥ ከአጋጅ ራቸት ጋር አልተገናኘም — መለኪያው +`quality-baseline.json` ውስጥ አለ፣ ነገር ግን በ`ci.yml` ውስጥ ከሚያግድ ራቼት ጋር አልተገናኘም — መለኪያው በአሁኑ ጊዜ ወላጅ አልባ ነው። -### ማዋሃድ / ድግግሞሽን ማስወገድ (ሜካኒካዊ፣ ዝቅተኛ ስጋት) +### ማዋሃድ / ብዜት ማስወገድ (መካኒካዊ፣ ዝቅተኛ አደጋ) -እያንዳንዱ እጩ በ2026-06-17 በነበረው ቀጥታ የጌት ሁኔታ ላይ ተረጋግጧል (እመን-ግን-አረጋግጥ)፤ -ብዙ “ግልጽ” የሚመስሉ ውህደቶች እዳን የሚደብቁ ሆነው ተገኝተዋል እና **ያለ ችግር በቀጥታ የሚተኩ አይደሉም**። +እያንዳንዱ ዕጩ በ2026-06-17 በነበረው የቀጥታ ጌት ሁኔታ ላይ ተረጋግጧል (እመን-ግን-አረጋግጥ)፤ +በርካታ "ግልጽ" የሚመስሉ ውህደቶች ዕዳን እንደሚደብቁ ታውቋል እና **ንጹሕ** ቀጥተኛ ምትኮች አይደሉም። -- **`check:docs-sync` ሁለት ጊዜ ይሠራል** — በ`lint` ሥራ ውስጥ ራሱን ችሎ እና እንደገና በ`check:docs-all` (`docs-sync-strict`) እና በhusky pre-commit hook ውስጥ። ✅ **ተጠናቋል** — ራሱን የቻለው የ`lint` ጥሪ ተወግዷል። -- **የCVE ቅኝት** — ❌ **ንጹሕ ውህደት አይደለም።** `audit:deps` በማንኛውም ከፍተኛ/ወሳኝ CVE ላይ በጥብቅ ይወድቃል፤ `check:vuln-ratchet` (osv) የሚወድቀው ከመነሻ መስመሩ ጋር ሲነጻጸር _ማሽቆልቆል_ ሲኖር ብቻ ነው (በአሁኑ ጊዜ 1 MODERATE)። የተለያየ ትርጉም አላቸው — `audit:deps`ን ማስወገድ ፍጹሙን የከፍተኛ/ወሳኝ ጌት ያስቀራል። ሁለቱንም ያቆዩ። -- **የዑደት ማወቂያ** — ❌ **ንጹሕ ውህደት አይደለም።** `check:circular-deps` (dpdm) **91 ዑደቶችን** ያሳውቃል (አማካሪ የሆነውም ለዚህ ነው)፤ መጀመሪያ እነሱን ሳይፈታ ወደ አጋጅነት ማሳደግ አይቻልም፣ እንዲሁም አረንጓዴ ከሆነውና በጥንቃቄ ከተመረጠው `check:cycles` የበለጠ ሰፊ ወሰን አለው። `check:cycles`ን አጋጅ አድርገው ያቆዩ፤ 91ዱን የdpdm ዑደቶች መፍታት የራሱ የኋላ ቀር ሥራ ነው። -- **ውስብስብነት** — ✅ **ተጠናቋል** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)፦ አንድ የESLint ዳሰሳ፣ በruleId ይቆጥራል፣ ስለዚህ የcyclomatic+max-lines እና cognitive መነሻ መስመሮች ተለያይተው ይቆያሉ፤ ነጠላዎቹ `check:complexity` / `check:cognitive-complexity` ለአካባቢያዊ `--update` ይቆያሉ። -- **የ`/api` ፀረ-ቅዠት** — ✅ **ተጠናቋል** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)፦ አንድ የ`src/app/api` FS ቆጠራ፣ openapi-routes + docs-symbols አሁንም ራሳቸውን ችለው ሪፖርት ያደርጋሉ፤ ነጠላዎቹ ለአካባቢያዊ ማስኬዶች ይቆያሉ። -- **`check:node-runtime` በ11 ሥራዎች ውስጥ ይሠራል** — ⚠️ **ዝቅተኛ ROI።** እያንዳንዱ የተለየ runner ነው፣ እና ምርመራው <1s ነው፤ አጠቃላይ ቁጠባው ~10s ሲሆን፣ በእያንዳንዱ ሥራ ያለውን ርካሽ መከላከያ ማጣትን አያካክስም። ለዚህ ለውጥ የሚደረገው ጥረት ዋጋ የለውም። -- **በCI lint ላይ `typecheck:noimplicit:core`** — ✅ **ከlint ሥራ ተወግዷል** (አማካሪ `continue-on-error` ነበር)፤ አጋጁ የዓይነት ወሰን `typecheck:core` + `check:type-coverage` ነው። አካባቢያዊው ስክሪፕት ተይዟል። +- **`check:docs-sync` ሁለት ጊዜ ይሰራል** — በ`lint` ሥራ ውስጥ ራሱን ችሎ እና እንደገና በ`check:docs-all` (`docs-sync-strict`) ውስጥ እንዲሁም በhusky pre-commit hook ውስጥ። ✅ **ተጠናቋል** — ራሱን የቻለው የ`lint` ጥሪ ተወግዷል። +- **የCVE ቅኝት** — ❌ **ንጹሕ ውህደት አይደለም።** `audit:deps` በማንኛውም high/critical CVE ላይ በጥብቅ ይወድቃል፤ `check:vuln-ratchet` (osv) የሚወድቀው ከመነሻ መስመሩ ጋር ሲነጻጸር _መመለስ_ ሲኖር ብቻ ነው (በአሁኑ ጊዜ 1 MODERATE)። የተለያየ ትርጉም አላቸው — `audit:deps`ን ማስወገድ ፍጹሙን high/critical ጌት ያሳጣል። ሁለቱንም አቆዩ። +- **የዑደት ማወቂያ** — ✅ **ተጠናቋል** (#15159 G-01/G-02)። እዚህ የነበረው የድሮ ጽሑፍ `check:cycles`ን "አረንጓዴው፣ በጥንቃቄ የተመረጠው" ጌት ብሎ ጠርቶታል እና `check:circular-deps` (dpdm) 91 ዑደቶችን ስለዘገበ እንደ አጋጅ መቆየቱን አጽድቋል። ያ አረንጓዴ ውጤት **ሐሰተኛ አረንጓዴ** ነበር፦ `check:cycles` 5 ንዑስ ማውጫዎችን (450 ፋይሎች) ቃኝቷል፣ static `import|export … from`ን ብቻ አዛምዷል፣ እና እያንዳንዱን `@/` እና `@omniroute/open-sse/` specifier አስወግዷል፤ ስለዚህ በrepoው ውስጥ የበዙትን dynamic-import + alias ዑደቶች ማየት አልቻለም። ተስተካክሏል፦ ጌቱ አሁን `src` + `open-sse`ን (5023 ፋይሎች) ያስሳል፣ specifierዎችን ከTypeScript AST ይሰበስባል (ስለዚህ `import("…")` ይቆጠራል እና በtype-position ያለ `typeof import("…")` አይቆጠርም)፣ እንዲሁም የtsconfig `paths`ን ይፈታል። 0 ሳይሆን **14** ዑደቶችን ያገኛል። ቀድሞ የነበሩት 14 ዑደቶች በጌት PR ውስጥ ሊስተካከሉ ስለማይችሉ፣ `check:cycles` አሁን **ራቼት** ነው (`--ratchet`፣ በ`quality-baseline.json` ውስጥ ጣሪያው `metrics.cycles.value = 14`፣ `direction: down`) — ማንኛውንም _መመለስ_ ያግዳል እና ቁጥሩ መቀነስ ብቻ ይችላል። CI `npm run check:cycles:ratchet`ን ያስኬዳል። ቀስ በቀስ የማጥፋት ሥራው ከ**A-01** ጋር ይከናወናል። `check:circular-deps` (dpdm) እንደ ሰፊ ሁለተኛ አስተያየት አማካሪ ሆኖ ይቆያል። +- **ውስብስብነት** — ✅ **ተጠናቋል** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)፦ አንድ የESLint ቅኝት፣ cyclomatic+max-lines እና cognitive መነሻ መስመሮች እርስ በርሳቸው ነጻ ሆነው እንዲቆዩ በruleId ይቆጥራል፤ የተናጠል `check:complexity` / `check:cognitive-complexity` ለአካባቢያዊ `--update` ይቆያሉ። +- **የ`/api` ፀረ-ቅዠት** — ✅ **ተጠናቋል** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)፦ አንድ የ`src/app/api` FS ንብረት ዝርዝር፣ openapi-routes + docs-symbols አሁንም በተናጠል ሪፖርት ያደርጋሉ፤ የተናጠል ስክሪፕቶቹ ለአካባቢያዊ ማስኬዶች ይቆያሉ። +- **`check:node-runtime` በ11 ሥራዎች ውስጥ ይሰራል** — ⚠️ **ዝቅተኛ ROI።** እያንዳንዱ የተለየ runner ነው እና ፍተሻው <1s ነው፤ ጠቅላላ ቁጠባው ~10s ነው፣ በምላሹ ግን ርካሽ የየሥራውን ጥበቃ ማጣት ይኖራል። የለውጥ ውጣ ውረዱን አያዋጣም። +- **በCI lint ላይ `typecheck:noimplicit:core`** — ✅ **ከlint ሥራ ተወግዷል** (አማካሪ `continue-on-error` ነበር)፤ አጋጁ የtype ወሰን `typecheck:core` + `check:type-coverage` ነው። አካባቢያዊ ስክሪፕቱ ተቀምጧል። -### ማስገደጃን መቀየር / መወሰን (የኦፕሬተር ፖሊሲ) +### መቀየር / መወሰን (የኦፕሬተር ፖሊሲ) -- `check:openapi-security-tiers` (አማካሪ) — ❌ **በንጽሕና ወደ አጋጅነት ሊቀየር አይችልም።** በ0 ይወጣል፣ ነገር ግን በ`LOCAL_ONLY_API_PREFIXES` ስር ያሉ በርካታ የ`traffic-inspector` መንገዶች የ`x-loopback-only: true` ማብራሪያ እንደሌላቸው ያስጠነቅቃል። ማስገደድ በመጀመሪያ እነዚያን ማብራሪያዎች ወደ`openapi.yaml` ማከልን ይጠይቃል። -- `typecheck:noimplicit:core` (አማካሪ) — በአብዛኛው በአጋጁ `check:type-coverage` ራቸት ተሸፍኗል። ወደ ራቸት ይቀይሩት ወይም ተደጋጋሚውን ሁለተኛ የ`tsc` ማስኬድ ያስወግዱ። -- `test:vitest:ui` (አሁን **አጋጅ**) — ቀድሞ የነበሩ ውድቀቶች በ`vitest.config.ts` ውስጥ በ`// #8618` የክትትል አስተያየቶች በግልጽ ተገልለዋል፤ አዳዲስ ውድቀቶች ሥራውን ያወድቃሉ። -- `check:secrets` (gitleaks፣ በ3 በሰነድ የተመዘገቡ የሐሰት-አዎንታዊ ውጤቶች ላይ የቀዘቀዘ አጋጅ ራቸት) — 0 ላይ ለመድረስ 3ቱን allowlist ያድርጉ፣ ወይም ወደ አማካሪነት ዝቅ ያድርጉት። ከGitHub ቤተኛ secret-scanning + `check:public-creds` ጋር ይደራረባል። -- `check:pr-evidence` (አጋጅ፣ የPR-body ጽሑፍን በgrep ይፈልጋል) — ከፍተኛ የሐሰት-አዎንታዊ ስጋት አለው፤ ከተወገደ የHard Rule #18 ማስፈጸሚያን ያዳክማል፣ ስለዚህ ይህ እውነተኛ የፖሊሲ ውሳኔ ነው። -- `semgrep` (ራሱን የቻለ አማካሪ) — ለOWASP ምድቦች ከCodeQL ጋር ይደራረባል፤ መነሻ መስመሩን ከራቸት ጋር ያገናኙ ወይም ያስወግዱት። +- `check:openapi-security-tiers` (አማካሪ) — ❌ **በንጽሕና ሊቀየር አይችልም።** በ0 ይወጣል፣ ነገር ግን በ`LOCAL_ONLY_API_PREFIXES` ስር ያሉ በርካታ `traffic-inspector` መስመሮች የ`x-loopback-only: true` ማብራሪያ እንደሌላቸው ያስጠነቅቃል። ማስገደድ በመጀመሪያ እነዚያን ማብራሪያዎች ወደ`openapi.yaml` መጨመርን ይጠይቃል። +- `typecheck:noimplicit:core` (አማካሪ) — በአብዛኛው በአጋጁ `check:type-coverage` ራቼት ውስጥ ተካቷል። ወደ ራቼት ይቀየር ወይም ተደጋጋሚው ሁለተኛ የ`tsc` ማለፊያ ይወገድ። +- `test:vitest:ui` (አሁን **አጋጅ**) — ቀድሞ የነበሩ ውድቀቶች በ`vitest.config.ts` ውስጥ በ`// #8618` የክትትል አስተያየቶች በግልጽ ተገልለዋል፤ አዲስ ውድቀቶች ሥራውን ያወድቃሉ። +- `check:secrets` (gitleaks፣ በ3 የተመዘገቡ ሐሰተኛ-አዎንታዊ ውጤቶች ላይ የቀዘቀዘ አጋጅ ራቼት) — 0 ላይ ለመድረስ 3ቱን allowlist ውስጥ ያስገቡ፣ ወይም ወደ አማካሪ ዝቅ ያድርጉት። ከGitHub ቤተኛ secret-scanning + `check:public-creds` ጋር ይደራረባል። +- `check:pr-evidence` (አጋጅ፣ የPR-body ስድ ንባብን በgrep ይፈልጋል) — ከፍተኛ የሐሰት-አዎንታዊ አደጋ አለው፤ ከተወገደ የHard Rule #18 ማስፈጸሚያን ያዳክማል፣ ስለዚህ ይህ እውነተኛ የፖሊሲ ውሳኔ ነው። +- `semgrep` (ራሱን የቻለ አማካሪ) — ለOWASP ቤተሰቦች ከCodeQL ጋር ይደራረባል፤ መነሻ መስመሩን ከራቼት ጋር ያገናኙ ወይም ያስወግዱት። --- diff --git a/docs/i18n/ar/CONTRIBUTING.md b/docs/i18n/ar/CONTRIBUTING.md index 4ae77d2d20f..5a51fb16d97 100644 --- a/docs/i18n/ar/CONTRIBUTING.md +++ b/docs/i18n/ar/CONTRIBUTING.md @@ -390,19 +390,19 @@ docs/ # Documentation ## قائمة التحقق لطلب السحب - [ ] نجاح الاختبارات (`npm test`) -- [ ] اجتياز فحص التنسيق (`npm run lint`) -- [ ] نجاح عملية البناء (`npm run build`) +- [ ] نجاح فحص التنسيق (`npm run lint`) +- [ ] نجاح البناء (`npm run build`) - [ ] إضافة أنواع TypeScript للدوال والواجهات العامة الجديدة - [ ] عدم وجود أسرار أو قيم احتياطية مضمنة مباشرةً -- [ ] تضمين بيانات اعتماد المصادر العامة عبر `resolvePublicCred()` (راجع [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md))، وليس كقيم حرفية مطلقًا -- [ ] تمرير استجابات الأخطاء عبر `buildErrorBody()` / `sanitizeErrorMessage()` — من دون آثار مكدس خام في نصوص الاستجابة (راجع [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] تضمين بيانات اعتماد المنبع العامة عبر `resolvePublicCred()` (راجع [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md))، وعدم تضمينها أبدًا كقيم حرفية +- [ ] تمرير استجابات الأخطاء عبر `buildErrorBody()` / `sanitizeErrorMessage()` — وعدم تضمين تتبعات المكدس الأولية في نصوص الاستجابات (راجع [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] تمرير أوامر الصدفة (`exec` / `spawn`) قيم وقت التشغيل عبر `env`، وليس عبر استيفاء السلاسل النصية - [ ] التحقق من صحة جميع المدخلات باستخدام مخططات Zod -- [ ] إضافة **جزء** من سجل التغييرات ضمن `changelog.d/{features|fixes|maintenance}/-.md` للتغييرات الظاهرة للمستخدم (راجع [`changelog.d/README.md`](./changelog.d/README.md)) — **لا** تعدّل `CHANGELOG.md` مباشرةً؛ إذ تُجمّع الأجزاء عند الإصدار ولا تتعارض مطلقًا بين طلبات السحب -- [ ] تحديث الوثائق (إن كان ذلك منطبقًا) -- [ ] عدم فتح أي تنبيهات جديدة من CodeQL / Secret-Scanning، أو رفض كل تنبيه مع تقديم مبرر تقني يشير إلى المستند ذي الصلة ضمن `docs/security/` -- [ ] تصنيف المسارات التي تُنشئ عمليات فرعية (`/api/mcp/`، و`/api/cli-tools/runtime/`) على أنها `isLocalOnlyPath()` في `src/server/authz/routeGuard.ts` — راجع [القاعدة الصارمة رقم 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] عدم وجود تذييلات `Co-Authored-By` في رسائل الالتزام — يجب أن تظهر الالتزامات حصريًا ضمن هوية Git الخاصة بمالك المستودع (القاعدة الصارمة رقم 16) +- [ ] إضافة **جزء** من سجل التغييرات ضمن `changelog.d/{features|fixes|maintenance}/-.md` للتغييرات التي تؤثر في المستخدم (راجع [`changelog.d/README.md`](./changelog.d/README.md)) — لا تعدّل `CHANGELOG.md` مباشرةً؛ إذ تُجمّع الأجزاء عند الإصدار ولا تتعارض أبدًا بين طلبات السحب +- [ ] تحديث الوثائق (إن أمكن) +- [ ] عدم فتح أي تنبيهات جديدة من CodeQL / Secret-Scanning، أو رفض كل تنبيه مع تقديم مبرر تقني يشير إلى مستند `docs/security/` ذي الصلة +- [ ] تصنيف المسارات التي تنشئ عمليات فرعية (`/api/mcp/`، و`/api/cli-tools/runtime/`) على أنها `isLocalOnlyPath()` في `src/server/authz/routeGuard.ts` — راجع [القاعدة الصارمة رقم 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] عدم تضمين تذييلات `Co-authored-by` خاصة بالذكاء الاصطناعي/الروبوتات في رسائل الالتزام (القاعدة الصارمة رقم 16) — يُنسب الفضل إلى المتعاونين البشريين الذين أُعيد استخدام عملهم باستخدام تذييلات `Co-authored-by: Name ` القياسية --- diff --git a/docs/i18n/ar/docs/architecture/QUALITY_GATES.md b/docs/i18n/ar/docs/architecture/QUALITY_GATES.md index 04972bf9248..c7eb271ee82 100644 --- a/docs/i18n/ar/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ar/docs/architecture/QUALITY_GATES.md @@ -15,213 +15,212 @@ --- -## حصر البوابات وملفات تعريف التنفيذ +## مخزون البوابات وملفات تعريف التنفيذ ### قبول المرشحين -يُصدر كل من سيري عمل CI وبوابات الجودة حكمًا ثابتًا: `Gate / CI` و -`Gate / Quality`. وتسرد سياسة القبول ذات الإصدارات الخاصة بهما كل مهمة سابقة -بوصفها مطلوبة أو استشارية. يجب أن تنجح أي مهمة مطلوبة قابلة للتطبيق: فالنتائج -المفقودة أو الملغاة أو المتخطاة أو المعلقة أو غير المعروفة لا يمكنها إثبات PASS. يمكن -لتصنيف صالح خاص بالتوثيق فقط أو بالكتالوج فقط أن يجعل مسار الشيفرة غير قابل للتطبيق؛ -ولا يُعد طلب السحب المسودة مرشحًا مقبولًا. ولا تعفي التسمية `hotfix` من تقديم الأدلة. - -يغطي كلا سيري العمل طلبات السحب وعمليات الدفع إلى الفروع الرئيسية/فروع الإصدار، والتشغيل -اليدوي، وأحداث مجموعات الدمج. وتُشغّل عمليات الدفع والتشغيل اليدوي ومجموعات الدمج التحديد -الكامل. تستخدم التفرعات ومجموعات الدمج مشغّلات مستضافة للمهام التي تختار عادةً مشغّلات -ذاتية الاستضافة؛ ويجب التحقق من توفر سعة مستضافة كافية قبل الطرح. - -يحدد كل إيصال JSON قيمة SHA التي جرى جلبها، وتشغيل سير العمل، والمحاولة. -وترفض CLI عدم تطابق SHA بين النسخة المجلوبة والحدث. تربط اختبارات سير العمل عضوية السياسة -بقائمة `needs` الخاصة بمهمة الحكم، بحيث لا يمكن لمسار جديد أو محذوف أن يختفي بصمت. +يُصدر كل من سيري عمل CI وبوابات الجودة حكمًا مستقرًا: `Gate / CI` و +`Gate / Quality`. وتسرد سياسة القبول ذات الإصدارات الخاصة بهما كل مهمة مصدرية +على أنها مطلوبة أو استشارية. يجب أن تنجح أي مهمة مطلوبة منطبقة: فالنتائج +المفقودة أو الملغاة أو المتخطاة أو المعلقة أو غير المعروفة لا يمكنها إثبات PASS. ويمكن +لتصنيف صالح خاص بالوثائق فقط أو بالكتالوج فقط أن يجعل مسارًا برمجيًا غير منطبق؛ +ولا يُعد طلب السحب في وضع المسودة مرشحًا مقبولًا. كما أن تسمية `hotfix` لا تُعفي من تقديم الأدلة. + +يغطي كلا سيري العمل طلبات السحب وعمليات الدفع إلى فروع main/release، والتشغيل اليدوي، +وأحداث مجموعات الدمج. وتُشغّل عمليات الدفع والتشغيل اليدوي ومجموعات الدمج التحديد الكامل. تستخدم +التفرعات ومجموعات الدمج مشغّلات مستضافة للمهام التي تختار مشغّلات ذاتية الاستضافة في الحالات الأخرى؛ +ويجب التحقق من توفر سعة استضافة كافية قبل الطرح. + +يحدد كل إيصال JSON قيمة SHA التي تم سحبها، وتشغيل سير العمل، والمحاولة. +ترفض CLI عدم تطابق SHA بين النسخة المسحوبة والحدث. تربط اختبارات سير العمل عضوية السياسة +بقائمة `needs` الخاصة بمهمة الحكم، بحيث لا يمكن لمسار جديد أو مُزال أن يختفي بصمت. تغطي الإيصالات سير العمل الخاص بها، وليس النشر أو التوزيع أو التفاصيل الداخلية -لأداة فحص استشارية موجودة. ويُعد تفعيل اسمي الفحص في قواعد الفروع تغييرًا -إداريًا منفصلًا؛ فإضافة هذه المهام لا تحمي الفرع بحد ذاتها. +لأداة فحص استشارية موجودة. ويُعد تفعيل اسمي الفحص كليهما في قواعد الفروع +تغييرًا إداريًا منفصلًا؛ فإضافة هذه المهام لا تحمي فرعًا بحد ذاتها. -### حصر الفحص الثابت +### مخزون الفحص الساكن -يوجد حصر الأسماء المستعارة لـ npm ذات الإصدارات وعضوية الفحص الثابت في +يوجد مخزون الأسماء المستعارة لـ npm ذو الإصدارات وعضوية الفحص الساكن في `config/quality/gate-manifest.json`. شغّل `npm run check:gate-manifest` للتحقق -من أسماء البرامج النصية والأوامر الدقيقة بمقارنتها مع `package.json`؛ وتتسبب الإضافات -وعمليات الحذف وانحراف الأوامر في فشل كل من الخطاف المحلي ومهام تصنيف التغييرات في CI. -الاسم المستعار ليس مهمة في سير العمل، ولا مثيلًا في مصفوفة، ولا حالة اختبار: لذلك يجب -عدم عرض هذه الأعداد كما لو كانت قابلة للتبادل. +من أسماء البرامج النصية والأوامر الدقيقة بمقارنتها مع `package.json`؛ تؤدي الإضافات وعمليات الإزالة +وانحراف الأوامر إلى فشل كل من الخطاف المحلي ومهام تصنيف التغييرات في CI. +الاسم المستعار ليس مهمة سير عمل أو مثيل مصفوفة أو حالة اختبار: يجب +عدم عرض هذه الأعداد على أنها قابلة للتبادل. استخدم `npm run quality:scan -- --list` أو `npm run quality:scan:fast -- --list` -لفحص الأسماء المستعارة المحددة دون تنفيذها. يستدعي المشغّل نقطة دخول npm، ولذلك تُحفظ -بيئة تشغيلها (بما في ذلك Bun حيثما تكون مهيأة). يسجل البيان الأسماء المستعارة الواقعة خارج -ملفات التعريف هذه بوصفها مستدعاة بصورة منفصلة، وتُحظر أوامر الصيانة في ملفات تعريف الفحص -المخصصة للقراءة فقط. +لفحص الأسماء المستعارة المحددة دون تنفيذها. يستدعي المشغّل نقطة دخول +npm، ولذلك تُحفظ بيئة تشغيلها (بما في ذلك Bun حيث يكون مهيأ). +يسجل البيان الأسماء المستعارة الواقعة خارج ملفات التعريف هذه على أنها تُستدعى بشكل منفصل، كما +تُحظر أوامر الصيانة في ملفات تعريف الفحص للقراءة فقط. -لا تغطي ملفات التعريف هذه سوى الفحص الثابت. وهي لا تصادق على اختبارات المنتج +تغطي ملفات التعريف هذه الفحص الساكن فقط. وهي لا تعتمد اختبارات المنتج أو التغطية أو التحزيم أو الفحوص الخارجية أو القبول الكامل للمرشح للإصدار. يستخدم قبول سير العمل الملف المرتبط `config/quality/admission-policy.json` و -`scripts/quality/admission-verdict.mjs`. وتظل ملفات تعريف مراقبة الإصدار منفصلة؛ -افحص فحوصها وإيصالاتها القابلة للتطبيق بصورة مستقلة. ويُعد الحصر النصي -أدناه مرجعًا، وليس دليلًا على تشغيل إحدى البوابات فعليًا. - -توجد البرامج النصية ضمن `scripts/check/` (بوابات السياسة) و`scripts/quality/` (محرك التصعيد التدريجي). -ومصدر الحقيقة الخاص بـ CI هو `.github/workflows/ci.yml`. - -### المسار السريع لطلب سحب الإصدار (`quality.yml`) - -يُكمل `.github/workflows/quality.yml` ‏CI في طلبات السحب الخاصة بالفروع الرئيسية/فروع الإصدار، -وعمليات الدفع إلى الفروع المحمية، والتشغيل اليدوي، ومجموعات الدمج. تستخدم طلبات السحب فحوصًا -سريعة مرشحة حسب المسار. وقد أزيلت عملية البناء المكررة والمعطلة بصورة دائمة؛ بينما تظل فحوص -البناء/التحزيم/الإقلاع الفعلية ضمن CI. - -| المهمة | النطاق | الحجب | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | طلبات سحب التوثيق/الشيفرة؛ مراجع توثيق API وكل التوثيق | نعم | -| `Fast Quality Gates` | طلبات سحب الشيفرة؛ الفحوص الثابتة، وفحص الأنواع، وفحص أنواع لوحة المعلومات، واختبارات الوحدات المتأثرة | نعم | -| `Forgotten sibling tests` | طلبات سحب الشيفرة؛ تتبع الوحدات المتغيرة وصولًا إلى المستهلكين الثابتين واختبارات الأشقاء المرشحة؛ ويُبلّغ عن مسارات barrel والاستيراد الديناميكي بوصفها تشخيصات استشارية، مع استثناءات قائمة السماح المشار إليها | **استشاري** | -| `Vitest (fast-path)` | طلبات سحب الشيفرة؛ حزمة vitest السريعة | نعم | -| `Unit Tests fast-path` | طلبات سحب الشيفرة؛ حزمة اختبارات الوحدات ذات الأجزاء الأربعة | نعم | -| `No new ESLint warnings` | طلبات سحب الشيفرة؛ حارس lint المراعي لعمليات الكبت | نعم، بما في ذلك التفرعات | -| `Merge integrity (changelog + generated skills)` | طلبات السحب غير المسودة؛ مزامنة سجل التغييرات والمهارات المُنشأة | نعم، بما في ذلك التفرعات | - -#### تقرير اختبارات الأشقاء المنسية - -يعيد `npm run check:forgotten-sibling-tests` استخدام محلل الاستيراد الذي تستند إليه خريطة تأثير الاختبارات. -وبالنسبة إلى كل وحدة إنتاج متغيرة، فإنه يبلّغ عن سلاسل حتمية من النوع -`changed module/symbol -> static consumer -> candidate sibling test` عندما لا يكون الاختبار -المرشح موجودًا ضمن فروق طلب السحب. ويُحتفظ بملخص Markdown ونتيجة JSON بوصفهما -أثر سير العمل `forgotten-sibling-tests` لأغراض المعايرة قبل أي طرح حاجب. - -عمليات إعادة التصدير عبر ملفات التجميع والاستيرادات الديناميكية هي أدوات تشخيص للدقة فقط؛ ولا تؤدي مطلقًا إلى إنشاء -نتيجة مانعة. توجد الاستثناءات التي تمت مراجعتها في +`scripts/quality/admission-verdict.mjs`. وتظل ملفات تعريف مراقب الإصدار منفصلة؛ +افحص فحوصها المنطبقة وإيصالاتها بشكل مستقل. المخزون +النثري أدناه مرجع، وليس دليلًا على أن بوابة ما قد شُغّلت بالفعل. + +توجد البرامج النصية ضمن `scripts/check/` (بوابات السياسة) و`scripts/quality/` (محرك التصعيد). +مصدر الحقيقة الخاص بـ CI هو `.github/workflows/ci.yml`. + +### المسار السريع لطلبات سحب الإصدار (`quality.yml`) + +يُكمل `.github/workflows/quality.yml` ‏CI في طلبات السحب الخاصة بـ main/release، وعمليات الدفع +إلى الفروع المحمية، والتشغيل اليدوي، ومجموعات الدمج. تستخدم طلبات السحب فحوصًا سريعة مرشحة حسب المسار. وقد أزيل +بناء النسخة المكرر والمعطل بشكل دائم؛ بينما تظل فحوص البناء/التحزيم/الإقلاع الفعلية في CI. + +| المهمة | النطاق | الحظر | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `Docs Gates (fast-path)` | طلبات سحب الوثائق/الشيفرة؛ مراجع وثائق API وdocs-all | نعم | +| `Fast Quality Gates` | طلبات سحب الشيفرة؛ الفحوص الساكنة، وفحص الأنواع، وفحص أنواع لوحة المعلومات، واختبارات الوحدات المتأثرة | نعم | +| `Forgotten sibling tests` | طلبات سحب الشيفرة؛ تتبّع الوحدات المعدّلة إلى المستهلكين الساكنين واختبارات الوحدات الشقيقة المرشحة؛ تُبلّغ مسارات barrel والاستيراد الديناميكي بوصفها تشخيصات استشارية، مع استثناءات قائمة السماح المشار إليها | **استشاري** | +| `Vitest (fast-path)` | طلبات سحب الشيفرة؛ حزمة vitest السريعة | نعم | +| `Unit Tests fast-path` | طلبات سحب الشيفرة؛ حزمة اختبارات وحدات موزعة على 4 أجزاء | نعم | +| `No new ESLint warnings` | طلبات سحب الشيفرة؛ حارس lint مدرك لعمليات الكبت | نعم، بما في ذلك التفرعات | +| `Merge integrity (changelog + generated skills)` | طلبات السحب غير المسودة؛ مزامنة سجل التغييرات والمهارات المُنشأة | نعم، بما في ذلك التفرعات | + +#### تقرير اختبارات الوحدات الشقيقة المنسية + +يعيد `npm run check:forgotten-sibling-tests` استخدام محلّل الاستيراد الذي تستند إليه خريطة تأثير الاختبارات. +وبالنسبة إلى كل وحدة إنتاج معدّلة، فإنه يبلّغ عن سلاسل حتمية من نوع +`changed module/symbol -> static consumer -> candidate sibling test` عندما يكون الاختبار المرشح +غائبًا عن فرق طلب السحب. ويُحتفظ بملخص Markdown ونتيجة JSON بوصفهما +عنصر سير العمل `forgotten-sibling-tests` لأغراض المعايرة قبل أي طرح حاجب. + +إعادات التصدير المجمّعة والاستيرادات الديناميكية هي تشخيصات لحلّ الوحدات فقط؛ ولا تُنشئ مطلقًا +نتيجةً مانعة. توجد الاستثناءات المُراجَعة في `config/quality/forgotten-sibling-allowlist.json`. يجب أن يحدّد كل إدخال المستهلك والاختبار المرشّح، -وأن يقدّم مبررًا محددًا، وأن يتضمن رابطًا إلى مشكلة أو طلب سحب على GitHub. تؤدي الإدخالات المشوّهة إلى -الرفض افتراضيًا. لا يمكن للاستثناءات إخفاء اختبار مرشّح محذوف أو فرق يضيف `.skip`/`.todo`؛ -ويظل إضعاف التأكيدات وغيره من أساليب الإخفاء ضمن مسؤولية بوابة +وأن يقدّم مبررًا محددًا، وأن يتضمن رابطًا لمشكلة أو طلب سحب على GitHub. تؤدي الإدخالات غير الصحيحة +إلى الرفض افتراضيًا. لا يمكن للاستثناءات تجاوز اختبار مرشّح محذوف أو فرق يضيف `.skip`/`.todo`؛ +ويظل إضعاف التأكيدات وغيره من أساليب الإخفاء خاضعًا لبوابة `check:test-masking` المانعة بشكل مستقل. ### المهمة: `lint` -تعمل مع كل طلب سحب إلى `main`. تمنع الدمج عند الفشل. - -| البرنامج النصي (`npm run ...`) | ما يتحقق منه | مانع | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| `check:node-runtime` | وجود إصدار Node.js ضمن النطاق المدعوم | نعم | -| `check:cycles` | الاستيرادات الدائرية — جميع وحدات `src/` + `open-sse/` | نعم | -| `check:route-validation:t06` | وجود مخططات Zod في جميع المسارات (سياسة المستوى 6) | نعم | -| `check:any-budget:t11` | ألّا يتجاوز عدد `@ts-expect-error // any` الميزانية المحددة (بوابة المستوى 11) | نعم | -| `check:provider-consistency` | لكل موفّر في `providers.ts` إدخال مطابق في `providerRegistry.ts` (والعكس صحيح، ضمن قائمة السماح) | نعم | -| `check:model-lifecycle` | تظل جداول التوجيه الثلاثة التي تُصان يدويًا متسقة مع لقطة دورة الحياة المحفوظة في المستودع (#11503): لا يمنح `FITNESS_TABLE` (`taskFitness.ts`) درجات لأي معرّف متقاعد يمكن لـ `REGISTRY` توجيهه؛ وكل هدف في `BUILT_IN_ALIASES` موجود في `REGISTRY` وغير موجود في لقطة المعرّفات المتقاعدة؛ وكل معرّف متقاعد لا يزال في `REGISTRY` تتم إعادة توجيهه أو إدراجه في `allowedRetiredInCatalog`؛ ولا يظهر أي مصدر أو هدف من `DEFAULT_DEGRADATION_MAP` كمتقاعد في تلك اللقطة. لا يثبت هذا أن نموذجًا ما تتم خدمته حاليًا بواسطة مصدر علوي فعّال. يعمل دون اتصال — إذ يقارن مع `config/quality/model-lifecycle.json`، الذي يُحدَّث يدويًا باستخدام `npm run quality:refresh-model-lifecycle` (يتطلب الشبكة؛ وغير مدمج في CI). تمثل `allowedRetiredInCatalog` آلية تناقص تدريجي: لا تُضف إدخالًا إلا مع مشكلة تتبع. | نعم | -| `check:fetch-targets` | كل استدعاء `fetch("/api/...")` في `src/` من جانب العميل يُحلّ إلى ملف `route.ts` فعلي | نعم | -| `check:deps` | جميع التبعيات القابلة للتثبيت باستخدام `npm install` عبر كل ملف `package.json` في المستودع موجودة في `dependency-allowlist.json`؛ ويتم تمييز الحزم الجديدة غير المثبّتة بإصدار محدد أو التي يُشتبه في انتحالها لأسماء حزم أخرى | نعم | -| `audit:deps` | `npm audit` (الجذر + Electron) — لا توجد تنبيهات عالية/حرجة (يتداخل مع `check:vuln-ratchet` الخاص بـ OSV؛ راجع قائمة الأعمال المتراكمة للترشيد) | نعم | -| `check:lockfile` | سلامة `package-lock.json` — سجل HTTPS، وبصمات تكامل، وعدم وجود تجاوزات للمضيف | نعم | -| `check:licenses` | قائمة السماح لتراخيص SPDX لتبعيات الإنتاج | نعم | -| `check:tracked-artifacts` | لا توجد نواتج بناء / روابط رمزية لـ `node_modules` مُضمَّنة في المستودع (يُشغَّل أيضًا في husky قبل الالتزام؛ أما ما قبل الدفع فخفيف عمدًا — #6716) | نعم | -| `check:ai-attribution` | لا يوجد تذييل `Co-Authored-By` منسوب إلى الذكاء الاصطناعي/بوت، ولا تذييل يشير إلى التوليد بالذكاء الاصطناعي في التزامات طلب السحب أو عنوانه أو نصه — القاعدة الصارمة رقم 16 (ضمن حلقة البوابات السريعة في `quality.yml` لطلبات السحب إلى `release/**` — يقرأ حمولة الحدث ولا ينفّذ شيئًا خارج طلبات السحب — وكذلك خطوة خاصة بطلبات السحب ضمن فحص التنسيق في `ci.yml` لطلبات السحب إلى `main`؛ بالإضافة إلى خطاف husky المسمى `commit-msg`؛ يُسمح بالمؤلفين المشاركين من البشر؛ #14436) | -| `check:vitest-exclusions` | يشير كل استثناء في Vitest إلى مشكلة تتبّع ويظهر في `config/quality/vitest-exclusions.json` (#13204) | نعم | -| `check:file-size` | لا يتجاوز أي ملف مصدر الحد الأقصى الخاص بامتداده (آلية تصعيد تدريجية: الملفات الكبيرة المجمّدة مدرجة في قائمة `frozen`) | نعم | -| `check:error-helper` | تستخدم استجابات الأخطاء في المنفّذات/المعالجات `buildErrorBody()` / `sanitizeErrorMessage()` (القاعدة الصارمة رقم 12) | نعم | -| `check:migration-numbering` | ملفات SQL الخاصة بالترحيل مرقّمة تسلسليًا، دون فجوات أو تكرارات | نعم | -| `check:public-creds` | لا توجد قيم حرفية لـ OAuth مثل `client_id`/`client_secret` أو مفاتيح Firebase Web خارج `publicCreds.ts` (القاعدة الصارمة رقم 11) | نعم | -| `check:db-rules` | لا توجد استعلامات SQL خام خارج وحدات `src/lib/db/`؛ ولا توجد استيرادات تجميعية من `localDb.ts` (القاعدتان الصارمتان رقم 2 ورقم 5) | نعم | -| `check:known-symbols` | تتطابق منفّذات المزوّد، واستراتيجيات التوجيه، والمترجمات المسجّلة في جداول التوزيع الخاصة بها مع الملفات الموجودة على القرص — دون رموز يتيمة أو غير مصرّح بها | نعم | -| `check:route-guard-membership` | كل مسار ينشئ عملية فرعية مُصنّف بواسطة `isLocalOnlyPath()` (القاعدتان الصارمتان رقم 15 ورقم 17) | نعم | -| `check:test-discovery` | يجمع مشغّل اختبار واحد على الأقل كل ملف `*.test.ts` / `*.spec.ts` في المستودع (آلية التدرّج: لا يمكن لقائمة الملفات اليتيمة في `test-discovery-baseline.json` إلا أن تتقلص) | نعم | -| `check:agent-skills-sync` | تطابق مخرجات مهارات الوكيل المُولَّدة كتالوج المصدر الخاص بها (دون انحراف) | -| `check:provider-asset-provenance` | تحمل شعارات/أصول المزوّد إدخالًا مسجلًا لمصدرها | -| `lint:json` | تُحلَّل ملفات إعداد JSON وتستوفي قواعد التدقيق الخاصة بالمستودع | -| `typecheck:core` | ترجمة TypeScript دون أخطاء (تحذيرات إرشادية فقط) | نعم | -| `typecheck:noimplicit:core` | تطبيق صارم لـ `noImplicitAny` — استشرافي؛ لا تزال العديد من مواضع الاستدعاء الموجودة مسبقًا بحاجة إلى تعليقات توضيحية للأنواع | **إرشادي** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | تشغيل `tsc` ضمن نطاق `src/app/(dashboard)/**` (#7033) — لا تتضمن قائمة السماح المنقّحة المكوّنة من 27 ملفًا في `typecheck:core` أي ملفات TSX للوحة المعلومات، كما أن `next build` لا يتحقق من أنواعها أيضًا (يضبط `next.config.mjs` الخيار `ignoreBuildErrors: true`)، لذا كانت تراجعات المعرّفات المعزولة هناك (#6625/#6909) غير مرئية لنظام CI. تُقارَن النتائج بخط أساس مجمّد لعدد الأخطاء لكل ملف ولكل رمز TS (`config/quality/dashboard-typecheck-baseline.json`، بنمط فرض التقادم نفسه المستخدم في `check:known-symbols`) — لا تفشل البوابة إلا عند ظهور أخطاء جديدة تتجاوز العدد المسجل في خط الأساس؛ ويمكن خفض الحد تدريجيًا باستخدام `--update` عند إصلاح خطأ موجود مسبقًا. | نعم | +تُشغَّل عند كل طلب سحب إلى `main`. تمنع الدمج عند الفشل. + +| البرنامج النصي (`npm run ...`) | ما يتحقق منه | مانع | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | +| `check:node-runtime` | أن يكون إصدار Node.js ضمن النطاق المدعوم | نعم | +| `check:cycles` | الاستيرادات الدائرية عبر كامل `src/` و`open-sse/` (استنادًا إلى AST، مع حلّ `paths` الخاصة بـ tsconfig). الوضع المجرّد = إرشادي، ويسرد الدورات. يحظر `check:cycles:ratchet` (الذي تشغّله CI) عندما يتجاوز العدد الحد الأقصى `metrics.cycles` في `quality-baseline.json` — وهو حاليًا 14، مع `direction: down`، لذا لا يمكنه إلا الانخفاض (#15159 G-01/G-02) | نعم (آلية تصعيدية) | +| `check:route-validation:t06` | وجود مخططات Zod في جميع المسارات (سياسة المستوى 6) | نعم | +| `check:any-budget:t11` | ألّا يتجاوز عدد `@ts-expect-error // any` الميزانية المحددة (آلية المستوى 11) | نعم | +| `check:provider-consistency` | لكل موفّر في `providers.ts` إدخال مطابق في `providerRegistry.ts` (والعكس صحيح، ضمن قائمة السماح) | نعم | +| `check:model-lifecycle` | تظل جداول التوجيه الثلاثة التي تتم صيانتها يدويًا متسقة مع لقطة دورة الحياة المُضمّنة في المستودع (#11503): لا يمنح `FITNESS_TABLE` (`taskFitness.ts`) أي معرّف متقاعد يمكن لـ `REGISTRY` توجيهه؛ وكل هدف في `BUILT_IN_ALIASES` موجود في `REGISTRY` وغير موجود في لقطة المعرّفات المتقاعدة؛ وكل معرّف متقاعد لا يزال موجودًا في `REGISTRY` تتم إعادة توجيهه أو إدراجه في `allowedRetiredInCatalog`؛ ولا يظهر أي مصدر أو هدف من `DEFAULT_DEGRADATION_MAP` كمتقاعد في تلك اللقطة. لا يثبت هذا أن النموذج تتم خدمته حاليًا بواسطة مزوّد فعّال. يعمل دون اتصال — إذ يقارن مع `config/quality/model-lifecycle.json`، الذي يُحدَّث يدويًا باستخدام `npm run quality:refresh-model-lifecycle` (يتطلب الشبكة؛ غير مدمج في CI). يُعد `allowedRetiredInCatalog` آلية تصعيدية لخفض العدد: لا تُضف إدخالًا إلا مع مشكلة تتبّع. | نعم | +| `check:fetch-targets` | كل استدعاء `fetch("/api/...")` في `src/` من جهة العميل يُحلّ إلى ملف `route.ts` فعلي | نعم | +| `check:deps` | جميع التبعيات القابلة للتثبيت عبر `npm install` في كل ملف `package.json` ضمن المستودع موجودة في `dependency-allowlist.json`؛ ويتم الإبلاغ عن الحزم الجديدة غير المثبّتة بإصدار محدد أو التي تنتحل أسماء حزم أخرى | نعم | +| `audit:deps` | تشغيل `npm audit` (الجذر + Electron) — لا توجد تحذيرات عالية/حرجة (يتداخل مع `check:vuln-ratchet` الخاص بـ OSV؛ راجع قائمة الأعمال المتراكمة للترشيد) | نعم | +| `check:lockfile` | سلامة `package-lock.json` — سجل HTTPS، وبصمات سلامة، ومن دون تجاوزات للمضيف | نعم | +| `check:licenses` | قائمة السماح لتراخيص SPDX لتبعيات الإنتاج | نعم | +| `check:tracked-artifacts` | عدم وجود نواتج بناء / روابط رمزية ملتزم بها إلى `node_modules` (يُشغَّل أيضًا ضمن husky قبل الالتزام؛ أما ما قبل الدفع فخفيف عمدًا — #6716) | نعم | +| `check:ai-attribution` | عدم وجود تذييل `Co-Authored-By` للذكاء الاصطناعي/الروبوتات أو تذييل يفيد بالتوليد بواسطة الذكاء الاصطناعي في التزامات طلب السحب أو عنوانه أو نصه — القاعدة الصارمة #16 (ضمن حلقة البوابات السريعة في `quality.yml` لطلبات السحب إلى `release/**` — يقرأ حمولة الحدث ولا ينفّذ شيئًا خارج طلبات السحب — وكذلك خطوة خاصة بطلبات السحب في فحص التنسيق بملف `ci.yml` لطلبات السحب إلى `main`؛ وأيضًا خطاف `commit-msg` في husky؛ يُسمح بالمؤلفين المشاركين من البشر؛ #14436) | +| `check:vitest-exclusions` | كل استثناء في Vitest يذكر مشكلة تتبّع ويظهر في `config/quality/vitest-exclusions.json` (#13204) | نعم | +| `check:file-size` | لا يتجاوز أي ملف مصدر الحد الأقصى المحدد لكل امتداد (آلية تصعيد تدريجية: الملفات الكبيرة المجمّدة في قائمة `frozen`) | نعم | +| `check:error-helper` | تستخدم استجابات الأخطاء في المنفّذات/المعالِجات `buildErrorBody()` / `sanitizeErrorMessage()` (القاعدة الصارمة #12) | نعم | +| `check:migration-numbering` | ملفات SQL الخاصة بالترحيل مرقّمة تسلسليًا، من دون فجوات أو تكرارات | نعم | +| `check:public-creds` | لا توجد قيم OAuth حرفية لـ `client_id`/`client_secret` أو مفاتيح Firebase Web خارج `publicCreds.ts` (القاعدة الصارمة رقم 11) | نعم | +| `check:db-rules` | لا توجد تعليمات SQL خام خارج وحدات `src/lib/db/`؛ ولا توجد عمليات استيراد تجميعي من `localDb.ts` (القاعدتان الصارمتان رقم 2 ورقم 5) | نعم | +| `check:known-symbols` | تتطابق منفّذات المزوّد واستراتيجيات التوجيه والمترجمات المسجّلة في جداول التوزيع الخاصة بها مع الملفات الموجودة على القرص — من دون رموز يتيمة أو غير مصرّح بها | نعم | +| `check:route-guard-membership` | يُصنَّف كل مسار ينشئ عملية فرعية بواسطة `isLocalOnlyPath()` (القاعدتان الصارمتان رقم 15 ورقم 17) | نعم | +| `check:test-discovery` | يلتقط مشغّل اختبار واحد على الأقل كل ملف `*.test.ts` / `*.spec.ts` في المستودع (آلية تصاعدية: لا يمكن لقائمة الملفات اليتيمة في `test-discovery-baseline.json` إلا أن تتقلّص) | نعم | +| `check:agent-skills-sync` | تطابق عناصر agent-skills المُنشأة كتالوج المصدر الخاص بها (من دون انحراف) | +| `check:provider-asset-provenance` | تحمل شعارات/أصول المزوّد إدخالًا مسجلًا لمصدرها | +| `lint:json` | يجري تحليل ملفات إعداد JSON وتستوفي قواعد التدقيق الخاصة بالمستودع | +| `typecheck:core` | تجميع TypeScript من دون أخطاء (تحذيرات إرشادية فقط) | نعم | +| `typecheck:noimplicit:core` | ‏`noImplicitAny` صارم — استشرافي؛ لا تزال العديد من مواضع الاستدعاء الموجودة مسبقًا بحاجة إلى تعليقات توضيحية للأنواع | **إرشادي** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | تشغيل `tsc` بنطاق يقتصر على `src/app/(dashboard)/**` ‏(#7033) — لا تتضمن قائمة السماح المنسّقة المكوّنة من 27 ملفًا والخاصة بـ `typecheck:core` أي ملف TSX للوحة المعلومات، كما أن `next build` لا يتحقق من أنواعها أيضًا (يضبط `next.config.mjs` الخيار `ignoreBuildErrors: true`)، ولذلك لم تكن تراجعات المعرّفات المعزولة هناك (#6625/#6909) مرئية لنظام CI. تُجرى المقارنة مع خط أساس مجمّد لأعداد الأخطاء لكل ملف ولكل رمز TS (`config/quality/dashboard-typecheck-baseline.json`، باتباع نمط فرض اكتشاف التقادم نفسه المستخدم في `check:known-symbols`) — لا تؤدي إلى فشل البوابة إلا الأخطاء الجديدة التي تتجاوز العدد المسجّل في خط الأساس؛ خفّض خط الأساس تدريجيًا باستخدام `--update` عند إصلاح خطأ موجود مسبقًا. | نعم | ### المهمة: `quality-gate` -تُشغَّل بعد `test-coverage`. تمنع الدمج عند الفشل. +تعمل بعد `test-coverage`. تمنع الدمج عند الفشل. -| البرنامج النصي | ما يتحقق منه | حاجب للدمج | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `quality:collect` | يُنشئ `quality-metrics.json` (عدد تحذيرات ESLint، والتغطية من تقرير الأجزاء المدمج) | نعم (يسبق آلية التثبيت) | -| `quality:ratchet` | عدم تراجع أي مقياس في `quality-baseline.json` (تحذيرات ESLint ≤ خط الأساس؛ التغطية ≥ خط الأساس) | نعم | -| `check:duplication` | عدم تجاوز تكرار الشيفرة (jscpd@4) لخط الأساس في `quality-baseline.json` | نعم | -| `check:complexity` | عدم تجاوز التعقيد الدوري على مستوى الملف للحد الأقصى (قاعدتا ESLint الأساسيتان `complexity` و`max-lines-per-function`) | نعم | -| `check:cognitive-complexity` | آلية تثبيت التعقيد الإدراكي (`eslint-plugin-sonarjs`) — تمريرة ESLint منفصلة؛ يشغّل CI كليهما مدمجين في خطوة `check:complexity-ratchets` واحدة | نعم | -| `check:dead-code` | عدم تراجع آلية تثبيت التصديرات / الملفات غير المستخدمة (knip) مقارنة بخط الأساس | نعم | -| `check:compression-budget` | ميزانية معيار الضغط — يجب ألا تتراجع الحدود الدنيا لتوفير الرموز لكل محرك | نعم | -| `check:type-coverage` | عدم تراجع آلية تثبيت نسبة التغطية بالأنواع (`type-coverage`)؛ وهي تستوعب إلى حد كبير `typecheck:noimplicit:core` | نعم | -| `check:codeql-ratchet` | عدم تراجع عدد تنبيهات CodeQL المفتوحة (تُقرأ عبر `gh api`؛ تخطٍ سلس عند عدم وجود رمز وصول) — لدورية التحديث والتشغيل اليدوي: راجع "آلية تثبيت CodeQL" أدناه | نعم | +| البرنامج النصي | ما يتحقق منه | مانع للدمج | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | +| `quality:collect` | يُصدر `quality-metrics.json` (عدد تحذيرات ESLint، والتغطية من تقرير الأجزاء المدمج) | نعم (يسبق آلية التصعيد) | +| `quality:ratchet` | عدم تراجع أي مقياس في `quality-baseline.json` (تحذيرات ESLint ≤ خط الأساس؛ التغطية ≥ خط الأساس) | نعم | +| `check:duplication` | عدم تجاوز تكرار الشيفرة (jscpd@4) لخط الأساس في `quality-baseline.json` | نعم | +| `check:complexity` | عدم تجاوز التعقيد الدوري على مستوى الملف للحد الأقصى (قاعدتا ESLint الأساسيتان `complexity` و`max-lines-per-function`) | نعم | +| `check:cognitive-complexity` | آلية تصعيد التعقيد المعرفي (`eslint-plugin-sonarjs`) — تمريرة ESLint منفصلة؛ يشغّل CI كلتيهما مدمجتين كخطوة `check:complexity-ratchets` واحدة | نعم | +| `check:dead-code` | عدم تراجع آلية تصعيد التصديرات / الملفات غير المستخدمة (knip) مقارنةً بخط الأساس | نعم | +| `check:compression-budget` | ميزانية معيار ضغط الأداء — يجب ألا تتراجع الحدود الدنيا لتوفير الرموز لكل محرك | نعم | +| `check:type-coverage` | عدم تراجع آلية تصعيد نسبة الأنواع المحددة (`type-coverage`)؛ وهي تغطي إلى حد كبير `typecheck:noimplicit:core` | نعم | +| `check:codeql-ratchet` | عدم تراجع عدد تنبيهات CodeQL المفتوحة (تُقرأ عبر `gh api`؛ تخطٍّ سلس عند عدم وجود رمز مميز) — لمعرفة وتيرة التحديث والتشغيل اليدوي: راجع "آلية تصعيد CodeQL" أدناه | نعم | ### المهمة: `quality-extended` -المهمة بأكملها استشارية (`continue-on-error: true`). تعمل آليات التثبيت المستندة إلى npm +المهمة بأكملها استشارية (`continue-on-error: true`). تعمل آليات التصعيد المستندة إلى npm فعليًا؛ أما أدوات الفحص الخارجية فتُثبَّت عبر `gh release download` وتتخطى نفسها (رمز الخروج 0) -إذا ظل الملف الثنائي غير موجود. +عندما تظل الأداة التنفيذية غير موجودة. -| البرنامج النصي | ما يتحقق منه | حاجب للدمج | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:circular-deps` | عدم وجود تبعيات دائرية (dpdm) | **استشاري** | -| `check:bundle-size` | عدم تجاوز حجم الحزمة للحد الأقصى | **استشاري** | -| `check:secrets` | فحص الأسرار (gitleaks) — يُتخطى إذا كان الملف الثنائي غير موجود | **استشاري** | -| `check:vuln-ratchet` | عدم تراجع ثغرات التبعيات (osv-scanner) — يُتخطى إذا كان الملف الثنائي غير موجود | **استشاري** | -| `check:workflows` | تدقيق سير العمل (actionlint + zizmor)؛ يؤدي غياب أدوات الفحص أو تعطلها، أو عدم صلاحية التقارير، أو غياب خط أساس آلية التثبيت إلى الفشل بحالة INCOMPLETE. تتبع النتائج الصالحة سياسة الوضع الصارم/الاستشاري/آلية التثبيت المحددة | التنفيذ مطلوب؛ آلية تثبيت zizmor حاجبة في CI | -| `check:openapi-breaking` | التغييرات الكاسرة لعقد API العام (`openapi.yaml`) مقارنة بالفرع الأساسي (oasdiff) — يُنشئ `openapiBreaking=N`؛ يُتخطى إذا كان oasdiff غير موجود أو تعذر تحليل المواصفات الأساسية | **استشاري** | +| البرنامج النصي | ما يتحقق منه | مانع للدمج | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | +| `check:circular-deps` | عدم وجود تبعيات دائرية (dpdm) | **استشاري** | +| `check:bundle-size` | عدم تجاوز حجم الحزمة للحد الأقصى | **استشاري** | +| `check:secrets` | فحص الأسرار (gitleaks) — يتم التخطي إذا كانت الأداة التنفيذية غير موجودة | **استشاري** | +| `check:vuln-ratchet` | عدم تراجع ثغرات التبعيات (osv-scanner) — يتم التخطي إذا كانت الأداة التنفيذية غير موجودة | **استشاري** | +| `check:workflows` | تدقيق سير العمل (actionlint + zizmor)؛ يؤدي غياب أدوات الفحص أو تعطلها، أو التقارير غير الصالحة، أو غياب خط أساس آلية التصعيد إلى الفشل بالحالة INCOMPLETE. تتبع النتائج الصالحة سياسة الصرامة/الاستشارة/التصعيد المحددة | التنفيذ مطلوب؛ آلية تصعيد zizmor مانعة للدمج في CI | +| `check:openapi-breaking` | التغييرات الكاسرة لعقد واجهة API العامة (`openapi.yaml`) مقارنةً بالفرع الأساسي (oasdiff) — يُصدر `openapiBreaking=N`؛ ويتم التخطي إذا كان oasdiff غائبًا أو تعذّر تحليل المواصفات الأساسية | **استشاري** | ### المهمة: `docs-sync-strict` -تعمل عند كل PR إلى `main`. وتحجب الدمج عند الفشل. - -| البرنامج النصي | ما يتحقق منه | مانع | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | بوابة شاملة تشغّل البوابات الفرعية الست أدناه بالتتابع | نعم | -| ↳ `check:docs-sync` | اتساق الإصدارات بين CHANGELOG وOpenAPI وllm.txt | نعم | -| ↳ `check:docs-counts` | أن تكون الأعداد المذكورة في النصوص (عدد المزوّدين، وعدد عمليات الترحيل، وما إلى ذلك) ضمن نافذة التصعيد التدريجي للأعداد الفعلية | نعم | -| ↳ `check:env-doc-sync` | أن يكون كل متغير بيئة في `.env.example` موثقًا في جدول ضمن الوثائق، والعكس صحيح | نعم | -| ↳ `check:deprecated-versions` | عدم وجود سلاسل إصدارات مهملة في الوثائق | نعم | -| ↳ `check:doc-links` | أن تشير روابط Markdown الداخلية في الوثائق إلى ملفات فعلية (بالصيغة `[النص]`/`(path)`) | نعم | -| ↳ `check:fabricated-docs` | أن تكون المسارات، ومتغيرات البيئة، وأوامر CLI، وأسماء الخطافات، ومسارات الملفات المذكورة في الوثائق موجودة في قاعدة الشيفرة. بوابة صارمة عبر `--strict`؛ وفشل غير مانع من دون هذا الخيار. | نعم (عبر `--strict` في CI) | -| `check:cli-i18n` | وجود سلاسل أوامر CLI في جميع ملفات الإعدادات المحلية لـ i18n | نعم | -| `check:openapi-coverage` | أن تغطي مواصفات OpenAPI حدًا أدنى متزايدًا تدريجيًا من المسارات الفعلية | نعم | -| `check:openapi-security-tiers` | اتساق تعليقات مستويات الأمان في `openapi.yaml` مع التصنيفات الموجودة في `routeGuard.ts` | **استشاري** | -| `check:openapi-routes` | أن يشير كل مسار في `openapi.yaml` إلى ملف `route.ts` فعلي (لمنع الهلوسة) | نعم | -| `check:docs-symbols` | أن يشير كل مرجع `/api/...` في `docs/**/*.md` إلى ملف `route.ts` فعلي (لمنع الهلوسة) | نعم | -| `i18n translation drift` | المفاتيح غير المترجمة في ملفات الإعدادات المحلية لـ i18n — تحذير فقط | **استشاري** | +تعمل مع كل طلب سحب إلى `main`. وتمنع الدمج عند الفشل. + +| السكربت | ما الذي يتحقق منه | حاجب | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | بوابة تجميعية تشغّل البوابات الفرعية الست أدناه بالتتابع | نعم | +| ↳ `check:docs-sync` | اتساق الإصدارات بين CHANGELOG وOpenAPI وllm.txt | نعم | +| ↳ `check:docs-counts` | الأعداد المذكورة في النصوص (عدد المزوّدين، وعدد عمليات الترحيل، وما إلى ذلك) تقع ضمن نافذة التصعيد التدريجي للأعداد الفعلية | نعم | +| ↳ `check:env-doc-sync` | كل متغير بيئة في `.env.example` موثّق في جدول ضمن الوثائق، والعكس صحيح | نعم | +| ↳ `check:deprecated-versions` | عدم وجود سلاسل إصدارات مهملة في الوثائق | نعم | +| ↳ `check:doc-links` | روابط markdown الداخلية في الوثائق تحيل إلى ملفات موجودة فعلًا (بصيغة `[text]`/`(path)`) | نعم | +| ↳ `check:fabricated-docs` | المسارات، ومتغيرات البيئة، وأوامر CLI، وأسماء الخطافات، ومسارات الملفات المذكورة في الوثائق موجودة في قاعدة الشفرة. بوابة صارمة عبر `--strict`؛ وفشل غير حاجب دون هذا الخيار. | نعم (عبر `--strict` في CI) | +| `check:cli-i18n` | سلاسل أوامر CLI موجودة في جميع ملفات اللغات في i18n | نعم | +| `check:openapi-coverage` | تغطي مواصفات OpenAPI حدًا أدنى متزايدًا تدريجيًا من المسارات الفعلية | نعم | +| `check:openapi-security-tiers` | تعليقات مستويات الأمان في `openapi.yaml` متسقة مع التصنيفات في `routeGuard.ts` | **استشاري** | +| `check:openapi-routes` | كل مسار في `openapi.yaml` يحيل إلى ملف `route.ts` موجود فعلًا (لمنع الهلوسة) | نعم | +| `check:docs-symbols` | كل مرجع إلى `/api/...` في `docs/**/*.md` يحيل إلى ملف `route.ts` موجود فعلًا (لمنع الهلوسة) | نعم | +| `i18n translation drift` | المفاتيح غير المترجمة في ملفات لغات i18n — تحذير فقط | **استشاري** | ### المهمة: `i18n-ui-coverage` -| البرنامج النصي | ما يتحقق منه | مانع | -| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check-ui-keys-coverage` (مضمّن) | أن تكون تغطية مفاتيح i18n لواجهة المستخدم ≥ 65% | نعم | -| `check-ui-value-drift` (مضمّن) | ألا تترك إعادة كتابة **قيمة** إنجليزية أي ترجمة قديمة | نعم | -| `check-new-key-coverage` (مضمّن) | أن يكون المفتاح الإنجليزي **الجديد** مترجمًا في كل إعداد محلي — وتُرفض علامة `__MISSING__:` | نعم | -| `check-translation-ratio` | يجب ألا تتجاوز نسبة الترجمات الفعلية لكل إعداد محلي (القيم المطابقة للإنجليزية / العناصر النائبة / العناصر المفقودة خارج قائمة السماح) القيمة المحددة في `config/quality/i18n-translation-baseline.json` مع هامش السماح | **استشاري** | +| السكربت | ما الذي يتحقق منه | حاجب | +| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (مضمّن) | تغطية مفاتيح i18n لواجهة المستخدم تبلغ ≥ 65% | نعم | +| `check-ui-value-drift` (مضمّن) | إعادة صياغة **قيمة** إنجليزية لا تترك وراءها ترجمة قديمة | نعم | +| `check-new-key-coverage` (مضمّن) | كل مفتاح إنجليزي **جديد** مترجم في كل لغة — تُرفض علامة `__MISSING__:` | نعم | +| `check-translation-ratio` | يجب ألا تتجاوز نسبة الترجمات الفعلية لكل لغة (القيم المطابقة للإنجليزية / العناصر النائبة / العناصر الناقصة خارج قائمة السماح) القيمة المحددة في `config/quality/i18n-translation-baseline.json` + الهامش | **استشاري** | -يتطلب `fetch-depth: 0` — إذ تقارن بوابة انحراف القيم ملف `en.json` مع قاعدة الدمج. +تحتاج إلى `fetch-depth: 0` — إذ تقارن بوابة انحراف القيم ملف `en.json` مع قاعدة الدمج. #### `check-ui-value-drift` — بوابة الترجمات القديمة -ترصد هذه البوابة حالة تراجع واحدة في i18n لا تستطيع البوابات الأخرى اكتشافها بنيويًا: إعادة -كتابة قيمة إنجليزية مع بقاء الترجمات المشتقة من النص الإنجليزي _السابق_، ما يؤدي إلى استمرار -المستخدمين غير الناطقين بالإنجليزية في قراءة نص مصاغ بثقة لكنه أصبح خاطئًا. +ترصد حالة التراجع الوحيدة في i18n التي لا تستطيع البوابات الأخرى اكتشافها بنيويًا: إعادة صياغة قيمة إنجليزية +مع بقاء الترجمات المشتقة من النص الإنجليزي _السابق_، ما يجعل +المستخدمين غير الناطقين بالإنجليزية يستمرون في قراءة نص يبدو موثوقًا لكنه أصبح خاطئًا. -وقد حدث هذا فعليًا في إصدار منشور. أُعيدت كتابة `oauthModal.googleOAuthWarning` عند إضافة -أداة تسجيل الدخول المساعدة Antigravity ‏(#5203)؛ لكن **39 من أصل 43 إعدادًا محليًا** احتفظت -بنص يطلب من المشغّلين «نسخ عنوان URL الكامل ولصقه أدناه» — وهي آلية لا يمكن إكمالها لهذا -المزوّد. ولم يُلاحظ ذلك حتى #8463 للأسباب التالية: +وقد حدث هذا فعليًا في إصدار منشور. أُعيدت صياغة `oauthModal.googleOAuthWarning` عند إضافة مساعد تسجيل الدخول +Antigravity (#5203)؛ وأبقت **39 من أصل 43 لغة** على نص يطلب من المشغّلين «نسخ عنوان URL +بالكامل ولصقه أدناه» — وهي آلية لا يمكن إكمالها لهذا المزوّد. ولم +يُلاحظ ذلك حتى #8463 للأسباب التالية: -- لا يملأ `sync-ui-keys` إلا المفاتيح **الغائبة**، وليس المفاتيح **القديمة**؛ -- يحسب `check-ui-keys-coverage` _وجود_ المفتاح، ولذلك تُحتسب الترجمة القديمة على أنها مغطاة؛ -- يتتبع `check-translation-drift` نُسخ الوثائق المطابقة في `docs/i18n//**.md` — - ولا يقرأ `src/i18n/messages/*.json` مطلقًا. وهو مانع في المهمة `docs-sync-strict` منذ - إعادة المزامنة في 2026-09: عند تعديل وثيقة أساسية ← `npm run i18n:run -- --files=` (على مستوى القسم، ومنخفض التكلفة). +- لا يملأ `sync-ui-keys` إلا المفاتيح **الغائبة**، ولا يحدّث المفاتيح **القديمة** مطلقًا؛ +- يحتسب `check-ui-keys-coverage` _وجود_ المفتاح، لذا تُحسب الترجمة القديمة على أنها مغطاة؛ +- يتتبع `check-translation-drift` نسخ الوثائق المتطابقة في `docs/i18n//**.md` — + ولا يقرأ `src/i18n/messages/*.json` أبدًا. وهو حاجب في المهمة `docs-sync-strict` منذ + إعادة المزامنة في 2026-09: عند تعديل وثيقة أساسية → `npm run i18n:run -- --files=` (على مستوى القسم، وقليل التكلفة). -**مراعي للفروق، وليس مدعومًا بخط أساس.** يقارن `en.json` عند قاعدة الدمج -بشجرة العمل؛ ولكل مفتاح تغيّرت قيمته الإنجليزية، تُعدّ أي لغة ما تزال تحتوي على -ترجمة لم تُمس قديمة. يؤدي هذا عمدًا إلى **تجميد الدين الموجود مسبقًا** — إذ لا يمكن للفرق -كشف النص الإنجليزي القديم الذي جاءت منه ترجمة قديمة، لذلك لا تتحقق البوابة إلا مما -يمسّه التغيير الحالي. أما البديل (خط أساس لتجزئة كل مفتاح) فسيتطلب ملفًا مولّدًا بحجم -نحو 600 KB، أي 3 أضعاف أكبر خط أساس موجود، وسيتغير مع كل PR متعلق بالتدويل. +**مدرك للاختلافات، وغير مستند إلى خط أساس.** يقارن `en.json` عند قاعدة الدمج +بشجرة العمل؛ ولكل مفتاح تغيّرت قيمته الإنجليزية، تُعد أي لغة ما تزال تحتفظ +بترجمة لم تُمس قديمة. يؤدي ذلك عمدًا إلى **تجميد الدَّين الموجود مسبقًا** — إذ لا يمكن +للاختلاف أن يكشف النص الإنجليزي القديم الذي جاءت منه ترجمة قديمة، لذا لا تفحص البوابة +إلا ما يمسّه التغيير الحالي. أما البديل (خط أساس لتجزئة كل مفتاح) فسيتطلب +ملفًا مولّدًا بحجم ~600 KB، أي 3× حجم أكبر خط أساس موجود، وسيتغير مع كل طلب سحب خاص بالتدويل. -هناك طريقتان لاستيفاء ذلك: +هناك طريقتان لاجتياز الفحص: 1. تحديث الترجمات المتأثرة، أو 2. تعيينها إلى `__MISSING__:` — وعندها يقدّم وقت التشغيل النص الإنجليزي المصحح - (`src/i18n/request.ts::deepMergeFallback`، #7258)، ويُضاف المفتاح إلى قائمة انتظار الترجمة. + (`src/i18n/request.ts::deepMergeFallback`، #7258) ويُدرج المفتاح في طابور الترجمة. إذا تغيّر **معنى** السلسلة، فمن الأفضل **إعادة تسمية المفتاح**: لا يمكن لمفتاح جديد أن يرث ترجمة قديمة. وهذا هو النمط الذي استخدمه #8463. @@ -233,47 +232,47 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` يخرج بالرمز 0 مع `SKIP reason=base-unresolved` عندما تتعذر قراءة الكتالوج الأساسي (نسخة -سطحية دون مرجع الأساس)، بما يماثل `check-openapi-breaking`. +سطحية من المستودع دون مرجع الأساس)، بما يماثل `check-openapi-breaking`. ### المهمة: `i18n` -مصفوفة تحقق كاملة للتدويل (مهمة واحدة لكل لغة). المهمة بأكملها استشارية. +مصفوفة التحقق الكاملة من التدويل (مهمة واحدة لكل لغة). المهمة بأكملها استشارية. -| البرنامج النصي | ما يتحقق منه | الحظر | -| ------------------------------- | ---------------------- | -------------------------------------------------------- | -| `validate_translation.py quick` | اكتمال الترجمة لكل لغة | **استشاري** (`continue-on-error: true` على المهمة كاملة) | +| البرنامج النصي | ما يتحقق منه | الحظر | +| ------------------------------- | ---------------------- | ------------------------------------------------------ | +| `validate_translation.py quick` | اكتمال الترجمة لكل لغة | **استشاري** (`continue-on-error: true` للمهمة بأكملها) | ### المهمة: `pr-test-policy` -تُشغّل لطلبات السحب فقط. +تعمل على طلبات السحب فقط. -| البرنامج النصي | ما يتحقق منه | الحظر | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----- | -| `check:pr-test-policy` | يجب أن تتضمن طلبات السحب التي تغيّر شيفرة الإنتاج في `src/` أو `open-sse/` أو `electron/` أو `bin/` اختبارات أو تحدّثها (القاعدة الصارمة #8) | نعم | -| `check:test-masking` | ملفات الاختبار المتغيرة لا تقلل العدد الصافي للتوكيدات ولا تضيف تحصيلات حاصل من نوع `assert.ok(true)` | نعم | -| `check:pr-evidence` | يشير نص طلب السحب إلى أدلة اختبار/VPS للتغيير (يؤتمت القاعدة الصارمة #18 بالبحث في نص طلب السحب — هش، راجع قائمة الأعمال المتراكمة) | نعم | +| البرنامج النصي | ما يتحقق منه | الحظر | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----- | +| `check:pr-test-policy` | يجب أن تتضمن طلبات السحب التي تغيّر شيفرة الإنتاج في `src/` أو `open-sse/` أو `electron/` أو `bin/` اختبارات أو أن تحدّثها (القاعدة الصارمة #8) | نعم | +| `check:test-masking` | لا تقلل ملفات الاختبار المتغيرة العدد الصافي للتأكيدات ولا تضيف تحصيلات حاصلة من نوع `assert.ok(true)` | نعم | +| `check:pr-evidence` | يشير نص طلب السحب إلى أدلة الاختبار/VPS الخاصة بالتغيير (يؤتمت القاعدة الصارمة #18 عبر البحث في نص طلب السحب — هش، راجع قائمة الأعمال المؤجلة) | نعم | ### المهمة: `test-vitest` -تُشغّل بعد `build`. تمنع الدمج عند الفشل. +تعمل بعد `build`. تمنع الدمج عند الفشل. | الحزمة | ما تتحقق منه | الحظر | | ---------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | `test:vitest` | خادم MCP ‏(110 أداة)، وautoCombo، وذاكرة التخزين المؤقت — مشغّل vitest | نعم | -| `test:vitest:ui` | اختبارات مكوّنات واجهة المستخدم — مشغّل vitest | **مانع** — تُستبعد حالات الفشل الموجودة مسبقًا صراحةً في `vitest.config.ts`؛ وتتسبب حالات الفشل الجديدة في فشل المهمة | +| `test:vitest:ui` | اختبارات مكوّنات واجهة المستخدم — مشغّل vitest | **حاظر** — تُستبعد حالات الفشل الموجودة مسبقًا صراحةً في `vitest.config.ts`؛ وتؤدي حالات الفشل الجديدة إلى فشل المهمة | -### مهام سير العمل الليلية (مجدولة، استشارية) +### تدفقات العمل الليلية (مجدولة، استشارية) -تعمل وفق جدول cron (وكذلك عبر `workflow_dispatch`)، ولا تعمل مطلقًا على طلبات السحب. كلها استشارية. +تعمل هذه وفق جدول cron (وكذلك عبر `workflow_dispatch`)، ولا تعمل أبدًا على طلبات السحب. وجميعها استشارية. -| سير العمل | ما يتحقق منه | الحظر | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `nightly-property` | اختبارات الخصائص باستخدام fast-check مع بذرة عشوائية وعدد تشغيلات مرتفع | **استشاري** | -| `nightly-resilience` | بوابة نمو الكومة، وحقن الأعطال الفوضوي، واختبارات التحميل/التحمّل باستخدام k6 | **استشاري** | -| `nightly-llm-security` | حارس حقن promptfoo (وضع الحظر) + فحوصات garak (تُتخطى دون سر لمزوّد) | **استشاري** | -| `nightly-schemathesis` | اختبار عشوائي لعقد OpenAPI ‏(schemathesis) مقابل OmniRoute مباشر باستخدام `docs/openapi.yaml` — يكشف انتهاكات المواصفات / أخطاء 500 غير المعالجة (المرحلة 8 B.4) | **استشاري** | -| `nightly-mutation` | نتيجة اختبار الطفرات باستخدام Stryker على مسار اختبارات الوحدة السريع — تكشف الطفرات الباقية التوكيدات الضعيفة | **استشاري** | -| `nightly-compat` | مصفوفة توافق محرك Node عبر نطاقات `engines.node` المدعومة | **استشاري** | +| تدفق العمل | ما يتحقق منه | الحظر | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `nightly-property` | اختبارات الخصائص باستخدام fast-check مع بذرة عشوائية + عدد تشغيلات مرتفع | **استشاري** | +| `nightly-resilience` | بوابة نمو الكومة، وحقن أعطال الفوضى، واختبارات الحمل/الاستمرارية باستخدام k6 | **استشاري** | +| `nightly-llm-security` | حاجز حقن promptfoo (وضع الحظر) + فحوصات garak (تُتخطى دون سر لمزوّد الخدمة) | **استشاري** | +| `nightly-schemathesis` | اختبار عشوائي لعقد OpenAPI ‏(schemathesis) مقابل OmniRoute مباشر باستخدام `docs/openapi.yaml` — يكشف مخالفات المواصفات / أخطاء 500 غير المعالجة (المرحلة 8 B.4) | **استشاري** | +| `nightly-mutation` | درجة اختبار الطفرات باستخدام Stryker عبر مسار الوحدات السريع — تكشف الطفرات الناجية التأكيدات الضعيفة | **استشاري** | +| `nightly-compat` | مصفوفة توافق محرك Node عبر نطاقات `engines.node` المدعومة | **استشاري** | --- @@ -536,42 +535,42 @@ CodeQL: Default → Advanced. لا تضف مشغل `schedule:` من دون إج --- -## قائمة ترشيد الأعمال المتراكمة (مراجعة العائد على الاستثمار — المرحلة 9، الموجة 3) +## قائمة أعمال الترشيد المتراكمة (مراجعة العائد على الاستثمار — المرحلة 9، الموجة 3) -تمت مطابقة هذا الجرد مع `ci.yml` بتاريخ 2026-06-17 (أغفل الإصدار السابق +تمت مطابقة هذا الحصر مع `ci.yml` في 2026-06-17 (أغفل الإصدار السابق `audit:deps` و`check:tracked-artifacts` و`check:lockfile` و`check:licenses` و`check:dead-code` و`check:cognitive-complexity` و`check:type-coverage` و`check:codeql-ratchet` و`check:pr-evidence`). حدّدت مراجعة العائد على الاستثمار للمجموعة التي تمت مطابقتها -مرشحي الترشيد التاليين. **عمليات الدمج هي تغييرات ميكانيكية في CI؛ أما عمليات التفعيل/الحذف فهي قرارات تتعلق بالسياسة ومتروكة للمشغّل.** لم يُطبَّق أي مما يلي +مرشحي الترشيد الآتين. **عمليات الدمج هي تغييرات آلية في CI؛ أما تغييرات الحالة/عمليات الحذف فهي قرارات سياسات متروكة للمشغّل.** لم يُطبّق أي مما يرد أدناه حتى الآن. -**ومن الأمور غير الموثّقة أعلاه أيضًا** (استشارية، منخفضة الإشارة): مهمة `docs-lint` -(markdownlint + Vale، والمهمة بأكملها تستخدم `continue-on-error`) ومسارات عمل الفحص المستقلة +**ومن الأمور غير الموثقة أعلاه أيضًا** (استشارية، منخفضة الدلالة): مهمة `docs-lint` +(markdownlint + Vale، مع تعيين `continue-on-error` للمهمة بأكملها) ومسارات عمل الفحص المستقلة `semgrep.yml` / `codeql.yml` / `scorecard.yml`. القيمة `semgrepFindings: 0` موجودة في -`quality-baseline.json` لكنها غير موصولة بآلية تصعيد حاجبة في `ci.yml` — لذا فالمقياس -معزول حاليًا. - -### الدمج / إزالة التكرار (ميكانيكي، أقل خطورة) - -تم التحقق من كل مرشح مقابل الحالة الفعلية للبوابات بتاريخ 2026-06-17 (الثقة مع التحقق)؛ -وقد تبيّن أن عدة عمليات دمج بدت «بديهية» تخفي ديونًا، وبالتالي فهي **ليست** بدائل مباشرة سليمة. - -- **يعمل `check:docs-sync` مرتين** — مرة بصورة مستقلة في مهمة `lint` ومرة أخرى داخل `check:docs-all` (`docs-sync-strict`) وفي خطاف husky السابق للإيداع. ✅ **تم** — أزيل الاستدعاء المستقل من `lint`. -- **فحص CVE** — ❌ **ليس دمجًا مباشرًا سليمًا.** يفشل `audit:deps` فشلًا حاسمًا عند وجود أي CVE عالي/حرج؛ بينما لا يفشل `check:vuln-ratchet` (osv) إلا عند حدوث _تراجع_ مقارنة بخط الأساس (حاليًا توجد حالة واحدة MODERATE). الدلالات مختلفة — سيؤدي حذف `audit:deps` إلى فقدان البوابة المطلقة للثغرات العالية/الحرجة. أبقِ كليهما. -- **اكتشاف الدورات** — ❌ **ليس دمجًا مباشرًا سليمًا.** يُبلغ `check:circular-deps` (dpdm) عن **91 دورة** (ولهذا السبب هو استشاري)؛ ولا يمكن ترقيته إلى حاجب قبل حلها أولًا، كما أن نطاقه أوسع من `check:cycles` المنسّق والناجح. أبقِ `check:cycles` حاجبًا؛ أما حل دورات dpdm البالغ عددها 91 فهو بند مستقل في قائمة الأعمال المتراكمة. -- **التعقيد** — ✅ **تم** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): مرور واحد عبر ESLint، مع العد حسب ruleId بحيث تظل خطوط الأساس الخاصة بالتعقيد الدوري+الحد الأقصى للأسطر والتعقيد المعرفي مستقلة؛ ويظل كل من `check:complexity` و`check:cognitive-complexity` متاحًا على حدة لاستخدام `--update` محليًا. -- **مكافحة الهلوسة في `/api`** — ✅ **تم** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): جرد واحد لنظام الملفات في `src/app/api`، مع استمرار openapi-routes وdocs-symbols في إعداد تقارير مستقلة؛ وتظل الأوامر المنفردة متاحة للتشغيل المحلي. -- **يعمل `check:node-runtime` في 11 مهمة** — ⚠️ **عائد منخفض على الاستثمار.** تعمل كل مهمة على مشغّل منفصل ويستغرق الفحص أقل من ثانية واحدة؛ ويبلغ إجمالي التوفير نحو 10 ثوانٍ، مقابل فقدان أداة حماية زهيدة لكل مهمة. لا يستحق هذا الاضطراب. -- **`typecheck:noimplicit:core` في lint الخاص بـCI** — ✅ **أزيل من مهمة lint** (كان استشاريًا مع `continue-on-error`)؛ ويتكون سطح الأنواع الحاجب من `typecheck:core` + `check:type-coverage`. تم الإبقاء على السكربت المحلي. - -### التفعيل / اتخاذ القرار (سياسة المشغّل) - -- `check:openapi-security-tiers` (استشاري) — ❌ **لا يمكن تحويله إلى حاجب بصورة سليمة مباشرةً.** ينتهي برمز 0، لكنه يحذّر من أن عدة مسارات `traffic-inspector` ضمن `LOCAL_ONLY_API_PREFIXES` تفتقر إلى التعليق التوضيحي `x-loopback-only: true`. يتطلب فرضه إضافة تلك التعليقات التوضيحية إلى `openapi.yaml` أولًا. -- `typecheck:noimplicit:core` (استشاري) — تستوعبه إلى حد كبير آلية التصعيد الحاجبة `check:type-coverage`. حوّله إلى آلية تصعيد أو احذف مرور `tsc` الثاني المتكرر. -- `test:vitest:ui` (أصبح الآن **حاجبًا**) — تُستبعد حالات الفشل الموجودة مسبقًا صراحةً في `vitest.config.ts` باستخدام تعليقات التتبع `// #8618`؛ أما حالات الفشل الجديدة فتُفشل المهمة. -- `check:secrets` (gitleaks، آلية تصعيد حاجبة مجمّدة عند 3 نتائج إيجابية كاذبة موثّقة) — أضف الحالات الثلاث إلى قائمة السماح للوصول إلى 0، أو اخفضها إلى استشارية. تتداخل مع الفحص الأصلي للأسرار في GitHub ومع `check:public-creds`. -- `check:pr-evidence` (حاجب، يبحث في النص النثري لنص PR) — خطر مرتفع للنتائج الإيجابية الكاذبة؛ وسيؤدي حذفه إلى إضعاف تطبيق القاعدة الصارمة رقم 18، لذا فهذا قرار حقيقي يتعلق بالسياسة. -- `semgrep` (مسار مستقل استشاري) — يتداخل مع CodeQL بالنسبة إلى عائلات OWASP؛ اربط خط أساسه بآلية تصعيد أو احذفه. +`quality-baseline.json` لكنها غير موصولة بآلية سقاطة مانعة في `ci.yml` — وهذا المقياس +يتيم حاليًا. + +### الدمج / إزالة التكرار (آلي، أقل مخاطرة) + +تم التحقق من كل مرشح مقابل الحالة الفعلية للبوابات في 2026-06-17 (الثقة مع التحقق)؛ +وتبيّن أن عدة عمليات دمج «بديهية» تخفي ديونًا، ولذلك فهي **ليست** بدائل مباشرة سليمة. + +- **يُشغَّل `check:docs-sync` مرتين** — بصورة مستقلة في مهمة `lint`، ومرة أخرى داخل `check:docs-all` (`docs-sync-strict`) وفي خطاف husky السابق للالتزام. ✅ **تم** — أزيل الاستدعاء المستقل من `lint`. +- **فحص CVE** — ❌ **ليس دمجًا سليمًا مباشرًا.** يفشل `audit:deps` فشلًا قاطعًا عند وجود أي ثغرة CVE عالية/حرجة؛ بينما لا يفشل `check:vuln-ratchet` (osv) إلا عند حدوث _تراجع_ مقارنة بخط الأساس (حاليًا 1 MODERATE). الدلالات مختلفة — سيؤدي حذف `audit:deps` إلى فقدان البوابة المطلقة للثغرات العالية/الحرجة. أبقِ كليهما. +- **اكتشاف الدورات** — ✅ **تم** (#15159 G-01/G-02). وصف النص القديم هنا `check:cycles` بأنه البوابة «الخضراء والمنتقاة» وبرّر إبقاءها مانعة لأن `check:circular-deps` (dpdm) أبلغ عن 91 دورة. كان ذلك اللون الأخضر **نجاحًا زائفًا**: كان `check:cycles` يفحص 5 أدلة فرعية (450 ملفًا)، ولا يطابق سوى `import|export … from` الساكنة، ويتجاهل كل محددات `@/` و`@omniroute/open-sse/`، ولذلك لم يكن يستطيع رؤية دورات الاستيراد الديناميكي + الأسماء المستعارة التي كانت سائدة في المستودع. تم الإصلاح: تجتاز البوابة الآن `src` + `open-sse` (5023 ملفًا)، وتجمع المحددات من TypeScript AST (وبالتالي يُحتسب `import("…")`، بينما لا يُحتسب `typeof import("…")` في موضع النوع)، وتحل `paths` في tsconfig. وهي تعثر على **14** دورة، لا 0. ولأن إصلاح 14 دورة موجودة مسبقًا غير ممكن في طلب سحب خاص بالبوابة، أصبح `check:cycles` الآن **سقاطة** (`--ratchet`، بسقف `metrics.cycles.value = 14` في `quality-baseline.json`، و`direction: down`) — فهي تمنع أي _تراجع_، ولا يمكن للعدد إلا أن ينخفض. يشغّل CI الأمر `npm run check:cycles:ratchet`. تتم معالجة الخفض التدريجي ضمن **A-01**. يبقى `check:circular-deps` (dpdm) استشاريًا بوصفه رأيًا ثانيًا أوسع نطاقًا. +- **التعقيد** — ✅ **تم** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): اجتياز واحد بواسطة ESLint، مع العد حسب ruleId بحيث تظل خطوط الأساس للتعقيد الدوري+الحد الأقصى للأسطر وللتعقيد المعرفي مستقلة؛ ويظل كل من `check:complexity` / `check:cognitive-complexity` متاحًا للاستخدام المحلي مع `--update`. +- **مكافحة الهلوسة في `/api`** — ✅ **تم** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): حصر واحد لنظام الملفات في `src/app/api`، مع استمرار openapi-routes + docs-symbols في إعداد تقارير مستقلة؛ وتظل الفحوص الفردية متاحة للتشغيل المحلي. +- **يُشغَّل `check:node-runtime` في 11 مهمة** — ⚠️ **عائد منخفض على الاستثمار.** تستخدم كل مهمة مشغّلًا منفصلًا، ويستغرق الفحص أقل من ثانية واحدة؛ الوفر الإجمالي نحو 10 ثوانٍ، مقابل فقدان إجراء حماية زهيد لكل مهمة. لا يستحق عناء التغيير. +- **`typecheck:noimplicit:core` ضمن lint في CI** — ✅ **أزيل من مهمة lint** (كان استشاريًا مع `continue-on-error`)؛ سطح الأنواع المانع هو `typecheck:core` + `check:type-coverage`. تم الاحتفاظ بالبرنامج النصي المحلي. + +### تغيير الحالة / اتخاذ القرار (سياسة المشغّل) + +- `check:openapi-security-tiers` (استشاري) — ❌ **لا يمكن تحويله إلى مانع بصورة سليمة مباشرةً.** ينتهي بالرمز 0، لكنه يحذر من أن عدة مسارات `traffic-inspector` ضمن `LOCAL_ONLY_API_PREFIXES` تفتقر إلى التعليق التوضيحي `x-loopback-only: true`. يتطلب فرضه إضافة تلك التعليقات التوضيحية إلى `openapi.yaml` أولًا. +- `typecheck:noimplicit:core` (استشاري) — تغطيه إلى حد كبير سقاطة `check:type-coverage` المانعة. حوّله إلى سقاطة أو احذف مرور `tsc` الثاني المتكرر. +- `test:vitest:ui` (أصبح الآن **مانعًا**) — حالات الفشل الموجودة مسبقًا مستثناة صراحةً في `vitest.config.ts` مع تعليقات التتبع `// #8618`؛ وتؤدي حالات الفشل الجديدة إلى فشل المهمة. +- `check:secrets` (gitleaks، سقاطة مانعة مجمّدة عند 3 نتائج إيجابية زائفة موثقة) — أضف الحالات الثلاث إلى قائمة السماح للوصول إلى 0، أو اخفضه إلى استشاري. يتداخل مع فحص الأسرار الأصلي في GitHub ومع `check:public-creds`. +- `check:pr-evidence` (مانع، يبحث في نثر متن طلب السحب باستخدام grep) — ينطوي على خطر مرتفع للنتائج الإيجابية الزائفة؛ وسيؤدي حذفه إلى إضعاف فرض القاعدة الصارمة رقم 18، لذا فهذا قرار سياسات حقيقي. +- `semgrep` (مستقل واستشاري) — يتداخل مع CodeQL بالنسبة إلى عائلات OWASP؛ صِل خط أساسه بسقاطة أو احذفه. --- diff --git a/docs/i18n/az/CONTRIBUTING.md b/docs/i18n/az/CONTRIBUTING.md index 5a9d415681b..c6d99795c53 100644 --- a/docs/i18n/az/CONTRIBUTING.md +++ b/docs/i18n/az/CONTRIBUTING.md @@ -391,18 +391,18 @@ Model təriflərini `open-sse/config/providerRegistry.ts` faylına əlavə edin. - [ ] Testlər uğurla keçir (`npm test`) - [ ] Lint yoxlaması uğurla keçir (`npm run lint`) -- [ ] Yığma uğurla tamamlanır (`npm run build`) +- [ ] Build uğurla tamamlanır (`npm run build`) - [ ] Yeni ictimai funksiyalar və interfeyslər üçün TypeScript tipləri əlavə edilib - [ ] Sərt kodlaşdırılmış məxfi məlumatlar və ya ehtiyat dəyərlər yoxdur - [ ] İctimai upstream giriş məlumatları literal kimi deyil, `resolvePublicCred()` vasitəsilə daxil edilib (bax: [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) -- [ ] Xəta cavabları `buildErrorBody()` / `sanitizeErrorMessage()` vasitəsilə yönləndirilir — cavab gövdələrində emal edilməmiş stek izləri yoxdur (bax: [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell əmrləri (`exec` / `spawn`) icra vaxtı dəyərlərini sətir interpolyasiyası ilə deyil, `env` vasitəsilə ötürür -- [ ] Bütün giriş məlumatları Zod sxemləri ilə doğrulanıb -- [ ] İstifadəçiyə təsir edən dəyişikliklər üçün `changelog.d/{features|fixes|maintenance}/-.md` altında dəyişiklik jurnalı **fraqmenti** əlavə edilib (bax: [`changelog.d/README.md`](./changelog.d/README.md)) — `CHANGELOG.md` faylını birbaşa redaktə **etməyin**; fraqmentlər buraxılış zamanı birləşdirilir və PR-lar arasında heç vaxt ziddiyyət yaratmır +- [ ] Xəta cavabları `buildErrorBody()` / `sanitizeErrorMessage()` vasitəsilə yönləndirilir — cavab gövdələrində emal edilməmiş stack trace-lər yoxdur (bax: [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell komandaları (`exec` / `spawn`) icra vaxtı dəyərlərini sətir interpolasiyası ilə deyil, `env` vasitəsilə ötürür +- [ ] Bütün girişlər Zod sxemləri ilə yoxlanılır +- [ ] İstifadəçiyə təsir edən dəyişikliklər üçün `changelog.d/{features|fixes|maintenance}/-.md` altında dəyişiklik jurnalının **fraqmenti** əlavə edilib (bax: [`changelog.d/README.md`](./changelog.d/README.md)) — `CHANGELOG.md` faylını birbaşa redaktə **etməyin**; fraqmentlər buraxılış zamanı birləşdirilir və PR-lər arasında heç vaxt ziddiyyət yaratmır - [ ] Sənədləşmə yenilənib (tətbiq olunduğu halda) - [ ] Yeni CodeQL / Secret-Scanning xəbərdarlıqları açılmayıb və ya hər biri müvafiq `docs/security/` sənədinə istinad edən texniki əsaslandırma ilə rədd edilib -- [ ] Alt proseslər yaradan marşrutlar (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` daxilində `isLocalOnlyPath()` kimi təsnif edilib — bax: [Sərt Qayda #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Commit mesajlarında `Co-Authored-By` treylerləri yoxdur — commitlər yalnız repozitoriya sahibinin Git identifikasiyası altında görünməlidir (Sərt Qayda #16) +- [ ] Alt proseslər yaradan marşrutlar (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` faylında `isLocalOnlyPath()` kimi təsnif edilib — bax: [Sərt Qayda #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Commit mesajlarında AI/bot `Co-authored-by` treylerləri yoxdur (Sərt Qayda #16) — işindən yenidən istifadə edilən insan əməkdaşlara standart `Co-authored-by: Name ` treylerləri ilə istinad edilir --- diff --git a/docs/i18n/az/docs/architecture/QUALITY_GATES.md b/docs/i18n/az/docs/architecture/QUALITY_GATES.md index 09b9c08c1da..3102953c0f2 100644 --- a/docs/i18n/az/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/az/docs/architecture/QUALITY_GATES.md @@ -12,274 +12,271 @@ Qısa xülasə və icazə siyahısı siyasəti üçün `AGENTS.md` faylındakı --- -## Qeydlərin inventarı və icra profilləri +## Qeyt inventarı və icra profilləri -### Namizədlərin qəbulu +### Namizədin qəbulu -CI və Quality Gates iş axınlarının hər biri sabit hökm yaradır: `Gate / CI` və -`Gate / Quality`. Onların versiyalaşdırılmış qəbul siyasəti hər bir yuxarı axın tapşırığını -məcburi və ya tövsiyə xarakterli olaraq siyahıya alır. Tətbiq olunan məcburi tapşırıq uğurla -başa çatmalıdır: mövcud olmayan, ləğv edilmiş, ötürülmüş, gözləmədə olan və naməlum nəticələr +CI və Quality Gates iş axınlarının hər biri sabit nəticə yaradır: `Gate / CI` və +`Gate / Quality`. Onların versiyalaşdırılmış qəbul siyasəti bütün yuxarı axın tapşırıqlarını +məcburi və ya tövsiyə xarakterli kimi sadalayır. Tətbiq olunan məcburi tapşırıq uğurla +tamamlanmalıdır: mövcud olmayan, ləğv edilmiş, ötürülmüş, gözləmədə olan və naməlum nəticələr PASS statusunu təsdiqləyə bilməz. Yalnız sənədlərə və ya yalnız kataloqa aid etibarlı təsnifat -kod xəttini tətbiqedilməz edə bilər; qaralama PR qəbul edilmiş namizəd deyil. `hotfix` etiketi -sübut tələbini aradan qaldırmır. - -Hər iki iş axını PR-ləri və əsas/buraxılış budaqlarına göndərişləri, əl ilə işə salmanı və -birləşdirmə qrupu hadisələrini əhatə edir. Göndəriş, əl ilə işə salma və birləşdirmə qrupu tam -seçimi icra edir. Fork-lar və birləşdirmə qrupları, əks halda öz serverində yerləşdirilən -icraçıları seçəcək tapşırıqlar üçün platformada yerləşdirilən icraçılardan istifadə edir; -tətbiqdən əvvəl kifayət qədər platforma tutumu yoxlanmalıdır. - -Hər JSON qəbzi seçilmiş SHA-nı, iş axını icrasını və cəhdi müəyyənləşdirir. -CLI seçilmiş versiya ilə hadisənin SHA-sı arasındakı uyğunsuzluğu rədd edir. İş axını testləri -siyasət üzvlüyünü hökm tapşırığının `needs` siyahısına bağlayır ki, yeni və ya silinmiş xətt -səssizcə yoxa çıxmasın. Qəbzlər yalnız öz iş axınlarını əhatə edir; nəşri, yerləşdirməni və ya -mövcud tövsiyə xarakterli skanerin daxili mexanizmlərini əhatə etmir. Budaq qaydalarında hər -iki yoxlama adının aktivləşdirilməsi ayrıca inzibati dəyişiklikdir; bu tapşırıqların əlavə -edilməsi öz-özlüyündə budağı qorumur. +kod zolağını tətbiqedilməz edə bilər; qaralama PR qəbul edilmiş namizəd deyil. `hotfix` +etiketi sübut tələbini aradan qaldırmır. + +Hər iki iş axını PR-ləri və main/release budaqlarına göndərişləri, əl ilə başladılmanı və +birləşdirmə qrupu hadisələrini əhatə edir. Göndəriş, başladılma və birləşdirmə qrupu tam +seçimi işlədir. Fork-lar və birləşdirmə qrupları, əks halda öz serverində yerləşdirilən +icraçıları seçəcək tapşırıqlar üçün hostinq olunan icraçılardan istifadə edir; tətbiqdən +əvvəl kifayət qədər hostinq tutumu yoxlanılmalıdır. + +Hər bir JSON qəbzi checkout edilmiş SHA-nı, iş axını icrasını və cəhdi müəyyən edir. +CLI checkout/hadisə SHA uyğunsuzluğunu rədd edir. İş axını testləri siyasət üzvlüyünü +nəticə tapşırığının `needs` siyahısına bağlayır ki, yeni və ya silinmiş zolaq səssizcə +yoxa çıxmasın. Qəbzlər nəşri, yerləşdirməni və ya mövcud tövsiyə xarakterli skanerin +daxili işini deyil, öz iş axınlarını əhatə edir. Budaq qaydalarında hər iki yoxlama adının +aktivləşdirilməsi ayrıca inzibati dəyişiklikdir; bu tapşırıqların əlavə edilməsi öz-özlüyündə +budağı qorumur. ### Statik skan inventarı Versiyalaşdırılmış npm-alias inventarı və statik skan üzvlüyü `config/quality/gate-manifest.json` daxilində yerləşir. Skript adlarını və dəqiq əmrləri -`package.json` ilə müqayisə edərək yoxlamaq üçün `npm run check:gate-manifest` əmrini icra edin; -əlavələr, silinmələr və əmr dəyişiklikləri həm lokal hook-un, həm də CI-dakı dəyişiklik -təsnifatı tapşırıqlarının uğursuz olmasına səbəb olur. Alias iş axını tapşırığı, matris -instansiyası və ya test nümunəsi deyil: bu saylar bir-birini əvəz edə bilən göstəricilər kimi -təqdim edilməməlidir. - -Seçilmiş alias-ları icra etmədən nəzərdən keçirmək üçün -`npm run quality:scan -- --list` və ya `npm run quality:scan:fast -- --list` -əmrindən istifadə edin. İcraçı npm giriş nöqtəsini çağırır, buna görə də onun icra mühiti -(konfiqurasiya edildiyi hallarda Bun daxil olmaqla) qorunur. Manifest həmin profillərdən -kənardakı alias-ları ayrıca çağırılanlar kimi qeydə alır və yalnız oxuma üçün nəzərdə tutulan -skan profillərində texniki xidmət əmrləri qadağandır. +`package.json` ilə müqayisədə doğrulamaq üçün `npm run check:gate-manifest` əmrini icra edin; +əlavələr, silinmələr və əmr dəyişiklikləri həm lokal hook-u, həm də CI daxilindəki +dəyişiklik təsnifatı tapşırıqlarını uğursuz edir. Alias iş axını tapşırığı, matris instansiyası +və ya test nümunəsi deyil: bu saylar bir-birini əvəz edə bilən kimi təqdim edilməməlidir. + +Seçilmiş alias-ları icra etmədən yoxlamaq üçün `npm run quality:scan -- --list` və ya +`npm run quality:scan:fast -- --list` istifadə edin. İcraçı npm giriş nöqtəsini çağırır, +buna görə onun icra mühiti (konfiqurasiya edildiyi hallarda Bun daxil olmaqla) qorunur. +Manifest həmin profillərdən kənardakı alias-ları ayrıca çağırılan kimi qeyd edir və +yalnız oxuma üçün nəzərdə tutulmuş skan profillərində texniki xidmət əmrləri qadağandır. Bu profillər yalnız statik skanı əhatə edir. Onlar məhsul testlərini, əhatə dairəsini, -paketləməni, xarici yoxlamaları və ya namizədin buraxılış üçün tam qəbulunu təsdiqləmir. -İş axınına qəbul əlaqəli `config/quality/admission-policy.json` və +paketləməni, xarici yoxlamaları və ya namizədin tam buraxılış qəbulunu təsdiqləmir. +İş axını qəbulu əlaqələndirilmiş `config/quality/admission-policy.json` və `scripts/quality/admission-verdict.mjs` fayllarından istifadə edir. Buraxılış müşahidəçisi -profilləri ayrı qalır; onların tətbiq olunan yoxlamalarını və qəbzlərini müstəqil şəkildə -nəzərdən keçirin. Aşağıdakı mətn inventarı istinad üçündür və qeydin həqiqətən icra olunduğuna -dəlil deyil. +profilləri ayrıca qalır; onların tətbiq olunan yoxlamalarını və qəbzlərini müstəqil şəkildə +yoxlayın. Aşağıdakı mətn inventarı istinad üçündür, qeytin həqiqətən işə salındığının +sübutu deyil. -Skriptlər `scripts/check/` (siyasət qeydləri) və `scripts/quality/` (ratchet mühərriki) +Skriptlər `scripts/check/` (siyasət qeytləri) və `scripts/quality/` (ratchet mühərriki) altında yerləşir. CI üçün əsas həqiqət mənbəyi `.github/workflows/ci.yml` faylıdır. ### Buraxılış PR-i üçün sürətli yol (`quality.yml`) -`.github/workflows/quality.yml` əsas/buraxılış PR-lərində, qorunan budaqlara göndərişlərdə, -əl ilə işə salmada və birləşdirmə qruplarında CI-ı tamamlayır. PR-lər yol üzrə filtrlənmiş -sürətli yoxlamalardan istifadə edir. Daimi olaraq deaktiv edilmiş dublikat yığım silinib; -real yığım/paketləmə/işə salma yoxlamaları CI-da qalır. - -| Tapşırıq | Əhatə dairəsi | Bloklayıcı | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `Docs Gates (fast-path)` | Sənəd/kod PR-ləri; API sənəd istinadları və bütün sənədlər | Bəli | -| `Fast Quality Gates` | Kod PR-ləri; statik yoxlamalar, tip yoxlaması, idarə panelinin tip yoxlaması, təsirə məruz qalan modul testləri | Bəli | -| `Forgotten sibling tests` | Kod PR-ləri; dəyişdirilmiş modulların statik istehlakçılara və ehtimal olunan qonşu testlərə qədər izlənməsi; barrel və dinamik import yolları, istinad edilən icazə siyahısı istisnaları ilə birlikdə tövsiyə xarakterli diaqnostika kimi bildirilir | **Tövsiyə xarakterli** | -| `Vitest (fast-path)` | Kod PR-ləri; sürətli vitest dəsti | Bəli | -| `Unit Tests fast-path` | Kod PR-ləri; 4 hissəli modul test dəsti | Bəli | -| `No new ESLint warnings` | Kod PR-ləri; susdurmaları nəzərə alan lint qoruyucusu | Bəli, fork-lar daxil olmaqla | -| `Merge integrity (changelog + generated skills)` | Qaralama olmayan PR-lər; dəyişiklik jurnalı və yaradılmış bacarıqların sinxronlaşdırılması | Bəli, fork-lar daxil olmaqla | - -#### Unudulmuş qonşu testlər hesabatı - -`npm run check:forgotten-sibling-tests` test təsiri xəritəsinin əsasındakı import -həlledicisindən təkrar istifadə edir. Dəyişdirilmiş hər bir istehsal modulu üçün, ehtimal -olunan test pull-request fərqində olmadıqda, deterministik -`dəyişdirilmiş modul/simvol -> statik istehlakçı -> ehtimal olunan qonşu test` zəncirlərini -bildirir. Markdown xülasəsi və JSON nəticəsi hər hansı bloklayıcı tətbiqdən əvvəl -kalibrləmə üçün `forgotten-sibling-tests` iş axını artefaktı kimi saxlanılır. - -Barrel təkrar ixracları və dinamik importlar yalnız həll diaqnostikası üçündür; onlar heç vaxt -bloklayıcı tapıntı yaratmır. Nəzərdən keçirilmiş istisnalar -`config/quality/forgotten-sibling-allowlist.json` faylında saxlanılır. Hər bir qeyd istehlakçı və namizəd +`.github/workflows/quality.yml` main/release PR-lərində, qorunan budaqlara göndərişlərdə, +əl ilə başladılmada və birləşdirmə qruplarında CI-ni tamamlayır. PR-lər yol üzrə filtrlənmiş +sürətli yoxlamalardan istifadə edir. Daimi olaraq deaktiv edilmiş dublikat qurma prosesi +silinib; həqiqi qurma/paketləmə/işəsalma yoxlamaları CI daxilində qalır. + +| Tapşırıq | Əhatə dairəsi | Bloklayıcı | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `Docs Gates (fast-path)` | Sənəd/kod PR-ləri; API sənəd istinadları və bütün sənədlər | Bəli | +| `Fast Quality Gates` | Kod PR-ləri; statik yoxlamalar, tip yoxlaması, idarə panelinin tip yoxlaması, təsirlənmiş vahid testləri | Bəli | +| `Forgotten sibling tests` | Kod PR-ləri; dəyişdirilmiş modulların statik istehlakçılara və namizəd qardaş testlərə qədər izlənməsi; barrel və dinamik idxal yolları, istinad edilən icazə siyahısı istisnaları ilə birlikdə, tövsiyə xarakterli diaqnostika kimi bildirilir | **Tövsiyə xarakterli** | +| `Vitest (fast-path)` | Kod PR-ləri; sürətli vitest dəsti | Bəli | +| `Unit Tests fast-path` | Kod PR-ləri; 4 hissəli vahid test dəsti | Bəli | +| `No new ESLint warnings` | Kod PR-ləri; susdurmaları nəzərə alan lint qoruyucusu | Bəli, fork-lar daxil olmaqla | +| `Merge integrity (changelog + generated skills)` | Qaralama olmayan PR-lər; dəyişiklik jurnalı və yaradılmış bacarıqların sinxronlaşdırılması | Bəli, fork-lar daxil olmaqla | + +#### Unudulmuş qardaş testlər hesabatı + +`npm run check:forgotten-sibling-tests` test təsiri xəritəsinin arxasındakı idxal həlledicisindən +təkrar istifadə edir. Hər bir dəyişdirilmiş istehsal modulu üçün namizəd test pull request +fərqində olmadıqda deterministik +`dəyişdirilmiş modul/simvol -> statik istehlakçı -> namizəd qardaş test` zəncirlərini bildirir. +Markdown xülasəsi və JSON nəticəsi hər hansı bloklayıcı tətbiqdən əvvəl kalibrləmə üçün +`forgotten-sibling-tests` iş axını artefaktı kimi saxlanılır. + +Barrel təkrar ixracları və dinamik importlar yalnız həll etmə diaqnostikasıdır; onlar heç vaxt +bloklayıcı aşkarlama yaratmır. Nəzərdən keçirilmiş istisnalar +`config/quality/forgotten-sibling-allowlist.json` faylında saxlanılır. Hər qeyd istehlakçı və namizəd testi göstərməli, konkret əsaslandırma təqdim etməli və GitHub məsələsinə və ya pull request-ə keçid verməlidir. Səhv formatlanmış qeydlər -qapalı rejimdə uğursuz olur. İstisnalar silinmiş namizəd testi və ya `.skip`/`.todo` əlavə edən diff-i gizlədə bilməz; -assertion-ların zəiflədilməsi və digər maskalama halları ayrıca bloklayıcı olan -`check:test-masking` keçidinin məsuliyyətində qalır. +təhlükəsiz şəkildə rədd edilir. İstisnalar silinmiş namizəd testi və ya `.skip`/`.todo` əlavə edən diff-i gözardı edə bilməz; +assertion-ların zəiflədilməsi və digər maskalama halları müstəqil şəkildə bloklayan +`check:test-masking` keçidinin nəzarətində qalır. ### Tapşırıq: `lint` -`main` budağına göndərilən hər PR üçün icra olunur. Uğursuz olduqda birləşdirməni bloklayır. - -| Skript (`npm run ...`) | Yoxlayır | Bloklayıcı | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -| `check:node-runtime` | Node.js versiyasının dəstəklənən diapazonda olmasını | Bəli | -| `check:cycles` | Dövri importları — bütün `src/` + `open-sse/` modullarında | Bəli | -| `check:route-validation:t06` | Zod sxemlərinin bütün marşrutlarda mövcud olmasını (Tier 6 siyasəti) | Bəli | -| `check:any-budget:t11` | `@ts-expect-error // any` sayının büdcəni aşmamasını (Tier 11 catraca) | Bəli | -| `check:provider-consistency` | `providers.ts` daxilindəki hər bir provayderin `providerRegistry.ts` daxilində uyğun qeydi var (və əksinə, icazə verilənlər siyahısı çərçivəsində) | Bəli | -| `check:model-lifecycle` | Əl ilə saxlanılan üç marşrutlaşdırma cədvəli repozitoriyada qeydə alınmış həyat dövrü ani görüntüsü (#11503) ilə uyğun qalır: `FITNESS_TABLE` (`taskFitness.ts`) `REGISTRY` tərəfindən marşrutlaşdırıla bilən istifadədən çıxarılmış heç bir identifikatoru qiymətləndirmir; hər bir `BUILT_IN_ALIASES` hədəfi `REGISTRY` daxilində mövcuddur və istifadədən çıxarılmış identifikatorların ani görüntüsündə yoxdur; `REGISTRY` daxilində hələ də mövcud olan hər bir istifadədən çıxarılmış identifikator yönləndirilir və ya `allowedRetiredInCatalog` daxilində siyahıya alınır; və heç bir `DEFAULT_DEGRADATION_MAP` mənbəyi və ya hədəfi həmin ani görüntüdə istifadədən çıxarılmış kimi görünmür. Bu, modelin hazırda aktiv yuxarı axın xidməti tərəfindən təqdim edildiyini sübut etmir. Oflayn — əl ilə `npm run quality:refresh-model-lifecycle` vasitəsilə yenilənən `config/quality/model-lifecycle.json` ilə müqayisə edir (şəbəkə tələb olunur; CI-a qoşulmayıb). `allowedRetiredInCatalog` tədricən azaldılmalı olan siyahıdır: yalnız izləmə məsələsi olduqda qeyd əlavə edin. | Bəli | -| `check:fetch-targets` | Müştəri tərəfindəki `src/` daxilində olan hər bir `fetch("/api/...")` real `route.ts` faylına yönəlir | Bəli | -| `check:deps` | Repozitoriyadakı hər bir `package.json` faylında olan və `npm install` ilə quraşdırıla bilən bütün asılılıqlar `dependency-allowlist.json` daxilindədir; yeni versiyası sabitlənməmiş və ya slopsquatting hücumuna məruz qala bilən paketlər işarələnir | Bəli | -| `audit:deps` | `npm audit` (kök + electron) — yüksək/kritik səviyyəli xəbərdarlıqlar yoxdur (osv `check:vuln-ratchet` ilə üst-üstə düşür; Rasionallaşdırma üzrə görüləcək işlər siyahısına baxın) | Bəli | -| `check:lockfile` | `package-lock.json` bütövlüyü — https reyestri, bütövlük heşləri, host əvəzləmələri yoxdur | Bəli | -| `check:licenses` | İstehsal asılılıqları üçün SPDX lisenziyalarının icazə siyahısı | Bəli | -| `check:tracked-artifacts` | Build artefaktları / repozitoriyaya daxil edilmiş `node_modules` simvolik keçidləri yoxdur (həmçinin husky pre-commit zamanı işə salınır; pre-push qəsdən yüngüldür — #6716) | Bəli | -| `check:ai-attribution` | PR commit-lərində, başlığında və ya mətnində AI/bot `Co-Authored-By` sonluğu və ya AI tərəfindən generasiya edildiyini bildirən altbilgi yoxdur — Sərt Qayda #16 (`quality.yml` faylındakı PR→`release/**` üçün fast-gates dövründə — hadisə yükünü oxuyur, PR olmadığı halda heç bir əməliyyat aparmır — və `ci.yml` lint yoxlamasında PR→`main` üçün yalnız PR-a aid addım; həmçinin husky `commit-msg` hook-u; insan həmmüəlliflərə icazə verilir; #14436) | -| `check:vitest-exclusions` | Hər bir Vitest istisnası izləmə məsələsini göstərir və `config/quality/vitest-exclusions.json` faylında yer alır (#13204) | Bəli | -| `check:file-size` | Heç bir mənbə faylı genişlənmə üzrə limiti aşmır (ratchet: böyük fayllar `frozen` siyahısında dondurulub) | Bəli | -| `check:error-helper` | İcraedicilərdə/işləyicilərdə xəta cavabları `buildErrorBody()` / `sanitizeErrorMessage()` funksiyalarından istifadə edir (Sərt Qayda #12) | Bəli | -| `check:migration-numbering` | Miqrasiya SQL faylları ardıcıl nömrələnib, boşluqlar və ya təkrarlar yoxdur | Bəli | -| `check:public-creds` | `publicCreds.ts` xaricində heç bir literal OAuth `client_id`/`client_secret` və ya Firebase Web açarı yoxdur (Sərt Qayda #11) | Bəli | -| `check:db-rules` | `src/lib/db/` modullarından kənarda xam SQL yoxdur; `localDb.ts` faylından barrel-importlar yoxdur (Sərt Qaydalar #2/#5) | Bəli | -| `check:known-symbols` | Dispetçer cədvəllərində qeydiyyata alınmış provayder icraçıları, marşrutlaşdırma strategiyaları və tərcüməçilər diskdəki fayllarla uyğun gəlir — sahibsiz və ya elan edilməmiş simvollar yoxdur | Bəli | -| `check:route-guard-membership` | Alt proses yaradan hər bir marşrut `isLocalOnlyPath()` tərəfindən təsnif edilir (Sərt Qaydalar #15/#17) | Bəli | -| `check:test-discovery` | Repozitoriyadakı hər bir `*.test.ts` / `*.spec.ts` faylı ən azı bir test icraçısı tərəfindən aşkarlanır (xırxıra mexanizmi: `test-discovery-baseline.json` faylındakı sahibsiz fayllar siyahısı yalnız kiçilə bilər) | Bəli | -| `check:agent-skills-sync` | Yaradılmış agent-skills artefaktları mənbə kataloqu ilə uyğun gəlir (fərqlənmə yoxdur) | -| `check:provider-asset-provenance` | Provayder loqoları/aktivləri qeydə alınmış mənşə qeydini ehtiva edir | -| `lint:json` | JSON konfiqurasiya faylları parsinq olunur və repozitoriyanın lint qaydalarına cavab verir | -| `typecheck:core` | TypeScript kompilyasiyası xətasız tamamlanır (yalnız tövsiyə xarakterli xəbərdarlıqlar) | Bəli | -| `typecheck:noimplicit:core` | Sərt `noImplicitAny` — gələcəyə yönəlikdir; əvvəlcədən mövcud olan bir çox çağırış nöqtəsi hələ də annotasiyalara ehtiyac duyur | **Tövsiyə xarakterli** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` ilə məhdudlaşdırılmış `tsc` (#7033) — `typecheck:core` üçün hazırlanmış 27 fayllıq icazə siyahısına heç bir dashboard TSX faylı daxil deyil və `next build` də onları heç vaxt tip yoxlamasından keçirmir (`next.config.mjs` faylında `ignoreBuildErrors: true` təyin olunub), buna görə də oradakı sahibsiz identifikator reqressiyaları (#6625/#6909) CI üçün görünməz idi. Dondurulmuş fayl üzrə/TS kodu üzrə say bazası (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ilə eyni köhnəlmə yoxlaması modeli) ilə fərqləri müqayisə edir — yalnız baza sayından artıq YENİ xətalar keçidin uğursuz olmasına səbəb olur; əvvəlcədən mövcud olan xəta düzəldildikdə `--update` ilə baza sayını azaldın. | Bəli | +`main` budağına edilən hər PR üçün işə salınır. Uğursuz olduqda birləşdirməni bloklayır. + +| Skript (`npm run ...`) | Yoxlayır | Bloklayıcı | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| `check:node-runtime` | Node.js versiyasının dəstəklənən diapazonda olub-olmadığını | Bəli | +| `check:cycles` | Bütün `src/` + `open-sse/` üzrə dövri importları (AST əsaslıdır, tsconfig `paths` həll edilir). Sadə rejim = məsləhət xarakterlidir, dövrləri sadalayır. `check:cycles:ratchet` (CI-nin işə saldığı) say `quality-baseline.json` faylındakı `metrics.cycles` həddini aşdıqda bloklayır — hazırda 14, `direction: down`, buna görə də yalnız azala bilər (#15159 G-01/G-02) | Bəli (ratchet) | +| `check:route-validation:t06` | Zod sxemlərinin bütün marşrutlarda mövcudluğunu (Tier 6 siyasəti) | Bəli | +| `check:any-budget:t11` | `@ts-expect-error // any` sayının büdcəni aşmamasını (Tier 11 ratchet-i) | Bəli | +| `check:provider-consistency` | `providers.ts` faylındakı hər bir provayderin `providerRegistry.ts` faylında uyğun qeydi var (və əksinə, icazə siyahısı daxilində) | Bəli | +| `check:model-lifecycle` | Əl ilə idarə olunan üç marşrutlaşdırma cədvəli repozitoriyaya daxil edilmiş həyat dövrü anlıq görüntüsü (#11503) ilə uyğun qalır: `FITNESS_TABLE` (`taskFitness.ts`) `REGISTRY` tərəfindən marşrutlaşdırıla bilən heç bir istifadədən çıxarılmış id-ni qiymətləndirmir; hər `BUILT_IN_ALIASES` hədəfi `REGISTRY` daxilində mövcuddur və istifadədən çıxarılmış id-lərin anlıq görüntüsündə yoxdur; `REGISTRY` daxilində hələ də qalan hər istifadədən çıxarılmış id yönləndirilir və ya `allowedRetiredInCatalog` siyahısında göstərilir; həmçinin heç bir `DEFAULT_DEGRADATION_MAP` mənbəyi və ya hədəfi həmin anlıq görüntüdə istifadədən çıxarılmış kimi göstərilmir. Bu, modelin hazırda aktiv yuxarı axın xidməti tərəfindən təqdim olunduğunu sübut etmir. Oflayn — əl ilə `npm run quality:refresh-model-lifecycle` vasitəsilə yenilənən `config/quality/model-lifecycle.json` ilə müqayisə edir (şəbəkə tələb olunur; CI sisteminə qoşulmayıb). `allowedRetiredInCatalog` tədricən azaldılan məhdudlaşdırıcı siyahıdır: qeydi yalnız izləmə məsələsi ilə birlikdə əlavə edin. | Bəli | +| `check:fetch-targets` | Müştəri tərəfindəki `src/` daxilində hər `fetch("/api/...")` real `route.ts` faylına yönəlir | Bəli | +| `check:deps` | Repozitoriyadakı hər `package.json` faylında `npm install` vasitəsilə quraşdırıla bilən bütün asılılıqlar `dependency-allowlist.json` daxilindədir; versiyası sabitlənməmiş və ya slopsquatting riski daşıyan yeni paketlər işarələnir | Bəli | +| `audit:deps` | `npm audit` (kök + electron) — yüksək/kritik səviyyəli xəbərdarlıq yoxdur (osv `check:vuln-ratchet` ilə üst-üstə düşür; Əsaslandırma Gözləyən İşlər Siyahısına baxın) | Bəli | +| `check:lockfile` | `package-lock.json` bütövlüyü — https reyestri, bütövlük heşləri, host əvəzləmələri yoxdur | Bəli | +| `check:licenses` | İstehsal asılılıqları üçün SPDX lisenziyalarının icazə siyahısı | Bəli | +| `check:tracked-artifacts` | Build artefaktları / repozitoriyaya əlavə edilmiş `node_modules` simvolik keçidləri yoxdur (həmçinin husky pre-commit zamanı işləyir; pre-push qəsdən yüngüldür — #6716) | Bəli | +| `check:ai-attribution` | PR commit-lərində, başlığında və ya mətnində AI/bot `Co-Authored-By` treyleri və ya AI tərəfindən yaradılma altbilgisi yoxdur — Sərt Qayda #16 (`quality.yml` faylındakı PR→`release/**` üçün fast-gates dövrəsində — hadisə payload-unu oxuyur, PR olmadıqda heç bir əməliyyat etmir — və `ci.yml` lint prosesində PR→`main` üçün yalnız PR-a aid addım; həmçinin husky `commit-msg` hook-u; insan həmmüəlliflərə icazə verilir; #14436) | +| `check:vitest-exclusions` | Hər bir Vitest istisnası izləmə məsələsini göstərir və `config/quality/vitest-exclusions.json` faylında yer alır (#13204) | Bəli | +| `check:file-size` | Heç bir mənbə faylı genişlənməyə görə müəyyən edilmiş limiti aşmır (ratchet: böyük fayllar `frozen` siyahısında dondurulub) | Bəli | +| `check:error-helper` | İcraçılarda/işləyicilərdə xəta cavabları `buildErrorBody()` / `sanitizeErrorMessage()` funksiyalarından istifadə edir (Sərt Qayda #12) | Bəli | +| `check:migration-numbering` | Miqrasiya SQL faylları boşluqlar və ya dublikatlar olmadan ardıcıl nömrələnib | Bəli | +| `check:public-creds` | `publicCreds.ts` xaricində heç bir literal OAuth `client_id`/`client_secret` və ya Firebase Web açarı yoxdur (Sərt Qayda #11) | Bəli | +| `check:db-rules` | `src/lib/db/` modullarından kənarda xam SQL yoxdur; `localDb.ts` faylından barrel-importlar yoxdur (Sərt Qaydalar #2/#5) | Bəli | +| `check:known-symbols` | Dispetçer cədvəllərində qeydiyyatdan keçirilmiş provayder icraçıları, marşrutlaşdırma strategiyaları və tərcüməçilər diskdəki fayllarla uyğun gəlir — yetim və ya elan edilməmiş simvollar yoxdur | Bəli | +| `check:route-guard-membership` | Alt proses yaradan hər bir marşrut `isLocalOnlyPath()` tərəfindən təsnif edilir (Sərt Qaydalar #15/#17) | Bəli | +| `check:test-discovery` | Repodakı hər bir `*.test.ts` / `*.spec.ts` faylı ən azı bir test icraçısı tərəfindən toplanır (ratchet: `test-discovery-baseline.json` faylındakı yetimlər siyahısı yalnız kiçilə bilər) | Bəli | +| `check:agent-skills-sync` | Yaradılmış agent-skills artefaktları mənbə kataloqu ilə uyğun gəlir (fərqlənmə yoxdur) | +| `check:provider-asset-provenance` | Provayder loqoları/aktivləri qeydə alınmış mənşə qeydini ehtiva edir | +| `lint:json` | JSON konfiqurasiya faylları təhlil olunur və repozitoriyanın lint qaydalarına cavab verir | +| `typecheck:core` | TypeScript kompilyasiyası xətasız tamamlanır (yalnız tövsiyə xarakterli xəbərdarlıqlar) | Bəli | +| `typecheck:noimplicit:core` | Sərt `noImplicitAny` — gələcəyə yönəlib; əvvəlcədən mövcud olan bir çox çağırış nöqtəsi hələ də annotasiyalara ehtiyac duyur | **Tövsiyə xarakterli** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` ilə məhdudlaşdırılmış `tsc` (#7033) — `typecheck:core` modulunun xüsusi seçilmiş 27 fayllıq icazə siyahısına heç bir idarə paneli TSX faylı daxil deyil və `next build` də onları heç vaxt tip yoxlamasından keçirmir (`next.config.mjs` faylında `ignoreBuildErrors: true` təyin edilib), buna görə də oradakı sahibsiz identifikator reqressiyaları (#6625/#6909) CI üçün görünməz idi. Dondurulmuş hər-fayl/hər-TS-kod xəta sayı bazası (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ilə eyni köhnəlmə nəzarəti nümunəsi) ilə müqayisə aparır — yalnız baza sayını aşan YENİ xətalar yoxlamanın uğursuz olmasına səbəb olur; əvvəlcədən mövcud olan xəta düzəldildikdə `--update` ilə bazanı tədricən azaldın. | Bəli | ### Tapşırıq: `quality-gate` -`test-coverage` tamamlandıqdan sonra işə düşür. Uğursuzluq halında birləşdirməni bloklayır. +`test-coverage` tamamlandıqdan sonra işə düşür. Uğursuz olarsa, birləşdirməni bloklayır. -| Skript | Yoxlayır | Bloklayıcı | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | `quality-metrics.json` faylını yaradır (ESLint xəbərdarlıqlarının sayı, birləşdirilmiş shard hesabatından əhatə göstəricisi) | Bəli (ratchet-dən əvvəl) | -| `quality:ratchet` | `quality-baseline.json` faylındakı heç bir metrik geriləməyib (ESLint xəbərdarlıqları ≤ baza göstəricisi; əhatə ≥ baza göstəricisi) | Bəli | -| `check:duplication` | Kod təkrarlanması (jscpd@4) `quality-baseline.json` faylındakı baza göstəricisini aşmır | Bəli | -| `check:complexity` | Fayl səviyyəsində siklomatik mürəkkəblik həddi aşmır (əsas ESLint `complexity` + `max-lines-per-function`) | Bəli | -| `check:cognitive-complexity` | Koqnitiv mürəkkəblik ratchet-i (`eslint-plugin-sonarjs`) — ayrıca ESLint keçidi; CI hər ikisini vahid `check:complexity-ratchets` addımı kimi birlikdə işə salır | Bəli | -| `check:dead-code` | İstifadə olunmayan eksportlar / fayllar üçün ratchet (knip) baza göstəricisi ilə müqayisədə geriləmir | Bəli | -| `check:compression-budget` | Sıxılma bençmarkı büdcəsi — hər mühərrik üzrə token qənaətinin minimum hədləri geriləməməlidir | Bəli | -| `check:type-coverage` | Tiplənmə faizi ratchet-i (`type-coverage`) geriləmir; əsasən `typecheck:noimplicit:core` yoxlamasını əvəz edir | Bəli | -| `check:codeql-ratchet` | Açıq CodeQL xəbərdarlıqlarının sayı artmır (`gh api` vasitəsilə oxuyur; token olmadıqda təhlükəsiz şəkildə ötürür) — yeniləmə tezliyi və əl ilə işə salma: aşağıdakı "CodeQL ratchet" bölməsinə baxın | Bəli | +| Skript | Yoxlayır | Bloklayıcı | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | `quality-metrics.json` yaradır (ESLint xəbərdarlıqlarının sayı, birləşdirilmiş şard hesabatından əhatə göstəricisi) | Bəli (ratchet-dən əvvəl) | +| `quality:ratchet` | `quality-baseline.json` faylındakı hər bir metrik geriləməyib (ESLint xəbərdarlıqları ≤ baza göstəricisi; əhatə ≥ baza göstəricisi) | Bəli | +| `check:duplication` | Kod təkrarlanması (jscpd@4) `quality-baseline.json` faylındakı baza göstəricisini aşmır | Bəli | +| `check:complexity` | Fayl səviyyəsində siklomatik mürəkkəblik həddi aşmır (əsas ESLint `complexity` + `max-lines-per-function`) | Bəli | +| `check:cognitive-complexity` | Koqnitiv mürəkkəblik ratchet-i (`eslint-plugin-sonarjs`) — ayrıca ESLint keçidi; CI hər ikisini vahid `check:complexity-ratchets` addımı kimi birləşdirərək işə salır | Bəli | +| `check:dead-code` | İstifadə olunmayan eksportlar / fayllar ratchet-i (knip) baza göstəricisi ilə müqayisədə geriləmir | Bəli | +| `check:compression-budget` | Sıxılma etalon testinin büdcəsi — hər mühərrik üzrə token qənaətinin minimum hədləri geriləməməlidir | Bəli | +| `check:type-coverage` | Tipləşdirilmiş kod faizi ratchet-i (`type-coverage`) geriləmir; `typecheck:noimplicit:core` yoxlamasını böyük ölçüdə əvəz edir | Bəli | +| `check:codeql-ratchet` | Açıq CodeQL xəbərdarlıqlarının sayı artmır (`gh api` vasitəsilə oxuyur; token olmadıqda xətasız ötürür) — yenilənmə tezliyi və əl ilə işə salma: aşağıdakı "CodeQL ratchet" bölməsinə baxın | Bəli | ### Tapşırıq: `quality-extended` -Bütün tapşırıq tövsiyə xarakterlidir (`continue-on-error: true`). npm əsaslı ratchet-lər -faktiki olaraq işləyir; xarici skanerlər `gh release download` vasitəsilə quraşdırılır və -binar fayl hələ də mövcud olmadıqda özlərini ötürürlər (exit 0). +Bütün tapşırıq məsləhət xarakterlidir (`continue-on-error: true`). npm əsaslı ratchet-lər +real olaraq işə salınır; xarici skanerlər `gh release download` vasitəsilə quraşdırılır və +binar fayl hələ də mövcud olmadıqda özünü ötürür (exit 0). -| Skript | Yoxlayır | Bloklayıcı | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | -| `check:circular-deps` | Dövri asılılıqların olmaması (dpdm) | **Tövsiyə xarakterli** | -| `check:bundle-size` | Paket ölçüsünün həddi aşmaması | **Tövsiyə xarakterli** | -| `check:secrets` | Məxfi məlumatların skan edilməsi (gitleaks) — binar fayl olmadıqda ötürür | **Tövsiyə xarakterli** | -| `check:vuln-ratchet` | Asılılıqlardakı zəifliklər (osv-scanner) geriləmir — binar fayl olmadıqda ötürür | **Tövsiyə xarakterli** | -| `check:workflows` | İş axını lint yoxlaması (actionlint + zizmor); çatışmayan/işləməyən skanerlər, etibarsız hesabatlar və ya çatışmayan ratchet baza göstəricisi INCOMPLETE kimi uğursuz olur. Etibarlı tapıntılar seçilmiş sərt/tövsiyə/ratchet siyasətinə tabedir | İcra tələb olunur; zizmor ratchet-i CI-də bloklayıcıdır | -| `check:openapi-breaking` | İctimai API müqaviləsində (`openapi.yaml`) baza budağı ilə müqayisədə geriyə uyğunluğu pozan dəyişikliklər (oasdiff) — `openapiBreaking=N` yaradır; oasdiff olmadıqda və ya baza spesifikasiyası həll edilə bilmədikdə ötürür | **Tövsiyə xarakterli** | +| Skript | Yoxlayır | Bloklayıcı | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| `check:circular-deps` | Dövri asılılıqların olmaması (dpdm) | **Məsləhət xarakterli** | +| `check:bundle-size` | Paket ölçüsü həddi aşmır | **Məsləhət xarakterli** | +| `check:secrets` | Məxfi məlumatların skan edilməsi (gitleaks) — binar fayl olmadıqda ötürülür | **Məsləhət xarakterli** | +| `check:vuln-ratchet` | Asılılıqlardakı zəifliklər (osv-scanner) geriləmir — binar fayl olmadıqda ötürülür | **Məsləhət xarakterli** | +| `check:workflows` | İş axını lint-i (actionlint + zizmor); çatışmayan/nasaz skanerlər, etibarsız hesabatlar və ya çatışmayan ratchet baza göstəricisi INCOMPLETE kimi uğursuz sayılır. Etibarlı tapıntılar seçilmiş sərt/məsləhət/ratchet siyasətinə tabedir | İcra tələb olunur; zizmor ratchet-i CI-də bloklayıcıdır | +| `check:openapi-breaking` | Açıq API müqaviləsində (`openapi.yaml`) baza budağı ilə müqayisədə geriyə uyğunluğu pozan dəyişikliklər (oasdiff) — `openapiBreaking=N` yaradır; oasdiff olmadıqda və ya baza spesifikasiyasını müəyyən etmək mümkün olmadıqda ötürülür | **Məsləhət xarakterli** | ### Tapşırıq: `docs-sync-strict` -`main` budağına açılan hər PR üçün işə salınır. Uğursuz olduqda birləşdirməni bloklayır. - -| Skript | Yoxlayır | Bloklayıcı | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | -| `check:docs-all` | Aşağıdakı 6 alt-keçidi ardıcıl işə salan meta-keçid | Bəli | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versiyalarının uyğunluğu | Bəli | -| ↳ `check:docs-counts` | Mətndəki sayların (provayder sayı, miqrasiya sayı və s.) real sayların ratchet intervalında olması | Bəli | -| ↳ `check:env-doc-sync` | `.env.example` daxilindəki hər bir mühit dəyişəninin sənədlərdəki cədvəldə təsvir edilməsi və əksinin də doğru olması | Bəli | -| ↳ `check:deprecated-versions` | Sənədlərdə köhnəlmiş versiya sətirlərinin olmaması | Bəli | -| ↳ `check:doc-links` | Sənədlərdəki daxili markdown keçidlərinin real fayllara yönəlməsi (`[mətn]`/`(path)` forması) | Bəli | -| ↳ `check:fabricated-docs` | Sənədlərdə qeyd olunan marşrutların, mühit dəyişənlərinin, CLI əmrlərinin, hook adlarının və fayl yollarının kod bazasında mövcud olması. `--strict` vasitəsilə sərt keçid; bayraq olmadan yumşaq xəta. | Bəli (CI-də `--strict` vasitəsilə) | -| `check:cli-i18n` | CLI əmr sətirlərinin bütün i18n lokal fayllarında mövcud olması | Bəli | -| `check:openapi-coverage` | OpenAPI spesifikasiyasının real marşrutların ən azı ratchet ilə müəyyən edilmiş minimum həddini əhatə etməsi | Bəli | -| `check:openapi-security-tiers` | `openapi.yaml` daxilindəki təhlükəsizlik səviyyəsi annotasiyalarının `routeGuard.ts` təsnifatları ilə uyğunluğu | **Tövsiyə xarakterli** | -| `check:openapi-routes` | `openapi.yaml` daxilindəki hər yolun real `route.ts` faylına uyğun gəlməsi (hallüsinasiyaya qarşı) | Bəli | -| `check:docs-symbols` | `docs/**/*.md` daxilindəki hər `/api/...` istinadının real `route.ts` faylına uyğun gəlməsi (hallüsinasiyaya qarşı) | Bəli | -| `i18n translation drift` | i18n lokal fayllarında tərcümə edilməmiş açarlar — yalnız xəbərdarlıq | **Tövsiyə xarakterli** | +`main` budağına hər PR zamanı işə salınır. Uğursuzluq halında birləşdirməni bloklayır. + +| Skript | Yoxlayır | Bloklayıcı | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | +| `check:docs-all` | Aşağıdakı 6 alt-keçidi ardıcıl işə salan meta-keçid | Bəli | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versiyalarının uyğunluğu | Bəli | +| ↳ `check:docs-counts` | Mətndəki sayların (provayder sayı, miqrasiya sayı və s.) real sayların ratchet pəncərəsi daxilində olması | Bəli | +| ↳ `check:env-doc-sync` | `.env.example` faylındakı hər bir mühit dəyişəninin sənədlərdəki cədvəldə təsvir edilməsi və əksinin də doğru olması | Bəli | +| ↳ `check:deprecated-versions` | Sənədlərdə köhnəlmiş versiya sətirlərinin olmaması | Bəli | +| ↳ `check:doc-links` | Sənədlərdəki daxili markdown keçidlərinin real fayllara yönəlməsi (`[mətn]`/`(path)` forması) | Bəli | +| ↳ `check:fabricated-docs` | Sənədlərdə qeyd edilən marşrutların, mühit dəyişənlərinin, CLI əmrlərinin, hook adlarının və fayl yollarının kod bazasında mövcud olması. `--strict` ilə sərt keçid; bayraq olmadan yumşaq xəta. | Bəli (CI-də `--strict` vasitəsilə) | +| `check:cli-i18n` | CLI əmr sətirlərinin bütün i18n lokalizasiya fayllarında mövcud olması | Bəli | +| `check:openapi-coverage` | OpenAPI spesifikasiyasının real marşrutların ən azı ratchet ilə müəyyən edilmiş minimumunu əhatə etməsi | Bəli | +| `check:openapi-security-tiers` | `openapi.yaml` faylındakı təhlükəsizlik səviyyəsi annotasiyalarının `routeGuard.ts` təsnifatları ilə uyğun olması | **Tövsiyə xarakterli** | +| `check:openapi-routes` | `openapi.yaml` faylındakı hər bir yolun real `route.ts` faylına yönəlməsi (hallüsinasiyaya qarşı) | Bəli | +| `check:docs-symbols` | `docs/**/*.md` daxilindəki hər bir `/api/...` istinadının real `route.ts` faylına yönəlməsi (hallüsinasiyaya qarşı) | Bəli | +| `i18n translation drift` | i18n lokalizasiya fayllarındakı tərcümə edilməmiş açarlar — yalnız xəbərdarlıq | **Tövsiyə xarakterli** | ### İş: `i18n-ui-coverage` -| Skript | Yoxlayır | Bloklayıcı | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `check-ui-keys-coverage` (inline) | UI i18n açarlarının əhatə səviyyəsi ≥ 65%-dir | Bəli | -| `check-ui-value-drift` (inline) | Yenidən yazılmış ingiliscə **dəyər** köhnəlmiş tərcümə saxlamır | Bəli | -| `check-new-key-coverage` (inline) | **Yeni** ingiliscə açar hər lokalda tərcümə olunur — `__MISSING__:` markeri rədd edilir | Bəli | -| `check-translation-ratio` | Hər lokal üzrə real tərcümə nisbəti (icazə siyahısından kənarda ingiliscə ilə eyni / yer tutucu / çatışmayan son düyünlər) `config/quality/i18n-translation-baseline.json` + ehtiyat həddini aşmamalıdır | **Tövsiyə xarakterli** | +| Skript | Yoxlayır | Bloklayıcı | +| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `check-ui-keys-coverage` (sətirdaxili) | UI i18n açarlarının əhatə dairəsi ≥ 65%-dir | Bəli | +| `check-ui-value-drift` (sətirdaxili) | Yenidən yazılmış ingiliscə **dəyər** geridə köhnəlmiş tərcümə saxlamır | Bəli | +| `check-new-key-coverage` (sətirdaxili) | **Yeni** ingiliscə açar hər bir lokalizasiya üçün tərcümə edilib — `__MISSING__:` markeri rədd edilir | Bəli | +| `check-translation-ratio` | Hər lokalizasiya üçün real tərcümə nisbəti (icazə siyahısından kənarda ingiliscə ilə eyni / yer tutucu / çatışmayan yarpaqlar) `config/quality/i18n-translation-baseline.json` + güzəşt həddini aşmamalıdır | **Tövsiyə xarakterli** | -`fetch-depth: 0` tələb olunur — dəyər yayınması keçidi `en.json` faylını birləşdirmə bazası ilə müqayisə edir. +`fetch-depth: 0` tələb edir — dəyər fərqi keçidi `en.json` faylını birləşdirmə bazası ilə müqayisə edir. #### `check-ui-value-drift` — köhnəlmiş tərcümə keçidi Digər keçidlərin struktur baxımından görə bilmədiyi yeganə i18n reqressiyasını aşkarlayır: ingiliscə dəyər -yenidən yazılır, lakin _əvvəlki_ ingiliscə mətndən yaradılmış tərcümələr saxlanılır və nəticədə -ingiliscə bilməyən istifadəçilər inamlı ifadə edilmiş, lakin artıq yanlış olan mətni oxumağa davam edirlər. +yenidən yazılır və _əvvəlki_ ingiliscə mətndən əldə edilmiş tərcümələr yerində qalır, buna görə də +ingilisdilli olmayan istifadəçilər əminliklə ifadə edilmiş, lakin artıq yanlış olan mətni oxumağa davam edirlər. -Bu, həqiqətən də buraxılışa düşüb. Antigravity giriş köməkçisi əlavə ediləndə (#5203) -`oauthModal.googleOAuthWarning` yenidən yazılmışdı; **43 lokaldan 39-u** operatorlara "tam URL-i -kopyalayıb aşağıya yapışdırmağı" bildirən mətni saxlamışdı — həmin provayder üçün tamamlanması +Bu, həqiqətən buraxılışa daxil olub. Antigravity giriş köməkçisi əlavə ediləndə (#5203) +`oauthModal.googleOAuthWarning` yenidən yazılmışdı; **43 lokalizasiyadan 39-u** operatorlara "tam +URL-i kopyalayıb aşağıya yapışdırmağı" bildirən mətni saxlamışdı — həmin provayder üçün tamamlanması mümkün olmayan bir axın. Bu, #8463-ə qədər nəzərdən qaçdı, çünki: -- `sync-ui-keys` yalnız **mövcud olmayan** açarları əlavə edir, **köhnəlmiş** açarları isə heç vaxt yeniləmir; -- `check-ui-keys-coverage` açarın _mövcudluğunu_ hesablayır, buna görə köhnəlmiş tərcümə əhatə olunmuş sayılır; +- `sync-ui-keys` yalnız **mövcud olmayan** açarları geriyə doldurur, **köhnəlmiş** olanları isə heç vaxt yeniləmir; +- `check-ui-keys-coverage` açarın _mövcudluğunu_ sayır, buna görə köhnəlmiş tərcümə əhatə olunmuş kimi hesablanır; - `check-translation-drift` `docs/i18n//**.md` sənədləşdirmə güzgülərini izləyir — - o, heç vaxt `src/i18n/messages/*.json` fayllarını oxumur. 2026-09 yenidən sinxronlaşdırılmasından etibarən - `docs-sync-strict` işində bloklayıcıdır: əsas sənədi redaktə edin → `npm run i18n:run -- --files=` - (bölmə səviyyəsində, az xərc tələb edir). - -**Fərqləri nəzərə alır, baza xəttinə əsaslanmır.** O, birləşdirmə bazasındakı `en.json` faylını -işçi ağacı ilə müqayisə edir; ingiliscə dəyəri dəyişmiş hər bir açar üçün hələ də -toxunulmamış tərcüməni saxlayan istənilən lokal köhnəlmiş sayılır. Bu, qəsdən **əvvəldən mövcud olan borcu dondurur** — -fərq uzun müddətdir mövcud olan tərcümənin hansı köhnə ingiliscə mətndən gəldiyini göstərə bilməz, buna görə də yoxlama -yalnız cari dəyişikliyin toxunduğu hissələri qiymətləndirir. Alternativ yanaşma (hər açar üzrə heş baza xətti) + o, heç vaxt `src/i18n/messages/*.json` fayllarını oxumur. 2026-09 yenidən sinxronizasiyasından bəri `docs-sync-strict` + işində bloklayıcıdır: əsas sənədi redaktə edin → `npm run i18n:run -- --files=` (bölmə səviyyəsində, az resurs tələb edir). + +**Fərqləri nəzərə alır, baza xəttinə əsaslanmır.** Birləşdirmə bazasındakı `en.json` faylını +işçi ağacı ilə müqayisə edir; ingiliscə dəyəri dəyişmiş hər açar üçün hələ də +toxunulmamış tərcüməni saxlayan istənilən lokal köhnəlmiş sayılır. Bu, qəsdən **əvvəldən mövcud olan borcu dondurur** — fərq +uzun müddətdir mövcud olan tərcümənin hansı köhnə ingiliscə mətndən gəldiyini göstərə bilməz, buna görə yoxlama +yalnız cari dəyişikliyin toxunduğu hissələri qiymətləndirir. Alternativ (hər açar üçün heş baza xətti) təxminən 600 KB həcmində yaradılan fayl tələb edərdi; bu, mövcud ən böyük baza xəttindən 3 dəfə böyükdür və hər i18n PR-da -dəyişiklik yaradardı. +dəyişiklik səs-küyü yaradardı. Tələbi ödəməyin iki yolu var: -1. təsirlənmiş tərcümələri yeniləyin və ya +1. təsirə məruz qalan tərcümələri yeniləyin və ya 2. onları `__MISSING__:` olaraq təyin edin — bundan sonra icra mühiti düzəldilmiş ingiliscə mətni təqdim edir (`src/i18n/request.ts::deepMergeFallback`, #7258) və açar tərcümə növbəsinə əlavə olunur. -Sətrin **mənası** dəyişibsə, **açarın adını dəyişməyə** üstünlük verin: yeni açar +Əgər sətrin **mənası** dəyişibsə, **açarın adını dəyişməyə** üstünlük verin: yeni açar köhnəlmiş tərcüməni miras ala bilməz. #8463-də istifadə olunan nümunə budur. ```bash -npm run i18n:check-value-drift # ciddi rejim (CI-da işlədilən) +npm run i18n:check-value-drift # sərt (CI-da işlədilən) npm run i18n:check-value-drift:warn # yalnız hesabat BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Baza kataloqu oxuna bilmədikdə (baza istinadı olmayan dayaz -klon) `SKIP reason=base-unresolved` ilə 0 çıxış kodu qaytarır və `check-openapi-breaking` davranışını təkrarlayır. +Baza kataloqunu oxumaq mümkün olmadıqda (baza ref-i olmayan dayaz +klon) `SKIP reason=base-unresolved` ilə 0 çıxış kodu qaytarır; bu, `check-openapi-breaking` davranışını təkrarlayır. ### Tapşırıq: `i18n` Tam i18n doğrulama matrisi (hər lokal üçün bir tapşırıq). Bütün tapşırıq tövsiyə xarakterlidir. -| Skript | Doğruladığı sahə | Bloklama | -| ------------------------------- | ------------------------------ | ------------------------------------------------------------------- | -| `validate_translation.py quick` | Hər lokal üzrə tərcümə tamlığı | **Tövsiyə xarakterli** (bütün tapşırıqda `continue-on-error: true`) | +| Skript | Doğruladığı | Bloklama | +| ------------------------------- | --------------------------------- | ------------------------------------------------------------------- | +| `validate_translation.py quick` | Hər lokal üzrə tərcümənin tamlığı | **Tövsiyə xarakterli** (bütün tapşırıqda `continue-on-error: true`) | ### Tapşırıq: `pr-test-policy` Yalnız pull request-lərdə işləyir. -| Skript | Doğruladığı sahə | Bloklama | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` və ya `bin/` daxilində istehsal kodunu dəyişən PR-lar testlər əlavə etməli və ya yeniləməlidir (Sərt Qayda #8) | Bəli | -| `check:test-masking` | Dəyişdirilmiş test faylları xalis təsdiq sayını azaltmır və ya `assert.ok(true)` tavtologiyaları əlavə etmir | Bəli | -| `check:pr-evidence` | PR mətni dəyişiklik üçün test/VPS sübutlarına istinad edir (PR mətnində axtarış apararaq Sərt Qayda #18-i avtomatlaşdırır — kövrəkdir, Backlog-a baxın) | Bəli | +| Skript | Doğruladığı | Bloklama | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` və ya `bin/` daxilində istehsal kodunu dəyişən PR-lar testləri daxil etməli və ya yeniləməlidir (Sərt Qayda #8) | Bəli | +| `check:test-masking` | Dəyişdirilmiş test faylları xalis təsdiq sayını azaltmır və `assert.ok(true)` tavtologiyaları əlavə etmir | Bəli | +| `check:pr-evidence` | PR mətni dəyişiklik üçün test/VPS sübutlarına istinad edir (PR mətnini grep etməklə Sərt Qayda #18-i avtomatlaşdırır — kövrəkdir, Backlog-a baxın) | Bəli | ### Tapşırıq: `test-vitest` -`build`-dən sonra işləyir. Uğursuzluq baş verdikdə birləşdirməni bloklayır. +`build` sonrasında işləyir. Uğursuz olduqda birləşdirməni bloklayır. -| Test dəsti | Doğruladığı sahə | Bloklama | -| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP serveri (110 alət), autoCombo, keş — vitest icraçısı | Bəli | -| `test:vitest:ui` | UI komponent testləri — vitest icraçısı | **Bloklayır** — əvvəlcədən mövcud olan uğursuzluqlar `vitest.config.ts` daxilində açıq şəkildə istisna edilib; yeni uğursuzluqlar tapşırığı uğursuz edir | +| Test dəsti | Doğruladığı | Bloklama | +| ---------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP serveri (110 alət), autoCombo, keş — vitest icraedicisi | Bəli | +| `test:vitest:ui` | UI komponent testləri — vitest icraedicisi | **Bloklayır** — əvvəldən mövcud olan uğursuzluqlar `vitest.config.ts` daxilində açıq şəkildə istisna edilib; yeni uğursuzluqlar tapşırığın uğursuz olmasına səbəb olur | -### Gecəlik iş axınları (planlaşdırılmış, tövsiyə xarakterli) +### Gecə iş axınları (planlaşdırılmış, tövsiyə xarakterli) -Bunlar cron cədvəli üzrə (və `workflow_dispatch` ilə) işləyir, PR-larda isə heç vaxt işə düşmür. Hamısı tövsiyə xarakterlidir. +Bunlar cron cədvəli üzrə (və `workflow_dispatch` ilə) işləyir, PR-larda isə heç vaxt işləmir. Hamısı tövsiyə xarakterlidir. -| İş axını | Doğruladığı sahə | Bloklama | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `nightly-property` | təsadüfi toxum və yüksək icra sayı ilə fast-check xüsusiyyət testləri | **Tövsiyə xarakterli** | -| `nightly-resilience` | heap artımı yoxlaması, xaos nasazlıq inyeksiyası, k6 yük/uzunmüddətli yük testi | **Tövsiyə xarakterli** | -| `nightly-llm-security` | promptfoo inyeksiya qoruması (bloklama rejimi) + garak yoxlamaları (provayder sirri olmadıqda ötürülür) | **Tövsiyə xarakterli** | -| `nightly-schemathesis` | `docs/openapi.yaml` istifadə edərək canlı OmniRoute-a qarşı OpenAPI müqaviləsinin fuzzinqi (schemathesis) — spesifikasiya pozuntularını / idarə olunmayan 500 xətalarını üzə çıxarır (Mərhələ 8 B.4) | **Tövsiyə xarakterli** | -| `nightly-mutation` | sürətli modul testləri xətti üzrə Stryker mutasiya testi balı — sağ qalan mutantlar zəif təsdiqləri üzə çıxarır | **Tövsiyə xarakterli** | -| `nightly-compat` | dəstəklənən `engines.node` diapazonları üzrə Node mühərriki uyğunluq matrisi | **Tövsiyə xarakterli** | +| İş axını | Doğruladığı | Bloklama | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `nightly-property` | təsadüfi seed + yüksək icra sayı ilə fast-check xüsusiyyət testləri | **Tövsiyə xarakterli** | +| `nightly-resilience` | heap artımı yoxlaması, xaos nasazlıq inyeksiyası, k6 yük/davamlı yük testi | **Tövsiyə xarakterli** | +| `nightly-llm-security` | promptfoo inyeksiya qoruyucusu (bloklama rejimi) + garak yoxlamaları (provayder sirri olmadıqda ötürülür) | **Tövsiyə xarakterli** | +| `nightly-schemathesis` | `docs/openapi.yaml` istifadə etməklə canlı OmniRoute-a qarşı OpenAPI müqaviləsinin fuzzinqi (schemathesis) — spesifikasiya pozuntularını / idarə olunmamış 500 xətalarını üzə çıxarır (Mərhələ 8 B.4) | **Tövsiyə xarakterli** | +| `nightly-mutation` | sürətli vahid test xətti üzrə Stryker mutasiya testi balı — sağ qalan mutantlar zəif təsdiqləri üzə çıxarır | **Tövsiyə xarakterli** | +| `nightly-compat` | dəstəklənən `engines.node` diapazonları üzrə Node mühərriki uyğunluq matrisi | **Tövsiyə xarakterli** | --- @@ -549,43 +546,43 @@ bağlantı xətasını jurnala yazır və sessiyaları heç vaxt pozmur. --- -## Rasionallaşdırma üçün görüləcək işlər siyahısı (ROI icmalı — Mərhələ 9 Dalğa 3) +## Rasionallaşdırma ehtiyat siyahısı (ROI icmalı — Mərhələ 9 Dalğa 3) -Bu inventar 2026-06-17 tarixində `ci.yml` ilə tutuşdurulub (əvvəlki versiyada +Bu inventar 2026-06-17 tarixində `ci.yml` ilə tutuşduruldu (əvvəlki versiyada `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence` buraxılmışdı). Tutuşdurulmuş dəstin ROI icmalı aşağıdakı rasionallaşdırma namizədlərini müəyyən etdi. **Birləşdirmələr mexaniki CI -dəyişiklikləridir; aktivləşdirmə/statusun aşağı salınması qərarları operator üçün saxlanılan siyasət qərarlarıdır.** Aşağıdakılardan heç biri +dəyişiklikləridir; çevirmə/ləğvetmə qərarları operatorun səlahiyyətində olan siyasət qərarlarıdır.** Aşağıdakılardan heç biri hələ tətbiq edilməyib. **Yuxarıda sənədləşdirilməyənlər də var** (məsləhət xarakterli, zəif siqnal): `docs-lint` işi -(markdownlint + Vale, bütün iş üçün `continue-on-error`) və ayrıca skaner iş axınları +(markdownlint + Vale, bütün iş üçün `continue-on-error`) və müstəqil skaner iş axınları `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` -`quality-baseline.json` daxilindədir, lakin `ci.yml` daxilində bloklayıcı ratchet-ə qoşulmayıb — metrik -hazırda sahibsizdir. - -### Birləşdirmə / dublikatların aradan qaldırılması (mexaniki, daha az riskli) - -Hər bir namizəd 2026-06-17 tarixində aktiv keçid vəziyyəti ilə müqayisədə yoxlanılıb (etibar et, amma yoxla); -bir neçə «aşkar» birləşdirmənin əslində texniki borcu gizlətdiyi üzə çıxdı və onlar **təmiz şəkildə birbaşa əvəzlənə bilmir**. - -- **`check:docs-sync` iki dəfə icra olunur** — `lint` işində ayrıca və yenidən `check:docs-all` (`docs-sync-strict`) daxilində, həmçinin husky pre-commit hook-unda. ✅ **TAMAMLANDI** — ayrıca `lint` çağırışı silindi. -- **CVE skanı** — ❌ **Təmiz birləşdirmə DEYİL.** `audit:deps` istənilən yüksək/kritik CVE olduqda sərt şəkildə uğursuz olur; `check:vuln-ratchet` (osv) isə yalnız baza səviyyəsi ilə müqayisədə _reqressiya_ olduqda uğursuz olur (hazırda 1 MODERATE). Semantikaları fərqlidir — `audit:deps` silinsəydi, mütləq yüksək/kritik keçid itirilərdi. Hər ikisini saxlayın. -- **Dövr aşkarlanması** — ❌ **Təmiz birləşdirmə DEYİL.** `check:circular-deps` (dpdm) **91 dövr** bildirir (məhz buna görə məsləhət xarakterlidir); əvvəlcə onlar həll edilmədən bloklayıcı səviyyəyə qaldırıla bilməz və yaşıl statuslu, seçilmiş `check:cycles` ilə müqayisədə daha geniş əhatə dairəsinə malikdir. `check:cycles` bloklayıcı olaraq saxlanılsın; 91 dpdm dövrünün həlli ayrıca görüləcək işdir. -- **Mürəkkəblik** — ✅ **TAMAMLANDI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): bir ESLint keçidi, cyclomatic+max-lines və cognitive baza səviyyələrinin müstəqil qalması üçün ruleId üzrə hesablanır; ayrıca `check:complexity` / `check:cognitive-complexity` lokal `--update` üçün saxlanılır. -- **`/api` anti-hallüsinasiya** — ✅ **TAMAMLANDI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` üçün bir FS inventarı, openapi-routes + docs-symbols hələ də müstəqil hesabat verir; ayrı-ayrı yoxlamalar lokal icralar üçün saxlanılır. -- **`check:node-runtime` 11 işdə icra olunur** — ⚠️ **aşağı ROI.** Hər biri ayrıca runner-dır və yoxlama <1s çəkir; ucuz, hər iş üzrə qoruyucunun itirilməsi müqabilində ümumi qənaət təxminən 10s-dir. Yaradacağı qarışıqlığa dəyməz. -- **CI lint-də `typecheck:noimplicit:core`** — ✅ **lint işindən silindi** (məsləhət xarakterli `continue-on-error` idi); bloklayıcı tip səthi `typecheck:core` + `check:type-coverage` kombinasiyasıdır. Lokal skript saxlanılıb. - -### Aktivləşdirmə / qərar vermə (operator siyasəti) - -- `check:openapi-security-tiers` (məsləhət xarakterli) — ❌ **Təmiz şəkildə aktivləşdirilə BİLMƏZ.** O, 0 çıxış kodu ilə bitir, lakin `LOCAL_ONLY_API_PREFIXES` altındakı bir neçə `traffic-inspector` marşrutunda `x-loopback-only: true` annotasiyasının olmadığını bildirir. Onu məcburi etmək üçün əvvəlcə həmin annotasiyaları `openapi.yaml` faylına əlavə etmək lazımdır. -- `typecheck:noimplicit:core` (məsləhət xarakterli) — əsasən bloklayıcı `check:type-coverage` ratchet-i ilə əhatə olunur. Ratchet-ə çevirin və ya təkrarlanan ikinci `tsc` keçidini silin. -- `test:vitest:ui` (indi **bloklayıcıdır**) — əvvəlcədən mövcud olan xətalar `vitest.config.ts` daxilində `// #8618` izləmə şərhləri ilə açıq şəkildə istisna edilib; yeni xətalar işi uğursuz edir. -- `check:secrets` (gitleaks, 3 sənədləşdirilmiş yanlış müsbət nəticədə dondurulmuş bloklayıcı ratchet) — 0-a çatmaq üçün bu 3 nəticəni icazə siyahısına əlavə edin və ya məsləhət xarakterli səviyyəyə endirin. GitHub-un daxili secret-scanning funksiyası + `check:public-creds` ilə üst-üstə düşür. -- `check:pr-evidence` (bloklayıcıdır, PR mətnində grep axtarışı aparır) — yanlış müsbət nəticə riski yüksəkdir; silinərsə, Hard Rule #18 tələbinin tətbiqini zəiflədir, buna görə də bu, həqiqi siyasət qərarıdır. -- `semgrep` (ayrıca, məsləhət xarakterli) — OWASP ailələri üzrə CodeQL ilə üst-üstə düşür; onun baza səviyyəsini ratchet-ə qoşun və ya silin. +`quality-baseline.json` daxilindədir, lakin `ci.yml` daxilində bloklayıcı bir xırxır mexanizminə qoşulmayıb — metrik +hazırda təcrid olunub. + +### Birləşdirmə / təkrarların aradan qaldırılması (mexaniki, daha az riskli) + +Hər bir namizəd 2026-06-17 tarixində mövcud qapı vəziyyətinə əsasən yoxlanılıb (etibar et, amma yoxla); +bir neçə «aşkar» birləşdirmənin borcu gizlətdiyi üzə çıxdı və onlar **birbaşa əvəzləmə üçün uyğun deyil**. + +- **`check:docs-sync` iki dəfə işə düşür** — `lint` işində ayrıca və yenidən `check:docs-all` (`docs-sync-strict`) daxilində, həmçinin husky pre-commit qarmağında. ✅ **TAMAMLANDI** — ayrıca `lint` çağırışı silindi. +- **CVE skanlaması** — ❌ **Təmiz birləşdirmə DEYİL.** `audit:deps` istənilən yüksək/kritik CVE olduqda sərt şəkildə uğursuz olur; `check:vuln-ratchet` (osv) isə yalnız baza xətti ilə müqayisədə _geriləmə_ olduqda uğursuz olur (hazırda 1 MODERATE). Semantikaları fərqlidir — `audit:deps` ləğv edilsəydi, mütləq yüksək/kritik qapı itirilərdi. Hər ikisini saxlayın. +- **Dövr aşkarlanması** — ✅ **TAMAMLANDI** (#15159 G-01/G-02). Buradakı köhnə mətn `check:cycles` yoxlamasını «yaşıl, seçilmiş» qapı adlandırır və `check:circular-deps` (dpdm) 91 dövr bildirdiyi üçün onu bloklayıcı saxlamağı əsaslandırırdı. Həmin yaşıl status **yanlış yaşıl** idi: `check:cycles` 5 alt kataloqu (450 fayl) skan edir, yalnız statik `import|export … from` nümunələrini uyğunlaşdırır və hər bir `@/` və `@omniroute/open-sse/` spesifikatorunu kənarlaşdırırdı; buna görə repozitoriyada üstünlük təşkil edən dinamik import + alias dövrlərini görə bilmirdi. Düzəldildi: qapı indi `src` + `open-sse` daxilində gəzir (5023 fayl), spesifikatorları TypeScript AST-dən toplayır (beləliklə, `import("…")` nəzərə alınır, tip mövqeyindəki `typeof import("…")` isə alınmır) və tsconfig `paths` dəyərlərini həll edir. O, 0 deyil, **14** dövr tapır. Əvvəldən mövcud olan 14 dövr qapı PR-ında düzəldilə bilmədiyi üçün `check:cycles` indi **xırxır mexanizmidir** (`--ratchet`, `quality-baseline.json` daxilində yuxarı hədd `metrics.cycles.value = 14`, `direction: down`) — istənilən _geriləməni_ bloklayır və say yalnız azala bilər. CI `npm run check:cycles:ratchet` əmrini işə salır. Azaltma işi **A-01** ilə birlikdə aparılır. `check:circular-deps` (dpdm) daha geniş ikinci rəy kimi məsləhət xarakterli qalır. +- **Mürəkkəblik** — ✅ **TAMAMLANDI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): bir ESLint keçidi, ruleId üzrə sayır ki, siklomatik+max-lines və koqnitiv baza xətləri müstəqil qalsın; ayrı-ayrı `check:complexity` / `check:cognitive-complexity` yoxlamaları lokal `--update` üçün saxlanılır. +- **`/api` anti-hallüsinasiya yoxlaması** — ✅ **TAMAMLANDI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` üçün bir FS inventarı, openapi-routes + docs-symbols yenə də müstəqil hesabat verir; fərdi yoxlamalar lokal icralar üçün saxlanılır. +- **`check:node-runtime` 11 işdə icra olunur** — ⚠️ **aşağı ROI.** Hər biri ayrıca icra mühitidir və yoxlama <1s çəkir; ümumi qənaət ~10s təşkil edir, əvəzində isə hər iş üçün ucuz qoruyucu itirilir. Yaradacağı qarışıqlığa dəyməz. +- **CI lint-də `typecheck:noimplicit:core`** — ✅ **lint işindən silindi** (məsləhət xarakterli `continue-on-error` idi); bloklayıcı tip səthi `typecheck:core` + `check:type-coverage` ilə təmin edilir. Lokal skript saxlanıldı. + +### Çevirmə / qərarvermə (operator siyasəti) + +- `check:openapi-security-tiers` (məsləhət xarakterli) — ❌ **Təmiz şəkildə çevrilə BİLMƏZ.** 0 kodu ilə çıxır, lakin `LOCAL_ONLY_API_PREFIXES` altındakı bir neçə `traffic-inspector` marşrutunda `x-loopback-only: true` annotasiyasının olmadığını bildirir. Onu məcburi etmək üçün əvvəlcə həmin annotasiyalar `openapi.yaml` faylına əlavə edilməlidir. +- `typecheck:noimplicit:core` (məsləhət xarakterli) — bloklayıcı `check:type-coverage` xırxır mexanizmi tərəfindən əsasən əhatə olunur. Xırxır mexanizminə çevirin və ya lazımsız ikinci `tsc` keçidini ləğv edin. +- `test:vitest:ui` (indi **bloklayıcıdır**) — əvvəldən mövcud uğursuzluqlar `vitest.config.ts` daxilində `// #8618` izləmə şərhləri ilə açıq şəkildə istisna edilib; yeni uğursuzluqlar işin uğursuz olmasına səbəb olur. +- `check:secrets` (gitleaks, 3 sənədləşdirilmiş yanlış müsbət nəticədə dondurulmuş bloklayıcı xırxır mexanizmi) — 0-a çatmaq üçün bu 3 nəticəni icazə siyahısına əlavə edin və ya məsləhət xarakterli statusa endirin. GitHub-un daxili məxfi məlumat skanlaması + `check:public-creds` ilə üst-üstə düşür. +- `check:pr-evidence` (bloklayıcıdır, PR mətnini grep ilə axtarır) — yanlış müsbət nəticə riski yüksəkdir; ləğv edilərsə, Sərt Qayda #18-in icrasını zəiflədir, buna görə bu, həqiqi siyasət qərarıdır. +- `semgrep` (məsləhət xarakterli müstəqil yoxlama) — OWASP ailələri üzrə CodeQL ilə üst-üstə düşür; baza xəttini xırxır mexanizminə qoşun və ya ləğv edin. --- diff --git a/docs/i18n/bg/CONTRIBUTING.md b/docs/i18n/bg/CONTRIBUTING.md index b81a73069a2..112b954a62f 100644 --- a/docs/i18n/bg/CONTRIBUTING.md +++ b/docs/i18n/bg/CONTRIBUTING.md @@ -391,18 +391,18 @@ docs/ # Documentation - [ ] Тестовете преминават успешно (`npm test`) - [ ] Проверката за стил преминава успешно (`npm run lint`) -- [ ] Компилацията завършва успешно (`npm run build`) +- [ ] Компилацията е успешна (`npm run build`) - [ ] Добавени са TypeScript типове за новите публични функции и интерфейси - [ ] Няма твърдо зададени тайни или резервни стойности -- [ ] Публичните идентификационни данни за upstream са вградени чрез `resolvePublicCred()` (вижте [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), никога като литерални стойности -- [ ] Отговорите при грешки преминават през `buildErrorBody()` / `sanitizeErrorMessage()` — без необработени stack trace-ове в телата на отговорите (вижте [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell командите (`exec` / `spawn`) подават стойности по време на изпълнение чрез `env`, а не чрез интерполация на низове +- [ ] Публичните идентификационни данни от upstream са вградени чрез `resolvePublicCred()` (вижте [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), никога като литерали +- [ ] Отговорите при грешки преминават през `buildErrorBody()` / `sanitizeErrorMessage()` — без необработени stack trace данни в телата на отговорите (вижте [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell командите (`exec` / `spawn`) предават стойностите по време на изпълнение чрез `env`, а не чрез интерполация на низове - [ ] Всички входни данни са валидирани със Zod схеми -- [ ] Добавен е **фрагмент** за списъка с промени в `changelog.d/{features|fixes|maintenance}/-.md` за промени, видими за потребителите (вижте [`changelog.d/README.md`](./changelog.d/README.md)) — **не** редактирайте директно `CHANGELOG.md`; фрагментите се обединяват при публикуване на версия и никога не предизвикват конфликти между Pull Request-и +- [ ] Добавен е **фрагмент** към регистъра на промените в `changelog.d/{features|fixes|maintenance}/-.md` за промени, видими за потребителите (вижте [`changelog.d/README.md`](./changelog.d/README.md)) — **не** редактирайте директно `CHANGELOG.md`; фрагментите се обединяват при издаване на версия и никога не създават конфликти между PR-и - [ ] Документацията е актуализирана (ако е приложимо) -- [ ] Няма нови отворени предупреждения от CodeQL / Secret-Scanning или всяко от тях е отхвърлено с техническа обосновка, която препраща към съответния документ в `docs/security/` +- [ ] Няма нови предупреждения от CodeQL / Secret-Scanning или всяко от тях е отхвърлено с техническа обосновка, която препраща към съответния документ в `docs/security/` - [ ] Маршрутите, които стартират дъщерни процеси (`/api/mcp/`, `/api/cli-tools/runtime/`), са класифицирани като `isLocalOnlyPath()` в `src/server/authz/routeGuard.ts` — вижте [Строго правило №15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Няма `Co-Authored-By` завършващи редове в съобщенията на commit-ите — commit-ите трябва да се показват единствено под Git самоличността на собственика на хранилището (Строго правило №16) +- [ ] Няма AI/bot трейлъри `Co-authored-by` в съобщенията за commit-и (Строго правило №16) — човешките сътрудници, чиято работа е използвана повторно, се посочват със стандартни трейлъри `Co-authored-by: Name ` --- diff --git a/docs/i18n/bg/docs/architecture/QUALITY_GATES.md b/docs/i18n/bg/docs/architecture/QUALITY_GATES.md index c648e0384ad..e6b25627829 100644 --- a/docs/i18n/bg/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/bg/docs/architecture/QUALITY_GATES.md @@ -15,151 +15,151 @@ --- -## Инвентар на гейтовете и профили за изпълнение +## Инвентар на проверките и профили за изпълнение ### Допускане на кандидати -Работните процеси CI и Quality Gates публикуват по една стабилна присъда: `Gate / CI` и -`Gate / Quality`. Тяхната версионирана политика за допускане определя всяка предходна задача +Работните процеси CI и Quality Gates извеждат по една стабилна присъда: `Gate / CI` и +`Gate / Quality`. Тяхната версионирана политика за допускане определя всяка предшестваща задача като задължителна или препоръчителна. Всяка приложима задължителна задача трябва да завърши успешно: липсващи, отменени, пропуснати, изчакващи и неизвестни резултати не могат да установят PASS. Валидна -класификация „само документация“ или „само каталог“ може да направи дадена пътека за код неприложима; -чернова на PR не се приема като кандидат. Етикет `hotfix` не отменя изискването за доказателства. +класификация само за документация или само за каталог може да направи даден кодов поток неприложим; +чернова на PR не се приема за кандидат. Етикетът `hotfix` не отменя изискванията за доказателства. -И двата работни процеса обхващат PR-и и push операции към основни/release клонове, ръчно стартиране и -събития на merge group. Push операциите, ръчното стартиране и merge group изпълняват пълния набор. -Fork-овете и merge group-ите използват хоствани изпълнители за задачи, които иначе избират самостоятелно -хоствани изпълнители; преди внедряването трябва да се провери наличието на достатъчен хостван капацитет. +И двата работни процеса обхващат PR-и и push операции към основните клонове и клоновете за издания, ръчно стартиране и +събития от групи за сливане. Push операциите, ръчното стартиране и групите за сливане изпълняват пълния набор. Разклоненията +и групите за сливане използват хоствани изпълнители за задачи, които в противен случай избират самостоятелно хоствани +изпълнители; преди внедряването трябва да се потвърди наличието на достатъчен хостван капацитет. -Всяка JSON разписка идентифицира извлечения SHA, изпълнението на работния процес и опита. -CLI отхвърля несъответствие между SHA на извлеченото състояние и SHA на събитието. Тестовете на работните процеси свързват членството в политиката -със списъка `needs` на задачата за присъда, така че нова или премахната пътека да не може да изчезне незабелязано. +Всяка JSON разписка идентифицира SHA на извлечената версия, изпълнението на работния процес и опита. +CLI отхвърля несъответствие между SHA на извлечената версия и събитието. Тестовете на работния процес обвързват членството в политиката +със списъка `needs` на задачата за присъдата, така че нов или премахнат поток да не може да изчезне незабелязано. Разписките обхващат собствения си работен процес, а не публикуването, внедряването или вътрешната логика на съществуващ препоръчителен скенер. Активирането на двете имена на проверки в правилата за клонове е отделна административна промяна; добавянето на тези задачи само по себе си не защитава даден клон. -### Инвентар на статичните сканирания +### Инвентар на статичното сканиране -Версионираният инвентар от npm псевдоними и членството в статичните сканирания се намират в +Версионираният инвентар на npm псевдонимите и членството в статичното сканиране се намират в `config/quality/gate-manifest.json`. Изпълнете `npm run check:gate-manifest`, за да валидирате имената на скриптовете и точните команди спрямо `package.json`; добавянията, премахванията и -отклоненията в командите водят до неуспех както на локалната кука, така и на задачите за класификация на промените в CI. -Псевдонимът не е задача в работен процес, екземпляр от матрица или тестов случай: тези бройки не трябва +отклоненията в командите водят до неуспех както на локалната кука, така и на задачите за класифициране на промените в CI. +Псевдонимът не е задача от работен процес, екземпляр на матрица или тестов случай: тези бройки не трябва да се представят като взаимозаменяеми. Използвайте `npm run quality:scan -- --list` или `npm run quality:scan:fast -- --list`, за да прегледате избраните псевдоними, без да ги изпълнявате. Изпълнителят извиква -входната точка на npm, така че средата ѝ за изпълнение (включително Bun, където е конфигуриран) се запазва. +npm входната точка, така че нейната среда за изпълнение (включително Bun, където е конфигуриран) се запазва. Манифестът записва псевдонимите извън тези профили като извиквани отделно, а командите за поддръжка са забранени в профилите за сканиране само за четене. -Тези профили обхващат единствено статичното сканиране. Те не удостоверяват продуктовите тестове, +Тези профили обхващат единствено статичното сканиране. Те не сертифицират продуктовите тестове, покритието, пакетирането, външните проверки или пълното приемане на кандидат за издание. Допускането от работния процес използва свързаните `config/quality/admission-policy.json` и -`scripts/quality/admission-verdict.mjs`. Профилите за наблюдение на издания остават отделни; +`scripts/quality/admission-verdict.mjs`. Профилите за наблюдение на изданията остават отделни; проверявайте независимо приложимите им проверки и разписки. Текстовият -инвентар по-долу е справочен материал, а не доказателство, че даден гейт действително е бил изпълнен. +инвентар по-долу е справочен материал, а не доказателство, че дадена проверка действително е била изпълнена. -Скриптовете се намират в `scripts/check/` (гейтове за политики) и `scripts/quality/` (механизъм с храпов принцип). +Скриптовете се намират в `scripts/check/` (проверки на политики) и `scripts/quality/` (механизъм с тресчотка). Източникът на истина за CI е `.github/workflows/ci.yml`. -### Бърза пътека за PR за издание (`quality.yml`) +### Ускорен път за PR за издание (`quality.yml`) -`.github/workflows/quality.yml` допълва CI при PR-и към основни/release клонове, push операции към защитени -клонове, ръчно стартиране и merge group-и. PR-ите използват бързи проверки, филтрирани по пътища. Постоянно -деактивираното дублирано изграждане беше премахнато; реалните проверки за изграждане/пакетиране/стартиране остават в CI. +`.github/workflows/quality.yml` допълва CI за PR-и към основните клонове и клоновете за издания, push операции към защитени клонове, +ръчно стартиране и групи за сливане. PR-ите използват филтрирани по пътища бързи проверки. Постоянно +деактивираното дублиращо изграждане беше премахнато; реалните проверки за изграждане, пакетиране и стартиране остават в CI. -| Задача | Обхват | Блокираща | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | PR-и за документация/код; препратки към API документация и цялата документация | Да | -| `Fast Quality Gates` | PR-и за код; статични проверки, проверка на типове, проверка на типовете на таблото, засегнати модулни тестове | Да | -| `Forgotten sibling tests` | PR-и за код; променени модули, проследени до статични потребители и кандидат-тестове за сродни модули; пътищата през barrel файлове и динамични импорти се отчитат като препоръчителна диагностика, с посочени изключения от списъка с разрешения | **Препоръчителна** | -| `Vitest (fast-path)` | PR-и за код; бърз пакет от vitest тестове | Да | -| `Unit Tests fast-path` | PR-и за код; пакет от модулни тестове в 4 шарда | Да | -| `No new ESLint warnings` | PR-и за код; lint защита, отчитаща потисканията | Да, включително fork-ове | -| `Merge integrity (changelog + generated skills)` | PR-и, които не са чернови; синхронизиране на регистъра на промените и генерираните умения | Да, включително fork-ове | +| Задача | Обхват | Блокираща | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | +| `Docs Gates (fast-path)` | PR-и за документация/код; препратки в API документацията и цялата документация | Да | +| `Fast Quality Gates` | PR-и за код; статични проверки, проверка на типовете, проверка на типовете на таблото, засегнати модулни тестове | Да | +| `Forgotten sibling tests` | PR-и за код; променените модули се проследяват до статичните потребители и кандидат-тестовете за сродни модули; пътищата през обобщаващи модули и динамичен импорт се отчитат като препоръчителна диагностика, с посочени изключения от списъка с разрешения | **Препоръчителна** | +| `Vitest (fast-path)` | PR-и за код; бърз набор от vitest тестове | Да | +| `Unit Tests fast-path` | PR-и за код; набор от модулни тестове в 4 сегмента | Да | +| `No new ESLint warnings` | PR-и за код; предпазна lint проверка, отчитаща потисканията | Да, включително разклонения | +| `Merge integrity (changelog + generated skills)` | PR-и, които не са чернови; синхронизиране на регистъра на промените и генерираните умения | Да, включително разклонения | -#### Отчет за забравени тестове за сродни модули +#### Отчет за забравени тестове на сродни модули -`npm run check:forgotten-sibling-tests` използва повторно механизма за разрешаване на импорти зад картата за въздействие върху тестовете. +`npm run check:forgotten-sibling-tests` използва повторно механизма за разрешаване на импорти зад картата на въздействието върху тестовете. За всеки променен производствен модул той отчита детерминистични вериги -`променен модул/символ -> статичен потребител -> кандидат-тест за сроден модул`, когато кандидат-тестът -отсъства от разликите в pull request-а. Markdown резюмето и JSON резултатът се запазват като -артефакта `forgotten-sibling-tests` на работния процес за калибриране преди евентуално внедряване като блокираща проверка. +`променен модул/символ -> статичен потребител -> кандидат-тест на сроден модул`, когато кандидат- +тестът липсва от разликите в pull request-а. Markdown обобщението и JSON резултатът се съхраняват като +артефакта `forgotten-sibling-tests` на работния процес за калибриране преди евентуално въвеждане като блокираща проверка. -Barrel реекспортите и динамичните импорти служат само за диагностика на резолюцията; те никога не създават +Barrel реекспортите и динамичните импорти служат само за диагностика на разрешаването; те никога не създават блокираща констатация. Прегледаните изключения се намират в -`config/quality/forgotten-sibling-allowlist.json`. Всеки запис трябва да посочва потребителя и кандидат-теста, -да предоставя конкретна обосновка и да съдържа връзка към GitHub issue или pull request. Неправилно форматираните записи водят -до отказ по подразбиране. Изключенията не могат да потиснат изтрит кандидат-тест или diff, който добавя `.skip`/`.todo`; -отслабването на твърденията и другите форми на прикриване остават отговорност на независимо блокиращата -проверка `check:test-masking`. +`config/quality/forgotten-sibling-allowlist.json`. Всеки запис трябва да посочва потребителския и кандидатстващия +тест, да съдържа конкретна обосновка и връзка към GitHub issue или pull request. Неправилно форматираните записи водят +до отказ по подразбиране. Изключенията не могат да потиснат изтрит кандидатстващ тест или diff, който добавя `.skip`/`.todo`; +отслабването на проверки и другите форми на прикриване остават отговорност на независимо блокиращия +контролен механизъм `check:test-masking`. ### Задача: `lint` Изпълнява се при всеки PR към `main`. Блокира сливането при неуспех. -| Скрипт (`npm run ...`) | Проверява | Блокираща | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `check:node-runtime` | Версията на Node.js е в поддържания диапазон | Да | -| `check:cycles` | Циклични импорти — всички модули в `src/` + `open-sse/` | Да | -| `check:route-validation:t06` | Наличие на Zod схеми във всички маршрути (политика от ниво 6) | Да | -| `check:any-budget:t11` | Броят на `@ts-expect-error // any` не надвишава бюджета (catraca от ниво 11) | Да | -| `check:provider-consistency` | Всеки доставчик в `providers.ts` има съответстващ запис в `providerRegistry.ts` (и обратно, в рамките на списъка с разрешени стойности) | Да | -| `check:model-lifecycle` | Трите ръчно поддържани таблици за маршрутизиране остават съгласувани с включената в хранилището моментна снимка на жизнения цикъл (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не оценява нито един изведен от употреба идентификатор, който `REGISTRY` може да маршрутизира; всяка цел на `BUILT_IN_ALIASES` присъства в `REGISTRY` и отсъства от моментната снимка на изведените от употреба идентификатори; всеки изведен от употреба идентификатор, който все още е в `REGISTRY`, се препраща или е посочен в `allowedRetiredInCatalog`; и нито един източник или цел в `DEFAULT_DEGRADATION_MAP` не е отбелязан като изведен от употреба в тази моментна снимка. Това не доказва, че даден модел в момента се обслужва от активна външна услуга. Офлайн — сравнява с `config/quality/model-lifecycle.json`, обновяван ръчно чрез `npm run quality:refresh-model-lifecycle` (изисква мрежа; не е интегрирано в CI). `allowedRetiredInCatalog` е механизъм за постепенно намаляване: добавяйте запис само при наличие на задача за проследяване. | Да | -| `check:fetch-targets` | Всяко `fetch("/api/...")` в клиентската част на `src/` се съпоставя с реален `route.ts` | Да | -| `check:deps` | Всички зависимости, които могат да бъдат инсталирани чрез `npm install`, във всеки `package.json` в хранилището присъстват в `dependency-allowlist.json`; новите зависимости без фиксирана версия или пакетите с имена, имитиращи популярни пакети, се маркират | Да | -| `audit:deps` | `npm audit` (основна директория + electron) — няма предупреждения с висока/критична тежест (припокрива се с osv `check:vuln-ratchet`; вижте списъка със задачи за рационализиране) | Да | -| `check:lockfile` | Цялост на `package-lock.json` — регистър по https, хешове за цялост, без замествания на хоста | Да | -| `check:licenses` | Списък с разрешени SPDX лицензи за производствени зависимости | Да | -| `check:tracked-artifacts` | Без артефакти от компилация / включени в хранилището символни връзки към `node_modules` (изпълнява се и в husky pre-commit; pre-push умишлено е олекотен — #6716) | Да | -| `check:ai-attribution` | Без завършващ ред `Co-Authored-By` за AI/бот или бележка за генериране от AI в commit-ите, заглавието или описанието на PR — Строго правило #16 (в цикъла за бързи проверки на `quality.yml` за PR→`release/**` — прочита payload-а на събитието и не извършва действие извън PR — и стъпка само за PR в lint на `ci.yml` за PR→`main`; също и hook-ът `commit-msg` на husky; разрешени са човешки съавтори; #14436) | -| `check:vitest-exclusions` | Всяко изключение на Vitest посочва issue за проследяване и присъства в `config/quality/vitest-exclusions.json` (#13204) | Да | -| `check:file-size` | Никой файл с изходен код не надвишава ограничението за съответното разширение (ratchet: фиксирани големи файлове в списъка `frozen`) | Да | -| `check:error-helper` | Отговорите за грешки в изпълнителите/обработчиците използват `buildErrorBody()` / `sanitizeErrorMessage()` (Строго правило #12) | Да | -| `check:migration-numbering` | SQL файловете за миграции са номерирани последователно, без пропуски или дубликати | Да | -| `check:public-creds` | Няма литерални OAuth `client_id`/`client_secret` или Firebase Web ключове извън `publicCreds.ts` (Строго правило №11) | Да | -| `check:db-rules` | Няма необработен SQL извън модулите в `src/lib/db/`; няма обобщаващи импорти от `localDb.ts` (Строги правила №2/№5) | Да | -| `check:known-symbols` | Изпълнителите на доставчици, стратегиите за маршрутизиране и транслаторите, регистрирани в съответните им таблици за диспечиране, съответстват на файловете на диска — няма осиротели или недекларирани символи | Да | -| `check:route-guard-membership` | Всеки маршрут, който стартира дъщерен процес, е класифициран чрез `isLocalOnlyPath()` (Строги правила №15/№17) | Да | -| `check:test-discovery` | Всеки файл `*.test.ts` / `*.spec.ts` в хранилището се открива от поне един механизъм за изпълнение на тестове (ratchet: списъкът с осиротели файлове в `test-discovery-baseline.json` може само да намалява) | Да | -| `check:agent-skills-sync` | Генерираните артефакти за agent-skills съответстват на изходния им каталог (без разминаване) | -| `check:provider-asset-provenance` | Логата/ресурсите на доставчиците имат запис за произход | -| `lint:json` | JSON конфигурационните файлове се анализират успешно и отговарят на правилата за lint на хранилището | -| `typecheck:core` | Компилиране на TypeScript без грешки (само консултативни предупреждения) | Да | -| `typecheck:noimplicit:core` | Строг `noImplicitAny` — с поглед към бъдещето; много съществуващи места на извикване все още се нуждаят от анотации | **Консултативно** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, ограничен до `src/app/(dashboard)/**` (#7033) — подбраният списък с 27 файла за разрешаване на `typecheck:core` не включва нито един dashboard TSX файл, а `next build` също никога не извършва проверка на типовете му (`next.config.mjs` задава `ignoreBuildErrors: true`), така че регресиите с несвързани идентификатори там (#6625/#6909) оставаха невидими за CI. Сравнява със замразена базова линия на броя по файл/TS код (`config/quality/dashboard-typecheck-baseline.json`, същият модел за налагане при остаряване като при `check:known-symbols`) — само НОВИ грешки над броя в базовата линия водят до неуспешно преминаване на контролата; намалявайте постепенно с `--update`, когато съществуваща грешка бъде поправена. | Да | +| Скрипт (`npm run ...`) | Проверява | Блокиращ | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:node-runtime` | Версията на Node.js е в поддържания диапазон | Да | +| `check:cycles` | Циклични импорти в целите `src/` + `open-sse/` (базирано на AST, с разрешени `paths` от tsconfig). Самостоятелното изпълнение е с препоръчителен характер и извежда списък с циклите. `check:cycles:ratchet` (изпълняваното от CI) блокира, когато броят надвиши тавана `metrics.cycles` в `quality-baseline.json` — понастоящем 14, `direction: down`, така че може само да намалява (#15159 G-01/G-02) | Да (ratchet) | +| `check:route-validation:t06` | Наличие на Zod схеми във всички маршрути (политика от ниво 6) | Да | +| `check:any-budget:t11` | Броят на `@ts-expect-error // any` не надвишава бюджета (catraca от ниво 11) | Да | +| `check:provider-consistency` | Всеки доставчик в `providers.ts` има съответстващ запис в `providerRegistry.ts` (и обратно, в рамките на списъка с разрешени стойности) | Да | +| `check:model-lifecycle` | Трите ръчно поддържани таблици за маршрутизиране остават съгласувани със snapshot-а на жизнения цикъл, включен в хранилището (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не оценява нито един изведен от употреба id, който `REGISTRY` може да маршрутизира; всяка цел от `BUILT_IN_ALIASES` присъства в `REGISTRY` и отсъства от snapshot-а с изведени от употреба id; всеки изведен от употреба id, който все още е в `REGISTRY`, се пренасочва или е посочен в `allowedRetiredInCatalog`; и нито един източник или цел от `DEFAULT_DEGRADATION_MAP` не фигурира като изведен от употреба в този snapshot. Това не доказва, че даден модел в момента се обслужва от действаща външна услуга. Офлайн — сравнява с `config/quality/model-lifecycle.json`, обновяван ръчно чрез `npm run quality:refresh-model-lifecycle` (изисква мрежа; не е интегриран в CI). `allowedRetiredInCatalog` е поетапно затягащ се ограничител: добавяйте запис само при наличие на issue за проследяване. | Да | +| `check:fetch-targets` | Всеки `fetch("/api/...")` в клиентската част на `src/` се съпоставя с реален `route.ts` | Да | +| `check:deps` | Всички зависимости, които могат да бъдат инсталирани чрез `npm install`, във всеки `package.json` в хранилището присъстват в `dependency-allowlist.json`; новите пакети без фиксирана версия или със slopsquatted имена се маркират | Да | +| `audit:deps` | `npm audit` (основен проект + electron) — няма предупреждения с висока/критична тежест (припокрива се с osv `check:vuln-ratchet`; вижте списъка с натрупани задачи за рационализация) | Да | +| `check:lockfile` | Цялост на `package-lock.json` — https регистър, хешове за цялост, без замени на хостове | Да | +| `check:licenses` | Списък с разрешени SPDX лицензи за продукционните зависимости | Да | +| `check:tracked-artifacts` | Без артефакти от компилацията / включени в хранилището символни връзки към `node_modules` (изпълнява се и в husky pre-commit; pre-push умишлено е олекотен — #6716) | Да | +| `check:ai-attribution` | Без завършващ ред `Co-Authored-By` за ИИ/бот или бележка за генериране от ИИ в commit-ите, заглавието или описанието на PR — Строго правило №16 (в цикъла за бързи проверки на `quality.yml` за PR→`release/**` — прочита данните за събитието и не извършва операция извън PR — както и в стъпка само за PR в lint на `ci.yml` за PR→`main`; също и hook-ът `commit-msg` на husky; човешки съавтори са разрешени; #14436) | +| `check:vitest-exclusions` | Всяко изключение на Vitest посочва проследяващ issue и присъства в `config/quality/vitest-exclusions.json` (#13204) | Да | +| `check:file-size` | Никой файл с изходен код не надвишава ограничението за съответното разширение (ratchet: фиксирани големи файлове в списъка `frozen`) | Да | +| `check:error-helper` | Отговорите за грешки в изпълнители/обработчици използват `buildErrorBody()` / `sanitizeErrorMessage()` (Строго правило №12) | Да | +| `check:migration-numbering` | SQL файловете за миграции са номерирани последователно, без пропуски или дубликати | Да | +| `check:public-creds` | Няма буквално зададени OAuth `client_id`/`client_secret` или Firebase Web ключове извън `publicCreds.ts` (Строго правило №11) | Да | +| `check:db-rules` | Няма необработен SQL извън модулите в `src/lib/db/`; няма обобщаващи импорти от `localDb.ts` (Строги правила №2/№5) | Да | +| `check:known-symbols` | Изпълнителите на доставчици, стратегиите за маршрутизиране и преводачите, регистрирани в съответните им таблици за диспечиране, съвпадат с файловете на диска — няма осиротели или недекларирани символи | Да | +| `check:route-guard-membership` | Всеки маршрут, който стартира дъщерен процес, е класифициран чрез `isLocalOnlyPath()` (Строги правила №15/№17) | Да | +| `check:test-discovery` | Всеки файл `*.test.ts` / `*.spec.ts` в хранилището се открива от поне една програма за изпълнение на тестове (ограничителен механизъм: списъкът с осиротели файлове в `test-discovery-baseline.json` може само да намалява) | Да | +| `check:agent-skills-sync` | Генерираните артефакти за уменията на агентите съответстват на изходния им каталог (без разминавания) | +| `check:provider-asset-provenance` | Логата/ресурсите на доставчиците имат регистриран запис за произход | +| `lint:json` | JSON конфигурационните файлове се анализират успешно и отговарят на правилата за lint на хранилището | +| `typecheck:core` | Компилация на TypeScript без грешки (само консултативни предупреждения) | Да | +| `typecheck:noimplicit:core` | Строг `noImplicitAny` — с насоченост към бъдещето; много съществуващи места на извикване все още се нуждаят от анотации | **Консултативно** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, ограничен до `src/app/(dashboard)/**` (#7033) — подбраният списък с 27 файла на `typecheck:core` не включва нито един TSX файл на таблото, а `next build` също никога не извършва проверка на типовете му (`next.config.mjs` задава `ignoreBuildErrors: true`), така че регресиите с осиротели идентификатори там (#6625/#6909) оставаха невидими за CI. Сравнява със замразена базова линия за броя по файл/TS код (`config/quality/dashboard-typecheck-baseline.json`, същият модел за налагане при остаряване като при `check:known-symbols`) — само НОВИ грешки над броя в базовата линия водят до неуспех на проверката; намалявайте постепенно базовата линия с `--update`, когато съществуваща грешка бъде поправена. | Да | ### Задача: `quality-gate` Изпълнява се след `test-coverage`. Блокира сливането при неуспех. -| Скрипт | Проверява | Блокиращ | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -| `quality:collect` | Генерира `quality-metrics.json` (брой предупреждения от ESLint, покритие от обединения отчет на отделните части) | Да (преди ratchet) | -| `quality:ratchet` | Нито един показател в `quality-baseline.json` не се е влошил (предупреждения от ESLint ≤ базовото ниво; покритие ≥ базовото ниво) | Да | -| `check:duplication` | Дублирането на код (jscpd@4) не надвишава базовото ниво в `quality-baseline.json` | Да | -| `check:complexity` | Цикломатичната сложност на ниво файл не надвишава лимита (основните правила на ESLint `complexity` + `max-lines-per-function`) | Да | -| `check:cognitive-complexity` | Ratchet за когнитивна сложност (`eslint-plugin-sonarjs`) — отделно изпълнение на ESLint; CI изпълнява и двете обединено като една стъпка `check:complexity-ratchets` | Да | -| `check:dead-code` | Ratchet за неизползвани експорти/файлове (knip) не се влошава спрямо базовото ниво | Да | -| `check:compression-budget` | Бюджет за сравнителния тест на компресията — минималните прагове за спестени токени за всяка машина не трябва да се влошават | Да | -| `check:type-coverage` | Ratchet за процента типизиран код (`type-coverage`) не се влошава; до голяма степен включва `typecheck:noimplicit:core` | Да | -| `check:codeql-ratchet` | Броят на отворените предупреждения от CodeQL не се влошава (прочита се чрез `gh api`; коректно пропускане без токен) — за честотата на обновяване и ръчното задействане вижте „CodeQL ratchet“ по-долу | Да | +| Скрипт | Проверява | Блокиращ | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `quality:collect` | Генерира `quality-metrics.json` (брой предупреждения от ESLint, покритие от обединения отчет на шардовете) | Да (предшества ratchet) | +| `quality:ratchet` | Нито една метрика в `quality-baseline.json` не се е влошила (предупреждения от ESLint ≤ базовата стойност; покритие ≥ базовата стойност) | Да | +| `check:duplication` | Дублирането на код (jscpd@4) не надвишава базовата стойност в `quality-baseline.json` | Да | +| `check:complexity` | Цикломатичната сложност на ниво файл не надвишава лимита (основните правила на ESLint `complexity` + `max-lines-per-function`) | Да | +| `check:cognitive-complexity` | Ratchet за когнитивна сложност (`eslint-plugin-sonarjs`) — отделно изпълнение на ESLint; CI изпълнява и двете обединени като една стъпка `check:complexity-ratchets` | Да | +| `check:dead-code` | Ratchet за неизползвани експорти / файлове (knip) не се влошава спрямо базовата стойност | Да | +| `check:compression-budget` | Бюджет за бенчмарк на компресията — минималните стойности за спестени токени за всяка машина не трябва да се влошават | Да | +| `check:type-coverage` | Ratchet за процента типизиран код (`type-coverage`) не се влошава; до голяма степен обхваща `typecheck:noimplicit:core` | Да | +| `check:codeql-ratchet` | Броят на отворените предупреждения от CodeQL не се влошава (чете чрез `gh api`; коректно пропуска без токен) — за честотата на опресняване и ръчното задействане вижте „CodeQL ratchet“ по-долу | Да | ### Задача: `quality-extended` Цялата задача е препоръчителна (`continue-on-error: true`). Базираните на npm ratchet проверки се изпълняват -реално; външните скенери се инсталират чрез `gh release download` и се пропускат автоматично (exit 0), -когато съответният изпълним файл все още липсва. - -| Скрипт | Проверява | Блокиращ | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | -| `check:circular-deps` | Няма циклични зависимости (dpdm) | **Препоръчителен** | -| `check:bundle-size` | Размерът на пакета не надвишава лимита | **Препоръчителен** | -| `check:secrets` | Сканиране за тайни (gitleaks) — пропуска се, ако изпълнимият файл липсва | **Препоръчителен** | -| `check:vuln-ratchet` | Уязвимостите в зависимостите (osv-scanner) не се увеличават — пропуска се, ако изпълнимият файл липсва | **Препоръчителен** | -| `check:workflows` | Проверка на работните процеси (actionlint + zizmor); липсващи/повредени скенери, невалидни отчети или липсващо базово ниво за ratchet водят до неуспех със статус INCOMPLETE. Валидните констатации следват избраната строга/препоръчителна/ratchet политика | Изпълнението е задължително; zizmor ratchet блокира в CI | -| `check:openapi-breaking` | Нарушаващи съвместимостта промени в публичния API договор (`openapi.yaml`) спрямо базовия клон (oasdiff) — генерира `openapiBreaking=N`; пропуска се, ако oasdiff липсва или базовата спецификация не може да бъде намерена | **Препоръчителен** | +реално; външните скенери се инсталират чрез `gh release download` и се самопропускат (exit 0), +когато даден изпълним файл все още липсва. + +| Скрипт | Проверява | Блокиращ | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| `check:circular-deps` | Няма циклични зависимости (dpdm) | **Препоръчителен** | +| `check:bundle-size` | Размерът на пакета не надвишава лимита | **Препоръчителен** | +| `check:secrets` | Сканиране за тайни (gitleaks) — пропуска се, ако изпълнимият файл липсва | **Препоръчителен** | +| `check:vuln-ratchet` | Уязвимостите в зависимостите (osv-scanner) не се увеличават — пропуска се, ако изпълнимият файл липсва | **Препоръчителен** | +| `check:workflows` | Линтинг на работни процеси (actionlint + zizmor); липсващи/повредени скенери, невалидни отчети или липсваща базова стойност за ratchet водят до неуспех със статус INCOMPLETE. Валидните констатации следват избраната строга/препоръчителна/ratchet политика | Изпълнението е задължително; zizmor ratchet е блокиращ в CI | +| `check:openapi-breaking` | Несъвместими промени в публичния API договор (`openapi.yaml`) спрямо базовия клон (oasdiff) — генерира `openapiBreaking=N`; пропуска се, ако oasdiff липсва или базовата спецификация не може да бъде прочетена | **Препоръчителен** | ### Задача: `docs-sync-strict` @@ -169,49 +169,49 @@ Barrel реекспортите и динамичните импорти слу | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | `check:docs-all` | Мета-проверка, която изпълнява последователно 6-те подпроверки по-долу | Да | | ↳ `check:docs-sync` | Съгласуваност на версиите в CHANGELOG / OpenAPI / llm.txt | Да | -| ↳ `check:docs-counts` | Броевете в текста (брой доставчици, брой миграции и др.) са в рамките на прозореца за постепенно затягане спрямо реалните стойности | Да | +| ↳ `check:docs-counts` | Числата в текста (брой доставчици, брой миграции и т.н.) са в рамките на прозореца с еднопосочно затягане спрямо реалните стойности | Да | | ↳ `check:env-doc-sync` | Всяка променлива на средата в `.env.example` е документирана в таблица в документацията и обратно | Да | -| ↳ `check:deprecated-versions` | В документацията няма низове за оттеглени версии | Да | -| ↳ `check:doc-links` | Вътрешните markdown връзки в документацията сочат към реални файлове (формат `[text]`/`(path)`) | Да | +| ↳ `check:deprecated-versions` | В документацията няма низове с остарели версии | Да | +| ↳ `check:doc-links` | Вътрешните markdown връзки в документацията сочат към реални файлове (във формат `[text]`/`(path)`) | Да | | ↳ `check:fabricated-docs` | Маршрутите, променливите на средата, CLI командите, имената на hook-ове и файловите пътища, посочени в документацията, съществуват в кодовата база. Строга проверка чрез `--strict`; без флага неуспехът не е блокиращ. | Да (чрез `--strict` в CI) | -| `check:cli-i18n` | Низовете на CLI командите присъстват във всички i18n файлове за локали | Да | -| `check:openapi-coverage` | Спецификацията OpenAPI покрива поне постепенно повишаван минимален праг от реалните маршрути | Да | -| `check:openapi-security-tiers` | Анотациите за нивата на сигурност в `openapi.yaml` са съгласувани с класификациите в `routeGuard.ts` | **Препоръчителна** | +| `check:cli-i18n` | Низовете на CLI командите присъстват във всички файлове с i18n локали | Да | +| `check:openapi-coverage` | Спецификацията OpenAPI покрива поне постепенно повишавания минимален праг от реални маршрути | Да | +| `check:openapi-security-tiers` | Анотациите за нивата на сигурност в `openapi.yaml` са съгласувани с класификациите в `routeGuard.ts` | **Консултативно** | | `check:openapi-routes` | Всеки път в `openapi.yaml` съответства на реален `route.ts` (защита срещу халюцинации) | Да | -| `check:docs-symbols` | Всяка препратка към `/api/...` в `docs/**/*.md` съответства на реален `route.ts` (защита срещу халюцинации) | Да | -| `i18n translation drift` | Непреведени ключове във файловете за i18n локали — само предупреждение | **Препоръчителна** | +| `check:docs-symbols` | Всяко позоваване на `/api/...` в `docs/**/*.md` съответства на реален `route.ts` (защита срещу халюцинации) | Да | +| `i18n translation drift` | Непреведени ключове във файловете с i18n локали — само предупреждение | **Консултативно** | ### Задача: `i18n-ui-coverage` -| Скрипт | Проверява | Блокиращ | -| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `check-ui-keys-coverage` (вграден) | Покритието на UI i18n ключовете е ≥ 65% | Да | -| `check-ui-value-drift` (вграден) | Пренаписана английска **стойност** не оставя след себе си остарял превод | Да | -| `check-new-key-coverage` (вграден) | **Нов** английски ключ е преведен във всеки локал — маркер `__MISSING__:` се отхвърля | Да | -| `check-translation-ratio` | Делът на реалните преводи за всеки локал (еднакви с английския / заместващи / липсващи крайни ключове извън списъка с разрешени изключения) не трябва да надвишава `config/quality/i18n-translation-baseline.json` + допустимия толеранс | **Препоръчителна** | +| Скрипт | Проверява | Блокиращ | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `check-ui-keys-coverage` (вграден) | Покритието на UI i18n ключовете е ≥ 65% | Да | +| `check-ui-value-drift` (вграден) | Пренаписана английска **стойност** не оставя след себе си остарял превод | Да | +| `check-new-key-coverage` (вграден) | **Нов** английски ключ е преведен във всеки локал — маркерът `__MISSING__:` се отхвърля | Да | +| `check-translation-ratio` | Делът на реалните преводи за всеки локал (стойности, идентични с английските / заместители / липсващи стойности извън списъка с изключения) не трябва да надвишава `config/quality/i18n-translation-baseline.json` + допустимото отклонение | **Консултативно** | -Изисква `fetch-depth: 0` — проверката за разминаване на стойностите сравнява разликите в `en.json` спрямо базата на сливане. +Изисква `fetch-depth: 0` — проверката за отклонение на стойностите сравнява разликите в `en.json` спрямо общата база за сливане. #### `check-ui-value-drift` — проверка за остарели преводи -Улавя единствения тип i18n регресия, който останалите проверки структурно не могат да открият: английска стойност -е пренаписана, а преводите, създадени от _предишния_ английски текст, остават непроменени, така че -потребителите, които не използват английски, продължават да четат уверено формулиран, но вече неправилен текст. +Улавя единствената i18n регресия, която останалите проверки не могат да открият структурно: английска стойност +е пренаписана, а преводите, създадени от _предишния_ английски текст, остават, така че +потребителите, които не използват английски, продължават да четат уверено формулиран, но вече грешен текст. -Това действително достигна до продукционна версия. `oauthModal.googleOAuthWarning` беше пренаписан при добавянето на помощната -функция за вход в Antigravity (#5203); **39 от 43 локала** запазиха текст, който указваше на операторите да „копират -пълния URL адрес и да го поставят по-долу“ — процес, който не може да бъде завършен за този доставчик. Това остана -незабелязано до #8463, защото: +Това действително стигна до продукционна версия. `oauthModal.googleOAuthWarning` беше пренаписан при добавянето на помощната +функция за вход в Antigravity (#5203); **39 от 43 локала** запазиха текст, който казваше на операторите да „копират +целия URL адрес и да го поставят по-долу“ — процес, който не може да бъде завършен за този доставчик. Това +остана незабелязано до #8463, защото: -- `sync-ui-keys` попълва само ключове, които **липсват**, но никога такива, които са **остарели**; -- `check-ui-keys-coverage` отчита _наличието_ на ключа, така че остарелият превод се счита за покрит; +- `sync-ui-keys` добавя само ключове, които **липсват**, но никога такива, които са **остарели**; +- `check-ui-keys-coverage` отчита _наличието_ на ключа, затова остарелият превод се счита за покрит; - `check-translation-drift` следи огледалните копия на документацията в `docs/i18n//**.md` — - той никога не чете `src/i18n/messages/*.json`. Блокираща проверка в задачата `docs-sync-strict` след - повторното синхронизиране през 2026-09: редактирайте основен документ → `npm run i18n:run -- --files=` (на ниво раздел, бързо). + той никога не чете `src/i18n/messages/*.json`. Блокиращо в задачата `docs-sync-strict` след + повторната синхронизация през 2026-09: редактирайте основен документ → `npm run i18n:run -- --files=` (на ниво раздел, евтино). **Отчита разликите, без да разчита на базов файл.** Сравнява `en.json` в базата за сливане с работното дърво; за всеки ключ, чиято английска стойност е променена, всеки език, който все още съдържа -непроменен превод, се счита за остарял. Това умишлено **замразява вече съществуващия дълг** — разликата +непроменен превод, се счита за остарял. Това умишлено **замразява съществуващия дълг** — разликата не може да покаже от коя стара английска стойност произлиза отдавна съществуващ превод, затова проверката оценява само засегнатото от текущата промяна. Алтернативата (базов файл с хеш за всеки ключ) би изисквала генериран файл от ~600 KB, 3× по-голям от най-големия съществуващ базов файл, който би се променял при всяка i18n PR заявка. @@ -219,15 +219,15 @@ Barrel реекспортите и динамичните импорти слу Има два начина проверката да бъде удовлетворена: 1. актуализирайте засегнатите преводи или -2. задайте стойността им на `__MISSING__:` — тогава по време на изпълнение се предоставя коригираният английски текст - (`src/i18n/request.ts::deepMergeFallback`, #7258), а ключът се добавя към опашката за превод. +2. задайте ги като `__MISSING__:` — тогава по време на изпълнение се предоставя коригираният английски текст + (`src/i18n/request.ts::deepMergeFallback`, #7258), а ключът се поставя на опашка за превод. Ако **значението** на низа се е променило, предпочитайте **преименуване на ключа**: нов ключ не може да наследи остарял превод. Това е подходът, използван в #8463. ```bash npm run i18n:check-value-drift # строг режим (изпълняваният от CI) -npm run i18n:check-value-drift:warn # само отчет +npm run i18n:check-value-drift:warn # само доклад BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` @@ -236,43 +236,43 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ### Задача: `i18n` -Пълна матрица за валидиране на i18n (по една задача за всеки език). Цялата задача има препоръчителен характер. +Пълна матрица за валидиране на i18n (по една задача за всеки език). Цялата задача е препоръчителна. -| Скрипт | Валидира | Блокиране | -| ------------------------------- | ---------------------------------- | --------------------------------------------------------------- | -| `validate_translation.py quick` | Пълнотата на превода за всеки език | **Препоръчително** (`continue-on-error: true` за цялата задача) | +| Скрипт | Какво валидира | Блокираща | +| ------------------------------- | -------------------------------- | --------------------------------------------------------------- | +| `validate_translation.py quick` | Пълнота на превода за всеки език | **Препоръчителна** (`continue-on-error: true` за цялата задача) | ### Задача: `pr-test-policy` -Изпълнява се само при заявки за изтегляне. +Изпълнява се само за pull request заявки. -| Скрипт | Валидира | Блокиране | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | PR заявките, които променят продукционен код в `src/`, `open-sse/`, `electron/` или `bin/`, трябва да включват или актуализират тестове (Строго правило #8) | Да | -| `check:test-masking` | Променените тестови файлове не намаляват общия брой проверки и не добавят тавтологии `assert.ok(true)` | Да | -| `check:pr-evidence` | Описанието на PR заявката посочва доказателства от тестове/VPS за промяната (автоматизира Строго правило #18 чрез търсене в текста на PR заявката — ненадеждно, вижте списъка със задачи) | Да | +| Скрипт | Какво валидира | Блокираща | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | +| `check:pr-test-policy` | PR заявки, които променят производствен код в `src/`, `open-sse/`, `electron/` или `bin/`, трябва да включват или актуализират тестове (Твърдо правило №8) | Да | +| `check:test-masking` | Променените тестови файлове не намаляват общия брой проверки и не добавят тавтологии `assert.ok(true)` | Да | +| `check:pr-evidence` | Описанието на PR посочва доказателства от тестове/VPS за промяната (автоматизира Твърдо правило №18 чрез търсене в текста на PR — ненадеждно, вижте Backlog) | Да | ### Задача: `test-vitest` -Изпълнява се след `build`. При неуспех блокира сливането. +Изпълнява се след `build`. Блокира сливането при неуспех. -| Набор | Валидира | Блокиране | -| ---------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP сървър (110 инструмента), autoCombo, кеш — изпълнява се с vitest | Да | -| `test:vitest:ui` | Тестове на UI компоненти — изпълняват се с vitest | **Блокира** — вече съществуващите неуспешни тестове са изрично изключени във `vitest.config.ts`; новите неуспехи провалят задачата | +| Набор | Какво валидира | Блокираща | +| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP сървър (110 инструмента), autoCombo, кеш — vitest runner | Да | +| `test:vitest:ui` | Тестове на UI компоненти — vitest runner | **Блокираща** — съществуващите неуспешни тестове са изрично изключени във `vitest.config.ts`; новите неуспехи провалят задачата | ### Нощни работни процеси (планирани, препоръчителни) -Те се изпълняват по cron график (и чрез `workflow_dispatch`), но никога при PR заявки. Всички имат препоръчителен характер. +Те се изпълняват по cron график (и чрез `workflow_dispatch`), никога при PR заявки. Всички са препоръчителни. -| Работен процес | Валидира | Блокиране | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -| `nightly-property` | Тестове на свойства с fast-check, произволно начално число и голям брой изпълнения | **Препоръчително** | -| `nightly-resilience` | Проверка за нарастване на heap паметта, внедряване на хаотични откази, k6 тестове за натоварване/продължително натоварване | **Препоръчително** | -| `nightly-llm-security` | Защита срещу инжектиране с promptfoo (режим на блокиране) + garak сонди (пропускат се без тайна за доставчик) | **Препоръчително** | -| `nightly-schemathesis` | Размиващо тестване на OpenAPI договора (schemathesis) спрямо работещ OmniRoute чрез `docs/openapi.yaml` — открива нарушения на спецификацията / необработени грешки 500 (Фаза 8 B.4) | **Препоръчително** | -| `nightly-mutation` | Оценка от мутационно тестване със Stryker върху бързата линия за модулни тестове — оцелелите мутанти разкриват слаби проверки | **Препоръчително** | -| `nightly-compat` | Матрица за съвместимост с Node engine във всички поддържани диапазони на `engines.node` | **Препоръчително** | +| Работен процес | Какво валидира | Блокиращ | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `nightly-property` | fast-check тестове на свойства със случайно начално състояние + голям брой изпълнения | **Препоръчителен** | +| `nightly-resilience` | проверка за нарастване на heap паметта, инжектиране на хаотични повреди, k6 тестове за натоварване/продължително натоварване | **Препоръчителен** | +| `nightly-llm-security` | promptfoo защита срещу инжектиране (режим на блокиране) + garak сонди (пропускат се без тайна за доставчик) | **Препоръчителен** | +| `nightly-schemathesis` | fuzz тестване на OpenAPI договора (schemathesis) спрямо работещ OmniRoute чрез `docs/openapi.yaml` — открива нарушения на спецификацията / необработени грешки 500 (Фаза 8 B.4) | **Препоръчителен** | +| `nightly-mutation` | резултат от мутационно тестване със Stryker върху бързия набор от модулни тестове — оцелелите мутанти разкриват слаби проверки | **Препоръчителен** | +| `nightly-compat` | матрица за съвместимост на Node engine във всички поддържани диапазони на `engines.node` | **Препоръчителен** | --- @@ -536,43 +536,44 @@ Job-ът никога не прави push към `release/*` — човек mer --- -## Списък за рационализация (преглед на ROI — Фаза 9 Вълна 3) +## Натрупани задачи за рационализиране (преглед на ROI — Фаза 9, Вълна 3) -Този опис беше съгласуван с `ci.yml` на 2026-06-17 (предишната версия пропускаше +Този инвентар беше съпоставен с `ci.yml` на 2026-06-17 (в предходната версия бяха пропуснати `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Прегледът на ROI на съгласувания набор -идентифицира следните кандидати за рационализация. **Обединяванията са механични промени -по CI; превключванията/премахванията са решения по правилата, запазени за оператора.** Нищо -от посоченото по-долу все още не е приложено. - -**Също недокументирани по-горе** (препоръчителни, слаб сигнал): задачата `docs-lint` -(markdownlint + Vale, цялата задача е с `continue-on-error`) и самостоятелните работни процеси за сканиране -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` присъства в -`quality-baseline.json`, но не е свързано с блокиращ ограничител в `ci.yml` — метриката -в момента е изолирана. - -### Обединяване / премахване на дублирането (механично, с по-нисък риск) - -Всеки кандидат беше валидиран спрямо актуалното състояние на проверките на 2026-06-17 (доверявай се, но проверявай); -няколко „очевидни“ обединявания се оказаха прикриващи технически дълг и **не** могат да бъдат директно приложени. - -- **`check:docs-sync` се изпълнява два пъти** — самостоятелно в задачата `lint` и отново в `check:docs-all` (`docs-sync-strict`), както и в pre-commit куката на husky. ✅ **ГОТОВО** — самостоятелното извикване в `lint` е премахнато. -- **Сканиране за CVE** — ❌ **НЕ е подходящо за директно обединяване.** `audit:deps` приключва с грешка при всяка CVE с висока/критична тежест; `check:vuln-ratchet` (osv) се проваля само при _регресия_ спрямо базовото ниво (в момента 1 MODERATE). Семантиките са различни — премахването на `audit:deps` би премахнало абсолютната проверка за висока/критична тежест. Запазете и двете. -- **Откриване на цикли** — ❌ **НЕ е подходящо за директно обединяване.** `check:circular-deps` (dpdm) отчита **91 цикъла** (затова е препоръчителна проверка); тя не може да бъде направена блокираща, без те първо да бъдат отстранени, и има по-широк обхват от успешната, внимателно подбрана `check:cycles`. Запазете `check:cycles` като блокираща; отстраняването на 91-те цикъла на dpdm е самостоятелна задача. -- **Сложност** — ✅ **ГОТОВО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): едно обхождане с ESLint, броене по ruleId, така че базовите нива за цикломатична сложност + максимален брой редове и когнитивна сложност да останат независими; отделните `check:complexity` / `check:cognitive-complexity` се запазват за локално изпълнение с `--update`. -- **Защита срещу халюцинации за `/api`** — ✅ **ГОТОВО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): един опис на файловата система за `src/app/api`, като openapi-routes + docs-symbols продължават да докладват независимо; отделните проверки се запазват за локално изпълнение. -- **`check:node-runtime` се изпълнява в 11 задачи** — ⚠️ **ниска ROI.** Всяка е на отделен runner и проверката отнема <1s; общото спестяване е ~10s, срещу загубата на евтина защита за всяка задача. Не си струва сътресението. -- **`typecheck:noimplicit:core` в CI lint** — ✅ **премахнато от задачата lint** (беше препоръчителна проверка с `continue-on-error`); блокиращата повърхност за типовете е `typecheck:core` + `check:type-coverage`. Локалният скрипт е запазен. +`check:codeql-ratchet`, `check:pr-evidence`). Прегледът на ROI на съпоставения набор +идентифицира следните кандидати за рационализиране. **Обединяванията са механични промени +по CI; превключванията/премахванията са решения относно правилата, запазени за оператора.** +Нищо от посоченото по-долу все още не е приложено. + +**Също недокументирани по-горе** (консултативни, със слаб сигнал): задачата `docs-lint` +(markdownlint + Vale, цялата задача е с `continue-on-error`) и самостоятелните работни процеси +за сканиране `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` присъства в +`quality-baseline.json`, но не е свързана с блокиращ ограничител в `ci.yml` — понастоящем +метриката е осиротяла. + +### Обединяване / дедупликация (механично, по-нисък риск) + +Всеки кандидат беше валидиран спрямо актуалното състояние на проверките на 2026-06-17 +(доверявай се, но проверявай); оказа се, че няколко „очевидни“ обединявания прикриват +натрупани проблеми и **не** са директни заместители. + +- **`check:docs-sync` се изпълнява два пъти** — самостоятелно в задачата `lint` и отново в `check:docs-all` (`docs-sync-strict`), както и в husky pre-commit hook. ✅ **ГОТОВО** — самостоятелното извикване в `lint` е премахнато. +- **Сканиране за CVE** — ❌ **НЕ е чисто обединяване.** `audit:deps` прекратява с грешка при всяка CVE с висока/критична тежест; `check:vuln-ratchet` (osv) се проваля само при _регресия_ спрямо базовата стойност (в момента 1 MODERATE). Семантиката е различна — премахването на `audit:deps` би премахнало абсолютната проверка за висока/критична тежест. Запазете и двете. +- **Откриване на цикли** — ✅ **ГОТОВО** (#15159 G-01/G-02). Старият текст тук наричаше `check:cycles` „зелената, курирана“ проверка и обосноваваше запазването ѝ като блокираща с това, че `check:circular-deps` (dpdm) отчита 91 цикъла. Този зелен резултат беше **фалшиво зелен**: `check:cycles` сканираше 5 поддиректории (450 файла), съпоставяше само статични `import|export … from` и отхвърляше всеки спецификатор `@/` и `@omniroute/open-sse/`, така че не можеше да види циклите с динамичен импорт и псевдоними, които преобладаваха в хранилището. Поправено: проверката вече обхожда `src` + `open-sse` (5023 файла), събира спецификатори от TypeScript AST (така `import("…")` се отчита, а `typeof import("…")` в позиция на тип — не) и разрешава `paths` от tsconfig. Тя намира **14** цикъла, а не 0. Тъй като 14-те съществуващи цикъла не могат да бъдат поправени в PR за проверката, `check:cycles` вече е **ограничител** (`--ratchet`, таван `metrics.cycles.value = 14` в `quality-baseline.json`, `direction: down`) — блокира всяка _регресия_ и броят може само да намалява. CI изпълнява `npm run check:cycles:ratchet`. Постепенното намаляване върви с **A-01**. `check:circular-deps` (dpdm) остава консултативна като по-широко второ мнение. +- **Сложност** — ✅ **ГОТОВО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): едно обхождане с ESLint, броене по ruleId, така че базовите стойности за цикломатична сложност + максимален брой редове и когнитивна сложност да останат независими; отделните `check:complexity` / `check:cognitive-complexity` се запазват за локално `--update`. +- **Защита срещу халюцинации за `/api`** — ✅ **ГОТОВО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): един FS инвентар на `src/app/api`, openapi-routes + docs-symbols продължават да докладват независимо; отделните проверки се запазват за локални изпълнения. +- **`check:node-runtime` се изпълнява в 11 задачи** — ⚠️ **нисък ROI.** Всяка е на отделен runner и проверката отнема <1s; общото спестяване е ~10s, за сметка на загубата на евтина защита за всяка задача. Не си струва сътресението. +- **`typecheck:noimplicit:core` в CI lint** — ✅ **премахната от задачата lint** (беше консултативна с `continue-on-error`); блокиращата повърхност за типовете е `typecheck:core` + `check:type-coverage`. Локалният скрипт е запазен. ### Превключване / решение (правила на оператора) -- `check:openapi-security-tiers` (препоръчителна) — ❌ **НЕ може да бъде директно превключена.** Завършва с код 0, но предупреждава, че на няколко маршрута на `traffic-inspector` под `LOCAL_ONLY_API_PREFIXES` липсва анотацията `x-loopback-only: true`. Налагането ѝ изисква първо добавяне на тези анотации в `openapi.yaml`. -- `typecheck:noimplicit:core` (препоръчителна) — до голяма степен е покрита от блокиращия ограничител `check:type-coverage`. Превключете я към ограничител или премахнете излишното второ изпълнение на `tsc`. -- `test:vitest:ui` (вече **блокираща**) — съществуващите отпреди грешки са изрично изключени във `vitest.config.ts` с проследяващи коментари `// #8618`; новите грешки провалят задачата. -- `check:secrets` (gitleaks, блокиращ ограничител, замразен на 3 документирани фалшиво положителни резултата) — добавете трите в списъка с позволени, за да достигнете 0, или понижете проверката до препоръчителна. Припокрива се с вграденото сканиране за тайни на GitHub + `check:public-creds`. -- `check:pr-evidence` (блокираща, търси чрез grep в прозата на тялото на PR) — висок риск от фалшиво положителни резултати; премахването ѝ отслабва прилагането на строго правило №18, така че това е реално решение по правилата. -- `semgrep` (самостоятелна препоръчителна проверка) — припокрива се с CodeQL за категориите на OWASP; свържете базовото ѝ ниво с ограничител или я премахнете. +- `check:openapi-security-tiers` (консултативна) — ❌ **НЕ може да бъде чисто превключена.** Завършва с код 0, но предупреждава, че няколко маршрута на `traffic-inspector` под `LOCAL_ONLY_API_PREFIXES` нямат анотацията `x-loopback-only: true`. Налагането ѝ изисква първо тези анотации да бъдат добавени в `openapi.yaml`. +- `typecheck:noimplicit:core` (консултативна) — до голяма степен е покрита от блокиращия ограничител `check:type-coverage`. Превключете я към ограничител или премахнете излишното второ изпълнение на `tsc`. +- `test:vitest:ui` (вече **блокираща**) — съществуващите неуспешни тестове са изрично изключени във `vitest.config.ts` с проследяващи коментари `// #8618`; новите неуспешни тестове провалят задачата. +- `check:secrets` (gitleaks, блокиращ ограничител, фиксиран на 3 документирани фалшиво положителни резултата) — добавете трите към allowlist, за да достигне 0, или я понижете до консултативна. Припокрива се с вграденото сканиране на тайни в GitHub + `check:public-creds`. +- `check:pr-evidence` (блокираща, търси чрез grep в прозата на тялото на PR) — висок риск от фалшиво положителни резултати; премахването ѝ отслабва прилагането на Hard Rule #18, така че това е реално решение относно правилата. +- `semgrep` (самостоятелна консултативна) — припокрива се с CodeQL за категориите на OWASP; свържете базовата ѝ стойност с ограничител или я премахнете. --- diff --git a/docs/i18n/bn/CONTRIBUTING.md b/docs/i18n/bn/CONTRIBUTING.md index 306b5911076..16d682b42b5 100644 --- a/docs/i18n/bn/CONTRIBUTING.md +++ b/docs/i18n/bn/CONTRIBUTING.md @@ -387,20 +387,20 @@ docs/ # Documentation ## পুল রিকোয়েস্ট চেকলিস্ট -- [ ] টেস্টসমূহ পাস করে (`npm test`) +- [ ] টেস্ট পাস করে (`npm test`) - [ ] লিন্টিং পাস করে (`npm run lint`) - [ ] বিল্ড সফল হয় (`npm run build`) - [ ] নতুন পাবলিক ফাংশন ও ইন্টারফেসের জন্য TypeScript টাইপ যোগ করা হয়েছে - [ ] কোনো হার্ডকোড করা সিক্রেট বা ফলব্যাক মান নেই -- [ ] পাবলিক আপস্ট্রিম ক্রেডেনশিয়ালগুলো `resolvePublicCred()`-এর মাধ্যমে এম্বেড করা হয়েছে ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) দেখুন), কখনোই লিটারেল হিসেবে নয় -- [ ] ত্রুটির রেসপন্সগুলো `buildErrorBody()` / `sanitizeErrorMessage()`-এর মাধ্যমে রাউট করা হয় — রেসপন্স বডিতে কোনো অপরিশোধিত স্ট্যাক ট্রেস নেই ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) দেখুন) -- [ ] শেল কমান্ডগুলো (`exec` / `spawn`) রানটাইম মান স্ট্রিং ইন্টারপোলেশনের মাধ্যমে নয়, `env`-এর মাধ্যমে পাস করে +- [ ] পাবলিক আপস্ট্রিম ক্রেডেনশিয়াল `resolvePublicCred()`-এর মাধ্যমে এম্বেড করা হয়েছে ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) দেখুন), কখনোই লিটারেল হিসেবে নয় +- [ ] ত্রুটির রেসপন্স `buildErrorBody()` / `sanitizeErrorMessage()`-এর মাধ্যমে রাউট করা হয় — রেসপন্স বডিতে কোনো অপরিশোধিত স্ট্যাক ট্রেস নেই ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) দেখুন) +- [ ] শেল কমান্ড (`exec` / `spawn`) রানটাইম মান স্ট্রিং ইন্টারপোলেশনের মাধ্যমে নয়, `env`-এর মাধ্যমে পাস করে - [ ] সব ইনপুট Zod স্কিমা দিয়ে যাচাই করা হয়েছে -- [ ] ব্যবহারকারীর দৃশ্যমান পরিবর্তনের জন্য `changelog.d/{features|fixes|maintenance}/-.md`-এর অধীনে চেঞ্জলগ **ফ্র্যাগমেন্ট** যোগ করা হয়েছে ([`changelog.d/README.md`](./changelog.d/README.md) দেখুন) — সরাসরি `CHANGELOG.md` সম্পাদনা করবেন **না**; রিলিজের সময় ফ্র্যাগমেন্টগুলো একত্রিত করা হয় এবং PR-গুলোর মধ্যে কখনোই দ্বন্দ্ব হয় না +- [ ] ব্যবহারকারীর দৃশ্যমান পরিবর্তনের জন্য `changelog.d/{features|fixes|maintenance}/-.md`-এর অধীনে চেঞ্জলগ **ফ্র্যাগমেন্ট** যোগ করা হয়েছে ([`changelog.d/README.md`](./changelog.d/README.md) দেখুন) — `CHANGELOG.md` সরাসরি সম্পাদনা করবেন **না**; রিলিজের সময় ফ্র্যাগমেন্টগুলো একত্রিত করা হয় এবং PR-গুলোর মধ্যে কখনো দ্বন্দ্ব সৃষ্টি করে না - [ ] ডকুমেন্টেশন হালনাগাদ করা হয়েছে (প্রযোজ্য হলে) -- [ ] নতুন কোনো CodeQL / Secret-Scanning সতর্কতা খোলা হয়নি, অথবা প্রতিটি সতর্কতা প্রাসঙ্গিক `docs/security/` ডকুমেন্ট উল্লেখ করে কারিগরি যৌক্তিকতাসহ খারিজ করা হয়েছে -- [ ] যেসব রাউট চাইল্ড প্রসেস চালু করে (`/api/mcp/`, `/api/cli-tools/runtime/`), সেগুলো `src/server/authz/routeGuard.ts`-এ `isLocalOnlyPath()` হিসেবে শ্রেণিবদ্ধ করা হয়েছে — [কঠোর নিয়ম #15](docs/security/ROUTE_GUARD_TIERS.md) দেখুন -- [ ] কমিট মেসেজে কোনো `Co-Authored-By` ট্রেলার নেই — কমিটগুলো অবশ্যই কেবল রিপোজিটরি মালিকের Git পরিচয়ের অধীনে প্রদর্শিত হতে হবে (কঠোর নিয়ম #16) +- [ ] কোনো নতুন CodeQL / Secret-Scanning সতর্কতা খোলা হয়নি, অথবা প্রতিটি সতর্কতা প্রাসঙ্গিক `docs/security/` ডকুমেন্ট উল্লেখ করে কারিগরি যৌক্তিকতাসহ খারিজ করা হয়েছে +- [ ] চাইল্ড প্রসেস চালু করা রাউটগুলো (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts`-এ `isLocalOnlyPath()` হিসেবে শ্রেণিবদ্ধ করা হয়েছে — [কঠোর নিয়ম #15](docs/security/ROUTE_GUARD_TIERS.md) দেখুন +- [ ] কমিট মেসেজে AI/বটের `Co-authored-by` ট্রেলার নেই (কঠোর নিয়ম #16) — যেসব মানব সহযোগীর কাজ পুনর্ব্যবহার করা হয়েছে, তাঁদের স্ট্যান্ডার্ড `Co-authored-by: Name ` ট্রেলার দিয়ে কৃতিত্ব দেওয়া হয়েছে --- diff --git a/docs/i18n/bn/docs/architecture/QUALITY_GATES.md b/docs/i18n/bn/docs/architecture/QUALITY_GATES.md index 23a574b4779..b10c014124a 100644 --- a/docs/i18n/bn/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/bn/docs/architecture/QUALITY_GATES.md @@ -19,261 +19,253 @@ ### প্রার্থী গ্রহণ -CI এবং Quality Gates ওয়ার্কফ্লো প্রতিটি একটি স্থিতিশীল সিদ্ধান্ত প্রকাশ করে: `Gate / CI` এবং -`Gate / Quality`। এগুলোর সংস্করণযুক্ত গ্রহণ নীতিতে প্রতিটি আপস্ট্রিম জবকে -আবশ্যিক বা পরামর্শমূলক হিসেবে তালিকাভুক্ত করা হয়। প্রযোজ্য কোনো আবশ্যিক জব অবশ্যই সফল হতে হবে: +CI এবং Quality Gates ওয়ার্কফ্লো—প্রতিটি একটি স্থিতিশীল রায় প্রকাশ করে: `Gate / CI` এবং +`Gate / Quality`। এগুলোর সংস্করণযুক্ত গ্রহণনীতি প্রতিটি আপস্ট্রিম জবকে +আবশ্যিক বা পরামর্শমূলক হিসেবে তালিকাভুক্ত করে। প্রযোজ্য কোনো আবশ্যিক জবকে অবশ্যই সফল হতে হবে: অনুপস্থিত, বাতিল, এড়িয়ে যাওয়া, অপেক্ষমাণ এবং অজানা ফলাফল PASS প্রতিষ্ঠা করতে পারে না। একটি বৈধ -শুধু-ডক্স বা শুধু-ক্যাটালগ শ্রেণিবিন্যাস কোনো কোড লেনকে অপ্রযোজ্য করতে পারে; +শুধু-ডকস বা শুধু-ক্যাটালগ শ্রেণিবিন্যাস কোনো কোড লেনকে অপ্রযোজ্য করতে পারে; একটি খসড়া PR গ্রহণযোগ্য প্রার্থী নয়। একটি `hotfix` লেবেল প্রমাণের আবশ্যকতা মওকুফ করে না। উভয় ওয়ার্কফ্লোই PR এবং main/release ব্রাঞ্চে push, manual dispatch এবং -merge-group ইভেন্ট অন্তর্ভুক্ত করে। Push, dispatch এবং merge-group সম্পূর্ণ নির্বাচন চালায়। Fork -এবং merge group সেইসব জবের জন্য hosted runner ব্যবহার করে, যেগুলো অন্যথায় self-hosted +merge-group ইভেন্ট কভার করে। Push, dispatch এবং merge-group সম্পূর্ণ নির্বাচন চালায়। Fork +এবং merge group এমন জবগুলোর জন্য hosted runner ব্যবহার করে, যেগুলো অন্যথায় self-hosted runner নির্বাচন করে; রোলআউটের আগে পর্যাপ্ত hosted capacity যাচাই করতে হবে। প্রতিটি JSON রসিদ checked-out SHA, workflow run এবং attempt শনাক্ত করে। -CLI একটি checkout/event SHA অমিল প্রত্যাখ্যান করে। Workflow test-গুলো policy membership-কে +CLI একটি checkout/event SHA অমিল প্রত্যাখ্যান করে। Workflow test নীতির সদস্যপদকে verdict job-এর `needs` তালিকার সঙ্গে আবদ্ধ করে, যাতে কোনো নতুন বা অপসারিত lane নীরবে অদৃশ্য হতে না পারে। -রসিদগুলো তাদের নিজস্ব workflow কভার করে; publication, deployment অথবা বিদ্যমান কোনো +রসিদগুলো নিজেদের workflow কভার করে, publication, deployment অথবা বিদ্যমান advisory scanner-এর অভ্যন্তরীণ কার্যপ্রণালী নয়। Branch rule-এ উভয় check name সক্রিয় করা একটি পৃথক প্রশাসনিক পরিবর্তন; এই job-গুলো যোগ করলেই কোনো branch সুরক্ষিত হয় না। ### স্ট্যাটিক স্ক্যান ইনভেন্টরি -সংস্করণযুক্ত npm-alias inventory এবং static-scan membership -`config/quality/gate-manifest.json`-এ রয়েছে। `package.json`-এর বিপরীতে -script name এবং সঠিক command যাচাই করতে `npm run check:gate-manifest` চালান; সংযোজন, অপসারণ এবং -command drift local hook এবং CI-এর change-classification job উভয়কেই ব্যর্থ করে। -কোনো alias একটি workflow job, matrix instance বা test case নয়: এই সংখ্যাগুলোকে -বিনিময়যোগ্য হিসেবে উপস্থাপন করা যাবে না। - -নির্বাচিত alias-গুলো এক্সিকিউট না করেই পরিদর্শন করতে `npm run quality:scan -- --list` অথবা -`npm run quality:scan:fast -- --list` ব্যবহার করুন। Runner npm entrypoint চালায়, -তাই এর runtime (যেখানে কনফিগার করা আছে সেখানে Bun-সহ) সংরক্ষিত থাকে। -Manifest-এ এই profile-গুলোর বাইরের alias-গুলোকে পৃথকভাবে আহ্বানকৃত হিসেবে রেকর্ড করা হয়, এবং +সংস্করণযুক্ত npm-alias ইনভেন্টরি এবং static-scan সদস্যপদ +`config/quality/gate-manifest.json`-এ রয়েছে। `package.json`-এর বিপরীতে script name এবং সঠিক +command যাচাই করতে `npm run check:gate-manifest` চালান; সংযোজন, অপসারণ এবং +command drift—দুটিই local hook এবং CI-এর change-classification job-গুলোকে ব্যর্থ করে। +একটি alias কোনো workflow job, matrix instance বা test case নয়: এই সংখ্যাগুলোকে +পরস্পর বিনিময়যোগ্য হিসেবে উপস্থাপন করা যাবে না। + +নির্বাচিত alias-গুলো নির্বাহ না করে পরিদর্শন করতে `npm run quality:scan -- --list` অথবা `npm run quality:scan:fast -- --list` +ব্যবহার করুন। Runner-টি +npm entrypoint আহ্বান করে, তাই এর runtime (যেখানে কনফিগার করা আছে সেখানে Bun-সহ) অক্ষুণ্ণ থাকে। +Manifest-টি ওই profile-গুলোর বাইরের alias-গুলোকে আলাদাভাবে আহ্বান করা হয়েছে বলে নথিভুক্ত করে এবং read-only scan profile-এ maintenance command নিষিদ্ধ। -এই profile-গুলো শুধু static scan কভার করে। এগুলো product test, +এই profile-গুলো কেবল static scan কভার করে। এগুলো product test, coverage, packaging, external check অথবা কোনো প্রার্থীর সম্পূর্ণ release acceptance প্রত্যয়িত করে না। Workflow admission সংযুক্ত `config/quality/admission-policy.json` এবং `scripts/quality/admission-verdict.mjs` ব্যবহার করে। Release-observer profile-গুলো পৃথক থাকে; -এগুলোর প্রযোজ্য check এবং receipt স্বতন্ত্রভাবে পরিদর্শন করুন। নিচের গদ্য -inventory একটি রেফারেন্স, কোনো gate বাস্তবে চলেছে—তার প্রমাণ নয়। +এগুলোর প্রযোজ্য check এবং receipt স্বাধীনভাবে পরিদর্শন করুন। নিচের গদ্যধর্মী +ইনভেন্টরিটি একটি রেফারেন্স, কোনো gate সত্যিই চলেছে তার প্রমাণ নয়। Script-গুলো `scripts/check/` (policy gate) এবং `scripts/quality/` (ratchet engine)-এর অধীনে থাকে। -CI-এর নির্ভরযোগ্য উৎস হলো `.github/workflows/ci.yml`। +CI-এর নির্ভরযোগ্য মূল উৎস হলো `.github/workflows/ci.yml`। -### Release PR ফাস্ট-পাথ (`quality.yml`) +### Release PR দ্রুত-পথ (`quality.yml`) `.github/workflows/quality.yml` main/release PR, protected-branch -push, dispatch এবং merge group-এ CI-এর পরিপূরক হিসেবে কাজ করে। PR-গুলো path-filtered fast check ব্যবহার করে। স্থায়ীভাবে -নিষ্ক্রিয় duplicate build সরিয়ে দেওয়া হয়েছে; প্রকৃত build/package/boot check-গুলো CI-তে রয়ে গেছে। - -| Job | পরিধি | ব্লকিং | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `Docs Gates (fast-path)` | Docs/code PR; API docs ref এবং docs-all | হ্যাঁ | -| `Fast Quality Gates` | Code PR; static check, typecheck, dashboard typecheck, প্রভাবিত unit test | হ্যাঁ | -| `Forgotten sibling tests` | Code PR; পরিবর্তিত module থেকে static consumer এবং সম্ভাব্য sibling test ট্রেস করা হয়; barrel এবং dynamic-import path-গুলো referenced allowlist exception-সহ পরামর্শমূলক diagnostic হিসেবে রিপোর্ট করা হয় | **পরামর্শমূলক** | -| `Vitest (fast-path)` | Code PR; fast vitest suite | হ্যাঁ | -| `Unit Tests fast-path` | Code PR; 4-shard unit suite | হ্যাঁ | -| `No new ESLint warnings` | Code PR; suppression-aware lint guard | হ্যাঁ, fork-সহ | -| `Merge integrity (changelog + generated skills)` | Non-draft PR; changelog এবং generated skill sync | হ্যাঁ, fork-সহ | +push, dispatch এবং merge group-এ CI-কে সম্পূরক করে। PR-গুলো path-filtered fast check ব্যবহার করে। স্থায়ীভাবে +নিষ্ক্রিয় duplicate build সরিয়ে ফেলা হয়েছে; প্রকৃত build/package/boot check-গুলো CI-তে রয়ে গেছে। + +| জব | পরিধি | ব্লকিং | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `Docs Gates (fast-path)` | Docs/code PR; API docs ref এবং docs-all | হ্যাঁ | +| `Fast Quality Gates` | Code PR; static check, typecheck, dashboard typecheck, প্রভাবিত unit test | হ্যাঁ | +| `Forgotten sibling tests` | Code PR; পরিবর্তিত module থেকে static consumer এবং সম্ভাব্য sibling test পর্যন্ত অনুসরণ; barrel এবং dynamic-import path-গুলো পরামর্শমূলক diagnostic হিসেবে রিপোর্ট করা হয়, সঙ্গে উল্লেখিত allowlist exception | **পরামর্শমূলক** | +| `Vitest (fast-path)` | Code PR; দ্রুত vitest suite | হ্যাঁ | +| `Unit Tests fast-path` | Code PR; 4-shard unit suite | হ্যাঁ | +| `No new ESLint warnings` | Code PR; suppression-aware lint guard | হ্যাঁ, fork-সহ | +| `Merge integrity (changelog + generated skills)` | Non-draft PR; changelog এবং generated skill sync | হ্যাঁ, fork-সহ | #### ভুলে যাওয়া sibling test-এর রিপোর্ট `npm run check:forgotten-sibling-tests` test-impact map-এর পেছনের import resolver পুনরায় ব্যবহার করে। -প্রতিটি পরিবর্তিত production module-এর জন্য, pull-request diff-এ সম্ভাব্য -test অনুপস্থিত থাকলে এটি নির্ধারিত ক্রমে -`changed module/symbol -> static consumer -> candidate sibling test` chain রিপোর্ট করে। যেকোনো blocking rollout-এর আগে -ক্যালিব্রেশনের জন্য Markdown summary এবং JSON result-কে `forgotten-sibling-tests` -workflow artifact হিসেবে সংরক্ষণ করা হয়। - -ব্যারেল রি-এক্সপোর্ট এবং ডায়নামিক ইমপোর্ট কেবল রেজোলিউশন ডায়াগনস্টিক; এগুলো কখনোই -ব্লকিং ফাইন্ডিং তৈরি করে না। পর্যালোচিত ব্যতিক্রমগুলো -`config/quality/forgotten-sibling-allowlist.json`-এ থাকে। প্রতিটি এন্ট্রিতে কনজিউমার এবং ক্যান্ডিডেট -টেস্টের নাম, একটি নির্দিষ্ট যৌক্তিকতা এবং একটি GitHub ইস্যু বা পুল রিকোয়েস্টের লিংক থাকতে হবে। ত্রুটিপূর্ণ এন্ট্রি -থাকলে যাচাই ব্যর্থ হয়। কোনো ব্যতিক্রম মুছে ফেলা ক্যান্ডিডেট টেস্ট অথবা `.skip`/`.todo` যোগ করা কোনো ডিফকে -উপেক্ষা করতে পারে না; অ্যাসারশন দুর্বল করা এবং অন্যান্য মাস্কিং স্বতন্ত্রভাবে ব্লকিং -`check:test-masking` গেটের আওতায় থাকে। - -### জব: `lint` - -`main`-এ প্রতিটি PR-এর ক্ষেত্রে চলে। ব্যর্থ হলে মার্জ ব্লক করে। - -| স্ক্রিপ্ট (`npm run ...`) | যা যাচাই করে | ব্লকিং | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | Node.js সংস্করণ সমর্থিত সীমার মধ্যে আছে | হ্যাঁ | -| `check:cycles` | সার্কুলার ইমপোর্ট — সব `src/` + `open-sse/` মডিউল | হ্যাঁ | -| `check:route-validation:t06` | সব রুটে Zod স্কিমা উপস্থিত আছে (Tier 6 নীতি) | হ্যাঁ | -| `check:any-budget:t11` | `@ts-expect-error // any`-এর সংখ্যা নির্ধারিত বাজেট অতিক্রম করে না (Tier 11 catraca) | হ্যাঁ | -| `check:provider-consistency` | `providers.ts`-এর প্রতিটি provider-এর জন্য `providerRegistry.ts`-এ একটি সামঞ্জস্যপূর্ণ এন্ট্রি রয়েছে (এবং বিপরীতক্রমেও, allowlist-এর মধ্যে) | হ্যাঁ | -| `check:model-lifecycle` | হাতে রক্ষণাবেক্ষণ করা তিনটি routing table checked-in lifecycle snapshot (#11503)-এর সঙ্গে সামঞ্জস্যপূর্ণ থাকে: `FITNESS_TABLE` (`taskFitness.ts`) এমন কোনো retired id-কে স্কোর করে না, যেটিতে `REGISTRY` route করতে পারে; প্রতিটি `BUILT_IN_ALIASES` target `REGISTRY`-তে উপস্থিত এবং retired-id snapshot-এ অনুপস্থিত; `REGISTRY`-তে এখনও থাকা প্রতিটি retired id forward করা হয় অথবা `allowedRetiredInCatalog`-এ তালিকাভুক্ত থাকে; এবং কোনো `DEFAULT_DEGRADATION_MAP` source বা target ওই snapshot-এ retired হিসেবে উপস্থিত নয়। এটি প্রমাণ করে না যে কোনো model বর্তমানে live upstream দ্বারা পরিবেশিত হচ্ছে। Offline — `config/quality/model-lifecycle.json`-এর সঙ্গে তুলনা করে, যা `npm run quality:refresh-model-lifecycle` ব্যবহার করে হাতে refresh করা হয় (network; CI-এর সঙ্গে সংযুক্ত নয়)। `allowedRetiredInCatalog` হলো একটি burn-down ratchet: শুধু tracking issue থাকলেই একটি এন্ট্রি যোগ করুন। | হ্যাঁ | -| `check:fetch-targets` | client-side `src/`-এর প্রতিটি `fetch("/api/...")` একটি বাস্তব `route.ts`-এ resolve করে | হ্যাঁ | -| `check:deps` | repo-র প্রতিটি `package.json` জুড়ে `npm install`-যোগ্য সব dependency `dependency-allowlist.json`-এ রয়েছে; নতুন unpinned বা slopsquatted package চিহ্নিত করা হয় | হ্যাঁ | -| `audit:deps` | `npm audit` (root + electron) — কোনো high/critical advisory নেই (osv `check:vuln-ratchet`-এর সঙ্গে overlap করে; Rationalization Backlog দেখুন) | হ্যাঁ | -| `check:lockfile` | `package-lock.json`-এর integrity — https registry, integrity hash, কোনো host override নেই | হ্যাঁ | -| `check:licenses` | প্রোডাকশন ডিপেন্ডেন্সিগুলোর জন্য SPDX লাইসেন্স allowlist | হ্যাঁ | -| `check:tracked-artifacts` | কোনো বিল্ড artifact / কমিট করা `node_modules` symlink নেই (husky pre-commit-এও চলে; pre-push ইচ্ছাকৃতভাবে হালকা রাখা হয়েছে — #6716) | হ্যাঁ | -| `check:ai-attribution` | PR commit, title বা body-তে কোনো AI/bot `Co-Authored-By` trailer বা AI-generation footer নেই — কঠোর নিয়ম #16 (`quality.yml`-এর PR→`release/**`-এর fast-gates loop-এ — event payload পড়ে, PR না হলে কোনো কাজ করে না — এবং `ci.yml` lint-এ PR→`main`-এর জন্য শুধু-PR ধাপ; এছাড়াও husky `commit-msg` hook; মানব co-author অনুমোদিত; #14436) | -| `check:vitest-exclusions` | প্রতিটি Vitest exclusion-এ একটি tracking issue উল্লেখ করা থাকে এবং সেটি `config/quality/vitest-exclusions.json`-এ উপস্থিত থাকে (#13204) | হ্যাঁ | -| `check:file-size` | কোনো source file সংশ্লিষ্ট extension-এর সর্বোচ্চ সীমা অতিক্রম করে না (ratchet: `frozen` তালিকায় স্থিরীকৃত বড় file) | হ্যাঁ | -| `check:error-helper` | executor/handler-এ error response-এর জন্য `buildErrorBody()` / `sanitizeErrorMessage()` ব্যবহার করা হয় (কঠোর নিয়ম #12) | হ্যাঁ | -| `check:migration-numbering` | Migration SQL ফাইলগুলো ধারাবাহিকভাবে নম্বরযুক্ত, কোনো ফাঁক বা সদৃশ নম্বর নেই | হ্যাঁ | -| `check:public-creds` | `publicCreds.ts`-এর বাইরে কোনো আক্ষরিক OAuth `client_id`/`client_secret` বা Firebase Web কী নেই (কঠোর নিয়ম #11) | হ্যাঁ | -| `check:db-rules` | `src/lib/db/` মডিউলগুলোর বাইরে কোনো কাঁচা SQL নেই; `localDb.ts` থেকে কোনো ব্যারেল-ইমপোর্ট নেই (কঠোর নিয়ম #2/#5) | হ্যাঁ | -| `check:known-symbols` | যেসব প্রদানকারী নির্বাহক, রাউটিং কৌশল এবং অনুবাদক তাদের ডিসপ্যাচ টেবিলে নিবন্ধিত, সেগুলো ডিস্কে থাকা ফাইলগুলোর সঙ্গে মেলে—কোনো অনাথ বা অঘোষিত সিম্বল নেই | হ্যাঁ | -| `check:route-guard-membership` | চাইল্ড প্রসেস তৈরি করে এমন প্রতিটি রুট `isLocalOnlyPath()` দ্বারা শ্রেণিবদ্ধ (কঠোর নিয়ম #15/#17) | হ্যাঁ | -| `check:test-discovery` | রিপোজিটরির প্রতিটি `*.test.ts` / `*.spec.ts` ফাইল অন্তত একটি টেস্ট রানার দ্বারা সংগ্রহ করা হয় (র্যাচেট: `test-discovery-baseline.json`-এর অনাথ তালিকা কেবল ছোট হতে পারে) | হ্যাঁ | -| `check:agent-skills-sync` | জেনারেট করা agent-skills আর্টিফ্যাক্টগুলো তাদের সোর্স ক্যাটালগের সঙ্গে মেলে (কোনো বিচ্যুতি নেই) | -| `check:provider-asset-provenance` | Provider লোগো/অ্যাসেটের জন্য একটি রেকর্ডকৃত উৎস-তথ্য এন্ট্রি রয়েছে | -| `lint:json` | JSON কনফিগ ফাইলগুলো পার্স হয় এবং repo-এর lint নিয়ম পূরণ করে | -| `typecheck:core` | কোনো ত্রুটি ছাড়াই TypeScript কম্পাইলেশন (শুধু পরামর্শমূলক সতর্কতা) | হ্যাঁ | -| `typecheck:noimplicit:core` | কঠোর `noImplicitAny` — ভবিষ্যৎমুখী; আগে থেকে থাকা অনেক call site-এ এখনও annotation প্রয়োজন | **পরামর্শমূলক** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**`-এ সীমাবদ্ধ `tsc` (#7033) — `typecheck:core`-এর বাছাইকৃত 27-ফাইলের allowlist-এ কোনো dashboard TSX অন্তর্ভুক্ত নেই এবং `next build`-ও কখনো এটি type-check করে না (`next.config.mjs`-এ `ignoreBuildErrors: true` সেট করা আছে), তাই সেখানকার orphaned-identifier regression-গুলো (#6625/#6909) CI-তে অদৃশ্য ছিল। একটি স্থির করা প্রতি-ফাইল/প্রতি-TS-কোড ত্রুটি-সংখ্যার baseline-এর (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols`-এর মতো একই stale-enforcement প্যাটার্ন) বিপরীতে diff করা হয় — baselined সংখ্যার অতিরিক্ত শুধু নতুন ত্রুটিই gate-কে ব্যর্থ করে; আগে থেকে থাকা কোনো ত্রুটি ঠিক করা হলে `--update` দিয়ে baseline কমিয়ে আনুন। | হ্যাঁ | - -### Job: `quality-gate` - -`test-coverage`-এর পরে চলে। ব্যর্থ হলে merge ব্লক করে। - -| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -| `quality:collect` | `quality-metrics.json` তৈরি করে (ESLint সতর্কতার সংখ্যা, একীভূত শার্ড রিপোর্ট থেকে কভারেজ) | হ্যাঁ (ratchet-এর পূর্ববর্তী ধাপ) | -| `quality:ratchet` | `quality-baseline.json`-এর প্রতিটি মেট্রিকের অবনতি হয়নি (ESLint সতর্কতা ≤ বেসলাইন; কভারেজ ≥ বেসলাইন) | হ্যাঁ | -| `check:duplication` | কোডের অনুলিপি (jscpd@4) `quality-baseline.json`-এর বেসলাইন অতিক্রম করে না | হ্যাঁ | -| `check:complexity` | ফাইল-স্তরের সাইক্লোম্যাটিক জটিলতা সর্বোচ্চ সীমা অতিক্রম করে না (মূল ESLint `complexity` + `max-lines-per-function`) | হ্যাঁ | -| `check:cognitive-complexity` | কগনিটিভ জটিলতা ratchet (`eslint-plugin-sonarjs`) — পৃথক ESLint পাস; CI উভয়টিকে একীভূত করে একক `check:complexity-ratchets` ধাপ হিসেবে চালায় | হ্যাঁ | -| `check:dead-code` | অব্যবহৃত export / ফাইলের ratchet (knip) বেসলাইনের তুলনায় অবনতি ঘটায় না | হ্যাঁ | -| `check:compression-budget` | কম্প্রেশন বেঞ্চমার্ক বাজেট — প্রতিটি ইঞ্জিনের token-savings-এর ন্যূনতম সীমার অবনতি হওয়া যাবে না | হ্যাঁ | -| `check:type-coverage` | টাইপযুক্ত শতাংশের ratchet (`type-coverage`)-এর অবনতি হয় না; এটি মূলত `typecheck:noimplicit:core`-কে অন্তর্ভুক্ত করে | হ্যাঁ | -| `check:codeql-ratchet` | খোলা CodeQL সতর্কতার সংখ্যার অবনতি হয় না (`gh api`-এর মাধ্যমে পড়ে; token ছাড়া নির্বিঘ্নে এড়িয়ে যায়) — রিফ্রেশের সময়সূচি ও ম্যানুয়াল ট্রিগারের জন্য নিচের "CodeQL ratchet" দেখুন | হ্যাঁ | +প্রতিটি পরিবর্তিত production module-এর জন্য, সম্ভাব্য +test-টি pull-request diff-এ অনুপস্থিত থাকলে এটি নির্ধারিত ক্রমে +`changed module/symbol -> static consumer -> candidate sibling test` chain রিপোর্ট করে। যেকোনো blocking rollout-এর আগে calibration-এর জন্য +Markdown summary এবং JSON result `forgotten-sibling-tests` workflow artifact হিসেবে সংরক্ষিত থাকে। + +Barrel re-export এবং dynamic import কেবল resolution diagnostic; এগুলো কখনোই কোনো +blocking finding তৈরি করে না। পর্যালোচিত exception-গুলো +`config/quality/forgotten-sibling-allowlist.json`-এ থাকে। প্রতিটি entry-তে consumer এবং candidate +test-এর নাম, একটি সুনির্দিষ্ট rationale এবং একটি GitHub issue বা pull request-এর link থাকতে হবে। ত্রুটিপূর্ণ entry +fail closed করে। Exception কোনো মুছে ফেলা candidate test বা `.skip`/`.todo` যোগ করে এমন diff-কে suppress +করতে পারে না; assertion দুর্বল করা এবং অন্যান্য masking স্বাধীনভাবে blocking +`check:test-masking` gate-এর অধীনেই থাকে। + +### Job: `lint` + +`main`-এর প্রতিটি PR-এ চলে। ব্যর্থ হলে merge block করে। + +| Script (`npm run ...`) | যা যাচাই করে | Blocking | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | Node.js version সমর্থিত range-এর মধ্যে আছে | হ্যাঁ | +| `check:cycles` | `src/` + `open-sse/`-এর সব circular import (AST-ভিত্তিক, tsconfig `paths` resolve করা হয়)। Bare = advisory, cycle-গুলোর তালিকা দেয়। `check:cycles:ratchet` (যা CI চালায়) count `quality-baseline.json`-এর `metrics.cycles` ceiling অতিক্রম করলে block করে — বর্তমানে 14, `direction: down`, তাই এটি কেবল কমতে পারে (#15159 G-01/G-02) | হ্যাঁ (ratchet) | +| `check:route-validation:t06` | সব route-এ Zod schema উপস্থিত আছে (Tier 6 policy) | হ্যাঁ | +| `check:any-budget:t11` | `@ts-expect-error // any`-এর count budget অতিক্রম করে না (Tier 11 catraca) | হ্যাঁ | +| `check:provider-consistency` | `providers.ts`-এর প্রতিটি provider-এর জন্য `providerRegistry.ts`-এ একটি মিলে যাওয়া entry রয়েছে (এবং বিপরীতক্রমেও, allowlist-এর মধ্যে) | হ্যাঁ | +| `check:model-lifecycle` | হাতে রক্ষণাবেক্ষণ করা তিনটি routing table checked-in lifecycle snapshot-এর (#11503) সঙ্গে সামঞ্জস্যপূর্ণ থাকে: `FITNESS_TABLE` (`taskFitness.ts`) এমন কোনো retired id-কে score করে না, যেটিতে `REGISTRY` route করতে পারে; প্রতিটি `BUILT_IN_ALIASES` target `REGISTRY`-তে উপস্থিত এবং retired-id snapshot-এ অনুপস্থিত; `REGISTRY`-তে এখনও থাকা প্রতিটি retired id forwarded অথবা `allowedRetiredInCatalog`-এ তালিকাভুক্ত; এবং কোনো `DEFAULT_DEGRADATION_MAP` source বা target ওই snapshot-এ retired হিসেবে উপস্থিত নয়। এটি প্রমাণ করে না যে কোনো model বর্তমানে live upstream দ্বারা পরিবেশিত হচ্ছে। Offline — `config/quality/model-lifecycle.json`-এর সঙ্গে তুলনা করে, যা `npm run quality:refresh-model-lifecycle` দিয়ে হাতে refresh করা হয় (network; CI-এর সঙ্গে সংযুক্ত নয়)। `allowedRetiredInCatalog` একটি burn-down ratchet: কেবল tracking issue থাকলেই একটি entry যোগ করুন। | হ্যাঁ | +| `check:fetch-targets` | client-side `src/`-এর প্রতিটি `fetch("/api/...")` একটি বাস্তব `route.ts`-এ resolve হয় | হ্যাঁ | +| `check:deps` | repo-র প্রতিটি `package.json` জুড়ে `npm install`-যোগ্য সব deps `dependency-allowlist.json`-এ রয়েছে; নতুন unpinned বা slopsquatted package চিহ্নিত করা হয় | হ্যাঁ | +| `audit:deps` | `npm audit` (root + electron) — কোনো high/critical advisory নেই (osv `check:vuln-ratchet`-এর সঙ্গে overlap করে; Rationalization Backlog দেখুন) | হ্যাঁ | +| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hash, কোনো host override নেই | হ্যাঁ | +| `check:licenses` | প্রোডাকশন ডিপেন্ডেন্সিগুলোর জন্য SPDX লাইসেন্স অনুমোদন-তালিকা | হ্যাঁ | +| `check:tracked-artifacts` | কোনো বিল্ড আর্টিফ্যাক্ট / কমিট করা `node_modules` সিমলিংক নেই (husky pre-commit-এও চলে; pre-push ইচ্ছাকৃতভাবে হালকা — #6716) | হ্যাঁ | +| `check:ai-attribution` | PR কমিট, শিরোনাম বা বডিতে কোনো AI/bot `Co-Authored-By` ট্রেলার বা AI-জেনারেশন ফুটার নেই — কঠোর নিয়ম #16 (`quality.yml`-এর PR→`release/**`-এর fast-gates লুপে — event payload পড়ে, PR না হলে কোনো কাজ করে না — এবং `ci.yml` lint-এ PR→`main`-এর জন্য শুধু-PR ধাপ; এছাড়াও husky `commit-msg` hook; মানব সহ-লেখক অনুমোদিত; #14436) | +| `check:vitest-exclusions` | প্রতিটি Vitest exclusion-এ একটি tracking issue উল্লেখ থাকে এবং সেটি `config/quality/vitest-exclusions.json`-এ উপস্থিত থাকে (#13204) | হ্যাঁ | +| `check:file-size` | কোনো source file প্রতি-extension সীমা অতিক্রম করে না (ratchet: `frozen` তালিকায় স্থিরীকৃত বড় ফাইলসমূহ) | হ্যাঁ | +| `check:error-helper` | executors/handlers-এ error response-গুলো `buildErrorBody()` / `sanitizeErrorMessage()` ব্যবহার করে (কঠোর নিয়ম #12) | হ্যাঁ | +| `check:migration-numbering` | Migration SQL ফাইলগুলো কোনো ফাঁক বা সদৃশ নম্বর ছাড়াই ধারাবাহিকভাবে নম্বরযুক্ত | হ্যাঁ | +| `check:public-creds` | `publicCreds.ts`-এর বাইরে কোনো আক্ষরিক OAuth `client_id`/`client_secret` বা Firebase Web কী নেই (কঠোর নিয়ম #11) | হ্যাঁ | +| `check:db-rules` | `src/lib/db/` মডিউলের বাইরে কোনো সরাসরি SQL নেই; `localDb.ts` থেকে কোনো barrel-import নেই (কঠোর নিয়ম #2/#5) | হ্যাঁ | +| `check:known-symbols` | তাদের dispatch table-এ নিবন্ধিত provider executor, routing strategy এবং translator-গুলো ডিস্কের ফাইলগুলোর সঙ্গে মেলে—কোনো অনাথ বা অঘোষিত symbol নেই | হ্যাঁ | +| `check:route-guard-membership` | child process তৈরি করে এমন প্রতিটি route `isLocalOnlyPath()` দ্বারা শ্রেণিবদ্ধ (কঠোর নিয়ম #15/#17) | হ্যাঁ | +| `check:test-discovery` | repo-তে থাকা প্রতিটি `*.test.ts` / `*.spec.ts` ফাইল অন্তত একটি test runner দ্বারা সংগ্রহ করা হয় (ratchet: `test-discovery-baseline.json`-এর অনাথ তালিকা কেবল ছোট হতে পারে) | হ্যাঁ | +| `check:agent-skills-sync` | জেনারেট করা agent-skills আর্টিফ্যাক্টগুলো তাদের সোর্স ক্যাটালগের সঙ্গে মেলে (কোনো বিচ্যুতি নেই) | +| `check:provider-asset-provenance` | প্রোভাইডার লোগো/অ্যাসেটগুলোর জন্য নথিভুক্ত উৎস-তথ্যের এন্ট্রি রয়েছে | +| `lint:json` | JSON কনফিগ ফাইলগুলো সঠিকভাবে পার্স হয় এবং রিপোজিটরির লিন্ট নিয়ম পূরণ করে | +| `typecheck:core` | কোনো ত্রুটি ছাড়াই TypeScript কম্পাইলেশন (শুধু পরামর্শমূলক সতর্কতা) | হ্যাঁ | +| `typecheck:noimplicit:core` | কঠোর `noImplicitAny` — ভবিষ্যৎমুখী; আগে থেকে থাকা অনেক কল সাইটে এখনও অ্যানোটেশন প্রয়োজন | **পরামর্শমূলক** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**`-এ সীমাবদ্ধ `tsc` (#7033) — `typecheck:core`-এর বাছাইকৃত ২৭-ফাইলের অনুমোদিত তালিকায় কোনো ড্যাশবোর্ড TSX অন্তর্ভুক্ত নেই, এবং `next build`-ও কখনো এটির টাইপ পরীক্ষা করে না (`next.config.mjs`-এ `ignoreBuildErrors: true` সেট করা আছে), তাই সেখানে থাকা অনাথ-আইডেন্টিফায়ার রিগ্রেশনগুলো (#6625/#6909) CI-এর কাছে অদৃশ্য ছিল। একটি স্থিরীকৃত প্রতি-ফাইল/প্রতি-TS-কোড ত্রুটি-সংখ্যার বেসলাইনের (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols`-এর মতো একই অচলতা-প্রয়োগ প্যাটার্ন) সঙ্গে ডিফ করা হয় — বেসলাইনে থাকা সংখ্যার অতিরিক্ত শুধু নতুন ত্রুটিই গেটকে ব্যর্থ করে; আগে থেকে থাকা কোনো ত্রুটি সংশোধন হলে `--update` দিয়ে সীমা ধাপে ধাপে কমান। | হ্যাঁ | + +### জব: `quality-gate` + +`test-coverage`-এর পরে চলে। ব্যর্থ হলে মার্জ আটকে দেয়। + +| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `quality:collect` | `quality-metrics.json` তৈরি করে (ESLint সতর্কতার সংখ্যা, মার্জ করা শার্ড রিপোর্ট থেকে কভারেজ) | হ্যাঁ (র্যাচেটের পূর্ববর্তী ধাপ) | +| `quality:ratchet` | `quality-baseline.json`-এর প্রতিটি মেট্রিকের অবনতি হয়নি (ESLint সতর্কতা ≤ বেসলাইন; কভারেজ ≥ বেসলাইন) | হ্যাঁ | +| `check:duplication` | কোডের পুনরাবৃত্তি (jscpd@4) `quality-baseline.json`-এর বেসলাইন অতিক্রম করে না | হ্যাঁ | +| `check:complexity` | ফাইল-স্তরের সাইক্লোম্যাটিক জটিলতা নির্ধারিত সীমা অতিক্রম করে না (মূল ESLint `complexity` + `max-lines-per-function`) | হ্যাঁ | +| `check:cognitive-complexity` | কগনিটিভ জটিলতা র্যাচেট (`eslint-plugin-sonarjs`) — পৃথক ESLint পাস; CI উভয়টিকে একক `check:complexity-ratchets` ধাপ হিসেবে চালায় | হ্যাঁ | +| `check:dead-code` | অব্যবহৃত এক্সপোর্ট/ফাইলের র্যাচেট (knip) বেসলাইনের তুলনায় অবনতি ঘটায় না | হ্যাঁ | +| `check:compression-budget` | কম্প্রেশন বেঞ্চমার্ক বাজেট — প্রতিটি ইঞ্জিনের টোকেন-সাশ্রয়ের ন্যূনতম সীমার অবনতি হওয়া চলবে না | হ্যাঁ | +| `check:type-coverage` | টাইপযুক্ত শতাংশের র্যাচেট (`type-coverage`) অবনতি ঘটায় না; এটি মূলত `typecheck:noimplicit:core`-কে অন্তর্ভুক্ত করে | হ্যাঁ | +| `check:codeql-ratchet` | উন্মুক্ত CodeQL সতর্কতার সংখ্যা বৃদ্ধি পায় না (`gh api`-এর মাধ্যমে পড়ে; টোকেন না থাকলে সুষ্ঠুভাবে এড়িয়ে যায়) — রিফ্রেশের সময়সূচি ও ম্যানুয়াল ট্রিগার: নিচের "CodeQL ratchet" দেখুন | হ্যাঁ | ### জব: `quality-extended` -সম্পূর্ণ জবটি পরামর্শমূলক (`continue-on-error: true`)। npm-ভিত্তিক ratchet-গুলো -বাস্তবভাবে চলে; বাহ্যিক স্ক্যানারগুলো `gh release download`-এর মাধ্যমে ইনস্টল হয় এবং কোনো +সম্পূর্ণ জবটি পরামর্শমূলক (`continue-on-error: true`)। npm-ভিত্তিক র্যাচেটগুলো +প্রকৃতভাবে চলে; বাহ্যিক স্ক্যানারগুলো `gh release download`-এর মাধ্যমে ইনস্টল হয় এবং কোনো বাইনারি তখনও অনুপস্থিত থাকলে স্বয়ংক্রিয়ভাবে এড়িয়ে যায় (exit 0)। -| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:circular-deps` | কোনো চক্রাকার dependency নেই (dpdm) | **পরামর্শমূলক** | -| `check:bundle-size` | bundle-এর আকার সর্বোচ্চ সীমা অতিক্রম করে না | **পরামর্শমূলক** | -| `check:secrets` | secret স্ক্যানিং (gitleaks) — বাইনারি অনুপস্থিত থাকলে এড়িয়ে যায় | **পরামর্শমূলক** | -| `check:vuln-ratchet` | dependency-এর দুর্বলতা (osv-scanner) বৃদ্ধি পায় না — বাইনারি অনুপস্থিত থাকলে এড়িয়ে যায় | **পরামর্শমূলক** | -| `check:workflows` | workflow lint (actionlint + zizmor); অনুপস্থিত/বিকল স্ক্যানার, অবৈধ রিপোর্ট বা অনুপস্থিত ratchet বেসলাইন INCOMPLETE হিসেবে ব্যর্থ হয়। বৈধ ফলাফল নির্বাচিত strict/advisory/ratchet নীতি অনুসরণ করে | নির্বাহ আবশ্যক; CI-তে zizmor ratchet ব্লকিং | -| `check:openapi-breaking` | base branch-এর তুলনায় পাবলিক API contract (`openapi.yaml`)-এ ভঙ্গকারী পরিবর্তন (oasdiff) — `openapiBreaking=N` তৈরি করে; oasdiff অনুপস্থিত হলে বা base spec সমাধানযোগ্য না হলে এড়িয়ে যায় | **পরামর্শমূলক** | +| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:circular-deps` | কোনো চক্রাকার ডিপেন্ডেন্সি নেই (dpdm) | **পরামর্শমূলক** | +| `check:bundle-size` | বান্ডলের আকার নির্ধারিত সীমা অতিক্রম করে না | **পরামর্শমূলক** | +| `check:secrets` | গোপন তথ্য স্ক্যানিং (gitleaks) — বাইনারি অনুপস্থিত থাকলে এড়িয়ে যায় | **পরামর্শমূলক** | +| `check:vuln-ratchet` | ডিপেন্ডেন্সির দুর্বলতা (osv-scanner) বৃদ্ধি পায় না — বাইনারি অনুপস্থিত থাকলে এড়িয়ে যায় | **পরামর্শমূলক** | +| `check:workflows` | ওয়ার্কফ্লো লিন্ট (actionlint + zizmor); স্ক্যানার অনুপস্থিত/ত্রুটিপূর্ণ হলে, রিপোর্ট অবৈধ হলে বা র্যাচেট বেসলাইন অনুপস্থিত থাকলে INCOMPLETE হিসেবে ব্যর্থ হয়। বৈধ ফলাফল নির্বাচিত কঠোর/পরামর্শমূলক/র্যাচেট নীতি অনুসরণ করে | এক্সিকিউশন আবশ্যক; CI-তে zizmor র্যাচেট ব্লকিং | +| `check:openapi-breaking` | বেস ব্রাঞ্চের তুলনায় পাবলিক API কনট্র্যাক্টে (`openapi.yaml`) ব্রেকিং পরিবর্তন (oasdiff) — `openapiBreaking=N` নির্গত করে; oasdiff অনুপস্থিত থাকলে বা বেস স্পেক সমাধান করা না গেলে এড়িয়ে যায় | **পরামর্শমূলক** | ### জব: `docs-sync-strict` -`main`-এর প্রতিটি PR-এ চলে। ব্যর্থ হলে merge ব্লক করে। - -| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | -| `check:docs-all` | নিচের ৬টি সাব-গেট ধারাবাহিকভাবে চালানো মেটা-গেট | হ্যাঁ | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt সংস্করণের সামঞ্জস্য | হ্যাঁ | -| ↳ `check:docs-counts` | গদ্যে উল্লিখিত সংখ্যা (প্রোভাইডারের সংখ্যা, মাইগ্রেশনের সংখ্যা ইত্যাদি) প্রকৃত সংখ্যার র্যাচেট উইন্ডোর মধ্যে আছে | হ্যাঁ | -| ↳ `check:env-doc-sync` | `.env.example`-এর প্রতিটি env var একটি ডকুমেন্টেশন টেবিলে নথিভুক্ত আছে এবং বিপরীতটিও সত্য | হ্যাঁ | -| ↳ `check:deprecated-versions` | ডকুমেন্টেশনে কোনো অবচিত সংস্করণ স্ট্রিং নেই | হ্যাঁ | -| ↳ `check:doc-links` | ডকুমেন্টেশনের অভ্যন্তরীণ markdown লিংক বাস্তব ফাইলে রিজলভ করে (`[text]`/`(path)` ফর্ম) | হ্যাঁ | -| ↳ `check:fabricated-docs` | ডকুমেন্টেশনে উদ্ধৃত রুট, env var, CLI কমান্ড, হুকের নাম ও ফাইল পাথ কোডবেসে বিদ্যমান। `--strict`-এর মাধ্যমে হার্ড গেট; ফ্ল্যাগ ছাড়া সফট-ফেইল। | হ্যাঁ (CI-তে `--strict`-এর মাধ্যমে) | -| `check:cli-i18n` | CLI কমান্ডের স্ট্রিং সব i18n লোকেল ফাইলে উপস্থিত | হ্যাঁ | -| `check:openapi-coverage` | OpenAPI স্পেক প্রকৃত রুটগুলোর অন্তত র্যাচেট-করা ন্যূনতম সীমা পর্যন্ত কভার করে | হ্যাঁ | -| `check:openapi-security-tiers` | `openapi.yaml`-এর নিরাপত্তা স্তরের অ্যানোটেশনগুলো `routeGuard.ts`-এর শ্রেণিবিন্যাসের সঙ্গে সামঞ্জস্যপূর্ণ | **পরামর্শমূলক** | -| `check:openapi-routes` | `openapi.yaml`-এর প্রতিটি পাথ একটি বাস্তব `route.ts`-এ রিজলভ করে (হ্যালুসিনেশন-প্রতিরোধী) | হ্যাঁ | -| `check:docs-symbols` | `docs/**/*.md`-এর প্রতিটি `/api/...` রেফারেন্স একটি বাস্তব `route.ts`-এ রিজলভ করে (হ্যালুসিনেশন-প্রতিরোধী) | হ্যাঁ | -| `i18n translation drift` | i18n লোকেল ফাইলের অনূদিত না হওয়া কী — শুধু সতর্ক করে | **পরামর্শমূলক** | +`main`-এ প্রতিটি PR-এর সময় চলে। ব্যর্থ হলে মার্জ ব্লক করে। + +| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `check:docs-all` | নিচের 6টি সাব-গেট ধারাবাহিকভাবে চালানো মেটা-গেট | হ্যাঁ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt সংস্করণের সামঞ্জস্য | হ্যাঁ | +| ↳ `check:docs-counts` | গদ্যে উল্লিখিত সংখ্যা (প্রোভাইডারের সংখ্যা, মাইগ্রেশনের সংখ্যা ইত্যাদি) প্রকৃত সংখ্যার র্যাচেট সীমার মধ্যে আছে | হ্যাঁ | +| ↳ `check:env-doc-sync` | `.env.example`-এর প্রতিটি env var ডকুমেন্টেশনের একটি টেবিলে নথিভুক্ত আছে এবং এর বিপরীতটিও সত্য | হ্যাঁ | +| ↳ `check:deprecated-versions` | ডকুমেন্টেশনে কোনো অবচিত সংস্করণ স্ট্রিং নেই | হ্যাঁ | +| ↳ `check:doc-links` | ডকুমেন্টেশনের অভ্যন্তরীণ markdown লিংক বাস্তব ফাইলে রিজলভ হয় (`[text]`/`(path)` রূপে) | হ্যাঁ | +| ↳ `check:fabricated-docs` | ডকুমেন্টেশনে উল্লিখিত রুট, env var, CLI কমান্ড, হুকের নাম এবং ফাইল পাথ codebase-এ বিদ্যমান। `--strict`-এর মাধ্যমে হার্ড গেট; ফ্ল্যাগ ছাড়া সফট-ফেইল। | হ্যাঁ (CI-তে `--strict` দিয়ে) | +| `check:cli-i18n` | CLI কমান্ডের স্ট্রিং সব i18n locale ফাইলে উপস্থিত | হ্যাঁ | +| `check:openapi-coverage` | OpenAPI spec বাস্তব রুটগুলোর অন্তত একটি র্যাচেটেড ন্যূনতম সীমা কভার করে | হ্যাঁ | +| `check:openapi-security-tiers` | `openapi.yaml`-এর নিরাপত্তা স্তরের annotation-গুলো `routeGuard.ts`-এর classification-এর সঙ্গে সামঞ্জস্যপূর্ণ | **পরামর্শমূলক** | +| `check:openapi-routes` | `openapi.yaml`-এর প্রতিটি পাথ একটি বাস্তব `route.ts`-এ রিজলভ হয় (অলীক তথ্য প্রতিরোধ) | হ্যাঁ | +| `check:docs-symbols` | `docs/**/*.md`-এর প্রতিটি `/api/...` রেফারেন্স একটি বাস্তব `route.ts`-এ রিজলভ হয় (অলীক তথ্য প্রতিরোধ) | হ্যাঁ | +| `i18n translation drift` | i18n locale ফাইলে অনূদিত না হওয়া key — শুধু সতর্ক করে | **পরামর্শমূলক** | ### জব: `i18n-ui-coverage` -| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (ইনলাইন) | UI i18n কী কভারেজ ≥ 65% | হ্যাঁ | -| `check-ui-value-drift` (ইনলাইন) | পুনর্লিখিত কোনো ইংরেজি **মান** পুরোনো অনুবাদ অবশিষ্ট রাখে না | হ্যাঁ | -| `check-new-key-coverage` (ইনলাইন) | একটি **নতুন** ইংরেজি কী প্রতিটি লোকেলে অনূদিত — `__MISSING__:` মার্কার প্রত্যাখ্যান করা হয় | হ্যাঁ | -| `check-translation-ratio` | প্রতি লোকেলের প্রকৃত-অনুবাদ অনুপাত (ইংরেজির সঙ্গে অভিন্ন / প্লেসহোল্ডার / অনুমোদিত তালিকার বাইরে অনুপস্থিত লিফ) অবশ্যই `config/quality/i18n-translation-baseline.json` + slack অতিক্রম করবে না | **পরামর্শমূলক** | +| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (inline) | UI i18n key coverage ≥ 65% | হ্যাঁ | +| `check-ui-value-drift` (inline) | পুনর্লিখিত ইংরেজি **value** কোনো পুরোনো translation রেখে যায় না | হ্যাঁ | +| `check-new-key-coverage` (inline) | একটি **নতুন** ইংরেজি key প্রতিটি locale-এ অনূদিত — একটি `__MISSING__:` marker প্রত্যাখ্যাত হয় | হ্যাঁ | +| `check-translation-ratio` | প্রতি locale-এ প্রকৃত translation-এর অনুপাত (allowlist-এর বাইরে ইংরেজির সঙ্গে অভিন্ন / placeholder / অনুপস্থিত leaf) অবশ্যই `config/quality/i18n-translation-baseline.json` + slack অতিক্রম করবে না | **পরামর্শমূলক** | -`fetch-depth: 0` প্রয়োজন — value-drift গেটটি মার্জ বেসের বিপরীতে `en.json`-এর পার্থক্য নির্ণয় করে। +`fetch-depth: 0` প্রয়োজন — value-drift gate merge base-এর সঙ্গে `en.json`-এর diff করে। -#### `check-ui-value-drift` — পুরোনো-অনুবাদ গেট +#### `check-ui-value-drift` — পুরোনো-translation গেট -এটি সেই একটি i18n রিগ্রেশন ধরে, যা অন্য গেটগুলো কাঠামোগতভাবে শনাক্ত করতে পারে না: কোনো ইংরেজি মান -পুনর্লিখিত হয়, কিন্তু _আগের_ ইংরেজি থেকে তৈরি অনুবাদগুলো রয়ে যায়; ফলে -অ-ইংরেজি ব্যবহারকারীরা আত্মবিশ্বাসী ভাষায় লেখা, কিন্তু এখন ভুল, কপি পড়তে থাকেন। +এটি এমন একটি i18n regression ধরে, যা অন্য গেটগুলো কাঠামোগতভাবে দেখতে পারে না: কোনো ইংরেজি value +পুনর্লিখিত হয়, কিন্তু _আগের_ ইংরেজি থেকে তৈরি translation-গুলো থেকে যায়, ফলে +অ-ইংরেজি ব্যবহারকারীরা আত্মবিশ্বাসী ভাষায় লেখা, কিন্তু এখন ভুল, এমন copy পড়তে থাকেন। -এটি বাস্তবেই রিলিজ হয়েছিল। Antigravity লগইন হেলপার যুক্ত হওয়ার সময় (#5203) -`oauthModal.googleOAuthWarning` পুনর্লিখিত হয়েছিল; **৪৩টি লোকেলের মধ্যে ৩৯টিতে** অপারেটরদের "সম্পূর্ণ -URL কপি করে নিচে পেস্ট করতে" বলা টেক্সট রয়ে গিয়েছিল — এমন একটি প্রবাহ, যা ওই প্রোভাইডারের জন্য সম্পন্ন করা যায় না। এটি -#8463 পর্যন্ত নজরে আসেনি, কারণ: +এটি বাস্তবেই রিলিজে চলে গিয়েছিল। Antigravity login helper যুক্ত হওয়ার সময় (#5203) +`oauthModal.googleOAuthWarning` পুনর্লিখিত হয়েছিল; **43টি locale-এর মধ্যে 39টিতে** operator-দের "সম্পূর্ণ +URL কপি করে নিচে পেস্ট করতে" বলা text থেকে গিয়েছিল — এমন একটি flow, যা ওই provider-এর জন্য সম্পন্ন করা +অসম্ভব। #8463 পর্যন্ত এটি নজরে আসেনি, কারণ: -- `sync-ui-keys` শুধু **অনুপস্থিত** কী ব্যাকফিল করে, **পুরোনো** কী কখনো নয়; -- `check-ui-keys-coverage` কী-এর _উপস্থিতি_ গণনা করে, তাই পুরোনো অনুবাদও কভারড হিসেবে স্কোর পায়; -- `check-translation-drift` `docs/i18n//**.md` ডকুমেন্টেশন মিররগুলো ট্র্যাক করে — - এটি কখনোই `src/i18n/messages/*.json` পড়ে না। 2026-09 পুনরায় সিঙ্ক করার পর থেকে `docs-sync-strict` জবে ব্লকিং: - একটি মূল ডকুমেন্ট সম্পাদনা করুন → `npm run i18n:run -- --files=` (সেকশন-স্তরের, সাশ্রয়ী)। +- `sync-ui-keys` শুধু **অনুপস্থিত** key backfill করে, **পুরোনো** key কখনো নয়; +- `check-ui-keys-coverage` key-এর _উপস্থিতি_ গণনা করে, তাই একটি পুরোনো translation-ও covered হিসেবে গণ্য হয়; +- `check-translation-drift` `docs/i18n//**.md` documentation mirror ট্র্যাক করে — + এটি কখনোই `src/i18n/messages/*.json` পড়ে না। 2026-09 re-sync থেকে job `docs-sync-strict`-এ ব্লকিং: + একটি core doc সম্পাদনা করুন → `npm run i18n:run -- --files=` (section-level, সাশ্রয়ী)। -**ডিফ-সচেতন, বেসলাইন-সমর্থিত নয়।** এটি মার্জ বেসের `en.json`-কে -ওয়ার্কিং ট্রির সঙ্গে তুলনা করে; যেসব কী-এর ইংরেজি মান পরিবর্তিত হয়েছে, সেগুলোর ক্ষেত্রে -যে লোকেলে এখনও অপরিবর্তিত অনুবাদ রয়েছে, সেটি অচল। এটি ইচ্ছাকৃতভাবে **পূর্ব-বিদ্যমান ঋণকে স্থির রাখে** — -দীর্ঘদিনের কোনো অনুবাদ কোন পুরোনো ইংরেজি থেকে এসেছে, তা একটি ডিফ প্রকাশ করতে পারে না, তাই গেটটি -শুধু বর্তমান পরিবর্তনে স্পর্শ করা বিষয়গুলোই যাচাই করে। বিকল্পটি (প্রতি-কী হ্যাশ বেসলাইন) তৈরি করতে -~600 KB-এর একটি জেনারেটেড ফাইল লাগত, যা বিদ্যমান বৃহত্তম বেসলাইনের 3× এবং প্রতিটি i18n PR-এ পরিবর্তিত হতো। +**Diff-সচেতন, baseline-সমর্থিত নয়।** এটি merge base-এর `en.json`-কে working tree-এর সঙ্গে তুলনা করে; যেসব key-এর ইংরেজি value পরিবর্তিত হয়েছে, সেগুলোর ক্ষেত্রে কোনো locale-এ এখনও অপরিবর্তিত translation থাকলে সেটি stale। এটি ইচ্ছাকৃতভাবে **আগে থেকে থাকা ঘাটতিকে স্থির রাখে** — দীর্ঘদিন ধরে থাকা কোনো translation কোন পুরোনো ইংরেজি থেকে এসেছে, তা একটি diff প্রকাশ করতে পারে না; তাই gate কেবল বর্তমান পরিবর্তনে স্পর্শ করা বিষয়গুলোই বিচার করে। বিকল্পটি (প্রতি-key hash baseline) তৈরি করতে ~600 KB-এর একটি generated file লাগবে, যা বিদ্যমান বৃহত্তম baseline-এর 3× এবং প্রতিটি i18n PR-এ পরিবর্তিত হবে। -এটি পূরণ করার দুটি উপায়: +এটি সন্তুষ্ট করার দুটি উপায়: -1. প্রভাবিত অনুবাদগুলো হালনাগাদ করুন, অথবা -2. সেগুলোকে `__MISSING__:` হিসেবে সেট করুন — এরপর রানটাইম সংশোধিত ইংরেজি পরিবেশন করে - (`src/i18n/request.ts::deepMergeFallback`, #7258) এবং কী-টি অনুবাদের সারিতে যুক্ত হয়। +1. প্রভাবিত translation-গুলো update করুন, অথবা +2. সেগুলোকে `__MISSING__:`-এ সেট করুন — তখন runtime সংশোধিত ইংরেজিটি পরিবেশন করে + (`src/i18n/request.ts::deepMergeFallback`, #7258) এবং key-টি translation-এর জন্য queue-তে যোগ হয়। -স্ট্রিংটির **অর্থ** পরিবর্তিত হলে, **কী-এর নাম পরিবর্তন** করাকে অগ্রাধিকার দিন: একটি নতুন কী -অচল অনুবাদ উত্তরাধিকারসূত্রে পেতে পারে না। #8463-এ এই প্যাটার্ন ব্যবহার করা হয়েছিল। +string-টির **অর্থ** পরিবর্তিত হলে, **key-টির নাম পরিবর্তন** করাকে অগ্রাধিকার দিন: একটি নতুন key stale translation উত্তরাধিকারসূত্রে পেতে পারে না। #8463-এ এই pattern-টিই ব্যবহার করা হয়েছিল। ```bash npm run i18n:check-value-drift # কঠোর (CI যা চালায়) -npm run i18n:check-value-drift:warn # শুধু প্রতিবেদন +npm run i18n:check-value-drift:warn # শুধু রিপোর্ট BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -বেস ক্যাটালগ পড়া না গেলে (বেস ref ছাড়া শ্যালো ক্লোন), `SKIP reason=base-unresolved` সহ -0 এক্সিট করে, যা `check-openapi-breaking`-এর আচরণের অনুরূপ। +base catalog পড়া না গেলে (base ref ছাড়া shallow clone), `check-openapi-breaking`-এর আচরণ অনুসরণ করে `SKIP reason=base-unresolved` সহ 0 exit করে। -### জব: `i18n` +### Job: `i18n` -সম্পূর্ণ i18n যাচাইকরণ ম্যাট্রিক্স (প্রতি লোকেলে একটি জব)। পুরো জবটি পরামর্শমূলক। +সম্পূর্ণ i18n validation matrix (প্রতি locale-এ একটি job)। পুরো job-টি advisory। -| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | -| ------------------------------- | -------------------------------- | ---------------------------------------------------- | -| `validate_translation.py quick` | প্রতি লোকেলে অনুবাদের সম্পূর্ণতা | **পরামর্শমূলক** (পুরো জবে `continue-on-error: true`) | +| Script | যা যাচাই করে | Blocking | +| ------------------------------- | ------------------------------------- | --------------------------------------------------- | +| `validate_translation.py quick` | প্রতি locale-এ translation-এর পূর্ণতা | **Advisory** (পুরো job-এ `continue-on-error: true`) | -### জব: `pr-test-policy` +### Job: `pr-test-policy` -শুধু পুল রিকোয়েস্টে চলে। +শুধু pull request-এ চলে। -| স্ক্রিপ্ট | যা যাচাই করে | ব্লকিং | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| `check:pr-test-policy` | যেসব PR `src/`, `open-sse/`, `electron/`, বা `bin/`-এর প্রোডাকশন কোড পরিবর্তন করে, সেগুলোতে অবশ্যই টেস্ট যোগ বা হালনাগাদ করতে হবে (কঠোর নিয়ম #8) | হ্যাঁ | -| `check:test-masking` | পরিবর্তিত টেস্ট ফাইলগুলো মোট assert সংখ্যা কমায় না বা `assert.ok(true)`-এর মতো স্বতঃসিদ্ধ assertion যোগ করে না | হ্যাঁ | -| `check:pr-evidence` | PR-এর বিবরণে পরিবর্তনের জন্য টেস্ট/VPS প্রমাণ উল্লেখ করা হয়েছে (PR-এর গদ্য grep করে কঠোর নিয়ম #18 স্বয়ংক্রিয় করে — ভঙ্গুর, Backlog দেখুন) | হ্যাঁ | +| Script | যা যাচাই করে | Blocking | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | যেসব PR `src/`, `open-sse/`, `electron/`, বা `bin/`-এর production code পরিবর্তন করে, সেগুলোতে অবশ্যই test যোগ বা update করতে হবে (Hard Rule #8) | হ্যাঁ | +| `check:test-masking` | পরিবর্তিত test file-গুলো net assert count কমায় না বা `assert.ok(true)` tautology যোগ করে না | হ্যাঁ | +| `check:pr-evidence` | PR body-তে পরিবর্তনের জন্য test/VPS evidence উল্লেখ করা হয় (PR-এর prose grep করে Hard Rule #18 স্বয়ংক্রিয় করে — ভঙ্গুর, Backlog দেখুন) | হ্যাঁ | -### জব: `test-vitest` +### Job: `test-vitest` -`build`-এর পরে চলে। ব্যর্থ হলে মার্জ ব্লক করে। +`build`-এর পরে চলে। ব্যর্থ হলে merge block করে। -| স্যুট | যা যাচাই করে | ব্লকিং | -| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP সার্ভার (110টি টুল), autoCombo, cache — vitest রানার | হ্যাঁ | -| `test:vitest:ui` | UI কম্পোনেন্ট টেস্ট — vitest রানার | **ব্লকিং** — পূর্ব-বিদ্যমান ব্যর্থতাগুলো `vitest.config.ts`-এ স্পষ্টভাবে বাদ দেওয়া হয়েছে; নতুন ব্যর্থতায় জবটি ব্যর্থ হয় | +| Suite | যা যাচাই করে | Blocking | +| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | হ্যাঁ | +| `test:vitest:ui` | UI component test — vitest runner | **Blocking** — আগে থেকে থাকা failure-গুলো `vitest.config.ts`-এ স্পষ্টভাবে বাদ দেওয়া হয়েছে; নতুন failure হলে job ব্যর্থ হয় | -### রাত্রিকালীন ওয়ার্কফ্লো (নির্ধারিত, পরামর্শমূলক) +### Nightly workflow (নির্ধারিত, advisory) -এগুলো cron সময়সূচিতে (এবং `workflow_dispatch`-এ) চলে, PR-এ কখনোই নয়। সবগুলোই পরামর্শমূলক। +এগুলো cron schedule-এ (এবং `workflow_dispatch`-এ) চলে, PR-এ কখনোই চলে না। সবগুলোই advisory। -| ওয়ার্কফ্লো | যা যাচাই করে | ব্লকিং | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | র্যান্ডম seed + উচ্চ run count সহ fast-check প্রপার্টি টেস্ট | **পরামর্শমূলক** | -| `nightly-resilience` | heap-growth গেট, chaos fault-injection, k6 load/soak | **পরামর্শমূলক** | -| `nightly-llm-security` | promptfoo injection guard (block মোড) + garak probes (প্রোভাইডার secret না থাকলে বাদ দেওয়া হয়) | **পরামর্শমূলক** | -| `nightly-schemathesis` | `docs/openapi.yaml` ব্যবহার করে সচল OmniRoute-এর বিরুদ্ধে OpenAPI কন্ট্রাক্ট fuzzing (schemathesis) — স্পেক লঙ্ঘন / অনিয়ন্ত্রিত 500 প্রকাশ করে (পর্যায় 8 B.4) | **পরামর্শমূলক** | -| `nightly-mutation` | দ্রুত unit lane-এ Stryker mutation-testing স্কোর — টিকে যাওয়া mutants দুর্বল assertions প্রকাশ করে | **পরামর্শমূলক** | -| `nightly-compat` | সমর্থিত `engines.node` রেঞ্জজুড়ে Node engine compatibility matrix | **পরামর্শমূলক** | +| Workflow | যা যাচাই করে | Blocking | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | random seed + উচ্চ run count সহ fast-check property test | **Advisory** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **Advisory** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probe (provider secret ছাড়া skip করা হয়) | **Advisory** | +| `nightly-schemathesis` | `docs/openapi.yaml` ব্যবহার করে live OmniRoute-এর বিপরীতে OpenAPI contract fuzzing (schemathesis) — spec violation / unhandled 500 প্রকাশ করে (পর্যায় 8 B.4) | **Advisory** | +| `nightly-mutation` | fast unit lane-এর ওপর Stryker mutation-testing score — টিকে যাওয়া mutant দুর্বল assert প্রকাশ করে | **Advisory** | +| `nightly-compat` | সমর্থিত `engines.node` range জুড়ে Node engine compatibility matrix | **Advisory** | --- @@ -539,41 +531,41 @@ CI গেটগুলোর পাশাপাশি, OmniRoute একটি ** ## যৌক্তিকীকরণ ব্যাকলগ (ROI পর্যালোচনা — পর্যায় 9 তরঙ্গ 3) -এই তালিকাটি 2026-06-17 তারিখে `ci.yml`-এর সঙ্গে মিলিয়ে দেখা হয়েছে (আগের সংস্করণে +এই ইনভেন্টরিটি 2026-06-17 তারিখে `ci.yml`-এর সঙ্গে সমন্বয় করা হয়েছে (আগের সংস্করণে `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` বাদ পড়েছিল)। মিলিয়ে নেওয়া সেটটির একটি ROI পর্যালোচনায় -নিম্নলিখিত যৌক্তিকীকরণের প্রার্থীগুলো শনাক্ত হয়েছে। **মার্জগুলো যান্ত্রিক CI -পরিবর্তন; ফ্লিপ/বাদ দেওয়ার সিদ্ধান্তগুলো অপারেটরের জন্য সংরক্ষিত নীতিগত সিদ্ধান্ত।** নিচের কিছুই +`check:codeql-ratchet`, `check:pr-evidence` বাদ পড়েছিল)। সমন্বয়কৃত সেটটির একটি ROI পর্যালোচনায় +নিচের যৌক্তিকীকরণ প্রার্থীগুলো শনাক্ত হয়েছে। **মার্জগুলো যান্ত্রিক CI +পরিবর্তন; ফ্লিপ/বাদ দেওয়ার সিদ্ধান্তগুলো অপারেটরের জন্য সংরক্ষিত নীতিগত সিদ্ধান্ত।** নিচের কোনো কিছুই এখনও প্রয়োগ করা হয়নি। -**উপরের অংশে আরও যা নথিভুক্ত হয়নি** (পরামর্শমূলক, কম সংকেত): `docs-lint` জব -(markdownlint + Vale, পুরো জব `continue-on-error`) এবং স্বতন্ত্র স্ক্যানার ওয়ার্কফ্লো -`semgrep.yml` / `codeql.yml` / `scorecard.yml`। `semgrepFindings: 0` -`quality-baseline.json`-এ রয়েছে, কিন্তু `ci.yml`-এ কোনো ব্লকিং র্যাচেটের সঙ্গে সংযুক্ত নয় — মেট্রিকটি +**উপরেও নথিবদ্ধ হয়নি** (পরামর্শমূলক, দুর্বল সংকেত): `docs-lint` জব +(markdownlint + Vale, পুরো জবে `continue-on-error`) এবং স্বতন্ত্র স্ক্যানার ওয়ার্কফ্লো +`semgrep.yml` / `codeql.yml` / `scorecard.yml`। `quality-baseline.json`-এ +`semgrepFindings: 0` রয়েছে, কিন্তু `ci.yml`-এ এটি কোনো ব্লকিং র্যাচেটের সঙ্গে সংযুক্ত নয় — মেট্রিকটি বর্তমানে অনাথ। -### মার্জ / ডিডুপ (যান্ত্রিক, কম ঝুঁকি) +### মার্জ / ডিডুপ্লিকেশন (যান্ত্রিক, কম ঝুঁকি) -প্রতিটি প্রার্থীকে 2026-06-17 তারিখের সক্রিয় গেট অবস্থার বিপরীতে যাচাই করা হয়েছে (বিশ্বাস করুন, তবে যাচাইও করুন); -বেশ কয়েকটি "স্পষ্ট" মার্জের আড়ালে ঋণ লুকিয়ে থাকতে দেখা গেছে এবং সেগুলো **পরিষ্কার ড্রপ-ইন নয়**। +প্রতিটি প্রার্থীকে 2026-06-17 তারিখে সক্রিয় গেটের অবস্থার বিপরীতে যাচাই করা হয়েছে (বিশ্বাস করুন, তবে যাচাইও করুন); +বেশ কয়েকটি "স্পষ্ট" মার্জ আসলে লুকানো ঋণ আড়াল করছিল এবং সেগুলো **পরিষ্কার ড্রপ-ইন নয়**। -- **`check:docs-sync` দুবার চলে** — `lint` জবে স্বতন্ত্রভাবে এবং আবার `check:docs-all` (`docs-sync-strict`) ও husky pre-commit hook-এর মধ্যে। ✅ **সম্পন্ন** — স্বতন্ত্র `lint` ইনভোকেশন সরানো হয়েছে। -- **CVE স্ক্যানিং** — ❌ **পরিষ্কার মার্জ নয়।** `audit:deps` যেকোনো high/critical CVE-তে হার্ড-ফেল করে; `check:vuln-ratchet` (osv) কেবল বেসলাইনের তুলনায় কোনো _অবনতি_ হলে ব্যর্থ হয় (বর্তমানে 1 MODERATE)। অর্থগত আচরণ ভিন্ন — `audit:deps` বাদ দিলে পরম high/critical গেটটি হারিয়ে যাবে। দুটিই রাখুন। -- **সাইকেল শনাক্তকরণ** — ❌ **পরিষ্কার মার্জ নয়।** `check:circular-deps` (dpdm) **91টি সাইকেল** রিপোর্ট করে (এই কারণেই এটি পরামর্শমূলক); সেগুলো আগে সমাধান না করে এটিকে ব্লকিং হিসেবে উন্নীত করা যায় না, এবং সবুজ, নির্বাচিত `check:cycles`-এর তুলনায় এর পরিধি বিস্তৃত। `check:cycles`-কে ব্লকিং রাখুন; 91টি dpdm সাইকেল সমাধান করা একটি স্বতন্ত্র ব্যাকলগ। -- **জটিলতা** — ✅ **সম্পন্ন** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): একটি ESLint ওয়াক, ruleId অনুযায়ী গণনা করে যাতে cyclomatic+max-lines এবং cognitive বেসলাইনগুলো স্বাধীন থাকে; স্থানীয় `--update`-এর জন্য পৃথক `check:complexity` / `check:cognitive-complexity` বহাল রয়েছে। -- **`/api` অ্যান্টি-হ্যালুসিনেশন** — ✅ **সম্পন্ন** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-এর একটি FS ইনভেন্টরি, openapi-routes + docs-symbols এখনও স্বাধীনভাবে রিপোর্ট করে; স্থানীয় রানগুলোর জন্য পৃথকগুলো বহাল রয়েছে। -- **`check:node-runtime` 11টি জবে চলে** — ⚠️ **কম ROI।** প্রতিটি আলাদা রানার এবং যাচাইটি <1s; মোট সাশ্রয় ~10s, যার বিনিময়ে প্রতিটি জবের জন্য একটি সস্তা গার্ড হারাতে হবে। এই পরিবর্তনের ঝামেলার যোগ্য নয়। +- **`check:docs-sync` দুবার চলে** — `lint` জবে স্বতন্ত্রভাবে এবং আবার `check:docs-all` (`docs-sync-strict`) ও husky pre-commit hook-এর ভেতরে। ✅ **সম্পন্ন** — স্বতন্ত্র `lint` ইনভোকেশন সরানো হয়েছে। +- **CVE স্ক্যানিং** — ❌ **পরিষ্কার মার্জ নয়।** যেকোনো high/critical CVE-তে `audit:deps` হার্ড-ফেইল করে; `check:vuln-ratchet` (osv) কেবল baseline-এর তুলনায় কোনো _রিগ্রেশন_ হলে ব্যর্থ হয় (বর্তমানে 1 MODERATE)। সেমান্টিক্স ভিন্ন — `audit:deps` বাদ দিলে পরম high/critical গেটটি হারিয়ে যাবে। দুটিই রাখুন। +- **চক্র শনাক্তকরণ** — ✅ **সম্পন্ন** (#15159 G-01/G-02)। এখানে পুরোনো লেখায় `check:cycles`-কে "সবুজ, বাছাইকৃত" গেট বলা হয়েছিল এবং `check:circular-deps` (dpdm) 91টি চক্র রিপোর্ট করায় এটিকে ব্লকিং রাখার যৌক্তিকতা দেওয়া হয়েছিল। সেই সবুজ অবস্থা ছিল একটি **মিথ্যা সবুজ**: `check:cycles` 5টি সাবডিরেক্টরি (450টি ফাইল) স্ক্যান করত, শুধু স্থির `import|export … from` মেলাত এবং প্রতিটি `@/` ও `@omniroute/open-sse/` স্পেসিফায়ার বাদ দিত, ফলে রিপোজিটরিতে প্রাধান্য পাওয়া dynamic-import + alias চক্রগুলো এটি দেখতে পারত না। সংশোধন করা হয়েছে: গেটটি এখন `src` + `open-sse` (5023টি ফাইল) অতিক্রম করে, TypeScript AST থেকে স্পেসিফায়ার সংগ্রহ করে (তাই `import("…")` গণনা করা হয়, কিন্তু type-position `typeof import("…")` করা হয় না) এবং tsconfig `paths` রিজলভ করে। এটি 0 নয়, **14টি** চক্র খুঁজে পায়। যেহেতু গেট PR-এ আগে থেকে থাকা 14টি চক্র ঠিক করা সম্ভব নয়, `check:cycles` এখন একটি **র্যাচেট** (`--ratchet`, `quality-baseline.json`-এ সীমা `metrics.cycles.value = 14`, `direction: down`) — এটি যেকোনো _রিগ্রেশন_ ব্লক করে এবং সংখ্যা কেবল কমতে পারে। CI-তে `npm run check:cycles:ratchet` চলে। বার্ন-ডাউন **A-01**-এর সঙ্গে চলবে। বিস্তৃত দ্বিতীয় মতামত হিসেবে `check:circular-deps` (dpdm) পরামর্শমূলক থাকবে। +- **জটিলতা** — ✅ **সম্পন্ন** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): একটি ESLint ওয়াক, ruleId অনুযায়ী গণনা করে যাতে cyclomatic+max-lines এবং cognitive baseline স্বাধীন থাকে; স্থানীয় `--update`-এর জন্য পৃথক `check:complexity` / `check:cognitive-complexity` বজায় রাখা হয়েছে। +- **`/api` অ্যান্টি-হ্যালুসিনেশন** — ✅ **সম্পন্ন** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-এর একটি FS ইনভেন্টরি, openapi-routes + docs-symbols এখনও স্বাধীনভাবে রিপোর্ট করে; স্থানীয় রানের জন্য পৃথকগুলো বজায় রাখা হয়েছে। +- **`check:node-runtime` 11টি জবে চলে** — ⚠️ **কম ROI।** প্রতিটি আলাদা রানার এবং চেকটি <1s; সাশ্রয় মোটামুটি ~10s, যার বিপরীতে একটি সস্তা প্রতি-জব গার্ড হারাতে হবে। পরিবর্তনের ঝামেলা সার্থক নয়। - **CI lint-এ `typecheck:noimplicit:core`** — ✅ **lint জব থেকে সরানো হয়েছে** (এটি পরামর্শমূলক `continue-on-error` ছিল); ব্লকিং টাইপ সারফেস হলো `typecheck:core` + `check:type-coverage`। স্থানীয় স্ক্রিপ্ট রাখা হয়েছে। -### ফ্লিপ / সিদ্ধান্ত নিন (অপারেটর নীতি) +### ফ্লিপ / সিদ্ধান্ত (অপারেটর নীতি) -- `check:openapi-security-tiers` (পরামর্শমূলক) — ❌ **পরিষ্কারভাবে ফ্লিপযোগ্য নয়।** এটি 0 দিয়ে বের হয়, তবে সতর্ক করে যে `LOCAL_ONLY_API_PREFIXES`-এর অধীন একাধিক `traffic-inspector` রুটে `x-loopback-only: true` অ্যানোটেশন নেই। এটি কার্যকর করতে হলে প্রথমে `openapi.yaml`-এ ওই অ্যানোটেশনগুলো যোগ করতে হবে। -- `typecheck:noimplicit:core` (পরামর্শমূলক) — ব্লকিং `check:type-coverage` র্যাচেটের মাধ্যমে অনেকটাই অন্তর্ভুক্ত। এটিকে র্যাচেটে ফ্লিপ করুন অথবা অপ্রয়োজনীয় দ্বিতীয় `tsc` পাসটি বাদ দিন। -- `test:vitest:ui` (এখন **ব্লকিং**) — আগে থেকে বিদ্যমান ব্যর্থতাগুলো `vitest.config.ts`-এ `// #8618` ট্র্যাকিং মন্তব্যসহ স্পষ্টভাবে বাদ দেওয়া হয়েছে; নতুন ব্যর্থতা জবটিকে ব্যর্থ করে। -- `check:secrets` (gitleaks, 3টি নথিভুক্ত false-positive-এ স্থির করা ব্লকিং র্যাচেট) — 0-তে পৌঁছাতে 3টিকে allowlist করুন, অথবা পরামর্শমূলক স্তরে নামিয়ে দিন। GitHub-এর নেটিভ secret-scanning + `check:public-creds`-এর সঙ্গে ওভারল্যাপ করে। -- `check:pr-evidence` (ব্লকিং, PR-body-এর গদ্য grep করে) — false-positive-এর উচ্চ ঝুঁকি; বাদ দিলে Hard Rule #18-এর প্রয়োগ দুর্বল হয়, তাই এটি প্রকৃতপক্ষেই একটি নীতিগত সিদ্ধান্ত। -- `semgrep` (পরামর্শমূলক স্বতন্ত্র) — OWASP ফ্যামিলিগুলোর ক্ষেত্রে CodeQL-এর সঙ্গে ওভারল্যাপ করে; এর বেসলাইনকে একটি র্যাচেটের সঙ্গে সংযুক্ত করুন অথবা বাদ দিন। +- `check:openapi-security-tiers` (পরামর্শমূলক) — ❌ **পরিষ্কারভাবে ফ্লিপযোগ্য নয়।** এটি 0 দিয়ে এক্সিট করে, কিন্তু সতর্ক করে যে `LOCAL_ONLY_API_PREFIXES`-এর অধীন কয়েকটি `traffic-inspector` রুটে `x-loopback-only: true` অ্যানোটেশন নেই। এটি বলবৎ করার আগে `openapi.yaml`-এ ওই অ্যানোটেশনগুলো যোগ করতে হবে। +- `typecheck:noimplicit:core` (পরামর্শমূলক) — ব্লকিং `check:type-coverage` র্যাচেট এটিকে অনেকাংশে অন্তর্ভুক্ত করে। এটিকে র্যাচেটে ফ্লিপ করুন অথবা অপ্রয়োজনীয় দ্বিতীয় `tsc` পাসটি বাদ দিন। +- `test:vitest:ui` (এখন **ব্লকিং**) — আগে থেকে থাকা ব্যর্থতাগুলো `vitest.config.ts`-এ `// #8618` ট্র্যাকিং মন্তব্যসহ স্পষ্টভাবে বাদ দেওয়া হয়েছে; নতুন ব্যর্থতা জবটিকে ব্যর্থ করবে। +- `check:secrets` (gitleaks, 3টি নথিবদ্ধ false-positive-এ স্থির করা ব্লকিং র্যাচেট) — 0-তে পৌঁছাতে 3টিকে allowlist করুন, অথবা পরামর্শমূলক স্তরে নামিয়ে দিন। GitHub-এর নেটিভ secret-scanning + `check:public-creds`-এর সঙ্গে ওভারল্যাপ করে। +- `check:pr-evidence` (ব্লকিং, PR-body-এর গদ্য grep করে) — false-positive-এর উচ্চ ঝুঁকি; বাদ দিলে Hard Rule #18-এর প্রয়োগ দুর্বল হবে, তাই এটি সত্যিকারের নীতিগত সিদ্ধান্ত। +- `semgrep` (পরামর্শমূলক স্বতন্ত্র) — OWASP পরিবারগুলোর ক্ষেত্রে CodeQL-এর সঙ্গে ওভারল্যাপ করে; এর baseline-কে একটি র্যাচেটের সঙ্গে সংযুক্ত করুন অথবা বাদ দিন। --- diff --git a/docs/i18n/bs/CONTRIBUTING.md b/docs/i18n/bs/CONTRIBUTING.md index 73c7625a416..4241e63b320 100644 --- a/docs/i18n/bs/CONTRIBUTING.md +++ b/docs/i18n/bs/CONTRIBUTING.md @@ -394,22 +394,22 @@ Napišite unit testove u `tests/unit/` koji pokrivaju najmanje: --- -## Pull Request Checklist +## Kontrolna lista za Pull Request - [ ] Testovi prolaze (`npm test`) -- [ ] Linting prolazi (`npm run lint`) -- [ ] Build uspijeva (`npm run build`) -- [ ] TypeScript tipovi su dodani za nove javne funkcije i interfejse -- [ ] Nema hardkodiranih tajni (secrets) ili fallback vrijednosti -- [ ] Javni upstream kredencijali su ugrađeni putem `resolvePublicCred()` (vidi [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikada kao literali -- [ ] Odgovori o greškama prolaze kroz `buildErrorBody()` / `sanitizeErrorMessage()` — bez sirovih stack trace-ova u tijelima odgovora (vidi [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell komande (`exec` / `spawn`) prenose runtime vrijednosti putem `env`, a ne putem string interpolacije -- [ ] Svi inputi su validirani Zod shemama -- [ ] **Fragment** changeloga je dodan pod `changelog.d/{features|fixes|maintenance}/-.md` za promjene vidljive korisnicima (vidi [`changelog.d/README.md`](./changelog.d/README.md)) — **nemojte** direktno uređivati `CHANGELOG.md`; fragmenti se agregiraju prilikom release-a i nikada ne dolazi do konflikata između PR-ova +- [ ] Provjera lintinga prolazi (`npm run lint`) +- [ ] Build je uspješan (`npm run build`) +- [ ] Dodani su TypeScript tipovi za nove javne funkcije i interfejse +- [ ] Nema hardkodiranih tajni ili rezervnih vrijednosti +- [ ] Javni pristupni podaci uzvodnog sistema ugrađeni su putem `resolvePublicCred()` (pogledajte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikada kao literali +- [ ] Odgovori s greškama prolaze kroz `buildErrorBody()` / `sanitizeErrorMessage()` — nema neobrađenih stack traceova u tijelima odgovora (pogledajte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell komande (`exec` / `spawn`) prosljeđuju vrijednosti tokom izvršavanja putem `env`, a ne putem interpolacije stringova +- [ ] Svi ulazi validirani su pomoću Zod schema +- [ ] **Fragment** dnevnika promjena dodan je u `changelog.d/{features|fixes|maintenance}/-.md` za promjene vidljive korisnicima (pogledajte [`changelog.d/README.md`](./changelog.d/README.md)) — **nemojte** direktno uređivati `CHANGELOG.md`; fragmenti se objedinjuju prilikom izdavanja i nikada ne uzrokuju konflikte između PR-ova - [ ] Dokumentacija je ažurirana (ako je primjenjivo) -- [ ] Nema novih CodeQL / Secret-Scanning upozorenja, ili je svako od njih odbijeno uz tehničko obrazloženje koje referencira relevantni `docs/security/` dokument -- [ ] Rute koje pokreću child procese (`/api/mcp/`, `/api/cli-tools/runtime/`) su klasifikovane kao `isLocalOnlyPath()` u `src/server/authz/routeGuard.ts` — vidi [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Nema `Co-Authored-By` trailera u commit porukama — commitovi moraju pojaviti se isključivo pod Git identitetom vlasnika repozitorija (Hard Rule #16) +- [ ] Nisu otvorena nova CodeQL upozorenja / upozorenja skeniranja tajni ili je svako od njih odbačeno uz tehničko obrazloženje koje upućuje na relevantni dokument u `docs/security/` +- [ ] Rute koje pokreću podređene procese (`/api/mcp/`, `/api/cli-tools/runtime/`) klasificirane su kao `isLocalOnlyPath()` u `src/server/authz/routeGuard.ts` — pogledajte [Strogo pravilo #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Nema AI/bot `Co-authored-by` završnih redova u porukama commita (Strogo pravilo #16) — ljudski saradnici čiji se rad ponovo koristi navode se standardnim `Co-authored-by: Name ` završnim redovima --- diff --git a/docs/i18n/bs/docs/architecture/QUALITY_GATES.md b/docs/i18n/bs/docs/architecture/QUALITY_GATES.md index 9a9bd2ed6a4..a780f2ca55c 100644 --- a/docs/i18n/bs/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/bs/docs/architecture/QUALITY_GATES.md @@ -17,264 +17,268 @@ istog sistema nezavisan od alata, pogledajte --- -## Inventar kontrolnih tačaka i profili izvršavanja +## Inventar kontrola i profili izvršavanja -### Prihvat kandidata +### Prihvatanje kandidata -CI i Quality Gates tokovi rada daju stabilan rezultat: `Gate / CI` i -`Gate / Quality`. Njihova verzionirana politika prihvata navodi svaki prethodni posao -kao obavezan ili savjetodavan. Primjenjivi obavezni posao mora biti uspješan: nedostajući, -otkazani, preskočeni, neriješeni i nepoznati rezultati ne mogu uspostaviti PASS. Važeća +CI i Quality Gates radni tokovi emituju stabilan ishod: `Gate / CI` i +`Gate / Quality`. Njihova verzionirana politika prihvatanja navodi svaki prethodni posao +kao obavezan ili savjetodavan. Primjenjivi obavezni posao mora biti uspješan: rezultati koji +nedostaju, koji su otkazani, preskočeni, na čekanju ili nepoznati ne mogu uspostaviti PASS. Važeća klasifikacija samo za dokumentaciju ili samo za katalog može učiniti programsku putanju neprimjenjivom; nacrt PR-a nije prihvaćen kandidat. Oznaka `hotfix` ne ukida zahtjev za dokazima. -Oba toka rada obuhvataju PR-ove i slanja na glavne/release grane, ručno pokretanje i -događaje grupe spajanja. Slanje, pokretanje i grupa spajanja izvršavaju puni odabir. Forkovi +Oba radna toka obuhvataju PR-ove i slanja na glavne/release grane, ručno pokretanje i +događaje grupe spajanja. Slanje, ručno pokretanje i grupa spajanja izvršavaju puni izbor. Forkovi i grupe spajanja koriste hostovane izvršioce za poslove koji bi inače odabrali samostalno hostovane -izvršioce; dovoljan hostovani kapacitet mora biti provjeren prije uvođenja. +izvršioce; prije uvođenja mora se provjeriti dovoljan hostovani kapacitet. -Svaka JSON potvrda identificira preuzeti SHA, izvršavanje toka rada i pokušaj. -CLI odbija nepodudaranje SHA vrijednosti preuzete verzije i događaja. Testovi toka rada vežu članstvo u politici -za listu `needs` posla koji daje rezultat, tako da nova ili uklonjena putanja ne može neprimjetno nestati. -Potvrde obuhvataju vlastiti tok rada, a ne objavljivanje, implementaciju ili interne detalje -postojećeg savjetodavnog skenera. Aktiviranje oba naziva provjera u pravilima grane predstavlja -zasebnu administrativnu promjenu; dodavanje ovih poslova samo po sebi ne štiti granu. +Svaka JSON potvrda identifikuje odjavljeni SHA, izvršavanje radnog toka i pokušaj. +CLI odbija nepodudaranje SHA-a odjave i događaja. Testovi radnog toka vežu članstvo u politici +za listu `needs` posla koji daje ishod, tako da nova ili uklonjena putanja ne može neprimjetno nestati. +Potvrde obuhvataju vlastiti radni tok, a ne objavljivanje, implementaciju ili internu logiku +postojećeg savjetodavnog skenera. Aktiviranje oba naziva provjera u pravilima grane +zasebna je administrativna promjena; dodavanje ovih poslova samo po sebi ne štiti granu. ### Inventar statičkog skeniranja Verzionirani inventar npm aliasa i članstvo u statičkom skeniranju nalaze se u -`config/quality/gate-manifest.json`. Pokrenite `npm run check:gate-manifest` kako biste provjerili -nazive skripti i tačne naredbe u odnosu na `package.json`; dodavanja, uklanjanja i -odstupanja naredbi uzrokuju neuspjeh i lokalne kuke i poslova klasifikacije promjena u CI-ju. -Alias nije posao toka rada, instanca matrice niti testni slučaj: ovi brojevi se +`config/quality/gate-manifest.json`. Pokrenite `npm run check:gate-manifest` da biste provjerili +nazive skripti i tačne naredbe prema datoteci `package.json`; dodavanja, uklanjanja i +odstupanja naredbi uzrokuju neuspjeh i lokalne kuke i poslova klasifikacije promjena u CI-u. +Alias nije posao radnog toka, instanca matrice niti testni slučaj: ti se brojevi ne smiju predstavljati kao međusobno zamjenjivi. Koristite `npm run quality:scan -- --list` ili `npm run quality:scan:fast -- --list` da pregledate odabrane aliase bez njihovog izvršavanja. Izvršilac poziva -npm ulaznu tačku, pa je njeno okruženje izvršavanja (uključujući Bun gdje je konfiguriran) očuvano. -Manifest evidentira aliase izvan tih profila kao zasebno pozvane, a +npm ulaznu tačku, pa se njeno izvršno okruženje (uključujući Bun gdje je konfigurisan) zadržava. +Manifest bilježi aliase izvan tih profila kao zasebno pozvane, a naredbe za održavanje zabranjene su u profilima skeniranja samo za čitanje. -Ovi profili obuhvataju samo statičko skeniranje. Oni ne certificiraju testove proizvoda, -pokrivenost, pakovanje, vanjske provjere niti potpuno prihvatanje kandidata za izdavanje. -Prihvat u toku rada koristi povezane `config/quality/admission-policy.json` i -`scripts/quality/admission-verdict.mjs`. Profili posmatrača izdanja ostaju odvojeni; -njihove primjenjive provjere i potvrde pregledajte nezavisno. Tekstualni -inventar u nastavku služi kao referenca, a ne kao dokaz da je kontrolna tačka zaista izvršena. +Ovi profili obuhvataju samo statičko skeniranje. Oni ne potvrđuju testove proizvoda, +pokrivenost, pakovanje, vanjske provjere niti potpuno prihvatanje kandidata za izdanje. +Prihvatanje u radnom toku koristi povezane `config/quality/admission-policy.json` i +`scripts/quality/admission-verdict.mjs`. Profili posmatrača izdanja ostaju zasebni; +nezavisno pregledajte njihove primjenjive provjere i potvrde. Tekstualni +inventar u nastavku služi kao referenca, a ne kao dokaz da je kontrola zaista izvršena. -Skripte se nalaze u `scripts/check/` (kontrolne tačke politike) i `scripts/quality/` (mehanizam postepenog pooštravanja). +Skripte se nalaze u `scripts/check/` (kontrole politika) i `scripts/quality/` (mehanizam zapornog napretka). CI izvor istine je `.github/workflows/ci.yml`. -### Brza putanja za release PR (`quality.yml`) +### Brza putanja za PR izdanja (`quality.yml`) -`.github/workflows/quality.yml` dopunjuje CI za PR-ove prema glavnim/release granama, slanja na zaštićene grane, -pokretanja i grupe spajanja. PR-ovi koriste brze provjere filtrirane prema putanjama. Trajno -onemogućena duplikatna izgradnja je uklonjena; stvarne provjere izgradnje/pakovanja/pokretanja ostaju u CI-ju. +`.github/workflows/quality.yml` dopunjuje CI za PR-ove na glavnim/release granama, slanja na zaštićene +grane, ručno pokretanje i grupe spajanja. PR-ovi koriste brze provjere filtrirane prema putanjama. Trajno +onemogućena duplicirana izgradnja je uklonjena; stvarne provjere izgradnje/pakovanja/pokretanja ostaju u CI-u. -| Posao | Opseg | Blokirajuće | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | -| `Docs Gates (fast-path)` | PR-ovi dokumentacije/koda; reference API dokumentacije i sva dokumentacija | Da | -| `Fast Quality Gates` | PR-ovi koda; statičke provjere, provjera tipova, provjera tipova kontrolne ploče, pogođeni jedinični testovi | Da | -| `Forgotten sibling tests` | PR-ovi koda; promijenjeni moduli praćeni do statičkih potrošača i kandidatskih srodnih testova; putanje kroz barrel module i dinamički import prijavljuju se kao savjetodavna dijagnostika, uz navedene izuzetke s liste dozvoljenih | **Savjetodavno** | -| `Vitest (fast-path)` | PR-ovi koda; brzi vitest paket | Da | -| `Unit Tests fast-path` | PR-ovi koda; jedinični paket podijeljen na 4 dijela | Da | -| `No new ESLint warnings` | PR-ovi koda; zaštita lintera koja uzima u obzir potiskivanja | Da, uključujući forkove | -| `Merge integrity (changelog + generated skills)` | PR-ovi koji nisu nacrti; sinhronizacija dnevnika promjena i generiranih vještina | Da, uključujući forkove | +| Posao | Opseg | Blokirajuće | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `Docs Gates (fast-path)` | PR-ovi dokumentacije/koda; reference API dokumentacije i sva dokumentacija | Da | +| `Fast Quality Gates` | PR-ovi koda; statičke provjere, provjera tipova, provjera tipova kontrolne ploče, pogođeni jedinični testovi | Da | +| `Forgotten sibling tests` | PR-ovi koda; promijenjeni moduli praćeni do statičkih potrošača i potencijalnih srodnih testova; putanje barrel modula i dinamičkog uvoza prijavljuju se kao savjetodavna dijagnostika, uz navedene izuzetke s liste dopuštenja | **Savjetodavno** | +| `Vitest (fast-path)` | PR-ovi koda; brzi vitest paket | Da | +| `Unit Tests fast-path` | PR-ovi koda; jedinični paket podijeljen u 4 segmenta | Da | +| `No new ESLint warnings` | PR-ovi koda; zaštita od lint upozorenja koja uvažava potiskivanja | Da, uključujući forkove | +| `Merge integrity (changelog + generated skills)` | PR-ovi koji nisu nacrti; sinhronizacija evidencije promjena i generisanih vještina | Da, uključujući forkove | #### Izvještaj o zaboravljenim srodnim testovima -`npm run check:forgotten-sibling-tests` ponovo koristi razrješivač importa koji stoji iza mape uticaja testova. +`npm run check:forgotten-sibling-tests` ponovo koristi razrješavač uvoza na kojem se zasniva mapa uticaja testova. Za svaki promijenjeni produkcijski modul prijavljuje determinističke lance -`promijenjeni modul/simbol -> statički potrošač -> kandidatski srodni test` kada kandidatski -test nije prisutan u razlikama pull requesta. Markdown sažetak i JSON rezultat zadržavaju se kao -artefakt toka rada `forgotten-sibling-tests` radi kalibracije prije bilo kakvog uvođenja blokiranja. +`promijenjeni modul/simbol -> statički potrošač -> potencijalni srodni test` kada potencijalni +test nije prisutan u razlici zahtjeva za povlačenje. Markdown sažetak i JSON rezultat zadržavaju se kao +artefakt radnog toka `forgotten-sibling-tests` radi kalibracije prije bilo kakvog uvođenja blokiranja. -Barrel ponovni izvozi i dinamički uvozi služe samo kao dijagnostika razrješavanja; oni nikada ne stvaraju +Barrel ponovni izvozi i dinamički uvozi služe samo kao dijagnostika razrješavanja; nikada ne stvaraju blokirajući nalaz. Pregledani izuzeci nalaze se u -`config/quality/forgotten-sibling-allowlist.json`. Svaki unos mora navesti potrošača i kandidatski -test, dati konkretno obrazloženje i sadržavati poveznicu na GitHub issue ili pull request. Neispravni unosi rezultiraju -odbijanjem. Izuzeci ne mogu zanemariti izbrisani kandidatski test niti diff koji dodaje `.skip`/`.todo`; -slabljenje tvrdnji i druga prikrivanja ostaju u nadležnosti zasebno blokirajuće +`config/quality/forgotten-sibling-allowlist.json`. Svaki unos mora navesti potrošački i kandidatski +test, dati konkretno obrazloženje i sadržavati poveznicu na GitHub problem ili zahtjev za povlačenje. Neispravni unosi se +odbijaju. Izuzeci ne mogu zanemariti izbrisani kandidatski test niti razliku koja dodaje `.skip`/`.todo`; +slabljenje tvrdnji i drugo maskiranje ostaju u nadležnosti zasebno blokirajuće `check:test-masking` provjere. ### Zadatak: `lint` -Pokreće se na svakom PR-u prema grani `main`. U slučaju neuspjeha blokira spajanje. - -| Skripta (`npm run ...`) | Provjerava | Blokira | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Verzija Node.js-a nalazi se unutar podržanog raspona | Da | -| `check:cycles` | Cikličke uvoze — svi moduli u `src/` + `open-sse/` | Da | -| `check:route-validation:t06` | Zod sheme prisutne su na svim rutama (politika nivoa 6) | Da | -| `check:any-budget:t11` | Broj `@ts-expect-error // any` ne prelazi dozvoljeni prag (catraca nivoa 11) | Da | -| `check:provider-consistency` | Svaki dobavljač u `providers.ts` ima odgovarajući unos u `providerRegistry.ts` (i obrnuto, unutar liste dozvoljenih) | Da | -| `check:model-lifecycle` | Tri ručno održavane tabele usmjeravanja ostaju usklađene sa snapshotom životnog ciklusa pohranjenim u repozitoriju (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ne boduje nijedan povučeni id koji `REGISTRY` može usmjeriti; svaki cilj iz `BUILT_IN_ALIASES` prisutan je u `REGISTRY` i nije prisutan u snapshotu povučenih id-ova; svaki povučeni id koji je još uvijek u `REGISTRY` prosljeđuje se ili je naveden u `allowedRetiredInCatalog`; te se nijedan izvor ili cilj iz `DEFAULT_DEGRADATION_MAP` ne pojavljuje kao povučen u tom snapshotu. Ovo ne dokazuje da model trenutno poslužuje aktivni vanjski servis. Van mreže — poredi sa `config/quality/model-lifecycle.json`, koji se ručno osvježava pomoću `npm run quality:refresh-model-lifecycle` (mreža; nije uključen u CI). `allowedRetiredInCatalog` je jednosmjerna kontrola postepenog smanjivanja: unos dodajte samo uz problem za praćenje. | Da | -| `check:fetch-targets` | Svaki `fetch("/api/...")` u klijentskom `src/` razrješava se na stvarni `route.ts` | Da | -| `check:deps` | Sve zavisnosti koje se mogu instalirati pomoću `npm install` u svakom `package.json` u repozitoriju nalaze se u `dependency-allowlist.json`; nove neprikvačene ili slopsquattovane pakete označava kao problem | Da | -| `audit:deps` | `npm audit` (korijenski direktorij + electron) — nema upozorenja visoke/kritične ozbiljnosti (preklapa se s osv `check:vuln-ratchet`; pogledajte Backlog racionalizacije) | Da | -| `check:lockfile` | Integritet datoteke `package-lock.json` — https registar, hash vrijednosti integriteta, bez zamjena hosta | Da | -| `check:licenses` | Lista dozvoljenih SPDX licenci za produkcijske zavisnosti | Da | -| `check:tracked-artifacts` | Nema artefakata izgradnje / commitovanih `node_modules` simboličkih linkova (pokreće se i u husky pre-commit hooku; pre-push je namjerno minimalan — #6716) | Da | -| `check:ai-attribution` | Nema AI/bot `Co-Authored-By` završnog retka niti podnožja o AI generisanju u commitima, naslovu ili tijelu PR-a — Strogo pravilo #16 (u petlji brzih provjera u `quality.yml` za PR→`release/**` — čita sadržaj događaja, ne radi ništa izvan PR-ova — i korak samo za PR u lint provjeri u `ci.yml` za PR→`main`; također husky `commit-msg` hook; ljudski koautori su dozvoljeni; #14436) | -| `check:vitest-exclusions` | Svako Vitest izuzimanje navodi prateći issue i nalazi se u `config/quality/vitest-exclusions.json` (#13204) | Da | -| `check:file-size` | Nijedna izvorna datoteka ne premašuje ograničenje za odgovarajuću ekstenziju (ratchet: zamrznute velike datoteke na listi `frozen`) | Da | -| `check:error-helper` | Odgovori o greškama u executorima/handlerima koriste `buildErrorBody()` / `sanitizeErrorMessage()` (Strogo pravilo #12) | Da | -| `check:migration-numbering` | Migracijske SQL datoteke su numerisane uzastopno, bez praznina ili duplikata | Da | -| `check:public-creds` | Nema doslovnih OAuth `client_id`/`client_secret` ili Firebase Web ključeva izvan `publicCreds.ts` (Strogo pravilo #11) | Da | -| `check:db-rules` | Nema sirovog SQL-a izvan modula `src/lib/db/`; nema zbirnih uvoza iz `localDb.ts` (Stroga pravila #2/#5) | Da | -| `check:known-symbols` | Izvršitelji pružalaca usluga, strategije usmjeravanja i prevodioci registrirani u svojim tabelama za otpremu odgovaraju datotekama na disku — nema simbola bez pripadajuće datoteke ili deklaracije | Da | -| `check:route-guard-membership` | Svaka ruta koja pokreće podređeni proces klasificirana je pomoću `isLocalOnlyPath()` (Stroga pravila #15/#17) | Da | -| `check:test-discovery` | Svaku datoteku `*.test.ts` / `*.spec.ts` u repozitoriju prikuplja barem jedan pokretač testova (mehanizam s čegrtaljkom: lista nepridruženih datoteka u `test-discovery-baseline.json` može se samo smanjivati) | Da | -| `check:agent-skills-sync` | Generirani agent-skills artefakti odgovaraju svom izvornom katalogu (bez odstupanja) | -| `check:provider-asset-provenance` | Logotipi/resursi pružatelja imaju evidentiran zapis o porijeklu | -| `lint:json` | JSON konfiguracijske datoteke mogu se parsirati i zadovoljavaju pravila lintanja repozitorija | -| `typecheck:core` | TypeScript kompilacija bez grešaka (samo savjetodavna upozorenja) | Da | -| `typecheck:noimplicit:core` | Strogi `noImplicitAny` — usmjeren na budućnost; mnoga postojeća mjesta poziva još uvijek trebaju anotacije | **Savjetodavno** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ograničen na `src/app/(dashboard)/**` (#7033) — pažljivo odabrana lista od 27 datoteka u `typecheck:core` ne uključuje nijedan dashboard TSX, a ni `next build` ga nikada ne provjerava po tipovima (`next.config.mjs` postavlja `ignoreBuildErrors: true`), pa regresije s identifikatorima bez odgovarajućih definicija tamo (#6625/#6909) nisu bile vidljive CI-ju. Razlike se porede sa zamrznutom početnom vrijednošću broja grešaka po datoteci i TS kodu (`config/quality/dashboard-typecheck-baseline.json`, isti obrazac provođenja za zastarjele unose kao kod `check:known-symbols`) — provjera ne prolazi samo za NOVE greške iznad početnog broja; smanjite početnu vrijednost pomoću `--update` kada se ispravi postojeća greška. | Da | +Pokreće se za svaki PR prema grani `main`. U slučaju neuspjeha blokira spajanje. + +| Skripta (`npm run ...`) | Provjerava | Blokira | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Verzija Node.js-a je unutar podržanog raspona | Da | +| `check:cycles` | Kružne uvoze u cijelom `src/` + `open-sse/` (zasnovano na AST-u, razriješeni tsconfig `paths`). Osnovna provjera = savjetodavna, navodi cikluse. `check:cycles:ratchet` (koji pokreće CI) blokira kada broj premaši gornju granicu `metrics.cycles` u `quality-baseline.json` — trenutno 14, `direction: down`, pa se može samo smanjivati (#15159 G-01/G-02) | Da (postepeno ograničenje) | +| `check:route-validation:t06` | Zod sheme postoje na svim rutama (pravilo nivoa 6) | Da | +| `check:any-budget:t11` | Broj `@ts-expect-error // any` ne premašuje budžet (catraca nivoa 11) | Da | +| `check:provider-consistency` | Svaki pružalac u `providers.ts` ima odgovarajući unos u `providerRegistry.ts` (i obrnuto, unutar liste dozvoljenih) | Da | +| `check:model-lifecycle` | Tri ručno održavane tabele usmjeravanja ostaju usklađene s pohranjenim snimkom životnog ciklusa (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ne boduje nijedan povučeni id koji `REGISTRY` može usmjeriti; svaki cilj iz `BUILT_IN_ALIASES` prisutan je u `REGISTRY` i nije prisutan u snimku povučenih id-ova; svaki povučeni id koji je još uvijek u `REGISTRY` prosljeđuje se ili je naveden u `allowedRetiredInCatalog`; te se nijedan izvor ili cilj iz `DEFAULT_DEGRADATION_MAP` ne pojavljuje kao povučen u tom snimku. Ovo ne dokazuje da model trenutno poslužuje aktivni uzvodni servis. Izvan mreže — poredi s `config/quality/model-lifecycle.json`, koji se ručno osvježava pomoću `npm run quality:refresh-model-lifecycle` (mreža; nije uključen u CI). `allowedRetiredInCatalog` je jednosmjerna kontrola postepenog smanjenja: unos dodajte samo uz povezani zadatak za praćenje. | Da | +| `check:fetch-targets` | Svaki `fetch("/api/...")` u klijentskom direktoriju `src/` razrješava se na stvarni `route.ts` | Da | +| `check:deps` | Sve zavisnosti koje se mogu instalirati pomoću `npm install` iz svakog `package.json` u repozitoriju nalaze se u `dependency-allowlist.json`; nove verzijski nefiksirane ili typosquatting pakete označava kao sumnjive | Da | +| `audit:deps` | `npm audit` (korijenski direktorij + electron) — nema upozorenja visokog/kritičnog nivoa (preklapa se s osv `check:vuln-ratchet`; pogledajte Rationalization Backlog) | Da | +| `check:lockfile` | Integritet datoteke `package-lock.json` — https registar, sažeci integriteta, bez nadjačavanja hostova | Da | +| `check:licenses` | Lista dopuštenih SPDX licenci za produkcijske zavisnosti | Da | +| `check:tracked-artifacts` | Nema artefakata izgradnje / predanih `node_modules` simboličkih veza (također se pokreće u husky pre-commit; pre-push je namjerno pojednostavljen — #6716) | Da | +| `check:ai-attribution` | Nema AI/bot `Co-Authored-By` završnog retka niti podnožja o AI generiranju u commitovima, naslovu ili tijelu PR-a — Strogo pravilo #16 (u petlji brzih provjera `quality.yml` za PR→`release/**` — čita sadržaj događaja, ne radi ništa izvan PR-ova — i korak samo za PR u lint provjeri datoteke `ci.yml` za PR→`main`; također husky `commit-msg` hook; ljudski koautori su dozvoljeni; #14436) | +| `check:vitest-exclusions` | Svako Vitest izuzimanje navodi problem za praćenje i nalazi se u `config/quality/vitest-exclusions.json` (#13204) | Da | +| `check:file-size` | Nijedna datoteka izvornog koda ne premašuje ograničenje za odgovarajuću ekstenziju (mehanizam zapornog zupčanika: velike datoteke zamrznute su na listi `frozen`) | Da | +| `check:error-helper` | Odgovori o greškama u izvršiteljima/rukovateljima koriste `buildErrorBody()` / `sanitizeErrorMessage()` (Strogo pravilo #12) | Da | +| `check:migration-numbering` | Migracijske SQL datoteke su numerisane uzastopno, bez praznina ili duplikata | Da | +| `check:public-creds` | Nema doslovnih OAuth vrijednosti `client_id`/`client_secret` niti Firebase Web ključeva izvan `publicCreds.ts` (Strogo pravilo #11) | Da | +| `check:db-rules` | Nema sirovog SQL-a izvan modula `src/lib/db/`; nema zbirnih uvoza iz `localDb.ts` (Stroga pravila #2/#5) | Da | +| `check:known-symbols` | Izvršitelji pružalaca usluga, strategije usmjeravanja i prevodioci registrovani u svojim tabelama za otpremu podudaraju se s datotekama na disku — nema nepovezanih ili nedeklarisanih simbola | Da | +| `check:route-guard-membership` | Svaka ruta koja pokreće podređeni proces klasifikovana je pomoću `isLocalOnlyPath()` (Stroga pravila #15/#17) | Da | +| `check:test-discovery` | Svaku datoteku `*.test.ts` / `*.spec.ts` u repozitoriju prikuplja najmanje jedan pokretač testova (mehanizam zapornog zupčanika: lista nepovezanih datoteka u `test-discovery-baseline.json` može se samo smanjivati) | Da | +| `check:agent-skills-sync` | Generisani artefakti agent-skills odgovaraju svom izvornom katalogu (bez odstupanja) | +| `check:provider-asset-provenance` | Logotipi/resursi pružatelja imaju evidentiran zapis o porijeklu | +| `lint:json` | JSON konfiguracijske datoteke se mogu parsirati i zadovoljavaju lint pravila repozitorija | +| `typecheck:core` | TypeScript kompilacija bez grešaka (samo savjetodavna upozorenja) | Da | +| `typecheck:noimplicit:core` | Strogi `noImplicitAny` — usmjeren na budućnost; mnoga postojeća mjesta poziva i dalje trebaju anotacije | **Savjetodavno** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ograničen na `src/app/(dashboard)/**` (#7033) — pažljivo odabrana lista od 27 datoteka u `typecheck:core` ne uključuje nijedan dashboard TSX, a ni `next build` ga nikada ne provjerava po tipovima (`next.config.mjs` postavlja `ignoreBuildErrors: true`), pa su regresije vezane za nepovezane identifikatore (#6625/#6909) tamo bile nevidljive CI-ju. Razlike se porede sa zamrznutom osnovnom vrijednošću broja grešaka po datoteci i TS kodu (`config/quality/dashboard-typecheck-baseline.json`, isti obrazac provođenja za zastarjele stavke kao kod `check:known-symbols`) — samo NOVE greške iznad osnovnog broja dovode do pada provjere; smanjite osnovnu vrijednost pomoću `--update` kada se postojeća greška ispravi. | Da | ### Zadatak: `quality-gate` Pokreće se nakon `test-coverage`. Blokira spajanje u slučaju neuspjeha. -| Skripta | Provjerava | Blokirajuće | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -| `quality:collect` | Generira `quality-metrics.json` (broj ESLint upozorenja, pokrivenost iz objedinjenog izvještaja fragmenata) | Da (prethodi mehanizmu ratcheta) | -| `quality:ratchet` | Nijedna metrika u `quality-baseline.json` nije nazadovala (ESLint upozorenja ≤ početna vrijednost; pokrivenost ≥ početna vrijednost) | Da | -| `check:duplication` | Dupliciranje koda (jscpd@4) ne premašuje početnu vrijednost u `quality-baseline.json` | Da | -| `check:complexity` | Ciklomatska složenost na nivou datoteke ne premašuje ograničenje (osnovni ESLint `complexity` + `max-lines-per-function`) | Da | -| `check:cognitive-complexity` | Ratchet kognitivne složenosti (`eslint-plugin-sonarjs`) — zasebno pokretanje ESLint-a; CI pokreće oba objedinjena u jednom koraku `check:complexity-ratchets` | Da | -| `check:dead-code` | Ratchet nekorištenih izvoza / datoteka (knip) ne nazaduje u odnosu na početnu vrijednost | Da | -| `check:compression-budget` | Budžet mjerenja performansi kompresije — minimalne uštede tokena po mehanizmu ne smiju nazadovati | Da | -| `check:type-coverage` | Ratchet procenta tipiziranog koda (`type-coverage`) ne nazaduje; u velikoj mjeri obuhvata `typecheck:noimplicit:core` | Da | -| `check:codeql-ratchet` | Broj otvorenih CodeQL upozorenja ne nazaduje (čita putem `gh api`; uredno preskače bez tokena) — učestalost osvježavanja i ručno pokretanje: pogledajte „CodeQL ratchet“ ispod | Da | - -### Zadatak: `quality-extended` - -Cijeli zadatak je savjetodavan (`continue-on-error: true`). Ratcheti zasnovani na npm-u -zaista se izvršavaju; vanjski skeneri instaliraju se putem `gh release download` i sami -se preskaču (exit 0) kada binarna datoteka još uvijek nije prisutna. - -| Skripta | Provjerava | Blokirajuće | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| `check:circular-deps` | Nema kružnih zavisnosti (dpdm) | **Savjetodavno** | -| `check:bundle-size` | Veličina paketa ne premašuje ograničenje | **Savjetodavno** | -| `check:secrets` | Skeniranje tajni (gitleaks) — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | -| `check:vuln-ratchet` | Ranjivosti zavisnosti (osv-scanner) ne nazaduju — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | -| `check:workflows` | Provjera toka rada (actionlint + zizmor); nedostajući/neispravni skeneri, nevažeći izvještaji ili nedostajuća početna vrijednost ratcheta završavaju kao INCOMPLETE. Važeći nalazi slijede odabranu strogu/savjetodavnu/ratchet politiku | Izvršavanje je obavezno; zizmor ratchet blokira u CI-ju | -| `check:openapi-breaking` | Promjene javnog API ugovora (`openapi.yaml`) koje narušavaju kompatibilnost u odnosu na osnovnu granu (oasdiff) — generira `openapiBreaking=N`; preskače se ako oasdiff nije prisutan ili se osnovna specifikacija ne može razriješiti | **Savjetodavno** | - -### Zadatak: `docs-sync-strict` - -Pokreće se za svaki PR prema `main`. Blokira spajanje u slučaju neuspjeha. - -| Skripta | Provjerava | Blokira | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | -| `check:docs-all` | Meta-kontrola koja redom pokreće 6 podkontrola u nastavku | Da | -| ↳ `check:docs-sync` | Usklađenost verzija između CHANGELOG-a / OpenAPI-ja / llm.txt-a | Da | -| ↳ `check:docs-counts` | Brojevi u tekstu (broj pružalaca, broj migracija itd.) nalaze se unutar pragom definisanog raspona stvarnih brojeva | Da | -| ↳ `check:env-doc-sync` | Svaka varijabla okruženja iz `.env.example` dokumentovana je u tabeli dokumentacije i obrnuto | Da | -| ↳ `check:deprecated-versions` | U dokumentaciji nema zastarjelih oznaka verzija | Da | -| ↳ `check:doc-links` | Interne markdown poveznice u dokumentaciji vode do stvarnih datoteka (oblik `[tekst]`/`(putanja)`) | Da | -| ↳ `check:fabricated-docs` | Rute, varijable okruženja, CLI naredbe, nazivi hookova i putanje datoteka navedeni u dokumentaciji postoje u bazi koda. Stroga kontrola putem `--strict`; bez te zastavice greška nije blokirajuća. | Da (putem `--strict` u CI-ju) | -| `check:cli-i18n` | Nizovi CLI naredbi prisutni su u svim i18n datotekama lokalizacije | Da | -| `check:openapi-coverage` | OpenAPI specifikacija pokriva najmanje prag stvarnih ruta definisan postepenim povećavanjem | Da | -| `check:openapi-security-tiers` | Oznake sigurnosnih nivoa u `openapi.yaml` usklađene su s klasifikacijama u `routeGuard.ts` | **Savjetodavno** | -| `check:openapi-routes` | Svaka putanja u `openapi.yaml` odgovara stvarnoj datoteci `route.ts` (sprečavanje halucinacija) | Da | -| `check:docs-symbols` | Svaka referenca `/api/...` u `docs/**/*.md` odgovara stvarnoj datoteci `route.ts` (sprečavanje halucinacija) | Da | -| `i18n translation drift` | Neprevedeni ključevi u i18n datotekama lokalizacije — samo upozorenje | **Savjetodavno** | - -### Zadatak: `i18n-ui-coverage` - -| Skripta | Provjerava | Blokira | -| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (ugrađeno) | Pokrivenost UI i18n ključeva iznosi ≥ 65% | Da | -| `check-ui-value-drift` (ugrađeno) | Izmijenjena engleska **vrijednost** ne ostavlja nijedan zastarjeli prijevod | Da | -| `check-new-key-coverage` (ugrađeno) | **Novi** engleski ključ preveden je u svakoj lokalizaciji — oznaka `__MISSING__:` se odbija | Da | -| `check-translation-ratio` | Omjer stvarnih prijevoda po lokalizaciji (stavke identične engleskom / rezervirana mjesta / nedostajuće stavke izvan liste dopuštenih izuzetaka) ne smije premašiti `config/quality/i18n-translation-baseline.json` + toleranciju | **Savjetodavno** | - -Zahtijeva `fetch-depth: 0` — kontrola promjene vrijednosti poredi `en.json` s bazom spajanja. +| Skripta | Provjerava | Blokira | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `quality:collect` | Generiše `quality-metrics.json` (broj ESLint upozorenja, pokrivenost iz objedinjenog izvještaja segmenata) | Da (prethodi mehanizmu postepenog pooštravanja) | +| `quality:ratchet` | Nijedna metrika u `quality-baseline.json` nije nazadovala (ESLint upozorenja ≤ početna vrijednost; pokrivenost ≥ početna vrijednost) | Da | +| `check:duplication` | Dupliciranje koda (jscpd@4) ne prelazi početnu vrijednost u `quality-baseline.json` | Da | +| `check:complexity` | Ciklomatska složenost na nivou datoteke ne prelazi ograničenje (osnovni ESLint `complexity` + `max-lines-per-function`) | Da | +| `check:cognitive-complexity` | Postepeno pooštravanje kognitivne složenosti (`eslint-plugin-sonarjs`) — zasebno ESLint izvršavanje; CI izvršava oba objedinjena kao jedan korak `check:complexity-ratchets` | Da | +| `check:dead-code` | Postepeno pooštravanje za nekorištene izvoze/datoteke (knip) ne nazaduje u odnosu na početnu vrijednost | Da | +| `check:compression-budget` | Budžet mjerenja performansi kompresije — minimalne uštede tokena po mehanizmu ne smiju nazadovati | Da | +| `check:type-coverage` | Postotak tipiziranog koda (`type-coverage`) ne nazaduje; uglavnom obuhvata `typecheck:noimplicit:core` | Da | +| `check:codeql-ratchet` | Broj otvorenih CodeQL upozorenja ne nazaduje (čita putem `gh api`; uredno preskače bez tokena) — učestalost osvježavanja i ručno pokretanje: pogledajte „Postepeno pooštravanje za CodeQL“ u nastavku | Da | + +### Posao: `quality-extended` + +Cijeli posao je savjetodavan (`continue-on-error: true`). Mehanizmi postepenog pooštravanja zasnovani na npm-u +izvršavaju se stvarno; vanjski skeneri instaliraju se putem `gh release download` i sami se preskaču (izlazni kod 0) +kada binarna datoteka još uvijek nije prisutna. + +| Skripta | Provjerava | Blokira | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| `check:circular-deps` | Nema kružnih zavisnosti (dpdm) | **Savjetodavno** | +| `check:bundle-size` | Veličina paketa ne prelazi ograničenje | **Savjetodavno** | +| `check:secrets` | Skeniranje tajni (gitleaks) — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | +| `check:vuln-ratchet` | Ranjivosti zavisnosti (osv-scanner) ne nazaduju — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | +| `check:workflows` | Provjera radnih tokova (actionlint + zizmor); nedostajući/neispravni skeneri, nevažeći izvještaji ili nedostajuća početna vrijednost postepenog pooštravanja uzrokuju neuspjeh sa statusom INCOMPLETE. Važeći nalazi slijede odabranu strogu/savjetodavnu politiku ili politiku postepenog pooštravanja | Izvršavanje je obavezno; postepeno pooštravanje za zizmor blokira u CI-ju | +| `check:openapi-breaking` | Kompatibilnost javnog API ugovora (`openapi.yaml`) u odnosu na osnovnu granu (oasdiff) — generiše `openapiBreaking=N`; preskače se ako oasdiff nije prisutan ili se osnovna specifikacija ne može razriješiti | **Savjetodavno** | + +### Posao: `docs-sync-strict` + +Izvršava se za svaki PR prema grani `main`. Blokira spajanje u slučaju neuspjeha. + +| Skripta | Provjerava | Blokirajuće | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `check:docs-all` | Meta-kontrola koja redom pokreće 6 podkontrola navedenih ispod | Da | +| ↳ `check:docs-sync` | Usklađenost verzija u CHANGELOG-u / OpenAPI-ju / llm.txt-u | Da | +| ↳ `check:docs-counts` | Brojevi u tekstu (broj pružalaca, broj migracija itd.) nalaze se unutar granica postepenog praga u odnosu na stvarne brojeve | Da | +| ↳ `check:env-doc-sync` | Svaka varijabla okruženja iz `.env.example` dokumentovana je u tabeli dokumentacije i obrnuto | Da | +| ↳ `check:deprecated-versions` | U dokumentaciji nema zastarjelih oznaka verzija | Da | +| ↳ `check:doc-links` | Interne markdown veze u dokumentaciji upućuju na stvarne datoteke (oblik `[tekst]`/`(putanja)`) | Da | +| ↳ `check:fabricated-docs` | Rute, varijable okruženja, CLI naredbe, nazivi hookova i putanje datoteka navedeni u dokumentaciji postoje u bazi koda. Stroga kontrola putem `--strict`; bez zastavice neuspjeh je samo upozorenje. | Da (putem `--strict` u CI-ju) | +| `check:cli-i18n` | Tekstovi CLI naredbi prisutni su u svim i18n datotekama lokalizacije | Da | +| `check:openapi-coverage` | OpenAPI specifikacija pokriva najmanje postepeno utvrđeni minimalni prag stvarnih ruta | Da | +| `check:openapi-security-tiers` | Oznake sigurnosnih nivoa u `openapi.yaml` usklađene su s klasifikacijama u `routeGuard.ts` | **Savjetodavno** | +| `check:openapi-routes` | Svaka putanja u `openapi.yaml` odgovara stvarnom `route.ts` (sprečavanje halucinacija) | Da | +| `check:docs-symbols` | Svaka `/api/...` referenca u `docs/**/*.md` odgovara stvarnom `route.ts` (sprečavanje halucinacija) | Da | +| `i18n translation drift` | Neprevedeni ključevi u i18n datotekama lokalizacije — samo upozorenje | **Savjetodavno** | + +### Posao: `i18n-ui-coverage` + +| Skripta | Provjerava | Blokirajuće | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `check-ui-keys-coverage` (ugrađeno) | Pokrivenost UI i18n ključeva iznosi ≥ 65% | Da | +| `check-ui-value-drift` (ugrađeno) | Izmijenjena engleska **vrijednost** ne ostavlja za sobom zastarjeli prijevod | Da | +| `check-new-key-coverage` (ugrađeno) | **Novi** engleski ključ preveden je u svakoj lokalizaciji — oznaka `__MISSING__:` se odbija | Da | +| `check-translation-ratio` | Omjer stvarnih prijevoda po lokalizaciji (vrijednosti identične engleskim / rezervirana mjesta / nedostajući listovi izvan liste dozvoljenih) ne smije premašiti `config/quality/i18n-translation-baseline.json` + toleranciju | **Savjetodavno** | + +Zahtijeva `fetch-depth: 0` — kontrola odstupanja vrijednosti poredi `en.json` s osnovom spajanja. #### `check-ui-value-drift` — kontrola zastarjelih prijevoda -Otkriva onu i18n regresiju koju ostale kontrole strukturno ne mogu uočiti: engleska vrijednost -se izmijeni, a prijevodi izvedeni iz _prethodnog_ engleskog ostanu nepromijenjeni, pa -korisnici koji ne koriste engleski nastavljaju čitati uvjerljivo sročen, ali sada netačan tekst. +Otkriva onu i18n regresiju koju druge kontrole strukturno ne mogu uočiti: engleska vrijednost +se prepravi, dok prijevodi izvedeni iz _prethodnog_ engleskog ostanu nepromijenjeni, pa +korisnici koji ne koriste engleski nastavljaju čitati uvjerljivo sročen, ali sada pogrešan tekst. -Ovo je zaista dospjelo u produkciju. `oauthModal.googleOAuthWarning` je izmijenjen kada je -uveden pomoćnik za prijavu Antigravity (#5203); **39 od 43 lokalizacije** zadržalo je tekst koji -je operaterima govorio da „kopiraju puni URL i zalijepe ga ispod“ — tok koji se ne može dovršiti -za tog pružaoca. Problem je ostao neprimijećen sve do #8463 jer: +Ovo se zaista pojavilo u izdanju. `oauthModal.googleOAuthWarning` je prepravljen kada je uveden +Antigravity pomoćnik za prijavu (#5203); **39 od 43 lokalizacije** zadržalo je tekst koji je +operaterima govorio da „kopiraju cijeli URL i zalijepe ga ispod” — tok koji se za tog pružaoca +ne može dovršiti. Problem je ostao neprimijećen sve do #8463 zato što: -- `sync-ui-keys` popunjava samo ključeve koji **nedostaju**, nikada one koji su **zastarjeli**; -- `check-ui-keys-coverage` broji _prisutnost_ ključeva, pa se zastarjeli prijevod računa kao pokriven; -- `check-translation-drift` prati dokumentacijske kopije `docs/i18n//**.md` — - nikada ne čita `src/i18n/messages/*.json`. Blokira u zadatku `docs-sync-strict` od - ponovne sinhronizacije 2026-09: izmijenite osnovni dokument → `npm run i18n:run -- --files=` (na nivou odjeljka, brzo). +- `sync-ui-keys` samo naknadno dodaje ključeve koji **nedostaju**, a nikada one koji su **zastarjeli**; +- `check-ui-keys-coverage` broji _prisutnost_ ključa, pa se zastarjeli prijevod računa kao pokriven; +- `check-translation-drift` prati dokumentacijska ogledala `docs/i18n//**.md` — + nikada ne čita `src/i18n/messages/*.json`. Blokira u poslu `docs-sync-strict` od + ponovne sinhronizacije 2026-09: uredite osnovni dokument → `npm run i18n:run -- --files=` (na nivou odjeljka, brzo). -**Svjestan razlika, bez oslanjanja na bazno stanje.** Poredi `en.json` na bazi spajanja s -radnim stablom; za svaki ključ čija se engleska vrijednost promijenila, svaki lokalitet koji još uvijek sadrži -netaknuti prijevod smatra se zastarjelim. Ovo namjerno **zamrzava prethodno postojeći dug** — razlika -ne može otkriti iz koje je stare engleske vrijednosti nastao dugotrajni prijevod, pa kontrola procjenjuje -samo ono što trenutna izmjena dotiče. Alternativa (bazno stanje hash vrijednosti za svaki ključ) zahtijevala bi -generisanu datoteku od ~600 KB, 3× veću od najvećeg postojećeg baznog stanja, koja bi se mijenjala pri svakom i18n PR-u. +**Uvažava razlike, nije zasnovano na baznoj liniji.** Poredi `en.json` na osnovi spajanja s +radnim stablom; za svaki ključ čija se engleska vrijednost promijenila, svaki lokalitet koji +još uvijek sadrži neizmijenjen prijevod smatra se zastarjelim. Ovo namjerno **zamrzava +prethodno postojeći dug** — razlika ne može otkriti iz koje je stare engleske vrijednosti +nastao dugogodišnji prijevod, pa kontrola procjenjuje samo ono na šta trenutna izmjena +utiče. Alternativa (bazna linija heša za svaki ključ) zahtijevala bi generisanu datoteku +veličine ~600 KB, 3× veću od najveće postojeće bazne linije, koja bi se mijenjala pri svakom +i18n PR-u. -Postoje dva načina da se kontrola zadovolji: +Postoje dva načina da se zahtjev ispuni: -1. ažurirajte zahvaćene prijevode ili -2. postavite ih na `__MISSING__:` — izvršno okruženje tada poslužuje ispravljeni engleski - (`src/i18n/request.ts::deepMergeFallback`, #7258), a ključ se stavlja u red za prevođenje. +1. ažurirati obuhvaćene prijevode ili +2. postaviti ih na `__MISSING__:` — izvršno okruženje tada isporučuje + ispravljeni engleski tekst (`src/i18n/request.ts::deepMergeFallback`, #7258), a ključ se + stavlja u red za prevođenje. -Ako se promijenilo **značenje** stringa, poželjno je **preimenovati ključ**: novi ključ ne može naslijediti -zastarjeli prijevod. To je obrazac korišten u #8463. +Ako se promijenilo **značenje** niza, poželjno je **preimenovati ključ**: novi ključ ne može +naslijediti zastarjeli prijevod. To je obrazac korišten u #8463. ```bash -npm run i18n:check-value-drift # strogo (ono što CI izvršava) +npm run i18n:check-value-drift # strogo (ono što CI pokreće) npm run i18n:check-value-drift:warn # samo izvještaj BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Završava s kodom 0 i porukom `SKIP reason=base-unresolved` kada se osnovni katalog ne može pročitati (plitki -klon bez osnovne reference), prateći ponašanje `check-openapi-breaking`. +Završava s kodom 0 i porukom `SKIP reason=base-unresolved` kada se osnovni katalog ne može +pročitati (plitko kloniranje bez osnovne reference), po uzoru na `check-openapi-breaking`. ### Zadatak: `i18n` -Potpuna matrica i18n validacije (jedan zadatak po lokalitetu). Cijeli zadatak je savjetodavan. +Potpuna matrica i18n provjere (jedan zadatak po lokalitetu). Cijeli zadatak je savjetodavan. -| Skripta | Validira | Blokiranje | -| ------------------------------- | --------------------------------- | --------------------------------------------------------------- | -| `validate_translation.py quick` | Potpunost prijevoda po lokalitetu | **Savjetodavno** (`continue-on-error: true` na cijelom zadatku) | +| Skripta | Provjerava | Blokira | +| ------------------------------- | -------------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | Potpunost prijevoda za svaki lokalitet | **Savjetodavno** (`continue-on-error: true` za cijeli zadatak) | ### Zadatak: `pr-test-policy` -Izvršava se samo za zahtjeve za spajanje. +Pokreće se samo za zahtjeve za spajanje. -| Skripta | Validira | Blokiranje | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PR-ovi koji mijenjaju produkcijski kod u `src/`, `open-sse/`, `electron/` ili `bin/` moraju uključiti ili ažurirati testove (Strogo pravilo #8) | Da | -| `check:test-masking` | Izmijenjene testne datoteke ne smanjuju neto broj provjera niti dodaju tautologije `assert.ok(true)` | Da | -| `check:pr-evidence` | Tijelo PR-a navodi dokaze testiranja/VPS-a za izmjenu (automatizira Strogo pravilo #18 pretraživanjem teksta PR-a — krhko, pogledajte Backlog) | Da | +| Skripta | Provjerava | Blokira | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `check:pr-test-policy` | PR-ovi koji mijenjaju produkcijski kod u `src/`, `open-sse/`, `electron/` ili `bin/` moraju uključiti ili ažurirati testove (Strogo pravilo #8) | Da | +| `check:test-masking` | Izmijenjene testne datoteke ne smanjuju neto broj provjera niti dodaju tautologije `assert.ok(true)` | Da | +| `check:pr-evidence` | Opis PR-a navodi dokaze iz testova/VPS-a za izmjenu (automatizira Strogo pravilo #18 pretraživanjem teksta PR-a — nepouzdano, pogledajte Backlog) | Da | ### Zadatak: `test-vitest` -Izvršava se nakon `build`. Blokira spajanje u slučaju neuspjeha. +Pokreće se nakon `build`. Neuspjeh blokira spajanje. -| Paket testova | Validira | Blokiranje | +| Paket testova | Provjerava | Blokira | | ---------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `test:vitest` | MCP server (110 alata), autoCombo, predmemorija — vitest pokretač | Da | | `test:vitest:ui` | Testovi UI komponenti — vitest pokretač | **Blokira** — prethodno postojeći neuspjesi izričito su izuzeti u `vitest.config.ts`; novi neuspjesi obaraju zadatak | ### Noćni radni tokovi (zakazani, savjetodavni) -Izvršavaju se prema cron rasporedu (i putem `workflow_dispatch`), nikada na PR-ovima. Svi su savjetodavni. +Pokreću se prema cron rasporedu (i putem `workflow_dispatch`), nikada na PR-ovima. Svi su +savjetodavni. -| Radni tok | Validira | Blokiranje | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -| `nightly-property` | fast-check testove svojstava s nasumičnom početnom vrijednošću + velikim brojem izvršavanja | **Savjetodavno** | -| `nightly-resilience` | kontrolu rasta heap memorije, ubrizgavanje haotičnih grešaka, k6 testove opterećenja/izdržljivosti | **Savjetodavno** | -| `nightly-llm-security` | promptfoo zaštitu od ubrizgavanja (režim blokiranja) + garak provjere (preskaču se bez tajne pružaoca usluge) | **Savjetodavno** | -| `nightly-schemathesis` | fuzzing OpenAPI ugovora (schemathesis) nad aktivnim OmniRouteom koristeći `docs/openapi.yaml` — otkriva kršenja specifikacije / neobrađene greške 500 (Faza 8 B.4) | **Savjetodavno** | -| `nightly-mutation` | rezultat Stryker mutacijskog testiranja nad brzom jedinicom testnom granom — preživjeli mutanti otkrivaju slabe provjere | **Savjetodavno** | -| `nightly-compat` | matricu kompatibilnosti Node pokretača u podržanim rasponima `engines.node` | **Savjetodavno** | +| Radni tok | Provjerava | Blokira | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | fast-check testove svojstava s nasumičnim početnim brojem + velikim brojem pokretanja | **Savjetodavno** | +| `nightly-resilience` | kontrolu rasta heap memorije, chaos ubacivanje grešaka, k6 testiranje opterećenja/izdržljivosti | **Savjetodavno** | +| `nightly-llm-security` | promptfoo zaštitu od ubacivanja (blokirajući režim) + garak sonde (preskaču se bez tajne pružaoca usluge) | **Savjetodavno** | +| `nightly-schemathesis` | Fuzz testiranje OpenAPI ugovora (schemathesis) nad aktivnim OmniRouteom koristeći `docs/openapi.yaml` — otkriva kršenja specifikacije / neobrađene greške 500 (Faza 8 B.4) | **Savjetodavno** | +| `nightly-mutation` | Rezultat Stryker mutacijskog testiranja nad brzom trakom jediničnih testova — preživjeli mutanti otkrivaju slabe provjere | **Savjetodavno** | +| `nightly-compat` | Matricu kompatibilnosti Node pogona kroz podržane raspone `engines.node` | **Savjetodavno** | --- @@ -491,32 +495,43 @@ nije automatski učitan (vi birate i verifikujete MCP↔LSP most); neispravan un --- -## Backlog racionalizacije (ROI pregled — Faza 9 Talas 3) - -Ovaj inventar je usklađen sa `ci.yml` dana 17.06.2026. (prethodna verzija je izostavila `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). ROI pregled usklađenog skupa identifikovao je sljedeće kandidate za racionalizaciju. **Spajanja su mehaničke CI izmjene; promjene/odbacivanja su odluke o politici rezervisane za operatera.** Ništa od navedenog još nije primijenjeno. - -**Također, gore nije dokumentovano** (savjetodavno, nizak signal): `docs-lint` posao (markdownlint + Vale, cijeli posao `continue-on-error`) i samostalni radni tokovi skenera `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` se nalazi u `quality-baseline.json`, ali nije povezan sa blokirajućim ratchet-om u `ci.yml` — metrika je trenutno bez vlasnika. - -### Spajanje / dedup (mehaničko, manji rizik) - -Svaki kandidat je validiran u odnosu na stanje "live gate" na dan 17.06.2026. (povjerenje-ali-provjera); nekoliko "očiglednih" spajanja se ispostavilo da skrivaju dug i **nisu** čiste zamjene. - -- **`check:docs-sync` se pokreće dvaput** — samostalno u `lint` poslu i ponovo unutar `check:docs-all` (`docs-sync-strict`) i husky pre-commit hook-a. ✅ **GOTOVO** — samostalna `lint` invokacija uklonjena. -- **CVE skeniranje** — ❌ **NIJE čisto spajanje.** `audit:deps` strogo pada na bilo kojem visokom/kritičnom CVE-u; `check:vuln-ratchet` (osv) pada samo na _regresiji_ u odnosu na osnovnu vrijednost (trenutno 1 MODERATE). Različita semantika — odbacivanje `audit:deps` bi značilo gubitak apsolutne visoke/kritične kapije. Zadržati oba. -- **Detekcija ciklusa** — ❌ **NIJE čisto spajanje.** `check:circular-deps` (dpdm) prijavljuje **91 ciklus** (zato je savjetodavno); ne može se promovisati u blokirajuće bez prethodnog rješavanja, a ima širi obim od zelenog, kuriranog `check:cycles`. Zadržati `check:cycles` kao blokirajući; rješavanje 91 dpdm ciklusa je poseban zaostatak. -- **Kompleksnost** — ✅ **GOTOVO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jedan ESLint prolaz, broji po ruleId tako da ciklomatske+max-lines i kognitivne osnovne vrijednosti ostaju nezavisne; pojedinačni `check:complexity` / `check:cognitive-complexity` ostaju za lokalni `--update`. -- **`/api` anti-halucinacija** — ✅ **GOTOVO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jedan FS inventar `src/app/api`, openapi-routes + docs-symbols i dalje izvještavaju nezavisno; pojedinačni ostaju za lokalna pokretanja. -- **`check:node-runtime` se pokreće u 11 poslova** — ⚠️ **nizak ROI.** Svaki je poseban runner i provjera traje <1s; ukupne uštede ~10s, naspram gubitka jeftine zaštite po poslu. Nije vrijedno truda. -- **`typecheck:noimplicit:core` na CI lint-u** — ✅ **uklonjeno iz lint posla** (bilo je savjetodavno `continue-on-error`); blokirajuća površina tipova je `typecheck:core` + `check:type-coverage`. Lokalna skripta zadržana. - -### Promjena / odluka (politika operatera) - -- `check:openapi-security-tiers` (savjetodavno) — ❌ **NIJE lako promjenjivo.** Izlazi sa 0, ali upozorava da nekoliko `traffic-inspector` ruta pod `LOCAL_ONLY_API_PREFIXES` nema `x-loopback-only: true` anotaciju. Sprovođenje zahtijeva prvo dodavanje tih anotacija u `openapi.yaml`. -- `typecheck:noimplicit:core` (savjetodavno) — uglavnom obuhvaćeno blokirajućim `check:type-coverage` ratchet-om. Promijeniti u ratchet ili odbaciti redundantni drugi `tsc` prolaz. -- `test:vitest:ui` (sada **blokirajuće**) — postojeći kvarovi su eksplicitno isključeni u `vitest.config.ts` sa `// #8618` komentarima za praćenje; novi kvarovi obaraju posao. -- `check:secrets` (gitleaks, blokirajući ratchet zamrznut na 3 dokumentovana lažna pozitivna rezultata) — staviti 3 na listu dozvoljenih da bi se došlo do 0, ili degradirati na savjetodavno. Preklapa se sa GitHub izvornim skeniranjem tajni + `check:public-creds`. -- `check:pr-evidence` (blokirajuće, grepuje prozu u tijelu PR-a) — visok rizik od lažnih pozitivnih rezultata; slabi sprovođenje Hard Rule #18 ako se odbaci, tako da je ovo istinska odluka o politici. -- `semgrep` (savjetodavno samostalno) — preklapa se sa CodeQL za OWASP familije; povezati njegovu osnovnu vrijednost sa ratchet-om ili odbaciti. +## Zaostatak racionalizacije (pregled ROI-ja — Faza 9 Talas 3) + +Ovaj inventar je usklađen sa `ci.yml` 2026-06-17 (prethodna verzija je izostavila +`audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, +`check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, +`check:codeql-ratchet`, `check:pr-evidence`). Pregled ROI-ja usklađenog skupa +identificirao je sljedeće kandidate za racionalizaciju. **Spajanja su mehaničke CI +izmjene; promjene statusa/uklanjanja su odluke o pravilima rezervirane za operatera.** Ništa od navedenog +još nije primijenjeno. + +**Također nije dokumentirano iznad** (savjetodavno, slab signal): zadatak `docs-lint` +(markdownlint + Vale, cijeli zadatak ima `continue-on-error`) i samostalni tokovi rada skenera +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` se nalazi u +`quality-baseline.json`, ali nije povezan s blokirajućim mehanizmom postepenog pooštravanja u `ci.yml` — metrika je +trenutno nepovezana. + +### Spajanje / uklanjanje duplikata (mehanički, manji rizik) + +Svaki kandidat je provjeren u odnosu na aktivno stanje kontrolnih tačaka 2026-06-17 (vjeruj, ali provjeri); +ispostavilo se da nekoliko „očiglednih” spajanja skriva dug i **nisu** neposredno primjenjiva. + +- **`check:docs-sync` se pokreće dvaput** — samostalno u zadatku `lint` i ponovo unutar `check:docs-all` (`docs-sync-strict`) te u husky pre-commit kuki. ✅ **ZAVRŠENO** — samostalno pokretanje u zadatku `lint` je uklonjeno. +- **CVE skeniranje** — ❌ **NIJE jednostavno spajanje.** `audit:deps` bezuslovno ne prolazi za bilo koji CVE visoke/kritične ozbiljnosti; `check:vuln-ratchet` (osv) ne prolazi samo pri _regresiji_ u odnosu na osnovno stanje (trenutno 1 MODERATE). Različite semantike — uklanjanjem `audit:deps` izgubila bi se apsolutna kontrolna tačka za visoku/kritičnu ozbiljnost. Zadržati oba. +- **Otkrivanje ciklusa** — ✅ **ZAVRŠENO** (#15159 G-01/G-02). Stari tekst je ovdje nazivao `check:cycles` „zelenom, pažljivo odabranom” kontrolnom tačkom i opravdavao njeno zadržavanje kao blokirajuće jer je `check:circular-deps` (dpdm) prijavljivao 91 ciklus. To zeleno stanje bilo je **lažno zeleno**: `check:cycles` je skenirao 5 poddirektorija (450 datoteka), prepoznavao samo statičke izraze `import|export … from` i odbacivao svaki specifikator `@/` i `@omniroute/open-sse/`, pa nije mogao uočiti cikluse dinamičkog uvoza + aliasa koji su dominirali repozitorijem. Ispravljeno: kontrolna tačka sada prolazi kroz `src` + `open-sse` (5023 datoteke), prikuplja specifikatore iz TypeScript AST-a (tako da se `import("…")` računa, dok se `typeof import("…")` na poziciji tipa ne računa) i razrješava tsconfig `paths`. Pronalazi **14** ciklusa, a ne 0. Budući da se 14 prethodno postojećih ciklusa ne može ispraviti u PR-u kontrolne tačke, `check:cycles` je sada **mehanizam postepenog pooštravanja** (`--ratchet`, gornja granica `metrics.cycles.value = 14` u `quality-baseline.json`, `direction: down`) — blokira svaku _regresiju_, a broj se može samo smanjivati. CI pokreće `npm run check:cycles:ratchet`. Postepeno uklanjanje duga odvija se u sklopu **A-01**. `check:circular-deps` (dpdm) ostaje savjetodavan kao šire drugo mišljenje. +- **Složenost** — ✅ **ZAVRŠENO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jedan ESLint prolaz, brojanje prema ruleId-u kako bi osnovna stanja ciklomatske složenosti + maksimalnog broja linija i kognitivne složenosti ostala nezavisna; pojedinačne provjere `check:complexity` / `check:cognitive-complexity` ostaju za lokalni `--update`. +- **`/api` zaštita od halucinacija** — ✅ **ZAVRŠENO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jedan FS inventar za `src/app/api`, openapi-routes + docs-symbols i dalje izvještavaju nezavisno; pojedinačne provjere ostaju za lokalna pokretanja. +- **`check:node-runtime` se pokreće u 11 zadataka** — ⚠️ **nizak ROI.** Svaki je zaseban izvršitelj, a provjera traje <1s; ukupna ušteda je ~10s, uz gubitak jeftine zaštite za svaki zadatak. Nije vrijedno izmjena. +- **`typecheck:noimplicit:core` u CI lint zadatku** — ✅ **uklonjeno iz lint zadatka** (bilo je savjetodavno uz `continue-on-error`); blokirajuću površinu tipova čine `typecheck:core` + `check:type-coverage`. Lokalna skripta je zadržana. + +### Promijeniti status / odlučiti (pravila operatera) + +- `check:openapi-security-tiers` (savjetodavno) — ❌ **NE MOŽE se jednostavno učiniti blokirajućim.** Završava s kodom 0, ali upozorava da nekolicini `traffic-inspector` ruta pod `LOCAL_ONLY_API_PREFIXES` nedostaje anotacija `x-loopback-only: true`. Njegovo nametanje prvo zahtijeva dodavanje tih anotacija u `openapi.yaml`. +- `typecheck:noimplicit:core` (savjetodavno) — u velikoj mjeri ga zamjenjuje blokirajući mehanizam postepenog pooštravanja `check:type-coverage`. Pretvoriti ga u mehanizam postepenog pooštravanja ili ukloniti redundantni drugi `tsc` prolaz. +- `test:vitest:ui` (sada **blokirajuće**) — prethodno postojeći neuspjesi izričito su isključeni u `vitest.config.ts` pomoću komentara za praćenje `// #8618`; novi neuspjesi obaraju zadatak. +- `check:secrets` (gitleaks, blokirajući mehanizam postepenog pooštravanja zamrznut na 3 dokumentirana lažno pozitivna rezultata) — dodati ta 3 rezultata na listu dozvoljenih kako bi se došlo do 0 ili ga spustiti na savjetodavni status. Preklapa se s GitHubovim izvornim skeniranjem tajni + `check:public-creds`. +- `check:pr-evidence` (blokirajuće, pretražuje prozni tekst tijela PR-a) — visok rizik od lažno pozitivnih rezultata; uklanjanje bi oslabilo provođenje strogog pravila br. 18, tako da je ovo stvarna odluka o pravilima. +- `semgrep` (savjetodavni samostalni tok) — preklapa se s CodeQL-om za OWASP porodice; povezati njegovo osnovno stanje s mehanizmom postepenog pooštravanja ili ga ukloniti. --- diff --git a/docs/i18n/cs/CONTRIBUTING.md b/docs/i18n/cs/CONTRIBUTING.md index 210ac23b1e3..29148431eea 100644 --- a/docs/i18n/cs/CONTRIBUTING.md +++ b/docs/i18n/cs/CONTRIBUTING.md @@ -391,18 +391,18 @@ Napište unit testy v `tests/unit/`, které budou pokrývat minimálně: - [ ] Testy procházejí (`npm test`) - [ ] Kontrola lintování prochází (`npm run lint`) -- [ ] Sestavení je úspěšné (`npm run build`) +- [ ] Sestavení proběhne úspěšně (`npm run build`) - [ ] Pro nové veřejné funkce a rozhraní byly přidány typy TypeScriptu -- [ ] Žádná natvrdo zadaná tajemství ani záložní hodnoty -- [ ] Veřejné přihlašovací údaje upstreamu jsou vloženy prostřednictvím `resolvePublicCred()` (viz [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikdy jako literály -- [ ] Chybové odpovědi procházejí přes `buildErrorBody()` / `sanitizeErrorMessage()` — těla odpovědí neobsahují nezpracované výpisy zásobníku (viz [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Příkazy shellu (`exec` / `spawn`) předávají hodnoty za běhu prostřednictvím `env`, nikoli pomocí interpolace řetězců +- [ ] Žádné pevně zadané tajné údaje ani záložní hodnoty +- [ ] Veřejné přihlašovací údaje upstreamu jsou vloženy pomocí `resolvePublicCred()` (viz [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikdy jako literály +- [ ] Chybové odpovědi procházejí přes `buildErrorBody()` / `sanitizeErrorMessage()` — v tělech odpovědí nejsou žádné nezpracované výpisy zásobníku (viz [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shellové příkazy (`exec` / `spawn`) předávají hodnoty za běhu prostřednictvím `env`, nikoli pomocí interpolace řetězců - [ ] Všechny vstupy jsou validovány pomocí schémat Zod - [ ] Pro změny viditelné uživatelům byl přidán **fragment** přehledu změn do `changelog.d/{features|fixes|maintenance}/-.md` (viz [`changelog.d/README.md`](./changelog.d/README.md)) — neupravujte přímo `CHANGELOG.md`; fragmenty se slučují při vydání a mezi Pull Requesty nikdy nevznikají konflikty - [ ] Dokumentace byla aktualizována (pokud je to relevantní) -- [ ] Nebyla vytvořena žádná nová upozornění CodeQL / Secret-Scanning, případně bylo každé z nich zamítnuto s technickým odůvodněním odkazujícím na příslušný dokument v `docs/security/` -- [ ] Trasy, které spouštějí podřízené procesy (`/api/mcp/`, `/api/cli-tools/runtime/`), jsou v `src/server/authz/routeGuard.ts` klasifikovány jako `isLocalOnlyPath()` — viz [Pevné pravidlo č. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Zprávy commitů neobsahují patičky `Co-Authored-By` — commity musí být uvedeny výhradně pod identitou Git vlastníka repozitáře (Pevné pravidlo č. 16) +- [ ] Nebyla vytvořena žádná nová upozornění CodeQL / Secret-Scanning, případně byla všechna zamítnuta s technickým odůvodněním odkazujícím na příslušný dokument v `docs/security/` +- [ ] Trasy, které spouštějí podřízené procesy (`/api/mcp/`, `/api/cli-tools/runtime/`), jsou klasifikovány jako `isLocalOnlyPath()` v `src/server/authz/routeGuard.ts` — viz [Pevné pravidlo č. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Zprávy commitů neobsahují patičky AI/botů `Co-authored-by` (Pevné pravidlo č. 16) — lidští spolupracovníci, jejichž práce je znovu použita, jsou uvedeni pomocí standardních patiček `Co-authored-by: Jméno ` --- diff --git a/docs/i18n/cs/docs/architecture/QUALITY_GATES.md b/docs/i18n/cs/docs/architecture/QUALITY_GATES.md index c4e663b121b..05d98e5c38b 100644 --- a/docs/i18n/cs/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/cs/docs/architecture/QUALITY_GATES.md @@ -15,263 +15,267 @@ stejného systému nezávislý na konkrétních nástrojích naleznete v dokumen --- -## Inventář kontrolních bran a profily spouštění +## Inventář bran a profily spouštění ### Přijetí kandidáta -Workflowy CI a Quality Gates vydávají stabilní verdikt: `Gate / CI` a -`Gate / Quality`. Jejich verzované zásady přijímání uvádějí každou upstreamovou úlohu -jako povinnou nebo poradní. Každá relevantní povinná úloha musí uspět: chybějící, -zrušené, přeskočené, čekající a neznámé výsledky nemohou potvrdit stav PASS. Platná -klasifikace pouze pro dokumentaci nebo pouze pro katalog může způsobit, že větev pro kód nebude relevantní; -koncept PR není přijatelným kandidátem. Štítek `hotfix` neruší požadavek na důkazy. +Workflowy CI a Quality Gates poskytují stabilní verdikt: `Gate / CI` a +`Gate / Quality`. Jejich verzovaná politika přijetí označuje každou nadřazenou úlohu +jako povinnou nebo doporučující. Příslušná povinná úloha musí být úspěšná: chybějící, +zrušené, přeskočené, čekající ani neznámé výsledky nemohou stanovit stav PASS. Platná +klasifikace pouze pro dokumentaci nebo pouze pro katalog může způsobit, že větev +pro kód nebude použitelná; koncept PR není přijatelným kandidátem. Štítek `hotfix` +neruší požadavky na důkazy. -Oba workflowy pokrývají PR a pushnutí do hlavních/release větví, ruční spuštění a -události skupin slučování. Pushnutí, ruční spuštění a skupiny slučování spouštějí úplný výběr. Forky -a skupiny slučování používají hostované runnery pro úlohy, které by jinak zvolily self-hosted -runnery; před nasazením je nutné ověřit dostatečnou hostovanou kapacitu. +Oba workflowy pokrývají PR a pushnutí do hlavních/release větví, ruční spuštění +a události skupin slučování. Pushnutí, ruční spuštění a skupiny slučování spouštějí +úplný výběr. Forky a skupiny slučování používají hostované runnery pro úlohy, které +by jinak vybíraly self-hosted runnery; před zavedením musí být ověřena dostatečná +kapacita hostovaných runnerů. Každá účtenka JSON identifikuje SHA checkoutu, běh workflow a pokus. -CLI odmítne nesoulad mezi SHA checkoutu a události. Testy workflow vážou členství v zásadách -na seznam `needs` úlohy s verdiktem, takže nová nebo odebraná větev nemůže tiše zmizet. -Účtenky pokrývají vlastní workflow, nikoli publikování, nasazení ani vnitřní fungování -existujícího poradního skeneru. Aktivace obou názvů kontrol v pravidlech větve je -samostatná administrativní změna; přidání těchto úloh samo o sobě větev nechrání. +CLI odmítne nesoulad SHA checkoutu a události. Testy workflow vážou členství v politice +na seznam `needs` úlohy s verdiktem, takže nová nebo odebraná větev nemůže nepozorovaně +zmizet. Účtenky pokrývají vlastní workflow, nikoli publikování, nasazení ani interní +fungování existujícího doporučujícího skeneru. Aktivace obou názvů kontrol v pravidlech +větví je samostatnou administrativní změnou; samotné přidání těchto úloh větev nechrání. ### Inventář statických kontrol Verzovaný inventář aliasů npm a členství ve statických kontrolách se nacházejí v -`config/quality/gate-manifest.json`. Spusťte `npm run check:gate-manifest` a ověřte -názvy skriptů a přesné příkazy vůči souboru `package.json`; přidání, odebrání a -změny příkazů způsobí selhání lokálního hooku i úloh klasifikace změn v CI. -Alias není úlohou workflow, instancí matice ani testovacím případem: tyto počty +`config/quality/gate-manifest.json`. Spuštěním `npm run check:gate-manifest` ověřte +názvy skriptů a přesné příkazy vůči `package.json`; přidání, odebrání a změny příkazů +způsobí selhání jak lokálního hooku, tak úloh klasifikace změn v CI. +Alias není úloha workflow, instance matice ani testovací případ: počty těchto položek nesmějí být prezentovány jako vzájemně zaměnitelné. Pomocí `npm run quality:scan -- --list` nebo `npm run quality:scan:fast -- --list` -můžete vybrané aliasy zkontrolovat bez jejich spuštění. Runner volá vstupní bod -npm, takže jeho běhové prostředí (včetně Bun, kde je nakonfigurován) zůstává zachováno. -Manifest eviduje aliasy mimo tyto profily jako spouštěné samostatně a -v profilech kontrol určených pouze pro čtení jsou příkazy údržby zakázány. +můžete zkontrolovat vybrané aliasy bez jejich spuštění. Runner volá vstupní bod +npm, takže je zachováno jeho běhové prostředí (včetně Bun tam, kde je nakonfigurován). +Manifest zaznamenává aliasy mimo tyto profily jako spouštěné samostatně a +v profilech kontrol pouze pro čtení jsou příkazy údržby zakázány. Tyto profily pokrývají pouze statické kontroly. Necertifikují produktové testy, pokrytí, balení, externí kontroly ani úplné přijetí kandidáta k vydání. -Přijímání ve workflow používá propojené soubory `config/quality/admission-policy.json` a -`scripts/quality/admission-verdict.mjs`. Profily release observeru zůstávají oddělené; -jejich relevantní kontroly a účtenky prověřujte nezávisle. Níže uvedený textový -inventář slouží jako reference, nikoli jako důkaz, že kontrolní brána skutečně proběhla. +Přijetí workflow používá propojené soubory `config/quality/admission-policy.json` a +`scripts/quality/admission-verdict.mjs`. Profily pozorovatele vydání zůstávají oddělené; +jejich příslušné kontroly a účtenky prověřujte nezávisle. Níže uvedený textový +inventář slouží jako reference, nikoli jako důkaz, že byla brána skutečně spuštěna. -Skripty se nacházejí v `scripts/check/` (kontrolní brány zásad) a `scripts/quality/` (ratchet engine). +Skripty se nacházejí v `scripts/check/` (brány politik) a `scripts/quality/` (ratchet engine). Zdrojem pravdy pro CI je `.github/workflows/ci.yml`. -### Zrychlený průchod pro release PR (`quality.yml`) +### Zrychlená cesta pro release PR (`quality.yml`) `.github/workflows/quality.yml` doplňuje CI pro PR do hlavních/release větví, pushnutí do chráněných větví, ruční spuštění a skupiny slučování. PR používají rychlé kontroly -filtrované podle cest. Trvale zakázaný duplicitní build byl odstraněn; skutečné kontroly -buildu, balíčku a spuštění zůstávají v CI. - -| Úloha | Rozsah | Blokující | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `Docs Gates (fast-path)` | PR dokumentace/kódu; reference dokumentace API a veškerá dokumentace | Ano | -| `Fast Quality Gates` | PR s kódem; statické kontroly, typecheck, typecheck dashboardu, ovlivněné jednotkové testy | Ano | -| `Forgotten sibling tests` | PR s kódem; změněné moduly dohledané ke statickým konzumentům a kandidátním souvisejícím testům; cesty přes barrel soubory a dynamické importy jsou hlášeny jako poradní diagnostika s odkazovanými výjimkami v allowlistu | **Poradní** | -| `Vitest (fast-path)` | PR s kódem; rychlá sada vitest | Ano | -| `Unit Tests fast-path` | PR s kódem; sada jednotkových testů rozdělená do 4 shardů | Ano | -| `No new ESLint warnings` | PR s kódem; lintovací kontrola zohledňující potlačení | Ano, včetně forků | -| `Merge integrity (changelog + generated skills)` | PR, které nejsou koncepty; synchronizace changelogu a generovaných skills | Ano, včetně forků | +filtrované podle cest. Trvale zakázané duplicitní sestavení bylo odebráno; skutečné +kontroly sestavení, balíčku a spuštění zůstávají v CI. + +| Úloha | Rozsah | Blokující | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `Docs Gates (fast-path)` | PR dokumentace/kódu; odkazy na dokumentaci API a veškerá dokumentace | Ano | +| `Fast Quality Gates` | PR kódu; statické kontroly, kontrola typů, kontrola typů dashboardu, dotčené jednotkové testy | Ano | +| `Forgotten sibling tests` | PR kódu; změněné moduly vysledované ke statickým konzumentům a kandidátním souvisejícím testům; cesty přes barrel soubory a dynamické importy jsou hlášeny jako doporučující diagnostika s uvedenými výjimkami ze seznamu povolených položek | **Doporučující** | +| `Vitest (fast-path)` | PR kódu; rychlá sada Vitest | Ano | +| `Unit Tests fast-path` | PR kódu; jednotková sada rozdělená do 4 shardů | Ano | +| `No new ESLint warnings` | PR kódu; kontrola lintu zohledňující potlačení | Ano, včetně forků | +| `Merge integrity (changelog + generated skills)` | PR, které nejsou koncepty; synchronizace changelogu a generovaných dovedností | Ano, včetně forků | #### Report zapomenutých souvisejících testů -`npm run check:forgotten-sibling-tests` znovu používá resolver importů, na němž je založena mapa dopadu testů. +`npm run check:forgotten-sibling-tests` znovu používá resolver importů, na kterém je založena mapa dopadu testů. Pro každý změněný produkční modul hlásí deterministické řetězce `změněný modul/symbol -> statický konzument -> kandidátní související test`, pokud kandidátní test chybí v diffu pull requestu. Souhrn ve formátu Markdown a výsledek JSON jsou uchovány jako -artefakt workflow `forgotten-sibling-tests` pro kalibraci před případným zavedením blokujícího režimu. +artefakt workflow `forgotten-sibling-tests` pro kalibraci před případným zavedením blokující kontroly. -Reexporty z barrel souborů a dynamické importy slouží pouze k diagnostice rozlišení; nikdy nevytvářejí -blokující nález. Zkontrolované výjimky se nacházejí v +Opětovné exporty ze souborů barrel a dynamické importy slouží pouze jako diagnostika rozlišení; nikdy nevytvářejí +blokující nález. Posouzené výjimky se nacházejí v `config/quality/forgotten-sibling-allowlist.json`. Každá položka musí uvádět spotřebitele a kandidátní -test, obsahovat konkrétní zdůvodnění a odkazovat na issue nebo pull request na GitHubu. Chybně -formátované položky vedou k zamítnutí. Výjimky nemohou potlačit odstraněný kandidátní test ani změnu, -která přidává `.skip`/`.todo`; oslabování asercí a další maskování zůstávají v působnosti nezávisle -blokující kontroly `check:test-masking`. +test, obsahovat konkrétní odůvodnění a odkazovat na issue nebo pull request na GitHubu. Chybně vytvořené položky způsobí +zamítnutí. Výjimky nemohou potlačit smazaný kandidátní test ani změnu, která přidává `.skip`/`.todo`; +oslabování asercí a další maskování nadále spadá pod samostatně blokující +bránu `check:test-masking`. ### Úloha: `lint` Spouští se při každém PR do `main`. Při selhání blokuje sloučení. -| Skript (`npm run ...`) | Ověřuje | Blokující | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Verze Node.js je v podporovaném rozsahu | Ano | -| `check:cycles` | Cyklické importy — všechny moduly v `src/` + `open-sse/` | Ano | -| `check:route-validation:t06` | Schémata Zod jsou přítomna na všech trasách (zásady úrovně 6) | Ano | -| `check:any-budget:t11` | Počet `@ts-expect-error // any` nepřekračuje limit (catraca úrovně 11) | Ano | -| `check:provider-consistency` | Každý poskytovatel v `providers.ts` má odpovídající záznam v `providerRegistry.ts` (a naopak, v rámci seznamu povolených položek) | Ano | -| `check:model-lifecycle` | Tři ručně udržované směrovací tabulky zůstávají konzistentní se zařazeným snímkem životního cyklu (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nepřiřazuje skóre žádnému vyřazenému id, které může `REGISTRY` směrovat; každý cíl `BUILT_IN_ALIASES` je přítomen v `REGISTRY` a chybí ve snímku vyřazených id; každé vyřazené id, které je stále v `REGISTRY`, je přesměrováno nebo uvedeno v `allowedRetiredInCatalog`; a žádný zdroj ani cíl `DEFAULT_DEGRADATION_MAP` není v tomto snímku označen jako vyřazený. Toto nedokazuje, že je model aktuálně poskytován aktivní nadřazenou službou. Offline — porovnává se s `config/quality/model-lifecycle.json`, který se ručně aktualizuje pomocí `npm run quality:refresh-model-lifecycle` (vyžaduje síť; není zapojeno do CI). `allowedRetiredInCatalog` je postupně zpřísňovaná pojistka: záznam přidávejte pouze s odpovídajícím sledovacím problémem. | Ano | -| `check:fetch-targets` | Každé `fetch("/api/...")` v klientské části `src/` odkazuje na skutečný soubor `route.ts` | Ano | -| `check:deps` | Všechny závislosti instalovatelné pomocí `npm install` napříč všemi soubory `package.json` v repozitáři jsou uvedeny v `dependency-allowlist.json`; nové závislosti bez pevně určené verze nebo balíčky podezřelé z překlepu v názvu jsou označeny | Ano | -| `audit:deps` | `npm audit` (kořenový projekt + electron) — žádná upozornění vysoké ani kritické závažnosti (překrývá se s osv `check:vuln-ratchet`; viz backlog racionalizace) | Ano | -| `check:lockfile` | Integrita souboru `package-lock.json` — registr https, kontrolní součty integrity, žádná přepsání hostitele | Ano | -| `check:licenses` | Seznam povolených licencí SPDX pro produkční závislosti | Ano | -| `check:tracked-artifacts` | Žádné artefakty sestavení / verzované symbolické odkazy na `node_modules` (spouští se také v husky pre-commit; pre-push je záměrně odlehčený — #6716) | Ano | -| `check:ai-attribution` | Žádný dovětek `Co-Authored-By` od AI/bota ani poznámka o vygenerování AI v commitech, názvu nebo těle PR — Pevné pravidlo č. 16 (ve smyčce rychlých kontrol `quality.yml` pro PR→`release/**` — čte data události, mimo PR neprovádí žádnou operaci — a v kroku lint určeném pouze pro PR v `ci.yml` pro PR→`main`; také hook husky `commit-msg`; lidští spoluautoři jsou povoleni; #14436) | -| `check:vitest-exclusions` | Každá výjimka Vitest uvádí sledovaný problém a je uvedena v `config/quality/vitest-exclusions.json` (#13204) | Ano | -| `check:file-size` | Žádný zdrojový soubor nepřekračuje limit pro danou příponu (ráčna: velké soubory zmrazené v seznamu `frozen`) | Ano | -| `check:error-helper` | Chybové odpovědi v executorech/handlerech používají `buildErrorBody()` / `sanitizeErrorMessage()` (Pevné pravidlo č. 12) | Ano | -| `check:migration-numbering` | SQL soubory migrací jsou číslovány sekvenčně, bez mezer či duplicit | Ano | -| `check:public-creds` | Žádné literály OAuth `client_id`/`client_secret` ani webové klíče Firebase mimo `publicCreds.ts` (Pevné pravidlo č. 11) | Ano | -| `check:db-rules` | Žádné přímé SQL mimo moduly `src/lib/db/`; žádné souhrnné importy z `localDb.ts` (Pevná pravidla č. 2/5) | Ano | -| `check:known-symbols` | Exekutory poskytovatelů, strategie směrování a překladače zaregistrované v jejich dispatch tabulkách odpovídají souborům na disku — žádné osiřelé ani nedeklarované symboly | Ano | -| `check:route-guard-membership` | Každá trasa, která spouští podřízený proces, je klasifikována pomocí `isLocalOnlyPath()` (Pevná pravidla č. 15/17) | Ano | -| `check:test-discovery` | Každý soubor `*.test.ts` / `*.spec.ts` v repozitáři je zahrnut alespoň jedním nástrojem pro spouštění testů (ráčna: seznam osiřelých souborů v `test-discovery-baseline.json` se může pouze zmenšovat) | Ano | -| `check:agent-skills-sync` | Vygenerované artefakty agent-skills odpovídají jejich zdrojovému katalogu (bez rozdílů) | -| `check:provider-asset-provenance` | Loga/asset-y poskytovatelů mají zaznamenaný údaj o původu | -| `lint:json` | Konfigurační soubory JSON lze analyzovat a splňují lintovací pravidla repozitáře | -| `typecheck:core` | Kompilace TypeScriptu bez chyb (pouze informativní varování) | Ano | -| `typecheck:noimplicit:core` | Striktní `noImplicitAny` — výhledově; mnoho již existujících míst volání stále potřebuje anotace | **Informativní** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` omezené na `src/app/(dashboard)/**` (#7033) — pečlivě vybraný seznam 27 souborů v `typecheck:core` neobsahuje žádný dashboardový TSX a ani `next build` u nich nikdy neprovádí kontrolu typů (`next.config.mjs` nastavuje `ignoreBuildErrors: true`), takže regrese s osiřelými identifikátory (#6625/#6909) tam byly pro CI neviditelné. Rozdíly se porovnávají se zmrazenou výchozí hodnotou počtu chyb pro jednotlivé soubory a kódy TS (`config/quality/dashboard-typecheck-baseline.json`, stejný vzor vynucování zastaralosti jako u `check:known-symbols`) — brána selže pouze při NOVÝCH chybách nad rámec výchozího počtu; když je opravena již existující chyba, snižte výchozí hodnotu pomocí `--update`. | Ano | +| Skript (`npm run ...`) | Ověřuje | Blokující | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Verze Node.js je v podporovaném rozsahu | Ano | +| `check:cycles` | Cyklické importy napříč celými `src/` + `open-sse/` (založeno na AST, `paths` z tsconfig jsou vyřešeny). Samostatné spuštění = informativní, vypíše cykly. `check:cycles:ratchet` (varianta spouštěná v CI) blokuje, když počet překročí strop `metrics.cycles` v `quality-baseline.json` — aktuálně 14, `direction: down`, takže může pouze klesat (#15159 G-01/G-02) | Ano (ratchet) | +| `check:route-validation:t06` | Přítomnost schémat Zod na všech routách (zásada úrovně 6) | Ano | +| `check:any-budget:t11` | Počet `@ts-expect-error // any` nepřekračuje rozpočet (catraca úrovně 11) | Ano | +| `check:provider-consistency` | Každý poskytovatel v `providers.ts` má odpovídající záznam v `providerRegistry.ts` (a naopak, v rámci seznamu povolených položek) | Ano | +| `check:model-lifecycle` | Tři ručně udržované směrovací tabulky zůstávají konzistentní se snapshotem životního cyklu uloženým v repozitáři (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nehodnotí žádné vyřazené id, na které může `REGISTRY` směrovat; každý cíl `BUILT_IN_ALIASES` je přítomen v `REGISTRY` a chybí ve snapshotu vyřazených id; každé vyřazené id, které je stále v `REGISTRY`, je přesměrováno nebo uvedeno v `allowedRetiredInCatalog`; a žádný zdroj ani cíl `DEFAULT_DEGRADATION_MAP` není v tomto snapshotu označen jako vyřazený. Toto nedokazuje, že je model aktuálně poskytován aktivní upstream službou. Offline — porovnává se s `config/quality/model-lifecycle.json`, který se ručně aktualizuje pomocí `npm run quality:refresh-model-lifecycle` (vyžaduje síť; není zapojeno do CI). `allowedRetiredInCatalog` je postupně zpřísňovaná pojistka: záznam přidávejte pouze spolu se sledovacím issue. | Ano | +| `check:fetch-targets` | Každé `fetch("/api/...")` v klientské části `src/` se překládá na skutečný soubor `route.ts` | Ano | +| `check:deps` | Všechny závislosti instalovatelné pomocí `npm install` ze všech souborů `package.json` v repozitáři jsou uvedeny v `dependency-allowlist.json`; nové závislosti bez připnuté verze nebo balíčky podezřelé ze slopsquattingu jsou označeny | Ano | +| `audit:deps` | `npm audit` (kořenový adresář + electron) — žádná upozornění s vysokou nebo kritickou závažností (překrývá se s osv `check:vuln-ratchet`; viz backlog racionalizace) | Ano | +| `check:lockfile` | Integrita souboru `package-lock.json` — registr HTTPS, integritní hashe, žádná přepsání hostitelů | Ano | +| `check:licenses` | Seznam povolených licencí SPDX pro produkční závislosti | Ano | +| `check:tracked-artifacts` | Žádné artefakty sestavení / verzované symbolické odkazy na `node_modules` (spouští se také v husky pre-commit; pre-push je záměrně odlehčený — #6716) | Ano | +| `check:ai-attribution` | Žádná patička `Co-Authored-By` od AI/bota ani patička o vygenerování pomocí AI v commitech, názvu nebo popisu PR — Pevné pravidlo č. 16 (ve smyčce rychlých kontrol v `quality.yml` pro PR→`release/**` — čte datovou část události, mimo PR nic neprovádí — a krok pouze pro PR v lint kontrole v `ci.yml` pro PR→`main`; také hook husky `commit-msg`; lidští spoluautoři jsou povoleni; #14436) | +| `check:vitest-exclusions` | Každá výjimka Vitest uvádí sledovaný problém a je uvedena v `config/quality/vitest-exclusions.json` (#13204) | Ano | +| `check:file-size` | Žádný zdrojový soubor nepřekračuje limit pro danou příponu (rohatka: velké soubory zmrazené v seznamu `frozen`) | Ano | +| `check:error-helper` | Chybové odpovědi v executorech/handlerech používají `buildErrorBody()` / `sanitizeErrorMessage()` (Pevné pravidlo č. 12) | Ano | +| `check:migration-numbering` | Migrační SQL soubory jsou číslovány sekvenčně, bez mezer či duplicit | Ano | +| `check:public-creds` | Žádné literály OAuth `client_id`/`client_secret` ani webové klíče Firebase mimo `publicCreds.ts` (Pevné pravidlo č. 11) | Ano | +| `check:db-rules` | Žádné přímé SQL mimo moduly `src/lib/db/`; žádné hromadné importy z `localDb.ts` (Pevná pravidla č. 2/5) | Ano | +| `check:known-symbols` | Spouštěče poskytovatelů, strategie směrování a překladače registrované v příslušných dispečerských tabulkách odpovídají souborům na disku — žádné osiřelé ani nedeklarované symboly | Ano | +| `check:route-guard-membership` | Každá trasa, která spouští podřízený proces, je klasifikována pomocí `isLocalOnlyPath()` (Pevná pravidla č. 15/17) | Ano | +| `check:test-discovery` | Každý soubor `*.test.ts` / `*.spec.ts` v repozitáři je zahrnut alespoň jedním nástrojem pro spouštění testů (rohatka: seznam osiřelých souborů v `test-discovery-baseline.json` se může pouze zmenšovat) | Ano | +| `check:agent-skills-sync` | Vygenerované artefakty agent-skills odpovídají svému zdrojovému katalogu (bez odchylek) | +| `check:provider-asset-provenance` | Loga/assetty poskytovatelů mají zaznamenaný údaj o původu | +| `lint:json` | Konfigurační soubory JSON lze analyzovat a splňují pravidla lintování repozitáře | +| `typecheck:core` | Kompilace TypeScriptu bez chyb (pouze informativní varování) | Ano | +| `typecheck:noimplicit:core` | Striktní `noImplicitAny` — zaměřeno do budoucna; mnoho již existujících míst volání stále potřebuje anotace | **Informativní** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` omezené na `src/app/(dashboard)/**` (#7033) — kurátorovaný seznam 27 souborů v `typecheck:core` neobsahuje žádný dashboardový TSX a ani `next build` jej nikdy typově nekontroluje (`next.config.mjs` nastavuje `ignoreBuildErrors: true`), takže regrese osiřelých identifikátorů v této oblasti (#6625/#6909) nebyly v CI viditelné. Rozdíly se porovnávají se zmrazenou výchozí hodnotou počtu chyb pro každý soubor a každý kód TS (`config/quality/dashboard-typecheck-baseline.json`, stejný vzor vynucování aktuálnosti jako u `check:known-symbols`) — kontrola selže pouze u NOVÝCH chyb nad rámec výchozího počtu; při opravě již existující chyby výchozí hodnotu snižte pomocí `--update`. | Ano | ### Úloha: `quality-gate` Spouští se po `test-coverage`. Při selhání blokuje sloučení. -| Skript | Ověřuje | Blokující | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | Vytváří `quality-metrics.json` (počet varování ESLint, pokrytí ze sloučeného reportu shardů) | Ano (předchází ratchetu) | -| `quality:ratchet` | Žádná metrika v `quality-baseline.json` se nezhoršila (varování ESLint ≤ výchozí hodnota; pokrytí ≥ výchozí hodnota) | Ano | -| `check:duplication` | Duplikace kódu (jscpd@4) nepřekračuje výchozí hodnotu v `quality-baseline.json` | Ano | -| `check:complexity` | Cyklomatická složitost na úrovni souboru nepřekračuje limit (základní pravidla ESLint `complexity` + `max-lines-per-function`) | Ano | -| `check:cognitive-complexity` | Ratchet kognitivní složitosti (`eslint-plugin-sonarjs`) — samostatný průchod ESLint; CI spouští oba sloučené do jediného kroku `check:complexity-ratchets` | Ano | -| `check:dead-code` | Ratchet nepoužitých exportů / souborů (knip) se nezhoršil oproti výchozí hodnotě | Ano | -| `check:compression-budget` | Rozpočet benchmarku komprese — minimální úspory tokenů pro jednotlivé enginy se nesmí zhoršit | Ano | -| `check:type-coverage` | Ratchet procenta typovaného kódu (`type-coverage`) se nezhoršil; z velké části nahrazuje `typecheck:noimplicit:core` | Ano | -| `check:codeql-ratchet` | Počet otevřených upozornění CodeQL se nezhoršil (načítá se pomocí `gh api`; bez tokenu se kontrola korektně přeskočí) — frekvence aktualizace a ruční spuštění: viz „Ratchet CodeQL“ níže | Ano | +| Skript | Ověřuje | Blokující | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | Vytváří `quality-metrics.json` (počet varování ESLint, pokrytí ze sloučeného reportu dílčích běhů) | Ano (předchází ratchetu) | +| `quality:ratchet` | Žádná metrika v `quality-baseline.json` se nezhoršila (varování ESLint ≤ výchozí hodnota; pokrytí ≥ výchozí hodnota) | Ano | +| `check:duplication` | Duplikace kódu (jscpd@4) nepřekračuje výchozí hodnotu v `quality-baseline.json` | Ano | +| `check:complexity` | Cyklomatická složitost na úrovni souboru nepřekračuje limit (základní pravidla ESLint `complexity` + `max-lines-per-function`) | Ano | +| `check:cognitive-complexity` | Ratchet kognitivní složitosti (`eslint-plugin-sonarjs`) — samostatný průchod ESLint; CI spouští oba společně jako jediný krok `check:complexity-ratchets` | Ano | +| `check:dead-code` | Ratchet nepoužitých exportů / souborů (knip) se oproti výchozímu stavu nezhoršil | Ano | +| `check:compression-budget` | Rozpočet benchmarku komprese — minimální úspory tokenů pro jednotlivé enginy se nesmějí zhoršit | Ano | +| `check:type-coverage` | Ratchet procenta typovaného kódu (`type-coverage`) se nezhoršil; z velké části nahrazuje `typecheck:noimplicit:core` | Ano | +| `check:codeql-ratchet` | Počet otevřených výstrah CodeQL se nezhoršil (načítá se přes `gh api`; bez tokenu se korektně přeskočí) — interval aktualizace a ruční spuštění: viz níže „Ratchet CodeQL“ | Ano | ### Úloha: `quality-extended` -Celá úloha je informativní (`continue-on-error: true`). Ratchety založené na npm se spouštějí -skutečně; externí skenery se instalují pomocí `gh release download` a samy se přeskočí (ukončení s kódem 0), -pokud binární soubor stále chybí. +Celá úloha je pouze informativní (`continue-on-error: true`). Ratchety založené na npm se +spouštějí skutečně; externí skenery se instalují pomocí `gh release download` a samy se přeskočí (ukončení s kódem 0), +pokud binární soubor stále není k dispozici. | Skript | Ověřuje | Blokující | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | | `check:circular-deps` | Žádné cyklické závislosti (dpdm) | **Informativní** | | `check:bundle-size` | Velikost balíčku nepřekračuje limit | **Informativní** | -| `check:secrets` | Kontrola tajných údajů (gitleaks) — přeskočí se, pokud binární soubor chybí | **Informativní** | -| `check:vuln-ratchet` | Zranitelnosti závislostí (osv-scanner) se nezhoršily — přeskočí se, pokud binární soubor chybí | **Informativní** | -| `check:workflows` | Lint pracovních postupů (actionlint + zizmor); chybějící/nefunkční skenery, neplatné reporty nebo chybějící výchozí hodnota ratchetu způsobí selhání se stavem INCOMPLETE. Platné nálezy se řídí zvolenými zásadami strict/advisory/ratchet | Spuštění je povinné; ratchet zizmor je v CI blokující | -| `check:openapi-breaking` | Zpětně nekompatibilní změny veřejného kontraktu API (`openapi.yaml`) oproti základní větvi (oasdiff) — vytváří `openapiBreaking=N`; přeskočí se, pokud oasdiff chybí nebo nelze načíst základní specifikaci | **Informativní** | +| `check:secrets` | Vyhledávání tajných údajů (gitleaks) — přeskočí se, pokud binární soubor není k dispozici | **Informativní** | +| `check:vuln-ratchet` | Zranitelnosti závislostí (osv-scanner) se nezhoršily — přeskočí se, pokud binární soubor není k dispozici | **Informativní** | +| `check:workflows` | Kontrola workflow (actionlint + zizmor); chybějící/nefunkční skenery, neplatné reporty nebo chybějící výchozí stav ratchetu způsobí selhání se stavem INCOMPLETE. Platná zjištění se řídí vybranou přísnou/informativní/ratchetovou zásadou | Spuštění je povinné; ratchet zizmor je v CI blokující | +| `check:openapi-breaking` | Zpětně nekompatibilní změny veřejného kontraktu API (`openapi.yaml`) oproti základní větvi (oasdiff) — vytváří `openapiBreaking=N`; přeskočí se, pokud oasdiff není k dispozici nebo nelze načíst základní specifikaci | **Informativní** | ### Úloha: `docs-sync-strict` -Spouští se při každém PR do `main`. Při selhání blokuje sloučení. - -| Skript | Ověřuje | Blokující | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | Meta-brána, která postupně spouští 6 dílčích bran uvedených níže | Ano | -| ↳ `check:docs-sync` | Konzistence verzí mezi CHANGELOGem / OpenAPI / llm.txt | Ano | -| ↳ `check:docs-counts` | Počty v textu (počet poskytovatelů, počet migrací atd.) jsou v rámci zpřísňujícího se rozmezí skutečných počtů | Ano | -| ↳ `check:env-doc-sync` | Každá proměnná prostředí v `.env.example` je zdokumentována v tabulce dokumentace a naopak | Ano | -| ↳ `check:deprecated-versions` | V dokumentaci nejsou žádné řetězce zastaralých verzí | Ano | -| ↳ `check:doc-links` | Interní markdownové odkazy v dokumentaci odkazují na skutečné soubory (ve formátu `[text]`/`(path)`) | Ano | -| ↳ `check:fabricated-docs` | Trasy, proměnné prostředí, příkazy CLI, názvy hooků a cesty k souborům uvedené v dokumentaci existují v kódové základně. Tvrdá brána přes `--strict`; bez příznaku pouze nezávazné selhání. | Ano (přes `--strict` v CI) | -| `check:cli-i18n` | Řetězce příkazů CLI jsou přítomny ve všech souborech lokalizací i18n | Ano | -| `check:openapi-coverage` | Specifikace OpenAPI pokrývá alespoň postupně zpřísňovanou minimální hranici skutečných tras | Ano | -| `check:openapi-security-tiers` | Anotace úrovní zabezpečení v `openapi.yaml` jsou konzistentní s klasifikacemi v `routeGuard.ts` | **Informativní** | -| `check:openapi-routes` | Každá cesta v `openapi.yaml` odpovídá skutečnému souboru `route.ts` (ochrana proti halucinacím) | Ano | -| `check:docs-symbols` | Každý odkaz `/api/...` v `docs/**/*.md` odpovídá skutečnému souboru `route.ts` (ochrana proti halucinacím) | Ano | -| `i18n translation drift` | Nepřeložené klíče v souborech lokalizací i18n — pouze varování | **Informativní** | +Spouští se při každém PR do `main`. Při selhání zablokuje sloučení. + +| Skript | Ověřuje | Blokující | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | Metabránu, která postupně spouští 6 níže uvedených dílčích bran | Ano | +| ↳ `check:docs-sync` | Konzistenci verzí v CHANGELOGu / OpenAPI / llm.txt | Ano | +| ↳ `check:docs-counts` | Počty v textu (počet poskytovatelů, počet migrací atd.) se nacházejí v tolerančním rozsahu skutečných počtů | Ano | +| ↳ `check:env-doc-sync` | Každá proměnná prostředí v `.env.example` je zdokumentována v tabulce dokumentace a naopak | Ano | +| ↳ `check:deprecated-versions` | V dokumentaci nejsou žádné řetězce zastaralých verzí | Ano | +| ↳ `check:doc-links` | Interní markdownové odkazy v dokumentaci odkazují na existující soubory (ve formátu `[text]`/`(path)`) | Ano | +| ↳ `check:fabricated-docs` | Trasy, proměnné prostředí, příkazy CLI, názvy hooků a cesty k souborům uvedené v dokumentaci existují v kódové základně. Tvrdá brána přes `--strict`; bez tohoto příznaku nezpůsobí selhání. | Ano (přes `--strict` v CI) | +| `check:cli-i18n` | Řetězce příkazů CLI jsou přítomny ve všech souborech lokalizací i18n | Ano | +| `check:openapi-coverage` | Specifikace OpenAPI pokrývá alespoň postupně zpřísňovanou minimální hranici skutečných tras | Ano | +| `check:openapi-security-tiers` | Anotace úrovní zabezpečení v `openapi.yaml` jsou konzistentní s klasifikacemi v `routeGuard.ts` | **Informativní** | +| `check:openapi-routes` | Každá cesta v `openapi.yaml` odpovídá skutečnému souboru `route.ts` (ochrana proti halucinacím) | Ano | +| `check:docs-symbols` | Každý odkaz `/api/...` v `docs/**/*.md` odpovídá skutečnému souboru `route.ts` (ochrana proti halucinacím) | Ano | +| `i18n translation drift` | Nepřeložené klíče v souborech lokalizací i18n — pouze upozornění | **Informativní** | ### Úloha: `i18n-ui-coverage` -| Skript | Ověřuje | Blokující | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (inline) | Pokrytí klíčů i18n uživatelského rozhraní je ≥ 65 % | Ano | -| `check-ui-value-drift` (inline) | Přepsaná anglická **hodnota** po sobě nezanechá žádný zastaralý překlad | Ano | -| `check-new-key-coverage` (inline) | **Nový** anglický klíč je přeložen ve všech lokalizacích — značka `__MISSING__:` je odmítnuta | Ano | -| `check-translation-ratio` | Poměr skutečných překladů v jednotlivých lokalizacích (položky shodné s angličtinou / zástupné / chybějící mimo seznam povolených výjimek) nesmí překročit `config/quality/i18n-translation-baseline.json` + toleranci | **Informativní** | +| Skript | Ověřuje | Blokující | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `check-ui-keys-coverage` (inline) | Pokrytí klíčů i18n uživatelského rozhraní je ≥ 65 % | Ano | +| `check-ui-value-drift` (inline) | Po přepsání anglické **hodnoty** nezůstane žádný zastaralý překlad | Ano | +| `check-new-key-coverage` (inline) | **Nový** anglický klíč je přeložen ve všech lokalizacích — značka `__MISSING__:` je zamítnuta | Ano | +| `check-translation-ratio` | Podíl skutečných překladů v každé lokalizaci (položky mimo seznam výjimek, které jsou shodné s angličtinou, zástupné nebo chybějí) nesmí překročit `config/quality/i18n-translation-baseline.json` + rezervu | **Informativní** | -Vyžaduje `fetch-depth: 0` — brána kontroly změn hodnot porovnává `en.json` se společným předkem větví. +Vyžaduje `fetch-depth: 0` — brána kontroly změn hodnot porovnává `en.json` se společným předkem. #### `check-ui-value-drift` — brána proti zastaralým překladům -Odhaluje jedinou regresi i18n, kterou ostatní brány ze své podstaty nedokážou rozpoznat: anglická hodnota -je přepsána, ale překlady odvozené z _předchozího_ anglického znění zůstanou zachovány, takže +Zachytává jednu regresi i18n, kterou ostatní brány ze své podstaty nedokážou odhalit: anglická hodnota +je přepsána, ale překlady odvozené od _předchozího_ anglického znění zůstanou beze změny, takže neanglicky mluvící uživatelé nadále čtou sebejistě formulovaný, avšak nyní nesprávný text. -K tomu skutečně došlo v produkční verzi. `oauthModal.googleOAuthWarning` byl přepsán při zavedení pomocníka -pro přihlášení Antigravity (#5203); **39 ze 43 lokalizací** nadále obsahovalo text, který operátorům říkal, aby „zkopírovali -celou adresu URL a vložili ji níže“ — postup, který u tohoto poskytovatele nelze dokončit. Problém zůstal -bez povšimnutí až do #8463, protože: +K tomu skutečně došlo v produkční verzi. `oauthModal.googleOAuthWarning` byl přepsán při přidání +pomocníka pro přihlášení Antigravity (#5203); **39 ze 43 lokalizací** si ponechalo text, který správcům +říkal, aby „zkopírovali celou adresu URL a vložili ji níže“ — postup, který u tohoto poskytovatele nelze +dokončit. Až do #8463 to zůstalo bez povšimnutí, protože: -- `sync-ui-keys` doplňuje pouze klíče, které **chybějí**, nikdy ty, které jsou **zastaralé**; +- `sync-ui-keys` doplňuje pouze klíče, které **chybějí**, nikdy ne ty, které jsou **zastaralé**; - `check-ui-keys-coverage` počítá _přítomnost_ klíče, takže zastaralý překlad je započítán jako pokrytý; -- `check-translation-drift` sleduje zrcadlené kopie dokumentace `docs/i18n//**.md` — - soubory `src/i18n/messages/*.json` nikdy nečte. Od opětovné synchronizace 2026-09 je úloha `docs-sync-strict` blokující: upravte základní dokument → `npm run i18n:run -- --files=` (na úrovni sekcí, nenáročné). - -**Zohledňuje diff, neopírá se o baseline.** Porovnává `en.json` v merge base -s pracovním stromem; pro každý klíč, jehož anglická hodnota se změnila, je každý locale, -který stále obsahuje nezměněný překlad, zastaralý. Tím se záměrně **zmrazí již existující -dluh** — z diffu nelze zjistit, ze které starší anglické verze dlouhodobě existující překlad -vychází, takže kontrola posuzuje pouze to, čeho se aktuální změna dotýká. Alternativa -(baseline s hashem pro každý klíč) by vyžadovala přibližně 600KB generovaný soubor, -3× větší než největší existující baseline, který by se měnil při každém i18n PR. +- `check-translation-drift` sleduje dokumentační zrcadla `docs/i18n//**.md` — + soubory `src/i18n/messages/*.json` nikdy nečte. V úloze `docs-sync-strict` je tato kontrola blokující od + opětovné synchronizace 2026-09: upravte základní dokument → `npm run i18n:run -- --files=` (na úrovni sekce, nenáročné). + +**Zohledňuje rozdíly, není založeno na výchozím stavu.** Porovnává `en.json` v bodě sloučení +s pracovním stromem; pro každý klíč, jehož anglická hodnota se změnila, je každý jazyk, který +stále obsahuje nezměněný překlad, zastaralý. Tím se záměrně **zmrazí již existující dluh** — +z rozdílu nelze zjistit, ze které staré anglické verze dlouhodobě existující překlad pochází, +takže kontrola posuzuje pouze to, čeho se aktuální změna dotýká. Alternativa (výchozí stav +s hashem pro každý klíč) by vyžadovala přibližně 600KB generovaný soubor, 3× větší než +největší existující výchozí stav, který by se měnil při každém i18n PR. Kontrolu lze splnit dvěma způsoby: 1. aktualizovat dotčené překlady, nebo -2. nastavit je na `__MISSING__:` — runtime pak vrátí opravený anglický text - (`src/i18n/request.ts::deepMergeFallback`, #7258) a klíč zařadí do fronty k překladu. +2. nastavit je na `__MISSING__:` — běhové prostředí pak poskytne + opravený anglický text (`src/i18n/request.ts::deepMergeFallback`, #7258) a klíč zařadí + do fronty k překladu. -Pokud se změnil **význam** řetězce, dejte přednost **přejmenování klíče**: nový klíč nemůže +Pokud se změnil **význam** řetězce, upřednostněte **přejmenování klíče**: nový klíč nemůže zdědit zastaralý překlad. Tento postup byl použit v #8463. ```bash -npm run i18n:check-value-drift # striktní (spouští CI) +npm run i18n:check-value-drift # striktní režim (spouštěný v CI) npm run i18n:check-value-drift:warn # pouze hlášení BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Pokud nelze načíst základní katalog (mělký klon bez základního refu), skončí s kódem 0 -a hlášením `SKIP reason=base-unresolved`, obdobně jako `check-openapi-breaking`. +Ukončí se s kódem 0 a hlášením `SKIP reason=base-unresolved`, pokud nelze načíst základní +katalog (mělký klon bez základní reference), obdobně jako `check-openapi-breaking`. ### Úloha: `i18n` -Úplná matice validace i18n (jedna úloha pro každý locale). Celá úloha je informativní. +Úplná matice ověřování i18n (jedna úloha pro každý jazyk). Celá úloha je informativní. -| Skript | Ověřuje | Blokující | -| ------------------------------- | --------------------------------- | ------------------------------------------------------------ | -| `validate_translation.py quick` | Úplnost překladů pro každý locale | **Informativní** (`continue-on-error: true` pro celou úlohu) | +| Skript | Ověřuje | Blokující | +| ------------------------------- | -------------------------------- | ------------------------------------------------------------ | +| `validate_translation.py quick` | Úplnost překladu pro každý jazyk | **Informativní** (`continue-on-error: true` pro celou úlohu) | ### Úloha: `pr-test-policy` Spouští se pouze pro pull requesty. -| Skript | Ověřuje | Blokující | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | PR měnící produkční kód v `src/`, `open-sse/`, `electron/` nebo `bin/` musí zahrnovat nové či aktualizované testy (Tvrdé pravidlo č. 8) | Ano | -| `check:test-masking` | Změněné testovací soubory nesnižují čistý počet asercí ani nepřidávají tautologie `assert.ok(true)` | Ano | -| `check:pr-evidence` | Tělo PR uvádí důkazy z testů/VPS pro danou změnu (automatizuje Tvrdé pravidlo č. 18 pomocí vyhledávání v textu PR — křehké, viz Backlog) | Ano | +| Skript | Ověřuje | Blokující | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------- | +| `check:pr-test-policy` | PR měnící produkční kód v `src/`, `open-sse/`, `electron/` nebo `bin/` musí obsahovat nové či aktualizované testy (Pevné pravidlo č. 8) | Ano | +| `check:test-masking` | Změněné testovací soubory nesnižují čistý počet asercí ani nepřidávají tautologie `assert.ok(true)` | Ano | +| `check:pr-evidence` | Tělo PR uvádí doklady o testování/VPS dané změny (automatizuje Pevné pravidlo č. 18 prohledáváním textu PR — křehké, viz Backlog) | Ano | ### Úloha: `test-vitest` Spouští se po `build`. Při selhání blokuje sloučení. -| Sada | Ověřuje | Blokující | -| ---------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Server MCP (110 nástrojů), autoCombo, cache — testovací nástroj vitest | Ano | -| `test:vitest:ui` | Testy komponent uživatelského rozhraní — testovací nástroj vitest | **Blokující** — již existující selhání jsou explicitně vyloučena v `vitest.config.ts`; nová selhání způsobí selhání úlohy | +| Sada | Ověřuje | Blokující | +| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Server MCP (110 nástrojů), autoCombo, mezipaměť — vitest | Ano | +| `test:vitest:ui` | Testy komponent uživatelského rozhraní — vitest | **Blokující** — již existující selhání jsou v `vitest.config.ts` explicitně vyloučena; nová selhání způsobí pád úlohy | -### Noční workflow (plánované, informativní) +### Noční pracovní postupy (plánované, informativní) Spouštějí se podle plánu cron (a pomocí `workflow_dispatch`), nikdy pro PR. Všechny jsou informativní. -| Workflow | Ověřuje | Blokující | +| Pracovní postup | Ověřuje | Blokující | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | | `nightly-property` | Testy vlastností fast-check s náhodným seedem a vysokým počtem běhů | **Informativní** | -| `nightly-resilience` | Kontrolu růstu haldy, vkládání chaotických poruch, zátěžové/dlouhodobé testy k6 | **Informativní** | -| `nightly-llm-security` | Ochranu proti prompt injection pomocí promptfoo (režim blokování) + sondy garak (bez tajného klíče poskytovatele se přeskočí) | **Informativní** | -| `nightly-schemathesis` | Fuzzing kontraktu OpenAPI (schemathesis) proti živé instanci OmniRoute pomocí `docs/openapi.yaml` — odhaluje porušení specifikace / neošetřené chyby 500 (Fáze 8 B.4) | **Informativní** | +| `nightly-resilience` | Kontrolu růstu haldy, chaos fault-injection a zátěžové/dlouhodobé testy k6 | **Informativní** | +| `nightly-llm-security` | Ochranu proti injekcím promptfoo (režim blokování) a sondy garak (přeskočeno bez tajného klíče poskytovatele) | **Informativní** | +| `nightly-schemathesis` | Fuzzing kontraktu OpenAPI (schemathesis) proti běžící službě OmniRoute pomocí `docs/openapi.yaml` — odhaluje porušení specifikace / neošetřené chyby 500 (Fáze 8 B.4) | **Informativní** | | `nightly-mutation` | Skóre mutačního testování Stryker pro rychlou větev jednotkových testů — přeživší mutanty odhalují slabé aserce | **Informativní** | | `nightly-compat` | Matici kompatibility enginu Node napříč podporovanými rozsahy `engines.node` | **Informativní** | @@ -540,43 +544,44 @@ chybu připojení a nikdy nenaruší relace. --- -## Backlog racionalizace (revize ROI — fáze 9, vlna 3) +## Seznam racionalizačních úkolů (revize ROI — fáze 9, vlna 3) -Tento inventář byl 2026-06-17 porovnán s `ci.yml` (předchozí verze vynechávala +Tento inventář byl dne 2026-06-17 porovnán s `ci.yml` (předchozí verze vynechala `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Revize ROI sjednocené sady -identifikovala následující kandidáty na racionalizaci. **Sloučení jsou mechanické změny CI; -přepnutí či odstranění jsou politická rozhodnutí vyhrazená provozovateli.** Nic z níže -uvedeného dosud nebylo aplikováno. - -**Výše rovněž nezdokumentováno** (informativní, slabý signál): úloha `docs-lint` -(markdownlint + Vale, celá úloha s `continue-on-error`) a samostatné pracovní postupy skenerů -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. Hodnota `semgrepFindings: 0` se nachází v -`quality-baseline.json`, ale není v `ci.yml` napojena na blokující západku — metrika je -momentálně osiřelá. - -### Sloučení / deduplikace (mechanické, nižší riziko) - -Každý kandidát byl 2026-06-17 ověřen vůči aktuálnímu stavu kontrol (důvěřuj, ale prověřuj); -ukázalo se, že několik „zjevných“ sloučení skrývá dluh a **nelze** je provést jako přímé náhrady. - -- **`check:docs-sync` se spouští dvakrát** — samostatně v úloze `lint` a znovu uvnitř `check:docs-all` (`docs-sync-strict`) i v pre-commit hooku husky. ✅ **HOTOVO** — samostatné spuštění v úloze `lint` bylo odstraněno. -- **Skenování CVE** — ❌ **Sloučení NELZE provést přímo.** `audit:deps` tvrdě selže při jakékoli CVE vysoké nebo kritické závažnosti; `check:vuln-ratchet` (osv) selže pouze při _regresi_ oproti výchozímu stavu (aktuálně 1 MODERATE). Odlišná sémantika — odstraněním `audit:deps` by se ztratila absolutní kontrola vysoké/kritické závažnosti. Ponechat obojí. -- **Detekce cyklů** — ❌ **Sloučení NELZE provést přímo.** `check:circular-deps` (dpdm) hlásí **91 cyklů** (proto je pouze informativní); nelze jej změnit na blokující bez jejich předchozího vyřešení a má širší rozsah než úspěšná, pečlivě vybraná kontrola `check:cycles`. Ponechat `check:cycles` jako blokující; vyřešení 91 cyklů dpdm je samostatná položka backlogu. -- **Složitost** — ✅ **HOTOVO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jeden průchod ESLint, počítání podle ruleId, takže výchozí hodnoty cyklomatické složitosti + maximálního počtu řádků a kognitivní složitosti zůstávají nezávislé; jednotlivé kontroly `check:complexity` / `check:cognitive-complexity` zůstávají zachovány pro místní spuštění s `--update`. -- **Ochrana `/api` proti halucinacím** — ✅ **HOTOVO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jeden inventář FS pro `src/app/api`, openapi-routes + docs-symbols nadále hlásí výsledky nezávisle; jednotlivé kontroly zůstávají zachovány pro místní spuštění. -- **`check:node-runtime` se spouští v 11 úlohách** — ⚠️ **nízké ROI.** Každá používá samostatný runner a kontrola trvá <1 s; celková úspora činí ~10 s, ovšem za cenu ztráty levné ochrany pro každou úlohu. Nestojí to za komplikace. -- **`typecheck:noimplicit:core` v CI lint** — ✅ **odstraněno z úlohy lint** (bylo informativní s `continue-on-error`); blokující typovou plochu tvoří `typecheck:core` + `check:type-coverage`. Místní skript byl zachován. - -### Přepnout / rozhodnout (politika provozovatele) - -- `check:openapi-security-tiers` (informativní) — ❌ **Nelze jednoduše přepnout.** Končí s kódem 0, ale varuje, že několika trasám `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` chybí anotace `x-loopback-only: true`. Její vynucení nejprve vyžaduje přidat tyto anotace do `openapi.yaml`. -- `typecheck:noimplicit:core` (informativní) — z velké části jej nahrazuje blokující západka `check:type-coverage`. Přepnout na západku, nebo odstranit redundantní druhý průchod `tsc`. -- `test:vitest:ui` (nyní **blokující**) — dříve existující selhání jsou explicitně vyloučena v `vitest.config.ts` pomocí sledovacích komentářů `// #8618`; nová selhání způsobí neúspěch úlohy. -- `check:secrets` (gitleaks, blokující západka zmrazená na 3 zdokumentovaných falešně pozitivních nálezech) — přidat tyto 3 nálezy na seznam povolených, aby se dosáhlo hodnoty 0, nebo změnit kontrolu na informativní. Překrývá se s nativním skenováním tajných údajů na GitHubu + `check:public-creds`. -- `check:pr-evidence` (blokující, prohledává prózu v těle PR) — vysoké riziko falešně pozitivních nálezů; odstranění oslabí vynucování pevného pravidla č. 18, takže jde o skutečné politické rozhodnutí. -- `semgrep` (samostatná informativní kontrola) — překrývá se s CodeQL u kategorií OWASP; napojit její výchozí hodnotu na západku, nebo ji odstranit. +identifikovala následující kandidáty na racionalizaci. **Sloučení jsou mechanické změny +CI; změny režimu či odstranění jsou politická rozhodnutí vyhrazená provozovateli.** Nic +z níže uvedeného zatím nebylo aplikováno. + +**Výše rovněž nezdokumentováno** (poradní, nízká vypovídací hodnota): úloha `docs-lint` +(markdownlint + Vale, celá úloha s `continue-on-error`) a samostatné workflow skenerů +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. Hodnota `semgrepFindings: 0` se nachází +v `quality-baseline.json`, ale není v `ci.yml` napojena na blokující západku — tato metrika +je aktuálně osiřelá. + +### Sloučení / odstranění duplicit (mechanické, nižší riziko) + +Každý kandidát byl dne 2026-06-17 ověřen vůči aktuálnímu stavu kontrol (důvěřuj, ale +prověřuj); ukázalo se, že několik „zjevných“ sloučení skrývá dluh a **nelze** je čistě +nahradit. + +- **`check:docs-sync` se spouští dvakrát** — samostatně v úloze `lint` a znovu v rámci `check:docs-all` (`docs-sync-strict`) a husky pre-commit hooku. ✅ **HOTOVO** — samostatné spuštění v `lint` bylo odstraněno. +- **Skenování CVE** — ❌ **NEJDE o čisté sloučení.** `audit:deps` skončí tvrdou chybou při jakékoli CVE se závažností high/critical; `check:vuln-ratchet` (osv) selže pouze při _regresi_ oproti výchozímu stavu (aktuálně 1 MODERATE). Odlišná sémantika — odstraněním `audit:deps` by se ztratila absolutní kontrola závažností high/critical. Ponechat obě. +- **Detekce cyklů** — ✅ **HOTOVO** (#15159 G-01/G-02). Původní text zde označoval `check:cycles` za „zelenou, pečlivě vybranou“ kontrolu a její blokující režim zdůvodňoval tím, že `check:circular-deps` (dpdm) hlásil 91 cyklů. Tento zelený stav byl **falešně pozitivní**: `check:cycles` kontroloval 5 podadresářů (450 souborů), vyhledával pouze statické `import|export … from` a zahazoval všechny specifikátory `@/` a `@omniroute/open-sse/`, takže nemohl odhalit cykly dynamických importů a aliasů, které v repozitáři převažovaly. Opraveno: kontrola nyní prochází `src` + `open-sse` (5023 souborů), shromažďuje specifikátory z AST TypeScriptu (takže `import("…")` se započítává, zatímco `typeof import("…")` na pozici typu nikoli) a překládá `paths` z tsconfigu. Nachází **14** cyklů, nikoli 0. Protože 14 již existujících cyklů nelze opravit v PR zavádějícím kontrolu, je nyní `check:cycles` **západkou** (`--ratchet`, strop `metrics.cycles.value = 14` v `quality-baseline.json`, `direction: down`) — blokuje každou _regresi_ a počet může pouze klesat. CI spouští `npm run check:cycles:ratchet`. Postupné snižování probíhá společně s **A-01**. `check:circular-deps` (dpdm) zůstává poradní jako širší nezávislá kontrola. +- **Složitost** — ✅ **HOTOVO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jeden průchod ESLintu, počítání podle ruleId, takže výchozí hodnoty cyklomatické složitosti + maximálního počtu řádků a kognitivní složitosti zůstávají nezávislé; jednotlivé kontroly `check:complexity` / `check:cognitive-complexity` zůstávají zachovány pro místní použití s `--update`. +- **Ochrana `/api` proti halucinacím** — ✅ **HOTOVO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jeden inventář souborového systému pro `src/app/api`; openapi-routes + docs-symbols nadále hlásí výsledky nezávisle; jednotlivé kontroly zůstávají zachovány pro místní spuštění. +- **`check:node-runtime` se spouští v 11 úlohách** — ⚠️ **nízké ROI.** Každá běží na samostatném runneru a kontrola trvá <1 s; celková úspora činí přibližně 10 s za cenu ztráty levné ochrany pro každou úlohu. Nestojí to za související změny. +- **`typecheck:noimplicit:core` v lintování CI** — ✅ **odstraněno z úlohy lint** (dříve poradní s `continue-on-error`); blokující typový povrch tvoří `typecheck:core` + `check:type-coverage`. Místní skript byl zachován. + +### Změna režimu / rozhodnutí (politika provozovatele) + +- `check:openapi-security-tiers` (poradní) — ❌ **NELZE čistě přepnout.** Končí s kódem 0, ale upozorňuje, že několika trasám `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` chybí anotace `x-loopback-only: true`. Jeho vynucení nejprve vyžaduje přidání těchto anotací do `openapi.yaml`. +- `typecheck:noimplicit:core` (poradní) — z velké části nahrazeno blokující západkou `check:type-coverage`. Přepnout na západku, nebo odstranit redundantní druhý průchod `tsc`. +- `test:vitest:ui` (nyní **blokující**) — již existující selhání jsou explicitně vyloučena ve `vitest.config.ts` pomocí sledovacích komentářů `// #8618`; nová selhání způsobí neúspěch úlohy. +- `check:secrets` (gitleaks, blokující západka zmrazená na 3 zdokumentovaných falešně pozitivních nálezech) — přidat tyto 3 případy na seznam povolených a dosáhnout hodnoty 0, nebo kontrolu degradovat na poradní. Překrývá se s nativním skenováním tajných údajů GitHubu + `check:public-creds`. +- `check:pr-evidence` (blokující, vyhledává vzory v textu těla PR) — vysoké riziko falešně pozitivních výsledků; odstranění by oslabilo vynucování závazného pravidla č. 18, takže jde o skutečné politické rozhodnutí. +- `semgrep` (poradní, samostatný) — u rodin OWASP se překrývá s CodeQL; napojit jeho výchozí hodnotu na západku, nebo jej odstranit. --- diff --git a/docs/i18n/da/CONTRIBUTING.md b/docs/i18n/da/CONTRIBUTING.md index de21ccbd527..2719f740594 100644 --- a/docs/i18n/da/CONTRIBUTING.md +++ b/docs/i18n/da/CONTRIBUTING.md @@ -393,16 +393,16 @@ Skriv enhedstests i `tests/unit/`, som som minimum dækker: - [ ] Linting består (`npm run lint`) - [ ] Build lykkes (`npm run build`) - [ ] TypeScript-typer er tilføjet for nye offentlige funktioner og interfaces -- [ ] Ingen hardcodede hemmeligheder eller reserveværdier -- [ ] Offentlige upstream-legitimationsoplysninger indlejres via `resolvePublicCred()` (se [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), aldrig som litteraler -- [ ] Fejlsvar føres gennem `buildErrorBody()` / `sanitizeErrorMessage()` — ingen rå stack traces i svarenes bodies (se [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Ingen hardkodede hemmeligheder eller fallback-værdier +- [ ] Offentlige upstream-legitimationsoplysninger indlejres via `resolvePublicCred()` (se [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), aldrig som literals +- [ ] Fejlsvar sendes gennem `buildErrorBody()` / `sanitizeErrorMessage()` — ingen rå stack traces i svartekster (se [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Shell-kommandoer (`exec` / `spawn`) videregiver runtime-værdier via `env`, ikke via strenginterpolation - [ ] Alle input valideres med Zod-skemaer -- [ ] Changelog-**fragment** tilføjet under `changelog.d/{features|fixes|maintenance}/-.md` for brugerrettede ændringer (se [`changelog.d/README.md`](./changelog.d/README.md)) — rediger **ikke** `CHANGELOG.md` direkte; fragmenter samles ved udgivelsestidspunktet og skaber aldrig konflikter mellem pull requests -- [ ] Dokumentationen er opdateret (hvis relevant) -- [ ] Ingen nye CodeQL- / Secret-Scanning-advarsler er åbnet, eller hver enkelt er afvist med en teknisk begrundelse, der henviser til det relevante dokument under `docs/security/` +- [ ] Changelog-**fragment** tilføjet under `changelog.d/{features|fixes|maintenance}/-.md` for brugervendte ændringer (se [`changelog.d/README.md`](./changelog.d/README.md)) — rediger **ikke** `CHANGELOG.md` direkte; fragmenter samles ved udgivelsen og skaber aldrig konflikter mellem pull requests +- [ ] Dokumentation opdateret (hvis relevant) +- [ ] Ingen nye CodeQL- eller Secret-Scanning-advarsler oprettet, eller hver enkelt er afvist med en teknisk begrundelse, der henviser til det relevante dokument under `docs/security/` - [ ] Ruter, der starter underprocesser (`/api/mcp/`, `/api/cli-tools/runtime/`), er klassificeret som `isLocalOnlyPath()` i `src/server/authz/routeGuard.ts` — se [ufravigelig regel nr. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Ingen `Co-Authored-By`-trailere i commitbeskeder — commits må udelukkende fremstå under repository-ejerens Git-identitet (ufravigelig regel nr. 16) +- [ ] Ingen AI-/bot-`Co-authored-by`-trailere i commit-meddelelser (ufravigelig regel nr. 16) — menneskelige samarbejdspartnere, hvis arbejde genbruges, krediteres med standardtrailere i formatet `Co-authored-by: Name ` --- diff --git a/docs/i18n/da/docs/architecture/QUALITY_GATES.md b/docs/i18n/da/docs/architecture/QUALITY_GATES.md index 66d415c550b..73554007f8d 100644 --- a/docs/i18n/da/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/da/docs/architecture/QUALITY_GATES.md @@ -15,175 +15,171 @@ plan til replikering af det samme system. --- -## Gate-inventar og eksekveringsprofiler +## Oversigt over gates og eksekveringsprofiler ### Godkendelse af kandidater -CI- og Quality Gates-workflowene udsender hver især en stabil afgørelse: `Gate / CI` og -`Gate / Quality`. Deres versionsstyrede godkendelsespolitik angiver hvert upstream-job -som påkrævet eller vejledende. Et relevant påkrævet job skal gennemføres korrekt: -Manglende, annullerede, oversprungne, afventende og ukendte resultater kan ikke fastslå -PASS. En gyldig klassifikation som kun dokumentation eller kun katalog kan gøre et -kodeforløb irrelevant; en kladde-PR accepteres ikke som kandidat. En `hotfix`-etiket -fritager ikke for dokumentation. - -Begge workflows dækker PR'er og pushes til main-/release-grene, manuel dispatch og -merge-group-hændelser. Push, dispatch og merge-group kører den fulde udvælgelse. Forks -og merge groups bruger hostede runners til jobs, der ellers vælger self-hosted runners; -det skal før udrulning verificeres, at der er tilstrækkelig hostet kapacitet. - -Hver JSON-kvittering identificerer den udcheckede SHA, workflow-kørslen og forsøget. -CLI'en afviser uoverensstemmelser mellem checkout- og hændelses-SHA. Workflow-tests -binder medlemskab af politikken til afgørelsesjobbets `needs`-liste, så et nyt eller -fjernet forløb ikke ubemærket kan forsvinde. Kvitteringerne dækker deres eget workflow, -ikke publicering, udrulning eller de interne funktioner i en eksisterende vejledende -scanner. Aktivering af begge kontrolnavne i branch-regler er en separat administrativ -ændring; tilføjelse af disse jobs beskytter ikke i sig selv en branch. - -### Inventar over statisk scanning - -Det versionsstyrede npm-aliasinventar og medlemskab af statiske scanninger findes i +CI- og Quality Gates-workflowene udsender hver en stabil afgørelse: `Gate / CI` og +`Gate / Quality`. Deres versionerede godkendelsespolitik angiver hvert upstream-job +som påkrævet eller vejledende. Et relevant påkrævet job skal gennemføres: manglende, +annullerede, oversprungne, afventende og ukendte resultater kan ikke etablere PASS. En gyldig +klassificering som kun dokumentation eller kun katalog kan gøre et kodeforløb irrelevant; +en kladde-PR er ikke en accepteret kandidat. Et `hotfix`-label fritager ikke for dokumentationskrav. + +Begge workflows dækker PR'er og pushes til main/release-branches, manuel aktivering og +merge-group-hændelser. Push, aktivering og merge-group kører det fulde udvalg. Forks +og merge groups bruger hostede runners til jobs, der ellers vælger self-hosted +runners; tilstrækkelig hostet kapacitet skal verificeres før udrulning. + +Hver JSON-kvittering identificerer den checkoutede SHA, workflow-kørslen og forsøget. +CLI'en afviser uoverensstemmelse mellem checkout- og hændelses-SHA. Workflow-tests knytter politikkens medlemskab +til afgørelsesjobbets `needs`-liste, så et nyt eller fjernet forløb ikke kan forsvinde ubemærket. +Kvitteringerne dækker deres eget workflow, ikke publicering, udrulning eller de interne +detaljer i en eksisterende vejledende scanner. Aktivering af begge kontrolnavne i branch-regler er en +separat administrativ ændring; tilføjelse af disse jobs beskytter ikke i sig selv en branch. + +### Oversigt over statisk scanning + +Den versionerede oversigt over npm-aliasser og medlemskabet af statiske scanninger findes i `config/quality/gate-manifest.json`. Kør `npm run check:gate-manifest` for at validere scriptnavne og nøjagtige kommandoer mod `package.json`; tilføjelser, fjernelser og -kommandoafvigelser får både den lokale hook og ændringsklassificeringsjobbene i CI -til at fejle. Et alias er ikke et workflow-job, en matrixinstans eller en testcase: -Disse antal må ikke præsenteres, som om de var indbyrdes udskiftelige. +kommandoafvigelser får både den lokale hook og ændringsklassificeringsjobbene i CI til at fejle. +Et alias er ikke et workflow-job, en matrixinstans eller en testcase: disse antal må +ikke præsenteres som indbyrdes udskiftelige. Brug `npm run quality:scan -- --list` eller `npm run quality:scan:fast -- --list` -til at inspicere de valgte aliasser uden at eksekvere dem. Runneren kalder +til at gennemgå de valgte aliasser uden at køre dem. Runneren aktiverer npm-entrypointet, så dets runtime (herunder Bun, hvor det er konfigureret) bevares. -Manifestet registrerer aliasser uden for disse profiler som separat kaldte, og +Manifestet registrerer aliasser uden for disse profiler som aktiveret separat, og vedligeholdelseskommandoer er forbudt i skrivebeskyttede scanningsprofiler. Disse profiler dækker kun den statiske scanning. De certificerer ikke produkttests, dækning, pakning, eksterne kontroller eller en kandidats fulde release-godkendelse. -Workflow-godkendelse bruger de tilknyttede `config/quality/admission-policy.json` og +Workflow-godkendelse bruger den tilknyttede `config/quality/admission-policy.json` og `scripts/quality/admission-verdict.mjs`. Release-observer-profiler forbliver separate; -inspicér deres relevante kontroller og kvitteringer uafhængigt. Prosaoversigten -nedenfor er en reference, ikke et bevis på, at en gate faktisk blev kørt. +gennemgå deres relevante kontroller og kvitteringer separat. Oversigten i prosa +nedenfor er en reference, ikke dokumentation for, at en gate faktisk blev kørt. Scripts findes under `scripts/check/` (politik-gates) og `scripts/quality/` (ratchet-motor). CI's autoritative kilde er `.github/workflows/ci.yml`. ### Hurtigt forløb for release-PR'er (`quality.yml`) -`.github/workflows/quality.yml` supplerer CI for main-/release-PR'er, pushes til -beskyttede branches, dispatch og merge groups. PR'er bruger stifiltrerede hurtige -kontroller. Det permanent deaktiverede duplikerede build blev fjernet; de reelle -build-/pakke-/opstartskontroller forbliver i CI. - -| Job | Omfang | Blokerende | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | -| `Docs Gates (fast-path)` | Dokumentations-/kode-PR'er; API-dokumentationsreferencer og al dokumentation | Ja | -| `Fast Quality Gates` | Kode-PR'er; statiske kontroller, typekontrol, typekontrol af dashboard og berørte enhedstests | Ja | -| `Forgotten sibling tests` | Kode-PR'er; ændrede moduler spores til statiske forbrugere og mulige relaterede tests; barrel- og dynamic-import-stier rapporteres som vejledende diagnostik med refererede undtagelser på tilladelseslisten | **Vejledende** | -| `Vitest (fast-path)` | Kode-PR'er; hurtig vitest-suite | Ja | -| `Unit Tests fast-path` | Kode-PR'er; enhedstestsuite med 4 shards | Ja | -| `No new ESLint warnings` | Kode-PR'er; undertrykkelsesbevidst lint-kontrol | Ja, inklusive forks | -| `Merge integrity (changelog + generated skills)` | PR'er, der ikke er kladder; synkronisering af changelog og genererede skills | Ja, inklusive forks | - -#### Rapport om glemte relaterede tests - -`npm run check:forgotten-sibling-tests` genbruger import-resolveren bag kortet over -testpåvirkning. For hvert ændret produktionsmodul rapporterer den deterministiske -kæder af typen `changed module/symbol -> static consumer -> candidate sibling test`, -når den mulige test ikke findes i pull request-diffen. Markdown-oversigten og -JSON-resultatet gemmes som workflow-artefaktet `forgotten-sibling-tests` med henblik -på kalibrering før en eventuel udrulning som blokerende kontrol. - -Barrel-re-eksporter og dynamiske importer er kun diagnosticering af modulopløsning; de skaber aldrig et +`.github/workflows/quality.yml` supplerer CI på main/release-PR'er, pushes til beskyttede branches, +aktivering og merge groups. PR'er bruger stifiltrerede hurtige kontroller. Det permanent +deaktiverede duplikerede build blev fjernet; de reelle build-, pakke- og opstartskontroller forbliver i CI. + +| Job | Omfang | Blokerende | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `Docs Gates (fast-path)` | Dokumentations-/kode-PR'er; referencer til API-dokumentation og al dokumentation | Ja | +| `Fast Quality Gates` | Kode-PR'er; statiske kontroller, typekontrol, typekontrol af dashboard, berørte enhedstests | Ja | +| `Forgotten sibling tests` | Kode-PR'er; ændrede moduler spores til statiske forbrugere og mulige søskendetests; barrel- og dynamic-import-stier rapporteres som vejledende diagnosticering med refererede allowlist-undtagelser | **Vejledende** | +| `Vitest (fast-path)` | Kode-PR'er; hurtig vitest-suite | Ja | +| `Unit Tests fast-path` | Kode-PR'er; enhedstestsuite med 4 shards | Ja | +| `No new ESLint warnings` | Kode-PR'er; suppressions-bevidst lint-kontrol | Ja, inklusive forks | +| `Merge integrity (changelog + generated skills)` | PR'er, der ikke er kladder; changelog og synkronisering af genererede skills | Ja, inklusive forks | + +#### Rapport om glemte søskendetests + +`npm run check:forgotten-sibling-tests` genbruger import-resolveren bag kortet over testpåvirkning. +For hvert ændret produktionsmodul rapporterer den deterministiske +`changed module/symbol -> static consumer -> candidate sibling test`-kæder, når den mulige +test ikke findes i pull request-diffen. Markdown-oversigten og JSON-resultatet gemmes som +workflow-artefaktet `forgotten-sibling-tests` til kalibrering før en eventuel blokerende udrulning. + +Barrel-re-exports og dynamiske imports er kun diagnosticering af modulopløsning; de skaber aldrig et blokerende fund. Gennemgåede undtagelser findes i `config/quality/forgotten-sibling-allowlist.json`. Hver post skal angive forbrugeren og den mulige -test, give en specifik begrundelse og linke til et GitHub-issue eller en pull request. Fejlformaterede poster afvises -som standard. Undtagelser kan ikke undertrykke en slettet mulig test eller en diff, der tilføjer `.skip`/`.todo`; -svækkelse af assertions og anden maskering håndteres fortsat af den uafhængigt blokerende -`check:test-masking`-kontrol. +test, give en specifik begrundelse og linke til et GitHub-issue eller en pull request. Fejlformaterede poster får +kontrollen til at fejle lukket. Undtagelser kan ikke undertrykke en slettet mulig test eller en diff, der tilføjer `.skip`/`.todo`; +svækkelse af assertions og anden maskering hører fortsat under den uafhængigt blokerende +`check:test-masking`-gate. ### Job: `lint` -Kører ved hver PR til `main`. Blokerer sammenfletning ved fejl. - -| Script (`npm run ...`) | Validerer | Blokerende | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | -| `check:node-runtime` | Node.js-versionen er inden for det understøttede interval | Ja | -| `check:cycles` | Cirkulære importer — alle moduler i `src/` + `open-sse/` | Ja | -| `check:route-validation:t06` | Zod-skemaer findes på alle routes (Tier 6-politik) | Ja | -| `check:any-budget:t11` | Antallet af `@ts-expect-error // any` overstiger ikke budgettet (Tier 11-catraca) | Ja | -| `check:provider-consistency` | Hver provider i `providers.ts` har en tilsvarende post i `providerRegistry.ts` (og omvendt, inden for allowlisten) | Ja | -| `check:model-lifecycle` | De tre manuelt vedligeholdte routingtabeller forbliver konsistente med det indcheckede livscyklus-snapshot (#11503): `FITNESS_TABLE` (`taskFitness.ts`) scorer ikke noget udfaset id, som `REGISTRY` kan route; hvert mål i `BUILT_IN_ALIASES` findes i `REGISTRY` og er ikke med i snapshottet over udfasede id'er; hvert udfaset id, der stadig findes i `REGISTRY`, videresendes eller er angivet i `allowedRetiredInCatalog`; og ingen kilde eller destination i `DEFAULT_DEGRADATION_MAP` fremgår som udfaset i dette snapshot. Dette beviser ikke, at en model aktuelt leveres af en aktiv upstream-tjeneste. Offline — sammenligner med `config/quality/model-lifecycle.json`, som opdateres manuelt med `npm run quality:refresh-model-lifecycle` (netværk; ikke integreret i CI). `allowedRetiredInCatalog` er en gradvis afviklingsmekanisme: Tilføj kun en post med en tilknyttet tracking-issue. | Ja | -| `check:fetch-targets` | Hvert `fetch("/api/...")` i `src/` på klientsiden peger på en faktisk `route.ts` | Ja | -| `check:deps` | Alle afhængigheder, der kan installeres med `npm install`, på tværs af hver `package.json` i repositoriet findes i `dependency-allowlist.json`; nye ikke-fastlåste pakker eller pakker med navne, der kan være resultatet af slopsquatting, markeres | Ja | -| `audit:deps` | `npm audit` (rod + electron) — ingen advarsler med høj eller kritisk alvorlighedsgrad (overlapper osv `check:vuln-ratchet`; se rationaliseringsbackloggen) | Ja | -| `check:lockfile` | Integriteten af `package-lock.json` — https-register, integritetshashes, ingen værtstilsidesættelser | Ja | -| `check:licenses` | SPDX-licenstilladelsesliste for produktionsafhængigheder | Ja | -| `check:tracked-artifacts` | Ingen build-artefakter / committede `node_modules`-symlinks (kører også i husky pre-commit; pre-push er bevidst let — #6716) | Ja | -| `check:ai-attribution` | Ingen AI/bot-`Co-Authored-By`-trailer eller AI-genereret sidefod i PR-commits, titel eller brødtekst — fast regel #16 (i `quality.yml`-løkken med hurtige kontroller for PR→`release/**` — læser event-payloaden, gør intet uden for PR'er — og et trin kun for PR'er i `ci.yml`-lint for PR→`main`; også husky-`commit-msg`-hooken; menneskelige medforfattere er tilladt; #14436) | -| `check:vitest-exclusions` | Hver Vitest-undtagelse angiver en sporingsissue og findes i `config/quality/vitest-exclusions.json` (#13204) | Ja | -| `check:file-size` | Ingen kildefil overskrider grænsen for den pågældende filendelse (skraldeprincip: fastlåste store filer på listen `frozen`) | Ja | -| `check:error-helper` | Fejlsvar i executors/handlers bruger `buildErrorBody()` / `sanitizeErrorMessage()` (fast regel #12) | Ja | -| `check:migration-numbering` | Migrations-SQL-filer er fortløbende nummereret uden huller eller dubletter | Ja | -| `check:public-creds` | Ingen bogstavelige OAuth-`client_id`/`client_secret`-værdier eller Firebase Web-nøgler uden for `publicCreds.ts` (fast regel #11) | Ja | -| `check:db-rules` | Ingen rå SQL uden for moduler i `src/lib/db/`; ingen barrel-importer fra `localDb.ts` (faste regler #2/#5) | Ja | -| `check:known-symbols` | Provider-eksekveringsfunktioner, routingstrategier og oversættere, der er registreret i deres dispatch-tabeller, matcher filerne på disken — ingen forældreløse eller ikke-deklarerede symboler | Ja | -| `check:route-guard-membership` | Hver route, der opretter en underproces, er klassificeret af `isLocalOnlyPath()` (faste regler #15/#17) | Ja | -| `check:test-discovery` | Hver `*.test.ts`- / `*.spec.ts`-fil i repoet indsamles af mindst én test-runner (ratchet: listen over forældreløse filer i `test-discovery-baseline.json` kan kun blive kortere) | Ja | -| `check:agent-skills-sync` | Genererede agent-skills-artefakter matcher deres kildekatalog (ingen afvigelser) | -| `check:provider-asset-provenance` | Udbyderlogoer/-aktiver har en registreret provenienspost | -| `lint:json` | JSON-konfigurationsfiler kan parses og overholder repositoriets lint-regler | -| `typecheck:core` | TypeScript-kompilering uden fejl (kun vejledende advarsler) | Ja | -| `typecheck:noimplicit:core` | Streng `noImplicitAny` — fremadskuende; mange eksisterende kaldesteder mangler stadig annoteringer | **Vejledende** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` afgrænset til `src/app/(dashboard)/**` (#7033) — den kuraterede tilladelsesliste med 27 filer i `typecheck:core` inkluderer ingen dashboard-TSX-filer, og `next build` typekontrollerer dem heller aldrig (`next.config.mjs` angiver `ignoreBuildErrors: true`), så regressioner med forældreløse identifikatorer dér (#6625/#6909) var usynlige for CI. Sammenligner med en fastfrosset baseline for antal pr. fil og pr. TS-kode (`config/quality/dashboard-typecheck-baseline.json`, samme mønster for håndhævelse af forældede poster som `check:known-symbols`) — kun NYE fejl ud over det baselinefastsatte antal får kontrollen til at fejle; reducer gradvist med `--update`, når en eksisterende fejl rettes. | Ja | +Kører på hver PR til `main`. Blokerer fletning ved fejl. + +| Script (`npm run ...`) | Validerer | Blokerende | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | Node.js-versionen er inden for det understøttede interval | Ja | +| `check:cycles` | Cirkulære imports på tværs af hele `src/` + `open-sse/` (AST-baseret, tsconfig-`paths` opløst). Uden yderligere argumenter = vejledende, viser cyklusserne. `check:cycles:ratchet` (som CI kører) blokerer, når antallet overstiger loftet `metrics.cycles` i `quality-baseline.json` — i øjeblikket 14, `direction: down`, så det kan kun falde (#15159 G-01/G-02) | Ja (ratchet) | +| `check:route-validation:t06` | Zod-skemaer findes på alle routes (Tier 6-politik) | Ja | +| `check:any-budget:t11` | Antallet af `@ts-expect-error // any` overstiger ikke budgettet (Tier 11-catraca) | Ja | +| `check:provider-consistency` | Hver provider i `providers.ts` har en tilsvarende post i `providerRegistry.ts` (og omvendt inden for tilladelseslisten) | Ja | +| `check:model-lifecycle` | De tre manuelt vedligeholdte routingtabeller forbliver konsistente med det indcheckede livscyklusøjebliksbillede (#11503): `FITNESS_TABLE` (`taskFitness.ts`) scorer ikke noget udfaset id, som `REGISTRY` kan route; hvert `BUILT_IN_ALIASES`-mål findes i `REGISTRY` og er fraværende i øjebliksbilledet over udfasede id'er; hvert udfaset id, der stadig findes i `REGISTRY`, videresendes eller er angivet i `allowedRetiredInCatalog`; og ingen kilde eller intet mål i `DEFAULT_DEGRADATION_MAP` fremstår som udfaset i dette øjebliksbillede. Dette beviser ikke, at en model aktuelt leveres af en aktiv upstream-tjeneste. Offline — sammenligner med `config/quality/model-lifecycle.json`, som opdateres manuelt med `npm run quality:refresh-model-lifecycle` (netværk; ikke integreret i CI). `allowedRetiredInCatalog` er en gradvist strammende skraldemekanisme: Tilføj kun en post sammen med en tracking-sag. | Ja | +| `check:fetch-targets` | Hvert `fetch("/api/...")` i `src/` på klientsiden peger på en faktisk `route.ts` | Ja | +| `check:deps` | Alle afhængigheder, der kan installeres med `npm install`, på tværs af samtlige `package.json`-filer i repoet findes i `dependency-allowlist.json`; nye ikke-fastlåste pakker eller pakker med navne, der kan være resultatet af slopsquatting, markeres | Ja | +| `audit:deps` | `npm audit` (rod + Electron) — ingen rådgivningsmeddelelser med høj/kritisk alvorlighedsgrad (overlapper OSV's `check:vuln-ratchet`; se rationaliseringsbackloggen) | Ja | +| `check:lockfile` | Integriteten af `package-lock.json` — HTTPS-register, integritetshashes, ingen værtsoverskrivninger | Ja | +| `check:licenses` | SPDX-licenstilladelsesliste for produktionsafhængigheder | Ja | +| `check:tracked-artifacts` | Ingen build-artefakter / committede `node_modules`-symbolske links (kører også i husky pre-commit; pre-push er bevidst let — #6716) | Ja | +| `check:ai-attribution` | Ingen AI/bot-`Co-Authored-By`-trailer eller AI-genereringsfooter i PR-commits, titel eller brødtekst — fast regel #16 (i `quality.yml`-løkken med hurtige kontroller for PR→`release/**` — læser hændelses-payloaden, foretager ingen handling uden for PR'er — og et trin kun for PR'er i `ci.yml`-lint for PR→`main`; også husky-`commit-msg`-hooket; menneskelige medforfattere er tilladt; #14436) | +| `check:vitest-exclusions` | Hver Vitest-ekskludering angiver en tracking-issue og findes i `config/quality/vitest-exclusions.json` (#13204) | Ja | +| `check:file-size` | Ingen kildefil overskrider grænsen for den pågældende filendelse (skraldehjulsmekanisme: fastlåste store filer på listen `frozen`) | Ja | +| `check:error-helper` | Fejlsvar i executors/handlers bruger `buildErrorBody()` / `sanitizeErrorMessage()` (fast regel #12) | Ja | +| `check:migration-numbering` | Migrations-SQL-filer er fortløbende nummereret uden huller eller dubletter | Ja | +| `check:public-creds` | Ingen bogstavelige OAuth-`client_id`/`client_secret`-værdier eller Firebase Web-nøgler uden for `publicCreds.ts` (fast regel nr. 11) | Ja | +| `check:db-rules` | Ingen rå SQL uden for modulerne i `src/lib/db/`; ingen barrel-importer fra `localDb.ts` (faste regler nr. 2/nr. 5) | Ja | +| `check:known-symbols` | Provider-eksekveringsfunktioner, routingstrategier og oversættere, der er registreret i deres dispatch-tabeller, matcher filerne på disken — ingen forældreløse eller ikke-deklarerede symboler | Ja | +| `check:route-guard-membership` | Alle ruter, der starter en underproces, er klassificeret af `isLocalOnlyPath()` (faste regler nr. 15/nr. 17) | Ja | +| `check:test-discovery` | Alle `*.test.ts`- / `*.spec.ts`-filer i repoet indsamles af mindst én testkører (ratchet: listen over forældreløse filer i `test-discovery-baseline.json` kan kun blive kortere) | Ja | +| `check:agent-skills-sync` | Genererede agent-skills-artefakter matcher deres kildekatalog (ingen afvigelser) | +| `check:provider-asset-provenance` | Udbyderlogoer/-aktiver har en registreret oprindelsespost | +| `lint:json` | JSON-konfigurationsfiler kan parses og overholder repoets lintregler | +| `typecheck:core` | TypeScript-kompilering uden fejl (kun vejledende advarsler) | Ja | +| `typecheck:noimplicit:core` | Streng `noImplicitAny` — fremadrettet; mange eksisterende kaldesteder mangler stadig annoteringer | **Vejledende** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` afgrænset til `src/app/(dashboard)/**` (#7033) — `typecheck:core`'s kuraterede tilladelsesliste med 27 filer indeholder ingen dashboard-TSX-filer, og `next build` typekontrollerer dem heller aldrig (`next.config.mjs` angiver `ignoreBuildErrors: true`), så regressioner med ikke-tilknyttede identifikatorer dér (#6625/#6909) var usynlige for CI. Sammenligner med en fastfrosset baseline for antallet pr. fil/pr. TS-kode (`config/quality/dashboard-typecheck-baseline.json`, samme mønster for håndhævelse af forældelse som `check:known-symbols`) — kun NYE fejl ud over baseline-antallet får kontrollen til at fejle; reducer gradvist med `--update`, når en eksisterende fejl rettes. | Ja | ### Job: `quality-gate` Kører efter `test-coverage`. Blokerer sammenfletning ved fejl. -| Script | Validerer | Blokerende | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | -| `quality:collect` | Genererer `quality-metrics.json` (antal ESLint-advarsler, dækning fra flettet shard-rapport) | Ja (forud for ratchet) | -| `quality:ratchet` | Ingen metrik i `quality-baseline.json` er blevet forringet (ESLint-advarsler ≤ baseline; dækning ≥ baseline) | Ja | -| `check:duplication` | Kodeduplikering (jscpd@4) overstiger ikke baseline i `quality-baseline.json` | Ja | -| `check:complexity` | Cyklomatisk kompleksitet på filniveau overstiger ikke grænsen (ESLint-kernereglerne `complexity` + `max-lines-per-function`) | Ja | -| `check:cognitive-complexity` | Ratchet for kognitiv kompleksitet (`eslint-plugin-sonarjs`) — separat ESLint-kørsel; CI kører begge samlet som det enkelte trin `check:complexity-ratchets` | Ja | -| `check:dead-code` | Ratchet for ubrugte eksporter/filer (knip) forringes ikke i forhold til baseline | Ja | -| `check:compression-budget` | Budget for komprimeringsbenchmark — minimumskrav til tokenbesparelser pr. motor må ikke forringes | Ja | -| `check:type-coverage` | Ratchet for procentvist typet kode (`type-coverage`) forringes ikke; erstatter i vid udstrækning `typecheck:noimplicit:core` | Ja | -| `check:codeql-ratchet` | Antallet af åbne CodeQL-advarsler forringes ikke (læses via `gh api`; springes kontrolleret over uden token) — opdateringsfrekvens og manuel udløsning: se "CodeQL-ratchet" nedenfor | Ja | +| Script | Validerer | Blokerende | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `quality:collect` | Genererer `quality-metrics.json` (antal ESLint-advarsler, dækning fra flettet shard-rapport) | Ja (køres før ratchet) | +| `quality:ratchet` | Ingen metrik i `quality-baseline.json` er blevet forringet (ESLint-advarsler ≤ baseline; dækning ≥ baseline) | Ja | +| `check:duplication` | Kodeduplikering (jscpd@4) overskrider ikke baselinen i `quality-baseline.json` | Ja | +| `check:complexity` | Cyklomatisk kompleksitet på filniveau overskrider ikke grænsen (ESLint-kernereglen `complexity` + `max-lines-per-function`) | Ja | +| `check:cognitive-complexity` | Ratchet for kognitiv kompleksitet (`eslint-plugin-sonarjs`) — separat ESLint-kørsel; CI kører begge samlet som det enkelte trin `check:complexity-ratchets` | Ja | +| `check:dead-code` | Ratchet for ubrugte eksporter/filer (knip) forringes ikke i forhold til baselinen | Ja | +| `check:compression-budget` | Budget for komprimeringsbenchmark — minimumskravene til tokenbesparelser pr. motor må ikke forringes | Ja | +| `check:type-coverage` | Ratchet for procentvis typning (`type-coverage`) forringes ikke; erstatter i vid udstrækning `typecheck:noimplicit:core` | Ja | +| `check:codeql-ratchet` | Antallet af åbne CodeQL-advarsler forringes ikke (læses via `gh api`; springes uden fejl over uden token) — opdateringsfrekvens og manuel udløsning: se "CodeQL-ratchet" nedenfor | Ja | ### Job: `quality-extended` Hele jobbet er vejledende (`continue-on-error: true`). De npm-baserede ratchets køres reelt; de eksterne scannere installeres via `gh release download` og springer selv over (exit 0), -når en binær fil stadig mangler. +hvis en binær fil stadig mangler. -| Script | Validerer | Blokerende | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `check:circular-deps` | Ingen cirkulære afhængigheder (dpdm) | **Vejledende** | -| `check:bundle-size` | Bundtstørrelsen overstiger ikke grænsen | **Vejledende** | -| `check:secrets` | Scanning efter hemmeligheder (gitleaks) — springes over, hvis den binære fil mangler | **Vejledende** | -| `check:vuln-ratchet` | Sårbarheder i afhængigheder (osv-scanner) forringes ikke — springes over, hvis den binære fil mangler | **Vejledende** | -| `check:workflows` | Linting af workflows (actionlint + zizmor); manglende/defekte scannere, ugyldige rapporter eller manglende ratchet-baseline medfører fejlen INCOMPLETE. Gyldige fund følger den valgte strenge/vejledende/ratchet-politik | Kørsel påkrævet; zizmor-ratchet blokerer i CI | -| `check:openapi-breaking` | Inkompatible ændringer i den offentlige API-kontrakt (`openapi.yaml`) i forhold til basisgrenen (oasdiff) — genererer `openapiBreaking=N`; springes over, hvis oasdiff mangler, eller basisspecifikationen ikke kan findes | **Vejledende** | +| Script | Validerer | Blokerende | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| `check:circular-deps` | Ingen cirkulære afhængigheder (dpdm) | **Vejledende** | +| `check:bundle-size` | Bundtstørrelsen overskrider ikke grænsen | **Vejledende** | +| `check:secrets` | Scanning efter hemmeligheder (gitleaks) — springes over, hvis den binære fil mangler | **Vejledende** | +| `check:vuln-ratchet` | Sårbarheder i afhængigheder (osv-scanner) forringes ikke — springes over, hvis den binære fil mangler | **Vejledende** | +| `check:workflows` | Linting af workflows (actionlint + zizmor); manglende/defekte scannere, ugyldige rapporter eller en manglende ratchet-baseline medfører fejl som INCOMPLETE. Gyldige fund følger den valgte strenge/vejledende/ratchet-politik | Kørsel påkrævet; zizmor-ratchet er blokerende i CI | +| `check:openapi-breaking` | Bagudinkompatible ændringer i den offentlige API-kontrakt (`openapi.yaml`) i forhold til basisgrenen (oasdiff) — genererer `openapiBreaking=N`; springes over, hvis oasdiff mangler, eller basisspecifikationen ikke kan findes | **Vejledende** | ### Job: `docs-sync-strict` -Kører ved hver PR til `main`. Blokerer sammenfletning ved fejl. - -| Script | Validerer | Blokerende | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `check:docs-all` | Meta-gate, der kører de 6 underliggende gates nedenfor sekventielt | Ja | -| ↳ `check:docs-sync` | Versionskonsistens mellem CHANGELOG / OpenAPI / llm.txt | Ja | -| ↳ `check:docs-counts` | Antal angivet i prosa (antal udbydere, antal migreringer osv.) ligger inden for ratchet-intervallet for de faktiske antal | Ja | -| ↳ `check:env-doc-sync` | Hver miljøvariabel i `.env.example` er dokumenteret i en dokumentationstabel og omvendt | Ja | -| ↳ `check:deprecated-versions` | Ingen udfasede versionsstrenge i dokumentationen | Ja | -| ↳ `check:doc-links` | Interne markdown-links i dokumentationen peger på eksisterende filer (`[tekst]`/`(sti)`-format) | Ja | -| ↳ `check:fabricated-docs` | Ruter, miljøvariabler, CLI-kommandoer, hook-navne og filstier nævnt i dokumentationen findes i kodebasen. Hård gate via `--strict`; soft-fail uden flag. | Ja (via `--strict` i CI) | -| `check:cli-i18n` | CLI-kommandostrenge findes i alle i18n-lokalitetsfiler | Ja | -| `check:openapi-coverage` | OpenAPI-specifikationen dækker mindst en ratchet-baseret minimumsgrænse af de faktiske ruter | Ja | -| `check:openapi-security-tiers` | Sikkerhedsniveauannoteringer i `openapi.yaml` stemmer overens med klassifikationerne i `routeGuard.ts` | **Rådgivende** | -| `check:openapi-routes` | Hver sti i `openapi.yaml` svarer til en faktisk `route.ts` (modvirker hallucinationer) | Ja | -| `check:docs-symbols` | Hver `/api/...`-reference i `docs/**/*.md` svarer til en faktisk `route.ts` (modvirker hallucinationer) | Ja | -| `i18n translation drift` | Ikke-oversatte nøgler i i18n-lokalitetsfiler — kun advarsel | **Rådgivende** | +Køres for hver PR til `main`. Blokerer fletning ved fejl. + +| Script | Validerer | Blokerende | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `check:docs-all` | Metakontrol, der kører de 6 delkontroller nedenfor sekventielt | Ja | +| ↳ `check:docs-sync` | Versionsoverensstemmelse mellem CHANGELOG / OpenAPI / llm.txt | Ja | +| ↳ `check:docs-counts` | Antal i prosa (antal udbydere, antal migreringer osv.) ligger inden for skraldevinduet for de faktiske antal | Ja | +| ↳ `check:env-doc-sync` | Hver miljøvariabel i `.env.example` er dokumenteret i en dokumentationstabel og omvendt | Ja | +| ↳ `check:deprecated-versions` | Ingen forældede versionsstrenge i dokumentationen | Ja | +| ↳ `check:doc-links` | Interne markdownlinks i dokumentationen peger på faktiske filer (`[text]`/`(path)`-format) | Ja | +| ↳ `check:fabricated-docs` | Ruter, miljøvariabler, CLI-kommandoer, hooknavne og filstier, der nævnes i dokumentationen, findes i kodebasen. Hård kontrol via `--strict`; blød fejl uden flag. | Ja (via `--strict` i CI) | +| `check:cli-i18n` | CLI-kommandostrenge findes i alle i18n-lokalitetsfiler | Ja | +| `check:openapi-coverage` | OpenAPI-specifikationen dækker som minimum en gradvist hævet nedre grænse for faktiske ruter | Ja | +| `check:openapi-security-tiers` | Sikkerhedsniveauannoteringer i `openapi.yaml` stemmer overens med klassifikationerne i `routeGuard.ts` | **Vejledende** | +| `check:openapi-routes` | Hver sti i `openapi.yaml` peger på en faktisk `route.ts` (forebyggelse af hallucinationer) | Ja | +| `check:docs-symbols` | Hver `/api/...`-reference i `docs/**/*.md` peger på en faktisk `route.ts` (forebyggelse af hallucinationer) | Ja | +| `i18n translation drift` | Uoversatte nøgler i i18n-lokalitetsfiler — kun advarsel | **Vejledende** | ### Job: `i18n-ui-coverage` @@ -192,42 +188,42 @@ Kører ved hver PR til `main`. Blokerer sammenfletning ved fejl. | `check-ui-keys-coverage` (inline) | Dækningen af UI-i18n-nøgler er ≥ 65 % | Ja | | `check-ui-value-drift` (inline) | En omskrevet engelsk **værdi** efterlader ingen forældet oversættelse | Ja | | `check-new-key-coverage` (inline) | En **ny** engelsk nøgle er oversat i alle lokaliteter — en `__MISSING__:`-markør afvises | Ja | -| `check-translation-ratio` | Andelen af reelle oversættelser pr. lokalitet (blade uden for tilladelseslisten, der er identiske med engelsk / pladsholdere / mangler) må ikke overstige `config/quality/i18n-translation-baseline.json` + margen | **Rådgivende** | +| `check-translation-ratio` | Andelen af reelle oversættelser pr. lokalitet (blade uden for tilladelseslisten, der er identiske med engelsk / pladsholdere / mangler) må ikke overstige `config/quality/i18n-translation-baseline.json` + margen | **Vejledende** | -Kræver `fetch-depth: 0` — value-drift-gaten sammenligner `en.json` med merge-basen. +Kræver `fetch-depth: 0` — kontrollen for værdiafvigelser sammenligner `en.json` med fletningsbasen. -#### `check-ui-value-drift` — gate for forældede oversættelser +#### `check-ui-value-drift` — kontrol for forældede oversættelser -Opfanger den ene i18n-regression, som de andre gates strukturelt ikke kan se: En engelsk værdi -omskrives, mens oversættelserne, der er afledt af den _tidligere_ engelske tekst, bliver stående, så -ikke-engelske brugere fortsat læser en selvsikkert formuleret, men nu forkert tekst. +Opfanger den ene i18n-regression, som de andre kontroller strukturelt ikke kan se: En engelsk værdi +omskrives, mens oversættelserne baseret på den _tidligere_ engelske tekst bliver stående, så +ikke-engelske brugere fortsat læser selvsikkert formuleret, men nu forkert tekst. Dette blev faktisk udgivet. `oauthModal.googleOAuthWarning` blev omskrevet, da Antigravity- -loginhjælperen blev introduceret (#5203); **39 ud af 43 lokaliteter** beholdt en tekst, der bad operatører om at "kopiere -hele URL'en og indsætte den nedenfor" — et flow, der ikke kan gennemføres for den pågældende udbyder. Det +loginhjælperen blev tilføjet (#5203); **39 af 43 lokaliteter** beholdt tekst, der bad operatører om at "kopiere den +fulde URL og indsætte den nedenfor" — et flow, der ikke kan gennemføres for denne udbyder. Det blev ikke opdaget før #8463, fordi: - `sync-ui-keys` udfylder kun nøgler, der **mangler**, aldrig nøgler, der er **forældede**; -- `check-ui-keys-coverage` tæller nøglers _tilstedeværelse_, så en forældet oversættelse tæller som dækket; +- `check-ui-keys-coverage` tæller nøglers _tilstedeværelse_, så en forældet oversættelse regnes som dækket; - `check-translation-drift` sporer dokumentationsspejlene i `docs/i18n//**.md` — den læser aldrig `src/i18n/messages/*.json`. Blokerende i jobbet `docs-sync-strict` siden - gensynkroniseringen i 2026-09: Rediger et kernedokument → `npm run i18n:run -- --files=` (på sektionsniveau, billigt). + gensynkroniseringen i 2026-09: rediger et kernedokument → `npm run i18n:run -- --files=` (på sektionsniveau, billigt). -**Diff-bevidst, ikke understøttet af en baseline.** Den sammenligner `en.json` ved merge-basen med -arbejdstræet; for hver nøgle, hvis engelske værdi er ændret, er enhver lokalitet, der stadig indeholder en +**Diff-bevidst, ikke baseline-understøttet.** Den sammenligner `en.json` ved merge-basen med +arbejdstræet; for hver nøgle, hvis engelske værdi er ændret, er enhver lokalitet, der stadig har en uberørt oversættelse, forældet. Dette **fastfryser bevidst eksisterende gæld** — en diff kan ikke afsløre, hvilken gammel engelsk tekst en eksisterende oversættelse stammer fra, så kontrollen vurderer -kun det, den aktuelle ændring berører. Alternativet (en hash-baseline pr. nøgle) ville kræve -en genereret fil på ~600 KB, 3× større end den største eksisterende baseline, og medføre ændringer ved hver i18n-PR. +kun det, som den aktuelle ændring berører. Alternativet (en hash-baseline pr. nøgle) ville kræve +en genereret fil på ~600 KB, 3× større end den største eksisterende baseline, med ændringer ved hver i18n-PR. -Der er to måder at opfylde kravet på: +Det kan opfyldes på to måder: 1. opdater de berørte oversættelser, eller -2. indstil dem til `__MISSING__:` — kørselstiden leverer derefter den rettede engelske tekst +2. angiv dem som `__MISSING__:` — kørselssystemet leverer derefter den rettede engelske tekst (`src/i18n/request.ts::deepMergeFallback`, #7258), og nøglen sættes i kø til oversættelse. Hvis strengens **betydning** er ændret, bør du foretrække at **omdøbe nøglen**: En ny nøgle kan ikke arve -en forældet oversættelse. Det er det mønster, #8463 brugte. +en forældet oversættelse. Det er det mønster, som #8463 anvendte. ```bash npm run i18n:check-value-drift # streng (det, som CI kører) @@ -236,11 +232,11 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` Afslutter med 0 og `SKIP reason=base-unresolved`, når basiskataloget ikke kan læses (overfladisk -klon uden basereferencen), på samme måde som `check-openapi-breaking`. +klon uden basereferencen), i lighed med `check-openapi-breaking`. ### Job: `i18n` -Komplet i18n-valideringsmatrix (ét job pr. lokalitet). Hele jobbet er vejledende. +Fuld i18n-valideringsmatrix (ét job pr. lokalitet). Hele jobbet er vejledende. | Script | Validerer | Blokerende | | ------------------------------- | ----------------------------------------- | ---------------------------------------------------------- | @@ -250,20 +246,20 @@ Komplet i18n-valideringsmatrix (ét job pr. lokalitet). Hele jobbet er vejledend Kører kun på pull requests. -| Script | Validerer | Blokerende | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PR'er, der ændrer produktionskode i `src/`, `open-sse/`, `electron/` eller `bin/`, skal inkludere eller opdatere test (hård regel #8) | Ja | -| `check:test-masking` | Ændrede testfiler reducerer ikke nettoantallet af asserts og tilføjer ikke `assert.ok(true)`-tautologier | Ja | -| `check:pr-evidence` | PR-beskrivelsen henviser til test-/VPS-dokumentation for ændringen (automatiserer hård regel #18 ved at søge i PR-teksten — skrøbeligt, se Backlog) | Ja | +| Script | Validerer | Blokerende | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | PR'er, der ændrer produktionskode i `src/`, `open-sse/`, `electron/` eller `bin/`, skal inkludere eller opdatere tests (ufravigelig regel nr. 8) | Ja | +| `check:test-masking` | Ændrede testfiler reducerer ikke nettoantallet af assertions og tilføjer ikke `assert.ok(true)`-tautologier | Ja | +| `check:pr-evidence` | PR-beskrivelsen henviser til test-/VPS-dokumentation for ændringen (automatiserer ufravigelig regel nr. 18 ved at gennemsøge PR-teksten — skrøbeligt, se Backlog) | Ja | ### Job: `test-vitest` -Kører efter `build`. Blokerer fletning ved fejl. +Kører efter `build`. Blokerer sammenfletning ved fejl. -| Suite | Validerer | Blokerende | -| ---------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-server (110 værktøjer), autoCombo, cache — vitest-kørsel | Ja | -| `test:vitest:ui` | UI-komponenttest — vitest-kørsel | **Blokerende** — eksisterende fejl er udtrykkeligt ekskluderet i `vitest.config.ts`; nye fejl får jobbet til at fejle | +| Pakke | Validerer | Blokerende | +| ---------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP-server (110 værktøjer), autoCombo, cache — vitest-kørsel | Ja | +| `test:vitest:ui` | UI-komponenttests — vitest-kørsel | **Blokerende** — eksisterende fejl er eksplicit udeladt i `vitest.config.ts`; nye fejl får jobbet til at fejle | ### Natlige workflows (planlagte, vejledende) @@ -271,11 +267,11 @@ Disse kører efter en cron-plan (og `workflow_dispatch`), aldrig på PR'er. De e | Workflow | Validerer | Blokerende | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | fast-check-egenskabstest med en tilfældig seed-værdi + et højt antal kørsler | **Vejledende** | -| `nightly-resilience` | kontrol af heap-vækst, chaos-fejlinjektion, k6-belastnings-/udholdenhedstest | **Vejledende** | +| `nightly-property` | fast-check-egenskabstests med et tilfældigt seed og et højt antal kørsler | **Vejledende** | +| `nightly-resilience` | kontrol af heap-vækst, chaos fault-injection, k6-belastnings-/udholdenhedstest | **Vejledende** | | `nightly-llm-security` | promptfoo-injektionsbeskyttelse (blokeringstilstand) + garak-prober (springes over uden en udbyderhemmelighed) | **Vejledende** | -| `nightly-schemathesis` | OpenAPI-kontraktfuzzing (schemathesis) mod en aktiv OmniRoute ved hjælp af `docs/openapi.yaml` — afdækker specifikationsbrud/uhåndterede 500-fejl (Fase 8 B.4) | **Vejledende** | -| `nightly-mutation` | Stryker-mutationstestscore for den hurtige enhedstestbane — overlevende mutanter afdækker svage asserts | **Vejledende** | +| `nightly-schemathesis` | OpenAPI-kontraktfuzzing (schemathesis) mod en aktiv OmniRoute ved brug af `docs/openapi.yaml` — synliggør specifikationsbrud/uhåndterede 500-fejl (Fase 8 B.4) | **Vejledende** | +| `nightly-mutation` | Stryker-mutationstestscore for den hurtige enhedstestbane — overlevende mutanter synliggør svage assertions | **Vejledende** | | `nightly-compat` | Kompatibilitetsmatrix for Node-motoren på tværs af de understøttede `engines.node`-intervaller | **Vejledende** | --- @@ -540,43 +536,43 @@ forbindelsesfejl og afbryder aldrig sessioner. --- -## Rationaliserings-backlog (ROI-gennemgang — Fase 9 Bølge 3) +## Rationaliserings-backlog (ROI-gennemgang — Fase 9 Onda 3) Denne oversigt blev afstemt mod `ci.yml` den 2026-06-17 (den tidligere version udelod `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). En ROI-gennemgang af det afstemte sæt -identificerede følgende kandidater til rationalisering. **Sammenlægningerne er mekaniske -CI-ændringer; ændringerne/fjernelserne er politiske beslutninger, som er forbeholdt operatøren.** Intet nedenfor +identificerede følgende rationaliseringskandidater. **Sammenlægningerne er mekaniske +CI-ændringer; ændringerne/fjernelserne er politikbeslutninger, der er forbeholdt operatøren.** Intet nedenfor er anvendt endnu. -**Også udokumenteret ovenfor** (vejledende, lavt signal): jobbet `docs-lint` -(markdownlint + Vale, hele jobbet med `continue-on-error`) og de separate scanner-workflows +**Også udokumenteret ovenfor** (vejledende, lavt signalniveau): jobbet `docs-lint` +(markdownlint + Vale, hele jobbet har `continue-on-error`) og de selvstændige scanner-workflows `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` findes i -`quality-baseline.json`, men er ikke koblet til en blokerende skralde i `ci.yml` — metrikken er +`quality-baseline.json`, men er ikke koblet til en blokerende ratchet i `ci.yml` — metrikken er i øjeblikket forældreløs. ### Sammenlægning / deduplikering (mekanisk, lavere risiko) -Hver kandidat blev valideret mod den aktuelle gate-tilstand den 2026-06-17 (stol på, men verificér); -flere "åbenlyse" sammenlægninger viste sig at skjule gæld og er **ikke** direkte anvendelige erstatninger. +Hver kandidat blev valideret mod den aktive gate-tilstand den 2026-06-17 (hav tillid, men verificér); +flere "indlysende" sammenlægninger viste sig at skjule gæld og er **ikke** direkte anvendelige erstatninger. -- **`check:docs-sync` køres to gange** — separat i jobbet `lint` og igen i `check:docs-all` (`docs-sync-strict`) samt i husky pre-commit-hooken. ✅ **FÆRDIG** — separat `lint`-kørsel fjernet. -- **CVE-scanning** — ❌ **IKKE en ukompliceret sammenlægning.** `audit:deps` fejler hårdt ved enhver CVE med høj/kritisk alvorlighed; `check:vuln-ratchet` (osv) fejler kun ved en _regression_ i forhold til baseline (i øjeblikket 1 MODERATE). Forskellig semantik — fjernelse af `audit:deps` ville fjerne den absolutte gate for høj/kritisk alvorlighed. Behold begge. -- **Cyklusregistrering** — ❌ **IKKE en ukompliceret sammenlægning.** `check:circular-deps` (dpdm) rapporterer **91 cyklusser** (det er derfor, den er vejledende); den kan ikke gøres blokerende uden først at løse dem, og den har et bredere omfang end den grønne, kuraterede `check:cycles`. Behold `check:cycles` som blokerende; løsning af de 91 dpdm-cyklusser er sin egen backlog. -- **Kompleksitet** — ✅ **FÆRDIG** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): én ESLint-gennemgang, optællinger efter ruleId, så baselines for cyklomatisk kompleksitet+maksimalt antal linjer og kognitiv kompleksitet forbliver uafhængige; individuelle `check:complexity` / `check:cognitive-complexity` bibeholdes til lokal `--update`. -- **`/api`-antihallucination** — ✅ **FÆRDIG** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): én FS-oversigt over `src/app/api`; openapi-routes + docs-symbols rapporterer stadig uafhængigt; individuelle tjek bibeholdes til lokale kørsler. -- **`check:node-runtime` køres i 11 jobs** — ⚠️ **lav ROI.** Hvert job bruger en separat runner, og tjekket tager <1s; samlet besparelse ~10s mod tabet af en billig beskyttelse pr. job. Ikke besværet værd. +- **`check:docs-sync` kører to gange** — selvstændigt i jobbet `lint` og igen inde i `check:docs-all` (`docs-sync-strict`) samt i husky pre-commit-hooket. ✅ **FÆRDIG** — den selvstændige `lint`-kørsel er fjernet. +- **CVE-scanning** — ❌ **IKKE en problemfri sammenlægning.** `audit:deps` fejler hårdt ved enhver CVE med høj/kritisk alvorlighed; `check:vuln-ratchet` (osv) fejler kun ved en _forværring_ i forhold til baseline (aktuelt 1 MODERATE). Forskellig semantik — fjernelse af `audit:deps` ville fjerne den absolutte gate for høj/kritisk alvorlighed. Behold begge. +- **Cyklusdetektering** — ✅ **FÆRDIG** (#15159 G-01/G-02). Den gamle tekst her kaldte `check:cycles` for "den grønne, kuraterede" gate og begrundede, at den fortsat skulle være blokerende, fordi `check:circular-deps` (dpdm) rapporterede 91 cyklusser. Det grønne resultat var **falsk grønt**: `check:cycles` scannede 5 undermapper (450 filer), matchede kun statiske `import|export … from` og ignorerede alle `@/`- og `@omniroute/open-sse/`-specifikatorer, så den kunne ikke se de cyklusser med dynamiske imports og aliaser, der dominerede repoet. Rettet: gaten gennemgår nu `src` + `open-sse` (5023 filer), indsamler specifikatorer fra TypeScript-AST'en (så `import("…")` tæller, mens `typeof import("…")` i typeposition ikke gør) og opløser tsconfig-`paths`. Den finder **14** cyklusser, ikke 0. Da 14 allerede eksisterende cyklusser ikke kan rettes i en gate-PR, er `check:cycles` nu en **ratchet** (`--ratchet`, loft `metrics.cycles.value = 14` i `quality-baseline.json`, `direction: down`) — den blokerer enhver _forværring_, og antallet kan kun falde. CI kører `npm run check:cycles:ratchet`. Nedbringelsen følger med **A-01**. `check:circular-deps` (dpdm) forbliver vejledende som den bredere sekundære vurdering. +- **Kompleksitet** — ✅ **FÆRDIG** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): én ESLint-gennemgang, optælling efter ruleId, så cyclomatic+max-lines- og cognitive-baselines forbliver uafhængige; de individuelle `check:complexity` / `check:cognitive-complexity` bibeholdes til lokal `--update`. +- **`/api`-antihallucination** — ✅ **FÆRDIG** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): én FS-oversigt over `src/app/api`; openapi-routes + docs-symbols rapporterer stadig uafhængigt; de individuelle kontroller bibeholdes til lokale kørsler. +- **`check:node-runtime` kører i 11 jobs** — ⚠️ **lav ROI.** Hvert job bruger en separat runner, og kontrollen tager <1s; samlet besparelse ~10s mod at miste en billig sikkerhedskontrol pr. job. Ikke besværet værd. - **`typecheck:noimplicit:core` i CI-lint** — ✅ **fjernet fra lint-jobbet** (var vejledende med `continue-on-error`); den blokerende typeoverflade er `typecheck:core` + `check:type-coverage`. Det lokale script er bibeholdt. -### Skift / beslut (operatørpolitik) +### Ændr / beslut (operatørpolitik) -- `check:openapi-security-tiers` (vejledende) — ❌ **KAN IKKE ukompliceret gøres blokerende.** Den afslutter med 0, men advarer om, at flere `traffic-inspector`-ruter under `LOCAL_ONLY_API_PREFIXES` mangler annoteringen `x-loopback-only: true`. Håndhævelse kræver, at disse annoteringer først føjes til `openapi.yaml`. -- `typecheck:noimplicit:core` (vejledende) — er i vid udstrækning overflødiggjort af den blokerende `check:type-coverage`-skralde. Gør den til en skralde, eller fjern den redundante anden `tsc`-gennemgang. -- `test:vitest:ui` (nu **blokerende**) — allerede eksisterende fejl er eksplicit udelukket i `vitest.config.ts` med `// #8618`-sporingskommentarer; nye fejl får jobbet til at fejle. -- `check:secrets` (gitleaks, blokerende skralde fastfrosset ved 3 dokumenterede falske positiver) — føj de 3 til tilladelseslisten for at nå 0, eller nedgradér til vejledende. Overlapper GitHubs indbyggede hemmelighedsscanning + `check:public-creds`. -- `check:pr-evidence` (blokerende, søger i PR-brødtekstens prosa med grep) — høj risiko for falske positiver; hvis den fjernes, svækkes håndhævelsen af Hård regel #18, så dette er en reel politisk beslutning. -- `semgrep` (separat vejledende workflow) — overlapper CodeQL for OWASP-familierne; kobl dens baseline til en skralde, eller fjern den. +- `check:openapi-security-tiers` (vejledende) — ❌ **KAN IKKE problemfrit gøres blokerende.** Den afslutter med 0, men advarer om, at flere `traffic-inspector`-ruter under `LOCAL_ONLY_API_PREFIXES` mangler annoteringen `x-loopback-only: true`. Håndhævelse kræver, at disse annoteringer først føjes til `openapi.yaml`. +- `typecheck:noimplicit:core` (vejledende) — er i vid udstrækning dækket af den blokerende `check:type-coverage`-ratchet. Gør den til en ratchet, eller fjern den redundante anden `tsc`-kørsel. +- `test:vitest:ui` (nu **blokerende**) — allerede eksisterende fejl er eksplicit ekskluderet i `vitest.config.ts` med `// #8618`-sporingskommentarer; nye fejl får jobbet til at fejle. +- `check:secrets` (gitleaks, blokerende ratchet fastlåst ved 3 dokumenterede falske positiver) — tilføj de 3 til allowlisten for at nå 0, eller nedgradér til vejledende. Overlapper GitHubs indbyggede secret-scanning + `check:public-creds`. +- `check:pr-evidence` (blokerende, søger med grep i PR-brødteksten) — høj risiko for falske positiver; fjernelse svækker håndhævelsen af Hard Rule #18, så dette er en reel politikbeslutning. +- `semgrep` (selvstændig og vejledende) — overlapper CodeQL for OWASP-familierne; forbind dens baseline med en ratchet, eller fjern den. --- diff --git a/docs/i18n/de/CONTRIBUTING.md b/docs/i18n/de/CONTRIBUTING.md index 8f11eaf2b36..6d34ed40e37 100644 --- a/docs/i18n/de/CONTRIBUTING.md +++ b/docs/i18n/de/CONTRIBUTING.md @@ -389,20 +389,20 @@ Unit-Tests in `tests/unit/` schreiben, die mindestens Folgendes abdecken: ## Pull-Request-Checkliste -- [ ] Tests erfolgreich (`npm test`) -- [ ] Linting erfolgreich (`npm run lint`) -- [ ] Build erfolgreich (`npm run build`) +- [ ] Tests sind erfolgreich (`npm test`) +- [ ] Linting ist erfolgreich (`npm run lint`) +- [ ] Build ist erfolgreich (`npm run build`) - [ ] TypeScript-Typen für neue öffentliche Funktionen und Schnittstellen hinzugefügt - [ ] Keine hartcodierten Geheimnisse oder Fallback-Werte -- [ ] Öffentliche Upstream-Zugangsdaten über `resolvePublicCred()` eingebettet (siehe [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), niemals als Literale -- [ ] Fehlerantworten werden über `buildErrorBody()` / `sanitizeErrorMessage()` geleitet – keine unverarbeiteten Stacktraces in Antworttexten (siehe [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Öffentliche Zugangsdaten von Upstream-Diensten über `resolvePublicCred()` eingebettet (siehe [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), niemals als Literale +- [ ] Fehlerantworten werden über `buildErrorBody()` / `sanitizeErrorMessage()` geleitet — keine unbearbeiteten Stacktraces in Antwortinhalten (siehe [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Shell-Befehle (`exec` / `spawn`) übergeben Laufzeitwerte über `env`, nicht über String-Interpolation - [ ] Alle Eingaben mit Zod-Schemas validiert -- [ ] Changelog-**Fragment** für benutzersichtbare Änderungen unter `changelog.d/{features|fixes|maintenance}/-.md` hinzugefügt (siehe [`changelog.d/README.md`](./changelog.d/README.md)) – `CHANGELOG.md` **nicht** direkt bearbeiten; Fragmente werden zum Veröffentlichungszeitpunkt zusammengeführt und verursachen niemals Konflikte zwischen PRs +- [ ] Changelog-**Fragment** für benutzersichtbare Änderungen unter `changelog.d/{features|fixes|maintenance}/-.md` hinzugefügt (siehe [`changelog.d/README.md`](./changelog.d/README.md)) — `CHANGELOG.md` **nicht** direkt bearbeiten; Fragmente werden zum Veröffentlichungszeitpunkt zusammengeführt und verursachen niemals Konflikte zwischen PRs - [ ] Dokumentation aktualisiert (falls zutreffend) -- [ ] Keine neuen CodeQL- / Secret-Scanning-Warnungen ausgelöst oder jede einzelne mit einer technischen Begründung unter Verweis auf das relevante Dokument unter `docs/security/` verworfen -- [ ] Routen, die untergeordnete Prozesse starten (`/api/mcp/`, `/api/cli-tools/runtime/`), in `src/server/authz/routeGuard.ts` als `isLocalOnlyPath()` klassifiziert – siehe [Strikte Regel Nr. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Keine `Co-Authored-By`-Trailer in Commit-Nachrichten – Commits dürfen ausschließlich unter der Git-Identität des Repository-Eigentümers erscheinen (Strikte Regel Nr. 16) +- [ ] Keine neuen CodeQL-/Secret-Scanning-Warnungen ausgelöst oder jede Warnung mit einer technischen Begründung unter Verweis auf das relevante Dokument unter `docs/security/` verworfen +- [ ] Routen, die untergeordnete Prozesse starten (`/api/mcp/`, `/api/cli-tools/runtime/`), in `src/server/authz/routeGuard.ts` als `isLocalOnlyPath()` klassifiziert — siehe [Strikte Regel Nr. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Keine `Co-authored-by`-Trailer für KI/Bots in Commit-Nachrichten (strikte Regel Nr. 16) — menschliche Mitwirkende, deren Arbeit wiederverwendet wird, werden mit standardmäßigen `Co-authored-by: Name `-Trailern gewürdigt --- diff --git a/docs/i18n/de/docs/architecture/QUALITY_GATES.md b/docs/i18n/de/docs/architecture/QUALITY_GATES.md index 09ce2cf60f7..686e862f9a5 100644 --- a/docs/i18n/de/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/de/docs/architecture/QUALITY_GATES.md @@ -19,146 +19,153 @@ Replikationsplan desselben Systems finden Sie im ### Kandidatenzulassung -Die Workflows für CI- und Quality Gates geben jeweils ein stabiles Ergebnis aus: `Gate / CI` und +Die Workflows „CI“ und „Quality Gates“ geben jeweils ein stabiles Ergebnis aus: `Gate / CI` und `Gate / Quality`. Ihre versionierte Zulassungsrichtlinie führt jeden vorgelagerten Job -als erforderlich oder beratend auf. Ein zutreffender erforderlicher Job muss erfolgreich sein: -Fehlende, abgebrochene, übersprungene, ausstehende und unbekannte Ergebnisse können keinen PASS-Status begründen. Eine gültige Klassifizierung als „nur Dokumentation“ oder „nur Katalog“ kann einen Code-Ausführungspfad unzutreffend machen; -ein PR im Entwurfsstatus wird nicht als Kandidat akzeptiert. Ein `hotfix`-Label setzt die Nachweispflicht nicht außer Kraft. - -Beide Workflows decken PRs und Pushes auf main-/release-Branches, manuelle Auslösungen und -Merge-Group-Ereignisse ab. Bei Pushes, manuellen Auslösungen und Merge Groups wird die vollständige Auswahl ausgeführt. Forks -und Merge Groups verwenden gehostete Runner für Jobs, die andernfalls selbst gehostete -Runner auswählen; vor dem Rollout muss eine ausreichende gehostete Kapazität sichergestellt werden. +als erforderlich oder optional auf. Ein zutreffender erforderlicher Job muss erfolgreich sein: +Fehlende, abgebrochene, übersprungene, ausstehende und unbekannte Ergebnisse können keinen PASS +begründen. Eine gültige Klassifizierung als reine Dokumentations- oder Katalogänderung kann dazu +führen, dass ein Code-Ausführungspfad nicht anwendbar ist; ein PR-Entwurf ist kein akzeptierter +Kandidat. Ein `hotfix`-Label hebt die Nachweispflicht nicht auf. + +Beide Workflows decken PRs und Pushes auf main-/release-Branches, manuelle Ausführungen und +Merge-Group-Ereignisse ab. Bei Pushes, manuellen Ausführungen und Merge Groups wird die vollständige +Auswahl ausgeführt. Forks und Merge Groups verwenden gehostete Runner für Jobs, die andernfalls +selbst gehostete Runner auswählen; vor dem Rollout muss eine ausreichende gehostete Kapazität +verifiziert werden. Jeder JSON-Beleg identifiziert den ausgecheckten SHA, den Workflow-Lauf und den Versuch. -Die CLI weist eine Abweichung zwischen Checkout- und Ereignis-SHA zurück. Workflow-Tests binden die Richtlinienzugehörigkeit -an die `needs`-Liste des Ergebnis-Jobs, sodass ein neuer oder entfernter Ausführungspfad nicht unbemerkt verschwinden kann. -Die Belege decken den jeweils eigenen Workflow ab, nicht die Veröffentlichung, das Deployment oder die internen Abläufe -eines bestehenden beratenden Scanners. Die Aktivierung beider Prüfungsnamen in Branch-Regeln ist eine -separate administrative Änderung; das Hinzufügen dieser Jobs schützt einen Branch nicht automatisch. +Die CLI weist eine Abweichung zwischen Checkout- und Ereignis-SHA zurück. Workflow-Tests binden +die Richtlinienzugehörigkeit an die `needs`-Liste des Ergebnis-Jobs, sodass ein neuer oder entfernter +Ausführungspfad nicht unbemerkt verschwinden kann. Die Belege decken den eigenen Workflow ab, nicht +die Veröffentlichung, die Bereitstellung oder die Interna eines bestehenden optionalen Scanners. +Die Aktivierung beider Prüfnamen in Branch-Regeln ist eine separate administrative Änderung; +das Hinzufügen dieser Jobs schützt einen Branch nicht automatisch. ### Inventar der statischen Scans Das versionierte npm-Alias-Inventar und die Zugehörigkeit zu statischen Scans befinden sich in `config/quality/gate-manifest.json`. Führen Sie `npm run check:gate-manifest` aus, um -Skriptnamen und exakte Befehle anhand von `package.json` zu validieren; Ergänzungen, Entfernungen und -Befehlsabweichungen führen sowohl im lokalen Hook als auch in den Jobs zur Änderungsklassifizierung in CI zu einem Fehler. -Ein Alias ist weder ein Workflow-Job noch eine Matrixinstanz oder ein Testfall: Diese Anzahlen dürfen -nicht als austauschbar dargestellt werden. +Skriptnamen und exakte Befehle anhand von `package.json` zu validieren; Ergänzungen, Entfernungen +und Befehlsabweichungen lassen sowohl den lokalen Hook als auch die Jobs zur Änderungsklassifizierung +in CI fehlschlagen. Ein Alias ist weder ein Workflow-Job noch eine Matrixinstanz oder ein Testfall: +Diese Anzahlen dürfen nicht als austauschbar dargestellt werden. Verwenden Sie `npm run quality:scan -- --list` oder `npm run quality:scan:fast -- --list`, um die ausgewählten Aliasse zu prüfen, ohne sie auszuführen. Der Runner ruft den -npm-Einstiegspunkt auf, sodass dessen Laufzeitumgebung (einschließlich Bun, sofern konfiguriert) beibehalten wird. -Das Manifest erfasst Aliasse außerhalb dieser Profile als separat aufgerufen, und -Wartungsbefehle sind in schreibgeschützten Scanprofilen verboten. +npm-Einstiegspunkt auf, sodass dessen Laufzeitumgebung (einschließlich Bun, sofern konfiguriert) +beibehalten wird. Das Manifest erfasst Aliasse außerhalb dieser Profile als separat aufgerufen, +und Wartungsbefehle sind in schreibgeschützten Scanprofilen nicht zulässig. -Diese Profile decken nur den statischen Scan ab. Sie bestätigen weder Produkttests, -Abdeckung, Paketierung, externe Prüfungen noch die vollständige Release-Zulassung eines Kandidaten. -Die Workflow-Zulassung verwendet die verknüpften Dateien `config/quality/admission-policy.json` und -`scripts/quality/admission-verdict.mjs`. Profile für Release-Beobachter bleiben separat; -prüfen Sie deren zutreffende Prüfungen und Belege unabhängig. Das nachstehende -Textinventar dient als Referenz und ist kein Nachweis dafür, dass ein Gate tatsächlich ausgeführt wurde. +Diese Profile decken nur den statischen Scan ab. Sie zertifizieren weder Produkttests, +Testabdeckung, Paketierung, externe Prüfungen noch die vollständige Release-Zulassung eines +Kandidaten. Die Workflow-Zulassung verwendet die verknüpfte Datei +`config/quality/admission-policy.json` und `scripts/quality/admission-verdict.mjs`. +Release-Observer-Profile bleiben davon getrennt; prüfen Sie ihre zutreffenden Prüfungen und +Belege unabhängig voneinander. Das nachfolgende textuelle Inventar dient als Referenz und ist +kein Nachweis dafür, dass ein Gate tatsächlich ausgeführt wurde. -Skripte befinden sich unter `scripts/check/` (Richtlinien-Gates) und `scripts/quality/` (Ratchet-Engine). -Die maßgebliche CI-Quelle ist `.github/workflows/ci.yml`. +Skripte befinden sich unter `scripts/check/` (Richtlinien-Gates) und `scripts/quality/` +(Ratchet-Engine). Die maßgebliche CI-Quelle ist `.github/workflows/ci.yml`. -### Schneller Ausführungspfad für Release-PRs (`quality.yml`) +### Schneller Pfad für Release-PRs (`quality.yml`) `.github/workflows/quality.yml` ergänzt CI bei main-/release-PRs, Pushes auf geschützte Branches, -manuellen Auslösungen und Merge Groups. PRs verwenden pfadgefilterte Schnellprüfungen. Der dauerhaft -deaktivierte duplizierte Build wurde entfernt; die tatsächlichen Build-, Paketierungs- und Boot-Prüfungen verbleiben in CI. - -| Job | Umfang | Blockierend | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ | -| `Docs Gates (fast-path)` | Dokumentations-/Code-PRs; API-Dokumentationsreferenzen und vollständige Dokumentation | Ja | -| `Fast Quality Gates` | Code-PRs; statische Prüfungen, Typprüfung, Dashboard-Typprüfung, betroffene Unit-Tests | Ja | -| `Forgotten sibling tests` | Code-PRs; geänderte Module werden bis zu statischen Konsumenten und potenziellen Geschwistertests nachverfolgt; Barrel- und dynamische Importpfade werden als beratende Diagnosen gemeldet, mit referenzierten Ausnahmen aus der Zulassungsliste | **Beratend** | -| `Vitest (fast-path)` | Code-PRs; schnelle Vitest-Suite | Ja | -| `Unit Tests fast-path` | Code-PRs; Unit-Suite mit 4 Shards | Ja | -| `No new ESLint warnings` | Code-PRs; unterdrückungsbewusste Lint-Schutzprüfung | Ja, einschließlich Forks | -| `Merge integrity (changelog + generated skills)` | PRs ohne Entwurfsstatus; Synchronisierung des Changelogs und der generierten Skills | Ja, einschließlich Forks | - -#### Bericht zu vergessenen Geschwistertests - -`npm run check:forgotten-sibling-tests` verwendet den Import-Resolver wieder, der der Zuordnung der Testauswirkungen zugrunde liegt. -Für jedes geänderte Produktionsmodul meldet er deterministische Ketten vom Typ -`geändertes Modul/Symbol -> statischer Konsument -> potenzieller Geschwistertest`, wenn der potenzielle -Test nicht im Diff des Pull Requests enthalten ist. Die Markdown-Zusammenfassung und das JSON-Ergebnis werden als -Workflow-Artefakt `forgotten-sibling-tests` zur Kalibrierung vor einem möglichen blockierenden Rollout aufbewahrt. - -Barrel-Re-Exports und dynamische Importe dienen ausschließlich der Auflösungsdiagnose; sie erzeugen niemals einen +manuellen Ausführungen und Merge Groups. PRs verwenden pfadgefilterte Schnellprüfungen. Der dauerhaft +deaktivierte doppelte Build wurde entfernt; die tatsächlichen Build-, Paketierungs- und +Startprüfungen verbleiben in CI. + +| Job | Umfang | Blockierend | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ | +| `Docs Gates (fast-path)` | Dokumentations-/Code-PRs; API-Dokumentationsreferenzen und die gesamte Dokumentation | Ja | +| `Fast Quality Gates` | Code-PRs; statische Prüfungen, Typprüfung, Dashboard-Typprüfung, betroffene Unit-Tests | Ja | +| `Forgotten sibling tests` | Code-PRs; geänderte Module werden zu statischen Konsumenten und potenziellen zugehörigen Tests zurückverfolgt; Barrel- und dynamische Importpfade werden als optionale Diagnosen gemeldet, einschließlich referenzierter Ausnahmen in der Positivliste | **Optional** | +| `Vitest (fast-path)` | Code-PRs; schnelle Vitest-Suite | Ja | +| `Unit Tests fast-path` | Code-PRs; Unit-Test-Suite mit 4 Shards | Ja | +| `No new ESLint warnings` | Code-PRs; unterdrückungsbewusste Lint-Schutzprüfung | Ja, einschließlich Forks | +| `Merge integrity (changelog + generated skills)` | PRs, die keine Entwürfe sind; Synchronisierung von Changelog und generierten Skills | Ja, einschließlich Forks | + +#### Bericht zu vergessenen zugehörigen Tests + +`npm run check:forgotten-sibling-tests` verwendet den Import-Resolver hinter der +Testauswirkungszuordnung erneut. Für jedes geänderte Produktionsmodul meldet er deterministische +Ketten der Form `changed module/symbol -> static consumer -> candidate sibling test`, wenn der +potenzielle Test im Diff des Pull Requests fehlt. Die Markdown-Zusammenfassung und das JSON-Ergebnis +werden zur Kalibrierung vor einem blockierenden Rollout als Workflow-Artefakt +`forgotten-sibling-tests` aufbewahrt. + +Barrel-Re-Exporte und dynamische Importe dienen ausschließlich der Auflösungsdiagnose; sie erzeugen niemals einen blockierenden Befund. Geprüfte Ausnahmen befinden sich in -`config/quality/forgotten-sibling-allowlist.json`. Jeder Eintrag muss den Consumer und den infrage kommenden -Test benennen, eine konkrete Begründung enthalten und auf ein GitHub-Issue oder einen Pull Request verweisen. Fehlerhafte Einträge führen -standardmäßig zum Fehlschlagen. Ausnahmen können weder einen gelöschten infrage kommenden Test noch einen Diff unterdrücken, der `.skip`/`.todo` hinzufügt; -das Abschwächen von Assertions und andere Verschleierungen fallen weiterhin in den Zuständigkeitsbereich des unabhängig blockierenden +`config/quality/forgotten-sibling-allowlist.json`. Jeder Eintrag muss den Consumer und den +Kandidaten-Test benennen, eine konkrete Begründung enthalten und auf ein GitHub-Issue oder einen Pull Request verweisen. Fehlerhafte Einträge führen +standardmäßig zu einem Fehler. Ausnahmen können weder einen gelöschten Kandidaten-Test noch einen Diff unterdrücken, der `.skip`/`.todo` +hinzufügt; das Abschwächen von Assertions und andere Verschleierungen fallen weiterhin in den Zuständigkeitsbereich des unabhängig blockierenden `check:test-masking`-Gates. ### Job: `lint` -Wird bei jedem PR für `main` ausgeführt. Blockiert den Merge bei einem Fehler. - -| Skript (`npm run ...`) | Validiert | Blockierend | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Die Node.js-Version liegt innerhalb des unterstützten Bereichs | Ja | -| `check:cycles` | Zirkuläre Importe — alle Module unter `src/` + `open-sse/` | Ja | -| `check:route-validation:t06` | Zod-Schemas sind für alle Routen vorhanden (Tier-6-Richtlinie) | Ja | -| `check:any-budget:t11` | Die Anzahl von `@ts-expect-error // any` überschreitet das Budget nicht (Tier-11-Catraca) | Ja | -| `check:provider-consistency` | Jeder Provider in `providers.ts` hat einen entsprechenden Eintrag in `providerRegistry.ts` (und umgekehrt, innerhalb der Allowlist) | Ja | -| `check:model-lifecycle` | Die drei manuell gepflegten Routing-Tabellen bleiben mit dem eingecheckten Lifecycle-Snapshot (#11503) konsistent: `FITNESS_TABLE` (`taskFitness.ts`) bewertet keine außer Betrieb genommene ID, die `REGISTRY` routen kann; jedes Ziel von `BUILT_IN_ALIASES` ist in `REGISTRY` vorhanden und fehlt im Snapshot der außer Betrieb genommenen IDs; jede außer Betrieb genommene ID, die noch in `REGISTRY` enthalten ist, wird weitergeleitet oder ist in `allowedRetiredInCatalog` aufgeführt; und weder Quelle noch Ziel in `DEFAULT_DEGRADATION_MAP` ist in diesem Snapshot als außer Betrieb genommen verzeichnet. Dies beweist nicht, dass ein Modell derzeit von einem aktiven Upstream bereitgestellt wird. Offline — Vergleich mit `config/quality/model-lifecycle.json`, manuell aktualisiert mit `npm run quality:refresh-model-lifecycle` (Netzwerk; nicht in CI eingebunden). `allowedRetiredInCatalog` ist eine Burn-down-Ratsche: Einen Eintrag nur zusammen mit einem Tracking-Issue hinzufügen. | Ja | -| `check:fetch-targets` | Jeder Aufruf von `fetch("/api/...")` im clientseitigen `src/` wird zu einer tatsächlich vorhandenen `route.ts` aufgelöst | Ja | -| `check:deps` | Alle mit `npm install` installierbaren Abhängigkeiten aus jeder `package.json` im Repository sind in `dependency-allowlist.json` enthalten; neue nicht fixierte oder durch Slopsquatting entstandene Pakete werden markiert | Ja | -| `audit:deps` | `npm audit` (Root + Electron) — keine Warnungen mit hohem/kritischem Schweregrad (überschneidet sich mit OSV `check:vuln-ratchet`; siehe Rationalisierungs-Backlog) | Ja | -| `check:lockfile` | Integrität von `package-lock.json` — HTTPS-Registry, Integritäts-Hashes, keine Host-Überschreibungen | Ja | -| `check:licenses` | SPDX-Lizenz-Zulassungsliste für Produktionsabhängigkeiten | Ja | -| `check:tracked-artifacts` | Keine Build-Artefakte / eingecheckten `node_modules`-Symlinks (wird auch beim Husky-Pre-Commit ausgeführt; Pre-Push ist absichtlich schlank — #6716) | Ja | -| `check:ai-attribution` | Kein AI-/Bot-`Co-Authored-By`-Trailer oder Hinweis auf AI-Generierung in PR-Commits, Titel oder Beschreibung — Strikte Regel Nr. 16 (in der Fast-Gates-Schleife von `quality.yml` für PR→`release/**` — liest die Event-Nutzlast, außerhalb von PRs keine Aktion — sowie als reiner PR-Schritt im Lint-Job von `ci.yml` für PR→`main`; außerdem der Husky-Hook `commit-msg`; menschliche Co-Autoren sind zulässig; #14436) | -| `check:vitest-exclusions` | Jeder Vitest-Ausschluss nennt ein Tracking-Issue und ist in `config/quality/vitest-exclusions.json` aufgeführt (#13204) | Ja | -| `check:file-size` | Keine Quelldatei überschreitet die Obergrenze der jeweiligen Dateiendung (Ratchet-Prinzip: unveränderliche große Dateien in der Liste `frozen`) | Ja | -| `check:error-helper` | Fehlerantworten in Executors/Handlern verwenden `buildErrorBody()` / `sanitizeErrorMessage()` (Strikte Regel Nr. 12) | Ja | -| `check:migration-numbering` | Migrations-SQL-Dateien sind fortlaufend nummeriert, ohne Lücken oder Duplikate | Ja | -| `check:public-creds` | Keine fest eingetragenen OAuth-`client_id`/`client_secret`- oder Firebase-Web-Schlüssel außerhalb von `publicCreds.ts` (Strikte Regel Nr. 11) | Ja | -| `check:db-rules` | Kein direktes SQL außerhalb der Module in `src/lib/db/`; keine Barrel-Imports aus `localDb.ts` (Strikte Regeln Nr. 2/Nr. 5) | Ja | -| `check:known-symbols` | In ihren Dispatch-Tabellen registrierte Provider-Executors, Routing-Strategien und Übersetzer stimmen mit den Dateien auf dem Datenträger überein – keine verwaisten oder nicht deklarierten Symbole | Ja | -| `check:route-guard-membership` | Jede Route, die einen untergeordneten Prozess erzeugt, ist durch `isLocalOnlyPath()` klassifiziert (Strikte Regeln Nr. 15/Nr. 17) | Ja | -| `check:test-discovery` | Jede `*.test.ts`- / `*.spec.ts`-Datei im Repository wird von mindestens einem Test-Runner erfasst (Ratschenprinzip: Die Liste verwaister Dateien in `test-discovery-baseline.json` kann nur kleiner werden) | Ja | -| `check:agent-skills-sync` | Generierte Agent-Skills-Artefakte stimmen mit ihrem Quellkatalog überein (keine Abweichungen) | -| `check:provider-asset-provenance` | Anbieterlogos/-Assets verfügen über einen dokumentierten Herkunftsnachweis | -| `lint:json` | JSON-Konfigurationsdateien lassen sich parsen und erfüllen die Lint-Regeln des Repositorys | -| `typecheck:core` | TypeScript-Kompilierung ohne Fehler (nur informative Warnungen) | Ja | -| `typecheck:noimplicit:core` | Striktes `noImplicitAny` — zukunftsorientiert; viele bereits vorhandene Aufrufstellen benötigen noch Annotationen | **Informativ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | Auf `src/app/(dashboard)/**` beschränktes `tsc` (#7033) — die kuratierte Positivliste von `typecheck:core` mit 27 Dateien enthält keine Dashboard-TSX-Dateien, und `next build` führt dafür ebenfalls nie eine Typprüfung durch (`next.config.mjs` setzt `ignoreBuildErrors: true`), sodass Regressionen durch verwaiste Bezeichner dort (#6625/#6909) für CI unsichtbar waren. Abgleich mit einer eingefrorenen Baseline der Anzahl pro Datei und TS-Code (`config/quality/dashboard-typecheck-baseline.json`, dasselbe Muster zur Erkennung veralteter Einträge wie bei `check:known-symbols`) — nur NEUE Fehler, die über die in der Baseline festgehaltene Anzahl hinausgehen, lassen die Prüfung fehlschlagen; mit `--update` schrittweise reduzieren, wenn ein bereits vorhandener Fehler behoben wird. | Ja | +Wird bei jedem PR für `main` ausgeführt. Blockiert bei einem Fehler das Mergen. + +| Skript (`npm run ...`) | Validiert | Blockierend | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | Die Node.js-Version liegt innerhalb des unterstützten Bereichs | Ja | +| `check:cycles` | Zirkuläre Importe in `src/` + `open-sse/` (AST-basiert, `paths` aus tsconfig werden aufgelöst). Ohne Zusatz = nur Hinweis, listet die Zyklen auf. `check:cycles:ratchet` (wird von CI ausgeführt) blockiert, wenn die Anzahl den Grenzwert `metrics.cycles` in `quality-baseline.json` überschreitet — derzeit 14, `direction: down`, sodass sie nur sinken kann (#15159 G-01/G-02) | Ja (Ratchet) | +| `check:route-validation:t06` | Zod-Schemas sind für alle Routen vorhanden (Tier-6-Richtlinie) | Ja | +| `check:any-budget:t11` | Die Anzahl von `@ts-expect-error // any` überschreitet das Budget nicht (Tier-11-Catraca) | Ja | +| `check:provider-consistency` | Jeder Provider in `providers.ts` hat einen entsprechenden Eintrag in `providerRegistry.ts` (und umgekehrt, innerhalb der Zulassungsliste) | Ja | +| `check:model-lifecycle` | Die drei manuell gepflegten Routing-Tabellen bleiben mit dem eingecheckten Lebenszyklus-Snapshot (#11503) konsistent: `FITNESS_TABLE` (`taskFitness.ts`) bewertet keine eingestellte ID, die `REGISTRY` routen kann; jedes Ziel in `BUILT_IN_ALIASES` ist in `REGISTRY` vorhanden und fehlt im Snapshot der eingestellten IDs; jede eingestellte ID, die noch in `REGISTRY` enthalten ist, wird weitergeleitet oder ist in `allowedRetiredInCatalog` aufgeführt; und keine Quelle oder kein Ziel aus `DEFAULT_DEGRADATION_MAP` erscheint in diesem Snapshot als eingestellt. Dies beweist nicht, dass ein Modell derzeit von einem aktiven Upstream bereitgestellt wird. Offline — vergleicht mit `config/quality/model-lifecycle.json`, das manuell mit `npm run quality:refresh-model-lifecycle` aktualisiert wird (Netzwerk; nicht in CI eingebunden). `allowedRetiredInCatalog` ist eine schrittweise abzuarbeitende Sperrklinke: Einen Eintrag nur zusammen mit einem Tracking-Issue hinzufügen. | Ja | +| `check:fetch-targets` | Jedes `fetch("/api/...")` im clientseitigen `src/` wird in eine tatsächlich vorhandene `route.ts` aufgelöst | Ja | +| `check:deps` | Alle mit `npm install` installierbaren Abhängigkeiten in jeder `package.json` im Repository sind in `dependency-allowlist.json` enthalten; neue nicht fixierte oder durch Slopsquatting verdächtige Pakete werden gekennzeichnet | Ja | +| `audit:deps` | `npm audit` (Root + Electron) — keine Sicherheitshinweise mit hohem/kritischem Schweregrad (überschneidet sich mit OSV-`check:vuln-ratchet`; siehe Rationalisierungs-Backlog) | Ja | +| `check:lockfile` | Integrität von `package-lock.json` — HTTPS-Registry, Integritäts-Hashes, keine Host-Überschreibungen | Ja | +| `check:licenses` | SPDX-Lizenz-Positivliste für Produktionsabhängigkeiten | Ja | +| `check:tracked-artifacts` | Keine Build-Artefakte / eingecheckten `node_modules`-Symlinks (wird auch beim Husky-Pre-Commit ausgeführt; Pre-Push ist absichtlich schlank — #6716) | Ja | +| `check:ai-attribution` | Keine KI-/Bot-`Co-Authored-By`-Trailer oder KI-Generierungshinweise in PR-Commits, Titel oder Beschreibung — Strikte Regel Nr. 16 (in der Fast-Gates-Schleife von `quality.yml` für PR→`release/**` — liest die Event-Nutzlast, außerhalb von PRs keine Aktion — sowie als reiner PR-Schritt beim Linting in `ci.yml` für PR→`main`; außerdem der Husky-Hook `commit-msg`; menschliche Mitautoren sind zulässig; #14436) | +| `check:vitest-exclusions` | Jeder Vitest-Ausschluss nennt ein Tracking-Issue und ist in `config/quality/vitest-exclusions.json` aufgeführt (#13204) | Ja | +| `check:file-size` | Keine Quelldatei überschreitet die für ihre Erweiterung festgelegte Obergrenze (Ratsche: eingefrorene große Dateien in der Liste `frozen`) | Ja | +| `check:error-helper` | Fehlerantworten in Executors/Handlern verwenden `buildErrorBody()` / `sanitizeErrorMessage()` (Strikte Regel Nr. 12) | Ja | +| `check:migration-numbering` | Migration-SQL-Dateien sind fortlaufend nummeriert, ohne Lücken oder Duplikate | Ja | +| `check:public-creds` | Keine hartcodierten OAuth-`client_id`-/`client_secret`-Werte oder Firebase-Webschlüssel außerhalb von `publicCreds.ts` (Feste Regel Nr. 11) | Ja | +| `check:db-rules` | Kein unverarbeitetes SQL außerhalb der Module in `src/lib/db/`; keine Barrel-Importe aus `localDb.ts` (Feste Regeln Nr. 2/Nr. 5) | Ja | +| `check:known-symbols` | In ihren Dispatch-Tabellen registrierte Provider-Executors, Routing-Strategien und Übersetzer stimmen mit den Dateien auf dem Datenträger überein – keine verwaisten oder nicht deklarierten Symbole | Ja | +| `check:route-guard-membership` | Jede Route, die einen untergeordneten Prozess startet, wird durch `isLocalOnlyPath()` klassifiziert (Feste Regeln Nr. 15/Nr. 17) | Ja | +| `check:test-discovery` | Jede `*.test.ts`- / `*.spec.ts`-Datei im Repository wird von mindestens einem Test-Runner erfasst (Ratsche: Die Liste verwaister Dateien in `test-discovery-baseline.json` darf nur kleiner werden) | Ja | +| `check:agent-skills-sync` | Generierte Agent-Skills-Artefakte stimmen mit ihrem Quellkatalog überein (keine Abweichungen) | +| `check:provider-asset-provenance` | Anbieterlogos/-Assets verfügen über einen dokumentierten Herkunftsnachweis | +| `lint:json` | JSON-Konfigurationsdateien können geparst werden und erfüllen die Lint-Regeln des Repositorys | +| `typecheck:core` | TypeScript-Kompilierung ohne Fehler (nur hinweisende Warnungen) | Ja | +| `typecheck:noimplicit:core` | Striktes `noImplicitAny` — zukunftsorientiert; viele bereits vorhandene Aufrufstellen benötigen noch Annotationen | **Hinweisend** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | Auf `src/app/(dashboard)/**` beschränktes `tsc` (#7033) — die kuratierte Allowlist mit 27 Dateien von `typecheck:core` enthält keine Dashboard-TSX-Dateien, und `next build` führt dafür ebenfalls nie eine Typprüfung durch (`next.config.mjs` setzt `ignoreBuildErrors: true`), sodass Regressionen durch verwaiste Bezeichner dort (#6625/#6909) für CI unsichtbar waren. Abgleich mit einer eingefrorenen Baseline der Anzahl pro Datei und TS-Code (`config/quality/dashboard-typecheck-baseline.json`, dasselbe Muster zur Erkennung veralteter Einträge wie bei `check:known-symbols`) — nur NEUE Fehler, die über die in der Baseline erfasste Anzahl hinausgehen, lassen das Gate fehlschlagen; mit `--update` schrittweise reduzieren, wenn ein bereits vorhandener Fehler behoben wurde. | Ja | ### Job: `quality-gate` Wird nach `test-coverage` ausgeführt. Blockiert das Zusammenführen bei einem Fehler. -| Skript | Validiert | Blockierend | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `quality:collect` | Erzeugt `quality-metrics.json` (Anzahl der ESLint-Warnungen, Abdeckung aus dem zusammengeführten Shard-Bericht) | Ja (vorgelagert zum Ratchet) | -| `quality:ratchet` | Keine Metrik in `quality-baseline.json` hat sich verschlechtert (ESLint-Warnungen ≤ Baseline; Abdeckung ≥ Baseline) | Ja | -| `check:duplication` | Codeduplizierung (jscpd@4) überschreitet die Baseline in `quality-baseline.json` nicht | Ja | -| `check:complexity` | Zyklomatische Komplexität auf Dateiebene überschreitet den Grenzwert nicht (ESLint-Kernregeln `complexity` + `max-lines-per-function`) | Ja | -| `check:cognitive-complexity` | Ratchet für kognitive Komplexität (`eslint-plugin-sonarjs`) — separater ESLint-Durchlauf; CI führt beide zusammen als einzelnen Schritt `check:complexity-ratchets` aus | Ja | -| `check:dead-code` | Ratchet für ungenutzte Exporte/Dateien (knip) verschlechtert sich gegenüber der Baseline nicht | Ja | -| `check:compression-budget` | Budget für den Komprimierungsbenchmark — Mindestwerte für Token-Einsparungen je Engine dürfen sich nicht verschlechtern | Ja | -| `check:type-coverage` | Ratchet für den prozentual typisierten Anteil (`type-coverage`) verschlechtert sich nicht; deckt `typecheck:noimplicit:core` weitgehend ab | Ja | -| `check:codeql-ratchet` | Anzahl offener CodeQL-Warnungen verschlechtert sich nicht (Abruf über `gh api`; kontrolliertes Überspringen ohne Token) — Aktualisierungsintervall und manueller Auslöser: siehe „CodeQL-Ratchet“ unten | Ja | +| Skript | Validiert | Blockierend | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | +| `quality:collect` | Erzeugt `quality-metrics.json` (Anzahl der ESLint-Warnungen, Abdeckung aus dem zusammengeführten Shard-Bericht) | Ja (dem Ratchet vorgeschaltet) | +| `quality:ratchet` | Keine Metrik in `quality-baseline.json` hat sich verschlechtert (ESLint-Warnungen ≤ Baseline; Abdeckung ≥ Baseline) | Ja | +| `check:duplication` | Codeduplizierung (jscpd@4) überschreitet die Baseline in `quality-baseline.json` nicht | Ja | +| `check:complexity` | Zyklomatische Komplexität auf Dateiebene überschreitet die Obergrenze nicht (ESLint-Core-Regeln `complexity` + `max-lines-per-function`) | Ja | +| `check:cognitive-complexity` | Ratchet für kognitive Komplexität (`eslint-plugin-sonarjs`) — separater ESLint-Durchlauf; CI führt beide zusammen als den einzelnen Schritt `check:complexity-ratchets` aus | Ja | +| `check:dead-code` | Ratchet für ungenutzte Exporte/Dateien (knip) verschlechtert sich gegenüber der Baseline nicht | Ja | +| `check:compression-budget` | Budget für den Komprimierungs-Benchmark — Mindestwerte für Token-Einsparungen pro Engine dürfen sich nicht verschlechtern | Ja | +| `check:type-coverage` | Ratchet für den Anteil typisierten Codes (`type-coverage`) verschlechtert sich nicht; ersetzt weitgehend `typecheck:noimplicit:core` | Ja | +| `check:codeql-ratchet` | Anzahl offener CodeQL-Warnmeldungen verschlechtert sich nicht (Abruf über `gh api`; ordnungsgemäßes Überspringen ohne Token) — Aktualisierungsintervall und manuelle Auslösung: siehe „CodeQL-Ratchet“ unten | Ja | ### Job: `quality-extended` -Der gesamte Job dient nur als Hinweis (`continue-on-error: true`). Die npm-basierten Ratchets werden -tatsächlich ausgeführt; die externen Scanner werden über `gh release download` installiert und überspringen sich selbst (Exit-Code 0), -wenn eine Binärdatei weiterhin fehlt. +Der gesamte Job dient nur der Information (`continue-on-error: true`). Die npm-basierten Ratchets werden +tatsächlich ausgeführt; die externen Scanner werden über `gh release download` installiert und überspringen +sich selbst (Exit-Code 0), wenn eine Binärdatei weiterhin fehlt. -| Skript | Validiert | Blockierend | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `check:circular-deps` | Keine zirkulären Abhängigkeiten (dpdm) | **Nur Hinweis** | -| `check:bundle-size` | Bundle-Größe überschreitet den Grenzwert nicht | **Nur Hinweis** | -| `check:secrets` | Suche nach Geheimnissen (gitleaks) — wird übersprungen, wenn die Binärdatei fehlt | **Nur Hinweis** | -| `check:vuln-ratchet` | Schwachstellen in Abhängigkeiten (osv-scanner) verschlechtern sich nicht — wird übersprungen, wenn die Binärdatei fehlt | **Nur Hinweis** | -| `check:workflows` | Workflow-Linting (actionlint + zizmor); fehlende/defekte Scanner, ungültige Berichte oder eine fehlende Ratchet-Baseline führen zum Status INCOMPLETE. Gültige Befunde folgen der ausgewählten strikten, hinweisenden oder Ratchet-Richtlinie | Ausführung erforderlich; zizmor-Ratchet in CI blockierend | -| `check:openapi-breaking` | Inkompatible Änderungen am öffentlichen API-Vertrag (`openapi.yaml`) gegenüber dem Basis-Branch (oasdiff) — erzeugt `openapiBreaking=N`; wird übersprungen, wenn oasdiff fehlt oder die Basisspezifikation nicht aufgelöst werden kann | **Nur Hinweis** | +| Skript | Validiert | Blockierend | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| `check:circular-deps` | Keine zirkulären Abhängigkeiten (dpdm) | **Nur informativ** | +| `check:bundle-size` | Bundle-Größe überschreitet die Obergrenze nicht | **Nur informativ** | +| `check:secrets` | Suche nach Geheimnissen (gitleaks) — wird übersprungen, wenn die Binärdatei fehlt | **Nur informativ** | +| `check:vuln-ratchet` | Sicherheitslücken in Abhängigkeiten (osv-scanner) verschlechtern sich nicht — wird übersprungen, wenn die Binärdatei fehlt | **Nur informativ** | +| `check:workflows` | Workflow-Linting (actionlint + zizmor); fehlende/defekte Scanner, ungültige Berichte oder eine fehlende Ratchet-Baseline führen zum Status INCOMPLETE. Gültige Funde folgen der ausgewählten strikten/informativen/Ratchet-Richtlinie | Ausführung erforderlich; zizmor-Ratchet blockiert in CI | +| `check:openapi-breaking` | Inkompatible Änderungen am öffentlichen API-Vertrag (`openapi.yaml`) gegenüber dem Basis-Branch (oasdiff) — erzeugt `openapiBreaking=N`; wird übersprungen, wenn oasdiff fehlt oder die Basisspezifikation nicht aufgelöst werden kann | **Nur informativ** | ### Job: `docs-sync-strict` @@ -168,61 +175,61 @@ Wird bei jedem PR an `main` ausgeführt. Blockiert das Zusammenführen bei einem | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | | `check:docs-all` | Meta-Gate, das die 6 nachstehenden Sub-Gates nacheinander ausführt | Ja | | ↳ `check:docs-sync` | Versionskonsistenz zwischen CHANGELOG / OpenAPI / llm.txt | Ja | -| ↳ `check:docs-counts` | Zahlenangaben im Fließtext (Anbieteranzahl, Migrationsanzahl usw.) liegen innerhalb des Ratchet-Fensters der tatsächlichen Zahlen | Ja | +| ↳ `check:docs-counts` | Zahlenangaben im Fließtext (Anbieteranzahl, Migrationsanzahl usw.) liegen innerhalb des Ratchet-Fensters der tatsächlichen Werte | Ja | | ↳ `check:env-doc-sync` | Jede Umgebungsvariable in `.env.example` ist in einer Dokumentationstabelle dokumentiert und umgekehrt | Ja | | ↳ `check:deprecated-versions` | Keine veralteten Versionszeichenfolgen in der Dokumentation | Ja | -| ↳ `check:doc-links` | Interne Markdown-Links in der Dokumentation verweisen auf vorhandene Dateien (Form `[text]`/`(path)`) | Ja | -| ↳ `check:fabricated-docs` | In der Dokumentation erwähnte Routen, Umgebungsvariablen, CLI-Befehle, Hook-Namen und Dateipfade sind in der Codebasis vorhanden. Hartes Gate mit `--strict`; ohne Flag nur weicher Fehler. | Ja (über `--strict` in CI) | +| ↳ `check:doc-links` | Interne Markdown-Links in der Dokumentation verweisen auf vorhandene Dateien (Format `[text]`/`(path)`) | Ja | +| ↳ `check:fabricated-docs` | In der Dokumentation genannte Routen, Umgebungsvariablen, CLI-Befehle, Hook-Namen und Dateipfade sind in der Codebasis vorhanden. Hartes Gate mit `--strict`; ohne Flag nur weicher Fehler. | Ja (über `--strict` in CI) | | `check:cli-i18n` | CLI-Befehlszeichenfolgen sind in allen i18n-Locale-Dateien vorhanden | Ja | -| `check:openapi-coverage` | Die OpenAPI-Spezifikation deckt mindestens einen per Ratchet festgelegten Mindestwert realer Routen ab | Ja | -| `check:openapi-security-tiers` | Sicherheitsebenen-Annotationen in `openapi.yaml` stimmen mit den Klassifizierungen in `routeGuard.ts` überein | **Hinweis** | -| `check:openapi-routes` | Jeder Pfad in `openapi.yaml` verweist auf eine reale `route.ts` (Schutz vor Halluzinationen) | Ja | -| `check:docs-symbols` | Jede `/api/...`-Referenz in `docs/**/*.md` verweist auf eine reale `route.ts` (Schutz vor Halluzinationen) | Ja | -| `i18n translation drift` | Nicht übersetzte Schlüssel in i18n-Locale-Dateien — nur Warnung | **Hinweis** | +| `check:openapi-coverage` | Die OpenAPI-Spezifikation deckt mindestens einen per Ratchet festgelegten Mindestanteil der tatsächlichen Routen ab | Ja | +| `check:openapi-security-tiers` | Sicherheitsstufen-Annotationen in `openapi.yaml` stimmen mit den Klassifizierungen in `routeGuard.ts` überein | **Hinweis** | +| `check:openapi-routes` | Jeder Pfad in `openapi.yaml` verweist auf eine vorhandene `route.ts` (Anti-Halluzination) | Ja | +| `check:docs-symbols` | Jede `/api/...`-Referenz in `docs/**/*.md` verweist auf eine vorhandene `route.ts` (Anti-Halluzination) | Ja | +| `i18n translation drift` | Nicht übersetzte Schlüssel in i18n-Locale-Dateien – nur Warnung | **Hinweis** | ### Job: `i18n-ui-coverage` -| Skript | Validiert | Blockierend | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check-ui-keys-coverage` (inline) | Die Abdeckung der UI-i18n-Schlüssel beträgt ≥ 65 % | Ja | -| `check-ui-value-drift` (inline) | Ein umformulierter englischer **Wert** hinterlässt keine veraltete Übersetzung | Ja | -| `check-new-key-coverage` (inline) | Ein **neuer** englischer Schlüssel ist in jeder Locale übersetzt — eine `__MISSING__:`-Markierung wird abgelehnt | Ja | -| `check-translation-ratio` | Der Anteil echter Übersetzungen pro Locale (mit dem Englischen identische / Platzhalter- / fehlende Blätter außerhalb der Positivliste) darf `config/quality/i18n-translation-baseline.json` + Toleranz nicht überschreiten | **Hinweis** | +| Skript | Validiert | Blockierend | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| `check-ui-keys-coverage` (inline) | Die Abdeckung der UI-i18n-Schlüssel beträgt ≥ 65 % | Ja | +| `check-ui-value-drift` (inline) | Ein neu formulierter englischer **Wert** hinterlässt keine veraltete Übersetzung | Ja | +| `check-new-key-coverage` (inline) | Ein **neuer** englischer Schlüssel ist in jeder Locale übersetzt – ein `__MISSING__:`-Marker wird abgelehnt | Ja | +| `check-translation-ratio` | Der Anteil echter Übersetzungen pro Locale (mit dem Englischen identische / Platzhalter- / fehlende Blätter außerhalb der Zulassungsliste) darf `config/quality/i18n-translation-baseline.json` + Toleranz nicht überschreiten | **Hinweis** | -Erfordert `fetch-depth: 0` — das Value-Drift-Gate vergleicht `en.json` mit der Merge-Basis. +Benötigt `fetch-depth: 0` – das Value-Drift-Gate vergleicht `en.json` per Diff mit der Merge-Basis. -#### `check-ui-value-drift` — Gate gegen veraltete Übersetzungen +#### `check-ui-value-drift` – Gate gegen veraltete Übersetzungen -Erkennt die eine i18n-Regression, die die anderen Gates strukturell nicht erkennen können: Ein englischer Wert -wird umformuliert, während die aus dem _vorherigen_ englischen Text abgeleiteten Übersetzungen bestehen bleiben, sodass -nicht englischsprachige Benutzer weiterhin überzeugend formulierte, aber inzwischen falsche Texte lesen. +Erkennt die eine i18n-Regression, die für die anderen Gates strukturell unsichtbar ist: Ein englischer Wert +wird neu formuliert, während die aus dem _vorherigen_ englischen Text abgeleiteten Übersetzungen bestehen bleiben, sodass +nicht englischsprachige Benutzer weiterhin einen selbstsicher formulierten, aber nun falschen Text lesen. -Dies ist tatsächlich in die Produktion gelangt. `oauthModal.googleOAuthWarning` wurde umformuliert, als der Antigravity- -Anmeldehelfer eingeführt wurde (#5203); in **39 von 43 Locales** blieb ein Text erhalten, der Betreiber anwies, „die -vollständige URL zu kopieren und unten einzufügen“ — ein Ablauf, der für diesen Anbieter nicht abgeschlossen werden kann. Dies blieb +Dies wurde tatsächlich so ausgeliefert. `oauthModal.googleOAuthWarning` wurde neu formuliert, als der Antigravity- +Anmeldehelfer eingeführt wurde (#5203); in **39 von 43 Locales** blieb der Text bestehen, der Betreiber anwies, „die +vollständige URL zu kopieren und unten einzufügen“ – ein Ablauf, der bei diesem Anbieter nicht abgeschlossen werden kann. Dies blieb bis #8463 unbemerkt, weil: -- `sync-ui-keys` nur **fehlende** Schlüssel ergänzt, niemals **veraltete**; -- `check-ui-keys-coverage` die _Anwesenheit_ von Schlüsseln zählt, sodass eine veraltete Übersetzung als abgedeckt gilt; -- `check-translation-drift` die Dokumentationsspiegel unter `docs/i18n//**.md` verfolgt — - `src/i18n/messages/*.json` wird nie gelesen. Seit der 2026-09-Neusynchronisierung im Job `docs-sync-strict` blockierend: - Kerndokument bearbeiten → `npm run i18n:run -- --files=` (abschnittsweise, kostengünstig). - -**Diff-basiert, nicht durch eine Baseline gestützt.** Es vergleicht `en.json` am Merge-Base mit dem -Arbeitsbaum; für jeden Schlüssel, dessen englischer Wert geändert wurde, gilt jede Locale, die -noch eine unveränderte Übersetzung enthält, als veraltet. Dadurch werden **bereits vorhandene -Altlasten bewusst eingefroren** — aus einem Diff lässt sich nicht erkennen, von welchem alten -englischen Text eine bereits lange bestehende Übersetzung stammt. Daher bewertet das Gate nur, -was durch die aktuelle Änderung betroffen ist. Die Alternative (eine Hash-Baseline pro Schlüssel) -würde eine generierte Datei von ~600 KB erfordern, dreimal so groß wie die größte vorhandene -Baseline, und bei jedem i18n-PR Änderungen verursachen. +- `sync-ui-keys` nur Schlüssel ergänzt, die **fehlen**, niemals solche, die **veraltet** sind; +- `check-ui-keys-coverage` die _Existenz_ von Schlüsseln zählt, sodass eine veraltete Übersetzung als abgedeckt gewertet wird; +- `check-translation-drift` die Dokumentationsspiegel unter `docs/i18n//**.md` verfolgt – + `src/i18n/messages/*.json` wird niemals gelesen. Seit der erneuten Synchronisierung 2026-09 im Job `docs-sync-strict` blockierend: + Kerndokument bearbeiten → `npm run i18n:run -- --files=` (auf Abschnittsebene, kostengünstig). + +**Diff-basiert, nicht durch eine Baseline gestützt.** Dabei wird `en.json` am Merge-Base mit dem +Arbeitsbaum verglichen; für jeden Schlüssel, dessen englischer Wert geändert wurde, gilt jede +Locale, die noch eine unveränderte Übersetzung enthält, als veraltet. Dadurch werden +**bereits vorhandene Altlasten bewusst eingefroren** — aus einem Diff lässt sich nicht erkennen, +von welchem alten englischen Text eine bereits lange bestehende Übersetzung stammt. Daher +bewertet das Gate nur, was von der aktuellen Änderung betroffen ist. Die Alternative (eine +Hash-Baseline pro Schlüssel) würde eine generierte Datei von ~600 KB erfordern, dreimal so +groß wie die größte bestehende Baseline, und würde bei jedem i18n-PR geändert. Es gibt zwei Möglichkeiten, die Prüfung zu erfüllen: 1. die betroffenen Übersetzungen aktualisieren oder 2. sie auf `__MISSING__:` setzen — zur Laufzeit wird dann der korrigierte englische Text ausgeliefert (`src/i18n/request.ts::deepMergeFallback`, #7258) und der Schlüssel zur - Übersetzung vorgemerkt. + Übersetzung eingereiht. Wenn sich die **Bedeutung** des Textes geändert hat, sollte der **Schlüssel umbenannt** werden: Ein neuer Schlüssel kann keine veraltete Übersetzung übernehmen. Dieses Muster wurde in #8463 @@ -234,50 +241,49 @@ npm run i18n:check-value-drift:warn # nur Bericht BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Wird der Basiskatalog nicht gefunden, endet die Prüfung mit Code 0 und -`SKIP reason=base-unresolved` (flacher Klon ohne Basis-Ref), analog zu -`check-openapi-breaking`. +Wird der Basiskatalog nicht gefunden (flacher Klon ohne Basis-Ref), endet die Prüfung mit +Status 0 und `SKIP reason=base-unresolved`, entsprechend `check-openapi-breaking`. ### Job: `i18n` -Vollständige i18n-Validierungsmatrix (ein Job pro Locale). Der gesamte Job ist nicht blockierend. +Vollständige i18n-Validierungsmatrix (ein Job pro Locale). Der gesamte Job ist informativ. -| Skript | Validiert | Blockierend | -| ------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------- | -| `validate_translation.py quick` | Vollständigkeit der Übersetzung je Locale | **Nicht blockierend** (`continue-on-error: true` für den gesamten Job) | +| Skript | Validiert | Blockierend | +| ------------------------------- | ------------------------------------------ | ----------------------------------------------------------- | +| `validate_translation.py quick` | Vollständigkeit der Übersetzung pro Locale | **Informativ** (`continue-on-error: true` für gesamten Job) | ### Job: `pr-test-policy` Wird nur bei Pull Requests ausgeführt. -| Skript | Validiert | Blockierend | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | PRs, die Produktionscode in `src/`, `open-sse/`, `electron/` oder `bin/` ändern, müssen Tests enthalten oder aktualisieren (harte Regel #8) | Ja | -| `check:test-masking` | Geänderte Testdateien reduzieren nicht die Nettoanzahl der Assertions und fügen keine `assert.ok(true)`-Tautologien hinzu | Ja | -| `check:pr-evidence` | Der PR-Text nennt Test-/VPS-Nachweise für die Änderung (automatisiert harte Regel #18 durch Durchsuchen des PR-Textes — fragil, siehe Backlog) | Ja | +| Skript | Validiert | Blockierend | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check:pr-test-policy` | PRs, die Produktionscode in `src/`, `open-sse/`, `electron/` oder `bin/` ändern, müssen Tests enthalten oder aktualisieren (Feste Regel Nr. 8) | Ja | +| `check:test-masking` | Geänderte Testdateien verringern nicht die Nettoanzahl der Assertions und fügen keine `assert.ok(true)`-Tautologien hinzu | Ja | +| `check:pr-evidence` | Der PR-Text nennt Test-/VPS-Nachweise für die Änderung (automatisiert Feste Regel Nr. 18 durch Durchsuchen des PR-Textes — fragil, siehe Backlog) | Ja | ### Job: `test-vitest` -Wird nach `build` ausgeführt. Blockiert bei einem Fehler den Merge. +Wird nach `build` ausgeführt. Blockiert den Merge bei einem Fehler. -| Suite | Validiert | Blockierend | -| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-Server (110 Tools), autoCombo, Cache — vitest-Runner | Ja | -| `test:vitest:ui` | UI-Komponententests — vitest-Runner | **Blockierend** — bereits vorhandene Fehler sind in `vitest.config.ts` explizit ausgeschlossen; neue Fehler lassen den Job fehlschlagen | +| Suite | Validiert | Blockierend | +| ---------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP-Server (110 Tools), autoCombo, Cache — vitest-Test-Runner | Ja | +| `test:vitest:ui` | UI-Komponententests — vitest-Test-Runner | **Blockierend** — bereits vorhandene Fehler sind in `vitest.config.ts` ausdrücklich ausgeschlossen; neue Fehler lassen den Job fehlschlagen | -### Nächtliche Workflows (zeitgesteuert, nicht blockierend) +### Nächtliche Workflows (zeitgesteuert, informativ) -Diese werden nach einem Cron-Zeitplan (und per `workflow_dispatch`) ausgeführt, niemals bei PRs. -Sie sind alle nicht blockierend. +Diese werden nach einem Cron-Zeitplan (und über `workflow_dispatch`) ausgeführt, niemals bei PRs. +Sie sind alle informativ. -| Workflow | Validiert | Blockierend | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `nightly-property` | fast-check-Property-Tests mit zufälligem Seed und hoher Anzahl von Durchläufen | **Nicht blockierend** | -| `nightly-resilience` | Heap-Wachstums-Gate, Chaos-Fehlerinjektion, k6-Last-/Dauertests | **Nicht blockierend** | -| `nightly-llm-security` | promptfoo-Injection-Guard (Blockiermodus) + garak-Probes (werden ohne Provider-Secret übersprungen) | **Nicht blockierend** | -| `nightly-schemathesis` | OpenAPI-Contract-Fuzzing (schemathesis) gegen eine aktive OmniRoute mit `docs/openapi.yaml` — deckt Spezifikationsverstöße / unbehandelte 500er auf (Phase 8 B.4) | **Nicht blockierend** | -| `nightly-mutation` | Stryker-Mutation-Testing-Score für die schnelle Unit-Test-Spur — überlebende Mutanten weisen auf schwache Assertions hin | **Nicht blockierend** | -| `nightly-compat` | Node-Engine-Kompatibilitätsmatrix über die unterstützten `engines.node`-Bereiche hinweg | **Nicht blockierend** | +| Workflow | Validiert | Blockierend | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | fast-check-Property-Tests mit zufälligem Seed und hoher Anzahl an Durchläufen | **Informativ** | +| `nightly-resilience` | Heap-Wachstums-Gate, Chaos-Fehlerinjektion, k6-Last-/Dauertests | **Informativ** | +| `nightly-llm-security` | promptfoo-Injection-Guard (Blockiermodus) und garak-Prüfungen (werden ohne Provider-Secret übersprungen) | **Informativ** | +| `nightly-schemathesis` | OpenAPI-Contract-Fuzzing (schemathesis) gegen eine laufende OmniRoute-Instanz unter Verwendung von `docs/openapi.yaml` — deckt Spezifikationsverstöße / unbehandelte 500er auf (Phase 8 B.4) | **Informativ** | +| `nightly-mutation` | Stryker-Mutation-Testing-Bewertung für die schnelle Unit-Test-Spur — überlebende Mutanten decken schwache Assertions auf | **Informativ** | +| `nightly-compat` | Kompatibilitätsmatrix der Node-Engine über die unterstützten `engines.node`-Bereiche hinweg | **Informativ** | --- @@ -547,43 +553,44 @@ Verbindungsfehler und unterbricht niemals Sitzungen. --- -## Rationalisierungs-Backlog (ROI-Überprüfung — Phase 9 Welle 3) +## Rationalisierungs-Backlog (ROI-Prüfung — Phase 9 Welle 3) Dieses Inventar wurde am 2026-06-17 mit `ci.yml` abgeglichen (in der vorherigen Version fehlten `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Eine ROI-Überprüfung des abgeglichenen Bestands -ergab die folgenden Rationalisierungskandidaten. **Die Zusammenführungen sind mechanische CI- -Änderungen; die Umstellungen/Streichungen sind Richtlinienentscheidungen, die dem Betreiber vorbehalten sind.** Keine der nachstehenden -Änderungen wurde bisher angewendet. +`check:codeql-ratchet`, `check:pr-evidence`). Eine ROI-Prüfung des abgeglichenen Bestands +ergab die folgenden Rationalisierungskandidaten. **Die Zusammenführungen sind mechanische +CI-Änderungen; die Umstellungen/Entfernungen sind Richtlinienentscheidungen, die dem Betreiber +vorbehalten sind.** Nichts davon wurde bisher umgesetzt. -**Oben ebenfalls nicht dokumentiert** (nur hinweisend, geringe Aussagekraft): der Job `docs-lint` -(markdownlint + Vale, gesamter Job mit `continue-on-error`) und die eigenständigen Scanner-Workflows -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ist in -`quality-baseline.json` enthalten, aber in `ci.yml` nicht mit einem blockierenden Ratchet verknüpft — die Metrik ist -derzeit verwaist. +**Oben ebenfalls nicht dokumentiert** (nur Hinweischarakter, geringe Aussagekraft): der Job +`docs-lint` (markdownlint + Vale, gesamter Job mit `continue-on-error`) und die eigenständigen +Scanner-Workflows `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ist in +`quality-baseline.json` enthalten, aber nicht mit einer blockierenden Ratchet-Prüfung in `ci.yml` +verknüpft — die Metrik ist derzeit verwaist. ### Zusammenführen / Deduplizieren (mechanisch, geringeres Risiko) -Jeder Kandidat wurde am 2026-06-17 anhand des aktuellen Gate-Status validiert (Vertrauen ist gut, Kontrolle ist besser); -mehrere „offensichtliche“ Zusammenführungen erwiesen sich als versteckte Altlasten und sind **keine** direkt einsetzbaren Ersetzungen. +Jeder Kandidat wurde am 2026-06-17 anhand des aktiven Gate-Status validiert (Vertrauen ist gut, +Kontrolle ist besser); mehrere „offensichtliche“ Zusammenführungen verbargen tatsächlich +Altlasten und sind **kein** sauberer direkter Ersatz. -- **`check:docs-sync` wird zweimal ausgeführt** — eigenständig im Job `lint` und erneut innerhalb von `check:docs-all` (`docs-sync-strict`) sowie im Husky-Pre-Commit-Hook. ✅ **ERLEDIGT** — eigenständiger Aufruf in `lint` entfernt. -- **CVE-Scanning** — ❌ **KEINE saubere Zusammenführung.** `audit:deps` schlägt bei jeder CVE mit hohem/kritischem Schweregrad zwingend fehl; `check:vuln-ratchet` (osv) schlägt nur bei einer _Regression_ gegenüber der Baseline fehl (derzeit 1 MODERATE). Unterschiedliche Semantik — durch das Entfernen von `audit:deps` ginge das absolute Gate für hohe/kritische Schweregrade verloren. Beide beibehalten. -- **Zyklenerkennung** — ❌ **KEINE saubere Zusammenführung.** `check:circular-deps` (dpdm) meldet **91 Zyklen** (deshalb ist die Prüfung nur hinweisend); sie kann nicht auf blockierend hochgestuft werden, ohne diese zuvor zu beheben, und ihr Umfang ist größer als der der erfolgreichen, kuratierten Prüfung `check:cycles`. `check:cycles` als blockierend beibehalten; die Behebung der 91 dpdm-Zyklen ist ein eigener Backlog-Eintrag. +- **`check:docs-sync` wird zweimal ausgeführt** — eigenständig im Job `lint` und nochmals innerhalb von `check:docs-all` (`docs-sync-strict`) sowie im husky-Pre-Commit-Hook. ✅ **ERLEDIGT** — eigenständiger Aufruf in `lint` entfernt. +- **CVE-Scanning** — ❌ **KEINE saubere Zusammenführung.** `audit:deps` schlägt bei jeder CVE mit hohem/kritischem Schweregrad hart fehl; `check:vuln-ratchet` (osv) schlägt nur bei einer _Regression_ gegenüber der Baseline fehl (derzeit 1 MODERATE). Unterschiedliche Semantik — durch das Entfernen von `audit:deps` würde das absolute Gate für hohe/kritische Schweregrade verloren gehen. Beide beibehalten. +- **Zyklenerkennung** — ✅ **ERLEDIGT** (#15159 G-01/G-02). Der alte Text bezeichnete `check:cycles` als „das grüne, kuratierte“ Gate und begründete dessen blockierende Beibehaltung damit, dass `check:circular-deps` (dpdm) 91 Zyklen meldete. Dieses Grün war ein **falsch positives Grün**: `check:cycles` scannte 5 Unterverzeichnisse (450 Dateien), erfasste nur statische `import|export … from`-Anweisungen und verwarf jeden `@/`- und `@omniroute/open-sse/`-Spezifizierer, sodass die im Repository vorherrschenden Zyklen aus dynamischen Imports und Aliasen nicht erkannt werden konnten. Behoben: Das Gate durchsucht nun `src` + `open-sse` (5023 Dateien), erfasst Spezifizierer aus dem TypeScript-AST (sodass `import("…")` zählt, `typeof import("…")` an Typpositionen hingegen nicht) und löst `paths` aus tsconfig auf. Es findet **14** Zyklen, nicht 0. Da 14 bereits vorhandene Zyklen nicht in einem Gate-PR behoben werden können, ist `check:cycles` nun eine **Ratchet-Prüfung** (`--ratchet`, Obergrenze `metrics.cycles.value = 14` in `quality-baseline.json`, `direction: down`) — sie blockiert jede _Regression_, und die Anzahl kann nur sinken. CI führt `npm run check:cycles:ratchet` aus. Der schrittweise Abbau erfolgt zusammen mit **A-01**. `check:circular-deps` (dpdm) bleibt als umfassendere Zweitmeinung im Hinweisstatus. - **Komplexität** — ✅ **ERLEDIGT** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ein ESLint-Durchlauf, Zählung nach ruleId, sodass die Baselines für zyklomatische Komplexität + maximale Zeilenzahl und kognitive Komplexität unabhängig bleiben; die einzelnen Prüfungen `check:complexity` / `check:cognitive-complexity` bleiben für lokale Ausführungen mit `--update` erhalten. -- **`/api`-Anti-Halluzination** — ✅ **ERLEDIGT** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): ein einziges FS-Inventar von `src/app/api`; openapi-routes + docs-symbols melden weiterhin unabhängig; die einzelnen Prüfungen bleiben für lokale Ausführungen erhalten. -- **`check:node-runtime` wird in 11 Jobs ausgeführt** — ⚠️ **geringer ROI.** Jeder Job verwendet einen separaten Runner und die Prüfung dauert <1 s; Gesamtersparnis etwa 10 s, bei gleichzeitigem Verlust einer kostengünstigen Schutzprüfung pro Job. Den Änderungsaufwand nicht wert. -- **`typecheck:noimplicit:core` im CI-Linting** — ✅ **aus dem Job `lint` entfernt** (war mit `continue-on-error` nur hinweisend); die blockierende Typoberfläche besteht aus `typecheck:core` + `check:type-coverage`. Lokales Skript beibehalten. +- **`/api`-Anti-Halluzination** — ✅ **ERLEDIGT** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): eine einzige Dateisystem-Inventarisierung von `src/app/api`; openapi-routes + docs-symbols berichten weiterhin unabhängig; die einzelnen Prüfungen bleiben für lokale Ausführungen erhalten. +- **`check:node-runtime` wird in 11 Jobs ausgeführt** — ⚠️ **geringer ROI.** Jeder Job verwendet einen separaten Runner, und die Prüfung dauert <1 s; die Gesamtersparnis läge bei ~10 s, während dabei eine kostengünstige Schutzprüfung pro Job verloren ginge. Den Änderungsaufwand nicht wert. +- **`typecheck:noimplicit:core` im CI-Linting** — ✅ **aus dem Job `lint` entfernt** (war mit `continue-on-error` nur hinweisend); die blockierende Typabdeckung besteht aus `typecheck:core` + `check:type-coverage`. Lokales Skript beibehalten. ### Umstellen / Entscheiden (Betreiberrichtlinie) -- `check:openapi-security-tiers` (hinweisend) — ❌ **NICHT ohne Weiteres umstellbar.** Die Prüfung wird mit 0 beendet, warnt jedoch, dass bei mehreren `traffic-inspector`-Routen unter `LOCAL_ONLY_API_PREFIXES` die Annotation `x-loopback-only: true` fehlt. Für eine Erzwingung müssen diese Annotationen zuerst zu `openapi.yaml` hinzugefügt werden. -- `typecheck:noimplicit:core` (hinweisend) — weitgehend durch das blockierende Ratchet `check:type-coverage` abgedeckt. Auf ein Ratchet umstellen oder den redundanten zweiten `tsc`-Durchlauf entfernen. -- `test:vitest:ui` (jetzt **blockierend**) — bereits bestehende Fehler werden in `vitest.config.ts` explizit mit `// #8618`-Nachverfolgungskommentaren ausgeschlossen; neue Fehler lassen den Job fehlschlagen. -- `check:secrets` (gitleaks, blockierendes Ratchet, bei 3 dokumentierten Falschmeldungen eingefroren) — die 3 auf die Positivliste setzen, um 0 zu erreichen, oder auf hinweisend herabstufen. Überschneidet sich mit dem nativen GitHub-Secret-Scanning + `check:public-creds`. -- `check:pr-evidence` (blockierend, durchsucht den Fließtext des PR-Bodys mit grep) — hohes Falsch-positiv-Risiko; eine Entfernung schwächt die Durchsetzung von Hard Rule #18, daher handelt es sich um eine echte Richtlinienentscheidung. -- `semgrep` (eigenständig, hinweisend) — überschneidet sich bei den OWASP-Familien mit CodeQL; die Baseline mit einem Ratchet verknüpfen oder entfernen. +- `check:openapi-security-tiers` (hinweisend) — ❌ **NICHT ohne Weiteres umstellbar.** Die Prüfung beendet sich mit 0, warnt jedoch, dass mehreren `traffic-inspector`-Routen unter `LOCAL_ONLY_API_PREFIXES` die Annotation `x-loopback-only: true` fehlt. Vor einer Erzwingung müssen diese Annotationen zuerst zu `openapi.yaml` hinzugefügt werden. +- `typecheck:noimplicit:core` (hinweisend) — wird weitgehend durch die blockierende Ratchet-Prüfung `check:type-coverage` abgedeckt. In eine Ratchet-Prüfung umwandeln oder den redundanten zweiten `tsc`-Durchlauf entfernen. +- `test:vitest:ui` (jetzt **blockierend**) — bereits vorhandene Fehler sind in `vitest.config.ts` ausdrücklich mit `// #8618`-Tracking-Kommentaren ausgeschlossen; neue Fehler lassen den Job fehlschlagen. +- `check:secrets` (gitleaks, blockierende Ratchet-Prüfung, eingefroren bei 3 dokumentierten Falschmeldungen) — die 3 Einträge auf die Zulassungsliste setzen, um 0 zu erreichen, oder auf Hinweisstatus herabstufen. Überschneidet sich mit dem nativen Secret-Scanning von GitHub + `check:public-creds`. +- `check:pr-evidence` (blockierend, durchsucht den Fließtext des PR-Texts) — hohes Falsch-Positiv-Risiko; eine Entfernung würde die Durchsetzung der festen Regel Nr. 18 schwächen, daher handelt es sich um eine echte Richtlinienentscheidung. +- `semgrep` (eigenständig, hinweisend) — überschneidet sich bei den OWASP-Kategorien mit CodeQL; die Baseline mit einer Ratchet-Prüfung verknüpfen oder entfernen. --- diff --git a/docs/i18n/el/CONTRIBUTING.md b/docs/i18n/el/CONTRIBUTING.md index 0dde3acf9cb..b56ae64832a 100644 --- a/docs/i18n/el/CONTRIBUTING.md +++ b/docs/i18n/el/CONTRIBUTING.md @@ -392,22 +392,24 @@ docs/ --- -## Λίστα Ελέγχου Pull Request +## Λίστα ελέγχου Pull Request -- [ ] Τα tests περνούν (`npm test`) -- [ ] Το linting περνά (`npm run lint`) +- [ ] Οι δοκιμές ολοκληρώνονται επιτυχώς (`npm test`) +- [ ] Ο έλεγχος lint ολοκληρώνεται επιτυχώς (`npm run lint`) - [ ] Το build ολοκληρώνεται επιτυχώς (`npm run build`) -- [ ] Προστέθηκαν TypeScript types για νέες δημόσιες συναρτήσεις και interfaces -- [ ] Δεν υπάρχουν hardcoded secrets ή fallback τιμές -- [ ] Τα δημόσια upstream διαπιστευτήρια ενσωματώνονται μέσω `resolvePublicCred()` (δείτε [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ποτέ ως literals -- [ ] Οι αποκρίσεις σφαλμάτων δρομολογούνται μέσω `buildErrorBody()` / `sanitizeErrorMessage()` — χωρίς raw stack traces στα σώματα απόκρισης (δείτε [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Οι εντολές shell (`exec` / `spawn`) μεταβιβάζουν τιμές runtime μέσω `env`, όχι μέσω string interpolation -- [ ] Όλες οι εισόδοι επικυρώνονται με Zod schemas -- [ ] Προστέθηκε **fragment** Changelog στο `changelog.d/{features|fixes|maintenance}/-.md` για αλλαγές που επηρεάζουν τον χρήστη (δείτε [`changelog.d/README.md`](./changelog.d/README.md)) — **μην** επεξεργάζεστε απευθείας το `CHANGELOG.md`· τα fragments συγκεντρώνονται κατά την έκδοση και δεν δημιουργούν ποτέ συγκρούσεις μεταξύ PRs -- [ ] Η τεκμηρίωση ενημερώθηκε (εάν απαιτείται) -- [ ] Δεν ανοίχτηκαν νέες ειδοποιήσεις CodeQL / Secret-Scanning, ή κάθε μία απορρίφθηκε με τεχνική αιτιολόγηση που παραπέμπει στο σχετικό έγγραφο `docs/security/` -- [ ] Τα routes που εκκινούν child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) ταξινομούνται ως `isLocalOnlyPath()` στο `src/server/authz/routeGuard.ts` — δείτε [Κανόνα #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Δεν υπάρχουν trailers `Co-Authored-By` στα μηνύματα commit — τα commits πρέπει να εμφανίζονται αποκλειστικά υπό την Git ταυτότητα του ιδιοκτήτη του αποθετηρίου (Κανόνας #16) +- [ ] Προστέθηκαν τύποι TypeScript για νέες δημόσιες συναρτήσεις και διεπαφές +- [ ] Δεν υπάρχουν hardcoded μυστικά ή εφεδρικές τιμές +- [ ] Τα δημόσια διαπιστευτήρια upstream ενσωματώνονται μέσω `resolvePublicCred()` (βλ. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) και ποτέ ως literals +- [ ] Οι αποκρίσεις σφαλμάτων δρομολογούνται μέσω `buildErrorBody()` / `sanitizeErrorMessage()` — δεν υπάρχουν ανεπεξέργαστα stack traces στα σώματα αποκρίσεων (βλ. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Οι εντολές shell (`exec` / `spawn`) μεταβιβάζουν τις τιμές χρόνου εκτέλεσης μέσω `env` και όχι μέσω παρεμβολής συμβολοσειρών +- [ ] Όλες οι είσοδοι επικυρώνονται με σχήματα Zod +- [ ] Προστέθηκε **τμήμα** changelog στον κατάλογο `changelog.d/{features|fixes|maintenance}/-.md` για αλλαγές που επηρεάζουν τους χρήστες (βλ. [`changelog.d/README.md`](./changelog.d/README.md)) — **μην** επεξεργάζεστε απευθείας το `CHANGELOG.md`· τα τμήματα συγκεντρώνονται κατά την έκδοση και δεν δημιουργούν ποτέ διενέξεις μεταξύ PR +- [ ] Η τεκμηρίωση ενημερώθηκε (εφόσον απαιτείται) +- [ ] Δεν δημιουργήθηκαν νέες ειδοποιήσεις CodeQL / Secret-Scanning ή καθεμία απορρίφθηκε με τεχνική αιτιολόγηση που παραπέμπει στο σχετικό έγγραφο του `docs/security/` +- [ ] Οι διαδρομές που εκκινούν θυγατρικές διεργασίες (`/api/mcp/`, `/api/cli-tools/runtime/`) ταξινομούνται ως `isLocalOnlyPath()` στο `src/server/authz/routeGuard.ts` — βλ. [Αυστηρός κανόνας #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Δεν υπάρχουν trailers `Co-authored-by` από AI/bot στα μηνύματα commit (Αυστηρός κανόνας #16) — οι άνθρωποι συνεργάτες των οποίων η εργασία επαναχρησιμοποιείται αναφέρονται με τα τυπικά trailers `Co-authored-by: Name ` + +--- ## Κυκλοφορία Εκδόσεων diff --git a/docs/i18n/el/docs/architecture/QUALITY_GATES.md b/docs/i18n/el/docs/architecture/QUALITY_GATES.md index 423379a814b..3b9076971ff 100644 --- a/docs/i18n/el/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/el/docs/architecture/QUALITY_GATES.md @@ -17,274 +17,262 @@ ## Κατάλογος πυλών και προφίλ εκτέλεσης -### Αποδοχή υποψηφίου +### Αποδοχή υποψηφίων Οι ροές εργασίας CI και Quality Gates παράγουν καθεμία μια σταθερή ετυμηγορία: `Gate / CI` και -`Gate / Quality`. Η πολιτική αποδοχής τους με εκδόσεις απαριθμεί κάθε ανάντη εργασία -ως υποχρεωτική ή συμβουλευτική. Μια ισχύουσα υποχρεωτική εργασία πρέπει να ολοκληρωθεί επιτυχώς: -αποτελέσματα που λείπουν, έχουν ακυρωθεί, παραλειφθεί, εκκρεμούν ή είναι άγνωστα δεν μπορούν να -θεμελιώσουν κατάσταση PASS. Μια έγκυρη ταξινόμηση μόνο για τεκμηρίωση ή μόνο για τον κατάλογο -μπορεί να καταστήσει μη εφαρμόσιμη μια διαδρομή κώδικα· ένα πρόχειρο PR δεν αποτελεί αποδεκτό -υποψήφιο. Μια ετικέτα `hotfix` δεν καταργεί την απαίτηση παροχής αποδεικτικών στοιχείων. - -Και οι δύο ροές εργασίας καλύπτουν PR και push προς τους κύριους κλάδους/κλάδους έκδοσης, -χειροκίνητη εκτέλεση και συμβάντα ομάδας συγχώνευσης. Τα push, η χειροκίνητη εκτέλεση και οι -ομάδες συγχώνευσης εκτελούν την πλήρη επιλογή. Τα fork και οι ομάδες συγχώνευσης χρησιμοποιούν -φιλοξενούμενους runner για εργασίες που διαφορετικά θα επέλεγαν αυτοφιλοξενούμενους runner· -πριν από τη διάθεση πρέπει να επαληθευτεί ότι υπάρχει επαρκής φιλοξενούμενη χωρητικότητα. - -Κάθε απόδειξη JSON προσδιορίζει το SHA που έγινε checkout, την εκτέλεση της ροής εργασίας και -την απόπειρα. Το CLI απορρίπτει μια ασυμφωνία SHA μεταξύ checkout και συμβάντος. Οι δοκιμές της -ροής εργασίας συνδέουν τη συμμετοχή στην πολιτική με τη λίστα `needs` της εργασίας ετυμηγορίας, -ώστε μια νέα ή καταργημένη διαδρομή να μην μπορεί να εξαφανιστεί σιωπηρά. Οι αποδείξεις -καλύπτουν τη δική τους ροή εργασίας, όχι τη δημοσίευση, την ανάπτυξη ή τα εσωτερικά στοιχεία -ενός υπάρχοντος συμβουλευτικού σαρωτή. Η ενεργοποίηση και των δύο ονομάτων ελέγχου στους -κανόνες κλάδων αποτελεί ξεχωριστή διαχειριστική αλλαγή· η προσθήκη αυτών των εργασιών δεν -προστατεύει από μόνη της έναν κλάδο. +`Gate / Quality`. Η πολιτική αποδοχής τους, με διαχείριση εκδόσεων, απαριθμεί κάθε προηγούμενη εργασία +ως υποχρεωτική ή συμβουλευτική. Μια εφαρμοστέα υποχρεωτική εργασία πρέπει να ολοκληρωθεί επιτυχώς: +αποτελέσματα που λείπουν, έχουν ακυρωθεί, παραλειφθεί, εκκρεμούν ή είναι άγνωστα δεν μπορούν να θεμελιώσουν PASS. Μια έγκυρη +ταξινόμηση μόνο για τεκμηρίωση ή μόνο για κατάλογο μπορεί να καταστήσει μη εφαρμοστέα μια λωρίδα κώδικα· +ένα πρόχειρο PR δεν αποτελεί αποδεκτό υποψήφιο. Μια ετικέτα `hotfix` δεν αίρει την απαίτηση αποδεικτικών στοιχείων. + +Και οι δύο ροές εργασίας καλύπτουν PR και push προς τους κύριους κλάδους/κλάδους έκδοσης, χειροκίνητη ενεργοποίηση και +συμβάντα ομάδας συγχώνευσης. Τα push, dispatch και merge-group εκτελούν την πλήρη επιλογή. Τα fork +και οι ομάδες συγχώνευσης χρησιμοποιούν φιλοξενούμενους runners για εργασίες που διαφορετικά επιλέγουν αυτοφιλοξενούμενους +runners· πριν από τη διάθεση πρέπει να επαληθεύεται η επαρκής φιλοξενούμενη χωρητικότητα. + +Κάθε απόδειξη JSON προσδιορίζει το SHA που έχει ανακτηθεί, την εκτέλεση της ροής εργασίας και την απόπειρα. +Το CLI απορρίπτει αναντιστοιχία SHA μεταξύ checkout και συμβάντος. Οι δοκιμές ροής εργασίας συνδέουν τη συμμετοχή στην πολιτική +με τη λίστα `needs` της εργασίας ετυμηγορίας, ώστε μια νέα ή καταργημένη λωρίδα να μην μπορεί να εξαφανιστεί σιωπηρά. +Οι αποδείξεις καλύπτουν τη δική τους ροή εργασίας, όχι τη δημοσίευση, την ανάπτυξη ή τις εσωτερικές λειτουργίες +ενός υφιστάμενου συμβουλευτικού σαρωτή. Η ενεργοποίηση και των δύο ονομάτων ελέγχου στους κανόνες κλάδων αποτελεί +ξεχωριστή διαχειριστική αλλαγή· η προσθήκη αυτών των εργασιών δεν προστατεύει από μόνη της έναν κλάδο. ### Κατάλογος στατικής σάρωσης -Ο κατάλογος ψευδωνύμων npm με εκδόσεις και η συμμετοχή στη στατική σάρωση βρίσκονται στο -`config/quality/gate-manifest.json`. Εκτελέστε `npm run check:gate-manifest` για να -επικυρώσετε τα ονόματα των script και τις ακριβείς εντολές σε αντιπαραβολή με το -`package.json`· προσθήκες, καταργήσεις και αποκλίσεις εντολών προκαλούν αποτυχία τόσο στο -τοπικό hook όσο και στις εργασίες ταξινόμησης αλλαγών στο CI. Ένα ψευδώνυμο δεν είναι -εργασία ροής εργασίας, στιγμιότυπο matrix ή περίπτωση δοκιμής: αυτοί οι αριθμοί δεν πρέπει -να παρουσιάζονται ως εναλλάξιμοι. +Ο κατάλογος npm-alias με διαχείριση εκδόσεων και η συμμετοχή στη στατική σάρωση βρίσκονται στο +`config/quality/gate-manifest.json`. Εκτελέστε `npm run check:gate-manifest` για να επικυρώσετε +τα ονόματα των script και τις ακριβείς εντολές σε σχέση με το `package.json`· προσθήκες, καταργήσεις και +αποκλίσεις εντολών προκαλούν αποτυχία τόσο του τοπικού hook όσο και των εργασιών ταξινόμησης αλλαγών στο CI. +Ένα alias δεν είναι εργασία ροής εργασίας, στιγμιότυπο πίνακα ή περίπτωση δοκιμής: αυτές οι μετρήσεις δεν πρέπει +να παρουσιάζονται ως εναλλάξιμες. Χρησιμοποιήστε `npm run quality:scan -- --list` ή `npm run quality:scan:fast -- --list` -για να εξετάσετε τα επιλεγμένα ψευδώνυμα χωρίς να τα εκτελέσετε. Ο runner καλεί το -σημείο εισόδου npm, επομένως διατηρείται το περιβάλλον εκτέλεσής του (συμπεριλαμβανομένου -του Bun όπου έχει ρυθμιστεί). Το manifest καταγράφει τα ψευδώνυμα εκτός αυτών των προφίλ -ως καλούμενα ξεχωριστά, ενώ οι εντολές συντήρησης απαγορεύονται σε προφίλ σάρωσης μόνο -για ανάγνωση. - -Αυτά τα προφίλ καλύπτουν μόνο τη στατική σάρωση. Δεν πιστοποιούν τις δοκιμές του προϊόντος, -την κάλυψη, τη δημιουργία πακέτων, τους εξωτερικούς ελέγχους ή την πλήρη αποδοχή έκδοσης -ενός υποψηφίου. Η αποδοχή από τη ροή εργασίας χρησιμοποιεί τα συνδεδεμένα -`config/quality/admission-policy.json` και `scripts/quality/admission-verdict.mjs`. -Τα προφίλ παρατήρησης έκδοσης παραμένουν ξεχωριστά· εξετάστε ανεξάρτητα τους ισχύοντες -ελέγχους και τις αποδείξεις τους. Ο παρακάτω περιγραφικός κατάλογος αποτελεί αναφορά και -όχι απόδειξη ότι μια πύλη εκτελέστηκε πράγματι. - -Τα script βρίσκονται στους καταλόγους `scripts/check/` (πύλες πολιτικής) και -`scripts/quality/` (μηχανισμός ratchet). +για να επιθεωρήσετε τα επιλεγμένα alias χωρίς να τα εκτελέσετε. Ο runner καλεί το +σημείο εισόδου npm, επομένως διατηρείται το περιβάλλον εκτέλεσής του (συμπεριλαμβανομένου του Bun όπου έχει ρυθμιστεί). +Το manifest καταγράφει τα alias εκτός αυτών των προφίλ ως εκτελούμενα ξεχωριστά, ενώ +οι εντολές συντήρησης απαγορεύονται σε προφίλ σάρωσης μόνο για ανάγνωση. + +Αυτά τα προφίλ καλύπτουν μόνο τη στατική σάρωση. Δεν πιστοποιούν τις δοκιμές προϊόντος, +την κάλυψη, τη δημιουργία πακέτων, τους εξωτερικούς ελέγχους ή την πλήρη αποδοχή έκδοσης ενός υποψηφίου. +Η αποδοχή από τη ροή εργασίας χρησιμοποιεί τα συνδεδεμένα `config/quality/admission-policy.json` και +`scripts/quality/admission-verdict.mjs`. Τα προφίλ παρατηρητή έκδοσης παραμένουν ξεχωριστά· +επιθεωρείτε ανεξάρτητα τους εφαρμοστέους ελέγχους και τις αποδείξεις τους. Ο παρακάτω περιγραφικός +κατάλογος αποτελεί αναφορά και όχι απόδειξη ότι μια πύλη πράγματι εκτελέστηκε. + +Τα script βρίσκονται στους καταλόγους `scripts/check/` (πύλες πολιτικής) και `scripts/quality/` (μηχανισμός ratchet). Η πηγή αλήθειας του CI είναι το `.github/workflows/ci.yml`. ### Ταχεία διαδρομή PR έκδοσης (`quality.yml`) -Το `.github/workflows/quality.yml` συμπληρώνει το CI για PR προς τους κύριους κλάδους/κλάδους -έκδοσης, push σε προστατευμένους κλάδους, χειροκίνητη εκτέλεση και ομάδες συγχώνευσης. -Τα PR χρησιμοποιούν γρήγορους ελέγχους φιλτραρισμένους βάσει διαδρομών. Η μόνιμα -απενεργοποιημένη διπλότυπη δημιουργία αφαιρέθηκε· οι πραγματικοί έλεγχοι -δημιουργίας/πακεταρίσματος/εκκίνησης παραμένουν στο CI. - -| Εργασία | Πεδίο εφαρμογής | Αποκλεισμός | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -| `Docs Gates (fast-path)` | PR τεκμηρίωσης/κώδικα· αναφορές τεκμηρίωσης API και συνολικός έλεγχος τεκμηρίωσης | Ναι | -| `Fast Quality Gates` | PR κώδικα· στατικοί έλεγχοι, έλεγχος τύπων, έλεγχος τύπων πίνακα ελέγχου, επηρεαζόμενες δοκιμές μονάδας | Ναι | -| `Forgotten sibling tests` | PR κώδικα· τα τροποποιημένα αρθρώματα ανιχνεύονται έως τους στατικούς καταναλωτές και τις υποψήφιες συγγενικές δοκιμές· οι διαδρομές barrel και δυναμικής εισαγωγής αναφέρονται ως συμβουλευτικά διαγνωστικά, με τις αναφερόμενες εξαιρέσεις λίστας επιτρεπόμενων | **Συμβουλευτικό** | -| `Vitest (fast-path)` | PR κώδικα· γρήγορη σουίτα vitest | Ναι | -| `Unit Tests fast-path` | PR κώδικα· σουίτα δοκιμών μονάδας σε 4 shard | Ναι | -| `No new ESLint warnings` | PR κώδικα· έλεγχος lint με επίγνωση των καταστολών | Ναι, συμπεριλαμβανομένων των fork | -| `Merge integrity (changelog + generated skills)` | Μη πρόχειρα PR· συγχρονισμός changelog και παραγόμενων skill | Ναι, συμπεριλαμβανομένων των fork | +Το `.github/workflows/quality.yml` συμπληρώνει το CI για PR προς κύριους κλάδους/κλάδους έκδοσης, push σε προστατευμένους κλάδους, +dispatch και ομάδες συγχώνευσης. Τα PR χρησιμοποιούν γρήγορους ελέγχους φιλτραρισμένους βάσει διαδρομής. Η μόνιμα +απενεργοποιημένη διπλότυπη δημιουργία αφαιρέθηκε· οι πραγματικοί έλεγχοι δημιουργίας/πακεταρίσματος/εκκίνησης παραμένουν στο CI. + +| Εργασία | Πεδίο εφαρμογής | Αποκλεισμός | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `Docs Gates (fast-path)` | PR τεκμηρίωσης/κώδικα· αναφορές τεκμηρίωσης API και docs-all | Ναι | +| `Fast Quality Gates` | PR κώδικα· στατικοί έλεγχοι, typecheck, typecheck πίνακα εργαλείων, επηρεαζόμενες δοκιμές μονάδας | Ναι | +| `Forgotten sibling tests` | PR κώδικα· τα αλλαγμένα module ανιχνεύονται έως τους στατικούς καταναλωτές και τις υποψήφιες συγγενικές δοκιμές· οι διαδρομές barrel και δυναμικού import αναφέρονται ως συμβουλευτικά διαγνωστικά, με αναφερόμενες εξαιρέσεις allowlist | **Συμβουλευτικό** | +| `Vitest (fast-path)` | PR κώδικα· γρήγορη σουίτα vitest | Ναι | +| `Unit Tests fast-path` | PR κώδικα· σουίτα δοκιμών μονάδας 4 shard | Ναι | +| `No new ESLint warnings` | PR κώδικα· προστασία lint που λαμβάνει υπόψη τις καταστολές | Ναι, συμπεριλαμβανομένων των fork | +| `Merge integrity (changelog + generated skills)` | Μη πρόχειρα PR· συγχρονισμός changelog και παραγόμενων skill | Ναι, συμπεριλαμβανομένων των fork | #### Αναφορά ξεχασμένων συγγενικών δοκιμών -Το `npm run check:forgotten-sibling-tests` επαναχρησιμοποιεί τον επιλυτή εισαγωγών στον οποίο -βασίζεται ο χάρτης επίδρασης δοκιμών. Για κάθε τροποποιημένο άρθρωμα παραγωγής, αναφέρει -ντετερμινιστικές αλυσίδες +Το `npm run check:forgotten-sibling-tests` επαναχρησιμοποιεί τον επιλυτή import που βρίσκεται πίσω από τον χάρτη επίδρασης δοκιμών. +Για κάθε αλλαγμένο module παραγωγής, αναφέρει ντετερμινιστικές αλυσίδες `changed module/symbol -> static consumer -> candidate sibling test` όταν η υποψήφια -δοκιμή απουσιάζει από το diff του pull request. Η σύνοψη Markdown και το αποτέλεσμα JSON -διατηρούνται ως artifact ροής εργασίας `forgotten-sibling-tests` για βαθμονόμηση πριν από -οποιαδήποτε διάθεση με αποκλεισμό. +δοκιμή απουσιάζει από το diff του pull request. Η σύνοψη Markdown και το αποτέλεσμα JSON διατηρούνται ως +το artifact ροής εργασίας `forgotten-sibling-tests` για βαθμονόμηση πριν από οποιαδήποτε διάθεση με αποκλεισμό. -Οι επανεξαγωγές barrel και οι δυναμικές εισαγωγές χρησιμοποιούνται μόνο για διαγνωστικά επίλυσης· δεν δημιουργούν ποτέ +Οι επανεξαγωγές barrel και τα δυναμικά imports αποτελούν μόνο διαγνωστικά επίλυσης· δεν δημιουργούν ποτέ εύρημα που εμποδίζει τη συγχώνευση. Οι εγκεκριμένες εξαιρέσεις βρίσκονται στο `config/quality/forgotten-sibling-allowlist.json`. Κάθε καταχώριση πρέπει να κατονομάζει το consumer και το υποψήφιο -test, να παρέχει συγκεκριμένη αιτιολόγηση και να παραπέμπει σε issue ή pull request στο GitHub. Οι κακοσχηματισμένες καταχωρίσεις +test, να παρέχει συγκεκριμένη αιτιολόγηση και να παραπέμπει σε GitHub issue ή pull request. Οι εσφαλμένα διαμορφωμένες καταχωρίσεις αποτυγχάνουν με ασφαλή τρόπο. Οι εξαιρέσεις δεν μπορούν να παρακάμψουν ένα διαγραμμένο υποψήφιο test ή ένα diff που προσθέτει `.skip`/`.todo`· -η αποδυνάμωση των assertions και άλλες μορφές απόκρυψης παραμένουν υπό την ευθύνη της ανεξάρτητα δεσμευτικής +η αποδυνάμωση assertions και άλλες μορφές συγκάλυψης παραμένουν στην αρμοδιότητα της ανεξάρτητα δεσμευτικής πύλης `check:test-masking`. ### Εργασία: `lint` Εκτελείται σε κάθε PR προς το `main`. Εμποδίζει τη συγχώνευση σε περίπτωση αποτυχίας. -| Script (`npm run ...`) | Επικυρώνει | Δεσμευτικό | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `check:node-runtime` | Η έκδοση του Node.js βρίσκεται εντός του υποστηριζόμενου εύρους | Ναι | -| `check:cycles` | Κυκλικές εισαγωγές — όλες οι μονάδες των `src/` + `open-sse/` | Ναι | -| `check:route-validation:t06` | Υπάρχουν σχήματα Zod σε όλες τις διαδρομές (πολιτική Tier 6) | Ναι | -| `check:any-budget:t11` | Το πλήθος των `@ts-expect-error // any` δεν υπερβαίνει το όριο (catraca Tier 11) | Ναι | -| `check:provider-consistency` | Κάθε πάροχος στο `providers.ts` έχει αντίστοιχη καταχώριση στο `providerRegistry.ts` (και αντίστροφα, εντός της λίστας επιτρεπόμενων) | Ναι | -| `check:model-lifecycle` | Οι τρεις πίνακες δρομολόγησης που συντηρούνται χειροκίνητα παραμένουν συνεπείς με το στιγμιότυπο κύκλου ζωής που έχει καταχωριστεί (#11503): το `FITNESS_TABLE` (`taskFitness.ts`) δεν βαθμολογεί κανένα αποσυρμένο id που μπορεί να δρομολογήσει το `REGISTRY`· κάθε προορισμός του `BUILT_IN_ALIASES` υπάρχει στο `REGISTRY` και απουσιάζει από το στιγμιότυπο αποσυρμένων id· κάθε αποσυρμένο id που εξακολουθεί να βρίσκεται στο `REGISTRY` προωθείται ή παρατίθεται στο `allowedRetiredInCatalog`· και καμία πηγή ή προορισμός του `DEFAULT_DEGRADATION_MAP` δεν εμφανίζεται ως αποσυρμένος σε αυτό το στιγμιότυπο. Αυτό δεν αποδεικνύει ότι ένα μοντέλο εξυπηρετείται επί του παρόντος από ενεργή ανάντη υπηρεσία. Εκτός σύνδεσης — συγκρίνει με το `config/quality/model-lifecycle.json`, το οποίο ανανεώνεται χειροκίνητα με `npm run quality:refresh-model-lifecycle` (απαιτεί δίκτυο· δεν είναι ενσωματωμένο στο CI). Το `allowedRetiredInCatalog` είναι ένας μηχανισμός σταδιακής μείωσης: προσθέστε μια καταχώριση μόνο μαζί με ένα ζήτημα παρακολούθησης. | Ναι | -| `check:fetch-targets` | Κάθε `fetch("/api/...")` στο `src/` της πλευράς πελάτη αντιστοιχεί σε ένα πραγματικό `route.ts` | Ναι | -| `check:deps` | Όλες οι εξαρτήσεις που μπορούν να εγκατασταθούν με `npm install` σε κάθε `package.json` του αποθετηρίου περιλαμβάνονται στο `dependency-allowlist.json`· επισημαίνονται τα νέα πακέτα χωρίς κλειδωμένη έκδοση ή με ονόματα που ενδέχεται να αποτελούν slopsquatting | Ναι | -| `audit:deps` | `npm audit` (ριζικός κατάλογος + electron) — χωρίς ειδοποιήσεις υψηλής/κρίσιμης σοβαρότητας (επικαλύπτεται με το osv `check:vuln-ratchet`· βλ. Αν backlog εξορθολογισμού) | Ναι | -| `check:lockfile` | Ακεραιότητα του `package-lock.json` — μητρώο https, κατακερματισμοί ακεραιότητας, χωρίς παρακάμψεις κεντρικού υπολογιστή | Ναι | -| `check:licenses` | Λίστα επιτρεπόμενων αδειών SPDX για εξαρτήσεις παραγωγής | Ναι | -| `check:tracked-artifacts` | Χωρίς τεχνουργήματα μεταγλώττισης / δεσμευμένους συμβολικούς συνδέσμους `node_modules` (εκτελείται επίσης στο husky pre-commit· το pre-push είναι σκόπιμα ελαφρύ — #6716) | Ναι | -| `check:ai-attribution` | Χωρίς καταληκτική γραμμή `Co-Authored-By` από AI/bot ή υποσέλιδο δημιουργίας μέσω AI στα commits, στον τίτλο ή στο σώμα των PR — Αυστηρός Κανόνας #16 (στον βρόχο fast-gates του `quality.yml` για PR→`release/**` — διαβάζει το payload του συμβάντος, δεν εκτελεί καμία ενέργεια εκτός PR — και σε ένα βήμα μόνο για PR στο lint του `ci.yml` για PR→`main`· επίσης στο hook `commit-msg` του husky· επιτρέπονται ανθρώπινοι συν-συγγραφείς· #14436) | -| `check:vitest-exclusions` | Κάθε εξαίρεση του Vitest κατονομάζει ένα ζήτημα παρακολούθησης και εμφανίζεται στο `config/quality/vitest-exclusions.json` (#13204) | Ναι | -| `check:file-size` | Κανένα αρχείο πηγαίου κώδικα δεν υπερβαίνει το όριο ανά επέκταση (καστάνια: παγωμένα μεγάλα αρχεία στη λίστα `frozen`) | Ναι | -| `check:error-helper` | Οι αποκρίσεις σφάλματος σε εκτελεστές/χειριστές χρησιμοποιούν `buildErrorBody()` / `sanitizeErrorMessage()` (Αυστηρός Κανόνας #12) | Ναι | -| `check:migration-numbering` | Τα αρχεία SQL μετεγκατάστασης έχουν διαδοχική αρίθμηση, χωρίς κενά ή διπλότυπα | Ναι | -| `check:public-creds` | Δεν υπάρχουν κυριολεκτικές τιμές OAuth `client_id`/`client_secret` ή κλειδιά Firebase Web εκτός του `publicCreds.ts` (Απαράβατος κανόνας #11) | Ναι | -| `check:db-rules` | Δεν υπάρχει ανεπεξέργαστη SQL εκτός των αρθρωμάτων `src/lib/db/`· δεν υπάρχουν συγκεντρωτικές εισαγωγές από το `localDb.ts` (Απαράβατοι κανόνες #2/#5) | Ναι | -| `check:known-symbols` | Οι εκτελεστές παρόχων, οι στρατηγικές δρομολόγησης και οι μεταφραστές που είναι καταχωρισμένοι στους πίνακες διεκπεραίωσής τους αντιστοιχούν στα αρχεία στον δίσκο — χωρίς ορφανά ή μη δηλωμένα σύμβολα | Ναι | -| `check:route-guard-membership` | Κάθε διαδρομή που δημιουργεί μια θυγατρική διεργασία ταξινομείται από τη `isLocalOnlyPath()` (Απαράβατοι κανόνες #15/#17) | Ναι | -| `check:test-discovery` | Κάθε αρχείο `*.test.ts` / `*.spec.ts` στο αποθετήριο συλλέγεται από τουλάχιστον έναν εκτελεστή δοκιμών (καστάνια: η λίστα ορφανών στο `test-discovery-baseline.json` μπορεί μόνο να μειώνεται) | Ναι | -| `check:agent-skills-sync` | Τα παραγόμενα τεχνουργήματα agent-skills αντιστοιχούν στον κατάλογο προέλευσής τους (χωρίς αποκλίσεις) | -| `check:provider-asset-provenance` | Τα λογότυπα/τεχνουργήματα των παρόχων διαθέτουν καταγεγραμμένη καταχώριση προέλευσης | -| `lint:json` | Τα αρχεία ρυθμίσεων JSON αναλύονται επιτυχώς και πληρούν τους κανόνες lint του αποθετηρίου | -| `typecheck:core` | Μεταγλώττιση TypeScript χωρίς σφάλματα (μόνο συμβουλευτικές προειδοποιήσεις) | Ναι | -| `typecheck:noimplicit:core` | Αυστηρό `noImplicitAny` — μελλοντικός στόχος· πολλά προϋπάρχοντα σημεία κλήσης εξακολουθούν να χρειάζονται επισημειώσεις | **Συμβουλευτικό** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | Το `tsc` περιορίζεται στο `src/app/(dashboard)/**` (#7033) — η επιμελημένη λίστα επιτρεπόμενων 27 αρχείων του `typecheck:core` δεν περιλαμβάνει κανένα TSX του πίνακα ελέγχου, ενώ ούτε το `next build` εκτελεί ποτέ έλεγχο τύπων σε αυτά (το `next.config.mjs` ορίζει `ignoreBuildErrors: true`), επομένως οι παλινδρομήσεις ορφανών αναγνωριστικών εκεί (#6625/#6909) παρέμεναν αόρατες στο CI. Γίνεται σύγκριση με μια παγιωμένη γραμμή βάσης καταμέτρησης ανά αρχείο/ανά κωδικό TS (`config/quality/dashboard-typecheck-baseline.json`, με το ίδιο μοτίβο επιβολής για παρωχημένες καταχωρίσεις όπως το `check:known-symbols`) — μόνο ΝΕΑ σφάλματα πέρα από την καταγεγραμμένη γραμμή βάσης αποτυγχάνουν την πύλη· μειώστε σταδιακά τη γραμμή βάσης με `--update` όταν διορθώνεται ένα προϋπάρχον σφάλμα. | Ναι | +| Script (`npm run ...`) | Επικυρώνει | Δεσμευτικό | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:node-runtime` | Η έκδοση του Node.js βρίσκεται εντός του υποστηριζόμενου εύρους | Ναι | +| `check:cycles` | Κυκλικά imports σε ολόκληρα τα `src/` + `open-sse/` (βασισμένο σε AST, με επίλυση των `paths` του tsconfig). Η απλή εκτέλεση είναι συμβουλευτική και παραθέτει τους κύκλους. Το `check:cycles:ratchet` (αυτό που εκτελεί το CI) εμποδίζει τη συγχώνευση όταν ο αριθμός υπερβαίνει το ανώτατο όριο `metrics.cycles` στο `quality-baseline.json` — επί του παρόντος 14, `direction: down`, επομένως μπορεί μόνο να μειωθεί (#15159 G-01/G-02) | Ναι (ratchet) | +| `check:route-validation:t06` | Παρουσία σχημάτων Zod σε όλα τα routes (πολιτική Tier 6) | Ναι | +| `check:any-budget:t11` | Ο αριθμός των `@ts-expect-error // any` δεν υπερβαίνει το επιτρεπόμενο όριο (catraca Tier 11) | Ναι | +| `check:provider-consistency` | Κάθε πάροχος στο `providers.ts` έχει μια αντίστοιχη καταχώριση στο `providerRegistry.ts` (και αντιστρόφως, εντός της λίστας επιτρεπόμενων) | Ναι | +| `check:model-lifecycle` | Οι τρεις πίνακες δρομολόγησης που συντηρούνται χειροκίνητα παραμένουν συνεπείς με το στιγμιότυπο κύκλου ζωής που έχει υποβληθεί στο αποθετήριο (#11503): το `FITNESS_TABLE` (`taskFitness.ts`) δεν βαθμολογεί κανένα καταργημένο id που μπορεί να δρομολογήσει το `REGISTRY`· κάθε προορισμός του `BUILT_IN_ALIASES` υπάρχει στο `REGISTRY` και απουσιάζει από το στιγμιότυπο καταργημένων id· κάθε καταργημένο id που εξακολουθεί να βρίσκεται στο `REGISTRY` προωθείται ή παρατίθεται στο `allowedRetiredInCatalog`· και καμία πηγή ή προορισμός του `DEFAULT_DEGRADATION_MAP` δεν εμφανίζεται ως καταργημένος σε αυτό το στιγμιότυπο. Αυτό δεν αποδεικνύει ότι ένα μοντέλο εξυπηρετείται επί του παρόντος από μια ενεργή υπηρεσία ανώτερου επιπέδου. Εκτός σύνδεσης — συγκρίνει με το `config/quality/model-lifecycle.json`, το οποίο ανανεώνεται χειροκίνητα με `npm run quality:refresh-model-lifecycle` (απαιτεί δίκτυο· δεν είναι ενσωματωμένο στο CI). Το `allowedRetiredInCatalog` είναι ένας μηχανισμός σταδιακής μείωσης: προσθέστε μια καταχώριση μόνο μαζί με ένα ζήτημα παρακολούθησης. | Ναι | +| `check:fetch-targets` | Κάθε `fetch("/api/...")` στο `src/` της πλευράς πελάτη αντιστοιχεί σε ένα πραγματικό `route.ts` | Ναι | +| `check:deps` | Όλες οι εξαρτήσεις που μπορούν να εγκατασταθούν με `npm install` σε κάθε `package.json` του αποθετηρίου περιλαμβάνονται στο `dependency-allowlist.json`· επισημαίνονται νέα πακέτα χωρίς καρφιτσωμένη έκδοση ή πακέτα που ενδέχεται να αποτελούν slopsquatting | Ναι | +| `audit:deps` | `npm audit` (ριζικός κατάλογος + electron) — καμία ειδοποίηση υψηλής/κρίσιμης σοβαρότητας (επικαλύπτεται με το osv `check:vuln-ratchet`· βλ. Λίστα εκκρεμοτήτων εξορθολογισμού) | Ναι | +| `check:lockfile` | Ακεραιότητα του `package-lock.json` — μητρώο https, κατακερματισμοί ακεραιότητας, χωρίς παρακάμψεις κεντρικού υπολογιστή | Ναι | +| `check:licenses` | Λίστα επιτρεπόμενων αδειών SPDX για εξαρτήσεις παραγωγής | Ναι | +| `check:tracked-artifacts` | Χωρίς τεχνουργήματα μεταγλώττισης / δεσμευμένους συμβολικούς συνδέσμους `node_modules` (εκτελείται επίσης στο husky pre-commit· το pre-push είναι σκόπιμα ελαφρύ — #6716) | Ναι | +| `check:ai-attribution` | Χωρίς υποσέλιδο `Co-Authored-By` από AI/bot ή υποσέλιδο δημιουργίας από AI στα commits, στον τίτλο ή στο σώμα του PR — Αυστηρός Κανόνας #16 (στον βρόχο γρήγορων ελέγχων του `quality.yml` για PR→`release/**` — διαβάζει το ωφέλιμο φορτίο του συμβάντος, δεν εκτελεί καμία ενέργεια εκτός PR — και ως βήμα μόνο για PR στο lint του `ci.yml` για PR→`main`· επίσης στο hook `commit-msg` του husky· επιτρέπονται ανθρώπινοι συν-συγγραφείς· #14436) | +| `check:vitest-exclusions` | Κάθε εξαίρεση του Vitest αναφέρει ένα ζήτημα παρακολούθησης και εμφανίζεται στο `config/quality/vitest-exclusions.json` (#13204) | Ναι | +| `check:file-size` | Κανένα αρχείο πηγαίου κώδικα δεν υπερβαίνει το όριο ανά επέκταση (καστάνια: παγωμένα μεγάλα αρχεία στη λίστα `frozen`) | Ναι | +| `check:error-helper` | Οι αποκρίσεις σφάλματος σε executors/handlers χρησιμοποιούν `buildErrorBody()` / `sanitizeErrorMessage()` (Αυστηρός Κανόνας #12) | Ναι | +| `check:migration-numbering` | Τα αρχεία SQL μετεγκατάστασης είναι αριθμημένα διαδοχικά, χωρίς κενά ή διπλότυπα | Ναι | +| `check:public-creds` | Δεν υπάρχουν κυριολεκτικές τιμές OAuth `client_id`/`client_secret` ή κλειδιά Firebase Web εκτός του `publicCreds.ts` (Αυστηρός Κανόνας #11) | Ναι | +| `check:db-rules` | Δεν υπάρχει ακατέργαστη SQL εκτός των αρθρωμάτων `src/lib/db/`· δεν υπάρχουν συγκεντρωτικές εισαγωγές από το `localDb.ts` (Αυστηροί Κανόνες #2/#5) | Ναι | +| `check:known-symbols` | Οι εκτελεστές παρόχων, οι στρατηγικές δρομολόγησης και οι μεταφραστές που είναι καταχωρισμένοι στους πίνακες αποστολής τους αντιστοιχούν στα αρχεία του δίσκου — χωρίς ορφανά ή μη δηλωμένα σύμβολα | Ναι | +| `check:route-guard-membership` | Κάθε διαδρομή που δημιουργεί θυγατρική διεργασία ταξινομείται από τη `isLocalOnlyPath()` (Αυστηροί Κανόνες #15/#17) | Ναι | +| `check:test-discovery` | Κάθε αρχείο `*.test.ts` / `*.spec.ts` στο αποθετήριο συλλέγεται από τουλάχιστον έναν εκτελεστή δοκιμών (καστάνια: η λίστα ορφανών στο `test-discovery-baseline.json` μπορεί μόνο να συρρικνωθεί) | Ναι | +| `check:agent-skills-sync` | Τα παραγόμενα τεχνουργήματα agent-skills αντιστοιχούν στον κατάλογο προέλευσής τους (χωρίς αποκλίσεις) | +| `check:provider-asset-provenance` | Τα λογότυπα/στοιχεία των παρόχων διαθέτουν καταγεγραμμένη καταχώριση προέλευσης | +| `lint:json` | Τα αρχεία ρυθμίσεων JSON αναλύονται επιτυχώς και συμμορφώνονται με τους κανόνες lint του αποθετηρίου | +| `typecheck:core` | Μεταγλώττιση TypeScript χωρίς σφάλματα (μόνο συμβουλευτικές προειδοποιήσεις) | Ναι | +| `typecheck:noimplicit:core` | Αυστηρό `noImplicitAny` — μελλοντικός στόχος· πολλά προϋπάρχοντα σημεία κλήσης εξακολουθούν να χρειάζονται επισημειώσεις | **Συμβουλευτικό** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` περιορισμένο στο `src/app/(dashboard)/**` (#7033) — η επιμελημένη λίστα επιτρεπόμενων 27 αρχείων του `typecheck:core` δεν περιλαμβάνει κανένα αρχείο TSX του dashboard, ενώ ούτε το `next build` εκτελεί ποτέ έλεγχο τύπων σε αυτά (`next.config.mjs` ορίζει `ignoreBuildErrors: true`), με αποτέλεσμα οι παλινδρομήσεις ορφανών αναγνωριστικών εκεί (#6625/#6909) να μην είναι ορατές στο CI. Οι διαφορές συγκρίνονται με μια παγωμένη γραμμή βάσης πλήθους ανά αρχείο/ανά κωδικό TS (`config/quality/dashboard-typecheck-baseline.json`, με το ίδιο μοτίβο επιβολής παλαιότητας όπως το `check:known-symbols`) — μόνο ΝΕΑ σφάλματα πέρα από το πλήθος της γραμμής βάσης αποτυγχάνουν την πύλη· μειώστε σταδιακά τη γραμμή βάσης με `--update` όταν διορθώνεται ένα προϋπάρχον σφάλμα. | Ναι | ### Εργασία: `quality-gate` Εκτελείται μετά το `test-coverage`. Αποκλείει τη συγχώνευση σε περίπτωση αποτυχίας. -| Script | Επικυρώνει | Αποκλεισμός | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `quality:collect` | Δημιουργεί το `quality-metrics.json` (πλήθος προειδοποιήσεων ESLint, κάλυψη από τη συγχωνευμένη αναφορά shards) | Ναι (προηγείται του ratchet) | -| `quality:ratchet` | Κάθε μετρική στο `quality-baseline.json` δεν έχει υποχωρήσει (προειδοποιήσεις ESLint ≤ baseline· κάλυψη ≥ baseline) | Ναι | -| `check:duplication` | Η επανάληψη κώδικα (jscpd@4) δεν υπερβαίνει το baseline στο `quality-baseline.json` | Ναι | -| `check:complexity` | Η κυκλωματική πολυπλοκότητα σε επίπεδο αρχείου δεν υπερβαίνει το όριο (βασικοί κανόνες ESLint `complexity` + `max-lines-per-function`) | Ναι | -| `check:cognitive-complexity` | Ratchet γνωστικής πολυπλοκότητας (`eslint-plugin-sonarjs`) — ξεχωριστή εκτέλεση ESLint· το CI εκτελεί και τα δύο συγχωνευμένα στο ενιαίο βήμα `check:complexity-ratchets` | Ναι | -| `check:dead-code` | Το ratchet μη χρησιμοποιούμενων exports / αρχείων (knip) δεν υποχωρεί σε σχέση με το baseline | Ναι | -| `check:compression-budget` | Προϋπολογισμός benchmark συμπίεσης — τα ελάχιστα όρια εξοικονόμησης tokens ανά engine δεν πρέπει να υποχωρούν | Ναι | -| `check:type-coverage` | Το ratchet ποσοστού τυποποιημένου κώδικα (`type-coverage`) δεν υποχωρεί· σε μεγάλο βαθμό υπερκαλύπτει το `typecheck:noimplicit:core` | Ναι | -| `check:codeql-ratchet` | Το πλήθος ανοικτών ειδοποιήσεων CodeQL δεν υποχωρεί (ανάγνωση μέσω `gh api`· ομαλή παράλειψη χωρίς token) — για τη συχνότητα ανανέωσης και τη μη αυτόματη ενεργοποίηση: δείτε το "CodeQL ratchet" παρακάτω | Ναι | +| Script | Επαληθεύει | Αποκλεισμός συγχώνευσης | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `quality:collect` | Παράγει το `quality-metrics.json` (πλήθος προειδοποιήσεων ESLint, κάλυψη από τη συγχωνευμένη αναφορά τμημάτων) | Ναι (προηγείται του ratchet) | +| `quality:ratchet` | Κάθε μετρική στο `quality-baseline.json` δεν έχει υποχωρήσει (προειδοποιήσεις ESLint ≤ γραμμή βάσης· κάλυψη ≥ γραμμή βάσης) | Ναι | +| `check:duplication` | Η επανάληψη κώδικα (jscpd@4) δεν υπερβαίνει τη γραμμή βάσης στο `quality-baseline.json` | Ναι | +| `check:complexity` | Η κυκλωματική πολυπλοκότητα σε επίπεδο αρχείου δεν υπερβαίνει το όριο (βασικοί κανόνες ESLint `complexity` + `max-lines-per-function`) | Ναι | +| `check:cognitive-complexity` | Ratchet γνωστικής πολυπλοκότητας (`eslint-plugin-sonarjs`) — ξεχωριστή εκτέλεση ESLint· το CI εκτελεί και τα δύο συγχωνευμένα στο ενιαίο βήμα `check:complexity-ratchets` | Ναι | +| `check:dead-code` | Το ratchet μη χρησιμοποιούμενων exports / αρχείων (knip) δεν υποχωρεί σε σχέση με τη γραμμή βάσης | Ναι | +| `check:compression-budget` | Προϋπολογισμός συγκριτικής αξιολόγησης συμπίεσης — τα κατώτατα όρια εξοικονόμησης tokens ανά μηχανή δεν πρέπει να υποχωρούν | Ναι | +| `check:type-coverage` | Το ratchet ποσοστού τυποποιημένου κώδικα (`type-coverage`) δεν υποχωρεί· σε μεγάλο βαθμό υπερκαλύπτει το `typecheck:noimplicit:core` | Ναι | +| `check:codeql-ratchet` | Το πλήθος ανοιχτών ειδοποιήσεων CodeQL δεν υποχωρεί (ανάγνωση μέσω `gh api`· ομαλή παράλειψη χωρίς token) — για τη συχνότητα ανανέωσης και τη μη αυτόματη ενεργοποίηση: δείτε «CodeQL ratchet» παρακάτω | Ναι | ### Εργασία: `quality-extended` Ολόκληρη η εργασία είναι συμβουλευτική (`continue-on-error: true`). Τα ratchets που βασίζονται στο npm εκτελούνται -κανονικά· οι εξωτερικοί σαρωτές εγκαθίστανται μέσω `gh release download` και αυτοπαραλείπονται (exit 0) -όταν ένα εκτελέσιμο εξακολουθεί να απουσιάζει. - -| Script | Επικυρώνει | Αποκλεισμός | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| `check:circular-deps` | Δεν υπάρχουν κυκλικές εξαρτήσεις (dpdm) | **Συμβουλευτικό** | -| `check:bundle-size` | Το μέγεθος του bundle δεν υπερβαίνει το όριο | **Συμβουλευτικό** | -| `check:secrets` | Σάρωση για μυστικά (gitleaks) — παραλείπεται εάν απουσιάζει το εκτελέσιμο | **Συμβουλευτικό** | -| `check:vuln-ratchet` | Οι ευπάθειες εξαρτήσεων (osv-scanner) δεν υποχωρούν — παραλείπεται εάν απουσιάζει το εκτελέσιμο | **Συμβουλευτικό** | -| `check:workflows` | Έλεγχος workflow (actionlint + zizmor)· σαρωτές που λείπουν/δεν λειτουργούν, μη έγκυρες αναφορές ή baseline ratchet που λείπει αποτυγχάνουν ως INCOMPLETE. Τα έγκυρα ευρήματα ακολουθούν την επιλεγμένη πολιτική strict/advisory/ratchet | Απαιτείται εκτέλεση· το ratchet zizmor αποκλείει στο CI | -| `check:openapi-breaking` | Μη συμβατές αλλαγές στο δημόσιο συμβόλαιο API (`openapi.yaml`) σε σχέση με τον βασικό κλάδο (oasdiff) — δημιουργεί `openapiBreaking=N`· παραλείπεται εάν απουσιάζει το oasdiff ή δεν μπορεί να επιλυθεί το βασικό spec | **Συμβουλευτικό** | +κανονικά· οι εξωτερικοί σαρωτές εγκαθίστανται μέσω `gh release download` και παραλείπονται αυτόματα (exit 0) +όταν εξακολουθεί να απουσιάζει κάποιο εκτελέσιμο αρχείο. + +| Script | Επαληθεύει | Αποκλεισμός συγχώνευσης | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| `check:circular-deps` | Δεν υπάρχουν κυκλικές εξαρτήσεις (dpdm) | **Συμβουλευτικό** | +| `check:bundle-size` | Το μέγεθος του bundle δεν υπερβαίνει το όριο | **Συμβουλευτικό** | +| `check:secrets` | Σάρωση μυστικών (gitleaks) — παραλείπεται αν απουσιάζει το εκτελέσιμο αρχείο | **Συμβουλευτικό** | +| `check:vuln-ratchet` | Τα τρωτά σημεία εξαρτήσεων (osv-scanner) δεν υποχωρούν — παραλείπεται αν απουσιάζει το εκτελέσιμο αρχείο | **Συμβουλευτικό** | +| `check:workflows` | Έλεγχος ροών εργασίας (actionlint + zizmor)· σαρωτές που απουσιάζουν/δεν λειτουργούν, μη έγκυρες αναφορές ή γραμμή βάσης ratchet που απουσιάζει αποτυγχάνουν ως INCOMPLETE. Τα έγκυρα ευρήματα ακολουθούν την επιλεγμένη πολιτική strict/advisory/ratchet | Απαιτείται εκτέλεση· το zizmor ratchet αποκλείει στο CI | +| `check:openapi-breaking` | Αλλαγές που διακόπτουν τη συμβατότητα του δημόσιου συμβολαίου API (`openapi.yaml`) έναντι του βασικού branch (oasdiff) — παράγει `openapiBreaking=N`· παραλείπεται αν απουσιάζει το oasdiff ή δεν μπορεί να επιλυθεί η βασική προδιαγραφή | **Συμβουλευτικό** | ### Εργασία: `docs-sync-strict` Εκτελείται σε κάθε PR προς το `main`. Αποκλείει τη συγχώνευση σε περίπτωση αποτυχίας. -| Script | Επαληθεύει | Μπλοκάρει | +| Script | Ελέγχει | Αποκλειστικό | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | Μετα-πύλη που εκτελεί διαδοχικά τις 6 υπο-πύλες παρακάτω | Ναι | +| `check:docs-all` | Μετα-πύλη που εκτελεί διαδοχικά τις 6 παρακάτω υπο-πύλες | Ναι | | ↳ `check:docs-sync` | Συνέπεια εκδόσεων μεταξύ CHANGELOG / OpenAPI / llm.txt | Ναι | -| ↳ `check:docs-counts` | Οι αριθμοί στο κείμενο (πλήθος παρόχων, πλήθος μετεγκαταστάσεων κ.λπ.) βρίσκονται εντός του παραθύρου ratchet των πραγματικών αριθμών | Ναι | -| ↳ `check:env-doc-sync` | Κάθε μεταβλητή περιβάλλοντος στο `.env.example` τεκμηριώνεται σε πίνακα τεκμηρίωσης και αντιστρόφως | Ναι | -| ↳ `check:deprecated-versions` | Δεν υπάρχουν συμβολοσειρές παρωχημένων εκδόσεων στην τεκμηρίωση | Ναι | -| ↳ `check:doc-links` | Οι εσωτερικοί σύνδεσμοι markdown στην τεκμηρίωση αντιστοιχούν σε πραγματικά αρχεία (μορφή `[text]`/`(path)`) | Ναι | +| ↳ `check:docs-counts` | Οι αριθμοί στο κείμενο (πλήθος παρόχων, πλήθος μεταβιβάσεων κ.λπ.) βρίσκονται εντός του παραθύρου σταδιακής αύξησης των πραγματικών τιμών | Ναι | +| ↳ `check:env-doc-sync` | Κάθε μεταβλητή περιβάλλοντος στο `.env.example` τεκμηριώνεται σε πίνακα της τεκμηρίωσης και αντιστρόφως | Ναι | +| ↳ `check:deprecated-versions` | Δεν υπάρχουν παρωχημένες συμβολοσειρές εκδόσεων στην τεκμηρίωση | Ναι | +| ↳ `check:doc-links` | Οι εσωτερικοί σύνδεσμοι markdown στην τεκμηρίωση αντιστοιχούν σε πραγματικά αρχεία (μορφή `[κείμενο]`/`(διαδρομή)`) | Ναι | | ↳ `check:fabricated-docs` | Οι διαδρομές, οι μεταβλητές περιβάλλοντος, οι εντολές CLI, τα ονόματα hook και οι διαδρομές αρχείων που αναφέρονται στην τεκμηρίωση υπάρχουν στη βάση κώδικα. Αυστηρή πύλη μέσω `--strict`· ήπια αποτυχία χωρίς τη σημαία. | Ναι (μέσω `--strict` στο CI) | | `check:cli-i18n` | Οι συμβολοσειρές εντολών CLI υπάρχουν σε όλα τα αρχεία τοπικών ρυθμίσεων i18n | Ναι | -| `check:openapi-coverage` | Η προδιαγραφή OpenAPI καλύπτει τουλάχιστον ένα κατώτατο όριο πραγματικών διαδρομών που ορίζεται μέσω ratchet | Ναι | +| `check:openapi-coverage` | Η προδιαγραφή OpenAPI καλύπτει τουλάχιστον ένα σταδιακά αυξανόμενο κατώτατο όριο πραγματικών διαδρομών | Ναι | | `check:openapi-security-tiers` | Οι επισημάνσεις επιπέδων ασφαλείας στο `openapi.yaml` είναι συνεπείς με τις ταξινομήσεις του `routeGuard.ts` | **Συμβουλευτικό** | -| `check:openapi-routes` | Κάθε διαδρομή στο `openapi.yaml` αντιστοιχεί σε πραγματικό `route.ts` (αποτροπή επινοημένων στοιχείων) | Ναι | -| `check:docs-symbols` | Κάθε αναφορά `/api/...` στο `docs/**/*.md` αντιστοιχεί σε πραγματικό `route.ts` (αποτροπή επινοημένων στοιχείων) | Ναι | -| `i18n translation drift` | Αμετάφραστα κλειδιά στα αρχεία τοπικών ρυθμίσεων i18n — μόνο προειδοποίηση | **Συμβουλευτικό** | +| `check:openapi-routes` | Κάθε διαδρομή στο `openapi.yaml` αντιστοιχεί σε πραγματικό `route.ts` (αποτροπή επινόησης) | Ναι | +| `check:docs-symbols` | Κάθε αναφορά `/api/...` στο `docs/**/*.md` αντιστοιχεί σε πραγματικό `route.ts` (αποτροπή επινόησης) | Ναι | +| `i18n translation drift` | Μη μεταφρασμένα κλειδιά στα αρχεία τοπικών ρυθμίσεων i18n — μόνο προειδοποίηση | **Συμβουλευτικό** | ### Εργασία: `i18n-ui-coverage` -| Script | Επαληθεύει | Μπλοκάρει | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `check-ui-keys-coverage` (inline) | Η κάλυψη κλειδιών i18n του UI είναι ≥ 65% | Ναι | -| `check-ui-value-drift` (inline) | Μια επανεγγεγραμμένη αγγλική **τιμή** δεν αφήνει πίσω της παρωχημένη μετάφραση | Ναι | -| `check-new-key-coverage` (inline) | Ένα **νέο** αγγλικό κλειδί μεταφράζεται σε κάθε τοπική ρύθμιση — ένας δείκτης `__MISSING__:` απορρίπτεται | Ναι | -| `check-translation-ratio` | Η αναλογία πραγματικών μεταφράσεων ανά τοπική ρύθμιση (φύλλα πανομοιότυπα με τα αγγλικά / placeholder / απόντα εκτός λίστας επιτρεπόμενων) δεν πρέπει να υπερβαίνει το `config/quality/i18n-translation-baseline.json` + περιθώριο | **Συμβουλευτικό** | +| Script | Ελέγχει | Αποκλειστικό | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `check-ui-keys-coverage` (inline) | Η κάλυψη κλειδιών i18n του UI είναι ≥ 65% | Ναι | +| `check-ui-value-drift` (inline) | Μια αναδιατυπωμένη αγγλική **τιμή** δεν αφήνει πίσω της παρωχημένη μετάφραση | Ναι | +| `check-new-key-coverage` (inline) | Ένα **νέο** αγγλικό κλειδί είναι μεταφρασμένο σε κάθε τοπική ρύθμιση — ένας δείκτης `__MISSING__:` απορρίπτεται | Ναι | +| `check-translation-ratio` | Η αναλογία πραγματικών μεταφράσεων ανά τοπική ρύθμιση (τιμές ίδιες με τα αγγλικά / σύμβολα κράτησης θέσης / ελλείπουσες τιμές εκτός της λίστας εξαιρέσεων) δεν πρέπει να υπερβαίνει το `config/quality/i18n-translation-baseline.json` + περιθώριο | **Συμβουλευτικό** | -Απαιτεί `fetch-depth: 0` — η πύλη value-drift συγκρίνει το `en.json` με τη βάση συγχώνευσης. +Απαιτεί `fetch-depth: 0` — η πύλη απόκλισης τιμών συγκρίνει το `en.json` με τη βάση συγχώνευσης. #### `check-ui-value-drift` — πύλη παρωχημένων μεταφράσεων -Εντοπίζει τη μία παλινδρόμηση i18n που οι άλλες πύλες δεν μπορούν να ανιχνεύσουν δομικά: μια αγγλική τιμή -επανεγγράφεται και οι μεταφράσεις που προέρχονται από τα _προηγούμενα_ αγγλικά παραμένουν, με αποτέλεσμα -οι μη αγγλόφωνοι χρήστες να συνεχίζουν να διαβάζουν ένα κείμενο με βέβαιη διατύπωση, το οποίο πλέον είναι λανθασμένο. +Εντοπίζει τη μία παλινδρόμηση i18n που οι άλλες πύλες δεν μπορούν από τη δομή τους να δουν: μια αγγλική τιμή +αναδιατυπώνεται και οι μεταφράσεις που προέρχονται από τα _προηγούμενα_ αγγλικά παραμένουν, με αποτέλεσμα +οι μη αγγλόφωνοι χρήστες να συνεχίζουν να διαβάζουν κείμενο με βέβαιη διατύπωση, το οποίο πλέον είναι λανθασμένο. -Αυτό κυκλοφόρησε πράγματι σε παραγωγή. Το `oauthModal.googleOAuthWarning` επανεγγράφηκε όταν προστέθηκε το βοήθημα +Αυτό κυκλοφόρησε πράγματι στην παραγωγή. Το `oauthModal.googleOAuthWarning` αναδιατυπώθηκε όταν προστέθηκε το βοηθητικό πρόγραμμα σύνδεσης Antigravity (#5203)· **39 από τις 43 τοπικές ρυθμίσεις** διατήρησαν κείμενο που έλεγε στους διαχειριστές να «αντιγράψουν -ολόκληρο το URL και να το επικολλήσουν παρακάτω» — μια ροή που δεν μπορεί να ολοκληρωθεί για τον συγκεκριμένο πάροχο. Παρέμεινε -απαρατήρητο έως το #8463, επειδή: +ολόκληρο το URL και να το επικολλήσουν παρακάτω» — μια ροή που δεν μπορεί να ολοκληρωθεί για αυτόν τον πάροχο. Παρέμεινε +απαρατήρητο μέχρι το #8463 επειδή: -- το `sync-ui-keys` συμπληρώνει μόνο κλειδιά που **απουσιάζουν**, ποτέ κλειδιά που είναι **παρωχημένα**· +- το `sync-ui-keys` συμπληρώνει μόνο κλειδιά που **απουσιάζουν**, ποτέ όσα είναι **παρωχημένα**· - το `check-ui-keys-coverage` μετρά την _παρουσία_ κλειδιών, επομένως μια παρωχημένη μετάφραση υπολογίζεται ως καλυμμένη· - το `check-translation-drift` παρακολουθεί τα αντίγραφα τεκμηρίωσης `docs/i18n//**.md` — - δεν διαβάζει ποτέ τα `src/i18n/messages/*.json`. Μπλοκάρει στην εργασία `docs-sync-strict` από τον - επανασυγχρονισμό του 2026-09: επεξεργασία βασικού εγγράφου → `npm run i18n:run -- --files=` (σε επίπεδο ενότητας, χαμηλού κόστους). + δεν διαβάζει ποτέ το `src/i18n/messages/*.json`. Είναι αποκλειστικό στην εργασία `docs-sync-strict` από τον + επανασυγχρονισμό 2026-09: επεξεργασία βασικού εγγράφου → `npm run i18n:run -- --files=` (ανά ενότητα, χαμηλού κόστους). -**Λαμβάνει υπόψη τις διαφορές, δεν βασίζεται σε baseline.** Συγκρίνει το `en.json` στη βάση συγχώνευσης με το -δέντρο εργασίας· για κάθε κλειδί του οποίου άλλαξε η αγγλική τιμή, οποιαδήποτε τοπική προσαρμογή εξακολουθεί να περιέχει μια -ανέγγιχτη μετάφραση θεωρείται παρωχημένη. Αυτό σκόπιμα **παγώνει το προϋπάρχον χρέος** — ένα diff +**Λαμβάνει υπόψη το diff, δεν βασίζεται σε baseline.** Συγκρίνει το `en.json` στη βάση συγχώνευσης με το +δέντρο εργασίας· για κάθε κλειδί του οποίου άλλαξε η αγγλική τιμή, κάθε locale που εξακολουθεί να περιέχει μια +ανέγγιχτη μετάφραση θεωρείται παρωχημένο. Αυτό σκόπιμα **παγώνει το προϋπάρχον χρέος** — ένα diff δεν μπορεί να αποκαλύψει από ποιο παλιό αγγλικό κείμενο προήλθε μια μακροχρόνια μετάφραση, επομένως η πύλη αξιολογεί μόνο ό,τι επηρεάζει η τρέχουσα αλλαγή. Η εναλλακτική λύση (ένα baseline hash ανά κλειδί) θα απαιτούσε -ένα παραγόμενο αρχείο ~600 KB, 3× μεγαλύτερο από το μεγαλύτερο υπάρχον baseline, το οποίο θα άλλαζε σε κάθε PR διεθνοποίησης. +ένα παραγόμενο αρχείο ~600 KB, 3× μεγαλύτερο από το μεγαλύτερο υπάρχον baseline, το οποίο θα άλλαζε σε κάθε i18n PR. Υπάρχουν δύο τρόποι για να ικανοποιηθεί: 1. ενημερώστε τις επηρεαζόμενες μεταφράσεις ή -2. ορίστε τις σε `__MISSING__:` — κατά την εκτέλεση παρέχεται τότε το διορθωμένο αγγλικό κείμενο - (`src/i18n/request.ts::deepMergeFallback`, #7258) και το κλειδί εισάγεται στην ουρά προς μετάφραση. +2. ορίστε τις σε `__MISSING__:` — τότε, κατά την εκτέλεση, παρέχεται το διορθωμένο αγγλικό κείμενο + (`src/i18n/request.ts::deepMergeFallback`, #7258) και το κλειδί μπαίνει στην ουρά για μετάφραση. Αν άλλαξε το **νόημα** της συμβολοσειράς, προτιμήστε τη **μετονομασία του κλειδιού**: ένα νέο κλειδί δεν μπορεί να κληρονομήσει μια παρωχημένη μετάφραση. Αυτό είναι το μοτίβο που χρησιμοποιήθηκε στο #8463. ```bash -npm run i18n:check-value-drift # αυστηρός έλεγχος (αυτό εκτελεί το CI) +npm run i18n:check-value-drift # αυστηρός έλεγχος (όπως εκτελείται στο CI) npm run i18n:check-value-drift:warn # μόνο αναφορά BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Τερματίζει με κωδικό 0 και `SKIP reason=base-unresolved` όταν δεν είναι δυνατή η ανάγνωση του βασικού καταλόγου (ρηχό -clone χωρίς το βασικό ref), ακολουθώντας τη συμπεριφορά του `check-openapi-breaking`. +Τερματίζεται με κωδικό 0 και `SKIP reason=base-unresolved` όταν δεν είναι δυνατή η ανάγνωση του βασικού καταλόγου (ρηχός +κλώνος χωρίς το base ref), ακολουθώντας τη συμπεριφορά του `check-openapi-breaking`. ### Εργασία: `i18n` -Πλήρης πίνακας επικύρωσης διεθνοποίησης (μία εργασία ανά τοπική προσαρμογή). Ολόκληρη η εργασία είναι συμβουλευτική. +Πλήρης μήτρα επικύρωσης i18n (μία εργασία ανά locale). Ολόκληρη η εργασία είναι συμβουλευτική. -| Script | Επικυρώνει | Αποκλεισμός | -| ------------------------------- | ------------------------------------------ | --------------------------------------------------------------------- | -| `validate_translation.py quick` | Πληρότητα μετάφρασης ανά τοπική προσαρμογή | **Συμβουλευτικό** (`continue-on-error: true` σε ολόκληρη την εργασία) | +| Script | Τι επικυρώνει | Αποκλεισμός | +| ------------------------------- | ------------------------------- | --------------------------------------------------------------------- | +| `validate_translation.py quick` | Πληρότητα μετάφρασης ανά locale | **Συμβουλευτικό** (`continue-on-error: true` σε ολόκληρη την εργασία) | ### Εργασία: `pr-test-policy` Εκτελείται μόνο σε pull requests. -| Script | Επικυρώνει | Αποκλεισμός | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | Τα PR που αλλάζουν κώδικα παραγωγής στα `src/`, `open-sse/`, `electron/` ή `bin/` πρέπει να περιλαμβάνουν ή να ενημερώνουν δοκιμές (Αυστηρός Κανόνας #8) | Ναι | -| `check:test-masking` | Τα τροποποιημένα αρχεία δοκιμών δεν μειώνουν το καθαρό πλήθος assertions ούτε προσθέτουν ταυτολογίες `assert.ok(true)` | Ναι | -| `check:pr-evidence` | Το σώμα του PR παραθέτει τεκμήρια δοκιμών/VPS για την αλλαγή (αυτοματοποιεί τον Αυστηρό Κανόνα #18 μέσω αναζήτησης στο κείμενο του PR — εύθραυστο, βλ. Backlog) | Ναι | +| Script | Τι επικυρώνει | Αποκλεισμός | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check:pr-test-policy` | Τα PR που αλλάζουν κώδικα παραγωγής στα `src/`, `open-sse/`, `electron/` ή `bin/` πρέπει να περιλαμβάνουν ή να ενημερώνουν δοκιμές (Αυστηρός Κανόνας #8) | Ναι | +| `check:test-masking` | Τα αλλαγμένα αρχεία δοκιμών δεν μειώνουν τον καθαρό αριθμό assertions ούτε προσθέτουν ταυτολογίες `assert.ok(true)` | Ναι | +| `check:pr-evidence` | Το σώμα του PR παραθέτει τεκμήρια δοκιμών/VPS για την αλλαγή (αυτοματοποιεί τον Αυστηρό Κανόνα #18 αναζητώντας στο κείμενο του PR — εύθραυστο, βλ. Backlog) | Ναι | ### Εργασία: `test-vitest` Εκτελείται μετά το `build`. Αποκλείει τη συγχώνευση σε περίπτωση αποτυχίας. -| Σουίτα | Επικυρώνει | Αποκλεισμός | -| ---------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Διακομιστή MCP (110 εργαλεία), autoCombo, cache — εκτελεστής vitest | Ναι | -| `test:vitest:ui` | Δοκιμές στοιχείων UI — εκτελεστής vitest | **Αποκλεισμός** — οι προϋπάρχουσες αποτυχίες εξαιρούνται ρητά στο `vitest.config.ts`· οι νέες αποτυχίες αποτυγχάνουν την εργασία | +| Σουίτα | Τι επικυρώνει | Αποκλεισμός | +| ---------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Διακομιστής MCP (110 εργαλεία), autoCombo, cache — vitest runner | Ναι | +| `test:vitest:ui` | Δοκιμές στοιχείων UI — vitest runner | **Αποκλεισμός** — οι προϋπάρχουσες αποτυχίες εξαιρούνται ρητά στο `vitest.config.ts`· οι νέες αποτυχίες αποτυγχάνουν την εργασία | ### Νυχτερινές ροές εργασίας (προγραμματισμένες, συμβουλευτικές) -Αυτές εκτελούνται βάσει προγράμματος cron (και μέσω `workflow_dispatch`), ποτέ σε PR. Όλες είναι συμβουλευτικές. +Αυτές εκτελούνται βάσει χρονοδιαγράμματος cron (και μέσω `workflow_dispatch`), ποτέ σε PR. Όλες είναι συμβουλευτικές. -| Ροή εργασίας | Επικυρώνει | Αποκλεισμός | +| Ροή εργασίας | Τι επικυρώνει | Αποκλεισμός | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `nightly-property` | Δοκιμές ιδιοτήτων fast-check με τυχαίο seed + μεγάλο αριθμό εκτελέσεων | **Συμβουλευτικό** | -| `nightly-resilience` | Πύλη αύξησης heap, εισαγωγή σφαλμάτων χάους, δοκιμές φόρτου/παρατεταμένου φορτίου k6 | **Συμβουλευτικό** | +| `nightly-property` | Δοκιμές ιδιοτήτων fast-check με τυχαίο seed + υψηλό αριθμό εκτελέσεων | **Συμβουλευτικό** | +| `nightly-resilience` | Πύλη αύξησης heap, έγχυση σφαλμάτων chaos, δοκιμές φόρτου/παρατεταμένου φορτίου k6 | **Συμβουλευτικό** | | `nightly-llm-security` | Προστασία από injection του promptfoo (λειτουργία αποκλεισμού) + ανιχνεύσεις garak (παραλείπονται χωρίς μυστικό παρόχου) | **Συμβουλευτικό** | | `nightly-schemathesis` | Fuzzing συμβολαίου OpenAPI (schemathesis) σε ενεργό OmniRoute με χρήση του `docs/openapi.yaml` — αναδεικνύει παραβιάσεις προδιαγραφών / μη διαχειριζόμενα 500 (Φάση 8 B.4) | **Συμβουλευτικό** | -| `nightly-mutation` | Βαθμολογία δοκιμών μεταλλάξεων Stryker στη γρήγορη λωρίδα δοκιμών μονάδας — οι επιζώσες μεταλλάξεις αναδεικνύουν αδύναμα assertions | **Συμβουλευτικό** | -| `nightly-compat` | Πίνακας συμβατότητας μηχανής Node για τα υποστηριζόμενα εύρη `engines.node` | **Συμβουλευτικό** | +| `nightly-mutation` | Βαθμολογία δοκιμών μεταλλάξεων Stryker στη γρήγορη λωρίδα μονάδων — οι μεταλλάξεις που επιβιώνουν αναδεικνύουν αδύναμα assertions | **Συμβουλευτικό** | +| `nightly-compat` | Μήτρα συμβατότητας της μηχανής Node σε όλα τα υποστηριζόμενα εύρη `engines.node` | **Συμβουλευτικό** | --- @@ -550,41 +538,41 @@ push (`release-green`)· μόνο η αποθήκευση γίνεται σε π ## Εκκρεμότητες εξορθολογισμού (αξιολόγηση ROI — Φάση 9 Κύμα 3) -Αυτή η απογραφή διασταυρώθηκε με το `ci.yml` στις 2026-06-17 (η προηγούμενη έκδοση παρέλειπε τα +Αυτή η απογραφή αντιπαραβλήθηκε με το `ci.yml` στις 2026-06-17 (η προηγούμενη έκδοση παρέλειπε τα `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Μια αξιολόγηση ROI του ενοποιημένου συνόλου +`check:codeql-ratchet`, `check:pr-evidence`). Μια αξιολόγηση ROI του αντιπαραβλημένου συνόλου εντόπισε τους ακόλουθους υποψηφίους για εξορθολογισμό. **Οι συγχωνεύσεις είναι μηχανικές αλλαγές -CI· οι ενεργοποιήσεις/καταργήσεις είναι αποφάσεις πολιτικής που προορίζονται για τον χειριστή.** Τίποτα από τα παρακάτω +CI· οι αλλαγές κατάστασης/καταργήσεις είναι αποφάσεις πολιτικής που προορίζονται για τον διαχειριστή.** Τίποτα από τα παρακάτω δεν έχει εφαρμοστεί ακόμη. -**Επίσης δεν τεκμηριώνονται παραπάνω** (συμβουλευτικά, χαμηλό σήμα): η εργασία `docs-lint` +**Επίσης δεν τεκμηριώθηκαν παραπάνω** (συμβουλευτικά, χαμηλό σήμα): η εργασία `docs-lint` (markdownlint + Vale, ολόκληρη η εργασία με `continue-on-error`) και οι αυτόνομες ροές εργασίας σάρωσης `semgrep.yml` / `codeql.yml` / `scorecard.yml`. Το `semgrepFindings: 0` βρίσκεται στο -`quality-baseline.json`, αλλά δεν είναι συνδεδεμένο με μηχανισμό αποκλεισμού βάσει ορίου στο `ci.yml` — η μετρική είναι +`quality-baseline.json`, αλλά δεν είναι συνδεδεμένο με ανασταλτικό μηχανισμό καστάνιας στο `ci.yml` — η μετρική είναι προς το παρόν ορφανή. ### Συγχώνευση / αποδιπλοποίηση (μηχανική, χαμηλότερου κινδύνου) -Κάθε υποψήφιος επικυρώθηκε έναντι της ενεργής κατάστασης των πυλών στις 2026-06-17 (εμπιστοσύνη με επαλήθευση)· -αρκετές «προφανείς» συγχωνεύσεις αποδείχθηκε ότι έκρυβαν τεχνικό χρέος και **δεν** αποτελούν άμεσες, ασφαλείς αντικαταστάσεις. - -- **Το `check:docs-sync` εκτελείται δύο φορές** — αυτόνομα στην εργασία `lint` και ξανά μέσα στο `check:docs-all` (`docs-sync-strict`) και στο hook pre-commit του husky. ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** — αφαιρέθηκε η αυτόνομη κλήση από το `lint`. -- **Σάρωση CVE** — ❌ **ΔΕΝ είναι καθαρή συγχώνευση.** Το `audit:deps` αποτυγχάνει υποχρεωτικά για οποιοδήποτε CVE υψηλής/κρίσιμης σοβαρότητας· το `check:vuln-ratchet` (osv) αποτυγχάνει μόνο σε περίπτωση _επιδείνωσης_ σε σχέση με τη γραμμή βάσης (επί του παρόντος 1 MODERATE). Διαφορετική σημασιολογία — η κατάργηση του `audit:deps` θα αφαιρούσε την απόλυτη πύλη υψηλής/κρίσιμης σοβαρότητας. Διατηρήστε και τα δύο. -- **Εντοπισμός κύκλων** — ❌ **ΔΕΝ είναι καθαρή συγχώνευση.** Το `check:circular-deps` (dpdm) αναφέρει **91 κύκλους** (γι' αυτό είναι συμβουλευτικό)· δεν μπορεί να προαχθεί σε αποκλειστικό χωρίς να επιλυθούν πρώτα, ενώ έχει ευρύτερο πεδίο εφαρμογής από το επιτυχές, επιμελημένο `check:cycles`. Διατηρήστε το `check:cycles` ως αποκλειστικό· η επίλυση των 91 κύκλων του dpdm αποτελεί ξεχωριστή εκκρεμότητα. -- **Πολυπλοκότητα** — ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): μία διέλευση ESLint, με καταμέτρηση βάσει ruleId ώστε οι γραμμές βάσης για κυκλωματική πολυπλοκότητα+max-lines και γνωστική πολυπλοκότητα να παραμένουν ανεξάρτητες· τα μεμονωμένα `check:complexity` / `check:cognitive-complexity` διατηρούνται για τοπική εκτέλεση με `--update`. -- **Αποτροπή ψευδών αναφορών `/api`** — ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): μία απογραφή FS του `src/app/api`, ενώ τα openapi-routes + docs-symbols εξακολουθούν να αναφέρουν αποτελέσματα ανεξάρτητα· τα μεμονωμένα εργαλεία διατηρούνται για τοπικές εκτελέσεις. -- **Το `check:node-runtime` εκτελείται σε 11 εργασίες** — ⚠️ **χαμηλό ROI.** Κάθε εργασία χρησιμοποιεί ξεχωριστό runner και ο έλεγχος διαρκεί <1s· η συνολική εξοικονόμηση είναι ~10s, με αντίτιμο την απώλεια μιας οικονομικής δικλίδας ανά εργασία. Δεν αξίζει την αναστάτωση. -- **Το `typecheck:noimplicit:core` στο lint του CI** — ✅ **αφαιρέθηκε από την εργασία lint** (ήταν συμβουλευτικό με `continue-on-error`)· η αποκλειστική επιφάνεια τύπων είναι `typecheck:core` + `check:type-coverage`. Το τοπικό script διατηρήθηκε. - -### Ενεργοποίηση / απόφαση (πολιτική χειριστή) - -- `check:openapi-security-tiers` (συμβουλευτικό) — ❌ **ΔΕΝ μπορεί να γίνει καθαρά αποκλειστικό.** Τερματίζει με κωδικό 0, αλλά προειδοποιεί ότι αρκετές διαδρομές `traffic-inspector` κάτω από το `LOCAL_ONLY_API_PREFIXES` δεν διαθέτουν τη σημείωση `x-loopback-only: true`. Η επιβολή του απαιτεί πρώτα την προσθήκη αυτών των σημειώσεων στο `openapi.yaml`. -- `typecheck:noimplicit:core` (συμβουλευτικό) — καλύπτεται σε μεγάλο βαθμό από τον αποκλειστικό μηχανισμό ορίου `check:type-coverage`. Μετατρέψτε το σε μηχανισμό ορίου ή καταργήστε το περιττό δεύτερο πέρασμα `tsc`. -- `test:vitest:ui` (πλέον **αποκλειστικό**) — οι προϋπάρχουσες αποτυχίες εξαιρούνται ρητά στο `vitest.config.ts` με σχόλια παρακολούθησης `// #8618`· οι νέες αποτυχίες προκαλούν αποτυχία της εργασίας. -- `check:secrets` (gitleaks, αποκλειστικός μηχανισμός ορίου παγωμένος σε 3 τεκμηριωμένα ψευδώς θετικά) — προσθέστε τα 3 στη λίστα επιτρεπόμενων ώστε να φτάσουν στο 0 ή υποβιβάστε τον έλεγχο σε συμβουλευτικό. Επικαλύπτεται με την εγγενή σάρωση μυστικών του GitHub + το `check:public-creds`. -- `check:pr-evidence` (αποκλειστικό, αναζητά μοτίβα στο κείμενο του σώματος του PR) — υψηλός κίνδυνος ψευδώς θετικών· η κατάργησή του αποδυναμώνει την επιβολή του Αυστηρού Κανόνα #18, επομένως πρόκειται για ουσιαστική απόφαση πολιτικής. -- `semgrep` (συμβουλευτικό και αυτόνομο) — επικαλύπτεται με το CodeQL για τις οικογένειες OWASP· συνδέστε τη γραμμή βάσης του με μηχανισμό ορίου ή καταργήστε το. +Κάθε υποψήφιο στοιχείο επικυρώθηκε έναντι της ενεργής κατάστασης των πυλών στις 2026-06-17 (εμπιστοσύνη με επαλήθευση)· +αρκετές «προφανείς» συγχωνεύσεις αποδείχθηκε ότι έκρυβαν τεχνικό χρέος και **δεν** αποτελούν καθαρές άμεσες αντικαταστάσεις. + +- **Το `check:docs-sync` εκτελείται δύο φορές** — αυτόνομα στην εργασία `lint` και ξανά μέσα στο `check:docs-all` (`docs-sync-strict`) και στο hook pre-commit του husky. ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** — η αυτόνομη κλήση στο `lint` αφαιρέθηκε. +- **Σάρωση CVE** — ❌ **ΔΕΝ αποτελεί καθαρή συγχώνευση.** Το `audit:deps` αποτυγχάνει υποχρεωτικά για οποιοδήποτε CVE υψηλής/κρίσιμης σοβαρότητας· το `check:vuln-ratchet` (osv) αποτυγχάνει μόνο σε περίπτωση _επιδείνωσης_ έναντι της γραμμής βάσης (επί του παρόντος 1 MODERATE). Διαφορετική σημασιολογία — η κατάργηση του `audit:deps` θα αφαιρούσε την απόλυτη πύλη υψηλής/κρίσιμης σοβαρότητας. Διατηρήστε και τα δύο. +- **Εντοπισμός κύκλων** — ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** (#15159 G-01/G-02). Το παλιό κείμενο εδώ χαρακτήριζε το `check:cycles` ως «την πράσινη, επιμελημένη» πύλη και δικαιολογούσε τη διατήρησή της ως ανασταλτικής, επειδή το `check:circular-deps` (dpdm) ανέφερε 91 κύκλους. Αυτή η πράσινη ένδειξη ήταν **ψευδώς θετική**: το `check:cycles` σάρωνε 5 υποκαταλόγους (450 αρχεία), αντιστοίχιζε μόνο στατικό `import|export … from` και απέρριπτε κάθε προσδιοριστή `@/` και `@omniroute/open-sse/`, συνεπώς δεν μπορούσε να εντοπίσει τους κύκλους δυναμικών εισαγωγών και ψευδωνύμων που κυριαρχούσαν στο αποθετήριο. Διορθώθηκε: η πύλη πλέον διατρέχει τα `src` + `open-sse` (5023 αρχεία), συλλέγει προσδιοριστές από το AST της TypeScript (ώστε το `import("…")` να προσμετράται, ενώ το `typeof import("…")` σε θέση τύπου να μην προσμετράται) και επιλύει τα `paths` του tsconfig. Εντοπίζει **14** κύκλους, όχι 0. Επειδή 14 προϋπάρχοντες κύκλοι δεν μπορούν να διορθωθούν σε ένα PR πύλης, το `check:cycles` είναι πλέον ένας **μηχανισμός καστάνιας** (`--ratchet`, ανώτατο όριο `metrics.cycles.value = 14` στο `quality-baseline.json`, `direction: down`) — αποκλείει κάθε _επιδείνωση_ και το πλήθος μπορεί μόνο να μειώνεται. Το CI εκτελεί `npm run check:cycles:ratchet`. Η σταδιακή εξάλειψη προχωρά μαζί με το **A-01**. Το `check:circular-deps` (dpdm) παραμένει συμβουλευτικό ως ευρύτερη δεύτερη γνώμη. +- **Πολυπλοκότητα** — ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): μία διέλευση ESLint, καταμέτρηση ανά ruleId, ώστε οι γραμμές βάσης κυκλωματικής πολυπλοκότητας+μέγιστων γραμμών και γνωστικής πολυπλοκότητας να παραμένουν ανεξάρτητες· τα επιμέρους `check:complexity` / `check:cognitive-complexity` παραμένουν για τοπική χρήση με `--update`. +- **Αποτροπή παραισθήσεων για το `/api`** — ✅ **ΟΛΟΚΛΗΡΩΘΗΚΕ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): μία απογραφή FS του `src/app/api`, ενώ τα openapi-routes + docs-symbols εξακολουθούν να αναφέρουν αποτελέσματα ανεξάρτητα· τα επιμέρους εργαλεία παραμένουν για τοπικές εκτελέσεις. +- **Το `check:node-runtime` εκτελείται σε 11 εργασίες** — ⚠️ **χαμηλό ROI.** Καθεμία χρησιμοποιεί ξεχωριστό runner και ο έλεγχος διαρκεί <1s· συνολική εξοικονόμηση ~10s, με τίμημα την απώλεια μιας οικονομικής δικλίδας ασφαλείας ανά εργασία. Δεν αξίζει την αναστάτωση. +- **Το `typecheck:noimplicit:core` στο lint του CI** — ✅ **αφαιρέθηκε από την εργασία lint** (ήταν συμβουλευτικό με `continue-on-error`)· η ανασταλτική επιφάνεια τύπων είναι `typecheck:core` + `check:type-coverage`. Το τοπικό script διατηρήθηκε. + +### Αλλαγή κατάστασης / απόφαση (πολιτική διαχειριστή) + +- `check:openapi-security-tiers` (συμβουλευτικό) — ❌ **ΔΕΝ μπορεί να μετατραπεί καθαρά.** Τερματίζει με 0, αλλά προειδοποιεί ότι αρκετές διαδρομές `traffic-inspector` κάτω από το `LOCAL_ONLY_API_PREFIXES` δεν διαθέτουν τη σημείωση `x-loopback-only: true`. Η επιβολή του απαιτεί πρώτα την προσθήκη αυτών των σημειώσεων στο `openapi.yaml`. +- `typecheck:noimplicit:core` (συμβουλευτικό) — καλύπτεται σε μεγάλο βαθμό από τον ανασταλτικό μηχανισμό καστάνιας `check:type-coverage`. Μετατρέψτε το σε μηχανισμό καστάνιας ή καταργήστε το πλεονάζον δεύτερο πέρασμα `tsc`. +- `test:vitest:ui` (πλέον **ανασταλτικό**) — οι προϋπάρχουσες αποτυχίες εξαιρούνται ρητά στο `vitest.config.ts` με σχόλια παρακολούθησης `// #8618`· νέες αποτυχίες προκαλούν αποτυχία της εργασίας. +- `check:secrets` (gitleaks, ανασταλτικός μηχανισμός καστάνιας παγωμένος σε 3 τεκμηριωμένα ψευδώς θετικά) — προσθέστε τα 3 στη λίστα επιτρεπόμενων ώστε να φτάσουν στο 0 ή υποβαθμίστε τον έλεγχο σε συμβουλευτικό. Επικαλύπτεται με την εγγενή σάρωση μυστικών του GitHub + `check:public-creds`. +- `check:pr-evidence` (ανασταλτικό, εκτελεί grep στο πεζό κείμενο του σώματος του PR) — υψηλός κίνδυνος ψευδώς θετικών· η κατάργησή του αποδυναμώνει την επιβολή του Αυστηρού Κανόνα #18, επομένως πρόκειται για ουσιαστική απόφαση πολιτικής. +- `semgrep` (αυτόνομο συμβουλευτικό) — επικαλύπτεται με το CodeQL για τις οικογένειες OWASP· συνδέστε τη γραμμή βάσης του με έναν μηχανισμό καστάνιας ή καταργήστε το. --- diff --git a/docs/i18n/es/CONTRIBUTING.md b/docs/i18n/es/CONTRIBUTING.md index 29455243608..22b82c7d0f6 100644 --- a/docs/i18n/es/CONTRIBUTING.md +++ b/docs/i18n/es/CONTRIBUTING.md @@ -387,22 +387,22 @@ Escribe pruebas unitarias en `tests/unit/` que cubran, como mínimo: --- -## Lista de verificación de la solicitud de incorporación de cambios +## Lista de comprobación del Pull Request - [ ] Las pruebas pasan (`npm test`) - [ ] El linting pasa (`npm run lint`) - [ ] La compilación se completa correctamente (`npm run build`) - [ ] Se añadieron tipos de TypeScript para las nuevas funciones e interfaces públicas -- [ ] No hay secretos ni valores de respaldo codificados de forma fija +- [ ] No hay secretos ni valores de respaldo codificados directamente - [ ] Las credenciales públicas de upstream están integradas mediante `resolvePublicCred()` (consulta [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nunca como literales -- [ ] Las respuestas de error pasan por `buildErrorBody()` / `sanitizeErrorMessage()`; no hay trazas de pila sin procesar en los cuerpos de las respuestas (consulta [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Los comandos de shell (`exec` / `spawn`) pasan los valores en tiempo de ejecución mediante `env`, no mediante interpolación de cadenas +- [ ] Las respuestas de error se procesan mediante `buildErrorBody()` / `sanitizeErrorMessage()` — no hay trazas de pila sin procesar en los cuerpos de las respuestas (consulta [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Los comandos de shell (`exec` / `spawn`) pasan los valores de tiempo de ejecución mediante `env`, no mediante interpolación de cadenas - [ ] Todas las entradas se validan con esquemas de Zod -- [ ] Se añadió un **fragmento** del registro de cambios en `changelog.d/{features|fixes|maintenance}/-.md` para los cambios visibles para el usuario (consulta [`changelog.d/README.md`](./changelog.d/README.md)); **no** edites `CHANGELOG.md` directamente; los fragmentos se agregan en el momento de la publicación y nunca generan conflictos entre solicitudes de incorporación de cambios +- [ ] Se añadió un **fragmento** del registro de cambios en `changelog.d/{features|fixes|maintenance}/-.md` para los cambios visibles para el usuario (consulta [`changelog.d/README.md`](./changelog.d/README.md)) — **no** edites `CHANGELOG.md` directamente; los fragmentos se agregan en el momento del lanzamiento y nunca generan conflictos entre Pull Requests - [ ] Se actualizó la documentación (si corresponde) -- [ ] No se abrieron nuevas alertas de CodeQL / Secret-Scanning, o cada una se descartó con una justificación técnica que hace referencia al documento pertinente de `docs/security/` -- [ ] Las rutas que generan procesos secundarios (`/api/mcp/`, `/api/cli-tools/runtime/`) están clasificadas como `isLocalOnlyPath()` en `src/server/authz/routeGuard.ts`; consulta la [Regla estricta n.º 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] No hay pies `Co-Authored-By` en los mensajes de commit; los commits deben aparecer únicamente bajo la identidad de Git del propietario del repositorio (Regla estricta n.º 16) +- [ ] No se generaron nuevas alertas de CodeQL / Secret-Scanning, o cada una se descartó con una justificación técnica que hace referencia al documento pertinente de `docs/security/` +- [ ] Las rutas que generan procesos secundarios (`/api/mcp/`, `/api/cli-tools/runtime/`) están clasificadas como `isLocalOnlyPath()` en `src/server/authz/routeGuard.ts` — consulta la [Regla estricta n.º 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] No hay líneas finales `Co-authored-by` de IA/bots en los mensajes de commit (Regla estricta n.º 16) — se reconoce a los colaboradores humanos cuyo trabajo se reutiliza mediante líneas finales estándar `Co-authored-by: Name ` --- diff --git a/docs/i18n/es/docs/architecture/QUALITY_GATES.md b/docs/i18n/es/docs/architecture/QUALITY_GATES.md index 543647f1fe7..6cdc83319ed 100644 --- a/docs/i18n/es/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/es/docs/architecture/QUALITY_GATES.md @@ -20,226 +20,220 @@ replicación independiente de herramientas del mismo sistema, consulta el ### Admisión de candidatos Los workflows de CI y Quality Gates emiten cada uno un veredicto estable: `Gate / CI` y -`Gate / Quality`. Su política de admisión versionada enumera cada job precedente -como obligatorio o consultivo. Un job obligatorio aplicable debe finalizar correctamente: -los resultados ausentes, cancelados, omitidos, pendientes y desconocidos no pueden establecer -un PASS. Una clasificación válida de solo documentación o solo catálogo puede hacer que -un carril de código no sea aplicable; un PR en borrador no se acepta como candidato. -Una etiqueta `hotfix` no exime de presentar evidencias. +`Gate / Quality`. Su política de admisión versionada enumera cada job previo +como obligatorio o consultivo. Un job obligatorio aplicable debe finalizar correctamente: los resultados +ausentes, cancelados, omitidos, pendientes y desconocidos no pueden establecer PASS. Una clasificación válida +de solo documentación o solo catálogo puede hacer que un lane de código no sea aplicable; +un PR en borrador no es un candidato aceptado. Una etiqueta `hotfix` no exime de aportar evidencias. Ambos workflows abarcan los PR y los pushes a las ramas main/release, la ejecución manual y -los eventos de merge group. Los pushes, la ejecución manual y los merge groups ejecutan la -selección completa. Los forks y los merge groups usan runners alojados para los jobs que, de -otro modo, seleccionarían runners autoalojados; antes del despliegue debe verificarse que haya -capacidad alojada suficiente. +los eventos de merge group. Los pushes, las ejecuciones manuales y los merge groups ejecutan la selección completa. Los forks +y los merge groups utilizan runners alojados para los jobs que, de otro modo, seleccionarían runners +autohospedados; debe verificarse que haya capacidad alojada suficiente antes del despliegue. -Cada recibo JSON identifica el SHA extraído, la ejecución del workflow y el intento. -La CLI rechaza cualquier discrepancia entre el SHA del checkout y el del evento. Las pruebas -del workflow vinculan la pertenencia a la política con la lista `needs` del job de veredicto -para que ningún carril nuevo o eliminado pueda desaparecer silenciosamente. Los recibos cubren -su propio workflow, no la publicación, el despliegue ni el funcionamiento interno de un -escáner consultivo existente. Activar ambos nombres de checks en las reglas de las ramas es -un cambio administrativo independiente; añadir estos jobs no protege una rama por sí solo. +Cada recibo JSON identifica el SHA del checkout, la ejecución del workflow y el intento. +La CLI rechaza una discrepancia entre el SHA del checkout y el del evento. Las pruebas del workflow vinculan la pertenencia a la política +con la lista `needs` del job de veredicto, de modo que un lane nuevo o eliminado no pueda desaparecer silenciosamente. +Los recibos abarcan su propio workflow, no la publicación, el despliegue ni el funcionamiento interno +de un escáner consultivo existente. Activar ambos nombres de checks en las reglas de las ramas es un +cambio administrativo independiente; añadir estos jobs no protege por sí mismo una rama. -### Inventario de análisis estático +### Inventario del análisis estático El inventario versionado de alias de npm y la pertenencia al análisis estático se encuentran en `config/quality/gate-manifest.json`. Ejecute `npm run check:gate-manifest` para validar -los nombres de los scripts y los comandos exactos con respecto a `package.json`; las adiciones, -eliminaciones y desviaciones de comandos hacen fallar tanto el hook local como los jobs de -clasificación de cambios en CI. Un alias no es un job de workflow, una instancia de matriz ni -un caso de prueba: estos recuentos no deben presentarse como intercambiables. +los nombres de los scripts y los comandos exactos con respecto a `package.json`; las adiciones, eliminaciones y +variaciones de comandos hacen fallar tanto el hook local como los jobs de clasificación de cambios en CI. +Un alias no es un job del workflow, una instancia de matriz ni un caso de prueba: estos recuentos no deben +presentarse como intercambiables. -Use `npm run quality:scan -- --list` o `npm run quality:scan:fast -- --list` +Utilice `npm run quality:scan -- --list` o `npm run quality:scan:fast -- --list` para inspeccionar los alias seleccionados sin ejecutarlos. El runner invoca el -punto de entrada de npm, por lo que se conserva su entorno de ejecución (incluido Bun cuando -está configurado). El manifiesto registra como invocados por separado los alias que quedan -fuera de esos perfiles, y los comandos de mantenimiento están prohibidos en los perfiles de -análisis de solo lectura. - -Estos perfiles cubren únicamente el análisis estático. No certifican las pruebas del producto, -la cobertura, el empaquetado, los checks externos ni la aceptación completa de una versión -candidata. La admisión del workflow utiliza los archivos vinculados -`config/quality/admission-policy.json` y -`scripts/quality/admission-verdict.mjs`. Los perfiles de observación de versiones permanecen -separados; inspeccione de forma independiente sus checks aplicables y sus recibos. El inventario -descriptivo que aparece a continuación es una referencia, no una prueba de que un gate se haya -ejecutado realmente. +punto de entrada de npm, por lo que se conserva su entorno de ejecución (incluido Bun cuando esté configurado). +El manifiesto registra los alias externos a esos perfiles como invocados por separado, y +los comandos de mantenimiento están prohibidos en los perfiles de análisis de solo lectura. + +Estos perfiles abarcan únicamente el análisis estático. No certifican las pruebas del producto, +la cobertura, el empaquetado, los checks externos ni la aceptación completa de una versión candidata. +La admisión del workflow utiliza `config/quality/admission-policy.json` y +`scripts/quality/admission-verdict.mjs`, que están vinculados. Los perfiles de release observer permanecen separados; +inspeccione de forma independiente sus checks y recibos aplicables. El inventario descriptivo +que aparece a continuación es una referencia, no una prueba de que un gate se haya ejecutado realmente. Los scripts se encuentran en `scripts/check/` (gates de políticas) y `scripts/quality/` (motor de ratchet). La fuente de verdad de CI es `.github/workflows/ci.yml`. -### Ruta rápida de PR de versión (`quality.yml`) +### Ruta rápida de PR de release (`quality.yml`) -`.github/workflows/quality.yml` complementa a CI en los PR de main/release, los pushes a ramas -protegidas, la ejecución manual y los merge groups. Los PR usan checks rápidos filtrados por rutas. -Se eliminó la compilación duplicada que estaba deshabilitada permanentemente; los checks reales -de compilación, empaquetado y arranque permanecen en CI. +`.github/workflows/quality.yml` complementa CI en los PR de main/release, los pushes a ramas +protegidas, las ejecuciones manuales y los merge groups. Los PR utilizan checks rápidos filtrados por rutas. La compilación duplicada +deshabilitada permanentemente se eliminó; los checks reales de compilación/empaquetado/arranque permanecen en CI. -| Job | Alcance | Bloqueante | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `Docs Gates (fast-path)` | PR de documentación/código; referencias de documentación de la API y toda la documentación | Sí | -| `Fast Quality Gates` | PR de código; checks estáticos, typecheck, typecheck del dashboard y pruebas unitarias afectadas | Sí | -| `Forgotten sibling tests` | PR de código; módulos modificados rastreados hasta consumidores estáticos y pruebas hermanas candidatas; las rutas de barrel e importación dinámica se notifican como diagnósticos consultivos, con las excepciones referenciadas de la lista de permitidos | **Consultivo** | -| `Vitest (fast-path)` | PR de código; suite rápida de vitest | Sí | -| `Unit Tests fast-path` | PR de código; suite unitaria de 4 shards | Sí | -| `No new ESLint warnings` | PR de código; protección de lint que tiene en cuenta las supresiones | Sí, incluidos los forks | -| `Merge integrity (changelog + generated skills)` | PR que no están en borrador; sincronización del changelog y las skills generadas | Sí, incluidos los forks | +| Job | Alcance | Bloqueante | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `Docs Gates (fast-path)` | PR de documentación/código; referencias de documentación de la API y toda la documentación | Sí | +| `Fast Quality Gates` | PR de código; checks estáticos, typecheck, typecheck del dashboard y pruebas unitarias afectadas | Sí | +| `Forgotten sibling tests` | PR de código; módulos modificados rastreados hasta consumidores estáticos y posibles pruebas hermanas; las rutas mediante barrels e importaciones dinámicas se notifican como diagnósticos consultivos, con las excepciones referenciadas de la lista de permitidos | **Consultivo** | +| `Vitest (fast-path)` | PR de código; suite rápida de vitest | Sí | +| `Unit Tests fast-path` | PR de código; suite unitaria de 4 shards | Sí | +| `No new ESLint warnings` | PR de código; protección de lint que tiene en cuenta las supresiones | Sí, incluidos los forks | +| `Merge integrity (changelog + generated skills)` | PR que no estén en borrador; sincronización del changelog y de las skills generadas | Sí, incluidos los forks | #### Informe de pruebas hermanas olvidadas -`npm run check:forgotten-sibling-tests` reutiliza el resolutor de importaciones que sustenta el mapa de impacto de las pruebas. -Para cada módulo de producción modificado, informa de cadenas deterministas -`módulo/símbolo modificado -> consumidor estático -> prueba hermana candidata` cuando la prueba -candidata no aparece en el diff del pull request. El resumen Markdown y el resultado JSON se -conservan como el artefacto de workflow `forgotten-sibling-tests` para su calibración antes de -cualquier despliegue con carácter bloqueante. +`npm run check:forgotten-sibling-tests` reutiliza el solucionador de importaciones que sustenta el mapa de impacto de las pruebas. +Para cada módulo de producción modificado, notifica cadenas deterministas +`módulo/símbolo modificado -> consumidor estático -> posible prueba hermana` cuando la prueba candidata +no está presente en el diff del pull request. El resumen en Markdown y el resultado JSON se conservan como +el artefacto del workflow `forgotten-sibling-tests` para su calibración antes de cualquier despliegue bloqueante. -Las reexportaciones mediante barrels y las importaciones dinámicas son únicamente diagnósticos de resolución; nunca generan un +Las reexportaciones mediante archivos barrel y las importaciones dinámicas son únicamente diagnósticos de resolución; nunca generan un hallazgo bloqueante. Las excepciones revisadas se encuentran en `config/quality/forgotten-sibling-allowlist.json`. Cada entrada debe indicar la prueba consumidora y la -prueba candidata, proporcionar una justificación específica y enlazar a una incidencia o solicitud de extracción de GitHub. Las entradas con formato incorrecto -producen un fallo restrictivo. Las excepciones no pueden omitir una prueba candidata eliminada ni un diff que añada `.skip`/`.todo`; -el debilitamiento de aserciones y otros tipos de enmascaramiento siguen siendo responsabilidad de la puerta bloqueante independiente +prueba candidata, proporcionar una justificación específica y enlazar una incidencia o solicitud de incorporación de cambios de GitHub. Las entradas con formato incorrecto +producen un fallo seguro. Las excepciones no pueden omitir una prueba candidata eliminada ni un diff que añada `.skip`/`.todo`; +el debilitamiento de aserciones y otras formas de enmascaramiento siguen siendo responsabilidad de la puerta de control bloqueante e independiente `check:test-masking`. ### Trabajo: `lint` Se ejecuta en cada PR a `main`. Bloquea la fusión en caso de fallo. -| Script (`npm run ...`) | Valida | Bloqueante | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | La versión de Node.js está dentro del intervalo compatible | Sí | -| `check:cycles` | Importaciones circulares: todos los módulos de `src/` + `open-sse/` | Sí | -| `check:route-validation:t06` | Hay esquemas de Zod presentes en todas las rutas (política del nivel 6) | Sí | -| `check:any-budget:t11` | El recuento de `@ts-expect-error // any` no supera el límite (catraca del nivel 11) | Sí | -| `check:provider-consistency` | Cada proveedor en `providers.ts` tiene una entrada correspondiente en `providerRegistry.ts` (y viceversa, dentro de la lista de permitidos) | Sí | -| `check:model-lifecycle` | Las tres tablas de enrutamiento mantenidas manualmente permanecen coherentes con la instantánea del ciclo de vida incluida en el repositorio (#11503): `FITNESS_TABLE` (`taskFitness.ts`) no puntúa ningún id retirado que `REGISTRY` pueda enrutar; cada destino de `BUILT_IN_ALIASES` está presente en `REGISTRY` y ausente de la instantánea de ids retirados; cada id retirado que aún figura en `REGISTRY` se redirige o aparece en `allowedRetiredInCatalog`; y ningún origen o destino de `DEFAULT_DEGRADATION_MAP` figura como retirado en esa instantánea. Esto no demuestra que un modelo esté siendo servido actualmente por un proveedor ascendente activo. Sin conexión: compara con `config/quality/model-lifecycle.json`, que se actualiza manualmente con `npm run quality:refresh-model-lifecycle` (requiere red; no está integrado en CI). `allowedRetiredInCatalog` es un mecanismo de reducción progresiva: añada una entrada únicamente con una incidencia de seguimiento. | Sí | -| `check:fetch-targets` | Cada `fetch("/api/...")` del código cliente en `src/` se resuelve en un `route.ts` real | Sí | -| `check:deps` | Todas las dependencias instalables mediante `npm install` de cada `package.json` del repositorio figuran en `dependency-allowlist.json`; se marcan los paquetes nuevos sin versión fijada o con posibles errores tipográficos maliciosos | Sí | -| `audit:deps` | `npm audit` (raíz + electron): sin avisos de gravedad alta o crítica (se solapa con `check:vuln-ratchet` de osv; consulte la lista de tareas pendientes de racionalización) | Sí | -| `check:lockfile` | Integridad de `package-lock.json`: registro https, hashes de integridad y ninguna sobrescritura de host | Sí | -| `check:licenses` | Lista permitida de licencias SPDX para dependencias de producción | Sí | -| `check:tracked-artifacts` | Sin artefactos de compilación ni enlaces simbólicos de `node_modules` confirmados (también se ejecuta en el pre-commit de husky; el pre-push es intencionadamente ligero — #6716) | Sí | -| `check:ai-attribution` | Sin tráiler `Co-Authored-By` de IA/bot ni pie de página de generación mediante IA en los commits, el título o el cuerpo del PR — Regla estricta n.º 16 (en el bucle de comprobaciones rápidas de `quality.yml` para PR→`release/**` — lee la carga útil del evento y no realiza ninguna operación fuera de los PR — y un paso exclusivo para PR en el lint de `ci.yml` para PR→`main`; también en el hook `commit-msg` de husky; se permiten coautores humanos; #14436) | -| `check:vitest-exclusions` | Cada exclusión de Vitest menciona una incidencia de seguimiento y aparece en `config/quality/vitest-exclusions.json` (#13204) | Sí | -| `check:file-size` | Ningún archivo fuente supera el límite por extensión (ajuste progresivo: archivos grandes congelados en la lista `frozen`) | Sí | -| `check:error-helper` | Las respuestas de error en ejecutores/manejadores usan `buildErrorBody()` / `sanitizeErrorMessage()` (Regla estricta n.º 12) | Sí | -| `check:migration-numbering` | Los archivos SQL de migración están numerados secuencialmente, sin saltos ni duplicados | Sí | -| `check:public-creds` | No hay valores literales de OAuth `client_id`/`client_secret` ni claves web de Firebase fuera de `publicCreds.ts` (regla estricta n.º 11) | Sí | -| `check:db-rules` | No hay SQL sin procesar fuera de los módulos de `src/lib/db/`; no hay importaciones de barril desde `localDb.ts` (reglas estrictas n.º 2/n.º 5) | Sí | -| `check:known-symbols` | Los ejecutores de proveedores, las estrategias de enrutamiento y los traductores registrados en sus tablas de despacho coinciden con los archivos del disco, sin símbolos huérfanos ni sin declarar | Sí | -| `check:route-guard-membership` | Cada ruta que genera un proceso hijo está clasificada por `isLocalOnlyPath()` (reglas estrictas n.º 15/n.º 17) | Sí | -| `check:test-discovery` | Cada archivo `*.test.ts` / `*.spec.ts` del repositorio es recopilado por al menos un ejecutor de pruebas (mecanismo de trinquete: la lista de archivos huérfanos de `test-discovery-baseline.json` solo puede reducirse) | Sí | -| `check:agent-skills-sync` | Los artefactos generados de agent-skills coinciden con su catálogo de origen (sin desviaciones) | -| `check:provider-asset-provenance` | Los logotipos/recursos de proveedores tienen registrada una entrada de procedencia | -| `lint:json` | Los archivos de configuración JSON se analizan correctamente y cumplen las reglas de lint del repositorio | -| `typecheck:core` | Compilación de TypeScript sin errores (solo advertencias informativas) | Sí | -| `typecheck:noimplicit:core` | `noImplicitAny` estricto — orientado al futuro; muchos sitios de llamada preexistentes aún necesitan anotaciones | **Informativo** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limitado a `src/app/(dashboard)/**` (#7033): la lista de permitidos seleccionada de 27 archivos de `typecheck:core` no incluye ningún TSX del panel, y `next build` tampoco realiza nunca la comprobación de tipos (`next.config.mjs` establece `ignoreBuildErrors: true`), por lo que las regresiones de identificadores huérfanos allí (#6625/#6909) no eran visibles para CI. Compara con una línea base congelada del recuento por archivo y por código TS (`config/quality/dashboard-typecheck-baseline.json`, con el mismo patrón de detección de obsolescencia que `check:known-symbols`): solo los errores NUEVOS que superen el recuento de la línea base hacen fallar la comprobación; redúzcala progresivamente con `--update` cuando se corrija un error preexistente. | Sí | +| Script (`npm run ...`) | Valida | Bloqueante | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | La versión de Node.js se encuentra dentro del intervalo compatible | Sí | +| `check:cycles` | Importaciones circulares en todo `src/` + `open-sse/` (basado en AST, con los `paths` de tsconfig resueltos). Por sí solo = informativo; enumera los ciclos. `check:cycles:ratchet` (lo que ejecuta CI) bloquea cuando el recuento supera el límite máximo de `metrics.cycles` en `quality-baseline.json`: actualmente 14, `direction: down`, por lo que solo puede disminuir (#15159 G-01/G-02) | Sí (mecanismo de trinquete) | +| `check:route-validation:t06` | Hay esquemas Zod presentes en todas las rutas (política de nivel 6) | Sí | +| `check:any-budget:t11` | El recuento de `@ts-expect-error // any` no supera el presupuesto (mecanismo de trinquete de nivel 11) | Sí | +| `check:provider-consistency` | Cada proveedor de `providers.ts` tiene una entrada correspondiente en `providerRegistry.ts` (y viceversa, dentro de la lista de permitidos) | Sí | +| `check:model-lifecycle` | Las tres tablas de enrutamiento mantenidas manualmente permanecen coherentes con la instantánea del ciclo de vida incluida en el repositorio (#11503): `FITNESS_TABLE` (`taskFitness.ts`) no puntúa ningún id retirado que `REGISTRY` pueda enrutar; cada destino de `BUILT_IN_ALIASES` está presente en `REGISTRY` y ausente de la instantánea de ids retirados; cada id retirado que aún está en `REGISTRY` se reenvía o figura en `allowedRetiredInCatalog`; y ninguna fuente ni destino de `DEFAULT_DEGRADATION_MAP` aparece como retirado en esa instantánea. Esto no demuestra que un modelo sea servido actualmente por un servicio upstream activo. Sin conexión: compara con `config/quality/model-lifecycle.json`, actualizado manualmente mediante `npm run quality:refresh-model-lifecycle` (requiere red; no está integrado en CI). `allowedRetiredInCatalog` es un mecanismo de reducción progresiva: añade una entrada únicamente con una incidencia de seguimiento. | Sí | +| `check:fetch-targets` | Cada `fetch("/api/...")` del código del cliente en `src/` se resuelve en un `route.ts` real | Sí | +| `check:deps` | Todas las dependencias instalables mediante `npm install` de cada `package.json` del repositorio están en `dependency-allowlist.json`; se señalan los paquetes nuevos sin versión fijada o potencialmente fruto de slopsquatting | Sí | +| `audit:deps` | `npm audit` (raíz + electron): no hay avisos de gravedad alta/crítica (se solapa con `check:vuln-ratchet` de osv; consulta la Lista de racionalización pendiente) | Sí | +| `check:lockfile` | Integridad de `package-lock.json`: registro https, hashes de integridad y ninguna sobrescritura de host | Sí | +| `check:licenses` | Lista de licencias SPDX permitidas para las dependencias de producción | Sí | +| `check:tracked-artifacts` | Sin artefactos de compilación ni enlaces simbólicos de `node_modules` confirmados (también se ejecuta en el pre-commit de husky; el pre-push es intencionadamente ligero — #6716) | Sí | +| `check:ai-attribution` | Sin tráiler `Co-Authored-By` de IA/bot ni pie de página de generación mediante IA en los commits, el título o el cuerpo del PR — Regla estricta #16 (en el bucle de comprobaciones rápidas de `quality.yml` para PR→`release/**` — lee la carga útil del evento y no hace nada fuera de los PR — y en un paso exclusivo para PR de lint en `ci.yml` para PR→`main`; también en el hook `commit-msg` de husky; se permiten coautores humanos; #14436) | +| `check:vitest-exclusions` | Cada exclusión de Vitest indica una incidencia de seguimiento y aparece en `config/quality/vitest-exclusions.json` (#13204) | Sí | +| `check:file-size` | Ningún archivo fuente supera el límite por extensión (ajuste progresivo: archivos grandes inmovilizados en la lista `frozen`) | Sí | +| `check:error-helper` | Las respuestas de error en ejecutores/controladores usan `buildErrorBody()` / `sanitizeErrorMessage()` (Regla estricta #12) | Sí | +| `check:migration-numbering` | Los archivos SQL de migración están numerados secuencialmente, sin huecos ni duplicados | Sí | +| `check:public-creds` | No hay valores literales de OAuth `client_id`/`client_secret` ni claves web de Firebase fuera de `publicCreds.ts` (regla estricta n.º 11) | Sí | +| `check:db-rules` | No hay SQL sin procesar fuera de los módulos de `src/lib/db/`; no hay importaciones desde archivos de reexportación de `localDb.ts` (reglas estrictas n.º 2/5) | Sí | +| `check:known-symbols` | Los ejecutores de proveedores, las estrategias de enrutamiento y los traductores registrados en sus tablas de despacho coinciden con los archivos del disco; no hay símbolos huérfanos ni sin declarar | Sí | +| `check:route-guard-membership` | Todas las rutas que generan un proceso secundario están clasificadas por `isLocalOnlyPath()` (reglas estrictas n.º 15/17) | Sí | +| `check:test-discovery` | Cada archivo `*.test.ts` / `*.spec.ts` del repositorio es recopilado por al menos un ejecutor de pruebas (mecanismo de trinquete: la lista de archivos huérfanos de `test-discovery-baseline.json` solo puede reducirse) | Sí | +| `check:agent-skills-sync` | Los artefactos generados de agent-skills coinciden con su catálogo de origen (sin divergencias) | +| `check:provider-asset-provenance` | Los logotipos/recursos de proveedores cuentan con una entrada de procedencia registrada | +| `lint:json` | Los archivos de configuración JSON se analizan correctamente y cumplen las reglas de lint del repositorio | +| `typecheck:core` | Compilación de TypeScript sin errores (solo advertencias informativas) | Sí | +| `typecheck:noimplicit:core` | `noImplicitAny` estricto — orientado al futuro; muchos puntos de llamada preexistentes aún necesitan anotaciones | **Informativo** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` limitado a `src/app/(dashboard)/**` (#7033) — la lista permitida seleccionada de 27 archivos de `typecheck:core` no incluye ningún TSX del panel, y `next build` tampoco comprueba nunca sus tipos (`next.config.mjs` establece `ignoreBuildErrors: true`), por lo que las regresiones de identificadores huérfanos allí (#6625/#6909) eran invisibles para CI. Compara con una línea base congelada del recuento por archivo/por código TS (`config/quality/dashboard-typecheck-baseline.json`, el mismo patrón de aplicación contra obsolescencia que `check:known-symbols`): solo los errores NUEVOS que superen el recuento de la línea base hacen fallar la comprobación; reduzca progresivamente la línea base con `--update` cuando se corrija un error preexistente. | Sí | ### Trabajo: `quality-gate` Se ejecuta después de `test-coverage`. Bloquea la fusión si falla. -| Script | Valida | Bloqueante | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `quality:collect` | Genera `quality-metrics.json` (número de advertencias de ESLint, cobertura del informe combinado de fragmentos) | Sí (antes del ratchet) | -| `quality:ratchet` | Ninguna métrica de `quality-baseline.json` ha empeorado (advertencias de ESLint ≤ línea base; cobertura ≥ línea base) | Sí | -| `check:duplication` | La duplicación de código (jscpd@4) no supera la línea base de `quality-baseline.json` | Sí | -| `check:complexity` | La complejidad ciclomática a nivel de archivo no supera el límite (reglas `complexity` + `max-lines-per-function` del núcleo de ESLint) | Sí | -| `check:cognitive-complexity` | Ratchet de complejidad cognitiva (`eslint-plugin-sonarjs`): pasada de ESLint independiente; CI ejecuta ambas combinadas como el único paso `check:complexity-ratchets` | Sí | -| `check:dead-code` | El ratchet de exportaciones/archivos no utilizados (knip) no empeora con respecto a la línea base | Sí | -| `check:compression-budget` | Presupuesto del benchmark de compresión: los valores mínimos de ahorro de tokens por motor no deben empeorar | Sí | -| `check:type-coverage` | El ratchet del porcentaje de código tipado (`type-coverage`) no empeora; sustituye en gran medida a `typecheck:noimplicit:core` | Sí | -| `check:codeql-ratchet` | El número de alertas abiertas de CodeQL no empeora (se consulta mediante `gh api`; se omite correctamente si no hay token): para la frecuencia de actualización y la activación manual, véase «Ratchet de CodeQL» más abajo | Sí | +| Script | Valida | Bloqueante | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `quality:collect` | Genera `quality-metrics.json` (número de advertencias de ESLint, cobertura del informe combinado de los fragmentos) | Sí (previo al ratchet) | +| `quality:ratchet` | Ninguna métrica de `quality-baseline.json` ha empeorado (advertencias de ESLint ≤ línea base; cobertura ≥ línea base) | Sí | +| `check:duplication` | La duplicación de código (jscpd@4) no supera la línea base de `quality-baseline.json` | Sí | +| `check:complexity` | La complejidad ciclomática por archivo no supera el límite (reglas `complexity` + `max-lines-per-function` del núcleo de ESLint) | Sí | +| `check:cognitive-complexity` | Ratchet de complejidad cognitiva (`eslint-plugin-sonarjs`): pasada separada de ESLint; CI ejecuta ambas combinadas en el único paso `check:complexity-ratchets` | Sí | +| `check:dead-code` | El ratchet de exportaciones/archivos sin usar (knip) no empeora respecto a la línea base | Sí | +| `check:compression-budget` | Presupuesto del benchmark de compresión: los mínimos de ahorro de tokens por motor no deben empeorar | Sí | +| `check:type-coverage` | El ratchet del porcentaje tipado (`type-coverage`) no empeora; sustituye en gran medida a `typecheck:noimplicit:core` | Sí | +| `check:codeql-ratchet` | El número de alertas abiertas de CodeQL no empeora (se consulta mediante `gh api`; omisión controlada sin token): para la frecuencia de actualización y la activación manual, consulte «Ratchet de CodeQL» más abajo | Sí | ### Trabajo: `quality-extended` El trabajo completo es consultivo (`continue-on-error: true`). Los ratchets basados en npm se ejecutan -realmente; los analizadores externos se instalan mediante `gh release download` y se omiten automáticamente (código de salida 0) -cuando un binario sigue sin estar disponible. - -| Script | Valida | Bloqueante | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| `check:circular-deps` | No hay dependencias circulares (dpdm) | **Consultivo** | -| `check:bundle-size` | El tamaño del paquete no supera el límite | **Consultivo** | -| `check:secrets` | Análisis de secretos (gitleaks): se omite si el binario no está disponible | **Consultivo** | -| `check:vuln-ratchet` | Las vulnerabilidades de las dependencias (osv-scanner) no empeoran: se omite si el binario no está disponible | **Consultivo** | -| `check:workflows` | Lint de flujos de trabajo (actionlint + zizmor); los analizadores ausentes o defectuosos, los informes no válidos o la ausencia de una línea base del ratchet producen un fallo INCOMPLETE. Los hallazgos válidos siguen la política estricta, consultiva o de ratchet seleccionada | Ejecución obligatoria; el ratchet de zizmor es bloqueante en CI | -| `check:openapi-breaking` | Cambios incompatibles en el contrato de la API pública (`openapi.yaml`) con respecto a la rama base (oasdiff): genera `openapiBreaking=N`; se omite si oasdiff no está disponible o no se puede resolver la especificación base | **Consultivo** | +realmente; los escáneres externos se instalan mediante `gh release download` y se omiten por sí mismos (salida 0) +cuando aún no está disponible un binario. + +| Script | Valida | Bloqueante | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | +| `check:circular-deps` | No hay dependencias circulares (dpdm) | **Consultivo** | +| `check:bundle-size` | El tamaño del paquete no supera el límite | **Consultivo** | +| `check:secrets` | Análisis de secretos (gitleaks): se omite si el binario no está disponible | **Consultivo** | +| `check:vuln-ratchet` | Las vulnerabilidades de las dependencias (osv-scanner) no empeoran: se omite si el binario no está disponible | **Consultivo** | +| `check:workflows` | Lint de workflows (actionlint + zizmor); los escáneres ausentes o defectuosos, los informes no válidos o la ausencia de una línea base del ratchet provocan un fallo con estado INCOMPLETE. Los hallazgos válidos siguen la política estricta, consultiva o de ratchet seleccionada | Ejecución obligatoria; ratchet de zizmor bloqueante en CI | +| `check:openapi-breaking` | Cambios incompatibles en el contrato de la API pública (`openapi.yaml`) respecto a la rama base (oasdiff): genera `openapiBreaking=N`; se omite si oasdiff no está disponible o no se puede resolver la especificación base | **Consultivo** | ### Trabajo: `docs-sync-strict` -Se ejecuta en cada PR hacia `main`. Bloquea la fusión en caso de fallo. - -| Script | Valida | Bloqueante | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| `check:docs-all` | Puerta de control general que ejecuta secuencialmente las 6 puertas secundarias indicadas a continuación | Sí | -| ↳ `check:docs-sync` | Coherencia de versiones entre CHANGELOG / OpenAPI / llm.txt | Sí | -| ↳ `check:docs-counts` | Los recuentos indicados en el texto (número de proveedores, número de migraciones, etc.) están dentro del intervalo de ajuste de los recuentos reales | Sí | -| ↳ `check:env-doc-sync` | Cada variable de entorno de `.env.example` está documentada en una tabla de la documentación y viceversa | Sí | -| ↳ `check:deprecated-versions` | No hay cadenas de versiones obsoletas en la documentación | Sí | -| ↳ `check:doc-links` | Los enlaces internos de Markdown de la documentación apuntan a archivos reales (formato `[texto]`/`(ruta)`) | Sí | -| ↳ `check:fabricated-docs` | Las rutas, variables de entorno, órdenes de CLI, nombres de hooks y rutas de archivos citados en la documentación existen en el código fuente. Puerta estricta mediante `--strict`; fallo no bloqueante sin la opción. | Sí (mediante `--strict` en CI) | -| `check:cli-i18n` | Las cadenas de las órdenes de CLI están presentes en todos los archivos de configuración regional de i18n | Sí | -| `check:openapi-coverage` | La especificación OpenAPI cubre al menos un mínimo ajustado de rutas reales | Sí | -| `check:openapi-security-tiers` | Las anotaciones de niveles de seguridad de `openapi.yaml` son coherentes con las clasificaciones de `routeGuard.ts` | **Informativo** | -| `check:openapi-routes` | Cada ruta de `openapi.yaml` corresponde a un archivo `route.ts` real (prevención de alucinaciones) | Sí | -| `check:docs-symbols` | Cada referencia a `/api/...` en `docs/**/*.md` corresponde a un archivo `route.ts` real (prevención de alucinaciones) | Sí | -| `i18n translation drift` | Claves sin traducir en los archivos de configuración regional de i18n; solo se emite una advertencia | **Informativo** | +Se ejecuta en cada PR hacia `main`. Bloquea la fusión si se produce un error. + +| Script | Valida | Bloqueante | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `check:docs-all` | Metapuerta que ejecuta secuencialmente las 6 subpuertas siguientes | Sí | +| ↳ `check:docs-sync` | Coherencia de versiones entre CHANGELOG / OpenAPI / llm.txt | Sí | +| ↳ `check:docs-counts` | Los recuentos mencionados en el texto (cantidad de proveedores, migraciones, etc.) están dentro del intervalo de ajuste respecto a los recuentos reales | Sí | +| ↳ `check:env-doc-sync` | Todas las variables de entorno de `.env.example` están documentadas en una tabla de la documentación y viceversa | Sí | +| ↳ `check:deprecated-versions` | No hay cadenas de versiones obsoletas en la documentación | Sí | +| ↳ `check:doc-links` | Los enlaces internos de Markdown en la documentación apuntan a archivos reales (formato `[texto]`/`(ruta)`) | Sí | +| ↳ `check:fabricated-docs` | Las rutas, variables de entorno, órdenes de CLI, nombres de hooks y rutas de archivo citados en la documentación existen en el código. Puerta estricta mediante `--strict`; fallo no bloqueante sin la opción. | Sí (mediante `--strict` en CI) | +| `check:cli-i18n` | Las cadenas de órdenes de CLI están presentes en todos los archivos de configuración regional de i18n | Sí | +| `check:openapi-coverage` | La especificación OpenAPI cubre al menos un mínimo ajustado de rutas reales | Sí | +| `check:openapi-security-tiers` | Las anotaciones de niveles de seguridad en `openapi.yaml` son coherentes con las clasificaciones de `routeGuard.ts` | **Consultivo** | +| `check:openapi-routes` | Cada ruta de `openapi.yaml` corresponde a un `route.ts` real (prevención de alucinaciones) | Sí | +| `check:docs-symbols` | Cada referencia a `/api/...` en `docs/**/*.md` corresponde a un `route.ts` real (prevención de alucinaciones) | Sí | +| `i18n translation drift` | Claves sin traducir en los archivos de configuración regional de i18n; solo advertencia | **Consultivo** | ### Trabajo: `i18n-ui-coverage` -| Script | Valida | Bloqueante | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (inline) | La cobertura de claves de i18n de la interfaz de usuario es ≥ 65 % | Sí | -| `check-ui-value-drift` (inline) | Un **valor** en inglés reescrito no deja ninguna traducción obsoleta | Sí | -| `check-new-key-coverage` (inline) | Una clave en inglés **nueva** está traducida en todas las configuraciones regionales; se rechaza un marcador `__MISSING__:` | Sí | -| `check-translation-ratio` | La proporción de traducciones reales por configuración regional (valores idénticos al inglés, marcadores de posición o ausencias fuera de la lista permitida) no debe superar `config/quality/i18n-translation-baseline.json` + margen | **Informativo** | +| Script | Valida | Bloqueante | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (inline) | La cobertura de claves de i18n de la interfaz de usuario es ≥ 65 % | Sí | +| `check-ui-value-drift` (inline) | Un **valor** en inglés reescrito no deja ninguna traducción obsoleta | Sí | +| `check-new-key-coverage` (inline) | Una **nueva** clave en inglés está traducida en todas las configuraciones regionales; se rechaza un marcador `__MISSING__:` | Sí | +| `check-translation-ratio` | La proporción de traducciones reales por configuración regional (hojas idénticas al inglés, marcadores de posición o ausentes fuera de la lista permitida) no debe superar `config/quality/i18n-translation-baseline.json` + margen | **Consultivo** | -Requiere `fetch-depth: 0`: la puerta de control de valores obsoletos compara `en.json` con la base de fusión. +Requiere `fetch-depth: 0`: la puerta de divergencia de valores compara `en.json` con la base de fusión. -#### `check-ui-value-drift` — puerta de control de traducciones obsoletas +#### `check-ui-value-drift` — puerta de traducciones obsoletas -Detecta la única regresión de i18n que las demás puertas no pueden detectar estructuralmente: se reescribe un valor en inglés y las traducciones derivadas del inglés _anterior_ permanecen, por lo que los usuarios que no usan inglés siguen leyendo un texto formulado con seguridad, pero ahora incorrecto. +Detecta la única regresión de i18n que las otras puertas no pueden detectar estructuralmente: se reescribe un valor en inglés y las traducciones derivadas del inglés _anterior_ permanecen, por lo que los usuarios que no usan inglés siguen leyendo un texto redactado con seguridad, pero ahora incorrecto. -Esto llegó a producción. `oauthModal.googleOAuthWarning` se reescribió cuando se incorporó el asistente de inicio de sesión de Antigravity (#5203); **39 de 43 configuraciones regionales** conservaron el texto que indicaba a los operadores que debían «copiar la URL completa y pegarla abajo», un flujo que no puede completarse para ese proveedor. Pasó inadvertido hasta #8463 porque: +Esto llegó realmente a producción. `oauthModal.googleOAuthWarning` se reescribió cuando se incorporó el asistente de inicio de sesión de Antigravity (#5203); **39 de 43 configuraciones regionales** conservaron un texto que indicaba a los operadores que debían «copiar la URL completa y pegarla a continuación», un flujo que no puede completarse con ese proveedor. Pasó inadvertido hasta #8463 porque: -- `sync-ui-keys` solo rellena las claves que están **ausentes**, nunca las que están **obsoletas**; -- `check-ui-keys-coverage` contabiliza la _presencia_ de claves, por lo que una traducción obsoleta cuenta como cubierta; -- `check-translation-drift` supervisa las réplicas de documentación `docs/i18n//**.md`, pero nunca lee `src/i18n/messages/*.json`. Es bloqueante en el trabajo `docs-sync-strict` desde la resincronización de 2026-09: editar un documento principal → `npm run i18n:run -- --files=` (por secciones y de bajo coste). +- `sync-ui-keys` solo completa claves que están **ausentes**, nunca las que están **obsoletas**; +- `check-ui-keys-coverage` cuenta la _presencia_ de claves, por lo que una traducción obsoleta se considera cubierta; +- `check-translation-drift` realiza el seguimiento de las réplicas de documentación `docs/i18n//**.md` — + nunca lee `src/i18n/messages/*.json`. Es bloqueante en el trabajo `docs-sync-strict` desde la + resincronización de 2026-09: edite un documento principal → `npm run i18n:run -- --files=` (por sección, económico). -**Consciente del diff, no respaldado por una línea base.** Compara `en.json` en la base de fusión con el -árbol de trabajo; por cada clave cuyo valor en inglés haya cambiado, cualquier configuración regional que aún contenga una -traducción sin modificar está desactualizada. Esto **congela deliberadamente la deuda preexistente**: un diff -no puede revelar de qué versión anterior en inglés provino una traducción existente desde hace tiempo, por lo que la validación evalúa -únicamente lo que afecta el cambio actual. La alternativa (una línea base de hashes por clave) supondría -un archivo generado de ~600 KB, 3 veces mayor que la línea base más grande existente, que cambiaría con cada PR de i18n. +**Consciente de las diferencias, sin respaldo de línea base.** Compara `en.json` en la base de fusión con el +árbol de trabajo; para cada clave cuyo valor en inglés haya cambiado, cualquier configuración regional que aún conserve una +traducción intacta queda obsoleta. Esto **congela deliberadamente la deuda preexistente**: una diferencia +no puede revelar de qué versión anterior del texto en inglés provino una traducción antigua, por lo que la validación evalúa +únicamente lo que modifica el cambio actual. La alternativa (una línea base de hashes por clave) supondría +un archivo generado de ~600 KB, 3 veces mayor que la línea base existente más grande, que cambiaría con cada PR de i18n. -Hay dos formas de satisfacerla: +Hay dos formas de cumplir la validación: 1. actualizar las traducciones afectadas, o -2. establecerlas como `__MISSING__:`; en ese caso, durante la ejecución se proporciona el texto corregido en inglés +2. establecerlas como `__MISSING__:`; en ese caso, el entorno de ejecución sirve el texto en inglés corregido (`src/i18n/request.ts::deepMergeFallback`, #7258) y la clave queda en cola para su traducción. Si cambió el **significado** de la cadena, es preferible **cambiar el nombre de la clave**: una clave nueva no puede heredar -una traducción desactualizada. Ese es el patrón utilizado en #8463. +una traducción obsoleta. Ese es el patrón que utilizó #8463. ```bash npm run i18n:check-value-drift # estricto (lo que ejecuta CI) -npm run i18n:check-value-drift:warn # solo genera un informe +npm run i18n:check-value-drift:warn # solo informar BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Finaliza con el código 0 y `SKIP reason=base-unresolved` cuando no se puede leer el catálogo base (un clon -superficial sin la referencia base), replicando el comportamiento de `check-openapi-breaking`. +Finaliza con código 0 y `SKIP reason=base-unresolved` cuando no se puede leer el catálogo base (un clon +superficial sin la referencia base), de forma análoga a `check-openapi-breaking`. ### Trabajo: `i18n` -Matriz completa de validación de i18n (un trabajo por configuración regional). El trabajo completo es informativo. +Matriz completa de validación de i18n (un trabajo por configuración regional). Todo el trabajo es informativo. -| Script | Valida | Bloqueo | +| Script | Valida | Bloqueante | | ------------------------------- | ------------------------------------------------------ | -------------------------------------------------------------- | | `validate_translation.py quick` | Integridad de la traducción por configuración regional | **Informativo** (`continue-on-error: true` en todo el trabajo) | @@ -247,33 +241,33 @@ Matriz completa de validación de i18n (un trabajo por configuración regional). Se ejecuta únicamente en solicitudes de incorporación de cambios. -| Script | Valida | Bloqueo | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `check:pr-test-policy` | Los PR que cambien código de producción en `src/`, `open-sse/`, `electron/` o `bin/` deben incluir o actualizar pruebas (regla estricta n.º 8) | Sí | -| `check:test-masking` | Los archivos de prueba modificados no reducen el recuento neto de aserciones ni añaden tautologías `assert.ok(true)` | Sí | -| `check:pr-evidence` | El cuerpo del PR cita evidencias de pruebas/VPS para el cambio (mecaniza la regla estricta n.º 18 buscando patrones en el texto del PR; es frágil, véase la lista de tareas pendientes) | Sí | +| Script | Valida | Bloqueante | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | Los PR que cambian código de producción en `src/`, `open-sse/`, `electron/` o `bin/` deben incluir o actualizar pruebas (Regla estricta n.º 8) | Sí | +| `check:test-masking` | Los archivos de prueba modificados no reducen el número neto de aserciones ni añaden tautologías `assert.ok(true)` | Sí | +| `check:pr-evidence` | El cuerpo del PR cita evidencias de pruebas/VPS para el cambio (automatiza la Regla estricta n.º 18 buscando patrones en el texto del PR; es frágil, consulte el Backlog) | Sí | ### Trabajo: `test-vitest` -Se ejecuta después de `build`. Bloquea la fusión si falla. +Se ejecuta después de `build`. Bloquea la fusión en caso de fallo. -| Suite | Valida | Bloqueo | +| Conjunto | Valida | Bloqueante | | ---------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `test:vitest` | Servidor MCP (110 herramientas), autoCombo y caché; ejecutor vitest | Sí | -| `test:vitest:ui` | Pruebas de componentes de la interfaz; ejecutor vitest | **Bloqueante**: los fallos preexistentes se excluyen explícitamente en `vitest.config.ts`; los fallos nuevos hacen que el trabajo falle | +| `test:vitest:ui` | Pruebas de componentes de la IU; ejecutor vitest | **Bloqueante**: los fallos preexistentes se excluyen explícitamente en `vitest.config.ts`; los fallos nuevos hacen que el trabajo falle | ### Flujos de trabajo nocturnos (programados, informativos) Se ejecutan según una programación cron (y mediante `workflow_dispatch`), nunca en PR. Todos son informativos. -| Flujo de trabajo | Valida | Bloqueo | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | Pruebas basadas en propiedades de fast-check con una semilla aleatoria y un número elevado de ejecuciones | **Informativo** | -| `nightly-resilience` | Control de crecimiento del heap, inyección caótica de fallos y pruebas de carga/prolongadas con k6 | **Informativo** | -| `nightly-llm-security` | Protección contra inyección de promptfoo (modo de bloqueo) y sondas de garak (se omiten sin un secreto del proveedor) | **Informativo** | -| `nightly-schemathesis` | Pruebas difusas del contrato OpenAPI (schemathesis) contra una instancia activa de OmniRoute usando `docs/openapi.yaml`; detectan infracciones de la especificación y errores 500 no gestionados (Fase 8 B.4) | **Informativo** | -| `nightly-mutation` | Puntuación de pruebas de mutación de Stryker sobre la vía rápida de pruebas unitarias; los mutantes supervivientes revelan aserciones débiles | **Informativo** | -| `nightly-compat` | Matriz de compatibilidad del motor Node en los intervalos admitidos de `engines.node` | **Informativo** | +| Flujo de trabajo | Valida | Bloqueante | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `nightly-property` | Pruebas basadas en propiedades de fast-check con una semilla aleatoria y un número elevado de ejecuciones | **Informativo** | +| `nightly-resilience` | Validación del crecimiento del heap, inyección caótica de fallos y pruebas de carga/resistencia con k6 | **Informativo** | +| `nightly-llm-security` | Protección contra inyecciones de promptfoo (modo de bloqueo) y sondeos de garak (se omiten sin un secreto de proveedor) | **Informativo** | +| `nightly-schemathesis` | Pruebas difusas del contrato OpenAPI (schemathesis) contra una instancia activa de OmniRoute mediante `docs/openapi.yaml`; detectan infracciones de la especificación y errores 500 no gestionados (Fase 8 B.4) | **Informativo** | +| `nightly-mutation` | Puntuación de pruebas de mutación de Stryker sobre la vía rápida de pruebas unitarias; los mutantes supervivientes revelan aserciones débiles | **Informativo** | +| `nightly-compat` | Matriz de compatibilidad del motor Node para los intervalos admitidos de `engines.node` | **Informativo** | --- @@ -543,38 +537,38 @@ Este inventario se concilió con `ci.yml` el 2026-06-17 (la versión anterior om `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Una revisión de ROI del conjunto conciliado -identificó los siguientes candidatos para racionalización. **Las fusiones son cambios -mecánicos de CI; las activaciones/eliminaciones son decisiones de política reservadas -para el operador.** Nada de lo indicado a continuación se ha aplicado todavía. +identificó los siguientes candidatos de racionalización. **Las fusiones son cambios +mecánicos de CI; las activaciones/eliminaciones son decisiones de política reservadas al +operador.** Aún no se ha aplicado nada de lo indicado a continuación. -**También sin documentar anteriormente** (consultivo, señal débil): el trabajo `docs-lint` -(markdownlint + Vale, todo el trabajo con `continue-on-error`) y los flujos de trabajo -independientes de análisis `semgrep.yml` / `codeql.yml` / `scorecard.yml`. -`semgrepFindings: 0` está en `quality-baseline.json`, pero no está conectado a un ratchet -bloqueante en `ci.yml`; actualmente la métrica está huérfana. +**También sin documentar anteriormente** (consultivo, señal baja): el job `docs-lint` +(markdownlint + Vale, todo el job con `continue-on-error`) y los workflows independientes +de análisis `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` está en +`quality-baseline.json`, pero no está conectado a un ratchet bloqueante en `ci.yml`: la +métrica está actualmente huérfana. -### Fusión / deduplicación (mecánico, menor riesgo) +### Fusión / deduplicación (mecánica, menor riesgo) -Cada candidato se validó respecto al estado real de los controles el 2026-06-17 +Cada candidato se validó con el estado real de los gates el 2026-06-17 (confiar, pero verificar); varias fusiones «obvias» resultaron ocultar deuda y **no** son -sustituciones directas sin complicaciones. +sustituciones directas sin riesgos. -- **`check:docs-sync` se ejecuta dos veces** — de forma independiente en el trabajo `lint` y de nuevo dentro de `check:docs-all` (`docs-sync-strict`) y del hook de pre-commit de husky. ✅ **HECHO** — se eliminó la invocación independiente de `lint`. -- **Análisis de CVE** — ❌ **NO es una fusión limpia.** `audit:deps` falla de forma estricta ante cualquier CVE alta/crítica; `check:vuln-ratchet` (osv) solo falla ante una _regresión_ respecto a la línea base (actualmente 1 MODERATE). Semánticas diferentes: eliminar `audit:deps` supondría perder el control absoluto de vulnerabilidades altas/críticas. Mantener ambos. -- **Detección de ciclos** — ❌ **NO es una fusión limpia.** `check:circular-deps` (dpdm) informa de **91 ciclos** (por eso es consultivo); no puede convertirse en bloqueante sin resolverlos primero y tiene un alcance más amplio que el control verde y seleccionado `check:cycles`. Mantener `check:cycles` como bloqueante; resolver los 91 ciclos de dpdm constituye su propio backlog. -- **Complejidad** — ✅ **HECHO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): un recorrido de ESLint, con recuentos por ruleId para que las líneas base de complejidad ciclomática+máximo de líneas y complejidad cognitiva sigan siendo independientes; los controles individuales `check:complexity` / `check:cognitive-complexity` se mantienen para ejecutar `--update` localmente. -- **Antialucinación de `/api`** — ✅ **HECHO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): un inventario del sistema de archivos de `src/app/api`; openapi-routes + docs-symbols siguen informando de forma independiente; los controles individuales se mantienen para las ejecuciones locales. -- **`check:node-runtime` se ejecuta en 11 trabajos** — ⚠️ **ROI bajo.** Cada uno utiliza un ejecutor independiente y la comprobación tarda <1 s; el ahorro total sería de ~10 s, a cambio de perder una protección económica por trabajo. No merece la agitación. -- **`typecheck:noimplicit:core` en el lint de CI** — ✅ **eliminado del trabajo lint** (era consultivo con `continue-on-error`); la superficie de tipos bloqueante es `typecheck:core` + `check:type-coverage`. Se conserva el script local. +- **`check:docs-sync` se ejecuta dos veces** — de forma independiente en el job `lint` y nuevamente dentro de `check:docs-all` (`docs-sync-strict`) y del hook de pre-commit de husky. ✅ **HECHO** — se eliminó la invocación independiente de `lint`. +- **Análisis de CVE** — ❌ **NO es una fusión limpia.** `audit:deps` falla de forma bloqueante ante cualquier CVE de gravedad alta/crítica; `check:vuln-ratchet` (osv) solo falla ante una _regresión_ respecto a la línea base (actualmente 1 MODERATE). Semánticas diferentes: eliminar `audit:deps` supondría perder el gate absoluto para vulnerabilidades altas/críticas. Mantener ambos. +- **Detección de ciclos** — ✅ **HECHO** (#15159 G-01/G-02). El texto anterior llamaba a `check:cycles` el gate «verde y curado» y justificaba mantenerlo como bloqueante porque `check:circular-deps` (dpdm) notificaba 91 ciclos. Ese verde era un **falso verde**: `check:cycles` analizaba 5 subdirectorios (450 archivos), solo coincidía con `import|export … from` estáticos y descartaba todos los especificadores `@/` y `@omniroute/open-sse/`, por lo que no podía detectar los ciclos de importaciones dinámicas + alias que predominaban en el repositorio. Corregido: ahora el gate recorre `src` + `open-sse` (5023 archivos), recopila especificadores desde el AST de TypeScript (por lo que `import("…")` cuenta y `typeof import("…")` en posición de tipo no) y resuelve `paths` de tsconfig. Encuentra **14** ciclos, no 0. Como no es posible corregir 14 ciclos preexistentes en un PR del gate, `check:cycles` es ahora un **ratchet** (`--ratchet`, límite máximo `metrics.cycles.value = 14` en `quality-baseline.json`, `direction: down`): bloquea cualquier _regresión_ y el recuento solo puede disminuir. CI ejecuta `npm run check:cycles:ratchet`. La reducción progresiva se gestiona con **A-01**. `check:circular-deps` (dpdm) se mantiene como una segunda opinión consultiva más amplia. +- **Complejidad** — ✅ **HECHO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): un único recorrido de ESLint, con recuentos por ruleId para que las líneas base de complejidad ciclomática+max-lines y cognitiva se mantengan independientes; `check:complexity` / `check:cognitive-complexity` individuales se conservan para el uso local de `--update`. +- **Antialucinación de `/api`** — ✅ **HECHO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): un único inventario del sistema de archivos de `src/app/api`; openapi-routes + docs-symbols siguen generando informes independientes; los comandos individuales se conservan para ejecuciones locales. +- **`check:node-runtime` se ejecuta en 11 jobs** — ⚠️ **ROI bajo.** Cada uno usa un runner independiente y la comprobación tarda <1 s; el ahorro total sería de ~10 s, a costa de perder una protección económica por job. No merece la inestabilidad del cambio. +- **`typecheck:noimplicit:core` en el lint de CI** — ✅ **eliminado del job lint** (era consultivo con `continue-on-error`); la superficie de tipos bloqueante es `typecheck:core` + `check:type-coverage`. Se conserva el script local. ### Activar / decidir (política del operador) -- `check:openapi-security-tiers` (consultivo) — ❌ **NO se puede activar limpiamente.** Termina con 0, pero advierte que varias rutas de `traffic-inspector` bajo `LOCAL_ONLY_API_PREFIXES` carecen de la anotación `x-loopback-only: true`. Aplicarlo de forma obligatoria requiere añadir primero esas anotaciones a `openapi.yaml`. -- `typecheck:noimplicit:core` (consultivo) — sustituido en gran medida por el ratchet bloqueante `check:type-coverage`. Convertirlo en ratchet o eliminar la segunda pasada redundante de `tsc`. -- `test:vitest:ui` (ahora **bloqueante**) — los fallos preexistentes están excluidos explícitamente en `vitest.config.ts` mediante comentarios de seguimiento `// #8618`; los fallos nuevos hacen que el trabajo falle. -- `check:secrets` (gitleaks, ratchet bloqueante fijado en 3 falsos positivos documentados) — añadir los 3 a la lista de permitidos para llegar a 0, o degradarlo a consultivo. Se solapa con el análisis de secretos nativo de GitHub + `check:public-creds`. -- `check:pr-evidence` (bloqueante, busca patrones en el texto del cuerpo del PR) — alto riesgo de falsos positivos; eliminarlo debilita la aplicación de la Regla estricta n.º 18, por lo que se trata de una auténtica decisión de política. -- `semgrep` (independiente y consultivo) — se solapa con CodeQL en las familias de OWASP; conectar su línea base a un ratchet o eliminarlo. +- `check:openapi-security-tiers` (consultivo) — ❌ **NO se puede convertir limpiamente en bloqueante.** Finaliza con 0, pero advierte que varias rutas de `traffic-inspector` bajo `LOCAL_ONLY_API_PREFIXES` carecen de la anotación `x-loopback-only: true`. Para aplicarlo de forma obligatoria, primero es necesario añadir esas anotaciones a `openapi.yaml`. +- `typecheck:noimplicit:core` (consultivo) — queda ampliamente cubierto por el ratchet bloqueante `check:type-coverage`. Convertirlo en ratchet o eliminar la segunda pasada redundante de `tsc`. +- `test:vitest:ui` (ahora **bloqueante**) — los fallos preexistentes están excluidos explícitamente en `vitest.config.ts` con comentarios de seguimiento `// #8618`; los fallos nuevos hacen que el job falle. +- `check:secrets` (gitleaks, ratchet bloqueante fijado en 3 falsos positivos documentados) — incluir los 3 en la lista de permitidos para llegar a 0, o degradarlo a consultivo. Se solapa con el análisis nativo de secretos de GitHub + `check:public-creds`. +- `check:pr-evidence` (bloqueante, busca patrones en la prosa del cuerpo del PR) — alto riesgo de falsos positivos; eliminarlo debilitaría la aplicación de la Hard Rule #18, por lo que se trata de una auténtica decisión de política. +- `semgrep` (independiente y consultivo) — se solapa con CodeQL para las familias OWASP; conectar su línea base a un ratchet o eliminarlo. --- diff --git a/docs/i18n/et/CONTRIBUTING.md b/docs/i18n/et/CONTRIBUTING.md index 3ab325bace7..74f3e9bab0c 100644 --- a/docs/i18n/et/CONTRIBUTING.md +++ b/docs/i18n/et/CONTRIBUTING.md @@ -395,22 +395,22 @@ Kirjuta üksiktestid `tests/unit/` kataloogi, kattes vähemalt: --- -## Pull requesti kontrollnimekiri - -- [ ] Testid läbivad (`npm test`) -- [ ] Linting läbib (`npm run lint`) -- [ ] Ehitamine õnnestub (`npm run build`) -- [ ] TypeScripti tüübid lisatud uutele avalikele funktsioonidele ja liidestele -- [ ] Pole peidetud salajasi väärtusi ega fallback väärtusi -- [ ] Avalikud ülemised volikirjad sisestatud `resolvePublicCred()` kaudu (vaata [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), mitte kunagi sõna-sõnalt -- [ ] Vigavastused suunatakse läbi `buildErrorBody()` / `sanitizeErrorMessage()` — vastuste kehades ei ole toored stack trace'id (vaata [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Käsurea käsud (`exec` / `spawn`) edastavad käitusväärtused `env` kaudu, mitte stringi interpoleerimise teel -- [ ] Kõik sisendid valideeritud skeemidega -- [ ] Muudatuste logi **fragment** lisatud `changelog.d/{features|fixes|maintenance}/-.md` alla kasutajate suunatud muudatuste jaoks (vaata [`changelog.d/README.md`](./changelog.d/README.md)) — **ära** muuda `CHANGELOG.md` otse; fragmendid kogutakse väljaandmise ajal ja ei tekki kunagi konflikte -- [ ] Dokumentatsioon uuendatud (kohaldatavatel juhtudel) -- [ ] Uusi CodeQL / Secret-Scanning hoiatusi ei avatud, või iga neist lükati tagasi tehnilise põhjendusega, viidates asjakohasele `docs/security/` dokumendile -- [ ] Marsruudid, mis käivitavad lapseprotsesse (`/api/mcp/`, `/api/cli-tools/runtime/`), on klassifitseeritud `isLocalOnlyPath()` abil `src/server/authz/routeGuard.ts` failis — vaata [Rangedreegel nr 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Kommitedetsioonides pole `Co-Authored-By` trailerid — kommid peavad ilmuma ainult hoidla omaniku Git identiteedi all (Rangedreegel nr 16) +## Tõmbetaotluse kontrollnimekiri + +- [ ] Testid läbivad edukalt (`npm test`) +- [ ] Lintimine läbib edukalt (`npm run lint`) +- [ ] Järk õnnestub (`npm run build`) +- [ ] Uutele avalikele funktsioonidele ja liidestele on lisatud TypeScripti tüübid +- [ ] Puuduvad kõvakodeeritud saladused või varuväärtused +- [ ] Avalikud ülesvoolu pääsutunnused on manustatud `resolvePublicCred()` kaudu (vt [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), mitte kunagi literaalidena +- [ ] Veavastused läbivad `buildErrorBody()` / `sanitizeErrorMessage()` — vastuste kehades pole töötlemata pinujälgi (vt [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Kestakäsud (`exec` / `spawn`) edastavad käitusaegsed väärtused `env` kaudu, mitte stringinterpolatsiooni abil +- [ ] Kõik sisendid on valideeritud Zodi skeemidega +- [ ] Kasutajale nähtavate muudatuste jaoks on lisatud muudatuste logi **fragment** asukohta `changelog.d/{features|fixes|maintenance}/-.md` (vt [`changelog.d/README.md`](./changelog.d/README.md)) — ärge muutke faili `CHANGELOG.md` otse; fragmendid koondatakse väljalaske ajal ega lähe tõmbetaotluste vahel kunagi konflikti +- [ ] Dokumentatsioon on värskendatud (kui kohaldatav) +- [ ] Uusi CodeQL-i / saladuste skannimise hoiatusi pole avatud või iga hoiatus on tagasi lükatud tehnilise põhjendusega, mis viitab asjakohasele dokumendile kataloogis `docs/security/` +- [ ] Alamprotsesse käivitavad marsruudid (`/api/mcp/`, `/api/cli-tools/runtime/`) on failis `src/server/authz/routeGuard.ts` liigitatud funktsiooniga `isLocalOnlyPath()` — vt [ranget reeglit nr 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Sissekannete sõnumites pole tehisintellekti/roboti `Co-authored-by` järelridu (range reegel nr 16) — inimkaastöötajaid, kelle tööd taaskasutatakse, tunnustatakse standardsete `Co-authored-by: Name ` järelridadega --- diff --git a/docs/i18n/et/docs/architecture/QUALITY_GATES.md b/docs/i18n/et/docs/architecture/QUALITY_GATES.md index 7f139dcda62..78b2b816483 100644 --- a/docs/i18n/et/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/et/docs/architecture/QUALITY_GATES.md @@ -19,210 +19,210 @@ replikatsiooniplaani leiate dokumendist ### Kandidaadi vastuvõtmine -CI ja Quality Gates töövood väljastavad kumbki stabiilse otsuse: `Gate / CI` ja +CI ja Quality Gatesi töövood väljastavad kumbki stabiilse otsuse: `Gate / CI` ja `Gate / Quality`. Nende versioonitud vastuvõtupoliitika loetleb iga eelneva töö -kohustusliku või soovituslikuna. Kohaldatav kohustuslik töö peab õnnestuma: puuduv, +kohustusliku või nõuandvana. Kohaldatav kohustuslik töö peab õnnestuma: puuduv, tühistatud, vahele jäetud, ootel või tundmatu tulemus ei saa kinnitada olekut PASS. Kehtiv -ainult dokumentatsiooni või ainult kataloogi puudutav klassifikatsioon võib muuta koodiraja mittekohaldatavaks; -mustand-PR ei ole vastuvõetav kandidaat. Silt `hotfix` ei vabasta tõendite esitamisest. +ainult dokumentatsiooni või ainult kataloogi muudatuse klassifikatsioon võib muuta koodiraja mittekohaldatavaks; +mustand-PR ei ole aktsepteeritud kandidaat. Silt `hotfix` ei vabasta tõendite esitamisest. Mõlemad töövood hõlmavad PR-e ja tõukeid põhi-/väljalaskeharudesse, käsitsi käivitamist ning -ühendamisrühma sündmusi. Tõuge, käsitsi käivitamine ja ühendamisrühm käitavad täieliku valiku. Harud -ja ühendamisrühmad kasutavad GitHubi hostitud käitajaid tööde jaoks, mis muidu valiksid isemajutatud -käitajad; enne kasutuselevõttu tuleb kontrollida piisava hostitud ressursimahu olemasolu. +liitmisrühma sündmusi. Tõuke, käsitsi käivitamise ja liitmisrühma korral käivitatakse täielik valik. Forkid +ja liitmisrühmad kasutavad majutatud käitajaid tööde jaoks, mis muidu valiksid isemajutatud +käitajad; enne kasutuselevõttu tuleb kontrollida piisava majutatud võimsuse olemasolu. Iga JSON-kviitung tuvastab väljavõetud SHA, töövoo käivituse ja katse. -CLI lükkab väljavõtte/sündmuse SHA mittevastavuse tagasi. Töövootestid seovad poliitika liikmesuse +CLI lükkab tagasi väljavõtte/sündmuse SHA mittevastavuse. Töövootestid seovad poliitika liikmesuse otsusetöö `needs` loendiga, et uus või eemaldatud rada ei saaks märkamatult kaduda. -Kviitungid hõlmavad oma töövoogu, mitte avaldamist, juurutamist ega olemasoleva -soovitusliku skanneri sisemist toimimist. Mõlema kontrollnime aktiveerimine harureeglites on -eraldi administratiivne muudatus; nende tööde lisamine ei kaitse iseenesest haru. +Kviitungid hõlmavad nende enda töövoogu, mitte avaldamist, juurutamist ega olemasoleva +nõuandva skanneri sisemist tööd. Mõlema kontrollnime aktiveerimine harureeglites on +eraldi haldusmuudatus; nende tööde lisamine ei kaitse iseenesest haru. ### Staatilise skannimise loend -Versioonitud npm-aliaste loend ja staatilise skannimise koosseis asuvad failis +Versioonitud npm-i aliaste loend ja staatilise skannimise liikmesus asuvad failis `config/quality/gate-manifest.json`. Käivitage `npm run check:gate-manifest`, et valideerida -skriptide nimed ja täpsed käsud faili `package.json` suhtes; lisamised, eemaldamised ja -käskude kõrvalekalded põhjustavad tõrke nii kohalikus haagis kui ka CI muudatuste klassifitseerimise töödes. +skriptinimed ja täpsed käsud faili `package.json` suhtes; lisamised, eemaldamised ja +käskude lahknevused nurjavad nii kohaliku hook'i kui ka CI muudatuste klassifitseerimise tööd. Alias ei ole töövootöö, maatriksi eksemplar ega testjuhtum: neid arve ei tohi -esitada omavahel asendatavatena. +esitada samaväärsetena. -Kasutage valitud aliaste kontrollimiseks ilma neid käivitamata käsku `npm run quality:scan -- --list` või -`npm run quality:scan:fast -- --list`. -Käitaja kutsub välja npm-i sisenemispunkti, mistõttu säilib selle käituskeskkond -(sh Bun, kui see on seadistatud). -Manifest salvestab nendest profiilidest väljapoole jäävad aliased eraldi käivitatavatena ning +Kasutage `npm run quality:scan -- --list` või `npm run quality:scan:fast -- --list`, +et valitud aliaseid ilma neid käivitamata kontrollida. Käitaja kutsub välja +npm-i sisenemispunkti, mistõttu säilib selle käituskeskkond (sh Bun seal, kus see on seadistatud). +Manifest märgib neist profiilidest väljapoole jäävad aliased eraldi käivitatavatena ning hoolduskäsud on kirjutuskaitstud skannimisprofiilides keelatud. -Need profiilid hõlmavad ainult staatilist skannimist. Need ei sertifitseeri toote teste, -katvust, pakendamist, väliseid kontrolle ega kandidaadi täielikku väljalaskekõlblikkust. -Töövoo vastuvõtt kasutab lingitud faili `config/quality/admission-policy.json` ja -skripti `scripts/quality/admission-verdict.mjs`. Väljalaskevaatleja profiilid jäävad eraldiseisvaks; -kontrollige nende kohaldatavaid kontrolle ja kviitungeid eraldi. Allolev kirjeldav -loend on viitematerjal, mitte tõend selle kohta, et kontrollvärav tegelikult käivitus. +Need profiilid hõlmavad ainult staatilist skannimist. Need ei sertifitseeri tooteteste, +katvust, pakendamist, väliseid kontrolle ega kandidaadi täielikku väljalaske heakskiitu. +Töövoo vastuvõtmisel kasutatakse lingitud faili `config/quality/admission-policy.json` ja +`scripts/quality/admission-verdict.mjs`. Väljalaskevaatleja profiilid jäävad eraldiseisvaks; +kontrollige nende kohaldatavaid kontrolle ja kviitungeid eraldi. Allolev tekstiline +loend on viide, mitte tõend selle kohta, et kontrollvärav tegelikult käivitati. -Skriptid asuvad kataloogides `scripts/check/` (poliitika kontrollväravad) ja `scripts/quality/` (rangemaks muutmise mootor). +Skriptid asuvad kataloogides `scripts/check/` (poliitika kontrollväravad) ja `scripts/quality/` (ratchet-mootor). CI tõeallikas on `.github/workflows/ci.yml`. ### Väljalaske-PR-i kiirtee (`quality.yml`) -`.github/workflows/quality.yml` täiendab CI-d põhi-/väljalaskeharude PR-ide, kaitstud harudesse -tehtavate tõugete, käsitsi käivitamise ja ühendamisrühmade korral. PR-id kasutavad teepõhiselt filtreeritud kiirkontrolle. Püsivalt -keelatud dubleeriv koostamine eemaldati; tegelikud koostamise/pakendamise/käivitamise kontrollid jäävad CI-sse. - -| Töö | Ulatus | Blokeeriv | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `Docs Gates (fast-path)` | Dokumentatsiooni/koodi PR-id; API dokumentatsiooni viited ja kogu dokumentatsioon | Jah | -| `Fast Quality Gates` | Koodi PR-id; staatilised kontrollid, tüübikontroll, juhtpaneeli tüübikontroll, mõjutatud ühiktestid | Jah | -| `Forgotten sibling tests` | Koodi PR-id; muudetud moodulite seostamine staatiliste tarbijate ja võimalike sõsar-testidega; tünn- ja dünaamilise impordi teed esitatakse soovituslike diagnostikatena koos viidatud lubatud eranditega | **Soovituslik** | -| `Vitest (fast-path)` | Koodi PR-id; kiire vitesti komplekt | Jah | -| `Unit Tests fast-path` | Koodi PR-id; neljaks killuks jaotatud ühiktestide komplekt | Jah | -| `No new ESLint warnings` | Koodi PR-id; välistusi arvestav lintimise kaitse | Jah, sh harude puhul | -| `Merge integrity (changelog + generated skills)` | PR-id, mis pole mustandid; muudatuste logi ja genereeritud oskuste sünkroonimine | Jah, sh harude puhul | - -#### Unustatud sõsar-testide aruanne - -`npm run check:forgotten-sibling-tests` taaskasutab testimõjude kaardi aluseks olevat impordilahendajat. -Iga muudetud tootmismooduli puhul esitab see deterministlikud -`muudetud moodul/sümbol -> staatiline tarbija -> võimalik sõsar-test` ahelad, kui võimalik -test puudub tõmbetaotluse erinevustest. Markdowni kokkuvõte ja JSON-tulemus säilitatakse -töövooartefaktina `forgotten-sibling-tests`, et neid saaks enne blokeerivat kasutuselevõttu kalibreerida. - -Barrel-re-ekspordid ja dünaamilised impordid on ainult lahendamise diagnostika; need ei tekita kunagi +`.github/workflows/quality.yml` täiendab CI-d põhi-/väljalaske-PR-ide, kaitstud harudesse +tehtavate tõugete, käsitsi käivitamise ja liitmisrühmade korral. PR-id kasutavad teepõhise filtriga kiirkontrolle. Püsivalt +keelatud dubleeriv kooste eemaldati; tegelikud kooste-, pakendamis- ja käivituskontrollid jäävad CI-sse. + +| Töö | Ulatus | Blokeeriv | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `Docs Gates (fast-path)` | Dokumentatsiooni-/koodi-PR-id; API dokumentatsiooni viited ja docs-all | Jah | +| `Fast Quality Gates` | Koodi-PR-id; staatilised kontrollid, tüübikontroll, töölaua tüübikontroll, mõjutatud ühiktestid | Jah | +| `Forgotten sibling tests` | Koodi-PR-id; muudetud moodulid, mis on jälitatud staatiliste tarbijate ja võimalike sõsartestideni; barrel- ja dünaamilise impordi teed esitatakse nõuandva diagnostikana koos viidatud lubatud loendi eranditega | **Nõuandev** | +| `Vitest (fast-path)` | Koodi-PR-id; kiire vitest-komplekt | Jah | +| `Unit Tests fast-path` | Koodi-PR-id; neljaks killuks jaotatud ühiktestide komplekt | Jah | +| `No new ESLint warnings` | Koodi-PR-id; mahavaigistusi arvestav lint-kaitse | Jah, sh forkide puhul | +| `Merge integrity (changelog + generated skills)` | PR-id, mis pole mustandid; muudatuste logi ja genereeritud oskuste sünkroonimine | Jah, sh forkide puhul | + +#### Unustatud sõsartestide aruanne + +`npm run check:forgotten-sibling-tests` taaskasutab testimõju kaardi aluseks olevat impordilahendajat. +Iga muudetud tootmismooduli kohta esitab see deterministlikud +`muudetud moodul/sümbol -> staatiline tarbija -> võimalik sõsartest` ahelad, kui võimalik +test puudub pull request'i erinevustest. Markdowni kokkuvõte ja JSON-tulemus säilitatakse +töövoo artefaktina `forgotten-sibling-tests`, et neid enne blokeeriva kasutuselevõtu alustamist kalibreerida. + +Barrel-taasekspordid ja dünaamilised impordid on ainult lahendamise diagnostika; need ei tekita kunagi blokeerivat leidu. Läbivaadatud erandid asuvad failis `config/quality/forgotten-sibling-allowlist.json`. Iga kirje peab nimetama tarbija ja kandidaat- -testi, esitama konkreetse põhjenduse ning linkima GitHubi probleemi või tõmbetaotluse. Vigase vorminguga kirjed -lükatakse vaikimisi tagasi. Erandid ei saa eirata kustutatud kandidaattesti ega muudatust, mis lisab `.skip`/`.todo`; -assertide nõrgendamine ja muu varjamine jäävad sõltumatult blokeeriva +testi, esitama konkreetse põhjenduse ning viitama GitHubi probleemile või tõmbetaotlusele. Vigased kirjed +põhjustavad tõrke vaikimisi. Erandid ei saa peita kustutatud kandidaattesti ega muudatust, mis lisab `.skip`/`.todo`; +väidete nõrgendamine ja muu varjamine jäävad eraldi blokeeriva `check:test-masking` kontrollvärava vastutusalasse. ### Töö: `lint` -Käivitatakse iga `main`-haru tõmbetaotluse korral. Tõrke korral blokeerib ühendamise. - -| Skript (`npm run ...`) | Kontrollib | Blokeeriv | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | Node.js-i versioon jääb toetatud vahemikku | Jah | -| `check:cycles` | Tsüklilised impordid — kõik `src/` + `open-sse/` moodulid | Jah | -| `check:route-validation:t06` | Zod-skeemid on olemas kõigil marsruutidel (6. taseme reegel) | Jah | -| `check:any-budget:t11` | `@ts-expect-error // any` arv ei ületa eelarvet (11. taseme catraca) | Jah | -| `check:provider-consistency` | Igal teenusepakkujal failis `providers.ts` on vastav kirje failis `providerRegistry.ts` (ja vastupidi, lubatud loendi piires) | Jah | -| `check:model-lifecycle` | Kolm käsitsi hooldatavat marsruutimistabelit püsivad kooskõlas repositooriumisse talletatud elutsükli hetktõmmisega (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ei anna skoori ühelegi kasutuselt kõrvaldatud ID-le, mida `REGISTRY` saab marsruutida; iga `BUILT_IN_ALIASES`-e sihtmärk on olemas registris `REGISTRY` ja puudub kasutuselt kõrvaldatud ID-de hetktõmmisest; iga kasutuselt kõrvaldatud ID, mis on endiselt registris `REGISTRY`, suunatakse edasi või on loetletud loendis `allowedRetiredInCatalog`; ning ükski `DEFAULT_DEGRADATION_MAP`-i allikas ega sihtmärk ei ole selles hetktõmmises märgitud kasutuselt kõrvaldatuks. See ei tõesta, et aktiivne välisteenus mudelit praegu teenindab. Võrguühenduseta — võrdleb failiga `config/quality/model-lifecycle.json`, mida värskendatakse käsitsi käsuga `npm run quality:refresh-model-lifecycle` (vajab võrku; pole CI-ga ühendatud). `allowedRetiredInCatalog` on järkjärgulise vähendamise põrkmehhanism: lisa kirje ainult koos jälgimisprobleemiga. | Jah | -| `check:fetch-targets` | Iga kliendipoolses kataloogis `src/` olev `fetch("/api/...")` viib tegeliku failini `route.ts` | Jah | -| `check:deps` | Kõik repositooriumi igas failis `package.json` olevad käsuga `npm install` installitavad sõltuvused sisalduvad failis `dependency-allowlist.json`; uued fikseerimata versiooniga või kirjaveaga paketina maskeeritud sõltuvused märgistatakse | Jah | -| `audit:deps` | `npm audit` (juurkataloog + Electron) — puuduvad kõrge või kriitilise raskusastmega turvanõuanded (kattub OSV kontrolliga `check:vuln-ratchet`; vt ratsionaliseerimise ootenimekirja) | Jah | -| `check:lockfile` | Faili `package-lock.json` terviklus — HTTPS-register, terviklusräsid, hosti ülekirjutused puuduvad | Jah | -| `check:licenses` | Tootmissõltuvuste SPDX-litsentside lubatud loend | Jah | -| `check:tracked-artifacts` | Ei mingeid järgitavaid ehitusartefakte ega versioonihaldusse lisatud `node_modules`-i sümbollinke (käivitatakse ka husky pre-commit konksus; pre-push on tahtlikult kerge — #6716) | Jah | -| `check:ai-attribution` | PR-i commit'ides, pealkirjas ega sisus ei tohi olla tehisintellekti/boti `Co-Authored-By` järelkirjet ega tehisintellektiga genereerimise jalust — range reegel #16 (`quality.yml`-i kiirete kontrollide tsüklis PR→`release/**` jaoks — loeb sündmuse andmeid, väljaspool PR-e ei tee midagi — ning `ci.yml`-i lintimises ainult PR-idele mõeldud sammuna PR→`main` jaoks; samuti husky `commit-msg` konksus; inimestest kaasautorid on lubatud; #14436) | -| `check:vitest-exclusions` | Iga Vitesti välistus nimetab jälgimisprobleemi ja esineb failis `config/quality/vitest-exclusions.json` (#13204) | Jah | -| `check:file-size` | Ükski lähtefail ei ületa faililaiendipõhist piirangut (põrkmehhanism: fikseeritud suured failid loendis `frozen`) | Jah | -| `check:error-helper` | Täiturite/käsitlejate veavastused kasutavad `buildErrorBody()` / `sanitizeErrorMessage()` (range reegel #12) | Jah | -| `check:migration-numbering` | Migratsiooni SQL-failid on järjest nummerdatud, ilma lünkade ja duplikaatideta | Jah | -| `check:public-creds` | Väljaspool faili `publicCreds.ts` ei ole literaalseid OAuthi `client_id`/`client_secret` väärtusi ega Firebase Webi võtmeid (range reegel nr 11) | Jah | -| `check:db-rules` | Väljaspool `src/lib/db/` mooduleid ei ole toorest SQL-i; failist `localDb.ts` ei kasutata koondimporti (ranged reeglid nr 2 ja 5) | Jah | -| `check:known-symbols` | Dispetšertabelites registreeritud teenusepakkujate täiturid, marsruutimisstrateegiad ja tõlkijad vastavad kettal olevatele failidele — pole orvuks jäänud ega deklareerimata sümboleid | Jah | -| `check:route-guard-membership` | Iga alamprotsessi käivitav marsruut on funktsiooni `isLocalOnlyPath()` abil klassifitseeritud (ranged reeglid nr 15 ja 17) | Jah | -| `check:test-discovery` | Vähemalt üks testikäitaja kogub repositooriumist kõik `*.test.ts` / `*.spec.ts` failid (põrkmehhanism: orbfailide loend failis `test-discovery-baseline.json` saab ainult kahaneda) | Jah | -| `check:agent-skills-sync` | Genereeritud agent-skills artefaktid vastavad nende lähtekataloogile (lahknevusi pole) | -| `check:provider-asset-provenance` | Teenusepakkujate logode/varade päritolu on dokumenteeritud | -| `lint:json` | JSON-i konfiguratsioonifailid on süntaktiliselt korrektsed ja vastavad repo lintimisreeglitele | -| `typecheck:core` | TypeScripti kompileerimine vigadeta (ainult soovituslikud hoiatused) | Jah | -| `typecheck:noimplicit:core` | Range `noImplicitAny` — tulevikku suunatud; paljud olemasolevad väljakutsekohad vajavad endiselt annotatsioone | **Soovituslik** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, mille ulatus on piiratud teega `src/app/(dashboard)/**` (#7033) — `typecheck:core`-i hoolikalt valitud 27 faili lubamisloend ei sisalda ühtegi töölaua TSX-faili ning ka `next build` ei tee neile kunagi tüübikontrolli (`next.config.mjs` määrab `ignoreBuildErrors: true`), mistõttu jäid sealsete orvuks jäänud identifikaatorite regressioonid (#6625/#6909) CI-le nähtamatuks. Erinevusi võrreldakse fikseeritud faili- ja TS-koodi põhiste loendurite lähteväärtustega (`config/quality/dashboard-typecheck-baseline.json`, sama aegunud kirjete jõustamise muster nagu käsul `check:known-symbols`) — kontroll ebaõnnestub ainult siis, kui esineb lähteväärtuses fikseeritud arvust rohkem UUSI vigu; olemasoleva vea parandamisel vähenda lähteväärtust käsuga `--update`. | Jah | +Käivitatakse iga `main`-haru PR-i puhul. Tõrke korral blokeerib ühendamise. + +| Skript (`npm run ...`) | Kontrollib | Blokeeriv | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | +| `check:node-runtime` | Node.js-i versioon jääb toetatud vahemikku | Jah | +| `check:cycles` | Ringimpordid kogu kataloogis `src/` + `open-sse/` (AST-põhine, tsconfigi `paths` lahendatud). Ilma lisavalikuteta käivitamine on nõuandev ja loetleb tsüklid. `check:cycles:ratchet` (mida CI käitab) blokeerib, kui arv ületab faili `quality-baseline.json` ülempiiri `metrics.cycles` — praegu 14, `direction: down`, seega saab see ainult väheneda (#15159 G-01/G-02) | Jah (ratchet) | +| `check:route-validation:t06` | Zodi skeemide olemasolu kõigil marsruutidel (6. taseme poliitika) | Jah | +| `check:any-budget:t11` | `@ts-expect-error // any` arv ei ületa eelarvet (11. taseme catraca) | Jah | +| `check:provider-consistency` | Igal `providers.ts` failis oleval teenusepakkujal on vastav kirje failis `providerRegistry.ts` (ja vastupidi, lubatud loendi piires) | Jah | +| `check:model-lifecycle` | Kolm käsitsi hallatavat marsruutimistabelit püsivad kooskõlas repositooriumis talletatud elutsükli hetktõmmisega (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ei anna skoori ühelegi käigust kõrvaldatud ID-le, mida `REGISTRY` saab marsruutida; iga `BUILT_IN_ALIASES` sihtmärk leidub registris `REGISTRY` ja puudub käigust kõrvaldatud ID-de hetktõmmisest; iga käigust kõrvaldatud ID, mis on endiselt registris `REGISTRY`, suunatakse edasi või on loetletud loendis `allowedRetiredInCatalog`; ning ükski `DEFAULT_DEGRADATION_MAP` lähte- ega sihtüksus ei ole selles hetktõmmises märgitud käigust kõrvaldatuks. See ei tõesta, et mudelit teenindab praegu toimiv ülesvooluteenus. Võrguühenduseta — võrdleb failiga `config/quality/model-lifecycle.json`, mida värskendatakse käsitsi käsuga `npm run quality:refresh-model-lifecycle` (vajab võrku; pole CI-sse ühendatud). `allowedRetiredInCatalog` on järkjärgulise vähendamise põrkmehhanism: lisa kirje ainult koos jälgimisprobleemiga. | Jah | +| `check:fetch-targets` | Iga kliendipoolses kataloogis `src/` olev `fetch("/api/...")` viitab tegelikule failile `route.ts` | Jah | +| `check:deps` | Kõik repositooriumi igas failis `package.json` olevad käsuga `npm install` installitavad sõltuvused on loendis `dependency-allowlist.json`; uued fikseerimata versiooniga või kirjaveopettuse kahtlusega paketid märgistatakse | Jah | +| `audit:deps` | `npm audit` (juurkataloog + electron) — kõrge ega kriitilise tasemega turvahoiatusi pole (kattub OSV kontrolliga `check:vuln-ratchet`; vt ratsionaliseerimise tööjärge) | Jah | +| `check:lockfile` | Faili `package-lock.json` terviklus — HTTPS-register, terviklusräsid, hosti ülekirjutused puuduvad | Jah | +| `check:licenses` | Tootmissõltuvuste SPDX-litsentside lubatud loend | Jah | +| `check:tracked-artifacts` | Ei mingeid järgitavaid ehitusartefakte / hoidlasse lisatud `node_modules` sümbollinke (käivitatakse ka husky pre-commit-konksus; pre-push on tahtlikult kerge — #6716) | Jah | +| `check:ai-attribution` | PR-i commit'ides, pealkirjas ega sisus ei tohi olla AI/boti `Co-Authored-By` järelrida ega AI-ga genereerimise jalust — range reegel #16 (`quality.yml` kiirkontrollide tsüklis PR→`release/**` jaoks — loeb sündmuse andmestikku, väljaspool PR-e ei tee midagi — ning ainult PR-idele mõeldud sammuna `ci.yml` lintimises PR→`main` jaoks; samuti husky `commit-msg` konksus; inimestest kaasautorid on lubatud; #14436) | +| `check:vitest-exclusions` | Iga Vitesti välistus nimetab jälgimisülesande ja esineb failis `config/quality/vitest-exclusions.json` (#13204) | Jah | +| `check:file-size` | Ükski lähtekoodifail ei ületa faililaiendipõhist ülempiiri (põrkmehhanism: fikseeritud suurusega failid loendis `frozen`) | Jah | +| `check:error-helper` | Täiturite/käitlejate veavastused kasutavad funktsiooni `buildErrorBody()` / `sanitizeErrorMessage()` (range reegel #12) | Jah | +| `check:migration-numbering` | Migratsiooni SQL-failid on järjestikku nummerdatud, ilma lünkade või duplikaatideta | Jah | +| `check:public-creds` | Väljaspool faili `publicCreds.ts` ei ole literaalseid OAuthi `client_id`/`client_secret` väärtusi ega Firebase Webi võtmeid (range reegel nr 11) | Jah | +| `check:db-rules` | Väljaspool kataloogi `src/lib/db/` mooduleid ei ole töötlemata SQL-i; failist `localDb.ts` ei tehta koondimporti (ranged reeglid nr 2 / nr 5) | Jah | +| `check:known-symbols` | Teenusepakkujate täiturid, marsruutimisstrateegiad ja tõlkijad, mis on registreeritud nende väljastustabelites, vastavad kettal olevatele failidele — orvuks jäänud või deklareerimata sümboleid pole | Jah | +| `check:route-guard-membership` | Iga alamprotsessi käivitav marsruut on funktsiooni `isLocalOnlyPath()` alusel klassifitseeritud (ranged reeglid nr 15 / nr 17) | Jah | +| `check:test-discovery` | Iga repos olev fail `*.test.ts` / `*.spec.ts` kaasatakse vähemalt ühe testikäitaja poolt (põrkmehhanism: orbfailide loend failis `test-discovery-baseline.json` võib ainult kahaneda) | Jah | +| `check:agent-skills-sync` | Loodud agendioskuste artefaktid vastavad nende lähtekataloogile (lahknevusi pole) | +| `check:provider-asset-provenance` | Teenusepakkujate logodel/varadel on registreeritud päritolukirje | +| `lint:json` | JSON-i konfiguratsioonifailid on parsitavad ja vastavad hoidla lintimisreeglitele | +| `typecheck:core` | TypeScripti kompileerimine vigadeta (ainult nõuandvad hoiatused) | Jah | +| `typecheck:noimplicit:core` | Range `noImplicitAny` — tulevikku suunatud; paljud olemasolevad väljakutsed vajavad endiselt annotatsioone | **Nõuandev** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, mille ulatus on piiratud kataloogiga `src/app/(dashboard)/**` (#7033) — `typecheck:core`-i kureeritud 27 faili lubatud loend ei sisalda ühtegi dashboardi TSX-faili ning `next build` ei tee neile samuti kunagi tüübikontrolli (`next.config.mjs` määrab `ignoreBuildErrors: true`), mistõttu jäid sealsed orvuks jäänud identifikaatorite regressioonid (#6625/#6909) CI jaoks nähtamatuks. Erinevusi võrreldakse fikseeritud faili- ja TS-koodipõhise vigade arvu lähteolukorraga (`config/quality/dashboard-typecheck-baseline.json`, sama aegunud kirjete jõustamise muster nagu `check:known-symbols`-is) — kontroll ebaõnnestub ainult uute vigade korral, mis ületavad lähteolukorras määratud arvu; kui olemasolev viga parandatakse, vähendage väärtust käsuga `--update`. | Jah | ### Töö: `quality-gate` -Käivitub pärast tööd `test-coverage`. Ebaõnnestumise korral blokeerib ühendamise. +Käivitub pärast `test-coverage`-it. Ebaõnnestumise korral blokeerib ühendamise. -| Skript | Kontrollib | Blokeeriv | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `quality:collect` | Väljastab faili `quality-metrics.json` (ESLinti hoiatuste arv, katvus ühendatud osaaruandest) | Jah (ratchet'i eeltingimus) | -| `quality:ratchet` | Ükski faili `quality-baseline.json` mõõdik pole halvenenud (ESLinti hoiatusi ≤ lähtetase; katvus ≥ lähtetase) | Jah | -| `check:duplication` | Koodi dubleerimine (jscpd@4) ei ületa failis `quality-baseline.json` määratud lähtetaset | Jah | -| `check:complexity` | Failitaseme tsüklomaatiline keerukus ei ületa ülempiiri (ESLinti põhivahendid `complexity` + `max-lines-per-function`) | Jah | -| `check:cognitive-complexity` | Kognitiivse keerukuse ratchet (`eslint-plugin-sonarjs`) — eraldi ESLinti läbimine; CI käitab mõlemat ühendatult ühe sammuna `check:complexity-ratchets` | Jah | -| `check:dead-code` | Kasutamata eksporditud elementide / failide ratchet (knip) ei halvene võrreldes lähtetasemega | Jah | -| `check:compression-budget` | Tihendamise jõudlustesti eelarve — mootoripõhised tokenisäästu alampiirid ei tohi halveneda | Jah | -| `check:type-coverage` | Tüüpidega kaetuse protsendi ratchet (`type-coverage`) ei halvene; asendab suures osas kontrolli `typecheck:noimplicit:core` | Jah | -| `check:codeql-ratchet` | Avatud CodeQL-i hoiatuste arv ei halvene (loeb käsuga `gh api`; jätab tokeni puudumisel tõrgeteta vahele) — värskendamissageduse ja käsitsi käivitamise kohta vt allpool „CodeQL-i ratchet“ | Jah | +| Skript | Kontrollib | Blokeeriv | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `quality:collect` | Väljastab faili `quality-metrics.json` (ESLinti hoiatuste arv, ühendatud osaaruande põhjal arvutatud koodikate) | Jah (ratchet’i eelnev etapp) | +| `quality:ratchet` | Ükski faili `quality-baseline.json` mõõdik pole halvenenud (ESLinti hoiatusi ≤ lähtetase; koodikate ≥ lähtetase) | Jah | +| `check:duplication` | Koodi dubleerimine (jscpd@4) ei ületa failis `quality-baseline.json` määratud lähtetaset | Jah | +| `check:complexity` | Failitaseme tsüklomaatiline keerukus ei ületa ülempiiri (ESLinti põhireeglid `complexity` + `max-lines-per-function`) | Jah | +| `check:cognitive-complexity` | Kognitiivse keerukuse ratchet (`eslint-plugin-sonarjs`) — eraldi ESLinti läbimine; CI käitab mõlemat ühendatuna ühe etapina `check:complexity-ratchets` | Jah | +| `check:dead-code` | Kasutamata eksporditud elementide / failide ratchet (knip) ei halvene võrreldes lähtetasemega | Jah | +| `check:compression-budget` | Tihendamise võrdlustesti eelarve — mootoripõhised tokenisäästu alampiirid ei tohi halveneda | Jah | +| `check:type-coverage` | Tüübitud koodi osakaalu ratchet (`type-coverage`) ei halvene; asendab suures osas kontrolli `typecheck:noimplicit:core` | Jah | +| `check:codeql-ratchet` | Avatud CodeQL-i hoiatuste arv ei suurene (loeb käsuga `gh api`; tokeni puudumisel jäetakse sujuvalt vahele) — värskendamissagedus ja käsitsi käivitamine: vt allpool „CodeQL-i ratchet” | Jah | ### Töö: `quality-extended` -Kogu töö on nõuandev (`continue-on-error: true`). npm-il põhinevad ratchet'id -käivitatakse tegelikult; välised skannerid installitakse käsuga `gh release download` ja jätavad -binaarfaili jätkuva puudumise korral ise kontrolli vahele (väljumiskood 0). +Kogu töö on nõuandev (`continue-on-error: true`). npm-il põhinevad ratchet’id käivitatakse +tegelikult; välised skannerid installitakse käsuga `gh release download` ja jätavad kontrolli ise vahele (väljumiskood 0), +kui kahendfail endiselt puudub. -| Skript | Kontrollib | Blokeeriv | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `check:circular-deps` | Ringseid sõltuvusi pole (dpdm) | **Nõuandev** | -| `check:bundle-size` | Paketi suurus ei ületa ülempiiri | **Nõuandev** | -| `check:secrets` | Saladuste skannimine (gitleaks) — jäetakse binaarfaili puudumisel vahele | **Nõuandev** | -| `check:vuln-ratchet` | Sõltuvuste haavatavused (osv-scanner) ei halvene — jäetakse binaarfaili puudumisel vahele | **Nõuandev** | -| `check:workflows` | Töövoogude lintimine (actionlint + zizmor); puuduvad või katkised skannerid, vigased aruanded või puuduv ratchet'i lähtetase põhjustavad tulemuse INCOMPLETE. Leitud probleemidele rakendatakse valitud ranget/nõuandvat/ratchet'i poliitikat | Käivitamine on nõutav; zizmor'i ratchet on CI-s blokeeriv | -| `check:openapi-breaking` | Avaliku API lepingu (`openapi.yaml`) katkestavad muudatused võrreldes baasharuga (oasdiff) — väljastab `openapiBreaking=N`; jäetakse vahele, kui oasdiff puudub või põhispetsifikatsiooni ei saa lahendada | **Nõuandev** | +| Skript | Kontrollib | Blokeeriv | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | +| `check:circular-deps` | Ringikujulisi sõltuvusi pole (dpdm) | **Nõuandev** | +| `check:bundle-size` | Paketi suurus ei ületa ülempiiri | **Nõuandev** | +| `check:secrets` | Saladuste skannimine (gitleaks) — jäetakse vahele, kui kahendfail puudub | **Nõuandev** | +| `check:vuln-ratchet` | Sõltuvuste haavatavused (osv-scanner) ei halvene — jäetakse vahele, kui kahendfail puudub | **Nõuandev** | +| `check:workflows` | Töövoogude lintimine (actionlint + zizmor); puuduvad või katkised skannerid, vigased aruanded või puuduv ratchet’i lähtetase põhjustavad oleku INCOMPLETE. Kehtivate leidude puhul järgitakse valitud ranget, nõuandvat või ratchet’i poliitikat | Käivitamine on kohustuslik; zizmor’i ratchet on CI-s blokeeriv | +| `check:openapi-breaking` | Avaliku API lepingu (`openapi.yaml`) murrangulised muudatused võrreldes baasharuga (oasdiff) — väljastab `openapiBreaking=N`; jäetakse vahele, kui oasdiff puudub või baasspetsifikatsiooni ei saa lahendada | **Nõuandev** | ### Töö: `docs-sync-strict` -Käivitatakse iga harule `main` suunatud PR-i puhul. Tõrke korral blokeerib ühendamise. - -| Skript | Kontrollib | Blokeeriv | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `check:docs-all` | Metavärav, mis käitab allolevat kuut alamväravat järjestikku | Jah | -| ↳ `check:docs-sync` | CHANGELOG-i / OpenAPI / llm.txt versioonide kooskõla | Jah | -| ↳ `check:docs-counts` | Tekstis esitatud arvud (pakkujate arv, migratsioonide arv jne) jäävad tegelike arvude põrkmehhanismi lubatud vahemikku | Jah | -| ↳ `check:env-doc-sync` | Iga keskkonnamuutuja failis `.env.example` on dokumentatsiooni tabelis kirjeldatud ja vastupidi | Jah | -| ↳ `check:deprecated-versions` | Dokumentatsioonis puuduvad aegunud versioonistringid | Jah | -| ↳ `check:doc-links` | Dokumentatsiooni sisemised markdown-lingid osutavad olemasolevatele failidele (`[tekst]`/`(path)`-kujul) | Jah | -| ↳ `check:fabricated-docs` | Dokumentatsioonis viidatud marsruudid, keskkonnamuutujad, CLI-käsud, konksude nimed ja failiteed on koodibaasis olemas. Range värav lipuga `--strict`; ilma liputa pehme tõrge. | Jah (CI-s lipu `--strict` kaudu) | -| `check:cli-i18n` | CLI-käskude stringid on olemas kõigis i18n-i lokaadifailides | Jah | -| `check:openapi-coverage` | OpenAPI spetsifikatsioon hõlmab vähemalt põrkmehhanismiga määratud miinimumarvu tegelikke marsruute | Jah | -| `check:openapi-security-tiers` | Turbetaseme annotatsioonid failis `openapi.yaml` on kooskõlas faili `routeGuard.ts` klassifikatsioonidega | **Nõuandev** | -| `check:openapi-routes` | Iga faili `openapi.yaml` tee vastab tegelikule failile `route.ts` (hallutsinatsioonivastane kontroll) | Jah | -| `check:docs-symbols` | Iga viide `/api/...` failides `docs/**/*.md` vastab tegelikule failile `route.ts` (hallutsinatsioonivastane kontroll) | Jah | -| `i18n translation drift` | Tõlkimata võtmed i18n-i lokaadifailides — ainult hoiatus | **Nõuandev** | +Käivitatakse iga `main`-harule suunatud PR-i puhul. Tõrke korral blokeerib ühendamise. + +| Skript | Kontrollib | Blokeeriv | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `check:docs-all` | Metavärav, mis käitab alltoodud 6 alamväravat järjest | Jah | +| ↳ `check:docs-sync` | CHANGELOG-i / OpenAPI / llm.txt-i versioonide kooskõla | Jah | +| ↳ `check:docs-counts` | Proosas esitatud arvud (pakkujate arv, migratsioonide arv jne) jäävad tegelike arvude põrkmehhanismiga määratud vahemikku | Jah | +| ↳ `check:env-doc-sync` | Iga keskkonnamuutuja failis `.env.example` on dokumentatsiooni tabelis dokumenteeritud ja vastupidi | Jah | +| ↳ `check:deprecated-versions` | Dokumentatsioonis puuduvad aegunud versioonistringid | Jah | +| ↳ `check:doc-links` | Dokumentatsiooni sisemised markdown-lingid viitavad olemasolevatele failidele (`[text]`/`(path)` vormingus) | Jah | +| ↳ `check:fabricated-docs` | Dokumentatsioonis nimetatud marsruudid, keskkonnamuutujad, CLI-käsud, konksude nimed ja failiteed on koodibaasis olemas. Range värav lipuga `--strict`; ilma liputa lubatakse tõrget. | Jah (CI-s lipuga `--strict`) | +| `check:cli-i18n` | CLI-käskude stringid on olemas kõigis i18n-i lokaadifailides | Jah | +| `check:openapi-coverage` | OpenAPI spetsifikatsioon katab vähemalt põrkmehhanismiga määratud minimaalse arvu tegelikke marsruute | Jah | +| `check:openapi-security-tiers` | Turbetasemete annotatsioonid failis `openapi.yaml` on kooskõlas faili `routeGuard.ts` klassifikatsioonidega | **Soovituslik** | +| `check:openapi-routes` | Iga faili `openapi.yaml` tee viitab olemasolevale failile `route.ts` (hallutsinatsioonivastane kontroll) | Jah | +| `check:docs-symbols` | Iga viide kujul `/api/...` failides `docs/**/*.md` viitab olemasolevale failile `route.ts` (hallutsinatsioonivastane kontroll) | Jah | +| `i18n translation drift` | Tõlkimata võtmed i18n-i lokaadifailides — ainult hoiatus | **Soovituslik** | ### Töö: `i18n-ui-coverage` -| Skript | Kontrollib | Blokeeriv | -| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `check-ui-keys-coverage` (tekstisisene) | Kasutajaliidese i18n-i võtmete kaetus on ≥ 65% | Jah | -| `check-ui-value-drift` (tekstisisene) | Ümber kirjutatud ingliskeelne **väärtus** ei jäta endast maha aegunud tõlget | Jah | -| `check-new-key-coverage` (tekstisisene) | **Uus** ingliskeelne võti on tõlgitud igas lokaadis — marker `__MISSING__:` lükatakse tagasi | Jah | -| `check-translation-ratio` | Tegelike tõlgete suhtarv lokaadi kohta (ingliskeelsega identsed / kohatäitega / puuduvad lõppvõtmed väljaspool lubatud loendit) ei tohi ületada faili `config/quality/i18n-translation-baseline.json` väärtust koos lõtkuga | **Nõuandev** | +| Skript | Kontrollib | Blokeeriv | +| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | +| `check-ui-keys-coverage` (tekstisisene) | Kasutajaliidese i18n-võtmete katvus on ≥ 65% | Jah | +| `check-ui-value-drift` (tekstisisene) | Ümber kirjutatud ingliskeelne **väärtus** ei jäta maha aegunud tõlget | Jah | +| `check-new-key-coverage` (tekstisisene) | **Uus** ingliskeelne võti on tõlgitud igas lokaadis — marker `__MISSING__:` lükatakse tagasi | Jah | +| `check-translation-ratio` | Tegelike tõlgete suhe lokaadi kohta (ingliskeelsega identsed / kohatäite / puuduvad lõppvõtmed väljaspool lubatute loendit) ei tohi ületada faili `config/quality/i18n-translation-baseline.json` väärtust koos lubatud varuga | **Soovituslik** | -Vajab `fetch-depth: 0` — väärtuste triivi värav võrdleb faili `en.json` ühendamise lähtepunktiga. +Vajab sätet `fetch-depth: 0` — väärtuste triivi värav võrdleb faili `en.json` ühendamise lähtepunktiga. #### `check-ui-value-drift` — aegunud tõlgete värav -Tuvastab ühe i18n-i regressiooni, mida teised väravad struktuurselt tuvastada ei suuda: ingliskeelne väärtus +Tuvastab ühe i18n-i regressiooni, mida teised väravad struktuurselt ei näe: ingliskeelne väärtus kirjutatakse ümber, kuid _eelmisest_ ingliskeelsest tekstist tuletatud tõlked jäävad alles, mistõttu muukeelsed kasutajad loevad jätkuvalt enesekindlas sõnastuses, kuid nüüdseks valet teksti. -See jõudis päriselt väljalaskesse. `oauthModal.googleOAuthWarning` kirjutati ümber, kui lisati Antigravity -sisselogimisabiline (#5203); **39 lokaadis 43-st** jäi alles tekst, mis käskis operaatoritel „kopeerida -täielik URL ja kleepida see allapoole” — töövoog, mida selle pakkuja puhul ei saa lõpule viia. See jäi -kuni #8463-ni märkamata, sest: +See jõudis päriselt väljalaskesse. `oauthModal.googleOAuthWarning` kirjutati ümber, kui lisati +Antigravity sisselogimisabiline (#5203); **39 lokaati 43-st** säilitasid teksti, mis käskis operaatoritel +„kopeerida täielik URL ja kleepida see allapoole” — selle pakkuja puhul ei saa seda voogu lõpule viia. +Probleemi ei märgatud enne #8463, sest: -- `sync-ui-keys` lisab ainult võtmed, mis **puuduvad**, mitte neid, mis on **aegunud**; +- `sync-ui-keys` lisab tagantjärele ainult **puuduvad** võtmed, mitte kunagi **aegunud** võtmeid; - `check-ui-keys-coverage` loendab võtme _olemasolu_, seega läheb aegunud tõlge arvesse kaetuna; -- `check-translation-drift` jälgib dokumentatsiooni peegelkoopiaid `docs/i18n//**.md` — - see ei loe kunagi faile `src/i18n/messages/*.json`. Blokeeriv töös `docs-sync-strict` alates - 2026-09 uuesti sünkroonimisest: muuda põhidokumenti → `npm run i18n:run -- --files=` (jaotisepõhine, odav). +- `check-translation-drift` jälgib dokumentatsiooni peegelkoopiaid asukohas `docs/i18n//**.md` — + see ei loe kunagi faile `src/i18n/messages/*.json`. Töö `docs-sync-strict` blokeerib alates + 2026-09 uuesti sünkroonimisest: põhiteabe dokumendi muutmisel käita `npm run i18n:run -- --files=` (jaotisepõhine, kiire). -**Muudatusteadlik, mitte lähtetasemel põhinev.** See võrdleb ühendamisbaasi faili `en.json` +**Muudatuste erinevust arvestav, mitte etalonil põhinev.** See võrdleb liitmislähte `en.json`-i tööpuuga; iga võtme puhul, mille ingliskeelne väärtus muutus, loetakse aegunuks kõik lokaadid, -milles on endiselt muutmata tõlge. See **külmutab tahtlikult olemasoleva võla** — diff ei suuda -näidata, millisest vanast ingliskeelsest tekstist pärineb kaua kasutusel olnud tõlge, seega hindab -kontroll ainult seda, mida praegune muudatus puudutab. Alternatiiv (võtmepõhine räsi lähtetase) -nõuaks umbes 600 KB suurust genereeritud faili, mis on suurimast olemasolevast lähtetasemest -kolm korda suurem ja muutuks iga i18n-i PR-iga. +kus on endiselt muutmata tõlge. See **külmutab tahtlikult olemasoleva võla** — muudatuste +erinevusest ei saa tuvastada, millisest varasemast ingliskeelsest tekstist ammu olemas olnud +tõlge pärineb, seega kontroll hindab ainult seda, mida praegune muudatus puudutab. Alternatiiv +(võtmepõhine räsi-etalon) nõuaks ligikaudu 600 KB suurust genereeritud faili, mis oleks +suurimast olemasolevast etalonist kolm korda suurem ja muutuks iga i18n-i PR-iga. Kontrolli läbimiseks on kaks võimalust: 1. värskendada mõjutatud tõlkeid või -2. määrata nende väärtuseks `__MISSING__:` — käituskeskkond tagastab siis parandatud - ingliskeelse teksti (`src/i18n/request.ts::deepMergeFallback`, #7258) ja võti lisatakse tõlkejärjekorda. +2. määrata nende väärtuseks `__MISSING__:` — käituskeskkond väljastab seejärel + parandatud ingliskeelse teksti (`src/i18n/request.ts::deepMergeFallback`, #7258) ja võti + lisatakse tõlkejärjekorda. Kui stringi **tähendus** muutus, eelista **võtme ümbernimetamist**: uus võti ei saa pärida aegunud tõlget. Seda mustrit kasutati muudatuses #8463. @@ -233,48 +233,48 @@ npm run i18n:check-value-drift:warn # ainult aruanne BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Lõpetab koodiga 0 ja väljundiga `SKIP reason=base-unresolved`, kui baaskataloogi ei saa lugeda -(pinnapealne kloon ilma baasviiteta), järgides kontrolli `check-openapi-breaking` käitumist. +Kui aluskataloogi ei saa lugeda (pinnapealne kloon ilma alusviiteta), lõpetab olekukoodiga 0 +ja väljundiga `SKIP reason=base-unresolved`, järgides `check-openapi-breaking` käitumist. ### Töö: `i18n` -Täielik i18n-i valideerimismaatriks (üks töö iga lokaadi kohta). Kogu töö on nõuandev. +Täielik i18n-i valideerimismaatriks (üks töö lokaadi kohta). Kogu töö on nõuandev. -| Skript | Valideerib | Blokeeriv | -| ------------------------------- | ------------------------------ | ------------------------------------------------------- | -| `validate_translation.py quick` | Tõlke täielikkus lokaadi kaupa | **Nõuandev** (`continue-on-error: true` kogu töö puhul) | +| Skript | Valideerib | Blokeeriv | +| ------------------------------- | ------------------------------- | ------------------------------------------------------- | +| `validate_translation.py quick` | Tõlke täielikkust lokaadi kaupa | **Nõuandev** (`continue-on-error: true` kogu töö puhul) | ### Töö: `pr-test-policy` Käivitatakse ainult tõmbetaotluste puhul. -| Skript | Valideerib | Blokeeriv | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | -| `check:pr-test-policy` | PR-id, mis muudavad tootmiskoodi kataloogides `src/`, `open-sse/`, `electron/` või `bin/`, peavad lisama või värskendama teste (range reegel nr 8) | Jah | -| `check:test-masking` | Muudetud testifailid ei vähenda kontrolllausete netoarvu ega lisa tautoloogiaid `assert.ok(true)` | Jah | -| `check:pr-evidence` | PR-i kirjeldus viitab muudatuse testi-/VPS-tõenditele (automatiseerib range reegli nr 18, otsides vasteid PR-i tekstist — habras, vt tegemata tööde loendit) | Jah | +| Skript | Valideerib | Blokeeriv | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------- | +| `check:pr-test-policy` | PR-id, mis muudavad tootmiskoodi kaustades `src/`, `open-sse/`, `electron/` või `bin/`, peavad lisama või uuendama teste (range reegel nr 8) | Jah | +| `check:test-masking` | Muudetud testifailid ei vähenda kontrollväidete netoarvu ega lisa tautoloogiaid `assert.ok(true)` | Jah | +| `check:pr-evidence` | PR-i kirjeldus viitab muudatuse testi-/VPS-tõenditele (automatiseerib range reegli nr 18, otsides vasteid PR-i tekstist — habras, vt tööjärge) | Jah | ### Töö: `test-vitest` -Käivitatakse pärast tööd `build`. Tõrke korral blokeerib ühendamise. +Käivitatakse pärast tööd `build`. Ebaõnnestumise korral blokeerib liitmise. -| Testikomplekt | Valideerib | Blokeeriv | +| Testikogum | Valideerib | Blokeeriv | | ---------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | `test:vitest` | MCP-server (110 tööriista), autoCombo, vahemälu — vitesti testikäitaja | Jah | | `test:vitest:ui` | Kasutajaliidese komponenditestid — vitesti testikäitaja | **Blokeeriv** — olemasolevad tõrked on failis `vitest.config.ts` sõnaselgelt välistatud; uued tõrked nurjavad töö | -### Igaöised töövood (ajastatud, nõuandvad) +### Öised töövood (ajakava alusel, nõuandvad) -Need käivitatakse croni ajakava alusel (ja käsuga `workflow_dispatch`), mitte kunagi PR-ide puhul. Kõik on nõuandvad. +Need käivitatakse cron-ajakava alusel (ja sündmusega `workflow_dispatch`), mitte kunagi PR-ide puhul. Kõik on nõuandvad. -| Töövoog | Valideerib | Blokeeriv | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | -| `nightly-property` | fast-checki omaduspõhised testid juhusliku algväärtuse ja suure käituskordade arvuga | **Nõuandev** | -| `nightly-resilience` | mälukuhja kasvu kontroll, kaosepõhine tõrgete sisestamine, k6 koormus-/kestustestid | **Nõuandev** | -| `nightly-llm-security` | promptfoo sisestusründe kaitse (blokeerimisrežiim) + garaki sondid (teenusepakkuja saladuse puudumisel jäetakse vahele) | **Nõuandev** | -| `nightly-schemathesis` | OpenAPI lepingu hägustestimine (schemathesis) töötava OmniRoute'i suhtes, kasutades faili `docs/openapi.yaml` — toob esile spetsifikatsioonirikkumised / töötlemata 500-vead (etapp 8 B.4) | **Nõuandev** | -| `nightly-mutation` | Strykeri mutatsioonitestimise skoor kiirete ühiktestide harus — ellujäänud mutandid toovad esile nõrgad kontrolllaused | **Nõuandev** | -| `nightly-compat` | Node'i mootori ühilduvusmaatriks kõigis toetatud `engines.node` vahemikes | **Nõuandev** | +| Töövoog | Valideerib | Blokeeriv | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | fast-checki omaduspõhised testid juhusliku seemne ja suure käivituskordade arvuga | **Nõuandev** | +| `nightly-resilience` | kuhjamälu kasvu kontroll, kaosepõhine tõrgete sisestamine, k6 koormus-/kestustestid | **Nõuandev** | +| `nightly-llm-security` | promptfoo sisestusrünnete kaitse (blokeerimisrežiim) + garaki sondid (jäetakse teenusepakkuja saladuse puudumisel vahele) | **Nõuandev** | +| `nightly-schemathesis` | OpenAPI lepingu hägustestimine (schemathesis) töötava OmniRoute'i vastu, kasutades faili `docs/openapi.yaml` — toob esile spetsifikatsioonirikkumised / töötlemata 500-vead (etapp 8 B.4) | **Nõuandev** | +| `nightly-mutation` | Strykeri mutatsioonitestimise skoor kiirete ühiktestide harus — ellujäänud mutandid toovad esile nõrgad kontrollväited | **Nõuandev** | +| `nightly-compat` | Node'i mootori ühilduvusmaatriks toetatud `engines.node` vahemikes | **Nõuandev** | --- @@ -536,43 +536,43 @@ automaatselt (MCP↔LSP silla valite ja kontrollite teie); vigane kirje logib ai --- -## Ratsionaliseerimise tööjärg (ROI ülevaatus — 9. etapp, 3. laine) +## Ratsionaliseerimise mahajäämus (ROI ülevaatus — 9. etapp, 3. laine) See inventuur viidi 2026-06-17 vastavusse failiga `ci.yml` (eelmisest versioonist puudusid `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Kooskõlastatud komplekti ROI ülevaatus -tuvastas järgmised ratsionaliseerimise kandidaadid. **Liitmised on mehaanilised CI -muudatused; jõustamised/eemaldamised on operaatorile jäetud poliitikaotsused.** Midagi -alltoodust ei ole veel rakendatud. +`check:codeql-ratchet`, `check:pr-evidence`). Kooskõlastatud kogumi ROI ülevaatus +tuvastas järgmised ratsionaliseerimise kandidaadid. **Ühendamised on mehaanilised CI +muudatused; ümberlülitamised/eemaldamised on käitaja otsustada olevad poliitikavalikud.** Midagi alltoodust +pole veel rakendatud. -**Eespool samuti dokumenteerimata** (nõuandev, nõrk signaal): töö `docs-lint` +**Ülalpool on dokumenteerimata ka** (soovituslik, madala signaaliga): töö `docs-lint` (markdownlint + Vale, kogu tööl `continue-on-error`) ja eraldiseisvad skanneri töövood `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` asub failis -`quality-baseline.json`, kuid pole failis `ci.yml` seotud blokeeriva regressioonilävendiga — mõõdik on +`quality-baseline.json`, kuid pole failis `ci.yml` ühendatud blokeeriva põrkmehhanismiga — mõõdik on praegu orvuks jäänud. -### Liitmine / dubleerimise eemaldamine (mehaaniline, väiksem risk) +### Ühendamine / dubleerimise eemaldamine (mehaaniline, väiksem risk) -Iga kandidaati kontrolliti 2026-06-17 aktiivsete kontrollväravate oleku suhtes (usalda, aga kontrolli); -mitu „ilmset” liitmist peitsid tegelikult võlga ega ole **puhtad** asendused. +Iga kandidaati kontrolliti 2026-06-17 aktiivse kontrollvärava oleku suhtes (usalda, kuid kontrolli); +mitu „ilmselget“ ühendamist osutusid varjatud võlga sisaldavaks ega ole **puhtad** asendused. -- **`check:docs-sync` käivitub kaks korda** — eraldiseisvana töös `lint` ning uuesti `check:docs-all` (`docs-sync-strict`) sees ja husky commit'i-eelses konksus. ✅ **TEHTUD** — eraldiseisev käivitus tööst `lint` eemaldatud. -- **CVE skannimine** — ❌ **EI OLE puhas liitmine.** `audit:deps` nurjub rangelt iga kõrge/kriitilise CVE korral; `check:vuln-ratchet` (osv) nurjub ainult võrreldes baasjoonega toimunud _regressiooni_ korral (praegu 1 MODERATE). Semantika on erinev — `audit:deps` eemaldamine kaotaks absoluutse kõrge/kriitilise taseme kontrollvärava. Säilitada mõlemad. -- **Tsüklite tuvastamine** — ❌ **EI OLE puhas liitmine.** `check:circular-deps` (dpdm) raporteerib **91 tsüklit** (seetõttu on see nõuandev); seda ei saa enne nende lahendamist blokeerivaks muuta ning selle ulatus on laiem kui edukalt läbival, kureeritud kontrollil `check:cycles`. Säilitada `check:cycles` blokeerivana; 91 dpdm-tsükli lahendamine on eraldi tööjärje üksus. -- **Keerukus** — ✅ **TEHTUD** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): üks ESLint-i läbikäik, loendamine `ruleId` järgi, et tsüklomaatilise keerukuse + max-lines ja kognitiivse keerukuse baasjooned jääksid sõltumatuks; eraldiseisvad `check:complexity` / `check:cognitive-complexity` säilivad kohalikuks käivitamiseks võtmega `--update`. -- **`/api` hallutsineerimisvastane kontroll** — ✅ **TEHTUD** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): üks faili `src/app/api` failisüsteemi inventuur, openapi-routes + docs-symbols raporteerivad endiselt sõltumatult; eraldiseisvad kontrollid säilivad kohalikuks käivitamiseks. -- **`check:node-runtime` käivitub 11 töös** — ⚠️ **madal ROI.** Igaüks töötab eraldi täituris ja kontroll võtab <1 s; kogusääst on ~10 s, kuid selle hinnaks oleks odava tööpõhise kaitse kaotamine. Pole muudatustest tingitud vaeva väärt. -- **`typecheck:noimplicit:core` CI lintimisel** — ✅ **lintimise tööst eemaldatud** (oli nõuandev valikuga `continue-on-error`); blokeeriva tüübipinna moodustavad `typecheck:core` + `check:type-coverage`. Kohalik skript säilitati. +- **`check:docs-sync` käivitub kaks korda** — eraldiseisvalt töös `lint` ning uuesti `check:docs-all` (`docs-sync-strict`) sees ja husky commit'i-eelses konksus. ✅ **TEHTUD** — eraldiseisev `lint`-käivitus eemaldatud. +- **CVE-skannimine** — ❌ **EI OLE puhas ühendamine.** `audit:deps` nurjub kohe iga kõrge/kriitilise CVE korral; `check:vuln-ratchet` (osv) nurjub ainult baasjoonega võrreldes toimunud _regressiooni_ korral (praegu 1 MODERATE). Semantika on erinev — `audit:deps` eemaldamine kaotaks absoluutse kõrge/kriitilise taseme kontrollvärava. Säilitage mõlemad. +- **Tsüklite tuvastamine** — ✅ **TEHTUD** (#15159 G-01/G-02). Siinne vana tekst nimetas `check:cycles` kontrolli „roheliseks, kureeritud“ kontrollväravaks ja põhjendas selle blokeerivana hoidmist sellega, et `check:circular-deps` (dpdm) tuvastas 91 tsüklit. See roheline tulemus oli **valepositiivne roheline**: `check:cycles` skannis 5 alamkataloogi (450 faili), sobitas ainult staatilisi `import|export … from` konstruktsioone ning jättis välja kõik `@/` ja `@omniroute/open-sse/` spetsifikaatorid, mistõttu ei suutnud see näha dünaamilise impordi ja aliase tsükleid, mis repositooriumis domineerisid. Parandatud: kontrollvärav läbib nüüd kataloogid `src` + `open-sse` (5023 faili), kogub spetsifikaatorid TypeScripti AST-st (seega läheb `import("…")` arvesse, kuid tüübipositsioonis `typeof import("…")` mitte) ning lahendab tsconfigi `paths`-väärtused. See leiab **14** tsüklit, mitte 0. Kuna 14 olemasolevat tsüklit ei saa kontrollvärava PR-is parandada, on `check:cycles` nüüd **põrkmehhanism** (`--ratchet`, ülempiir `metrics.cycles.value = 14` failis `quality-baseline.json`, `direction: down`) — see blokeerib iga _regressiooni_ ja arv saab ainult väheneda. CI käivitab `npm run check:cycles:ratchet`. Vähendamine toimub koos üksusega **A-01**. `check:circular-deps` (dpdm) jääb laiema teise arvamusena soovituslikuks. +- **Keerukus** — ✅ **TEHTUD** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): üks ESLinti läbimine, loendamine `ruleId` järgi, et tsüklomaatilise keerukuse + maksimaalse ridade arvu ja kognitiivse keerukuse baasjooned püsiksid sõltumatuna; eraldiseisvad `check:complexity` / `check:cognitive-complexity` säilivad kohaliku `--update` jaoks. +- **`/api` hallutsinatsioonivastane kontroll** — ✅ **TEHTUD** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): üks `src/app/api` failisüsteemi inventuur, openapi-routes + docs-symbols annavad endiselt aru sõltumatult; eraldiseisvad kontrollid säilivad kohalikeks käivitusteks. +- **`check:node-runtime` käivitub 11 töös** — ⚠️ **madal ROI.** Igaüks kasutab eraldi käitajat ja kontroll võtab <1 s; kogusääst ~10 s, kuid selle hinnaks oleks odava tööpõhise kaitse kaotamine. Muudatuste vaeva ei väärt. +- **`typecheck:noimplicit:core` CI lintimisel** — ✅ **lint-tööst eemaldatud** (oli soovituslik `continue-on-error`); blokeeriv tüübipind on `typecheck:core` + `check:type-coverage`. Kohalik skript säilitati. -### Jõustamine / otsustamine (operaatori poliitika) +### Ümberlülitamine / otsustamine (käitaja poliitika) -- `check:openapi-security-tiers` (nõuandev) — ❌ **EI OLE puhtalt jõustatav.** See lõpetab koodiga 0, kuid hoiatab, et mitmel `traffic-inspector` marsruudil loendis `LOCAL_ONLY_API_PREFIXES` puudub annotatsioon `x-loopback-only: true`. Selle jõustamiseks tuleb need annotatsioonid esmalt faili `openapi.yaml` lisada. -- `typecheck:noimplicit:core` (nõuandev) — blokeeriv regressioonilävend `check:type-coverage` katab selle suures osas. Muuta regressioonilävendiks või eemaldada üleliigne teine `tsc` läbimine. -- `test:vitest:ui` (nüüd **blokeeriv**) — olemasolevad nurjumised on failis `vitest.config.ts` sõnaselgelt välistatud jälgimiskommentaaridega `// #8618`; uued nurjumised põhjustavad töö nurjumise. -- `check:secrets` (gitleaks, blokeeriv regressioonilävend, mis on fikseeritud 3 dokumenteeritud valepositiivse leiu juures) — lisada need 3 lubatud loendisse, et jõuda 0-ni, või muuta kontroll nõuandvaks. Kattub GitHubi sisseehitatud saladuste skannimisega + `check:public-creds`. -- `check:pr-evidence` (blokeeriv, otsib PR-i kirjelduse proosast vasteid) — suur valepositiivsete tulemuste risk; selle eemaldamine nõrgendab range reegli nr 18 jõustamist, seega on see tegelik poliitikaotsus. -- `semgrep` (nõuandev eraldiseisev kontroll) — kattub OWASP-i kategooriate puhul CodeQL-iga; siduda selle baasjoon regressioonilävendiga või eemaldada. +- `check:openapi-security-tiers` (soovituslik) — ❌ **EI OLE puhtalt ümberlülitatav.** See lõpetab koodiga 0, kuid hoiatab, et mitmel `traffic-inspector` marsruudil jaotises `LOCAL_ONLY_API_PREFIXES` puudub annotatsioon `x-loopback-only: true`. Selle jõustamiseks tuleb esmalt lisada need annotatsioonid faili `openapi.yaml`. +- `typecheck:noimplicit:core` (soovituslik) — blokeeriv `check:type-coverage` põrkmehhanism katab seda suuresti. Muutke see põrkmehhanismiks või eemaldage üleliigne teine `tsc` läbimine. +- `test:vitest:ui` (nüüd **blokeeriv**) — olemasolevad tõrked on failis `vitest.config.ts` selgesõnaliselt välistatud jälgimiskommentaaridega `// #8618`; uued tõrked nurjavad töö. +- `check:secrets` (gitleaks, blokeeriv põrkmehhanism, mis on külmutatud 3 dokumenteeritud valepositiivse tulemuse juures) — lisage need 3 lubatud loendisse, et jõuda nullini, või alandage kontroll soovituslikuks. Kattub GitHubi sisseehitatud saladuste skannimisega + `check:public-creds`. +- `check:pr-evidence` (blokeeriv, otsib PR-i kirjeldusest teksti) — suur valepositiivsete tulemuste risk; eemaldamine nõrgendaks range reegli nr 18 jõustamist, seega on see tõeline poliitikaotsus. +- `semgrep` (soovituslik eraldiseisev kontroll) — kattub OWASP-i kategooriate puhul CodeQL-iga; ühendage selle baasjoon põrkmehhanismiga või eemaldage. --- diff --git a/docs/i18n/fa/CONTRIBUTING.md b/docs/i18n/fa/CONTRIBUTING.md index ab74e21fd0b..e1efa898da3 100644 --- a/docs/i18n/fa/CONTRIBUTING.md +++ b/docs/i18n/fa/CONTRIBUTING.md @@ -388,16 +388,16 @@ docs/ # Documentation - [ ] بررسی Lint با موفقیت انجام میشود (`npm run lint`) - [ ] Build با موفقیت انجام میشود (`npm run build`) - [ ] نوعهای TypeScript برای توابع و رابطهای عمومی جدید اضافه شدهاند -- [ ] هیچ secret یا مقدار fallback بهصورت hardcoded وجود ندارد -- [ ] اطلاعات احراز هویت عمومی upstream از طریق `resolvePublicCred()` تعبیه شدهاند (نگاه کنید به [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) و هرگز بهصورت مقادیر literal نیستند -- [ ] پاسخهای خطا از طریق `buildErrorBody()` / `sanitizeErrorMessage()` هدایت میشوند — هیچ stack trace خامی در بدنه پاسخها وجود ندارد (نگاه کنید به [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] فرمانهای Shell (`exec` / `spawn`) مقادیر زمان اجرا را از طریق `env` ارسال میکنند، نه از طریق string interpolation +- [ ] هیچ مقدار محرمانه یا مقدار جایگزینی بهصورت hardcoded وجود ندارد +- [ ] اطلاعات احراز هویت عمومی upstream از طریق `resolvePublicCred()` تعبیه شدهاند (به [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) مراجعه کنید) و هرگز بهصورت literal درج نشدهاند +- [ ] پاسخهای خطا از طریق `buildErrorBody()` / `sanitizeErrorMessage()` پردازش میشوند — هیچ stack trace خامی در بدنه پاسخها وجود ندارد (به [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) مراجعه کنید) +- [ ] فرمانهای Shell (`exec` / `spawn`) مقادیر زمان اجرا را از طریق `env` ارسال میکنند، نه از طریق درونیابی رشتهای - [ ] همه ورودیها با schemaهای Zod اعتبارسنجی شدهاند -- [ ] برای تغییرات قابل مشاهده توسط کاربر، **fragment** مربوط به Changelog در مسیر `changelog.d/{features|fixes|maintenance}/-.md` اضافه شده است (نگاه کنید به [`changelog.d/README.md`](./changelog.d/README.md)) — فایل `CHANGELOG.md` را مستقیماً ویرایش **نکنید**؛ fragmentها هنگام انتشار تجمیع میشوند و هرگز میان PRها تداخل ایجاد نمیکنند +- [ ] برای تغییرات قابل مشاهده برای کاربر، یک **قطعه** Changelog در مسیر `changelog.d/{features|fixes|maintenance}/-.md` اضافه شده است (به [`changelog.d/README.md`](./changelog.d/README.md) مراجعه کنید) — فایل `CHANGELOG.md` را مستقیماً ویرایش **نکنید**؛ قطعهها هنگام انتشار تجمیع میشوند و هرگز میان PRها تداخل ایجاد نمیکنند - [ ] مستندات بهروزرسانی شدهاند (در صورت نیاز) -- [ ] هیچ هشدار جدیدی از CodeQL / Secret-Scanning ایجاد نشده است، یا هر مورد با توجیه فنی و ارجاع به سند مرتبط در `docs/security/` رد شده است -- [ ] مسیرهایی که فرایندهای فرزند ایجاد میکنند (`/api/mcp/`، `/api/cli-tools/runtime/`) در `src/server/authz/routeGuard.ts` بهعنوان `isLocalOnlyPath()` طبقهبندی شدهاند — نگاه کنید به [قانون قطعی شماره ۱۵](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] هیچ trailer از نوع `Co-Authored-By` در پیامهای commit وجود ندارد — commitها باید صرفاً تحت هویت Git مالک repository ثبت شوند (قانون قطعی شماره ۱۶) +- [ ] هیچ هشدار جدید CodeQL / Secret-Scanning ایجاد نشده است، یا هر هشدار با توجیه فنی و ارجاع به سند مرتبط در `docs/security/` رد شده است +- [ ] مسیرهایی که فرایندهای فرزند ایجاد میکنند (`/api/mcp/`، `/api/cli-tools/runtime/`) در `src/server/authz/routeGuard.ts` بهعنوان `isLocalOnlyPath()` طبقهبندی شدهاند — به [قانون سختگیرانه شماره ۱۵](docs/security/ROUTE_GUARD_TIERS.md) مراجعه کنید +- [ ] هیچ trailer از نوع `Co-authored-by` برای AI/bot در پیامهای commit وجود ندارد (قانون سختگیرانه شماره ۱۶) — از همکاران انسانی که از کارشان دوباره استفاده شده است، با trailerهای استاندارد `Co-authored-by: Name ` قدردانی میشود --- diff --git a/docs/i18n/fa/docs/architecture/QUALITY_GATES.md b/docs/i18n/fa/docs/architecture/QUALITY_GATES.md index 33a51dd23b0..516d10d706a 100644 --- a/docs/i18n/fa/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/fa/docs/architecture/QUALITY_GATES.md @@ -17,121 +17,117 @@ ## موجودی گیتها و پروفایلهای اجرا -### پذیرش کاندیدا - -گردشکارهای CI و Quality Gates هرکدام یک نتیجهٔ پایدار منتشر میکنند: `Gate / CI` و -`Gate / Quality`. سیاست پذیرش نسخهبندیشدهٔ آنها، تمام jobهای بالادستی را بهعنوان -الزامی یا توصیهای فهرست میکند. یک job الزامی و قابلاعمال باید با موفقیت اجرا شود: -نتایج مفقود، لغوشده، ردشده، در انتظار و ناشناخته نمیتوانند وضعیت PASS را اثبات کنند. -یک طبقهبندی معتبرِ صرفاً مستندات یا صرفاً کاتالوگ میتواند یک مسیر کد را غیرقابلاعمال -کند؛ یک PR پیشنویس، کاندیدای پذیرفتهشده نیست. برچسب `hotfix` الزام ارائهٔ شواهد را -لغو نمیکند. - -هر دو گردشکار، PRها و pushها به شاخههای main/release، اجرای دستی و رویدادهای -merge-group را پوشش میدهند. push، dispatch و merge-group مجموعهٔ کامل را اجرا -میکنند. forkها و merge groupها برای jobهایی که در حالت عادی runnerهای self-hosted -را انتخاب میکنند، از runnerهای میزبانیشده استفاده میکنند؛ پیش از عرضه باید از -کافیبودن ظرفیت میزبانیشده اطمینان حاصل شود. - -هر رسید JSON، SHA مربوط به checkout، اجرای گردشکار و تلاش را مشخص میکند. -CLI ناهماهنگی میان SHA مربوط به checkout/event را رد میکند. آزمونهای گردشکار، -عضویت در سیاست را به فهرست `needs` مربوط به job نتیجه متصل میکنند تا یک مسیر جدید -یا حذفشده نتواند بیسروصدا ناپدید شود. رسیدها گردشکار خود را پوشش میدهند، نه -انتشار، استقرار یا سازوکارهای داخلی یک اسکنر توصیهای موجود را. فعالسازی هر دو نام -بررسی در قوانین شاخه، یک تغییر مدیریتی جداگانه است؛ افزودن این jobها بهخودیخود از -یک شاخه محافظت نمیکند. +### پذیرش نامزد + +گردشکارهای CI و Quality Gates هرکدام یک نتیجه پایدار منتشر میکنند: `Gate / CI` و +`Gate / Quality`. خطمشی پذیرش نسخهبندیشده آنها، همه jobهای بالادستی را بهعنوان +الزامی یا مشورتی فهرست میکند. هر job الزامیِ قابلاعمال باید با موفقیت اجرا شود: +نتایج مفقود، لغوشده، ردشده، در انتظار و ناشناخته نمیتوانند وضعیت PASS را محرز کنند. +یک طبقهبندی معتبر docs-only یا catalog-only میتواند یک مسیر کد را غیرقابلاعمال کند؛ +یک PR پیشنویس بهعنوان نامزد پذیرفته نمیشود. برچسب `hotfix` نیاز به شواهد را لغو نمیکند. + +هر دو گردشکار، PRها و pushها به شاخههای main/release، اجرای دستی و +رویدادهای merge-group را پوشش میدهند. push، dispatch و merge-group انتخاب کامل را اجرا میکنند. forkها +و merge groupها برای jobهایی که در حالت عادی runnerهای self-hosted را انتخاب میکنند، از runnerهای hosted +استفاده میکنند؛ پیش از عرضه، باید کافیبودن ظرفیت hosted تأیید شود. + +هر رسید JSON، SHA مربوط به checkout، اجرای گردشکار و attempt را مشخص میکند. +CLI عدم تطابق SHA میان checkout/event را رد میکند. آزمونهای گردشکار، عضویت در خطمشی را +به فهرست `needs` مربوط به job نتیجه متصل میکنند تا یک مسیر جدید یا حذفشده نتواند بیسروصدا ناپدید شود. +رسیدها گردشکار خود را پوشش میدهند، نه انتشار، استقرار یا جزئیات داخلی +یک اسکنر مشورتی موجود را. فعالکردن هر دو نام check در قوانین شاخه، +یک تغییر مدیریتی جداگانه است؛ افزودن این jobها بهخودیخود از یک شاخه محافظت نمیکند. ### موجودی اسکن ایستا -موجودی نسخهبندیشدهٔ aliasهای npm و عضویت در اسکن ایستا در -`config/quality/gate-manifest.json` قرار دارند. برای اعتبارسنجی نام اسکریپتها و -دستورهای دقیق در برابر `package.json`، دستور `npm run check:gate-manifest` را اجرا -کنید؛ افزودهشدن، حذفشدن و تغییر دستور باعث شکست هم hook محلی و هم jobهای -طبقهبندی تغییرات در CI میشود. یک alias، job گردشکار، نمونهٔ matrix یا test case -نیست: این شمارشها نباید همارز یکدیگر ارائه شوند. - -برای بررسی aliasهای انتخابشده بدون اجرای آنها، از -`npm run quality:scan -- --list` یا `npm run quality:scan:fast -- --list` -استفاده کنید. runner نقطهٔ ورود npm را فراخوانی میکند، بنابراین runtime آن -(از جمله Bun در محلهایی که پیکربندی شده است) حفظ میشود. manifest، aliasهای خارج -از این پروفایلها را بهعنوان مواردی که جداگانه فراخوانی میشوند ثبت میکند و -دستورهای نگهداری در پروفایلهای اسکن فقطخواندنی ممنوع هستند. - -این پروفایلها فقط اسکن ایستا را پوشش میدهند. آنها آزمونهای محصول، پوشش، -بستهبندی، بررسیهای خارجی یا پذیرش کامل انتشار یک کاندیدا را تأیید نمیکنند. -پذیرش گردشکار از `config/quality/admission-policy.json` پیوندشده و -`scripts/quality/admission-verdict.mjs` استفاده میکند. پروفایلهای release-observer -جدا باقی میمانند؛ بررسیها و رسیدهای قابلاعمال آنها را مستقل بررسی کنید. موجودی -متنی زیر صرفاً یک مرجع است و اثبات نمیکند که یک گیت واقعاً اجرا شده است. - -اسکریپتها در `scripts/check/` (گیتهای سیاست) و `scripts/quality/` (موتور ratchet) -قرار دارند. منبع حقیقت CI فایل `.github/workflows/ci.yml` است. +موجودی نسخهبندیشده npm-alias و عضویت در اسکن ایستا در +`config/quality/gate-manifest.json` قرار دارند. برای اعتبارسنجی نام اسکریپتها و فرمانهای دقیق +در برابر `package.json`، دستور `npm run check:gate-manifest` را اجرا کنید؛ افزودنها، حذفها و +انحراف فرمانها باعث شکست hook محلی و jobهای طبقهبندی تغییر در CI میشوند. +یک alias، job گردشکار، نمونه matrix یا test case نیست: این تعدادها نباید +بهعنوان موارد قابلجایگزینی با یکدیگر ارائه شوند. + +برای بررسی aliasهای انتخابشده بدون اجرای آنها، از `npm run quality:scan -- --list` یا +`npm run quality:scan:fast -- --list` استفاده کنید. runner، نقطه ورود npm را فراخوانی میکند، +بنابراین runtime آن (از جمله Bun در محلهایی که پیکربندی شده است) حفظ میشود. +manifest، aliasهای خارج از این پروفایلها را بهعنوان مواردی که جداگانه فراخوانی میشوند ثبت میکند و +فرمانهای نگهداری در پروفایلهای اسکن فقطخواندنی ممنوع هستند. + +این پروفایلها فقط اسکن ایستا را پوشش میدهند. آنها آزمونهای محصول، +پوشش، بستهبندی، بررسیهای خارجی یا پذیرش کامل انتشار یک نامزد را تأیید نمیکنند. +پذیرش گردشکار از `config/quality/admission-policy.json` و +`scripts/quality/admission-verdict.mjs` پیوندشده استفاده میکند. پروفایلهای release-observer جدا باقی میمانند؛ +بررسیها و رسیدهای قابلاعمال آنها را مستقل بررسی کنید. موجودی متنی +زیر یک مرجع است، نه مدرکی دال بر اینکه یک گیت واقعاً اجرا شده است. + +اسکریپتها در `scripts/check/` (گیتهای خطمشی) و `scripts/quality/` (موتور ratchet) قرار دارند. +منبع حقیقت CI، فایل `.github/workflows/ci.yml` است. ### مسیر سریع PR انتشار (`quality.yml`) -`.github/workflows/quality.yml` مکمل CI برای PRهای main/release، pushهای شاخهٔ -محافظتشده، dispatch و merge groupها است. PRها از بررسیهای سریعِ فیلترشده بر اساس -مسیر استفاده میکنند. build تکراری که بهطور دائمی غیرفعال بود حذف شده است؛ -بررسیهای واقعی build/package/boot همچنان در CI باقی ماندهاند. - -| Job | دامنه | مسدودکننده | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | PRهای مستندات/کد؛ ارجاعات مستندات API و docs-all | بله | -| `Fast Quality Gates` | PRهای کد؛ بررسیهای ایستا، typecheck، typecheck داشبورد و آزمونهای واحد تحتتأثیر | بله | -| `Forgotten sibling tests` | PRهای کد؛ ردیابی ماژولهای تغییریافته تا مصرفکنندگان ایستا و آزمونهای sibling کاندیدا؛ مسیرهای barrel و dynamic-import بهعنوان تشخیصهای توصیهای، همراه با استثناهای ارجاعشدهٔ allowlist گزارش میشوند | **توصیهای** | -| `Vitest (fast-path)` | PRهای کد؛ مجموعهٔ سریع vitest | بله | -| `Unit Tests fast-path` | PRهای کد؛ مجموعهٔ آزمون واحد ۴-shard | بله | -| `No new ESLint warnings` | PRهای کد؛ محافظ lint آگاه از suppressionها | بله، شامل forkها | -| `Merge integrity (changelog + generated skills)` | PRهای غیرپیشنویس؛ همگامسازی changelog و skillهای تولیدشده | بله، شامل forkها | +`.github/workflows/quality.yml` مکمل CI برای PRهای main/release، pushهای شاخه محافظتشده، +dispatch و merge groupها است. PRها از بررسیهای سریع فیلترشده بر اساس مسیر استفاده میکنند. build تکراری که برای همیشه +غیرفعال بود حذف شده است؛ بررسیهای واقعی build/package/boot همچنان در CI باقی میمانند. + +| Job | دامنه | مسدودکننده | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `Docs Gates (fast-path)` | PRهای docs/code؛ ارجاعهای مستندات API و docs-all | بله | +| `Fast Quality Gates` | PRهای کد؛ بررسیهای ایستا، typecheck، typecheck داشبورد و آزمونهای واحد متأثر | بله | +| `Forgotten sibling tests` | PRهای کد؛ ردیابی ماژولهای تغییریافته تا مصرفکنندگان ایستا و آزمونهای sibling نامزد؛ مسیرهای barrel و dynamic-import بهعنوان تشخیصهای مشورتی گزارش میشوند و استثناهای allowlist ارجاعشده را نیز شامل میشوند | **مشورتی** | +| `Vitest (fast-path)` | PRهای کد؛ مجموعه سریع vitest | بله | +| `Unit Tests fast-path` | PRهای کد؛ مجموعه آزمون واحد 4-shard | بله | +| `No new ESLint warnings` | PRهای کد؛ محافظ lint آگاه از suppressionها | بله، شامل forkها | +| `Merge integrity (changelog + generated skills)` | PRهای غیرپیشنویس؛ همگامسازی changelog و skillهای تولیدشده | بله، شامل forkها | #### گزارش آزمونهای sibling فراموششده -`npm run check:forgotten-sibling-tests` از resolver مربوط به import که پشت نگاشت -تأثیر آزمون قرار دارد، مجدداً استفاده میکند. برای هر ماژول production تغییریافته، -هنگامی که آزمون کاندیدا در diff مربوط به pull request وجود نداشته باشد، زنجیرههای -قطعی `changed module/symbol -> static consumer -> candidate sibling test` را گزارش -میکند. خلاصهٔ Markdown و نتیجهٔ JSON بهعنوان artifact گردشکار -`forgotten-sibling-tests` برای کالیبراسیون پیش از هر عرضهٔ مسدودکننده نگهداری -میشوند. +`npm run check:forgotten-sibling-tests` از resolver مربوط به import که پشت نگاشت تأثیر آزمون قرار دارد، دوباره استفاده میکند. +برای هر ماژول production تغییریافته، زمانی که آزمون نامزد +در diff مربوط به pull request وجود نداشته باشد، زنجیرههای قطعی +`changed module/symbol -> static consumer -> candidate sibling test` را گزارش میکند. خلاصه Markdown و نتیجه JSON بهعنوان +artifact گردشکار `forgotten-sibling-tests` برای کالیبراسیون پیش از هرگونه عرضه مسدودکننده نگهداری میشوند. -بازصادراتهای barrel و importهای پویا فقط برای تشخیص resolution هستند؛ آنها هرگز یافتهای مسدودکننده ایجاد نمیکنند. استثناهای بازبینیشده در -`config/quality/forgotten-sibling-allowlist.json` قرار دارند. هر ورودی باید نام تست مصرفکننده و تست کاندید را مشخص کند، دلیل مشخصی ارائه دهد و به یک issue یا pull request در GitHub پیوند داشته باشد. ورودیهای ناقص یا نادرست بهصورت بسته fail میشوند. استثناها نمیتوانند تست کاندیدی را که حذف شده است یا diffای را که `.skip`/`.todo` اضافه میکند، نادیده بگیرند؛ تضعیف assertion و دیگر روشهای پنهانسازی همچنان تحت مسئولیت gate مسدودکننده و مستقل -`check:test-masking` باقی میمانند. +بازصادراتهای Barrel و importهای پویا فقط برای تشخیص مشکلات resolution هستند؛ آنها هرگز یک یافتهٔ مسدودکننده ایجاد نمیکنند. استثناهای بازبینیشده در +`config/quality/forgotten-sibling-allowlist.json` قرار دارند. هر ورودی باید consumer و candidate +test را مشخص کند، دلیل مشخصی ارائه دهد و به یک GitHub issue یا pull request پیوند داشته باشد. ورودیهای نادرست بهصورت +fail-closed عمل میکنند. استثناها نمیتوانند یک candidate test حذفشده یا diffای را که `.skip`/`.todo` اضافه میکند، نادیده بگیرند؛ +تضعیف assertion و سایر شیوههای پنهانسازی همچنان تحت مسئولیت gate مسدودکننده و مستقل +`check:test-masking` هستند. ### Job: `lint` -در هر PR به `main` اجرا میشود. در صورت شکست، merge را مسدود میکند. - -| Script (`npm run ...`) | اعتبارسنجی میکند | مسدودکننده | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| `check:node-runtime` | نسخه Node.js در محدوده پشتیبانیشده قرار دارد | بله | -| `check:cycles` | importهای حلقوی — همه ماژولهای `src/` + `open-sse/` | بله | -| `check:route-validation:t06` | وجود schemaهای Zod در همه routeها (سیاست Tier 6) | بله | -| `check:any-budget:t11` | تعداد `@ts-expect-error // any` از بودجه فراتر نمیرود (catraca سطح 11) | بله | -| `check:provider-consistency` | هر provider در `providers.ts` دارای یک ورودی متناظر در `providerRegistry.ts` است (و بالعکس، در محدوده allowlist) | بله | -| `check:model-lifecycle` | سه جدول مسیریابی که بهصورت دستی نگهداری میشوند، با snapshot چرخه عمر ثبتشده (#11503) سازگار میمانند: `FITNESS_TABLE` (`taskFitness.ts`) به هیچ id بازنشستهای که `REGISTRY` قادر به مسیریابی آن است امتیاز نمیدهد؛ هر target در `BUILT_IN_ALIASES` در `REGISTRY` وجود دارد و در snapshot مربوط به idهای بازنشسته وجود ندارد؛ هر id بازنشستهای که همچنان در `REGISTRY` است، به مقصد دیگری هدایت شده یا در `allowedRetiredInCatalog` فهرست شده است؛ و هیچ source یا target در `DEFAULT_DEGRADATION_MAP` در آن snapshot بازنشسته محسوب نمیشود. این بررسی ثابت نمیکند که یک model در حال حاضر توسط یک upstream فعال ارائه میشود. آفلاین — با `config/quality/model-lifecycle.json` مقایسه میشود؛ این فایل بهصورت دستی و با `npm run quality:refresh-model-lifecycle` بهروزرسانی میشود (نیازمند شبکه؛ به CI متصل نیست). `allowedRetiredInCatalog` یک ضامن کاهش تدریجی است: تنها در صورت وجود یک tracking issue، ورودی جدیدی به آن اضافه کنید. | بله | -| `check:fetch-targets` | هر `fetch("/api/...")` در `src/` سمت client به یک `route.ts` واقعی resolve میشود | بله | -| `check:deps` | همه dependencyهای قابل نصب با `npm install` در تمام فایلهای `package.json` در repo، در `dependency-allowlist.json` وجود دارند؛ packageهای جدیدی که pin نشدهاند یا دچار slopsquatting هستند علامتگذاری میشوند | بله | -| `audit:deps` | `npm audit` (root و electron) — بدون advisory با شدت بالا/بحرانی (با `check:vuln-ratchet` مربوط به osv همپوشانی دارد؛ Rationalization Backlog را ببینید) | بله | -| `check:lockfile` | یکپارچگی `package-lock.json` — registry مبتنی بر https، hashهای یکپارچگی، بدون override میزبان | بله | -| `check:licenses` | فهرست مجاز مجوزهای SPDX برای وابستگیهای محیط تولید | بله | -| `check:tracked-artifacts` | نبود مصنوعات ساخت / پیوندهای نمادین `node_modules` ثبتشده (همچنین در pre-commit مربوط به husky اجرا میشود؛ pre-push عمداً سبک نگه داشته شده است — #6716) | بله | -| `check:ai-attribution` | نبود دنبالهٔ `Co-Authored-By` مربوط به هوش مصنوعی/بات یا پانوشت تولیدشده با هوش مصنوعی در commitها، عنوان یا متن PR — قانون قطعی #16 (در حلقهٔ دروازههای سریع `quality.yml` برای PR→`release/**` — payload رویداد را میخواند و خارج از PRها کاری انجام نمیدهد — و یک مرحلهٔ مختص PR در lint فایل `ci.yml` برای PR→`main`؛ همچنین hook مربوط به `commit-msg` در husky؛ همنویسندگان انسانی مجازند؛ #14436) | -| `check:vitest-exclusions` | هر مورد استثنای Vitest باید یک issue رهگیری را ذکر کند و در `config/quality/vitest-exclusions.json` وجود داشته باشد (#13204) | بله | -| `check:file-size` | هیچ فایل منبعی از سقف تعیینشده برای پسوند خود فراتر نمیرود (ضامن یکطرفه: فایلهای بزرگ ثابتشده در فهرست `frozen`) | بله | -| `check:error-helper` | پاسخهای خطا در اجراکنندهها/مدیریتکنندهها از `buildErrorBody()` / `sanitizeErrorMessage()` استفاده میکنند (قانون قطعی #12) | بله | -| `check:migration-numbering` | فایلهای SQL مهاجرت بهصورت متوالی شمارهگذاری شدهاند و هیچ شکاف یا شمارهٔ تکراری وجود ندارد | بله | -| `check:public-creds` | هیچ `client_id`/`client_secret` مربوط به OAuth یا کلید وب Firebase بهصورت صریح خارج از `publicCreds.ts` وجود ندارد (قانون سختگیرانهٔ شمارهٔ ۱۱) | بله | -| `check:db-rules` | هیچ SQL خامی خارج از ماژولهای `src/lib/db/` وجود ندارد؛ هیچ واردسازی barrel از `localDb.ts` انجام نمیشود (قوانین سختگیرانهٔ شمارهٔ ۲/۵) | بله | -| `check:known-symbols` | اجراکنندههای ارائهدهنده، راهبردهای مسیریابی و مترجمهای ثبتشده در جدولهای dispatch مربوطه با فایلهای روی دیسک مطابقت دارند — هیچ نماد بدون استفاده یا اعلاننشدهای وجود ندارد | بله | -| `check:route-guard-membership` | هر مسیری که یک فرایند فرزند ایجاد میکند، توسط `isLocalOnlyPath()` طبقهبندی شده است (قوانین سختگیرانهٔ شمارهٔ ۱۵/۱۷) | بله | -| `check:test-discovery` | هر فایل `*.test.ts` / `*.spec.ts` در مخزن توسط حداقل یک اجراکنندهٔ آزمون جمعآوری میشود (سازوکار ratchet: فهرست فایلهای بدون اجراکننده در `test-discovery-baseline.json` فقط میتواند کوچکتر شود) | بله | -| `check:agent-skills-sync` | مصنوعات تولیدشدهٔ agent-skills با کاتالوگ منبع خود مطابقت دارند (بدون انحراف) | -| `check:provider-asset-provenance` | لوگوها/داراییهای ارائهدهنده دارای یک ورودی ثبتشده برای منشأ هستند | -| `lint:json` | فایلهای پیکربندی JSON تجزیه میشوند و با قواعد lint مخزن مطابقت دارند | -| `typecheck:core` | کامپایل TypeScript بدون خطا (فقط هشدارهای مشورتی) | بله | -| `typecheck:noimplicit:core` | `noImplicitAny` سختگیرانه — با نگاه به آینده؛ بسیاری از محلهای فراخوانی از قبل موجود همچنان به حاشیهنویسی نوع نیاز دارند | **مشورتی** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | اجرای `tsc` محدود به `src/app/(dashboard)/**` (#7033) — فهرست مجازِ گزینششدهٔ ۲۷ فایلیِ `typecheck:core` هیچ فایل TSX داشبوردی را شامل نمیشود و `next build` نیز هرگز آن را از نظر نوع بررسی نمیکند (`next.config.mjs` مقدار `ignoreBuildErrors: true` را تنظیم میکند)، بنابراین پسرفتهای شناسههای جداافتاده در آن بخش (#6625/#6909) برای CI نامرئی بودند. تفاوتها با یک خط مبنای ثابت از تعداد خطاها بهازای هر فایل/کد TS مقایسه میشوند (`config/quality/dashboard-typecheck-baseline.json`، با همان الگوی اعمال کهنگیِ `check:known-symbols`) — فقط خطاهای جدیدی که از تعداد ثبتشده در خط مبنا فراتر بروند باعث شکست دروازه میشوند؛ وقتی یک خطای از قبل موجود برطرف شد، با `--update` خط مبنا را بهتدریج کاهش دهید. | بله | +روی هر PR به `main` اجرا میشود. در صورت شکست، merge را مسدود میکند. + +| Script (`npm run ...`) | اعتبارسنجی میکند | مسدودکننده | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `check:node-runtime` | نسخهٔ Node.js در محدودهٔ پشتیبانیشده قرار دارد | بله | +| `check:cycles` | importهای حلقوی در سراسر `src/` + `open-sse/` (مبتنی بر AST، با resolve شدن `paths` در tsconfig). حالت Bare صرفاً advisory است و چرخهها را فهرست میکند. `check:cycles:ratchet` (چیزی که CI اجرا میکند) زمانی مسدود میکند که تعداد از سقف `metrics.cycles` در `quality-baseline.json` فراتر رود — در حال حاضر 14، با `direction: down`، بنابراین فقط میتواند کاهش یابد (#15159 G-01/G-02) | بله (ratchet) | +| `check:route-validation:t06` | وجود schemaهای Zod روی همهٔ routeها (سیاست Tier 6) | بله | +| `check:any-budget:t11` | تعداد `@ts-expect-error // any` از budget فراتر نمیرود (catraca در Tier 11) | بله | +| `check:provider-consistency` | هر ارائهدهنده در `providers.ts` دارای یک ورودی متناظر در `providerRegistry.ts` است (و برعکس، در محدوده فهرست مجاز) | بله | +| `check:model-lifecycle` | سه جدول مسیریابی که بهصورت دستی نگهداری میشوند، با تصویر لحظهای چرخهعمر ثبتشده (#11503) سازگار میمانند: `FITNESS_TABLE` (`taskFitness.ts`) به هیچ شناسه بازنشستهای که `REGISTRY` قادر به مسیریابی آن باشد امتیاز نمیدهد؛ هر مقصد `BUILT_IN_ALIASES` در `REGISTRY` وجود دارد و در تصویر لحظهای شناسههای بازنشسته نیست؛ هر شناسه بازنشستهای که همچنان در `REGISTRY` است، هدایت میشود یا در `allowedRetiredInCatalog` فهرست شده است؛ و هیچ مبدأ یا مقصدی در `DEFAULT_DEGRADATION_MAP` در آن تصویر لحظهای بازنشسته محسوب نمیشود. این بررسی ثابت نمیکند که یک مدل در حال حاضر توسط یک بالادست فعال ارائه میشود. آفلاین — با `config/quality/model-lifecycle.json` مقایسه میکند؛ این فایل بهصورت دستی با `npm run quality:refresh-model-lifecycle` تازهسازی میشود (نیازمند شبکه؛ به CI متصل نیست). `allowedRetiredInCatalog` یک ضامن کاهش تدریجی است: فقط همراه با یک مسئله رهگیری، ورودی جدیدی اضافه کنید. | بله | +| `check:fetch-targets` | هر `fetch("/api/...")` در `src/` سمت کلاینت به یک `route.ts` واقعی منتهی میشود | بله | +| `check:deps` | تمام وابستگیهای قابل نصب با `npm install` در همه فایلهای `package.json` مخزن، در `dependency-allowlist.json` قرار دارند؛ بستههای جدیدِ بدون نسخه ثابت یا دارای نامهای مستعد slopsquatting علامتگذاری میشوند | بله | +| `audit:deps` | `npm audit` (ریشه + electron) — بدون هشدارهای سطح بالا/بحرانی (با osv `check:vuln-ratchet` همپوشانی دارد؛ بخش Rationalization Backlog را ببینید) | بله | +| `check:lockfile` | یکپارچگی `package-lock.json` — رجیستری https، هشهای یکپارچگی، بدون بازنویسی میزبان | بله | +| `check:licenses` | فهرست مجاز مجوزهای SPDX برای وابستگیهای محیط تولید | بله | +| `check:tracked-artifacts` | بدون مصنوعات ساخت / پیوندهای نمادین `node_modules` ثبتشده (در pre-commit مربوط به husky نیز اجرا میشود؛ pre-push عمداً سبک نگه داشته شده است — #6716) | بله | +| `check:ai-attribution` | نبود تریلر `Co-Authored-By` مربوط به هوش مصنوعی/بات یا پانوشت تولید توسط هوش مصنوعی در commitها، عنوان یا بدنه PR — قانون سختگیرانه #16 (در حلقه fast-gates فایل `quality.yml` برای PR→`release/**` — payload رویداد را میخواند و خارج از PR هیچ عملی انجام نمیدهد — و یک مرحله مختص PR در lint فایل `ci.yml` برای PR→`main`؛ همچنین hook از نوع `commit-msg` در husky؛ همنویسندگان انسانی مجازند؛ #14436) | +| `check:vitest-exclusions` | هر مورد استثنای Vitest یک issue رهگیری را ذکر میکند و در `config/quality/vitest-exclusions.json` وجود دارد (#13204) | بله | +| `check:file-size` | هیچ فایل منبعی از سقف تعیینشده برای پسوند خود فراتر نمیرود (ratchet: فایلهای بزرگ تثبیتشده در فهرست `frozen`) | بله | +| `check:error-helper` | پاسخهای خطا در executorها/handlerها از `buildErrorBody()` / `sanitizeErrorMessage()` استفاده میکنند (قانون سختگیرانه #12) | بله | +| `check:migration-numbering` | فایلهای SQL مهاجرت بهترتیب شمارهگذاری شدهاند و هیچ فاصله یا شماره تکراری وجود ندارد | بله | +| `check:public-creds` | هیچ مقدار صریح OAuth برای `client_id`/`client_secret` یا کلید Firebase Web خارج از `publicCreds.ts` وجود ندارد (قانون سختگیرانه شماره ۱۱) | بله | +| `check:db-rules` | هیچ SQL خامی خارج از ماژولهای `src/lib/db/` وجود ندارد؛ هیچ درونریزی تجمیعی از `localDb.ts` انجام نمیشود (قوانین سختگیرانه شماره ۲/۵) | بله | +| `check:known-symbols` | اجراکنندههای ارائهدهنده، راهبردهای مسیریابی و مترجمهای ثبتشده در جدولهای توزیع مربوطه با فایلهای روی دیسک مطابقت دارند — هیچ نماد یتیم یا اعلاننشدهای وجود ندارد | بله | +| `check:route-guard-membership` | هر مسیری که یک فرایند فرزند ایجاد میکند، توسط `isLocalOnlyPath()` طبقهبندی شده است (قوانین سختگیرانه شماره ۱۵/۱۷) | بله | +| `check:test-discovery` | هر فایل `*.test.ts` / `*.spec.ts` در مخزن توسط حداقل یک اجراکننده آزمون جمعآوری میشود (سازوکار ضامن: فهرست فایلهای یتیم در `test-discovery-baseline.json` فقط میتواند کوچکتر شود) | بله | +| `check:agent-skills-sync` | مصنوعات تولیدشدهٔ agent-skills با کاتالوگ منبع خود مطابقت دارند (بدون انحراف) | +| `check:provider-asset-provenance` | لوگوها/داراییهای ارائهدهنده دارای یک ورودی ثبتشده برای منشأ هستند | +| `lint:json` | فایلهای پیکربندی JSON تجزیه میشوند و قوانین lint مخزن را رعایت میکنند | +| `typecheck:core` | کامپایل TypeScript بدون خطا (فقط هشدارهای مشورتی) | بله | +| `typecheck:noimplicit:core` | `noImplicitAny` سختگیرانه — آیندهنگر؛ بسیاری از محلهای فراخوانی از قبل موجود همچنان به حاشیهنویسی نوع نیاز دارند | **مشورتی** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | اجرای `tsc` محدود به `src/app/(dashboard)/**` (#7033) — فهرست مجاز گزینششدهٔ ۲۷ فایلیِ `typecheck:core` هیچ فایل TSX داشبوردی را شامل نمیشود و `next build` نیز هرگز آن را از نظر نوع بررسی نمیکند (`next.config.mjs` مقدار `ignoreBuildErrors: true` را تنظیم میکند)؛ بنابراین پسرفتهای شناسههای بدون مرجع در آن بخش (#6625/#6909) برای CI نامرئی بودند. تفاوتها با یک خط مبنای ثابتِ شمارش بر اساس فایل/کد TS مقایسه میشوند (`config/quality/dashboard-typecheck-baseline.json`، با همان الگوی اعمال منسوخشدگیِ `check:known-symbols`) — فقط خطاهای جدید فراتر از تعداد ثبتشده در خط مبنا باعث شکست این دروازه میشوند؛ هنگامی که یک خطای از قبل موجود رفع شد، با `--update` خط مبنا را کاهش دهید. | بله | ### کار: `quality-gate` @@ -139,91 +135,91 @@ CLI ناهماهنگی میان SHA مربوط به checkout/event را رد م | اسکریپت | اعتبارسنجی | مسدودکننده | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `quality:collect` | فایل `quality-metrics.json` را تولید میکند (تعداد هشدارهای ESLint، پوشش برگرفته از گزارش ادغامشدهٔ shardها) | بله (پیشنیاز ratchet) | +| `quality:collect` | فایل `quality-metrics.json` را تولید میکند (تعداد هشدارهای ESLint، پوشش از گزارش ادغامشدهٔ شاردها) | بله (پیشنیاز ratchet) | | `quality:ratchet` | هیچیک از معیارهای موجود در `quality-baseline.json` پسرفت نکرده باشد (هشدارهای ESLint ≤ خط مبنا؛ پوشش ≥ خط مبنا) | بله | -| `check:duplication` | تکرار کد (jscpd@4) از خط مبنای موجود در `quality-baseline.json` فراتر نرود | بله | +| `check:duplication` | میزان تکرار کد (jscpd@4) از خط مبنای موجود در `quality-baseline.json` فراتر نرود | بله | | `check:complexity` | پیچیدگی حلقوی در سطح فایل از سقف تعیینشده فراتر نرود (`complexity` هستهٔ ESLint + `max-lines-per-function`) | بله | -| `check:cognitive-complexity` | ratchet پیچیدگی شناختی (`eslint-plugin-sonarjs`) — اجرای جداگانهٔ ESLint؛ CI هر دو را بهصورت مرحلهٔ واحد `check:complexity-ratchets` اجرا میکند | بله | +| `check:cognitive-complexity` | ratchet پیچیدگی شناختی (`eslint-plugin-sonarjs`) — اجرای جداگانهٔ ESLint؛ CI هر دو را بهصورت ادغامشده در یک مرحلهٔ `check:complexity-ratchets` اجرا میکند | بله | | `check:dead-code` | ratchet مربوط به exportها / فایلهای استفادهنشده (knip) نسبت به خط مبنا پسرفت نکند | بله | -| `check:compression-budget` | بودجهٔ بنچمارک فشردهسازی — حداقل صرفهجویی توکن برای هر engine نباید پسرفت کند | بله | -| `check:type-coverage` | ratchet درصد کد دارای type (`type-coverage`) پسرفت نکند؛ تا حد زیادی `typecheck:noimplicit:core` را پوشش میدهد | بله | -| `check:codeql-ratchet` | تعداد هشدارهای باز CodeQL پسرفت نکند (خواندن از طریق `gh api`؛ در نبود token بدون خطا رد میشود) — تناوب بهروزرسانی و اجرای دستی: بخش «ratchet مربوط به CodeQL» را در ادامه ببینید | بله | +| `check:compression-budget` | بودجهٔ بنچمارک فشردهسازی — حداقل میزان صرفهجویی توکن برای هر موتور نباید پسرفت کند | بله | +| `check:type-coverage` | ratchet درصد کد تایپشده (`type-coverage`) پسرفت نکند؛ تا حد زیادی `typecheck:noimplicit:core` را پوشش میدهد | بله | +| `check:codeql-ratchet` | تعداد هشدارهای باز CodeQL پسرفت نکند (خواندن از طریق `gh api`؛ در نبود توکن با موفقیت رد میشود) — تناوب بهروزرسانی و اجرای دستی: بخش «ratchet مربوط به CodeQL» را در ادامه ببینید | بله | ### Job: `quality-extended` کل این job جنبهٔ مشورتی دارد (`continue-on-error: true`). ratchetهای مبتنی بر npm -بهصورت واقعی اجرا میشوند؛ اسکنرهای خارجی از طریق `gh release download` نصب میشوند و -اگر فایل اجرایی همچنان موجود نباشد، خودشان با موفقیت رد میشوند (exit 0). +واقعاً اجرا میشوند؛ اسکنرهای خارجی از طریق `gh release download` نصب میشوند و +اگر فایل باینری همچنان موجود نباشد، خودشان اجرا را رد میکنند (exit 0). | اسکریپت | اعتبارسنجی | مسدودکننده | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | `check:circular-deps` | نبود وابستگیهای دوری (dpdm) | **مشورتی** | | `check:bundle-size` | اندازهٔ bundle از سقف تعیینشده فراتر نرود | **مشورتی** | -| `check:secrets` | اسکن اطلاعات محرمانه (gitleaks) — در نبود فایل اجرایی رد میشود | **مشورتی** | -| `check:vuln-ratchet` | آسیبپذیریهای وابستگیها (osv-scanner) پسرفت نکنند — در نبود فایل اجرایی رد میشود | **مشورتی** | +| `check:secrets` | اسکن اسرار (gitleaks) — در نبود فایل باینری رد میشود | **مشورتی** | +| `check:vuln-ratchet` | آسیبپذیریهای وابستگیها (osv-scanner) پسرفت نکنند — در نبود فایل باینری رد میشود | **مشورتی** | | `check:workflows` | lint کردن workflowها (actionlint + zizmor)؛ اسکنرهای مفقود/خراب، گزارشهای نامعتبر یا نبود خط مبنای ratchet با وضعیت INCOMPLETE شکست میخورند. یافتههای معتبر از سیاست strict/advisory/ratchet انتخابشده پیروی میکنند | اجرا الزامی است؛ ratchet مربوط به zizmor در CI مسدودکننده است | -| `check:openapi-breaking` | تغییرات ناسازگارشکن در قرارداد API عمومی (`openapi.yaml`) نسبت به شاخهٔ پایه (oasdiff) — مقدار `openapiBreaking=N` را تولید میکند؛ اگر oasdiff موجود نباشد یا مشخصات پایه قابل resolve نباشد، رد میشود | **مشورتی** | +| `check:openapi-breaking` | تغییرات ناسازگار در قرارداد API عمومی (`openapi.yaml`) نسبت به شاخهٔ پایه (oasdiff) — مقدار `openapiBreaking=N` را تولید میکند؛ در نبود oasdiff یا در صورت غیرقابلدسترسی بودن مشخصات پایه رد میشود | **مشورتی** | ### Job: `docs-sync-strict` -در هر PR به `main` اجرا میشود. در صورت شکست، merge را مسدود میکند. - -| اسکریپت | موارد اعتبارسنجیشده | مسدودکننده | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | -| `check:docs-all` | دروازهٔ فراگیری که ۶ زیردروازهٔ زیر را بهترتیب اجرا میکند | بله | -| ↳ `check:docs-sync` | سازگاری نسخه میان CHANGELOG / OpenAPI / llm.txt | بله | -| ↳ `check:docs-counts` | تعدادهای ذکرشده در متن (تعداد ارائهدهندگان، تعداد مهاجرتها و غیره) در محدودهٔ افزایشی تعدادهای واقعی قرار دارند | بله | -| ↳ `check:env-doc-sync` | هر متغیر محیطی در `.env.example` در یکی از جدولهای مستندات ثبت شده است و برعکس | بله | -| ↳ `check:deprecated-versions` | هیچ رشتهٔ نسخهٔ منسوخی در مستندات وجود ندارد | بله | -| ↳ `check:doc-links` | پیوندهای داخلی markdown در مستندات به فایلهای واقعی ارجاع میدهند (با قالب `[text]`/`(path)`) | بله | -| ↳ `check:fabricated-docs` | مسیرها، متغیرهای محیطی، فرمانهای CLI، نام hookها و مسیرهای فایل ذکرشده در مستندات، در پایگاه کد وجود دارند. دروازهٔ سخت با `--strict`؛ شکست غیرمسدودکننده بدون این پرچم. | بله (از طریق `--strict` در CI) | -| `check:cli-i18n` | رشتههای فرمان CLI در همهٔ فایلهای locale مربوط به i18n وجود دارند | بله | -| `check:openapi-coverage` | مشخصات OpenAPI دستکم کفِ افزایشی تعیینشدهای از مسیرهای واقعی را پوشش میدهد | بله | -| `check:openapi-security-tiers` | حاشیهنویسیهای سطح امنیتی در `openapi.yaml` با طبقهبندیهای `routeGuard.ts` سازگار هستند | **مشورتی** | -| `check:openapi-routes` | هر مسیر در `openapi.yaml` به یک `route.ts` واقعی ارجاع میدهد (ضد توهم) | بله | -| `check:docs-symbols` | هر ارجاع `/api/...` در `docs/**/*.md` به یک `route.ts` واقعی ارجاع میدهد (ضد توهم) | بله | -| `i18n translation drift` | کلیدهای ترجمهنشده در فایلهای locale مربوط به i18n — فقط هشدار | **مشورتی** | - -### کار: `i18n-ui-coverage` - -| اسکریپت | موارد اعتبارسنجیشده | مسدودکننده | -| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check-ui-keys-coverage` (درونخطی) | پوشش کلیدهای i18n رابط کاربری ≥ ۶۵٪ است | بله | -| `check-ui-value-drift` (درونخطی) | بازنویسی یک **مقدار** انگلیسی، هیچ ترجمهٔ کهنهای بر جای نمیگذارد | بله | -| `check-new-key-coverage` (درونخطی) | یک کلید انگلیسی **جدید** در همهٔ localeها ترجمه شده است — نشانگر `__MISSING__:` رد میشود | بله | -| `check-translation-ratio` | نسبت ترجمهٔ واقعی در هر locale (برگهای یکسان با انگلیسی / جاینگهدار / مفقود خارج از فهرست مجاز) نباید از `config/quality/i18n-translation-baseline.json` بهعلاوهٔ حاشیهٔ مجاز فراتر رود | **مشورتی** | - -به `fetch-depth: 0` نیاز دارد — دروازهٔ انحراف مقدار، `en.json` را با مبنای ادغام مقایسه میکند. - -#### `check-ui-value-drift` — دروازهٔ ترجمهٔ کهنه - -آن رگرسیون i18n را شناسایی میکند که سایر دروازهها از نظر ساختاری قادر به دیدن آن نیستند: یک مقدار انگلیسی +در هر PR به `main` اجرا میشود. در صورت شکست، ادغام را مسدود میکند. + +| اسکریپت | موارد اعتبارسنجی | مسدودکننده | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | +| `check:docs-all` | دروازهٔ کلانی که ۶ زیردروازهٔ زیر را بهترتیب اجرا میکند | بله | +| ↳ `check:docs-sync` | سازگاری نسخه میان CHANGELOG / OpenAPI / llm.txt | بله | +| ↳ `check:docs-counts` | تعدادهای ذکرشده در متن (تعداد ارائهدهندگان، تعداد مهاجرتها و غیره) در محدودهٔ ضامندار نسبت به تعدادهای واقعی قرار دارند | بله | +| ↳ `check:env-doc-sync` | تمام متغیرهای محیطی موجود در `.env.example` در یک جدول مستندات ثبت شدهاند و بالعکس | بله | +| ↳ `check:deprecated-versions` | هیچ رشتهٔ نسخهٔ منسوخی در مستندات وجود ندارد | بله | +| ↳ `check:doc-links` | پیوندهای داخلی markdown در مستندات به فایلهای واقعی اشاره میکنند (با قالب `[text]`/`(path)`) | بله | +| ↳ `check:fabricated-docs` | مسیرها، متغیرهای محیطی، فرمانهای CLI، نام hookها و مسیر فایلهای ذکرشده در مستندات در پایگاه کد وجود دارند. دروازهٔ سخت با `--strict`؛ بدون این پرچم، شکست نرم است. | بله (از طریق `--strict` در CI) | +| `check:cli-i18n` | رشتههای فرمان CLI در همهٔ فایلهای locale مربوط به i18n وجود دارند | بله | +| `check:openapi-coverage` | مشخصات OpenAPI دستکم کف ضامنگذاریشدهای از مسیرهای واقعی را پوشش میدهد | بله | +| `check:openapi-security-tiers` | حاشیهنویسیهای سطح امنیت در `openapi.yaml` با طبقهبندیهای `routeGuard.ts` سازگارند | **مشورتی** | +| `check:openapi-routes` | هر path در `openapi.yaml` به یک `route.ts` واقعی منتهی میشود (ضد توهم) | بله | +| `check:docs-symbols` | هر ارجاع `/api/...` در `docs/**/*.md` به یک `route.ts` واقعی منتهی میشود (ضد توهم) | بله | +| `i18n translation drift` | کلیدهای ترجمهنشده در فایلهای locale مربوط به i18n — فقط هشدار | **مشورتی** | + +### Job: `i18n-ui-coverage` + +| اسکریپت | موارد اعتبارسنجی | مسدودکننده | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check-ui-keys-coverage` (درونخطی) | پوشش کلیدهای i18n رابط کاربری ≥ ۶۵٪ است | بله | +| `check-ui-value-drift` (درونخطی) | بازنویسی یک **مقدار** انگلیسی هیچ ترجمهٔ قدیمیای بر جای نمیگذارد | بله | +| `check-new-key-coverage` (درونخطی) | یک کلید انگلیسی **جدید** در همهٔ localeها ترجمه شده است — نشانگر `__MISSING__:` رد میشود | بله | +| `check-translation-ratio` | نسبت ترجمهٔ واقعی در هر locale (موارد یکسان با انگلیسی / placeholder / مقادیر ازدسترفته خارج از allowlist) نباید از `config/quality/i18n-translation-baseline.json` + حاشیهٔ مجاز فراتر رود | **مشورتی** | + +به `fetch-depth: 0` نیاز دارد — دروازهٔ value-drift، تفاوت `en.json` را با merge base بررسی میکند. + +#### `check-ui-value-drift` — دروازهٔ ترجمهٔ قدیمی + +آن خطای بازگشتی i18n را شناسایی میکند که دیگر دروازهها از نظر ساختاری قادر به دیدنش نیستند: یک مقدار انگلیسی بازنویسی میشود و ترجمههای برگرفته از مقدار انگلیسی _قبلی_ باقی میمانند؛ در نتیجه کاربران غیرانگلیسی همچنان متنی با لحنی مطمئن اما اکنون نادرست میخوانند. -این مشکل واقعاً منتشر شد. `oauthModal.googleOAuthWarning` هنگام اضافهشدن ابزار کمکی ورود Antigravity -بازنویسی شد (#5203)؛ **۳۹ مورد از ۴۳ locale** همچنان متنی را حفظ کردند که به اپراتورها میگفت «URL کامل را کپی +این مشکل واقعاً در نسخهٔ منتشرشده رخ داد. `oauthModal.googleOAuthWarning` هنگام اضافهشدن ابزار کمکی ورود Antigravity +بازنویسی شد (#5203)؛ **۳۹ مورد از ۴۳ locale** همچنان متنی داشتند که به اپراتورها میگفت «URL کامل را کپی کنید و در پایین جایگذاری کنید» — جریانی که برای آن ارائهدهنده قابل تکمیل نیست. این مشکل -تا #8463 نادیده ماند، زیرا: - -- `sync-ui-keys` فقط کلیدهایی را که **وجود ندارند** تکمیل میکند، نه کلیدهایی که **کهنه** هستند؛ -- `check-ui-keys-coverage` _وجود_ کلید را میشمارد، بنابراین یک ترجمهٔ کهنه بهعنوان پوششدادهشده امتیاز میگیرد؛ -- `check-translation-drift` نسخههای آینهای مستندات در `docs/i18n//**.md` را ردیابی میکند — - و هرگز `src/i18n/messages/*.json` را نمیخواند. از همگامسازی مجدد 2026-09 در کار `docs-sync-strict` مسدودکننده است: - یک سند اصلی را ویرایش کنید ← `npm run i18n:run -- --files=` (در سطح بخش و کمهزینه). - -**آگاه از diff، نه متکی به baseline.** این سازوکار `en.json` در merge base را با -working tree مقایسه میکند؛ برای هر کلیدی که مقدار انگلیسی آن تغییر کرده باشد، هر locale که همچنان -ترجمهای دستنخورده داشته باشد، منسوخ محسوب میشود. این کار عمداً **بدهی از قبل موجود را ثابت نگه میدارد** — یک diff -نمیتواند مشخص کند ترجمهای قدیمی و دیرپا از کدام متن انگلیسی قبلی منشأ گرفته است، بنابراین gate -فقط مواردی را ارزیابی میکند که تغییر فعلی به آنها دست میزند. راهکار جایگزین (یک hash baseline برای هر کلید) -به یک فایل تولیدشده با حجم حدود 600 KB، یعنی 3× بزرگتر از بزرگترین baseline موجود، نیاز دارد که با هر PR مربوط به i18n +تا #8463 شناسایی نشد، زیرا: + +- `sync-ui-keys` فقط کلیدهایی را که **وجود ندارند** تکمیل میکند، نه کلیدهایی را که **قدیمی** شدهاند؛ +- `check-ui-keys-coverage` _وجود_ کلید را میشمارد، بنابراین یک ترجمهٔ قدیمی نیز پوششدادهشده محسوب میشود؛ +- `check-translation-drift` همتاهای مستندات در `docs/i18n//**.md` را ردیابی میکند — + و هرگز `src/i18n/messages/*.json` را نمیخواند. از همگامسازی مجدد 2026-09 در job با نام `docs-sync-strict` مسدودکننده است: + یک سند اصلی را ویرایش کنید → `npm run i18n:run -- --files=` (در سطح بخش و کمهزینه). + +**آگاه از diff، بدون اتکا به baseline.** این سازوکار `en.json` را در merge base با +درخت کاری مقایسه میکند؛ برای هر کلیدی که مقدار انگلیسی آن تغییر کرده است، هر locale که همچنان +ترجمهای دستنخورده داشته باشد، منسوخ محسوب میشود. این کار عمداً **بدهی ازپیشموجود را ثابت نگه میدارد** — یک diff +نمیتواند مشخص کند که یک ترجمهٔ قدیمی و باسابقه از کدام متن انگلیسی قدیمی ایجاد شده است، بنابراین gate +فقط مواردی را ارزیابی میکند که تغییر فعلی به آنها دست میزند. راهکار جایگزین (یک baseline شامل hash برای هر کلید) +به یک فایل تولیدشدهٔ حدوداً 600 KB نیاز دارد که 3 برابر بزرگترین baseline موجود است و در هر PR مربوط به i18n دستخوش تغییر میشود. دو راه برای برآوردهکردن آن وجود دارد: 1. ترجمههای تحتتأثیر را بهروزرسانی کنید، یا -2. آنها را روی `__MISSING__:` تنظیم کنید — سپس runtime متن انگلیسی اصلاحشده را ارائه میکند +2. آنها را روی `__MISSING__:` تنظیم کنید — سپس runtime متن انگلیسی اصلاحشده را ارائه میدهد (`src/i18n/request.ts::deepMergeFallback`، #7258) و کلید برای ترجمه در صف قرار میگیرد. اگر **معنای** رشته تغییر کرده است، **تغییر نام کلید** را ترجیح دهید: یک کلید جدید نمیتواند @@ -235,8 +231,8 @@ npm run i18n:check-value-drift:warn # فقط گزارش BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -هنگامی که catalog پایه قابل خواندن نباشد، با `SKIP reason=base-unresolved` و کد 0 خارج میشود (clone کمعمق -بدون base ref) و رفتار `check-openapi-breaking` را منعکس میکند. +وقتی catalog پایه قابل خواندن نباشد (clone کمعمق بدون ref پایه)، با `SKIP reason=base-unresolved` +و کد 0 خارج میشود؛ مشابه رفتار `check-openapi-breaking`. ### Job: `i18n` @@ -250,33 +246,33 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift فقط روی pull requestها اجرا میشود. -| Script | اعتبارسنجی میکند | مسدودکننده | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PRهایی که کد production را در `src/`، `open-sse/`، `electron/` یا `bin/` تغییر میدهند باید شامل testهای جدید یا بهروزشده باشند (Hard Rule #8) | بله | -| `check:test-masking` | فایلهای test تغییریافته، تعداد خالص assertها را کاهش نمیدهند یا همانگوییهای `assert.ok(true)` اضافه نمیکنند | بله | -| `check:pr-evidence` | بدنه PR به شواهد test/VPS برای تغییر ارجاع میدهد (Hard Rule #18 را با grep کردن متن PR خودکار میکند — شکننده است، Backlog را ببینید) | بله | +| Script | اعتبارسنجی میکند | مسدودکننده | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | PRهایی که کد production را در `src/`، `open-sse/`، `electron/` یا `bin/` تغییر میدهند، باید تستها را اضافه یا بهروزرسانی کنند (Hard Rule #8) | بله | +| `check:test-masking` | فایلهای تست تغییرکرده، تعداد خالص assertها را کاهش نمیدهند و همانگوییهای `assert.ok(true)` را اضافه نمیکنند | بله | +| `check:pr-evidence` | بدنهٔ PR به شواهد تست/VPS برای تغییر اشاره میکند (Hard Rule #18 را با grepکردن نثر PR مکانیزه میکند — شکننده است؛ Backlog را ببینید) | بله | ### Job: `test-vitest` پس از `build` اجرا میشود. در صورت شکست، merge را مسدود میکند. -| Suite | اعتبارسنجی میکند | مسدودکننده | -| ---------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | سرور MCP (110 ابزار)، autoCombo، cache — اجراکننده vitest | بله | -| `test:vitest:ui` | testهای مؤلفه UI — اجراکننده vitest | **مسدودکننده** — شکستهای از قبل موجود صراحتاً در `vitest.config.ts` مستثنا شدهاند؛ شکستهای جدید باعث شکست job میشوند | +| Suite | اعتبارسنجی میکند | مسدودکننده | +| ---------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | سرور MCP (110 ابزار)، autoCombo، cache — اجراکنندهٔ vitest | بله | +| `test:vitest:ui` | تستهای مؤلفههای UI — اجراکنندهٔ vitest | **مسدودکننده** — شکستهای ازپیشموجود صراحتاً در `vitest.config.ts` مستثنا شدهاند؛ شکستهای جدید باعث شکست job میشوند | ### Workflowهای شبانه (زمانبندیشده، مشورتی) -این موارد طبق زمانبندی cron (و `workflow_dispatch`) اجرا میشوند و هرگز روی PRها اجرا نمیشوند. همه آنها مشورتی هستند. +این موارد طبق یک زمانبندی cron (و `workflow_dispatch`) اجرا میشوند و هرگز روی PRها اجرا نمیشوند. همهٔ آنها مشورتی هستند. -| Workflow | اعتبارسنجی میکند | مسدودکننده | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `nightly-property` | testهای property مبتنی بر fast-check با seed تصادفی + تعداد اجرای بالا | **مشورتی** | -| `nightly-resilience` | gate رشد heap، تزریق خطای chaos، بارگذاری/soak با k6 | **مشورتی** | -| `nightly-llm-security` | محافظ تزریق promptfoo (حالت block) + probeهای garak (بدون secret ارائهدهنده رد میشود) | **مشورتی** | -| `nightly-schemathesis` | fuzzing قرارداد OpenAPI (schemathesis) روی یک OmniRoute فعال با استفاده از `docs/openapi.yaml` — تخطی از spec / خطاهای 500 مدیریتنشده را آشکار میکند (Fase 8 B.4) | **مشورتی** | -| `nightly-mutation` | امتیاز mutation testing مربوط به Stryker روی مسیر سریع unit — mutantهای باقیمانده، assertهای ضعیف را آشکار میکنند | **مشورتی** | -| `nightly-compat` | ماتریس سازگاری موتور Node در محدودههای پشتیبانیشده `engines.node` | **مشورتی** | +| Workflow | اعتبارسنجی میکند | مسدودکننده | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | +| `nightly-property` | تستهای property مبتنی بر fast-check با seed تصادفی و تعداد اجرای بالا | **مشورتی** | +| `nightly-resilience` | gate رشد heap، تزریق خطای chaos و تست بار/دوام k6 | **مشورتی** | +| `nightly-llm-security` | محافظ تزریق promptfoo (حالت block) + probeهای garak (بدون secret ارائهدهنده رد میشود) | **مشورتی** | +| `nightly-schemathesis` | fuzzing قرارداد OpenAPI با schemathesis علیه یک OmniRoute فعال با استفاده از `docs/openapi.yaml` — نقضهای spec / خطاهای 500 مدیریتنشده را آشکار میکند (Fase 8 B.4) | **مشورتی** | +| `nightly-mutation` | امتیاز تست mutation با Stryker روی مسیر سریع unit — mutantهای باقیمانده، assertهای ضعیف را آشکار میکنند | **مشورتی** | +| `nightly-compat` | ماتریس سازگاری engine مربوط به Node در بازههای پشتیبانیشدهٔ `engines.node` | **مشورتی** | --- @@ -546,36 +542,36 @@ SLOهای هدف پس از راهاندازی تلهمتری آزمونهای ن `check:dead-code`، `check:cognitive-complexity`، `check:type-coverage`، `check:codeql-ratchet` و `check:pr-evidence` را از قلم انداخته بود). بازبینی ROI مجموعهی تطبیقدادهشده، گزینههای زیر را برای منطقیسازی مشخص کرد. **ادغامها تغییرات مکانیکی CI -هستند؛ تغییر وضعیتها/حذفها تصمیمهای سیاستیاند که در اختیار اپراتور قرار دارند.** هنوز هیچیک -از موارد زیر اعمال نشده است. +هستند؛ تغییر وضعیتها/حذفها تصمیمهای سیاستی محفوظ برای اپراتورند.** هنوز هیچیک از موارد +زیر اعمال نشده است. **موارد دیگری که در بالا مستند نشدهاند** (مشورتی، با سیگنال ضعیف): job مربوط به `docs-lint` -(markdownlint + Vale، با `continue-on-error` برای کل job) و workflowهای اسکنر مستقل +(markdownlint + Vale، با `continue-on-error` برای کل job) و workflowهای مستقل اسکنر `semgrep.yml` / `codeql.yml` / `scorecard.yml`. مقدار `semgrepFindings: 0` در -`quality-baseline.json` وجود دارد، اما در `ci.yml` به ratchet مسدودکنندهای متصل نیست — این معیار -در حال حاضر بدون استفاده مانده است. +`quality-baseline.json` وجود دارد، اما در `ci.yml` به یک ضامن افزایشی مسدودکننده متصل +نیست — این معیار در حال حاضر بدون استفاده مانده است. -### ادغام / حذف موارد تکراری (مکانیکی، با ریسک کمتر) +### ادغام / حذف موارد تکراری (مکانیکی، کمریسکتر) -هر گزینه در 2026-06-17 با وضعیت زندهی gate اعتبارسنجی شد (اعتماد کن، اما راستیآزمایی هم بکن)؛ -چند ادغام «بدیهی» مشخص شد که بدهی پنهانی دارند و **جایگزینهای مستقیم و بیدردسری نیستند**. +هر گزینه در 2026-06-17 در برابر وضعیت زندهی gate اعتبارسنجی شد (اعتماد، همراه با راستیآزمایی)؛ +مشخص شد چندین ادغام «بدیهی» بدهی پنهان دارند و جایگزینهای مستقیم و **پاکی نیستند**. -- **`check:docs-sync` دو بار اجرا میشود** — یکبار بهصورت مستقل در job مربوط به `lint` و بار دیگر داخل `check:docs-all` (`docs-sync-strict`) و hook مربوط به pre-commit در husky. ✅ **انجام شد** — فراخوانی مستقل `lint` حذف شد. -- **اسکن CVE** — ❌ **ادغام تمیزی نیست.** `audit:deps` در صورت وجود هر CVE با شدت بالا/بحرانی، hard-fail میشود؛ `check:vuln-ratchet` (osv) فقط در صورت وقوع _پسرفت_ نسبت به baseline شکست میخورد (در حال حاضر 1 مورد MODERATE). معناشناسی آنها متفاوت است — حذف `audit:deps` باعث از دست رفتن gate مطلق مربوط به شدت بالا/بحرانی میشود. هر دو حفظ شوند. -- **تشخیص چرخه** — ❌ **ادغام تمیزی نیست.** `check:circular-deps` (dpdm) تعداد **91 چرخه** گزارش میکند (به همین دلیل مشورتی است)؛ بدون برطرفکردن آنها نمیتوان آن را به حالت مسدودکننده ارتقا داد و دامنهی آن از `check:cycles` سبز و گزینششده گستردهتر است. `check:cycles` بهصورت مسدودکننده حفظ شود؛ رفع 91 چرخهی dpdm خود یک مورد مستقل در فهرست معوقه است. -- **پیچیدگی** — ✅ **انجام شد** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): یک پیمایش ESLint، با شمارش بر اساس ruleId تا baselineهای cyclomatic+max-lines و cognitive مستقل بمانند؛ `check:complexity` / `check:cognitive-complexity` جداگانه برای اجرای محلی با `--update` حفظ میشوند. -- **ضدتوهم `/api`** — ✅ **انجام شد** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): یک فهرستبرداری FS از `src/app/api`؛ openapi-routes و docs-symbols همچنان بهطور مستقل گزارش میدهند؛ موارد جداگانه برای اجراهای محلی حفظ میشوند. -- **`check:node-runtime` در 11 job اجرا میشود** — ⚠️ **ROI پایین.** هرکدام روی runner جداگانهای اجرا میشوند و زمان بررسی کمتر از 1 ثانیه است؛ صرفهجویی کلی حدود 10 ثانیه خواهد بود، درحالیکه یک محافظ ارزانقیمت برای هر job از دست میرود. ارزش این تغییر را ندارد. -- **`typecheck:noimplicit:core` در lint مربوط به CI** — ✅ **از job مربوط به lint حذف شد** (قبلاً با `continue-on-error` مشورتی بود)؛ سطح type مسدودکننده شامل `typecheck:core` + `check:type-coverage` است. اسکریپت محلی حفظ شد. +- **`check:docs-sync` دو بار اجرا میشود** — یک بار بهصورت مستقل در job مربوط به `lint` و بار دیگر درون `check:docs-all` (`docs-sync-strict`) و hook مربوط به pre-commit در husky. ✅ **انجام شد** — فراخوانی مستقل از `lint` حذف شد. +- **اسکن CVE** — ❌ **ادغام پاکی نیست.** `audit:deps` در صورت وجود هر CVE با شدت بالا/بحرانی، قاطعانه شکست میخورد؛ `check:vuln-ratchet` (osv) تنها در صورت وجود یک _پسرفت_ نسبت به خط مبنا شکست میخورد (در حال حاضر 1 مورد MODERATE). معناشناسی آنها متفاوت است — حذف `audit:deps` باعث از دست رفتن gate مطلق مربوط به شدت بالا/بحرانی میشود. هر دو حفظ شوند. +- **تشخیص چرخه** — ✅ **انجام شد** (#15159 G-01/G-02). متن قدیمی این بخش، `check:cycles` را gate «سبز و گزینششده» مینامید و مسدودکننده ماندن آن را با این استدلال توجیه میکرد که `check:circular-deps` (dpdm) تعداد 91 چرخه گزارش میدهد. آن وضعیت سبز، یک **سبز کاذب** بود: `check:cycles` تعداد 5 زیرشاخه (450 فایل) را اسکن میکرد، تنها با `import|export … from` ایستا تطبیق مییافت و همهی specifierهای `@/` و `@omniroute/open-sse/` را کنار میگذاشت؛ بنابراین نمیتوانست چرخههای import پویا + alias را که در مخزن غالب بودند ببیند. اصلاح شد: اکنون gate در `src` + `open-sse` پیمایش میکند (5023 فایل)، specifierها را از AST مربوط به TypeScript جمعآوری میکند (بنابراین `import("…")` محاسبه میشود، اما `typeof import("…")` در جایگاه type محاسبه نمیشود) و `paths` مربوط به tsconfig را resolve میکند. این gate **14** چرخه پیدا میکند، نه 0. از آنجا که 14 چرخهی ازپیشموجود را نمیتوان در یک PR مربوط به gate اصلاح کرد، اکنون `check:cycles` یک **ضامن افزایشی** است (`--ratchet`، سقف `metrics.cycles.value = 14` در `quality-baseline.json`، با `direction: down`) — هرگونه _پسرفت_ را مسدود میکند و تعداد چرخهها فقط میتواند کاهش یابد. CI دستور `npm run check:cycles:ratchet` را اجرا میکند. کاهش تدریجی همراه با **A-01** انجام میشود. `check:circular-deps` (dpdm) بهعنوان دیدگاه دوم و گستردهتر، مشورتی باقی میماند. +- **پیچیدگی** — ✅ **انجام شد** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): یک پیمایش ESLint، با شمارش بر اساس ruleId تا خطوط مبنای cyclomatic+max-lines و cognitive مستقل بمانند؛ `check:complexity` / `check:cognitive-complexity` منفرد برای اجرای محلی `--update` باقی میمانند. +- **ضد توهمزایی `/api`** — ✅ **انجام شد** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): یک فهرستبرداری FS از `src/app/api`؛ openapi-routes + docs-symbols همچنان مستقل گزارش میدهند؛ موارد منفرد برای اجراهای محلی باقی میمانند. +- **`check:node-runtime` در 11 job اجرا میشود** — ⚠️ **ROI پایین.** هرکدام runner جداگانهای دارند و بررسی کمتر از 1 ثانیه طول میکشد؛ صرفهجویی کل حدود 10 ثانیه است، در مقابل از دست دادن یک محافظ ارزان برای هر job. ارزش آشفتگی ناشی از تغییر را ندارد. +- **`typecheck:noimplicit:core` در lint مربوط به CI** — ✅ **از job مربوط به lint حذف شد** (مشورتی و دارای `continue-on-error` بود)؛ سطح type مسدودکننده عبارت است از `typecheck:core` + `check:type-coverage`. اسکریپت محلی حفظ شد. ### تغییر وضعیت / تصمیمگیری (سیاست اپراتور) -- `check:openapi-security-tiers` (مشورتی) — ❌ **نمیتوان وضعیت آن را بهسادگی تغییر داد.** با کد 0 خارج میشود، اما هشدار میدهد که چند route مربوط به `traffic-inspector` تحت `LOCAL_ONLY_API_PREFIXES` فاقد annotation مربوط به `x-loopback-only: true` هستند. اجباریکردن آن مستلزم افزودن آن annotationها به `openapi.yaml` است. -- `typecheck:noimplicit:core` (مشورتی) — تا حد زیادی توسط ratchet مسدودکنندهی `check:type-coverage` پوشش داده میشود. آن را به ratchet تبدیل کنید یا اجرای دوم و تکراری `tsc` را حذف کنید. -- `test:vitest:ui` (اکنون **مسدودکننده**) — شکستهای ازپیشموجود در `vitest.config.ts` بهطور صریح با کامنتهای پیگیری `// #8618` مستثنا شدهاند؛ شکستهای جدید باعث شکست job میشوند. -- `check:secrets` (gitleaks، یک ratchet مسدودکننده که روی 3 مثبت کاذب مستندشده ثابت شده است) — آن 3 مورد را در allowlist قرار دهید تا به 0 برسد، یا آن را به حالت مشورتی تنزل دهید. با secret-scanning بومی GitHub و `check:public-creds` همپوشانی دارد. -- `check:pr-evidence` (مسدودکننده، متن بدنهی PR را با grep جستوجو میکند) — ریسک مثبت کاذب بالایی دارد؛ حذف آن اجرای Hard Rule #18 را تضعیف میکند، بنابراین این واقعاً یک تصمیم سیاستی است. -- `semgrep` (مستقل و مشورتی) — برای خانوادههای OWASP با CodeQL همپوشانی دارد؛ baseline آن را به یک ratchet متصل کنید یا حذفش کنید. +- `check:openapi-security-tiers` (مشورتی) — ❌ **نمیتوان وضعیت آن را بهصورت پاک تغییر داد.** با کد 0 خارج میشود، اما هشدار میدهد که چندین route مربوط به `traffic-inspector` ذیل `LOCAL_ONLY_API_PREFIXES` فاقد annotation مربوط به `x-loopback-only: true` هستند. اعمال اجباری آن مستلزم افزودن این annotationها به `openapi.yaml` است. +- `typecheck:noimplicit:core` (مشورتی) — تا حد زیادی تحت پوشش ضامن افزایشی مسدودکنندهی `check:type-coverage` قرار دارد. آن را به ضامن افزایشی تبدیل کنید یا دومین اجرای زائد `tsc` را حذف کنید. +- `test:vitest:ui` (اکنون **مسدودکننده**) — شکستهای ازپیشموجود در `vitest.config.ts` با commentهای ردیابی `// #8618` صراحتاً مستثنا شدهاند؛ شکستهای جدید باعث شکست job میشوند. +- `check:secrets` (gitleaks، ضامن افزایشی مسدودکننده که روی 3 مثبت کاذب مستندشده ثابت شده است) — آن 3 مورد را در allowlist قرار دهید تا به 0 برسد، یا آن را به حالت مشورتی تنزل دهید. با secret-scanning بومی GitHub و `check:public-creds` همپوشانی دارد. +- `check:pr-evidence` (مسدودکننده، متن بدنهی PR را با grep بررسی میکند) — ریسک مثبت کاذب بالایی دارد؛ حذف آن اجرای Hard Rule #18 را تضعیف میکند، بنابراین این مورد واقعاً یک تصمیم سیاستی است. +- `semgrep` (مستقل و مشورتی) — برای خانوادههای OWASP با CodeQL همپوشانی دارد؛ خط مبنای آن را به یک ضامن افزایشی متصل کنید یا حذفش کنید. --- diff --git a/docs/i18n/fi/CONTRIBUTING.md b/docs/i18n/fi/CONTRIBUTING.md index a9fa028c96e..93070c576a6 100644 --- a/docs/i18n/fi/CONTRIBUTING.md +++ b/docs/i18n/fi/CONTRIBUTING.md @@ -388,20 +388,20 @@ Kirjoita hakemistoon `tests/unit/` yksikkötestit, jotka kattavat vähintään s ## Pull Request -tarkistuslista -- [ ] Testit läpäisty (`npm test`) -- [ ] Linttaus läpäisty (`npm run lint`) +- [ ] Testit läpäisevät (`npm test`) +- [ ] Linttaus läpäisee (`npm run lint`) - [ ] Koonti onnistuu (`npm run build`) - [ ] TypeScript-tyypit lisätty uusille julkisille funktioille ja rajapinnoille -- [ ] Ei kovakoodattuja salaisuuksia tai varaarvoja -- [ ] Julkiset upstream-tunnistetiedot upotettu `resolvePublicCred()`-funktion kautta (katso [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ei koskaan literaaleina -- [ ] Virhevastaukset kulkevat `buildErrorBody()`- / `sanitizeErrorMessage()`-funktioiden kautta — vastausten sisällöissä ei ole käsittelemättömiä pinojäljityksiä (katso [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Komentotulkkikomennot (`exec` / `spawn`) välittävät suorituksenaikaiset arvot `env`-ympäristön kautta, eivät merkkijonointerpoloinnilla +- [ ] Ei kovakoodattuja salaisuuksia tai varmistusarvoja +- [ ] Julkiset upstream-tunnistetiedot upotettu `resolvePublicCred()`-funktion avulla (katso [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ei koskaan literaaleina +- [ ] Virhevastaukset käsitellään `buildErrorBody()`- / `sanitizeErrorMessage()`-funktioiden kautta — vastausten sisältö ei sisällä käsittelemättömiä pinojälkiä (katso [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Komentotulkin komennot (`exec` / `spawn`) välittävät ajonaikaiset arvot `env`-muuttujan kautta, eivät merkkijonointerpolaatiolla - [ ] Kaikki syötteet validoitu Zod-skeemoilla -- [ ] Käyttäjille näkyvistä muutoksista lisätty muutoslokin **fragmentti** hakemistoon `changelog.d/{features|fixes|maintenance}/-.md` (katso [`changelog.d/README.md`](./changelog.d/README.md)) — **älä** muokkaa tiedostoa `CHANGELOG.md` suoraan; fragmentit yhdistetään julkaisun yhteydessä, eivätkä ne koskaan aiheuta ristiriitoja PR:ien välillä +- [ ] Käyttäjille näkyvistä muutoksista lisätty muutoslokin **katkelma** hakemistoon `changelog.d/{features|fixes|maintenance}/-.md` (katso [`changelog.d/README.md`](./changelog.d/README.md)) — älä muokkaa `CHANGELOG.md`-tiedostoa suoraan; katkelmat yhdistetään julkaisuhetkellä, eivätkä ne koskaan aiheuta ristiriitoja PR:ien välillä - [ ] Dokumentaatio päivitetty (tarvittaessa) -- [ ] Uusia CodeQL- tai Secret-Scanning-hälytyksiä ei ole avattu, tai jokainen niistä on hylätty teknisin perusteluin ja viittauksin asiaankuuluvaan `docs/security/`-dokumenttiin +- [ ] Uusia CodeQL- tai Secret-Scanning-hälytyksiä ei ole avattu, tai jokainen niistä on kuitattu teknisellä perustelulla, jossa viitataan asianmukaiseen `docs/security/`-dokumenttiin - [ ] Aliprosesseja käynnistävät reitit (`/api/mcp/`, `/api/cli-tools/runtime/`) luokiteltu `isLocalOnlyPath()`-funktion avulla tiedostossa `src/server/authz/routeGuard.ts` — katso [ehdoton sääntö #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Commit-viesteissä ei ole `Co-Authored-By`-trailereita — commitien on näyttävä yksinomaan repositorion omistajan Git-identiteetin alla (ehdoton sääntö #16) +- [ ] Commit-viesteissä ei ole tekoäly-/bottiavustajien `Co-authored-by`-lopputunnisteita (ehdoton sääntö #16) — ihmiskollaboraattorit, joiden työtä hyödynnetään, mainitaan tavanomaisilla `Co-authored-by: Name ` -lopputunnisteilla --- diff --git a/docs/i18n/fi/docs/architecture/QUALITY_GATES.md b/docs/i18n/fi/docs/architecture/QUALITY_GATES.md index 5cf30d35e50..2ed398d2d33 100644 --- a/docs/i18n/fi/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/fi/docs/architecture/QUALITY_GATES.md @@ -15,50 +15,50 @@ työkaluista riippumaton toisintamissuunnitelma ovat --- -## Porttien inventaario ja suoritusprofiilit +## Porttien luettelo ja suoritusprofiilit ### Ehdokkaiden hyväksyntä CI- ja Quality Gates -työnkulut tuottavat kumpikin vakaan tuloksen: `Gate / CI` ja -`Gate / Quality`. Niiden versioitu hyväksyntäkäytäntö luettelee jokaisen edeltävän työn -pakolliseksi tai neuvoa-antavaksi. Soveltuvan pakollisen työn on onnistuttava: puuttuvat, -peruutetut, ohitetut, odottavat ja tuntemattomat tulokset eivät voi muodostaa PASS-tulosta. Kelvollinen -vain dokumentaatiota tai vain luetteloa koskeva luokitus voi tehdä koodikaistasta soveltumattoman; -luonnos-PR ei ole hyväksytty ehdokas. `hotfix`-tunniste ei poista näyttövaatimusta. +`Gate / Quality`. Niiden versioitu hyväksyntäkäytäntö määrittää jokaisen edeltävän työn +pakolliseksi tai neuvoa-antavaksi. Soveltuvan pakollisen työn on onnistuttava: puuttuva, +peruutettu, ohitettu, keskeneräinen tai tuntematon tulos ei voi vahvistaa PASS-tulosta. Kelvollinen +vain dokumentaatiota tai vain luetteloa koskeva luokitus voi tehdä koodilinjasta soveltumattoman; +luonnostilassa oleva PR ei ole hyväksytty ehdokas. `hotfix`-tunniste ei poista näyttövaatimusta. -Molemmat työnkulut kattavat PR:t ja työnnöt main/release-haaroihin, manuaaliset käynnistykset sekä -merge-group-tapahtumat. Työnnöt, käynnistykset ja merge-group-tapahtumat suorittavat koko valikoiman. Forkit -ja yhdistämisryhmät käyttävät ylläpidettyjä suorittimia töissä, jotka muutoin valitsisivat itse ylläpidetyt -suorittimet; riittävä ylläpidetty kapasiteetti on varmistettava ennen käyttöönottoa. +Molemmat työnkulut kattavat PR:t ja pushit main/release-haaroihin, manuaalisen käynnistyksen sekä +merge-group-tapahtumat. Push, dispatch ja merge-group suorittavat täyden valinnan. Forkit +ja yhdistämisryhmät käyttävät ylläpidettyjä suorittimia töissä, jotka muutoin valitsevat itse ylläpidetyt +suorittimet; ylläpidetyn kapasiteetin riittävyys on varmistettava ennen käyttöönottoa. Jokainen JSON-kuitti yksilöi uloskuitatun SHA:n, työnkulun suorituksen ja yrityksen. -CLI hylkää uloskuittauksen ja tapahtuman SHA-arvojen ristiriidan. Työnkulkutestit sitovat käytäntöön kuulumisen -tulostyön `needs`-luetteloon, jotta uusi tai poistettu kaista ei voi kadota huomaamatta. -Kuitit kattavat oman työnkulkunsa, eivät julkaisua, käyttöönottoa tai olemassa olevan -neuvoa-antavan skannerin sisäistä toimintaa. Molempien tarkistusnimien aktivointi haarasäännöissä on +CLI hylkää tilanteen, jossa uloskuittauksen SHA ja tapahtuman SHA eivät täsmää. Työnkulkutestit sitovat käytäntöjäsenyyden +tulostyön `needs`-luetteloon, jotta uusi tai poistettu linja ei voi kadota huomaamatta. +Kuitit kattavat oman työnkulkunsa, eivät julkaisua, käyttöönottoa tai +olemassa olevan neuvoa-antavan skannerin sisäistä toimintaa. Molempien tarkistusnimien aktivoiminen haarasäännöissä on erillinen hallinnollinen muutos; näiden töiden lisääminen ei itsessään suojaa haaraa. -### Staattisen tarkistuksen inventaario +### Staattisen tarkistuksen luettelo -Versioitu npm-aliasten inventaario ja staattisen tarkistuksen jäsenyys sijaitsevat tiedostossa +Versioitu npm-aliasten luettelo ja staattisen tarkistuksen jäsenyydet sijaitsevat tiedostossa `config/quality/gate-manifest.json`. Suorita `npm run check:gate-manifest` vahvistaaksesi -skriptien nimet ja täsmälliset komennot tiedostoa `package.json` vasten; lisäykset, poistot ja -komentojen poikkeamat aiheuttavat virheen sekä paikallisessa koukussa että CI:n muutosluokittelutöissä. -Alias ei ole työnkulkutyö, matriisi-ilmentymä tai testitapaus: näitä määriä -ei pidä esittää keskenään vaihdettavina. +skriptien nimet ja tarkat komennot suhteessa tiedostoon `package.json`; lisäykset, poistot ja +komentojen muutokset aiheuttavat virheen sekä paikallisessa hookissa että CI:n muutosluokittelutöissä. +Alias ei ole työnkulun työ, matriisi-instanssi tai testitapaus: näitä määriä ei saa +esittää keskenään vaihdettavina. Käytä komentoa `npm run quality:scan -- --list` tai `npm run quality:scan:fast -- --list` tarkastellaksesi valittuja aliaksia suorittamatta niitä. Suoritin kutsuu -npm-aloituskohtaa, joten sen suoritusympäristö (mukaan lukien Bun, jos määritetty) säilyy. -Manifesti kirjaa näiden profiilien ulkopuoliset aliakset erikseen käynnistettäviksi, ja -ylläpitokomennot on kielletty vain luku -tarkistusprofiileissa. +npm-aloituskohtaa, joten sen suoritusympäristö (mukaan lukien Bun, jos se on määritetty) säilyy. +Manifesti kirjaa näiden profiilien ulkopuoliset aliakset erikseen kutsuttaviksi, ja +ylläpitokomennot ovat kiellettyjä vain luku -tarkistusprofiileissa. -Nämä profiilit kattavat vain staattisen tarkistuksen. Ne eivät varmenna tuotetestejä, +Nämä profiilit kattavat vain staattisen tarkistuksen. Ne eivät sertifioi tuotetestejä, kattavuutta, paketointia, ulkoisia tarkistuksia tai ehdokkaan täyttä julkaisuhyväksyntää. -Työnkulun hyväksyntä käyttää linkitettyjä tiedostoa `config/quality/admission-policy.json` ja -`scripts/quality/admission-verdict.mjs`. Julkaisun tarkkailuprofiilit pysyvät erillisinä; +Työnkulun hyväksyntä käyttää linkitettyä tiedostoa `config/quality/admission-policy.json` ja +skriptiä `scripts/quality/admission-verdict.mjs`. Release-observer-profiilit pysyvät erillisinä; tarkasta niiden soveltuvat tarkistukset ja kuitit itsenäisesti. Alla oleva sanallinen -inventaario on viite, ei todiste siitä, että portti todella suoritettiin. +luettelo on viite, ei todiste siitä, että portti todella suoritettiin. Skriptit sijaitsevat hakemistoissa `scripts/check/` (käytäntöportit) ja `scripts/quality/` (ratchet-moottori). CI:n totuuden lähde on `.github/workflows/ci.yml`. @@ -66,213 +66,217 @@ CI:n totuuden lähde on `.github/workflows/ci.yml`. ### Julkaisu-PR:n nopea polku (`quality.yml`) `.github/workflows/quality.yml` täydentää CI:tä main/release-PR:issä, suojattujen haarojen -työnnöissä, käynnistyksissä ja yhdistämisryhmissä. PR:t käyttävät polkusuodatettuja nopeita tarkistuksia. Pysyvästi -käytöstä poistettu päällekkäinen koonti poistettiin; varsinaiset koonti-/paketointi-/käynnistystarkistukset säilyvät CI:ssä. - -| Työ | Laajuus | Estävä | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `Docs Gates (fast-path)` | Dokumentaatio-/koodi-PR:t; API-dokumentaation viitteet ja kaikki dokumentaatiot | Kyllä | -| `Fast Quality Gates` | Koodi-PR:t; staattiset tarkistukset, tyyppitarkistus, koontinäytön tyyppitarkistus, vaikutuksen alaiset yksikkötestit | Kyllä | -| `Forgotten sibling tests` | Koodi-PR:t; muuttuneiden moduulien jäljitys staattisiin kuluttajiin ja ehdolla oleviin rinnakkaistesteihin; barrel- ja dynaamisen tuonnin polut raportoidaan neuvoa-antavana diagnostiikkana viitattuine sallittujen poikkeusten luetteloineen | **Neuvoa-antava** | -| `Vitest (fast-path)` | Koodi-PR:t; nopea vitest-testikokoelma | Kyllä | -| `Unit Tests fast-path` | Koodi-PR:t; neljään osaan jaettu yksikkötestikokoelma | Kyllä | -| `No new ESLint warnings` | Koodi-PR:t; poikkeusten huomioiva lint-suoja | Kyllä, myös forkeissa | -| `Merge integrity (changelog + generated skills)` | Muut kuin luonnos-PR:t; muutoslokin ja generoitujen taitojen synkronointi | Kyllä, myös forkeissa | +pusheissa, dispatch-käynnistyksissä ja yhdistämisryhmissä. PR:t käyttävät polkusuodatettuja nopeita tarkistuksia. Pysyvästi +käytöstä poistettu päällekkäinen koonti poistettiin; varsinaiset koonti-, paketointi- ja käynnistystarkistukset säilyvät CI:ssä. + +| Työ | Laajuus | Estävä | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `Docs Gates (fast-path)` | Dokumentaatio-/koodi-PR:t; API-dokumentaation viitteet ja kaikki dokumentaatiot | Kyllä | +| `Fast Quality Gates` | Koodi-PR:t; staattiset tarkistukset, tyyppitarkistus, koontinäytön tyyppitarkistus, vaikutuksenalaiset yksikkötestit | Kyllä | +| `Forgotten sibling tests` | Koodi-PR:t; muuttuneet moduulit jäljitetään staattisiin käyttäjiin ja mahdollisiin rinnakkaistesteihin; barrel- ja dynaamisen tuonnin polut raportoidaan neuvoa-antavina diagnostiikkoina yhdessä viitattujen sallittujen poikkeusten kanssa | **Neuvoa-antava** | +| `Vitest (fast-path)` | Koodi-PR:t; nopea vitest-testikokonaisuus | Kyllä | +| `Unit Tests fast-path` | Koodi-PR:t; neljään osaan jaettu yksikkötestikokonaisuus | Kyllä | +| `No new ESLint warnings` | Koodi-PR:t; ohitukset huomioiva lint-suojatarkistus | Kyllä, myös forkeissa | +| `Merge integrity (changelog + generated skills)` | Muut kuin luonnostilassa olevat PR:t; muutoslokin ja generoitujen taitojen synkronointi | Kyllä, myös forkeissa | #### Unohtuneiden rinnakkaistestien raportti -`npm run check:forgotten-sibling-tests` käyttää uudelleen testivaikutuskartan taustalla olevaa tuontien selvittäjää. -Jokaisesta muuttuneesta tuotantomoduulista se raportoi deterministiset -`muuttunut moduuli/symboli -> staattinen kuluttaja -> ehdolla oleva rinnakkaistesti` -ketjut, kun ehdolla oleva +`npm run check:forgotten-sibling-tests` käyttää uudelleen testivaikutuskartan taustalla olevaa tuontiresolveria. +Jokaiselle muuttuneelle tuotantomoduulille se raportoi deterministiset +`muuttunut moduuli/symboli -> staattinen käyttäjä -> mahdollinen rinnakkaistesti` -ketjut, kun mahdollinen testi puuttuu pull requestin diffistä. Markdown-yhteenveto ja JSON-tulos säilytetään `forgotten-sibling-tests`-työnkulkuartefaktina kalibrointia varten ennen mahdollista estävää käyttöönottoa. -Barrel-uudelleenviennit ja dynaamiset tuonnit ovat vain moduulien selvityksen diagnostiikkaa; ne eivät koskaan luo +Barrel-uudelleenviennit ja dynaamiset tuonnit ovat vain ratkaisudiagnostiikkaa; ne eivät koskaan luo estävää havaintoa. Tarkistetut poikkeukset sijaitsevat tiedostossa `config/quality/forgotten-sibling-allowlist.json`. Jokaisessa merkinnässä on nimettävä kuluttaja ja ehdolla oleva -testi, annettava täsmällinen perustelu ja linkitettävä GitHub-ongelmaan tai pull request -pyyntöön. Virheelliset merkinnät -hylätään turvallisesti. Poikkeukset eivät voi sivuuttaa poistettua ehdokastestiä tai diffiä, joka lisää `.skip`- tai `.todo`-merkinnän; -assertioiden heikentäminen ja muu peittäminen kuuluvat edelleen itsenäisesti estävälle +testi, annettava täsmällinen perustelu ja linkitettävä GitHub-ongelmaan tai vetopyyntöön. Virheelliset merkinnät +hylätään turvallisesti. Poikkeukset eivät voi ohittaa poistettua ehdokastestiä tai diffiä, joka lisää `.skip`- tai `.todo`-määrityksen; +väitteiden heikentäminen ja muu peittäminen kuuluvat edelleen itsenäisesti estävälle `check:test-masking`-portille. ### Työ: `lint` -Suoritetaan jokaiselle `main`-haaraan kohdistuvalle PR:lle. Epäonnistuminen estää yhdistämisen. - -| Skripti (`npm run ...`) | Tarkistaa | Estävä | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `check:node-runtime` | Node.js-versio on tuetulla alueella | Kyllä | -| `check:cycles` | Kehämäiset tuonnit — kaikki `src/`- ja `open-sse/`-moduulit | Kyllä | -| `check:route-validation:t06` | Zod-skeemat ovat käytössä kaikilla reiteillä (tason 6 käytäntö) | Kyllä | -| `check:any-budget:t11` | `@ts-expect-error // any` -määrä ei ylitä budjettia (tason 11 catraca) | Kyllä | -| `check:provider-consistency` | Jokaisella tiedoston `providers.ts` tarjoajalla on vastaava merkintä tiedostossa `providerRegistry.ts` (ja päinvastoin sallittujen luettelon puitteissa) | Kyllä | -| `check:model-lifecycle` | Kolme käsin ylläpidettävää reititystaulukkoa pysyvät yhdenmukaisina versionhallintaan tallennetun elinkaarikatselmuksen (#11503) kanssa: `FITNESS_TABLE` (`taskFitness.ts`) ei pisteytä yhtäkään poistunutta tunnistetta, jonka `REGISTRY` voi reitittää; jokainen `BUILT_IN_ALIASES`-kohde on mukana `REGISTRY`-rekisterissä eikä sisälly poistuneiden tunnisteiden katselmukseen; jokainen poistunut tunniste, joka on yhä `REGISTRY`-rekisterissä, välitetään eteenpäin tai luetellaan `allowedRetiredInCatalog`-luettelossa; eikä yksikään `DEFAULT_DEGRADATION_MAP`-lähde tai -kohde näy poistuneena kyseisessä katselmuksessa. Tämä ei todista, että malli on tällä hetkellä saatavilla toimivan ylävirran kautta. Suoritetaan offline-tilassa — vertaa tiedostoon `config/quality/model-lifecycle.json`, joka päivitetään käsin komennolla `npm run quality:refresh-model-lifecycle` (vaatii verkkoyhteyden; ei ole kytketty CI-putkeen). `allowedRetiredInCatalog` on asteittain tyhjennettävä yksisuuntainen rajoitin: lisää merkintä vain, jos sille on seurantatehtävä. | Kyllä | -| `check:fetch-targets` | Jokainen asiakaspuolen hakemiston `src/` kutsu `fetch("/api/...")` viittaa olemassa olevaan `route.ts`-tiedostoon | Kyllä | -| `check:deps` | Kaikki `npm install` -komennolla asennettavat riippuvuudet jokaisessa repositorion `package.json`-tiedostossa ovat mukana tiedostossa `dependency-allowlist.json`; uudet versioon lukitsemattomat tai kirjoitusvirheeseen perustuvaa pakettikaappausta hyödyntävät paketit merkitään | Kyllä | -| `audit:deps` | `npm audit` (juuri + electron) — ei vakavuudeltaan korkeita tai kriittisiä varoituksia (päällekkäinen osv-tarkistuksen `check:vuln-ratchet` kanssa; katso rationalisointijono) | Kyllä | -| `check:lockfile` | `package-lock.json`-tiedoston eheys — https-rekisteri, eheystiivisteet, ei isäntäkohtaisia ohituksia | Kyllä | -| `check:licenses` | Tuotantoriippuvuuksien SPDX-lisenssien sallittujen luettelo | Kyllä | -| `check:tracked-artifacts` | Ei koontiartefakteja / versionhallintaan lisättyjä `node_modules`-symbolisia linkkejä (suoritetaan myös huskyn pre-commit-koukussa; pre-push on tarkoituksella kevyt — #6716) | Kyllä | -| `check:ai-attribution` | Ei tekoälyn/botin `Co-Authored-By`-alatunnistetta tai tekoälyllä luomisesta kertovaa alatunnistetta PR:n commiteissa, otsikossa tai rungossa — ehdoton sääntö #16 (`quality.yml`-tiedoston nopeiden tarkistusten silmukassa PR→`release/**` — lukee tapahtuman hyötykuorman, ei tee mitään muille kuin PR:ille — sekä vain PR:ille suoritettavassa `ci.yml`-tiedoston lint-vaiheessa PR→`main`; myös huskyn `commit-msg`-koukussa; ihmiskirjoittajat sallitaan; #14436) | -| `check:vitest-exclusions` | Jokainen Vitest-poissulku nimeää seurantatehtävän ja esiintyy tiedostossa `config/quality/vitest-exclusions.json` (#13204) | Kyllä | -| `check:file-size` | Mikään lähdetiedosto ei ylitä tiedostopäätekohtaista enimmäiskokoa (räikkä: jäädytetyt suuret tiedostot `frozen`-luettelossa) | Kyllä | -| `check:error-helper` | Suorittimien/käsittelijöiden virhevastaukset käyttävät `buildErrorBody()`- / `sanitizeErrorMessage()`-funktiota (ehdoton sääntö #12) | Kyllä | -| `check:migration-numbering` | Migraatioiden SQL-tiedostot on numeroitu peräkkäin ilman aukkoja tai kaksoiskappaleita | Kyllä | -| `check:public-creds` | Ei literaaleja OAuth-`client_id`/`client_secret`-arvoja tai Firebase Web -avaimia `publicCreds.ts`-tiedoston ulkopuolella (ehdoton sääntö #11) | Kyllä | -| `check:db-rules` | Ei raakaa SQL:ää `src/lib/db/`-moduulien ulkopuolella; ei barrel-tuonteja `localDb.ts`-tiedostosta (ehdottomat säännöt #2/#5) | Kyllä | -| `check:known-symbols` | Välitystauluihinsa rekisteröidyt palveluntarjoajien suorittimet, reititysstrategiat ja muuntimet vastaavat levyllä olevia tiedostoja — ei irrallisia tai määrittelemättömiä symboleja | Kyllä | -| `check:route-guard-membership` | Jokainen aliprosessin käynnistävä reitti on luokiteltu `isLocalOnlyPath()`-funktiolla (ehdottomat säännöt #15/#17) | Kyllä | -| `check:test-discovery` | Vähintään yksi testiajo-ohjelma kerää jokaisen repositoriossa olevan `*.test.ts`- / `*.spec.ts`-tiedoston (ratchet: `test-discovery-baseline.json`-tiedoston irrallisten testien luettelo voi vain lyhentyä) | Kyllä | -| `check:agent-skills-sync` | Luodut agent-skills-artefaktit vastaavat lähdeluetteloaan (ei poikkeamia) | -| `check:provider-asset-provenance` | Palveluntarjoajien logoilla/resursseilla on kirjattu alkuperätieto | -| `lint:json` | JSON-määritystiedostot jäsentyvät ja täyttävät repositorion lint-säännöt | -| `typecheck:core` | TypeScript-käännös ilman virheitä (vain neuvoa-antavia varoituksia) | Kyllä | -| `typecheck:noimplicit:core` | Tiukka `noImplicitAny` — tulevaisuuteen suuntautuva; monet jo olemassa olevat kutsukohdat tarvitsevat edelleen annotaatioita | **Neuvoa-antava** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, jonka kohteena on `src/app/(dashboard)/**` (#7033) — `typecheck:core`-komennon tarkoin valittu 27 tiedoston sallittujen luettelo ei sisällä yhtään hallintapaneelin TSX-tiedostoa, eikä `next build` myöskään koskaan tee niille tyyppitarkistusta (`next.config.mjs` asettaa `ignoreBuildErrors: true`), joten irrallisiin tunnisteisiin liittyvät regressiot (#6625/#6909) eivät näkyneet CI:ssä. Eroja verrataan jäädytettyyn tiedosto- ja TS-koodikohtaisten määrien vertailutasoon (`config/quality/dashboard-typecheck-baseline.json`, sama vanhentuneisuuden valvontamalli kuin komennolla `check:known-symbols`) — vain vertailutason määrän ylittävät UUDET virheet hylkäävät tarkistuksen; alenna vertailutasoa komennolla `--update`, kun aiempi virhe on korjattu. | Kyllä | +Suoritetaan jokaisessa `main`-haaraan kohdistuvassa PR:ssä. Estää yhdistämisen epäonnistuessaan. + +| Skripti (`npm run ...`) | Tarkistaa | Estävä | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:node-runtime` | Node.js-versio on tuetulla alueella | Kyllä | +| `check:cycles` | Kehämäiset tuonnit koko `src/`- ja `open-sse/`-hakemistoissa (AST-pohjainen, tsconfigin `paths` ratkaistu). Pelkkä tarkistus on neuvoa-antava ja luettelee kehät. `check:cycles:ratchet` (jonka CI suorittaa) estää, kun määrä ylittää `quality-baseline.json`-tiedoston `metrics.cycles`-enimmäisrajan — tällä hetkellä 14, `direction: down`, joten määrä voi vain pienentyä (#15159 G-01/G-02) | Kyllä (räikkä) | +| `check:route-validation:t06` | Zod-skeemat ovat käytössä kaikilla reiteillä (tason 6 käytäntö) | Kyllä | +| `check:any-budget:t11` | `@ts-expect-error // any`-määrä ei ylitä budjettia (tason 11 räikkä) | Kyllä | +| `check:provider-consistency` | Jokaisella tiedoston `providers.ts` palveluntarjoajalla on vastaava merkintä tiedostossa `providerRegistry.ts` (ja päinvastoin sallittujen luettelon rajoissa) | Kyllä | +| `check:model-lifecycle` | Kolme käsin ylläpidettävää reititystaulukkoa pysyvät yhdenmukaisina versionhallintaan tallennetun elinkaarivedoksen (#11503) kanssa: `FITNESS_TABLE` (`taskFitness.ts`) ei pisteytä yhtäkään käytöstä poistettua tunnistetta, jonka `REGISTRY` voi reitittää; jokainen `BUILT_IN_ALIASES`-kohde sisältyy `REGISTRY`-rekisteriin eikä esiinny käytöstä poistettujen tunnisteiden vedoksessa; jokainen käytöstä poistettu tunniste, joka on yhä `REGISTRY`-rekisterissä, välitetään eteenpäin tai luetellaan kohdassa `allowedRetiredInCatalog`; eikä yksikään `DEFAULT_DEGRADATION_MAP`-lähde tai -kohde esiinny käytöstä poistettuna kyseisessä vedoksessa. Tämä ei todista, että aktiivinen upstream-palvelu tarjoaa mallia tällä hetkellä. Offline — vertaa tiedostoon `config/quality/model-lifecycle.json`, joka päivitetään käsin komennolla `npm run quality:refresh-model-lifecycle` (vaatii verkkoyhteyden; ei ole kytketty CI-järjestelmään). `allowedRetiredInCatalog` on asteittain supistettava lista: lisää merkintä vain, jos sille on seurantatehtävä. | Kyllä | +| `check:fetch-targets` | Jokainen asiakaspuolen `src/`-hakemistossa oleva `fetch("/api/...")` viittaa todelliseen `route.ts`-tiedostoon | Kyllä | +| `check:deps` | Kaikki repositorion jokaisen `package.json`-tiedoston `npm install` -komennolla asennettavat riippuvuudet sisältyvät tiedostoon `dependency-allowlist.json`; uudet versioon sitomattomat tai kirjoitusvirhetyyppisellä nimikaappauksella lisätyt paketit merkitään | Kyllä | +| `audit:deps` | `npm audit` (juuri + electron) — ei vakavia/kriittisiä varoituksia (osittain päällekkäinen OSV-tarkistuksen `check:vuln-ratchet` kanssa; katso Rationalisointijono) | Kyllä | +| `check:lockfile` | `package-lock.json`-tiedoston eheys — HTTPS-rekisteri, eheystiivisteet, ei palvelinkohtaisia ohituksia | Kyllä | +| `check:licenses` | Tuotantoriippuvuuksien SPDX-lisenssien sallittujen luettelo | Kyllä | +| `check:tracked-artifacts` | Ei koontiartefakteja / versionhallintaan lisättyjä `node_modules`-symbolisia linkkejä (suoritetaan myös husky pre-commit -koukussa; pre-push on tarkoituksella kevyt — #6716) | Kyllä | +| `check:ai-attribution` | Ei tekoälyn/botin `Co-Authored-By`-lopuketta tai tekoälygeneroinnin alatunnistetta PR-commiteissa, otsikossa tai kuvauksessa — ehdoton sääntö #16 (`quality.yml`-tiedoston nopeiden tarkistusten silmukassa PR→`release/**` — lukee tapahtuman hyötykuorman, ei tee mitään PR:ien ulkopuolella — sekä vain PR:ille suoritettavana vaiheena `ci.yml`-tiedoston lint-tarkistuksessa PR→`main`; myös husky `commit-msg` -koukussa; ihmiset sallitaan kanssakirjoittajina; #14436) | +| `check:vitest-exclusions` | Jokainen Vitest-poissulku nimeää seurantatehtävän ja esiintyy tiedostossa `config/quality/vitest-exclusions.json` (#13204) | Kyllä | +| `check:file-size` | Mikään lähdetiedosto ei ylitä tiedostopäätekohtaista enimmäiskokoa (räikkä: suuret tiedostot jäädytetty `frozen`-luettelossa) | Kyllä | +| `check:error-helper` | Suorittimien/käsittelijöiden virhevastaukset käyttävät funktioita `buildErrorBody()` / `sanitizeErrorMessage()` (ehdoton sääntö #12) | Kyllä | +| `check:migration-numbering` | Migraatioiden SQL-tiedostot on numeroitu peräkkäin ilman aukkoja tai päällekkäisyyksiä | Kyllä | +| `check:public-creds` | Ei literaaleja OAuth-`client_id`/`client_secret`-arvoja tai Firebase Web -avaimia `publicCreds.ts`-tiedoston ulkopuolella (ehdoton sääntö #11) | Kyllä | +| `check:db-rules` | Ei raakaa SQL:ää `src/lib/db/`-moduulien ulkopuolella; ei barrel-tuonteja `localDb.ts`-tiedostosta (ehdottomat säännöt #2/#5) | Kyllä | +| `check:known-symbols` | Välitystauluihinsa rekisteröidyt palveluntarjoajien suorittimet, reititysstrategiat ja muuntimet vastaavat levyllä olevia tiedostoja — ei irrallisia tai ilmoittamattomia symboleja | Kyllä | +| `check:route-guard-membership` | Jokainen aliprosessin käynnistävä reitti on luokiteltu `isLocalOnlyPath()`-funktiolla (ehdottomat säännöt #15/#17) | Kyllä | +| `check:test-discovery` | Jokainen repositorion `*.test.ts`- / `*.spec.ts`-tiedosto sisältyy vähintään yhden testiajon keräämiin testeihin (räikkäperiaate: `test-discovery-baseline.json`-tiedoston irrallisten testien lista voi vain lyhentyä) | Kyllä | +| `check:agent-skills-sync` | Luodut agent-skills-artefaktit vastaavat lähdeluetteloaan (ei poikkeamia) | +| `check:provider-asset-provenance` | Palveluntarjoajien logoilla/resursseilla on kirjattu alkuperätietue | +| `lint:json` | JSON-määritystiedostot jäsentyvät ja täyttävät repositorion lint-säännöt | +| `typecheck:core` | TypeScript-käännös ilman virheitä (vain neuvoa-antavia varoituksia) | Kyllä | +| `typecheck:noimplicit:core` | Tiukka `noImplicitAny` — tulevaisuuteen suuntautuva; monet aiemmin olemassa olleet kutsukohdat tarvitsevat yhä annotaatioita | **Neuvoa-antava** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, jonka kohteena on `src/app/(dashboard)/**` (#7033) — `typecheck:core`-tarkistuksen rajattu 27 tiedoston sallittujen luettelo ei sisällä yhtään dashboard-TSX-tiedostoa, eikä `next build` myöskään koskaan tyyppitarkista niitä (`next.config.mjs` määrittää asetuksen `ignoreBuildErrors: true`), joten irrallisiin tunnisteisiin liittyvät regressiot (#6625/#6909) jäivät CI:ltä havaitsematta. Eroja verrataan jäädytettyyn tiedosto- ja TS-koodikohtaiseen lukumäärän perustasoon (`config/quality/dashboard-typecheck-baseline.json`, sama vanhentuneisuuden valvontamalli kuin tarkistuksessa `check:known-symbols`) — vain perustason määrän ylittävät UUDET virheet aiheuttavat portin epäonnistumisen; alenna perustasoa valitsimella `--update`, kun aiemmin olemassa ollut virhe korjataan. | Kyllä | ### Työ: `quality-gate` -Suoritetaan `test-coverage`-työn jälkeen. Epäonnistuminen estää yhdistämisen. +Suoritetaan `test-coverage`-työn jälkeen. Estää yhdistämisen epäonnistuessaan. -| Skripti | Tarkistaa | Estävä | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| `quality:collect` | Tuottaa tiedoston `quality-metrics.json` (ESLint-varoitusten määrä, yhdistetystä osaraportista saatu kattavuus) | Kyllä (ennen ratchet-vaihetta) | -| `quality:ratchet` | Yksikään tiedoston `quality-baseline.json` mittari ei ole heikentynyt (ESLint-varoitukset ≤ vertailutaso; kattavuus ≥ vertailutaso) | Kyllä | -| `check:duplication` | Koodin monistus (jscpd@4) ei ylitä tiedostossa `quality-baseline.json` määritettyä vertailutasoa | Kyllä | -| `check:complexity` | Tiedostotason syklomaattinen monimutkaisuus ei ylitä ylärajaa (ESLint-ytimen `complexity` + `max-lines-per-function`) | Kyllä | -| `check:cognitive-complexity` | Kognitiivisen monimutkaisuuden ratchet-tarkistus (`eslint-plugin-sonarjs`) — erillinen ESLint-ajo; CI ajaa molemmat yhdistettynä yhtenä `check:complexity-ratchets`-vaiheena | Kyllä | -| `check:dead-code` | Käyttämättömien vientien / tiedostojen ratchet-tarkistus (knip) ei heikkene vertailutasoon nähden | Kyllä | -| `check:compression-budget` | Pakkausvertailun budjetti — moottorikohtaiset token-säästöjen vähimmäistasot eivät saa heikentyä | Kyllä | -| `check:type-coverage` | Tyypitetyn osuuden ratchet-tarkistus (`type-coverage`) ei heikkene; korvaa suurelta osin tarkistuksen `typecheck:noimplicit:core` | Kyllä | -| `check:codeql-ratchet` | Avointen CodeQL-hälytysten määrä ei kasva (lukee komennolla `gh api`; ohitetaan hallitusti ilman tokenia) — päivitystiheys ja manuaalinen käynnistys: katso alta "CodeQL-ratchet" | Kyllä | +| Skripti | Tarkistaa | Estävä | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `quality:collect` | Tuottaa tiedoston `quality-metrics.json` (ESLint-varoitusten määrä, yhdistetystä osaraportista saatu kattavuus) | Kyllä (ratchet-vaihetta edeltävä) | +| `quality:ratchet` | Yksikään tiedoston `quality-baseline.json` mittari ei ole heikentynyt (ESLint-varoitukset ≤ vertailutaso; kattavuus ≥ vertailutaso) | Kyllä | +| `check:duplication` | Koodin duplikaatio (jscpd@4) ei ylitä tiedostossa `quality-baseline.json` määritettyä vertailutasoa | Kyllä | +| `check:complexity` | Tiedostotason syklomaattinen kompleksisuus ei ylitä ylärajaa (ESLint-ytimen `complexity` + `max-lines-per-function`) | Kyllä | +| `check:cognitive-complexity` | Kognitiivisen kompleksisuuden ratchet-tarkistus (`eslint-plugin-sonarjs`) — erillinen ESLint-ajo; CI suorittaa molemmat yhdistettynä yhtenä `check:complexity-ratchets`-vaiheena | Kyllä | +| `check:dead-code` | Käyttämättömien vientien/tiedostojen ratchet-tarkistus (knip) ei heikkene vertailutasoon nähden | Kyllä | +| `check:compression-budget` | Pakkauksen suorituskykytestin budjetti — moottorikohtaiset token-säästöjen vähimmäisrajat eivät saa heikentyä | Kyllä | +| `check:type-coverage` | Tyypitetyn osuuden ratchet-tarkistus (`type-coverage`) ei heikkene; korvaa suurelta osin tarkistuksen `typecheck:noimplicit:core` | Kyllä | +| `check:codeql-ratchet` | Avointen CodeQL-hälytysten määrä ei kasva (lukee komennolla `gh api`; ohitetaan hallitusti ilman tunnistetta) — päivitystiheys ja manuaalinen käynnistys: katso alta ”CodeQL-ratchet” | Kyllä | ### Työ: `quality-extended` Koko työ on neuvoa-antava (`continue-on-error: true`). npm-pohjaiset ratchet-tarkistukset suoritetaan oikeasti; ulkoiset skannerit asennetaan komennolla `gh release download`, ja ne ohittavat itsensä (exit 0), -jos binääri puuttuu edelleen. +jos binääriä ei vieläkään ole saatavilla. -| Skripti | Tarkistaa | Estävyys | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -| `check:circular-deps` | Ei syklisiä riippuvuuksia (dpdm) | **Neuvoa-antava** | -| `check:bundle-size` | Paketin koko ei ylitä ylärajaa | **Neuvoa-antava** | -| `check:secrets` | Salaisuuksien skannaus (gitleaks) — ohitetaan, jos binääri puuttuu | **Neuvoa-antava** | -| `check:vuln-ratchet` | Riippuvuuksien haavoittuvuudet (osv-scanner) eivät lisäänny — ohitetaan, jos binääri puuttuu | **Neuvoa-antava** | -| `check:workflows` | Työnkulkujen lint-tarkistus (actionlint + zizmor); puuttuvat/rikkinäiset skannerit, virheelliset raportit tai puuttuva ratchet-vertailutaso epäonnistuvat tilassa INCOMPLETE. Kelvollisiin löydöksiin sovelletaan valittua tiukkaa, neuvoa-antavaa tai ratchet-käytäntöä | Suoritus vaaditaan; zizmor-ratchet estää CI:ssä | -| `check:openapi-breaking` | Julkisen API-sopimuksen (`openapi.yaml`) rikkovat muutokset suhteessa perushaaraan (oasdiff) — tuottaa arvon `openapiBreaking=N`; ohitetaan, jos oasdiff puuttuu tai perusmääritystä ei voida selvittää | **Neuvoa-antava** | +| Skripti | Tarkistaa | Estävä | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | +| `check:circular-deps` | Ei syklisiä riippuvuuksia (dpdm) | **Neuvoa-antava** | +| `check:bundle-size` | Paketin koko ei ylitä ylärajaa | **Neuvoa-antava** | +| `check:secrets` | Salaisuuksien skannaus (gitleaks) — ohitetaan, jos binääri puuttuu | **Neuvoa-antava** | +| `check:vuln-ratchet` | Riippuvuuksien haavoittuvuudet (osv-scanner) eivät lisäänny — ohitetaan, jos binääri puuttuu | **Neuvoa-antava** | +| `check:workflows` | Työnkulkujen lint-tarkistus (actionlint + zizmor); puuttuvat tai vialliset skannerit, virheelliset raportit tai puuttuva ratchet-vertailutaso epäonnistuvat tilalla INCOMPLETE. Kelvollisiin löydöksiin sovelletaan valittua tiukkaa, neuvoa-antavaa tai ratchet-käytäntöä | Suoritus vaaditaan; zizmor-ratchet on estävä CI:ssä | +| `check:openapi-breaking` | Julkisen API-sopimuksen (`openapi.yaml`) rikkovat muutokset verrattuna perushaaraan (oasdiff) — tuottaa arvon `openapiBreaking=N`; ohitetaan, jos oasdiff puuttuu tai perusmääritystä ei voida selvittää | **Neuvoa-antava** | ### Työ: `docs-sync-strict` -Suoritetaan jokaisessa `main`-haaraan kohdistuvassa PR:ssä. Epäonnistuminen estää yhdistämisen. +Suoritetaan jokaiselle `main`-haaraan kohdistuvalle PR:lle. Epäonnistuminen estää yhdistämisen. | Skripti | Tarkistaa | Estävä | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | `check:docs-all` | Metaportti, joka suorittaa alla olevat 6 aliporttia peräkkäin | Kyllä | -| ↳ `check:docs-sync` | CHANGELOGin / OpenAPIn / llm.txt:n versioiden yhdenmukaisuus | Kyllä | -| ↳ `check:docs-counts` | Tekstissä ilmoitetut määrät (palveluntarjoajien määrä, migraatioiden määrä jne.) ovat todellisiin määriin perustuvan ratchet-ikkunan sisällä | Kyllä | +| ↳ `check:docs-sync` | CHANGELOGin / OpenAPIn / llm.txt:n versioiden yhdenmukaisuuden | Kyllä | +| ↳ `check:docs-counts` | Tekstissä ilmoitetut lukumäärät (palveluntarjoajien määrä, migraatioiden määrä jne.) ovat todellisten lukumäärien räikkäikkunan sisällä | Kyllä | | ↳ `check:env-doc-sync` | Jokainen `.env.example`-tiedoston ympäristömuuttuja on dokumentoitu dokumentaation taulukossa ja päinvastoin | Kyllä | | ↳ `check:deprecated-versions` | Dokumentaatiossa ei ole vanhentuneita versiomerkkijonoja | Kyllä | | ↳ `check:doc-links` | Dokumentaation sisäiset markdown-linkit viittaavat olemassa oleviin tiedostoihin (`[teksti]`/`(polku)`-muoto) | Kyllä | | ↳ `check:fabricated-docs` | Dokumentaatiossa mainitut reitit, ympäristömuuttujat, CLI-komennot, hook-nimet ja tiedostopolut ovat olemassa koodikannassa. Kova portti `--strict`-valitsimella; pehmeä epäonnistuminen ilman valitsinta. | Kyllä (`--strict` CI:ssä) | | `check:cli-i18n` | CLI-komentomerkkijonot ovat mukana kaikissa i18n-lokaalitiedostoissa | Kyllä | -| `check:openapi-coverage` | OpenAPI-määritys kattaa vähintään ratchet-menetelmällä määritetyn vähimmäismäärän todellisista reiteistä | Kyllä | -| `check:openapi-security-tiers` | `openapi.yaml`-tiedoston turvallisuustasomerkinnät ovat yhdenmukaisia `routeGuard.ts`-luokitusten kanssa | **Neuvoa-antava** | +| `check:openapi-coverage` | OpenAPI-määritys kattaa vähintään räikällä määritetyn vähimmäismäärän todellisista reiteistä | Kyllä | +| `check:openapi-security-tiers` | `openapi.yaml`-tiedoston suojaustasomerkinnät ovat yhdenmukaisia `routeGuard.ts`-tiedoston luokitusten kanssa | **Ohjeellinen** | | `check:openapi-routes` | Jokainen `openapi.yaml`-tiedoston polku viittaa todelliseen `route.ts`-tiedostoon (hallusinaatioiden esto) | Kyllä | -| `check:docs-symbols` | Jokainen `docs/**/*.md`-tiedostojen `/api/...`-viittaus viittaa todelliseen `route.ts`-tiedostoon (hallusinaatioiden esto) | Kyllä | -| `i18n translation drift` | Kääntämättömät avaimet i18n-lokaalitiedostoissa — vain varoitus | **Neuvoa-antava** | +| `check:docs-symbols` | Jokainen `/api/...`-viittaus tiedostoissa `docs/**/*.md` viittaa todelliseen `route.ts`-tiedostoon (hallusinaatioiden esto) | Kyllä | +| `i18n translation drift` | Kääntämättömät avaimet i18n-lokaalitiedostoissa — vain varoitus | **Ohjeellinen** | ### Työ: `i18n-ui-coverage` -| Skripti | Tarkistaa | Estävä | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `check-ui-keys-coverage` (inline) | Käyttöliittymän i18n-avainten kattavuus on ≥ 65 % | Kyllä | -| `check-ui-value-drift` (inline) | Uudelleenkirjoitetusta englanninkielisestä **arvosta** ei jää jäljelle vanhentunutta käännöstä | Kyllä | -| `check-new-key-coverage` (inline) | **Uusi** englanninkielinen avain on käännetty kaikissa lokaaleissa — `__MISSING__:`-merkintää ei hyväksytä | Kyllä | -| `check-translation-ratio` | Todellisten käännösten suhde lokaaleittain (englanninkielisen kanssa identtiset / paikkamerkit / sallittujen luettelon ulkopuolella puuttuvat lehdet) ei saa ylittää arvoa `config/quality/i18n-translation-baseline.json` + liikkumavara | **Neuvoa-antava** | +| Skripti | Tarkistaa | Estävä | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | +| `check-ui-keys-coverage` (sisäinen) | Käyttöliittymän i18n-avainten kattavuus on ≥ 65 % | Kyllä | +| `check-ui-value-drift` (sisäinen) | Uudelleen kirjoitettu englanninkielinen **arvo** ei jätä jälkeensä vanhentunutta käännöstä | Kyllä | +| `check-new-key-coverage` (sisäinen) | **Uusi** englanninkielinen avain on käännetty jokaisessa lokaalissa — `__MISSING__:`-merkintää ei hyväksytä | Kyllä | +| `check-translation-ratio` | Todellisten käännösten osuus lokaaleittain (englannin kanssa identtiset / paikkamerkinnät / puuttuvat lehdet sallittujen luettelon ulkopuolella) ei saa ylittää arvoa `config/quality/i18n-translation-baseline.json` + liikkumavara | **Ohjeellinen** | -Edellyttää asetusta `fetch-depth: 0` — arvon vanhentumisen tarkistus vertaa `en.json`-tiedostoa yhdistämiskantaan. +Vaatii asetuksen `fetch-depth: 0` — arvomuutosten portti vertaa `en.json`-tiedostoa yhdistämiskantaan. #### `check-ui-value-drift` — vanhentuneiden käännösten portti -Havaitsee yhden i18n-regression, jota muut portit eivät rakenteellisesti pysty havaitsemaan: englanninkielinen arvo -kirjoitetaan uudelleen, mutta _aiempaan_ englanninkieliseen tekstiin perustuvat käännökset jäävät ennalleen, jolloin +Havaitsee sen yhden i18n-regression, jota muut portit eivät rakenteellisesti pysty näkemään: englanninkielinen arvo +kirjoitetaan uudelleen, mutta _aiemmasta_ englanninkielisestä tekstistä johdetut käännökset jäävät ennalleen, joten muunkieliset käyttäjät lukevat edelleen vakuuttavasti muotoiltua mutta nyt virheellistä tekstiä. -Tämä päätyi oikeasti tuotantoon. `oauthModal.googleOAuthWarning` kirjoitettiin uudelleen, kun Antigravity- -kirjautumisavustaja otettiin käyttöön (#5203); **39 lokaalia 43:sta** säilytti tekstin, jossa ylläpitäjiä kehotettiin "kopioimaan -koko URL-osoite ja liittämään se alle" — työnkulku, jota ei voi suorittaa loppuun kyseisellä palveluntarjoajalla. Se jäi -huomaamatta aina kohtaan #8463 asti, koska: +Tämä päätyi oikeasti julkaisuun. `oauthModal.googleOAuthWarning` kirjoitettiin uudelleen, kun Antigravity- +kirjautumisavustaja otettiin käyttöön (#5203); **39 lokaalia 43:sta** säilytti tekstin, joka kehotti ylläpitäjiä "kopioimaan +koko URL-osoitteen ja liittämään sen alle" — työnkulku ei voi valmistua kyseisen palveluntarjoajan kanssa. Ongelma +jäi huomaamatta tapaukseen #8463 asti, koska: -- `sync-ui-keys` täydentää vain avaimet, jotka **puuttuvat**, ei koskaan niitä, jotka ovat **vanhentuneita**; -- `check-ui-keys-coverage` laskee avaimen _olemassaolon_, joten vanhentunut käännös katsotaan katetuksi; +- `sync-ui-keys` täydentää vain **puuttuvat** avaimet, ei koskaan **vanhentuneita**; +- `check-ui-keys-coverage` laskee avaimen _olemassaolon_, joten vanhentunut käännös lasketaan katetuksi; - `check-translation-drift` seuraa dokumentaation `docs/i18n//**.md`-peilejä — se ei koskaan lue `src/i18n/messages/*.json`-tiedostoja. Estävä työssä `docs-sync-strict` vuoden - 2026-09 uudelleensynkronoinnista lähtien: muokkaa ydindokumenttia → `npm run i18n:run -- --files=` (osiotasoinen, kevyt). + 2026-09 uudelleensynkronoinnista alkaen: muokkaa ydindokumenttia → `npm run i18n:run -- --files=` (osiotasoinen, kevyt). -**Diff-tietoinen, ei perustasoon sidottu.** Se vertaa yhdistämiskohdan `en.json`-tiedostoa -työpuuhun; jokaisen avaimen kohdalla, jonka englanninkielinen arvo muuttui, kaikki lokalisaatiot, joissa on yhä -muuttamaton käännös, ovat vanhentuneita. Tämä tarkoituksellisesti **jäädyttää aiemmin kertyneen velan** — diff -ei voi paljastaa, mistä vanhasta englanninkielisestä tekstistä pitkään käytössä ollut käännös on peräisin, joten tarkistus arvioi -vain nykyisen muutoksen koskettamia kohtia. Vaihtoehto (avainkohtainen hajautusarvojen perustaso) vaatisi -noin 600 KB:n generoidun tiedoston, joka olisi 3× suurin nykyinen perustaso ja muuttuisi jokaisessa i18n-PR:ssä. +**Diff-tietoinen, ei perustasoon sidottu.** Se vertaa yhdistämiskannan `en.json`-tiedostoa +työpuuhun. Jos avaimen englanninkielinen arvo on muuttunut ja jossakin kieliversiossa +on edelleen koskematon käännös, käännös on vanhentunut. Tämä tarkoituksella **jäädyttää +aiemmin kertyneen velan** — diff ei voi paljastaa, mistä vanhasta englanninkielisestä +tekstistä pitkään käytössä ollut käännös on peräisin, joten portti arvioi vain nykyisen +muutoksen koskettamia kohtia. Vaihtoehto (avainkohtainen hajautusarvojen perustaso) vaatisi +noin 600 KB:n generoidun tiedoston, joka olisi kolme kertaa suurinta nykyistä perustasoa +suurempi ja muuttuisi jokaisessa i18n-PR:ssä. -Sen voi läpäistä kahdella tavalla: +Sen vaatimukset voi täyttää kahdella tavalla: 1. päivitä kyseiset käännökset tai -2. aseta niiden arvoksi `__MISSING__:` — suoritusympäristö tarjoaa tällöin korjatun englanninkielisen tekstin - (`src/i18n/request.ts::deepMergeFallback`, #7258), ja avain siirtyy käännösjonoon. +2. aseta niiden arvoksi `__MISSING__:` — suoritusympäristö näyttää tällöin + korjatun englanninkielisen tekstin (`src/i18n/request.ts::deepMergeFallback`, #7258), + ja avain asetetaan käännösjonoon. -Jos merkkijonon **merkitys** muuttui, suosi **avaimen uudelleennimeämistä**: uusi avain ei voi periä -vanhentunutta käännöstä. Tätä mallia käytettiin muutoksessa #8463. +Jos merkkijonon **merkitys** muuttui, suosi **avaimen nimeämistä uudelleen**: uusi avain +ei voi periä vanhentunutta käännöstä. Tätä mallia käytettiin muutoksessa #8463. ```bash -npm run i18n:check-value-drift # tiukka (CI:n suorittama tarkistus) +npm run i18n:check-value-drift # tiukka (CI suorittaa tämän) npm run i18n:check-value-drift:warn # vain raportointi BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Palauttaa poistumiskoodin 0 ja viestin `SKIP reason=base-unresolved`, kun perustason luetteloa ei voida lukea (matala -klooni ilman perustason viitettä), samalla tavoin kuin `check-openapi-breaking`. +Päättyy tilakoodilla 0 ja tulosteella `SKIP reason=base-unresolved`, kun perusluetteloa +ei voida lukea (matala klooni ilman perusviittausta), kuten `check-openapi-breaking`. ### Työ: `i18n` -Täysi i18n-validointimatriisi (yksi työ lokalisaatiota kohden). Koko työ on neuvoa-antava. +Täysi i18n-validointimatriisi (yksi työ kutakin kieliversiota kohden). Koko työ on neuvoa-antava. -| Skripti | Validoi | Estää yhdistämisen | -| ------------------------------- | --------------------------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | Käännösten kattavuus lokalisaatioittain | **Neuvoa-antava** (`continue-on-error: true` koko työssä) | +| Skripti | Validoi | Estää yhdistämisen | +| ------------------------------- | -------------------------------------- | --------------------------------------------------------- | +| `validate_translation.py quick` | Käännösten kattavuus kieliversioittain | **Neuvoa-antava** (`continue-on-error: true` koko työlle) | ### Työ: `pr-test-policy` -Suoritetaan vain vetopyynnöille. +Suoritetaan vain pull requesteille. -| Skripti | Validoi | Estää yhdistämisen | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `check:pr-test-policy` | PR:t, jotka muuttavat tuotantokoodia hakemistoissa `src/`, `open-sse/`, `electron/` tai `bin/`, sisältävät tai päivittävät testejä (Tiukka sääntö #8) | Kyllä | -| `check:test-masking` | Muutetut testitiedostot eivät vähennä väitteiden nettomäärää eivätkä lisää `assert.ok(true)`-tautologioita | Kyllä | -| `check:pr-evidence` | PR:n kuvaus viittaa muutoksen testi-/VPS-todisteisiin (automatisoi Tiukan säännön #18 etsimällä tekstiä PR:n kuvauksesta — hauras, katso kehitysjono) | Kyllä | +| Skripti | Validoi | Estää yhdistämisen | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `check:pr-test-policy` | PR:t, jotka muuttavat tuotantokoodia hakemistoissa `src/`, `open-sse/`, `electron/` tai `bin/`, sisältävät uusia tai päivitettyjä testejä (kova sääntö #8) | Kyllä | +| `check:test-masking` | Muutetut testitiedostot eivät vähennä assert-lauseiden nettomäärää eivätkä lisää `assert.ok(true)`-tautologioita | Kyllä | +| `check:pr-evidence` | PR:n kuvaus sisältää viittaukset muutoksen testi-/VPS-näyttöön (automatisoi kovaa sääntöä #18 etsimällä ilmauksia PR:n tekstistä — hauras, katso Backlog) | Kyllä | ### Työ: `test-vitest` Suoritetaan `build`-työn jälkeen. Epäonnistuminen estää yhdistämisen. -| Testikokonaisuus | Validoi | Estää yhdistämisen | -| ---------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | MCP-palvelin (110 työkalua), autoCombo, välimuisti — vitest-testiajuri | Kyllä | -| `test:vitest:ui` | Käyttöliittymäkomponenttien testit — vitest-testiajuri | **Estää yhdistämisen** — ennestään epäonnistuvat testit on nimenomaisesti ohitettu tiedostossa `vitest.config.ts`; uudet epäonnistumiset kaatavat työn | +| Testikokonaisuus | Validoi | Estää yhdistämisen | +| ---------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP-palvelin (110 työkalua), autoCombo, välimuisti — vitest-testiajuri | Kyllä | +| `test:vitest:ui` | Käyttöliittymäkomponenttien testit — vitest-testiajuri | **Estää yhdistämisen** — ennestään epäonnistuvat testit on nimenomaisesti suljettu pois tiedostossa `vitest.config.ts`; uudet epäonnistumiset kaatavat työn | ### Öiset työnkulut (ajastettuja, neuvoa-antavia) -Nämä suoritetaan cron-aikataulun mukaisesti (ja `workflow_dispatch`-toiminnolla), ei koskaan PR:issä. Kaikki ovat neuvoa-antavia. +Nämä suoritetaan cron-aikataulun mukaisesti (ja `workflow_dispatch`-toiminnolla), ei koskaan +PR:ille. Kaikki ovat neuvoa-antavia. -| Työnkulku | Validoi | Estää yhdistämisen | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -| `nightly-property` | fast-check-ominaisuustestit satunnaisella siemenluvulla ja suurella suorituskertojen määrällä | **Neuvoa-antava** | -| `nightly-resilience` | keon kasvun tarkistus, vikojen chaos-injektio, k6-kuormitus-/kestävyystestaus | **Neuvoa-antava** | -| `nightly-llm-security` | promptfoo-injektiosuojaus (estotila) + garak-koetukset (ohitetaan ilman palveluntarjoajan salaisuutta) | **Neuvoa-antava** | -| `nightly-schemathesis` | OpenAPI-sopimuksen fuzz-testaus (schemathesis) toimivaa OmniRoutea vasten käyttäen tiedostoa `docs/openapi.yaml` — tuo esiin määrittelyrikkomukset / käsittelemättömät 500-virheet (Vaihe 8 B.4) | **Neuvoa-antava** | -| `nightly-mutation` | Stryker-mutaatiotestauksen pisteet nopeasta yksikkötestilinjasta — selviytyvät mutantit paljastavat heikot väitteet | **Neuvoa-antava** | -| `nightly-compat` | Node-moottorin yhteensopivuusmatriisi tuetuilla `engines.node`-alueilla | **Neuvoa-antava** | +| Työnkulku | Validoi | Estää yhdistämisen | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `nightly-property` | fast-check-ominaisuustestit satunnaisella siemenluvulla ja suurella suorituskerralla | **Neuvoa-antava** | +| `nightly-resilience` | keon kasvun portti, häiriöiden kaaosinjektointi, k6-kuormitus-/pitkäkestoisuustestaus | **Neuvoa-antava** | +| `nightly-llm-security` | promptfoo-injektiosuojaus (estotila) + garak-tarkistukset (ohitetaan ilman palveluntarjoajan salaisuutta) | **Neuvoa-antava** | +| `nightly-schemathesis` | OpenAPI-sopimuksen fuzz-testaus (schemathesis) elävää OmniRoute-instanssia vasten käyttäen tiedostoa `docs/openapi.yaml` — tuo esiin spesifikaatiorikkomukset / käsittelemättömät 500-virheet (vaihe 8 B.4) | **Neuvoa-antava** | +| `nightly-mutation` | Stryker-mutaatiotestauksen pisteet nopealta yksikkötestikaistalta — selviytyvät mutantit paljastavat heikot assert-lauseet | **Neuvoa-antava** | +| `nightly-compat` | Node-moottorin yhteensopivuusmatriisi tuetuilla `engines.node`-alueilla | **Neuvoa-antava** | --- @@ -538,44 +542,44 @@ yhteysvirheen lokiin eikä koskaan riko istuntoja. --- -## Rationalisointijono (ROI-katselmus — vaihe 9, aalto 3) +## Rationalisointijono (ROI-katselmointi — vaihe 9, aalto 3) -Tämä inventaario täsmäytettiin `ci.yml`-tiedostoon 2026-06-17 (aiemmasta versiosta puuttuivat +Tämä luettelo täsmäytettiin `ci.yml`-tiedostoon 2026-06-17 (aiemmasta versiosta puuttuivat `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Täsmäytetylle joukolle tehty ROI-katselmus -tunnisti seuraavat rationalisointiehdokkaat. **Yhdistämiset ovat mekaanisia CI-muutoksia; -vaihdot ja poistot ovat operaattorille varattuja käytäntöpäätöksiä.** Mitään alla mainittua -ei ole vielä otettu käyttöön. +`check:codeql-ratchet`, `check:pr-evidence`). Täsmäytetyn kokonaisuuden ROI-katselmoinnissa +tunnistettiin seuraavat rationalisointiehdokkaat. **Yhdistämiset ovat mekaanisia CI-muutoksia; +käännöt ja poistot ovat operaattorille varattuja käytäntöpäätöksiä.** Mitään alla olevista +ei ole vielä toteutettu. -**Myös edellä dokumentoimatta** (neuvoa-antavia, signaali heikko): `docs-lint`-työ -(markdownlint + Vale, koko työssä `continue-on-error`) sekä erilliset tarkistustyönkulut +**Lisäksi yllä dokumentoimatta** (neuvoa-antavia, signaaliltaan heikkoja): `docs-lint`-työ +(markdownlint + Vale, koko työllä `continue-on-error`) ja erilliset tarkistustyönkulut `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` on -`quality-baseline.json`-tiedostossa, mutta sitä ei ole kytketty estävään räikkään -`ci.yml`-tiedostossa — mittari on tällä hetkellä irrallinen. +`quality-baseline.json`-tiedostossa, mutta sitä ei ole kytketty estävään räikkään `ci.yml`-tiedostossa — mittari +on tällä hetkellä irrallinen. -### Yhdistäminen / päällekkäisyyksien poistaminen (mekaaninen, pienempi riski) +### Yhdistäminen / päällekkäisyyksien poisto (mekaaninen, pienempi riski) Jokainen ehdokas validoitiin aktiivista porttitilaa vasten 2026-06-17 (luota, mutta varmista); -useat ”ilmeiset” yhdistämiset osoittautuivat peittävän teknistä velkaa, eivätkä ne ole -**suoraan korvaavia**. - -- **`check:docs-sync` suoritetaan kahdesti** — erikseen `lint`-työssä sekä uudelleen osana `check:docs-all`-tarkistusta (`docs-sync-strict`) ja huskyn pre-commit-koukkua. ✅ **TEHTY** — erillinen `lint`-suoritus poistettu. -- **CVE-tarkistus** — ❌ **EI ole siisti yhdistäminen.** `audit:deps` epäonnistuu ehdottomasti mistä tahansa vakavasta tai kriittisestä CVE:stä; `check:vuln-ratchet` (osv) epäonnistuu vain, jos perustasoon nähden tapahtuu _heikennys_ (tällä hetkellä 1 MODERATE). Semantiikka on erilainen — `audit:deps`-tarkistuksen poistaminen poistaisi ehdottoman vakavien ja kriittisten haavoittuvuuksien portin. Säilytä molemmat. -- **Syklien tunnistus** — ❌ **EI ole siisti yhdistäminen.** `check:circular-deps` (dpdm) raportoi **91 sykliä** (siksi se on neuvoa-antava); sitä ei voida muuttaa estäväksi ennen niiden ratkaisemista, ja sen kattavuus on laajempi kuin vihreän, kuratoidun `check:cycles`-tarkistuksen. Säilytä `check:cycles` estävänä; 91 dpdm-syklin ratkaiseminen kuuluu omaan työjonoonsa. -- **Monimutkaisuus** — ✅ **TEHTY** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): yksi ESLint-läpikäynti, laskenta ruleId-arvon mukaan, jotta syklomaattisuuden ja rivien enimmäismäärän sekä kognitiivisen monimutkaisuuden perustasot pysyvät erillisinä; yksittäiset `check:complexity` / `check:cognitive-complexity` säilyvät paikallista `--update`-ajoa varten. -- **`/api`-antihallusinaatio** — ✅ **TEHTY** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): yksi `src/app/api`-hakemiston tiedostojärjestelmäinventaario, openapi-routes + docs-symbols raportoivat edelleen erikseen; yksittäiset tarkistukset säilyvät paikallisia ajoja varten. -- **`check:node-runtime` suoritetaan 11 työssä** — ⚠️ **pieni ROI.** Jokainen on erillinen suoritusympäristö, ja tarkistus kestää alle sekunnin; kokonaissäästö olisi noin 10 sekuntia, mutta samalla menetettäisiin edullinen työkohtainen suojaus. Ei muutostyön arvoinen. -- **`typecheck:noimplicit:core` CI:n lint-tarkistuksessa** — ✅ **poistettu lint-työstä** (oli neuvoa-antava `continue-on-error`); estävä tyyppipinta muodostuu tarkistuksista `typecheck:core` + `check:type-coverage`. Paikallinen komentosarja säilytettiin. - -### Vaihda / päätä (operaattorin käytäntö) - -- `check:openapi-security-tiers` (neuvoa-antava) — ❌ **EI voida siististi muuttaa estäväksi.** Se päättyy koodilla 0, mutta varoittaa, että useilta `traffic-inspector`-reiteiltä kohdassa `LOCAL_ONLY_API_PREFIXES` puuttuu `x-loopback-only: true`-annotaatio. Sen pakottaminen edellyttää ensin näiden annotaatioiden lisäämistä `openapi.yaml`-tiedostoon. -- `typecheck:noimplicit:core` (neuvoa-antava) — estävä `check:type-coverage`-räikkä korvaa sen suurelta osin. Muuta se räikäksi tai poista tarpeeton toinen `tsc`-ajo. -- `test:vitest:ui` (nyt **estävä**) — aiemmat virheet on nimenomaisesti suljettu pois `vitest.config.ts`-tiedostossa `// #8618`-seurantakommenteilla; uudet virheet kaatavat työn. -- `check:secrets` (gitleaks, estävä räikkä jäädytetty kolmeen dokumentoituun väärään positiiviseen) — lisää kolme löydöstä sallittujen luetteloon nollatason saavuttamiseksi tai alenna tarkistus neuvoa-antavaksi. Päällekkäinen GitHubin oman salaisuuksien tarkistuksen ja `check:public-creds`-tarkistuksen kanssa. -- `check:pr-evidence` (estävä, tekee grep-haun PR-kuvauksen tekstistä) — suuri väärien positiivisten riski; poistaminen heikentäisi ehdottoman säännön #18 valvontaa, joten kyseessä on aito käytäntöpäätös. -- `semgrep` (neuvoa-antava erillinen tarkistus) — päällekkäinen CodeQL:n kanssa OWASP-perheiden osalta; kytke sen perustaso räikkään tai poista se. +useat ”ilmeiset” yhdistämiset osoittautuivat peittävän velkaa, eivätkä ne ole **suoraan** +korvattavissa. + +- **`check:docs-sync` suoritetaan kahdesti** — erillisenä `lint`-työssä ja uudelleen `check:docs-all`-tarkistuksen (`docs-sync-strict`) sekä husky-esitoimituskoukun sisällä. ✅ **VALMIS** — erillinen `lint`-kutsu poistettu. +- **CVE-tarkistus** — ❌ **EI suoraan yhdistettävissä.** `audit:deps` epäonnistuu ehdottomasti minkä tahansa vakavan/kriittisen CVE:n kohdalla; `check:vuln-ratchet` (osv) epäonnistuu vain baselineen nähden tapahtuvasta _regressiosta_ (tällä hetkellä 1 MODERATE). Semantiikka on erilainen — `audit:deps`-tarkistuksen poistaminen poistaisi ehdottoman vakavien/kriittisten haavoittuvuuksien portin. Säilytä molemmat. +- **Syklien tunnistus** — ✅ **VALMIS** (#15159 G-01/G-02). Vanha teksti kutsui `check:cycles`-tarkistusta ”vihreäksi, kuratoiduksi” portiksi ja perusteli sen säilyttämistä estävänä, koska `check:circular-deps` (dpdm) raportoi 91 sykliä. Tuo vihreä tulos oli **väärä positiivinen onnistuminen**: `check:cycles` tarkisti 5 alihakemistoa (450 tiedostoa), tunnisti vain staattiset `import|export … from` -rakenteet ja hylkäsi kaikki `@/`- ja `@omniroute/open-sse/`-määritteet, joten se ei voinut havaita dynaamisten tuontien ja aliasten muodostamia syklejä, jotka hallitsivat tietovarastoa. Korjattu: portti käy nyt läpi `src`- ja `open-sse`-hakemistot (5023 tiedostoa), kerää määritteet TypeScriptin AST:stä (joten `import("…")` lasketaan, mutta tyyppisijainnissa olevaa `typeof import("…")` -rakennetta ei) ja selvittää tsconfigin `paths`-määritykset. Se löytää **14** sykliä, ei 0:aa. Koska 14:ää jo olemassa olevaa sykliä ei voida korjata portin PR:ssä, `check:cycles` on nyt **räikkä** (`--ratchet`, yläraja `metrics.cycles.value = 14` tiedostossa `quality-baseline.json`, `direction: down`) — se estää minkä tahansa _regression_, ja määrä voi vain laskea. CI suorittaa komennon `npm run check:cycles:ratchet`. Velan vähentäminen etenee kohteen **A-01** mukana. `check:circular-deps` (dpdm) säilyy neuvoa-antavana laajempana toisena arviona. +- **Monimutkaisuus** — ✅ **VALMIS** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): yksi ESLint-läpikäynti, laskenta ruleId:n mukaan, jotta syklomaattisen monimutkaisuuden ja enimmäisrivimäärän sekä kognitiivisen monimutkaisuuden baselinet pysyvät erillisinä; yksittäiset `check:complexity` / `check:cognitive-complexity` säilyvät paikallista `--update`-käyttöä varten. +- **`/api`-hallusinaationesto** — ✅ **VALMIS** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): yksi `src/app/api`-hakemiston tiedostojärjestelmäinventaario; openapi-routes ja docs-symbols raportoivat edelleen itsenäisesti; yksittäiset tarkistukset säilyvät paikallisia suorituksia varten. +- **`check:node-runtime` suoritetaan 11 työssä** — ⚠️ **pieni ROI.** Jokainen käyttää erillistä suoritusympäristöä ja tarkistus kestää alle sekunnin; kokonaissäästö olisi noin 10 sekuntia, mutta samalla menetettäisiin edullinen työkohtainen suojaus. Ei muutostyön arvoista. +- **`typecheck:noimplicit:core` CI:n lint-tarkistuksessa** — ✅ **poistettu lint-työstä** (oli neuvoa-antava `continue-on-error`); estävä tyyppipinta muodostuu tarkistuksista `typecheck:core` + `check:type-coverage`. Paikallinen komentosarja säilytetty. + +### Käännä / päätä (operaattorin käytäntö) + +- `check:openapi-security-tiers` (neuvoa-antava) — ❌ **EI voida siirtää suoraan estäväksi.** Se palauttaa arvon 0, mutta varoittaa, että useilta `LOCAL_ONLY_API_PREFIXES`-määrityksen alaisilta `traffic-inspector`-reiteiltä puuttuu `x-loopback-only: true` -annotaatio. Sen pakottaminen edellyttää näiden annotaatioiden lisäämistä ensin `openapi.yaml`-tiedostoon. +- `typecheck:noimplicit:core` (neuvoa-antava) — estävä `check:type-coverage`-räikkä korvaa sen suurelta osin. Muuta räikäksi tai poista redundantti toinen `tsc`-läpikäynti. +- `test:vitest:ui` (nyt **estävä**) — jo olemassa olevat epäonnistumiset on nimenomaisesti rajattu pois `vitest.config.ts`-tiedostossa `// #8618`-seurantakommenteilla; uudet epäonnistumiset kaatavat työn. +- `check:secrets` (gitleaks, estävä räikkä lukittuna kolmeen dokumentoituun väärään positiiviseen) — lisää nämä 3 sallittujen luetteloon nollatason saavuttamiseksi tai alenna tarkistus neuvoa-antavaksi. Päällekkäinen GitHubin sisäänrakennetun salaisuuksien tarkistuksen ja `check:public-creds`-tarkistuksen kanssa. +- `check:pr-evidence` (estävä, hakee PR-kuvauksen proosasta) — suuri väärien positiivisten riski; poistaminen heikentää ehdottoman säännön nro 18 valvontaa, joten tämä on todellinen käytäntöpäätös. +- `semgrep` (neuvoa-antava erillistarkistus) — päällekkäinen CodeQL:n kanssa OWASP-perheiden osalta; kytke sen baseline räikkään tai poista. --- diff --git a/docs/i18n/fr/CONTRIBUTING.md b/docs/i18n/fr/CONTRIBUTING.md index f17dc9aa066..1b8c924953f 100644 --- a/docs/i18n/fr/CONTRIBUTING.md +++ b/docs/i18n/fr/CONTRIBUTING.md @@ -387,20 +387,20 @@ Ajoutez les définitions des modèles dans `open-sse/config/providerRegistry.ts` ## Liste de contrôle de la Pull Request -- [ ] Les tests réussissent (`npm test`) -- [ ] Le linting réussit (`npm run lint`) +- [ ] Les tests passent (`npm test`) +- [ ] Le linting passe (`npm run lint`) - [ ] Le build réussit (`npm run build`) -- [ ] Les types TypeScript ont été ajoutés pour les nouvelles fonctions et interfaces publiques +- [ ] Des types TypeScript ont été ajoutés pour les nouvelles fonctions et interfaces publiques - [ ] Aucun secret ni aucune valeur de repli codés en dur -- [ ] Les identifiants publics des services en amont sont intégrés via `resolvePublicCred()` (voir [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), jamais sous forme de littéraux -- [ ] Les réponses d'erreur passent par `buildErrorBody()` / `sanitizeErrorMessage()` — aucune trace de pile brute dans le corps des réponses (voir [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Les commandes shell (`exec` / `spawn`) transmettent les valeurs d'exécution via `env`, et non par interpolation de chaînes +- [ ] Les identifiants publics en amont sont intégrés via `resolvePublicCred()` (voir [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), jamais sous forme de littéraux +- [ ] Les réponses d’erreur passent par `buildErrorBody()` / `sanitizeErrorMessage()` — aucune trace de pile brute dans le corps des réponses (voir [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Les commandes shell (`exec` / `spawn`) transmettent les valeurs d’exécution via `env`, et non par interpolation de chaînes - [ ] Toutes les entrées sont validées avec des schémas Zod -- [ ] Un **fragment** de journal des modifications a été ajouté sous `changelog.d/{features|fixes|maintenance}/-.md` pour les changements visibles par les utilisateurs (voir [`changelog.d/README.md`](./changelog.d/README.md)) — ne modifiez **pas** directement `CHANGELOG.md` ; les fragments sont agrégés au moment de la publication et ne créent jamais de conflits entre les Pull Requests +- [ ] Un **fragment** de journal des modifications a été ajouté sous `changelog.d/{features|fixes|maintenance}/-.md` pour les changements visibles par les utilisateurs (voir [`changelog.d/README.md`](./changelog.d/README.md)) — ne modifiez **pas** directement `CHANGELOG.md` ; les fragments sont regroupés au moment de la publication et ne provoquent jamais de conflits entre les PR - [ ] La documentation a été mise à jour (le cas échéant) -- [ ] Aucune nouvelle alerte CodeQL / Secret-Scanning n'a été ouverte, ou chacune a été rejetée avec une justification technique faisant référence au document `docs/security/` pertinent +- [ ] Aucune nouvelle alerte CodeQL / Secret-Scanning n’a été ouverte, ou chacune a été rejetée avec une justification technique faisant référence au document `docs/security/` pertinent - [ ] Les routes qui lancent des processus enfants (`/api/mcp/`, `/api/cli-tools/runtime/`) sont classées comme `isLocalOnlyPath()` dans `src/server/authz/routeGuard.ts` — voir la [Règle stricte nº 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Aucun pied de message `Co-Authored-By` dans les messages de commit — les commits doivent apparaître uniquement sous l'identité Git du propriétaire du dépôt (Règle stricte nº 16) +- [ ] Aucun pied de message `Co-authored-by` attribué à une IA ou à un bot dans les messages de commit (Règle stricte nº 16) — les collaborateurs humains dont le travail est réutilisé sont crédités avec des pieds de message standard `Co-authored-by: Name ` --- diff --git a/docs/i18n/fr/docs/architecture/QUALITY_GATES.md b/docs/i18n/fr/docs/architecture/QUALITY_GATES.md index bc1841ecbc9..ebd8ebf767b 100644 --- a/docs/i18n/fr/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/fr/docs/architecture/QUALITY_GATES.md @@ -15,229 +15,246 @@ plan de réplication indépendant des outils du même système, consultez le --- -## Inventaire des contrôles et profils d’exécution +## Inventaire des gates et profils d’exécution ### Admission des candidats Les workflows CI et Quality Gates émettent chacun un verdict stable : `Gate / CI` et `Gate / Quality`. Leur politique d’admission versionnée répertorie chaque job en amont -comme obligatoire ou consultatif. Un job obligatoire applicable doit réussir : les résultats -manquants, annulés, ignorés, en attente ou inconnus ne permettent pas d’établir un PASS. Une -classification valide limitée à la documentation ou au catalogue peut rendre une voie de code -non applicable ; une PR en brouillon n’est pas un candidat accepté. Un label `hotfix` ne -dispense pas de fournir des preuves. - -Les deux workflows couvrent les PR et les poussées vers les branches main/release, le -déclenchement manuel et les événements de groupe de fusion. Les poussées, les déclenchements -et les groupes de fusion exécutent la sélection complète. Les forks et les groupes de fusion -utilisent des runners hébergés pour les jobs qui sélectionnent normalement des runners -auto-hébergés ; une capacité hébergée suffisante doit être vérifiée avant le déploiement. +comme obligatoire ou consultatif. Un job obligatoire applicable doit réussir : les +résultats manquants, annulés, ignorés, en attente ou inconnus ne peuvent pas établir +un PASS. Une classification valide limitée à la documentation ou au catalogue peut +rendre une voie de code non applicable ; une PR en brouillon n’est pas un candidat +accepté. Un label `hotfix` ne dispense pas de fournir des preuves. + +Les deux workflows couvrent les PR et les push vers les branches principales/de release, +les déclenchements manuels et les événements de groupe de fusion. Les push, les +déclenchements manuels et les groupes de fusion exécutent la sélection complète. Les +forks et les groupes de fusion utilisent des runners hébergés pour les jobs qui +sélectionneraient autrement des runners auto-hébergés ; une capacité hébergée suffisante +doit être vérifiée avant le déploiement. Chaque reçu JSON identifie le SHA extrait, l’exécution du workflow et la tentative. -La CLI rejette toute non-correspondance entre le SHA extrait et celui de l’événement. Les tests -de workflow lient l’appartenance à la politique à la liste `needs` du job de verdict, afin qu’une -voie nouvelle ou supprimée ne puisse pas disparaître silencieusement. Les reçus couvrent leur -propre workflow, et non la publication, le déploiement ou le fonctionnement interne d’un scanner -consultatif existant. L’activation des deux noms de contrôle dans les règles de branche constitue -une modification administrative distincte ; l’ajout de ces jobs ne protège pas, à lui seul, une branche. +La CLI rejette toute non-concordance entre le SHA extrait et celui de l’événement. Les +tests de workflow lient l’appartenance à la politique à la liste `needs` du job de +verdict, afin qu’une voie ajoutée ou supprimée ne puisse pas disparaître silencieusement. +Les reçus couvrent leur propre workflow, et non la publication, le déploiement ou les +mécanismes internes d’un scanner consultatif existant. L’activation des deux noms de +vérification dans les règles de branche constitue une modification administrative +distincte ; l’ajout de ces jobs ne protège pas, à lui seul, une branche. ### Inventaire de l’analyse statique -L’inventaire versionné des alias npm et l’appartenance à l’analyse statique se trouvent dans -`config/quality/gate-manifest.json`. Exécutez `npm run check:gate-manifest` pour valider -les noms des scripts et les commandes exactes par rapport à `package.json` ; les ajouts, -les suppressions et les dérives de commandes font échouer à la fois le hook local et les jobs -de classification des modifications dans CI. Un alias n’est ni un job de workflow, ni une -instance de matrice, ni un cas de test : ces nombres ne doivent pas être présentés comme -interchangeables. +L’inventaire versionné des alias npm et l’appartenance à l’analyse statique se trouvent +dans `config/quality/gate-manifest.json`. Exécutez `npm run check:gate-manifest` pour +valider les noms de scripts et les commandes exactes par rapport à `package.json` ; les +ajouts, les suppressions et les divergences de commandes font échouer à la fois le hook +local et les jobs de classification des modifications dans CI. Un alias n’est ni un job +de workflow, ni une instance de matrice, ni un cas de test : ces décomptes ne doivent +pas être présentés comme interchangeables. Utilisez `npm run quality:scan -- --list` ou `npm run quality:scan:fast -- --list` -pour inspecter les alias sélectionnés sans les exécuter. Le runner invoque le -point d’entrée npm, de sorte que son environnement d’exécution (y compris Bun lorsqu’il est -configuré) est préservé. Le manifeste enregistre comme invoqués séparément les alias situés -hors de ces profils, et les commandes de maintenance sont interdites dans les profils d’analyse +pour inspecter les alias sélectionnés sans les exécuter. Le runner appelle le point +d’entrée npm, ce qui préserve son environnement d’exécution (y compris Bun lorsqu’il est +configuré). Le manifeste consigne les alias extérieurs à ces profils comme étant invoqués +séparément, et les commandes de maintenance sont interdites dans les profils d’analyse en lecture seule. -Ces profils couvrent uniquement l’analyse statique. Ils ne certifient ni les tests du produit, -ni la couverture, ni la création de paquets, ni les contrôles externes, ni l’acceptation complète -d’un candidat à la publication. L’admission par workflow utilise le fichier lié -`config/quality/admission-policy.json` et -`scripts/quality/admission-verdict.mjs`. Les profils d’observation de publication restent distincts ; -inspectez séparément leurs contrôles applicables et leurs reçus. L’inventaire descriptif -ci-dessous est une référence, et non une preuve qu’un contrôle a réellement été exécuté. - -Les scripts se trouvent sous `scripts/check/` (contrôles de politique) et `scripts/quality/` (moteur de progression). -La source de vérité de CI est `.github/workflows/ci.yml`. - -### Chemin rapide des PR de publication (`quality.yml`) - -`.github/workflows/quality.yml` complète CI pour les PR main/release, les poussées vers les -branches protégées, les déclenchements et les groupes de fusion. Les PR utilisent des contrôles -rapides filtrés selon les chemins. La compilation en double, désactivée de manière permanente, -a été supprimée ; les véritables contrôles de compilation, de création de paquets et de démarrage -restent dans CI. - -| Job | Portée | Bloquant | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | PR de documentation/code ; références de documentation API et ensemble de la documentation | Oui | -| `Fast Quality Gates` | PR de code ; contrôles statiques, vérification des types, vérification des types du tableau de bord, tests unitaires affectés | Oui | -| `Forgotten sibling tests` | PR de code ; modules modifiés reliés aux consommateurs statiques et aux tests frères candidats ; les chemins de barrel et d’import dynamique sont signalés comme diagnostics consultatifs, avec les exceptions de la liste d’autorisation référencée | **Consultatif** | -| `Vitest (fast-path)` | PR de code ; suite vitest rapide | Oui | -| `Unit Tests fast-path` | PR de code ; suite unitaire répartie en 4 fragments | Oui | -| `No new ESLint warnings` | PR de code ; garde-fou de lint tenant compte des suppressions | Oui, y compris les forks | -| `Merge integrity (changelog + generated skills)` | PR hors brouillon ; synchronisation du journal des modifications et des compétences générées | Oui, y compris les forks | +Ces profils couvrent uniquement l’analyse statique. Ils ne certifient ni les tests du +produit, ni la couverture, ni la création de packages, ni les vérifications externes, ni +l’acceptation complète d’un candidat à la release. L’admission du workflow utilise +`config/quality/admission-policy.json`, auquel elle est liée, ainsi que +`scripts/quality/admission-verdict.mjs`. Les profils d’observation de release restent +distincts ; inspectez séparément leurs vérifications applicables et leurs reçus. +L’inventaire textuel ci-dessous est une référence, et non la preuve qu’un gate a +réellement été exécuté. + +Les scripts se trouvent sous `scripts/check/` (gates de politique) et +`scripts/quality/` (moteur de progression). La source de vérité de CI est +`.github/workflows/ci.yml`. + +### Voie rapide des PR de release (`quality.yml`) + +`.github/workflows/quality.yml` complète CI pour les PR vers les branches principales/de +release, les push vers les branches protégées, les déclenchements manuels et les groupes +de fusion. Les PR utilisent des vérifications rapides filtrées selon les chemins. Le +build dupliqué désactivé de manière permanente a été supprimé ; les véritables +vérifications de build, de création de package et de démarrage restent dans CI. + +| Job | Portée | Bloquant | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `Docs Gates (fast-path)` | PR de documentation/code ; références de documentation d’API et ensemble de la documentation | Oui | +| `Fast Quality Gates` | PR de code ; vérifications statiques, vérification des types, vérification des types du tableau de bord, tests unitaires affectés | Oui | +| `Forgotten sibling tests` | PR de code ; modules modifiés reliés aux consommateurs statiques et aux tests frères candidats ; les chemins de barrel et d’import dynamique sont signalés comme diagnostics consultatifs, avec les exceptions référencées de la liste d’autorisation | **Consultatif** | +| `Vitest (fast-path)` | PR de code ; suite Vitest rapide | Oui | +| `Unit Tests fast-path` | PR de code ; suite de tests unitaires en 4 shards | Oui | +| `No new ESLint warnings` | PR de code ; garde de lint tenant compte des suppressions | Oui, y compris les forks | +| `Merge integrity (changelog + generated skills)` | PR hors brouillon ; synchronisation du changelog et des compétences générées | Oui, y compris les forks | #### Rapport sur les tests frères oubliés -`npm run check:forgotten-sibling-tests` réutilise le résolveur d’imports à l’origine de la carte d’impact des tests. -Pour chaque module de production modifié, il signale des chaînes déterministes -`module/symbole modifié -> consommateur statique -> test frère candidat` lorsque le test candidat -est absent du diff de la pull request. Le résumé Markdown et le résultat JSON sont conservés comme -artefact de workflow `forgotten-sibling-tests` à des fins d’étalonnage avant tout déploiement bloquant. +`npm run check:forgotten-sibling-tests` réutilise le résolveur d’imports sur lequel repose +la carte d’impact des tests. Pour chaque module de production modifié, il signale des chaînes +déterministes `module/symbole modifié -> consommateur statique -> test frère candidat` lorsque +le test candidat est absent du diff de la pull request. Le résumé Markdown et le résultat JSON +sont conservés en tant qu’artefact de workflow `forgotten-sibling-tests` à des fins de +calibrage avant tout déploiement bloquant. -Les réexportations via des fichiers barrel et les importations dynamiques servent uniquement au diagnostic de résolution ; elles ne créent jamais de +Les réexportations via des barrels et les imports dynamiques servent uniquement au diagnostic de résolution ; ils ne créent jamais de constat bloquant. Les exceptions examinées se trouvent dans `config/quality/forgotten-sibling-allowlist.json`. Chaque entrée doit nommer le test consommateur et le test candidat, fournir une justification précise et contenir un lien vers une issue ou une pull request GitHub. Les entrées mal formées entraînent -un refus par défaut. Les exceptions ne peuvent pas masquer la suppression d’un test candidat ni un diff qui ajoute `.skip`/`.todo` ; -l’affaiblissement des assertions et les autres formes de masquage restent sous la responsabilité du contrôle bloquant indépendant +un refus par défaut. Les exceptions ne peuvent pas masquer la suppression d’un test candidat ni un diff ajoutant `.skip`/`.todo` ; +l’affaiblissement des assertions et les autres formes de masquage restent sous la responsabilité de la barrière bloquante indépendante `check:test-masking`. -### Job : `lint` +### Tâche : `lint` S’exécute sur chaque PR vers `main`. Bloque la fusion en cas d’échec. -| Script (`npm run ...`) | Vérifie | Bloquant | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | La version de Node.js se trouve dans la plage prise en charge | Oui | -| `check:cycles` | Les importations circulaires — tous les modules de `src/` + `open-sse/` | Oui | -| `check:route-validation:t06` | La présence de schémas Zod sur toutes les routes (politique de niveau 6) | Oui | -| `check:any-budget:t11` | Le nombre de `@ts-expect-error // any` ne dépasse pas le budget (catraca de niveau 11) | Oui | -| `check:provider-consistency` | Chaque fournisseur dans `providers.ts` possède une entrée correspondante dans `providerRegistry.ts` (et réciproquement, dans les limites de la liste d’autorisation) | Oui | -| `check:model-lifecycle` | Les trois tables de routage maintenues manuellement restent cohérentes avec l’instantané du cycle de vie archivé (#11503) : `FITNESS_TABLE` (`taskFitness.ts`) n’attribue de score à aucun identifiant retiré que `REGISTRY` peut acheminer ; chaque cible de `BUILT_IN_ALIASES` est présente dans `REGISTRY` et absente de l’instantané des identifiants retirés ; chaque identifiant retiré encore présent dans `REGISTRY` est redirigé ou répertorié dans `allowedRetiredInCatalog` ; et aucune source ni cible de `DEFAULT_DEGRADATION_MAP` n’apparaît comme retirée dans cet instantané. Cela ne prouve pas qu’un modèle est actuellement fourni par un service amont actif. Hors ligne — compare avec `config/quality/model-lifecycle.json`, actualisé manuellement avec `npm run quality:refresh-model-lifecycle` (réseau ; non intégré à la CI). `allowedRetiredInCatalog` est un mécanisme de réduction progressive : n’ajoutez une entrée qu’avec un ticket de suivi. | Oui | -| `check:fetch-targets` | Chaque `fetch("/api/...")` dans le répertoire client `src/` correspond à un véritable fichier `route.ts` | Oui | -| `check:deps` | Toutes les dépendances installables avec `npm install` dans chaque `package.json` du dépôt figurent dans `dependency-allowlist.json` ; les nouveaux paquets dont la version n’est pas épinglée ou qui présentent un risque de slopsquatting sont signalés | Oui | -| `audit:deps` | `npm audit` (racine + Electron) — aucun avis de sécurité de gravité élevée/critique (chevauche le contrôle OSV `check:vuln-ratchet` ; voir le backlog de rationalisation) | Oui | -| `check:lockfile` | Intégrité de `package-lock.json` — registre HTTPS, empreintes d’intégrité, aucune substitution d’hôte | Oui | -| `check:licenses` | Liste blanche de licences SPDX pour les dépendances de production | Oui | -| `check:tracked-artifacts` | Aucun artefact de build ni lien symbolique `node_modules` suivi dans le dépôt (également exécuté par le hook husky de pré-commit ; le pré-push est intentionnellement léger — #6716) | Oui | -| `check:ai-attribution` | Aucun pied de message `Co-Authored-By` d’IA/bot ni mention de génération par IA dans les commits, le titre ou le corps de la PR — Règle stricte n° 16 (dans la boucle de contrôles rapides de `quality.yml` pour les PR vers `release/**` — lit la charge utile de l’événement, sans effet hors PR — et dans une étape réservée aux PR du lint de `ci.yml` pour les PR vers `main` ; également dans le hook husky `commit-msg` ; les co-auteurs humains sont autorisés ; #14436) | -| `check:vitest-exclusions` | Chaque exclusion Vitest mentionne une issue de suivi et figure dans `config/quality/vitest-exclusions.json` (#13204) | Oui | -| `check:file-size` | Aucun fichier source ne dépasse la limite propre à son extension (limitation progressive : grands fichiers figés dans la liste `frozen`) | Oui | -| `check:error-helper` | Les réponses d’erreur dans les exécuteurs/gestionnaires utilisent `buildErrorBody()` / `sanitizeErrorMessage()` (Règle stricte n° 12) | Oui | -| `check:migration-numbering` | Les fichiers SQL de migration sont numérotés séquentiellement, sans numéro manquant ni doublon | Oui | -| `check:public-creds` | Aucun `client_id`/`client_secret` OAuth littéral ni aucune clé Web Firebase en dehors de `publicCreds.ts` (règle stricte nº 11) | Oui | -| `check:db-rules` | Aucun SQL brut en dehors des modules `src/lib/db/` ; aucun import depuis le fichier d'agrégation `localDb.ts` (règles strictes nº 2/5) | Oui | -| `check:known-symbols` | Les exécuteurs de fournisseurs, les stratégies de routage et les traducteurs enregistrés dans leurs tables de répartition correspondent aux fichiers présents sur le disque — aucun symbole orphelin ou non déclaré | Oui | -| `check:route-guard-membership` | Chaque route qui lance un processus enfant est classée par `isLocalOnlyPath()` (règles strictes nº 15/17) | Oui | -| `check:test-discovery` | Chaque fichier `*.test.ts` / `*.spec.ts` du dépôt est collecté par au moins un exécuteur de tests (mécanisme à cliquet : la liste des fichiers orphelins dans `test-discovery-baseline.json` ne peut que diminuer) | Oui | -| `check:agent-skills-sync` | Les artefacts agent-skills générés correspondent à leur catalogue source (aucune dérive) | -| `check:provider-asset-provenance` | Les logos/ressources des fournisseurs disposent d’une entrée de provenance enregistrée | -| `lint:json` | Les fichiers de configuration JSON sont analysés correctement et respectent les règles de lint du dépôt | -| `typecheck:core` | Compilation TypeScript sans erreur (avertissements consultatifs uniquement) | Oui | -| `typecheck:noimplicit:core` | Mode strict `noImplicitAny` — mesure prospective ; de nombreux sites d’appel préexistants nécessitent encore des annotations | **Consultatif** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limité à `src/app/(dashboard)/**` (#7033) — la liste d’autorisation organisée de 27 fichiers de `typecheck:core` n’inclut aucun TSX du tableau de bord, et `next build` n’effectue jamais non plus de vérification de types sur celui-ci (`next.config.mjs` définit `ignoreBuildErrors: true`) ; les régressions d’identifiants orphelins à cet endroit (#6625/#6909) étaient donc invisibles pour la CI. Comparaison avec une référence figée du nombre d’erreurs par fichier et par code TS (`config/quality/dashboard-typecheck-baseline.json`, selon le même modèle de contrôle de l’obsolescence que `check:known-symbols`) — seules les NOUVELLES erreurs dépassant le nombre de référence font échouer le contrôle ; réduisez progressivement la référence avec `--update` lorsqu’une erreur préexistante est corrigée. | Oui | +| Script (`npm run ...`) | Valide | Bloquant | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | La version de Node.js se situe dans la plage prise en charge | Oui | +| `check:cycles` | Les imports circulaires dans l’ensemble de `src/` + `open-sse/` (fondé sur l’AST, avec résolution des `paths` de tsconfig). Sans argument = informatif, répertorie les cycles. `check:cycles:ratchet` (ce que la CI exécute) bloque lorsque le nombre dépasse le plafond `metrics.cycles` défini dans `quality-baseline.json` — actuellement 14, `direction: down`, il ne peut donc que diminuer (#15159 G-01/G-02) | Oui (cliquet) | +| `check:route-validation:t06` | Présence de schémas Zod sur toutes les routes (politique de niveau 6) | Oui | +| `check:any-budget:t11` | Le nombre de `@ts-expect-error // any` ne dépasse pas le budget (cliquet de niveau 11) | Oui | +| `check:provider-consistency` | Chaque fournisseur dans `providers.ts` possède une entrée correspondante dans `providerRegistry.ts` (et inversement, dans les limites de la liste d’autorisation) | Oui | +| `check:model-lifecycle` | Les trois tables de routage maintenues manuellement restent cohérentes avec l’instantané du cycle de vie archivé dans le dépôt (#11503) : `FITNESS_TABLE` (`taskFitness.ts`) n’attribue aucun score à un identifiant retiré que `REGISTRY` peut acheminer ; chaque cible de `BUILT_IN_ALIASES` est présente dans `REGISTRY` et absente de l’instantané des identifiants retirés ; chaque identifiant retiré encore présent dans `REGISTRY` est redirigé ou répertorié dans `allowedRetiredInCatalog` ; et aucune source ni cible de `DEFAULT_DEGRADATION_MAP` n’apparaît comme retirée dans cet instantané. Cela ne prouve pas qu’un modèle est actuellement servi par un service amont actif. Hors ligne — effectue une comparaison avec `config/quality/model-lifecycle.json`, actualisé manuellement avec `npm run quality:refresh-model-lifecycle` (réseau ; non intégré à la CI). `allowedRetiredInCatalog` est un mécanisme de réduction progressive : n’ajoutez une entrée qu’avec un ticket de suivi. | Oui | +| `check:fetch-targets` | Chaque `fetch("/api/...")` dans le répertoire client `src/` correspond à un véritable `route.ts` | Oui | +| `check:deps` | Toutes les dépendances installables avec `npm install` de chaque fichier `package.json` du dépôt figurent dans `dependency-allowlist.json` ; les nouveaux paquets non épinglés ou issus de typosquattage sont signalés | Oui | +| `audit:deps` | `npm audit` (racine + Electron) — aucun avis de sécurité de gravité élevée/critique (chevauche le contrôle OSV `check:vuln-ratchet` ; voir le backlog de rationalisation) | Oui | +| `check:lockfile` | Intégrité de `package-lock.json` — registre HTTPS, empreintes d’intégrité, aucune substitution d’hôte | Oui | +| `check:licenses` | Liste d’autorisation des licences SPDX pour les dépendances de production | Oui | +| `check:tracked-artifacts` | Aucun artefact de build ni lien symbolique `node_modules` versionné (également exécuté dans le hook de pré-commit husky ; le pré-push est intentionnellement léger — #6716) | Oui | +| `check:ai-attribution` | Aucun trailer `Co-Authored-By` d’IA/de bot ni pied de page indiquant une génération par IA dans les commits, le titre ou le corps de la PR — Règle stricte no 16 (dans la boucle de contrôles rapides de `quality.yml` pour les PR→`release/**` — lit la charge utile de l’événement, sans effet hors des PR — et dans une étape réservée aux PR de l’analyse lint de `ci.yml` pour les PR→`main` ; également dans le hook `commit-msg` de husky ; coauteurs humains autorisés ; #14436) | +| `check:vitest-exclusions` | Chaque exclusion Vitest mentionne une issue de suivi et figure dans `config/quality/vitest-exclusions.json` (#13204) | Oui | +| `check:file-size` | Aucun fichier source ne dépasse la limite propre à son extension (mécanisme à cliquet : fichiers volumineux figés dans la liste `frozen`) | Oui | +| `check:error-helper` | Les réponses d’erreur dans les exécuteurs/gestionnaires utilisent `buildErrorBody()` / `sanitizeErrorMessage()` (Règle stricte no 12) | Oui | +| `check:migration-numbering` | Les fichiers SQL de migration sont numérotés séquentiellement, sans interruption ni doublon | Oui | +| `check:public-creds` | Aucun `client_id`/`client_secret` OAuth littéral ni aucune clé Web Firebase en dehors de `publicCreds.ts` (Règle stricte nº 11) | Oui | +| `check:db-rules` | Aucun SQL brut en dehors des modules de `src/lib/db/` ; aucun import depuis le fichier d’agrégation `localDb.ts` (Règles strictes nº 2/5) | Oui | +| `check:known-symbols` | Les exécuteurs de fournisseurs, les stratégies de routage et les traducteurs enregistrés dans leurs tables de répartition correspondent aux fichiers présents sur le disque — aucun symbole orphelin ou non déclaré | Oui | +| `check:route-guard-membership` | Chaque route qui lance un processus enfant est classée par `isLocalOnlyPath()` (Règles strictes nº 15/17) | Oui | +| `check:test-discovery` | Chaque fichier `*.test.ts` / `*.spec.ts` du dépôt est collecté par au moins un exécuteur de tests (mécanisme de verrouillage : la liste des fichiers orphelins dans `test-discovery-baseline.json` ne peut que diminuer) | Oui | +| `check:agent-skills-sync` | Les artefacts agent-skills générés correspondent à leur catalogue source (aucune dérive) | +| `check:provider-asset-provenance` | Les logos/ressources des fournisseurs disposent d’une entrée de provenance enregistrée | +| `lint:json` | Les fichiers de configuration JSON sont analysés correctement et respectent les règles de lint du dépôt | +| `typecheck:core` | Compilation TypeScript sans erreur (avertissements consultatifs uniquement) | Oui | +| `typecheck:noimplicit:core` | Mode strict `noImplicitAny` — objectif à terme ; de nombreux sites d’appel préexistants nécessitent encore des annotations | **Consultatif** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` limité à `src/app/(dashboard)/**` (#7033) — la liste d’autorisation organisée de 27 fichiers de `typecheck:core` n’inclut aucun fichier TSX du tableau de bord, et `next build` n’effectue pas non plus de vérification des types sur celui-ci (`next.config.mjs` définit `ignoreBuildErrors: true`) ; les régressions d’identifiants orphelins qui s’y trouvent (#6625/#6909) étaient donc invisibles pour la CI. Comparaison avec une référence figée du nombre d’erreurs par fichier et par code TS (`config/quality/dashboard-typecheck-baseline.json`, selon le même modèle de contrôle de l’obsolescence que `check:known-symbols`) — seules les NOUVELLES erreurs dépassant le nombre de référence font échouer le contrôle ; réduisez progressivement la référence avec `--update` lorsqu’une erreur préexistante est corrigée. | Oui | ### Tâche : `quality-gate` S’exécute après `test-coverage`. Bloque la fusion en cas d’échec. -| Script | Valide | Bloquant | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `quality:collect` | Génère `quality-metrics.json` (nombre d’avertissements ESLint, couverture issue du rapport fusionné des shards) | Oui (en amont du cliquet) | -| `quality:ratchet` | Aucune métrique de `quality-baseline.json` n’a régressé (avertissements ESLint ≤ référence ; couverture ≥ référence) | Oui | -| `check:duplication` | La duplication de code (jscpd@4) ne dépasse pas la référence définie dans `quality-baseline.json` | Oui | -| `check:complexity` | La complexité cyclomatique au niveau des fichiers ne dépasse pas le plafond (`complexity` d’ESLint core + `max-lines-per-function`) | Oui | -| `check:cognitive-complexity` | Cliquet de complexité cognitive (`eslint-plugin-sonarjs`) — passe ESLint distincte ; la CI exécute les deux ensemble dans l’unique étape `check:complexity-ratchets` | Oui | -| `check:dead-code` | Le cliquet des exports/fichiers inutilisés (knip) ne régresse pas par rapport à la référence | Oui | -| `check:compression-budget` | Budget du benchmark de compression — les seuils minimaux d’économie de jetons par moteur ne doivent pas régresser | Oui | -| `check:type-coverage` | Le cliquet du pourcentage typé (`type-coverage`) ne régresse pas ; remplace en grande partie `typecheck:noimplicit:core` | Oui | -| `check:codeql-ratchet` | Le nombre d’alertes CodeQL ouvertes ne régresse pas (lecture via `gh api` ; omission sans échec en l’absence de jeton) — cadence d’actualisation et déclenchement manuel : voir « Cliquet CodeQL » ci-dessous | Oui | +| Script | Valide | Bloquant | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | +| `quality:collect` | Génère `quality-metrics.json` (nombre d’avertissements ESLint, couverture issue du rapport fusionné des fragments) | Oui (en amont du mécanisme de cliquet) | +| `quality:ratchet` | Chaque métrique dans `quality-baseline.json` n’a pas régressé (avertissements ESLint ≤ référence ; couverture ≥ référence) | Oui | +| `check:duplication` | La duplication de code (jscpd@4) ne dépasse pas la référence définie dans `quality-baseline.json` | Oui | +| `check:complexity` | La complexité cyclomatique au niveau des fichiers ne dépasse pas la limite (`complexity` d’ESLint natif + `max-lines-per-function`) | Oui | +| `check:cognitive-complexity` | Cliquet de complexité cognitive (`eslint-plugin-sonarjs`) — passe ESLint distincte ; la CI exécute les deux conjointement dans l’unique étape `check:complexity-ratchets` | Oui | +| `check:dead-code` | Le cliquet des exports/fichiers inutilisés (knip) ne régresse pas par rapport à la référence | Oui | +| `check:compression-budget` | Budget du benchmark de compression — les seuils minimaux d’économie de jetons par moteur ne doivent pas régresser | Oui | +| `check:type-coverage` | Le cliquet du pourcentage de code typé (`type-coverage`) ne régresse pas ; remplace en grande partie `typecheck:noimplicit:core` | Oui | +| `check:codeql-ratchet` | Le nombre d’alertes CodeQL ouvertes ne régresse pas (lecture via `gh api` ; omission propre sans jeton) — fréquence d’actualisation et déclenchement manuel : voir « Cliquet CodeQL » ci-dessous | Oui | ### Tâche : `quality-extended` -L’ensemble de la tâche est indicatif (`continue-on-error: true`). Les cliquets basés sur npm -s’exécutent réellement ; les analyseurs externes s’installent via `gh release download` et +La tâche entière est consultative (`continue-on-error: true`). Les cliquets basés sur npm +s’exécutent réellement ; les analyseurs externes sont installés via `gh release download` et s’ignorent eux-mêmes (code de sortie 0) lorsqu’un binaire est toujours absent. -| Script | Valide | Bloquant | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| `check:circular-deps` | Aucune dépendance circulaire (dpdm) | **Indicatif** | -| `check:bundle-size` | La taille du bundle ne dépasse pas le plafond | **Indicatif** | -| `check:secrets` | Analyse des secrets (gitleaks) — ignorée si le binaire est absent | **Indicatif** | -| `check:vuln-ratchet` | Les vulnérabilités des dépendances (osv-scanner) ne régressent pas — ignoré si le binaire est absent | **Indicatif** | -| `check:workflows` | Validation des workflows (actionlint + zizmor) ; les analyseurs absents/défectueux, les rapports invalides ou l’absence de référence du cliquet entraînent un échec avec le statut INCOMPLETE. Les résultats valides suivent la politique stricte/indicative/cliquet sélectionnée | Exécution requise ; cliquet zizmor bloquant dans la CI | -| `check:openapi-breaking` | Modifications incompatibles du contrat d’API publique (`openapi.yaml`) par rapport à la branche de base (oasdiff) — génère `openapiBreaking=N` ; ignoré si oasdiff est absent ou si la spécification de base ne peut pas être résolue | **Indicatif** | +| Script | Valide | Bloquant | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| `check:circular-deps` | Aucune dépendance circulaire (dpdm) | **Consultatif** | +| `check:bundle-size` | La taille du bundle ne dépasse pas la limite | **Consultatif** | +| `check:secrets` | Analyse des secrets (gitleaks) — ignorée si le binaire est absent | **Consultatif** | +| `check:vuln-ratchet` | Les vulnérabilités des dépendances (osv-scanner) ne régressent pas — ignoré si le binaire est absent | **Consultatif** | +| `check:workflows` | Analyse des workflows (actionlint + zizmor) ; des analyseurs manquants/défaillants, des rapports invalides ou une référence de cliquet manquante entraînent un échec INCOMPLETE. Les constats valides suivent la politique stricte/consultative/de cliquet sélectionnée | Exécution requise ; cliquet zizmor bloquant dans la CI | +| `check:openapi-breaking` | Modifications incompatibles du contrat d’API public (`openapi.yaml`) par rapport à la branche de base (oasdiff) — génère `openapiBreaking=N` ; ignoré si oasdiff est absent ou si la spécification de base ne peut pas être résolue | **Consultatif** | ### Tâche : `docs-sync-strict` S’exécute sur chaque PR vers `main`. Bloque la fusion en cas d’échec. -| Script | Valide | Bloquant | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `check:docs-all` | Méta-barrière qui exécute séquentiellement les 6 sous-barrières ci-dessous | Oui | -| ↳ `check:docs-sync` | Cohérence des versions entre CHANGELOG / OpenAPI / llm.txt | Oui | -| ↳ `check:docs-counts` | Les décomptes dans le texte (nombre de fournisseurs, nombre de migrations, etc.) restent dans la fenêtre de progression des décomptes réels | Oui | -| ↳ `check:env-doc-sync` | Chaque variable d’environnement de `.env.example` est documentée dans un tableau de la documentation, et inversement | Oui | -| ↳ `check:deprecated-versions` | Aucune chaîne de version obsolète dans la documentation | Oui | -| ↳ `check:doc-links` | Les liens Markdown internes de la documentation renvoient vers des fichiers réels (forme `[texte]`/`(chemin)`) | Oui | -| ↳ `check:fabricated-docs` | Les routes, variables d’environnement, commandes CLI, noms de hooks et chemins de fichiers cités dans la documentation existent dans la base de code. Barrière stricte via `--strict` ; échec non bloquant sans cette option. | Oui (via `--strict` dans la CI) | -| `check:cli-i18n` | Les chaînes des commandes CLI sont présentes dans tous les fichiers de paramètres régionaux i18n | Oui | -| `check:openapi-coverage` | La spécification OpenAPI couvre au moins un seuil progressif de routes réelles | Oui | -| `check:openapi-security-tiers` | Les annotations des niveaux de sécurité dans `openapi.yaml` sont cohérentes avec les classifications de `routeGuard.ts` | **Consultatif** | -| `check:openapi-routes` | Chaque chemin de `openapi.yaml` correspond à un véritable fichier `route.ts` (anti-hallucination) | Oui | -| `check:docs-symbols` | Chaque référence `/api/...` dans `docs/**/*.md` correspond à un véritable fichier `route.ts` (anti-hallucination) | Oui | -| `i18n translation drift` | Clés non traduites dans les fichiers de paramètres régionaux i18n — avertissement uniquement | **Consultatif** | +| Script | Valide | Bloquant | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `check:docs-all` | Méta-contrôle qui exécute séquentiellement les 6 sous-contrôles ci-dessous | Oui | +| ↳ `check:docs-sync` | Cohérence des versions entre CHANGELOG / OpenAPI / llm.txt | Oui | +| ↳ `check:docs-counts` | Les nombres mentionnés dans le texte (nombre de fournisseurs, nombre de migrations, etc.) se situent dans la fenêtre de progression des nombres réels | Oui | +| ↳ `check:env-doc-sync` | Chaque variable d'environnement de `.env.example` est documentée dans un tableau de la documentation, et inversement | Oui | +| ↳ `check:deprecated-versions` | Aucune chaîne de version obsolète dans la documentation | Oui | +| ↳ `check:doc-links` | Les liens Markdown internes de la documentation pointent vers des fichiers réels (forme `[text]`/`(path)`) | Oui | +| ↳ `check:fabricated-docs` | Les routes, variables d'environnement, commandes CLI, noms de hooks et chemins de fichiers cités dans la documentation existent dans la base de code. Contrôle strict via `--strict` ; échec non bloquant sans cette option. | Oui (via `--strict` dans la CI) | +| `check:cli-i18n` | Les chaînes des commandes CLI sont présentes dans tous les fichiers de paramètres régionaux i18n | Oui | +| `check:openapi-coverage` | La spécification OpenAPI couvre au moins un seuil progressif de routes réelles | Oui | +| `check:openapi-security-tiers` | Les annotations de niveau de sécurité dans `openapi.yaml` sont cohérentes avec les classifications de `routeGuard.ts` | **Consultatif** | +| `check:openapi-routes` | Chaque chemin dans `openapi.yaml` correspond à un véritable fichier `route.ts` (anti-hallucination) | Oui | +| `check:docs-symbols` | Chaque référence `/api/...` dans `docs/**/*.md` correspond à un véritable fichier `route.ts` (anti-hallucination) | Oui | +| `i18n translation drift` | Clés non traduites dans les fichiers de paramètres régionaux i18n — avertissement uniquement | **Consultatif** | ### Tâche : `i18n-ui-coverage` -| Script | Valide | Bloquant | -| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (en ligne) | La couverture des clés i18n de l’interface utilisateur est ≥ 65 % | Oui | -| `check-ui-value-drift` (en ligne) | Une **valeur** anglaise réécrite ne laisse aucune traduction obsolète | Oui | -| `check-new-key-coverage` (en ligne) | Une **nouvelle** clé anglaise est traduite dans chaque langue — un marqueur `__MISSING__:` est rejeté | Oui | -| `check-translation-ratio` | Le taux de traductions réelles par langue (valeurs identiques à l’anglais / espaces réservés / éléments manquants hors de la liste d’autorisation) ne doit pas dépasser `config/quality/i18n-translation-baseline.json` + la marge | **Consultatif** | +| Script | Valide | Bloquant | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (inline) | La couverture des clés i18n de l'interface utilisateur est ≥ 65 % | Oui | +| `check-ui-value-drift` (inline) | La réécriture d'une **valeur** anglaise ne laisse aucune traduction obsolète | Oui | +| `check-new-key-coverage` (inline) | Une **nouvelle** clé anglaise est traduite dans chaque paramètre régional — un marqueur `__MISSING__:` est rejeté | Oui | +| `check-translation-ratio` | Le taux de traductions réelles par paramètre régional (valeurs identiques à l'anglais / espaces réservés / éléments manquants hors de la liste d'autorisation) ne doit pas dépasser `config/quality/i18n-translation-baseline.json` + la marge | **Consultatif** | -Nécessite `fetch-depth: 0` — la barrière de dérive des valeurs compare `en.json` à la base de fusion. +Nécessite `fetch-depth: 0` — le contrôle de dérive des valeurs compare `en.json` à la base de fusion. -#### `check-ui-value-drift` — barrière contre les traductions obsolètes +#### `check-ui-value-drift` — contrôle des traductions obsolètes -Détecte la seule régression i18n que les autres barrières ne peuvent structurellement pas voir : une valeur anglaise +Détecte la seule régression i18n que les autres contrôles ne peuvent structurellement pas voir : une valeur anglaise est réécrite tandis que les traductions dérivées de la valeur anglaise _précédente_ restent en place, si bien que les utilisateurs non anglophones continuent de lire un texte formulé avec assurance, mais désormais erroné. -Cela s’est réellement produit en production. `oauthModal.googleOAuthWarning` a été réécrit lors de l’arrivée de -l’assistant de connexion Antigravity (#5203) ; **39 langues sur 43** ont conservé un texte demandant aux opérateurs de « copier -l’URL complète et la coller ci-dessous » — un parcours qui ne peut pas aboutir pour ce fournisseur. Le problème est -passé inaperçu jusqu’à #8463, car : +Cela s'est réellement produit en production. `oauthModal.googleOAuthWarning` a été réécrit lors de l'arrivée de +l'assistant de connexion Antigravity (#5203) ; **39 paramètres régionaux sur 43** ont conservé un texte indiquant aux opérateurs de « copier +l'URL complète et la coller ci-dessous » — un flux qui ne peut pas aboutir pour ce fournisseur. Le problème est +passé inaperçu jusqu'au #8463 parce que : - `sync-ui-keys` ne complète que les clés **absentes**, jamais celles qui sont **obsolètes** ; -- `check-ui-keys-coverage` comptabilise la _présence_ des clés, si bien qu’une traduction obsolète est considérée comme couverte ; -- `check-translation-drift` suit les miroirs de documentation `docs/i18n//**.md` — +- `check-ui-keys-coverage` compte la _présence_ des clés, de sorte qu'une traduction obsolète est considérée comme couverte ; +- `check-translation-drift` suit les copies de la documentation dans `docs/i18n//**.md` — il ne lit jamais `src/i18n/messages/*.json`. Bloquant dans la tâche `docs-sync-strict` depuis la - resynchronisation 2026-09 : modifier un document principal → `npm run i18n:run -- --files=` (au niveau de la section, peu coûteux). + resynchronisation de 2026-09 : modifiez un document principal → `npm run i18n:run -- --files=` (au niveau de la section, peu coûteux). -**Prend en compte les différences, sans s'appuyer sur une référence.** Ce contrôle compare `en.json` à la base de fusion avec l'arborescence de travail ; pour chaque clé dont la valeur anglaise a changé, toute locale contenant encore une traduction inchangée est obsolète. Cela **fige délibérément la dette préexistante** — une différence ne permet pas de déterminer de quelle ancienne version anglaise provient une traduction de longue date, donc le contrôle porte uniquement sur ce que la modification actuelle affecte. L'autre solution (une référence de hachage par clé) nécessiterait un fichier généré d'environ 600 Ko, soit 3× la plus grande référence existante, et celui-ci serait modifié à chaque PR d'i18n. +**Sensible aux diffs, sans baseline.** Il compare `en.json` au point de fusion avec +l’arborescence de travail ; pour chaque clé dont la valeur anglaise a changé, toute locale +contenant encore une traduction non modifiée est obsolète. Cela **fige délibérément la dette +préexistante** — un diff ne permet pas de déterminer de quelle ancienne version anglaise +provient une traduction existante depuis longtemps ; le contrôle évalue donc uniquement ce +que la modification actuelle affecte. L’autre solution (une baseline de hachage par clé) +nécessiterait un fichier généré d’environ 600 Ko, soit 3 fois la plus grande baseline +existante, et entraînerait des modifications parasites à chaque PR d’i18n. Deux façons de satisfaire ce contrôle : 1. mettre à jour les traductions concernées, ou -2. les définir sur `__MISSING__:` — à l'exécution, le texte anglais corrigé est alors utilisé - (`src/i18n/request.ts::deepMergeFallback`, #7258) et la clé est ajoutée à la file d'attente de traduction. +2. les définir sur `__MISSING__:` — l’exécution fournit alors la version + anglaise corrigée (`src/i18n/request.ts::deepMergeFallback`, #7258) et place la clé dans + la file d’attente de traduction. -Si le **sens** de la chaîne a changé, privilégiez le **renommage de la clé** : une nouvelle clé ne peut pas hériter d'une traduction obsolète. C'est le modèle utilisé par #8463. +Si le **sens** de la chaîne a changé, privilégiez le **renommage de la clé** : une nouvelle +clé ne peut pas hériter d’une traduction obsolète. C’est le modèle utilisé par #8463. ```bash -npm run i18n:check-value-drift # strict (ce qu'exécute la CI) +npm run i18n:check-value-drift # strict (ce que la CI exécute) npm run i18n:check-value-drift:warn # rapport uniquement BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Se termine avec le code 0 et `SKIP reason=base-unresolved` lorsque le catalogue de base ne peut pas être lu (clone superficiel sans la référence de base), comme `check-openapi-breaking`. +Se termine avec le code 0 et `SKIP reason=base-unresolved` lorsque le catalogue de base ne +peut pas être lu (clone superficiel sans la référence de base), comme +`check-openapi-breaking`. ### Tâche : `i18n` -Matrice complète de validation i18n (une tâche par locale). La tâche entière est consultative. +Matrice complète de validation i18n (une tâche par locale). La tâche entière est +consultative. | Script | Valide | Bloquant | | ------------------------------- | --------------------------------------- | -------------------------------------------------------------- | @@ -245,35 +262,36 @@ Matrice complète de validation i18n (une tâche par locale). La tâche entière ### Tâche : `pr-test-policy` -S'exécute uniquement sur les pull requests. +S’exécute uniquement sur les pull requests. -| Script | Valide | Bloquant | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | Les PR qui modifient le code de production dans `src/`, `open-sse/`, `electron/` ou `bin/` doivent inclure ou mettre à jour des tests (Règle stricte nº 8) | Oui | -| `check:test-masking` | Les fichiers de test modifiés ne réduisent pas le nombre net d'assertions et n'ajoutent pas de tautologies `assert.ok(true)` | Oui | -| `check:pr-evidence` | Le corps de la PR mentionne des preuves de test/VPS pour la modification (automatise la Règle stricte nº 18 en recherchant des motifs dans le texte de la PR — fragile, voir la liste des tâches) | Oui | +| Script | Valide | Bloquant | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | Les PR qui modifient le code de production dans `src/`, `open-sse/`, `electron/` ou `bin/` doivent inclure ou mettre à jour des tests (Règle stricte nº 8) | Oui | +| `check:test-masking` | Les fichiers de test modifiés ne réduisent pas le nombre net d’assertions et n’ajoutent pas de tautologies `assert.ok(true)` | Oui | +| `check:pr-evidence` | Le corps de la PR cite des preuves de test/VPS pour la modification (automatise la Règle stricte nº 18 en analysant le texte de la PR — fragile, voir Backlog) | Oui | ### Tâche : `test-vitest` -S'exécute après `build`. Bloque la fusion en cas d'échec. +S’exécute après `build`. Bloque la fusion en cas d’échec. | Suite | Valide | Bloquant | | ---------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `test:vitest` | Serveur MCP (110 outils), autoCombo, cache — exécuteur vitest | Oui | -| `test:vitest:ui` | Tests des composants de l'interface — exécuteur vitest | **Bloquant** — les échecs préexistants sont explicitement exclus dans `vitest.config.ts` ; les nouveaux échecs font échouer la tâche | +| `test:vitest:ui` | Tests des composants d’interface — exécuteur vitest | **Bloquant** — les échecs préexistants sont explicitement exclus dans `vitest.config.ts` ; les nouveaux échecs font échouer la tâche | ### Workflows nocturnes (planifiés, consultatifs) -Ils s'exécutent selon une planification cron (ainsi que via `workflow_dispatch`), jamais sur les PR. Ils sont tous consultatifs. +Ils s’exécutent selon une planification cron (et avec `workflow_dispatch`), jamais sur les +PR. Ils sont tous consultatifs. -| Workflow | Valide | Bloquant | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | Tests fondés sur les propriétés avec fast-check, utilisant une graine aléatoire et un nombre élevé d'exécutions | **Consultatif** | -| `nightly-resilience` | Contrôle de la croissance du tas, injection chaotique de défaillances, tests de charge/d'endurance k6 | **Consultatif** | -| `nightly-llm-security` | Protection contre les injections promptfoo (mode blocage) + sondes garak (ignorées sans secret de fournisseur) | **Consultatif** | -| `nightly-schemathesis` | Fuzzing du contrat OpenAPI (schemathesis) sur une instance OmniRoute active à l'aide de `docs/openapi.yaml` — met en évidence les violations de la spécification / erreurs 500 non gérées (Phase 8 B.4) | **Consultatif** | -| `nightly-mutation` | Score des tests par mutation Stryker sur le parcours rapide des tests unitaires — les mutants survivants mettent en évidence les assertions faibles | **Consultatif** | -| `nightly-compat` | Matrice de compatibilité du moteur Node pour les plages `engines.node` prises en charge | **Consultatif** | +| Workflow | Valide | Bloquant | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `nightly-property` | Tests de propriétés fast-check avec une graine aléatoire et un nombre élevé d’exécutions | **Consultatif** | +| `nightly-resilience` | Contrôle de la croissance du tas, injection chaotique de défaillances, tests de charge/d’endurance k6 | **Consultatif** | +| `nightly-llm-security` | Protection contre l’injection promptfoo (mode blocage) + sondes garak (ignorées sans secret de fournisseur) | **Consultatif** | +| `nightly-schemathesis` | Fuzzing du contrat OpenAPI (schemathesis) sur une instance OmniRoute active à l’aide de `docs/openapi.yaml` — révèle les violations de la spécification / erreurs 500 non gérées (Phase 8 B.4) | **Consultatif** | +| `nightly-mutation` | Score des tests par mutation Stryker sur la voie rapide des tests unitaires — les mutants survivants révèlent les assertions faibles | **Consultatif** | +| `nightly-compat` | Matrice de compatibilité du moteur Node pour les plages `engines.node` prises en charge | **Consultatif** | --- @@ -547,36 +565,36 @@ Cet inventaire a été rapproché de `ci.yml` le 2026-06-17 (la version précéd `check:codeql-ratchet`, `check:pr-evidence`). Une revue du ROI de l’ensemble rapproché a permis d’identifier les candidats à la rationalisation suivants. **Les fusions sont des modifications mécaniques de la CI ; les basculements/suppressions sont des décisions de -politique réservées à l’opérateur.** Aucun des éléments ci-dessous n’est encore appliqué. +politique réservées à l’opérateur.** Rien de ce qui suit n’est encore appliqué. **Également non documentés ci-dessus** (consultatifs, signal faible) : la tâche `docs-lint` -(markdownlint + Vale, avec `continue-on-error` pour l’ensemble de la tâche) et les workflows -d’analyse autonomes `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` -figure dans `quality-baseline.json`, mais n’est relié à aucun cliquet bloquant dans -`ci.yml` — cette métrique est actuellement orpheline. +(markdownlint + Vale, tâche entière avec `continue-on-error`) et les workflows d’analyse +autonomes `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` figure dans +`quality-baseline.json`, mais n’est relié à aucun cliquet bloquant dans `ci.yml` — la métrique +est actuellement orpheline. -### Fusion / déduplication (mécanique, risque moindre) +### Fusion / déduplication (mécanique, risque plus faible) -Chaque candidat a été validé par rapport à l’état réel des contrôles le 2026-06-17 -(vérifier malgré la confiance) ; plusieurs fusions « évidentes » se sont avérées masquer -de la dette et **ne** peuvent **pas** être appliquées directement. +Chaque candidat a été validé par rapport à l’état réel des contrôles le 2026-06-17 (faire +confiance, mais vérifier) ; plusieurs fusions « évidentes » se sont avérées masquer de la +dette et ne sont **pas** des remplacements directs sans risque. -- **`check:docs-sync` est exécuté deux fois** — de manière autonome dans la tâche `lint`, puis à nouveau dans `check:docs-all` (`docs-sync-strict`) et dans le hook de pré-commit husky. ✅ **TERMINÉ** — invocation autonome supprimée de `lint`. -- **Analyse des CVE** — ❌ **PAS une fusion directe.** `audit:deps` échoue de manière bloquante pour toute CVE de gravité élevée/critique ; `check:vuln-ratchet` (osv) n’échoue qu’en cas de _régression_ par rapport à la référence (actuellement 1 MODERATE). Les sémantiques sont différentes — supprimer `audit:deps` ferait perdre le contrôle absolu des vulnérabilités élevées/critiques. Conserver les deux. -- **Détection des cycles** — ❌ **PAS une fusion directe.** `check:circular-deps` (dpdm) signale **91 cycles** (c’est pourquoi il est consultatif) ; il ne peut pas devenir bloquant avant leur résolution et sa portée est plus large que celle du contrôle `check:cycles`, ciblé et au vert. Conserver `check:cycles` comme contrôle bloquant ; la résolution des 91 cycles dpdm constitue un backlog distinct. -- **Complexité** — ✅ **TERMINÉ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`) : un seul parcours ESLint, avec comptage par ruleId afin que les références de complexité cyclomatique et de nombre maximal de lignes restent indépendantes des références cognitives ; les contrôles individuels `check:complexity` / `check:cognitive-complexity` sont conservés pour l’utilisation locale de `--update`. -- **Anti-hallucination de `/api`** — ✅ **TERMINÉ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`) : un seul inventaire du système de fichiers de `src/app/api` ; openapi-routes + docs-symbols continuent de produire des rapports indépendants ; les contrôles individuels sont conservés pour les exécutions locales. -- **`check:node-runtime` est exécuté dans 11 tâches** — ⚠️ **ROI faible.** Chacune s’exécute sur un runner distinct et le contrôle prend moins de 1 s ; l’économie totale est d’environ 10 s, au prix de la perte d’une protection peu coûteuse pour chaque tâche. Le bouleversement n’en vaut pas la peine. -- **`typecheck:noimplicit:core` dans le lint de la CI** — ✅ **supprimé de la tâche lint** (était consultatif avec `continue-on-error`) ; la surface de typage bloquante est assurée par `typecheck:core` + `check:type-coverage`. Script local conservé. +- **`check:docs-sync` s’exécute deux fois** — de manière autonome dans la tâche `lint`, puis à nouveau dans `check:docs-all` (`docs-sync-strict`) et dans le hook de pré-commit husky. ✅ **TERMINÉ** — invocation autonome supprimée de `lint`. +- **Analyse des CVE** — ❌ **PAS une fusion sans risque.** `audit:deps` échoue de manière bloquante pour toute CVE élevée/critique ; `check:vuln-ratchet` (osv) échoue uniquement en cas de _régression_ par rapport à la référence (actuellement 1 MODERATE). Sémantiques différentes — supprimer `audit:deps` ferait perdre le contrôle absolu des niveaux élevé/critique. Conserver les deux. +- **Détection des cycles** — ✅ **TERMINÉ** (#15159 G-01/G-02). L’ancien texte qualifiait ici `check:cycles` de contrôle « vert, organisé » et justifiait son maintien comme contrôle bloquant parce que `check:circular-deps` (dpdm) signalait 91 cycles. Ce vert était un **faux vert** : `check:cycles` analysait 5 sous-répertoires (450 fichiers), ne détectait que les instructions statiques `import|export … from` et ignorait tous les spécificateurs `@/` et `@omniroute/open-sse/`, de sorte qu’il ne pouvait pas voir les cycles d’import dynamique et d’alias qui dominaient le dépôt. Correction effectuée : le contrôle parcourt désormais `src` + `open-sse` (5023 fichiers), collecte les spécificateurs depuis l’AST TypeScript (ainsi, `import("…")` est pris en compte, contrairement à `typeof import("…")` en position de type) et résout les `paths` de tsconfig. Il détecte **14** cycles, et non 0. Comme 14 cycles préexistants ne peuvent pas être corrigés dans une PR consacrée aux contrôles, `check:cycles` est désormais un **cliquet** (`--ratchet`, plafond `metrics.cycles.value = 14` dans `quality-baseline.json`, `direction: down`) — il bloque toute _régression_ et le nombre ne peut que diminuer. La CI exécute `npm run check:cycles:ratchet`. La résorption progressive est intégrée à **A-01**. `check:circular-deps` (dpdm) reste consultatif en tant que deuxième avis plus large. +- **Complexité** — ✅ **TERMINÉ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`) : un seul parcours ESLint, avec des comptages par ruleId afin que les références cyclomatique+max-lines et cognitive restent indépendantes ; les commandes individuelles `check:complexity` / `check:cognitive-complexity` sont conservées pour les exécutions locales avec `--update`. +- **Anti-hallucination `/api`** — ✅ **TERMINÉ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`) : un seul inventaire du système de fichiers pour `src/app/api`, openapi-routes + docs-symbols continuent à produire des rapports indépendants ; les commandes individuelles sont conservées pour les exécutions locales. +- **`check:node-runtime` s’exécute dans 11 tâches** — ⚠️ **faible ROI.** Chacune utilise un exécuteur distinct et le contrôle dure moins de 1 s ; économies totales d’environ 10 s, au prix de la perte d’une protection peu coûteuse pour chaque tâche. Cela ne justifie pas les perturbations. +- **`typecheck:noimplicit:core` dans le lint de la CI** — ✅ **supprimé de la tâche lint** (était consultatif avec `continue-on-error`) ; la surface de typage bloquante est `typecheck:core` + `check:type-coverage`. Script local conservé. ### Basculer / décider (politique de l’opérateur) -- `check:openapi-security-tiers` (consultatif) — ❌ **PAS directement basculable.** Il se termine avec le code 0, mais avertit que plusieurs routes `traffic-inspector` sous `LOCAL_ONLY_API_PREFIXES` ne disposent pas de l’annotation `x-loopback-only: true`. Son application stricte nécessite d’abord l’ajout de ces annotations à `openapi.yaml`. -- `typecheck:noimplicit:core` (consultatif) — largement couvert par le cliquet bloquant `check:type-coverage`. Le convertir en cliquet ou supprimer ce second passage `tsc` redondant. -- `test:vitest:ui` (désormais **bloquant**) — les échecs préexistants sont explicitement exclus dans `vitest.config.ts` avec des commentaires de suivi `// #8618` ; tout nouvel échec fait échouer la tâche. -- `check:secrets` (gitleaks, cliquet bloquant figé à 3 faux positifs documentés) — ajouter les 3 à la liste d’exclusion pour atteindre 0, ou rétrograder le contrôle en consultatif. Chevauche l’analyse native des secrets de GitHub + `check:public-creds`. -- `check:pr-evidence` (bloquant, recherche des motifs dans le texte du corps de la PR) — risque élevé de faux positifs ; sa suppression affaiblirait l’application de la règle stricte nº 18, il s’agit donc d’une véritable décision de politique. -- `semgrep` (contrôle autonome consultatif) — chevauche CodeQL pour les familles OWASP ; relier sa référence à un cliquet ou le supprimer. +- `check:openapi-security-tiers` (consultatif) — ❌ **PAS directement basculable.** Il se termine avec le code 0, mais avertit que plusieurs routes `traffic-inspector` sous `LOCAL_ONLY_API_PREFIXES` ne comportent pas l’annotation `x-loopback-only: true`. Son application obligatoire nécessite d’abord l’ajout de ces annotations dans `openapi.yaml`. +- `typecheck:noimplicit:core` (consultatif) — largement couvert par le cliquet bloquant `check:type-coverage`. Le convertir en cliquet ou supprimer le second passage `tsc` redondant. +- `test:vitest:ui` (désormais **bloquant**) — les échecs préexistants sont explicitement exclus dans `vitest.config.ts` avec des commentaires de suivi `// #8618` ; les nouveaux échecs font échouer la tâche. +- `check:secrets` (gitleaks, cliquet bloquant figé à 3 faux positifs documentés) — ajouter les 3 à la liste d’autorisation pour atteindre 0, ou rétrograder le contrôle au statut consultatif. Recoupe l’analyse native des secrets de GitHub + `check:public-creds`. +- `check:pr-evidence` (bloquant, recherche du texte libre dans le corps de la PR avec grep) — risque élevé de faux positifs ; sa suppression affaiblirait l’application de la Règle stricte n° 18, il s’agit donc d’une véritable décision de politique. +- `semgrep` (workflow autonome consultatif) — recoupe CodeQL pour les familles OWASP ; relier sa référence à un cliquet ou le supprimer. --- diff --git a/docs/i18n/ga/CONTRIBUTING.md b/docs/i18n/ga/CONTRIBUTING.md index 7e7d38588f0..dec16f28952 100644 --- a/docs/i18n/ga/CONTRIBUTING.md +++ b/docs/i18n/ga/CONTRIBUTING.md @@ -404,18 +404,18 @@ Scríobh tástálacha aonaid in `tests/unit/` a chlúdaíonn, ar a laghad: - [ ] Éiríonn leis na tástálacha (`npm test`) - [ ] Éiríonn leis an lintáil (`npm run lint`) -- [ ] Éiríonn leis an tógáil (`npm run build`) +- [ ] Éiríonn leis an tiomsú (`npm run build`) - [ ] Cineálacha TypeScript curtha leis le haghaidh feidhmeanna agus comhéadain phoiblí nua - [ ] Gan aon rúin ná luachanna cúltaca crua-chódaithe -- [ ] Dintiúir phoiblí réamhtheachtacha leabaithe trí `resolvePublicCred()` (féach [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), agus ní mar theaghráin litriúla choíche -- [ ] Freagairtí earráide seolta trí `buildErrorBody()` / `sanitizeErrorMessage()` — gan aon lorg cruachta amh i gcoirp freagartha (féach [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Tugann orduithe bhlaosc (`exec` / `spawn`) luachanna ama rite ar aghaidh trí `env`, agus ní trí idirshuíomh teaghrán +- [ ] Dintiúir phoiblí réamhtheachtacha leabaithe trí `resolvePublicCred()` (féach [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), agus ní mar litearáil riamh +- [ ] Freagraí earráide seolta trí `buildErrorBody()` / `sanitizeErrorMessage()` — gan aon rianta amhchruaiche i gcorp na bhfreagraí (féach [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Orduithe blaoisce (`exec` / `spawn`) a chuireann luachanna ama rite ar aghaidh trí `env`, ní trí idirshuíomh teaghrán - [ ] Gach ionchur bailíochtaithe le scéimeanna Zod -- [ ] **Blúire** den loga athruithe curtha faoi `changelog.d/{features|fixes|maintenance}/-.md` le haghaidh athruithe atá le feiceáil ag úsáideoirí (féach [`changelog.d/README.md`](./changelog.d/README.md)) — **ná** cuir `CHANGELOG.md` in eagar go díreach; déantar na blúirí a chomhiomlánú tráth eisiúna agus ní bhíonn coinbhleacht eatarthu idir iarratais tarraingthe choíche +- [ ] **Blúire** den loga athruithe curtha leis faoi `changelog.d/{features|fixes|maintenance}/-.md` le haghaidh athruithe atá infheicthe ag úsáideoirí (féach [`changelog.d/README.md`](./changelog.d/README.md)) — ná cuir `CHANGELOG.md` in eagar go díreach; déantar na blúirí a chomhiomlánú tráth an eisiúna agus ní bhíonn coinbhleacht eatarthu riamh i measc PRanna - [ ] Doiciméadacht nuashonraithe (más infheidhme) -- [ ] Gan aon fholáirimh nua CodeQL / Secret-Scanning oscailte, nó gach ceann díobh diúltaithe le bonn cirt teicniúil a thagraíonn don doiciméad ábhartha in `docs/security/` +- [ ] Gan aon fholáirimh nua CodeQL / Secret-Scanning oscailte, nó gach ceann acu diúltaithe le bonn cirt teicniúil a thagraíonn don doiciméad ábhartha in `docs/security/` - [ ] Bealaí a sceitheann próisis mhac (`/api/mcp/`, `/api/cli-tools/runtime/`) aicmithe mar `isLocalOnlyPath()` in `src/server/authz/routeGuard.ts` — féach [Riail Dhocht #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Gan aon leantóirí `Co-Authored-By` i dteachtaireachtaí tiomantais — ní mór do thiomantais a bheith le feiceáil faoi aitheantas Git úinéir na stórtha amháin (Riail Dhocht #16) +- [ ] Gan aon leantóirí `Co-authored-by` ó IS/róbónna i dteachtaireachtaí tiomantais (Riail Dhocht #16) — tugtar aitheantas do chomhoibrithe daonna a n-athúsáidtear a gcuid oibre le leantóirí caighdeánacha `Co-authored-by: Name ` --- diff --git a/docs/i18n/ga/docs/architecture/QUALITY_GATES.md b/docs/i18n/ga/docs/architecture/QUALITY_GATES.md index c778fbc9253..03b86b0eca4 100644 --- a/docs/i18n/ga/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ga/docs/architecture/QUALITY_GATES.md @@ -15,205 +15,213 @@ neamhspleách ar uirlisí don chóras céanna, féach an --- -## Fardal geataí agus próifílí forghníomhaithe - -### Glacadh iarrthóra - -Eisíonn na sreafaí oibre CI agus Quality Gates breithiúnas cobhsaí araon: `Gate / CI` agus -`Gate / Quality`. Áirítear ina mbeartas glactha leaganaithe gach tasc réamhtheachtach -mar riachtanach nó mar chomhairleach. Ní mór do thasc riachtanach infheidhme éirí leis: ní féidir -PASS a bhunú le torthaí atá ar iarraidh, curtha ar ceal, scipeáilte, ar feitheamh nó anaithnid. Is féidir -le haicmiú bailí do dhoiciméid amháin nó don chatalóg amháin lána cóid a dhéanamh neamh-infheidhme; -ní ghlactar le dréacht-PR mar iarrthóir. Ní thugann lipéad `hotfix` díolúine ó fhianaise. - -Clúdaíonn an dá shreabhadh oibre PRanna agus brúnna chuig brainsí main/release, seoladh láimhe agus -imeachtaí grúpa cumaisc. Ritheann brú, seoladh agus grúpa cumaisc an roghnú iomlán. Úsáideann forcanna -agus grúpaí cumaisc riteoirí óstáilte le haghaidh tascanna a roghnódh riteoirí féinóstáilte murach sin; -ní mór dóthain acmhainneachta óstáilte a dheimhniú roimh an rolladh amach. - -Aithníonn gach admháil JSON an SHA atá seiceáilte amach, an rith sreafa oibre agus an iarracht. -Diúltaíonn an CLI do neamhréir idir SHA an tseiceáil amach agus SHA an imeachta. Ceanglaíonn tástálacha sreafa oibre ballraíocht an bheartais -le liosta `needs` thasc an bhreithiúnais ionas nach féidir le lána nua nó bainte imeacht gan rabhadh. -Clúdaíonn na hadmhálacha a sreabhadh oibre féin, ní foilsiú, imscaradh ná oibriú inmheánach -scanóra chomhairligh atá ann cheana. Is athrú riaracháin ar leith é an dá ainm seiceála a ghníomhachtú i rialacha brainse; -ní chosnaíonn cur leis na tascanna seo brainse ann féin. - -### Fardal scanta stataigh - -Tá an fardal npm-alias leaganaithe agus ballraíocht an scanta stataigh le fáil in -`config/quality/gate-manifest.json`. Rith `npm run check:gate-manifest` chun ainmneacha scripte agus orduithe beachta -a bhailíochtú in aghaidh `package.json`; má chuirtear rud leis, má bhaintear rud nó má athraíonn ordú, teipfidh -an crúca áitiúil agus na tascanna aicmithe athruithe in CI araon. -Ní tasc sreafa oibre, ásc maitríse ná cás tástála é ailias: níor cheart -na comhairimh seo a chur i láthair amhail is dá mbeidís inmhalartaithe. +## Fardal na ngeataí agus próifílí forghníomhaithe + +### Iarrthóirí a ghlacadh isteach + +Astaíonn sreafaí oibre CI agus Quality Gates breithiúnas cobhsaí araon: `Gate / CI` agus +`Gate / Quality`. Áirítear ina mbeartas iontrála le leaganacha gach jab réamhtheachtach +mar jab riachtanach nó comhairleach. Ní mór do jab riachtanach infheidhme a bheith rathúil: +ní féidir le torthaí atá ar iarraidh, curtha ar ceal, scipeáilte, ar feitheamh nó anaithnid +PASS a dheimhniú. Is féidir le haicmiú bailí do dhoiciméid amháin nó don chatalóg amháin +lána cóid a dhéanamh neamh-infheidhme; ní ghlactar le dréacht-PR mar iarrthóir. Ní +tharscaoileann lipéad `hotfix` an riachtanas fianaise. + +Clúdaíonn an dá shreabhadh oibre PRanna agus brúite chuig brainsí main/release, seoladh +láimhe agus teagmhais ghrúpa cumaisc. Ritheann brú, seoladh agus grúpa cumaisc an roghnú +iomlán. Úsáideann forcanna agus grúpaí cumaisc riteoirí óstáilte le haghaidh jabanna a +roghnódh riteoirí féinóstáilte murach sin; ní mór dóthain acmhainneachta óstáilte a +fhíorú roimh an rolladh amach. + +Sainaithníonn gach admháil JSON an SHA a seiceáladh amach, rith an tsreafa oibre agus an +iarracht. Diúltaíonn an CLI do neamhréir idir SHA an tseiceáil amach agus SHA an teagmhais. +Ceanglaíonn tástálacha sreafa oibre ballraíocht an bheartais le liosta `needs` an jab +breithiúnais ionas nach féidir le lána nua ná le lána bainte imeacht gan rabhadh. +Clúdaíonn na hadmhálacha a sreabhadh oibre féin, seachas foilsiú, imscaradh nó oibriú +inmheánach scanóra chomhairligh atá ann cheana. Is athrú riaracháin ar leith é an dá ainm +seiceála a ghníomhachtú i rialacha brainse; ní chosnaíonn cur leis na jabanna seo brainse +ann féin. + +### Fardal na scananna statacha + +Tá an fardal npm-alias le leaganacha agus ballraíocht an scanadh statach le fáil in +`config/quality/gate-manifest.json`. Rith `npm run check:gate-manifest` chun ainmneacha +scripte agus orduithe beachta a bhailíochtú in aghaidh `package.json`; cuirfidh breisithe, +bainte agus imeacht orduithe an duán áitiúil agus na jabanna aicmithe athruithe in CI +araon ó rath. Ní jab sreafa oibre, ásc maitríse ná cás tástála é ailias: níor cheart na +comhairimh seo a chur i láthair mar rudaí idirmhalartaithe. Úsáid `npm run quality:scan -- --list` nó `npm run quality:scan:fast -- --list` chun na hailiasanna roghnaithe a iniúchadh gan iad a fhorghníomhú. Glaonn an riteoir ar -phointe iontrála npm, mar sin caomhnaítear a thimpeallacht rite (Bun san áireamh nuair atá sé cumraithe). -Taifeadann an lastliosta ailiasanna lasmuigh de na próifílí sin mar chinn a ghlaoitear orthu ar leithligh, agus -tá cosc ar orduithe cothabhála i bpróifílí scanta inléite amháin. - -Ní chlúdaíonn na próifílí seo ach an scanadh statach. Ní dheimhníonn siad tástálacha táirge, -clúdach, pacáistiú, seiceálacha seachtracha ná glacadh iomlán iarrthóra le haghaidh eisiúna. -Úsáideann glacadh sreafa oibre na comhaid nasctha `config/quality/admission-policy.json` agus +an bpointe iontrála npm, agus mar sin caomhnaítear a thimpeallacht rite (Bun san áireamh +san áit a bhfuil sé cumraithe). Taifeadann an lastliosta ailiasanna lasmuigh de na +próifílí sin mar ailiasanna a ghlaoitear orthu ar leithligh, agus tá cosc ar orduithe +cothabhála i bpróifílí scanta inléite amháin. + +Ní chlúdaíonn na próifílí seo ach an scanadh statach. Ní dheimhníonn siad tástálacha +táirge, clúdach, pacáistiú, seiceálacha seachtracha ná glacadh iomlán le heisiúint +iarrthóra. Úsáideann ligean isteach sa sreabhadh oibre +`config/quality/admission-policy.json` nasctha agus `scripts/quality/admission-verdict.mjs`. Fanann próifílí breathnóra eisiúna ar leithligh; -scrúdaigh a seiceálacha agus a n-admhálacha infheidhme go neamhspleách. Is tagairt é an fardal -próis thíos, ní cruthúnas gur rith geata i ndáiríre. +iniúch a seiceálacha agus a n-admhálacha infheidhme go neamhspleách. Is tagairt é an +fardal próis thíos, ní cruthúnas gur ritheadh geata i ndáiríre. Tá scripteanna faoi `scripts/check/` (geataí beartais) agus `scripts/quality/` (inneall raicéid). Is é `.github/workflows/ci.yml` foinse fírinne CI. ### Mearchonair PR eisiúna (`quality.yml`) -Comhlánaíonn `.github/workflows/quality.yml` CI ar PRanna main/release, brúnna chuig brainsí cosanta, -seoladh agus grúpaí cumaisc. Úsáideann PRanna mearseiceálacha scagtha de réir conaire. Baineadh an tógáil dhúblach -a bhí díchumasaithe go buan; fanann na fíorsheiceálacha tógála/pacáistithe/tosaithe in CI. - -| Tasc | Raon feidhme | Blocála | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | PRanna do dhoiciméid/chód; tagairtí do dhoiciméid API agus na doiciméid uile | Tá | -| `Fast Quality Gates` | PRanna cóid; seiceálacha statacha, seiceáil cineálacha, seiceáil cineálacha an deais, tástálacha aonaid a ndearnadh difear dóibh | Tá | -| `Forgotten sibling tests` | PRanna cóid; modúil athraithe rianaithe chuig tomhaltóirí statacha agus tástálacha siblín féideartha; tuairiscítear conairí bairille agus iompórtála dhinimiciúil mar dhiagnóisic chomhairleach, le heisceachtaí ceadaithe a dtagraítear dóibh | **Comhairleach** | -| `Vitest (fast-path)` | PRanna cóid; sraith thapa vitest | Tá | -| `Unit Tests fast-path` | PRanna cóid; sraith aonadtástálacha le 4 sharda | Tá | -| `No new ESLint warnings` | PRanna cóid; cosaint lint atá feasach ar cheiltí | Tá, forcanna san áireamh | -| `Merge integrity (changelog + generated skills)` | PRanna nach dréachtaí iad; loga athruithe agus sioncrónú scileanna ginte | Tá, forcanna san áireamh | - -#### Tuairisc ar thástálacha siblín dearmadta - -Athúsáideann `npm run check:forgotten-sibling-tests` an réiteoir iompórtála taobh thiar den mhapa tionchair tástála. -I gcás gach modúil táirgeachta athraithe, tuairiscíonn sé slabhraí cinntitheacha -`changed module/symbol -> static consumer -> candidate sibling test` nuair nach bhfuil an tástáil fhéideartha -i ndifríocht an iarratais tarraingthe. Coinnítear an achoimre Markdown agus toradh JSON mar -dhéantán sreafa oibre `forgotten-sibling-tests` le haghaidh calabrúcháin roimh aon rolladh amach blocála. - -Is diagnóis réitigh amháin iad ath-easpórtálacha bairille agus iompórtálacha dinimiciúla; ní chruthaíonn siad toradh blocála riamh. Tá eisceachtaí athbhreithnithe in +Comhlánaíonn `.github/workflows/quality.yml` CI ar PRanna main/release, brúite chuig +brainsí cosanta, seoladh agus grúpaí cumaisc. Úsáideann PRanna seiceálacha tapa scagtha +de réir conairí. Baineadh an tógáil dhúblach a bhí díchumasaithe go buan; fanann na +fíorsheiceálacha tógála/pacáistithe/tosaithe in CI. + +| Jab | Raon feidhme | Blocáil | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `Docs Gates (fast-path)` | PRanna do dhoiciméid/do chód; tagairtí do dhoiciméid API agus gach doiciméad | Tá | +| `Fast Quality Gates` | PRanna cóid; seiceálacha statacha, seiceáil cineálacha, seiceáil cineálacha an deais, tástálacha aonaid a ndearnadh difear dóibh | Tá | +| `Forgotten sibling tests` | PRanna cóid; modúil athraithe arna rianú chuig tomhaltóirí statacha agus tástálacha siblíneacha féideartha; tuairiscítear conairí bairille agus iompórtála dinimiciúla mar dhiagnóisic chomhairleach, le heisceachtaí tagartha ón liosta ceadaithe | **Comhairleach** | +| `Vitest (fast-path)` | PRanna cóid; sraith thapa vitest | Tá | +| `Unit Tests fast-path` | PRanna cóid; sraith aonad 4-shard | Tá | +| `No new ESLint warnings` | PRanna cóid; cosaint lint a chuireann sochtaí san áireamh | Tá, forcanna san áireamh | +| `Merge integrity (changelog + generated skills)` | PRanna nach dréachtaí iad; changelog agus sioncronú scileanna ginte | Tá, forcanna san áireamh | + +#### Tuairisc ar thástálacha siblíneacha dearmadta + +Athúsáideann `npm run check:forgotten-sibling-tests` an réiteoir iompórtála taobh thiar +den mhapa tionchair tástála. I gcás gach modúil táirgeachta athraithe, tuairiscíonn sé +slabhraí cinntitheacha `changed module/symbol -> static consumer -> candidate sibling test` +nuair nach bhfuil an tástáil fhéideartha i ndifear na hiarrata tarraingthe. Coinnítear an +achoimre Markdown agus an toradh JSON mar dhéantán sreafa oibre +`forgotten-sibling-tests` lena gcalabrú sula ndéantar aon rolladh amach blocála. + +Is diagnóisic réitigh amháin iad athonnmhairí bairille agus iompórtálacha dinimiciúla; ní chruthaíonn siad toradh blocála riamh. Coinnítear eisceachtaí athbhreithnithe in `config/quality/forgotten-sibling-allowlist.json`. Ní mór do gach iontráil an tomhaltóir agus an tástáil iarrthóra a ainmniú, -réasúnaíocht shonrach a thabhairt, agus nasc a dhéanamh le saincheist nó iarratas tarraingthe GitHub. Diúltaítear -d’iontrálacha míchumtha de réir réamhshocraithe. Ní féidir le heisceachtaí tástáil iarrthóra scriosta ná difríocht a chuireann `.skip`/`.todo` leis a cheilt; +réasúnaíocht shonrach a thabhairt, agus nasc a dhéanamh le heisiúint nó iarratas tarraingthe GitHub. Teipeann ar iontrálacha míchumtha +ar bhealach dúnta. Ní féidir le heisceachtaí tástáil iarrthóra scriosta ná diff a chuireann `.skip`/`.todo` leis a cheilt; is leis an ngeata blocála neamhspleách -`check:test-masking` i gcónaí lagú dearbhuithe agus cineálacha eile ceilte. +`check:test-masking` i gcónaí lagú dearbhuithe agus cineálacha eile folaithe. ### Jab: `lint` -Ritear é ar gach PR chuig `main`. Cuireann sé bac ar chumasc má theipeann air. - -| Script (`npm run ...`) | Bailíochtaíonn | Blocála | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Tá leagan Node.js laistigh den raon tacaithe | Tá | -| `check:cycles` | Iompórtálacha ciorclacha — gach modúl `src/` + `open-sse/` | Tá | -| `check:route-validation:t06` | Tá scéimeanna Zod i láthair ar gach ródaire (beartas Shraith 6) | Tá | -| `check:any-budget:t11` | Ní sháraíonn líon `@ts-expect-error // any` an buiséad (catraca Shraith 11) | Tá | -| `check:provider-consistency` | Tá iontráil chomhfhreagrach in `providerRegistry.ts` ag gach soláthraí in `providers.ts` (agus a mhalairt, laistigh den liosta ceadaithe) | Tá | -| `check:model-lifecycle` | Fanann na trí thábla ródaithe a choinnítear de láimh comhsheasmhach leis an léargas saolré atá seiceáilte isteach (#11503): ní thugann `FITNESS_TABLE` (`taskFitness.ts`) scór d'aon aitheantas scortha is féidir le `REGISTRY` a ródú; tá gach sprioc `BUILT_IN_ALIASES` i láthair in `REGISTRY` agus as láthair ón léargas d'aitheantais scortha; déantar gach aitheantas scortha atá fós in `REGISTRY` a chur ar aghaidh nó a liostú in `allowedRetiredInCatalog`; agus níl aon fhoinse ná sprioc de chuid `DEFAULT_DEGRADATION_MAP` marcáilte mar scortha sa léargas sin. Ní chruthaíonn sé seo go bhfuil samhail á soláthar faoi láthair ag seirbhís réamhtheachtach bheo. As líne — déantar comparáid le `config/quality/model-lifecycle.json`, a athnuachan de láimh le `npm run quality:refresh-model-lifecycle` (líonra; níl sé ceangailte le CI). Is raicín laghdaitheach é `allowedRetiredInCatalog`: ná cuir iontráil leis ach amháin má tá saincheist rianaithe ann. | Tá | -| `check:fetch-targets` | Réitíonn gach `fetch("/api/...")` in `src/` ar thaobh an chliaint chuig `route.ts` atá ann i ndáiríre | Tá | -| `check:deps` | Tá gach spleáchas is féidir a shuiteáil le `npm install` thar gach `package.json` sa stór in `dependency-allowlist.json`; cuirtear bratach le pacáistí nua nach bhfuil pionnáilte nó a d'fhéadfadh a bheith slopsquattáilte | Tá | -| `audit:deps` | `npm audit` (fréamh + electron) — gan aon chomhairleoir ardriosca/criticiúil (forluíonn sé le `check:vuln-ratchet` osv; féach Rationalization Backlog) | Tá | -| `check:lockfile` | Sláine `package-lock.json` — clárlann https, haiseanna sláine, gan aon sáruithe óstaigh | Tá | -| `check:licenses` | Liosta ceadaithe ceadúnas SPDX le haghaidh spleáchais táirgthe | Tá | -| `check:tracked-artifacts` | Gan aon déantáin tiomsaithe / naisc shiombalacha `node_modules` geallta (ritear é freisin i réamh-ghealltanas husky; coinnítear an réamh-bhrú éadrom d’aon ghnó — #6716) | Tá | -| `check:ai-attribution` | Gan aon leantóir `Co-Authored-By` ó IS/bot ná buntásc giniúna IS i ngealltanais, teideal ná corp PR — Riail Dhocht #16 (sa lúb tapa-geataí `quality.yml` le haghaidh PR→`release/**` — léann sé pálasta an teagmhais, ní dhéanann sé aon rud lasmuigh de PRanna — agus céim do PR amháin i lint `ci.yml` le haghaidh PR→`main`; chomh maith leis sin, crúca `commit-msg` husky; ceadaítear comhúdair dhaonna; #14436) | -| `check:vitest-exclusions` | Ainmníonn gach eisiamh Vitest saincheist rianaithe agus tá sé le feiceáil in `config/quality/vitest-exclusions.json` (#13204) | Tá | -| `check:file-size` | Ní sháraíonn aon chomhad foinse an uasteorainn de réir iarmhíre (raicín: comhaid mhóra reoite sa liosta `frozen`) | Tá | -| `check:error-helper` | Úsáideann freagraí earráide i seiceadóirí/láimhseálaithe `buildErrorBody()` / `sanitizeErrorMessage()` (Riail Dhocht #12) | Tá | -| `check:migration-numbering` | Tá comhaid SQL imirce uimhrithe go seicheamhach, gan aon bhearnaí ná dúblaigh | Tá | -| `check:public-creds` | Níl aon `client_id`/`client_secret` OAuth litriúil ná eochracha Gréasáin Firebase lasmuigh de `publicCreds.ts` (Riail Dhocht #11) | Tá | -| `check:db-rules` | Níl aon SQL amh lasmuigh de mhodúil `src/lib/db/`; níl aon iompórtálacha bairille ó `localDb.ts` (Rialacha Dochta #2/#5) | Tá | -| `check:known-symbols` | Meaitseálann riteoirí soláthraithe, straitéisí ródúcháin agus aistritheoirí atá cláraithe ina dtáblaí seolta na comhaid ar an diosca — níl aon siombailí dílleachtacha ná neamhdhearbhaithe ann | Tá | -| `check:route-guard-membership` | Aicmítear gach bealach a sheolann próiseas páiste le `isLocalOnlyPath()` (Rialacha Dochta #15/#17) | Tá | -| `check:test-discovery` | Bailíonn riteoir tástála amháin ar a laghad gach comhad `*.test.ts` / `*.spec.ts` sa stór (raicín: ní féidir ach laghdú teacht ar liosta na ndílleachtaí in `test-discovery-baseline.json`) | Tá | -| `check:agent-skills-sync` | Meaitseálann déantáin ghinte agent-skills lena gcatalóg foinseach (gan aon imeacht) | -| `check:provider-asset-provenance` | Tá iontráil bhunáitíochta taifeadta ag lógónna/sócmhainní soláthraithe | -| `lint:json` | Parsálann comhaid chumraíochta JSON agus comhlíonann siad rialacha lint na stórtha | -| `typecheck:core` | Tiomsú TypeScript gan earráidí (rabhaidh chomhairleacha amháin) | Tá | -| `typecheck:noimplicit:core` | `noImplicitAny` docht — dírithe ar an todhchaí; tá anótálacha fós de dhíth ar go leor suíomhanna glaonna atá ann cheana | **Comhairleach** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` teoranta do `src/app/(dashboard)/**` (#7033) — ní chuimsíonn liosta ceadaithe coimeádta 27 gcomhad `typecheck:core` aon TSX de chuid an deais, agus ní dhéanann `next build` seiceáil cineáil air ach oiread (socraíonn `next.config.mjs` `ignoreBuildErrors: true`), mar sin ní raibh aischéimnithe aitheantóirí dílleachtacha ann (#6625/#6909) le feiceáil ag CI. Déantar difreálacha i gcoinne bonnlíne reoite comhairimh de réir comhaid/de réir chóid TS (`config/quality/dashboard-typecheck-baseline.json`, an patrún céanna forfheidhmithe seanda agus atá ag `check:known-symbols`) — ní theipeann ar an ngeata ach de bharr earráidí NUA sa bhreis ar an gcomhaireamh bonnlínithe; ísligh de réir a chéile é le `--update` nuair a cheartaítear earráid atá ann cheana. | Tá | +Ritear é ar gach PR chuig `main`. Cuireann teip bac ar chumasc. + +| Script (`npm run ...`) | Bailíochtaíonn | Blocála | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Tá an leagan de Node.js laistigh den raon tacaithe | Tá | +| `check:cycles` | Iompórtálacha ciorclacha ar fud `src/` + `open-sse/` ar fad (bunaithe ar AST, `paths` tsconfig réitithe). Lom = comhairleach, liostaíonn sé na timthriallta. Cuireann `check:cycles:ratchet` (an ceann a ritheann CI) bac nuair a sháraíonn an líon an uasteorainn `metrics.cycles` in `quality-baseline.json` — 14 faoi láthair, `direction: down`, mar sin ní féidir leis ach titim (#15159 G-01/G-02) | Tá (raicín) | +| `check:route-validation:t06` | Scéimeanna Zod i láthair ar gach bealach (beartas Shraith 6) | Tá | +| `check:any-budget:t11` | Ní sháraíonn líon `@ts-expect-error // any` an buiséad (catraca Shraith 11) | Tá | +| `check:provider-consistency` | Tá iontráil chomhfhreagrach in `providerRegistry.ts` ag gach soláthraí in `providers.ts` (agus a mhalairt, laistigh den liosta ceadaithe) | Tá | +| `check:model-lifecycle` | Fanann na trí thábla ródaithe a choinnítear de láimh comhsheasmhach leis an léargas saolré a seiceáladh isteach (#11503): ní thugann `FITNESS_TABLE` (`taskFitness.ts`) scór d'aon aitheantas scortha is féidir le `REGISTRY` a ródú; tá gach sprioc `BUILT_IN_ALIASES` i láthair in `REGISTRY` agus as láthair ón léargas ar aitheantais scortha; cuirtear gach aitheantas scortha atá fós in `REGISTRY` ar aghaidh nó liostaítear é in `allowedRetiredInCatalog`; agus níl aon fhoinse ná sprioc `DEFAULT_DEGRADATION_MAP` marcáilte mar scortha sa léargas sin. Ní chruthaíonn sé seo go bhfuil samhail á soláthar faoi láthair ag réamhsheirbhís bheo. As líne — déantar comparáid le `config/quality/model-lifecycle.json`, a athnuachan de láimh le `npm run quality:refresh-model-lifecycle` (líonra; níl sé comhtháite le CI). Is raicín laghdaithe é `allowedRetiredInCatalog`: ná cuir iontráil leis ach amháin má tá saincheist rianaithe ann. | Tá | +| `check:fetch-targets` | Réitíonn gach `fetch("/api/...")` i `src/` ar thaobh an chliaint chuig `route.ts` atá ann i ndáiríre | Tá | +| `check:deps` | Tá gach spleáchas is féidir a shuiteáil le `npm install`, ar fud gach `package.json` sa stór, in `dependency-allowlist.json`; cuirtear bratach le pacáistí nua nach bhfuil pionnáilte nó a bhfuil ainmneacha mealltacha orthu | Tá | +| `audit:deps` | `npm audit` (fréamh + electron) — gan aon chomhairleacht ardriosca/chriticiúil (forluíonn sé le `check:vuln-ratchet` de chuid osv; féach Riaráiste an Réasúnaithe) | Tá | +| `check:lockfile` | Sláine `package-lock.json` — clárlann https, hais sláine, gan aon sáruithe óstach | Tá | +| `check:licenses` | Liosta ceadaithe ceadúnas SPDX do spleáchais táirgthe | Tá | +| `check:tracked-artifacts` | Gan déantáin tógála / siomnaisc `node_modules` tiomnaithe (ritear é freisin i réamh-thiomnú husky; coinnítear an réamhbhrú éadrom d’aon ghnó — #6716) | Tá | +| `check:ai-attribution` | Gan leantóir `Co-Authored-By` ó IS/róbat ná buntásc giniúna IS i dtiomnúcháin, teideal ná corp PR — Riail Dhocht #16 (sa lúb mearthairsí `quality.yml` do PR→`release/**` — léann sé pálasta an teagmhais, agus ní dhéanann sé aon ní lasmuigh de PRanna — agus céim do PRanna amháin i lint `ci.yml` do PR→`main`; chomh maith leis sin, crúca `commit-msg` husky; ceadaítear comhúdair dhaonna; #14436) | +| `check:vitest-exclusions` | Ainmníonn gach eisiamh Vitest saincheist rianaithe agus tá sé le feiceáil in `config/quality/vitest-exclusions.json` (#13204) | Tá | +| `check:file-size` | Ní sháraíonn aon chomhad foinseach an uasteorainn de réir iarmhíre (raicín: comhaid mhóra reoite sa liosta `frozen`) | Tá | +| `check:error-helper` | Úsáideann freagraí earráide i seiceadóirí/láimhseálaithe `buildErrorBody()` / `sanitizeErrorMessage()` (Riail Dhocht #12) | Tá | +| `check:migration-numbering` | Tá comhaid SQL imirce uimhrithe go seicheamhach, gan bearnaí ná dúblaigh | Tá | +| `check:public-creds` | Níl aon `client_id`/`client_secret` OAuth ná eochracha Gréasáin Firebase litriúla lasmuigh de `publicCreds.ts` (Riail Dhocht #11) | Tá | +| `check:db-rules` | Níl aon SQL amh lasmuigh de mhodúil `src/lib/db/`; níl aon allmhairí bairille ó `localDb.ts` (Rialacha Dochta #2/#5) | Tá | +| `check:known-symbols` | Meaitseálann na riteoirí soláthraí, na straitéisí ródúcháin, agus na haistritheoirí atá cláraithe ina dtáblaí seolta na comhaid ar diosca — níl aon siombailí dílleachtacha ná neamhdhearbhaithe ann | Tá | +| `check:route-guard-membership` | Tá gach bealach a thionscnaíonn próiseas linbh aicmithe ag `isLocalOnlyPath()` (Rialacha Dochta #15/#17) | Tá | +| `check:test-discovery` | Bailíonn reathaí tástála amháin ar a laghad gach comhad `*.test.ts` / `*.spec.ts` sa stór (raicín: ní féidir ach laghdú teacht ar liosta na gcomhad dílleachtach in `test-discovery-baseline.json`) | Tá | +| `check:agent-skills-sync` | Meaitseálann déantáin ghinte agent-skills a gcatalóg fhoinseach (gan aon imeacht) | +| `check:provider-asset-provenance` | Tá iontráil bhunáite taifeadta ag lógónna/sócmhainní soláthraithe | +| `lint:json` | Parsálann comhaid chumraíochta JSON agus comhlíonann siad rialacha lint an taisclainne | +| `typecheck:core` | Tiomsú TypeScript gan earráidí (rabhaidh chomhairleacha amháin) | Tá | +| `typecheck:noimplicit:core` | `noImplicitAny` docht — ag féachaint chun cinn; tá anótálacha fós de dhíth ar go leor suíomhanna glao réamhreatha | **Comhairleach** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` teoranta do `src/app/(dashboard)/**` (#7033) — ní chuimsíonn liosta ceada coimeádta 27 gcomhad `typecheck:core` aon TSX de chuid an deais, agus ní dhéanann `next build` seiceáil cineáil air ach oiread (socraíonn `next.config.mjs` `ignoreBuildErrors: true`), mar sin ní raibh cúlchéimnithe aitheantóirí dílleachtaithe ann (#6625/#6909) infheicthe ag CI. Déantar difreálacha i gcoinne bunlíne reoite comhairimh de réir comhaid/de réir cód TS (`config/quality/dashboard-typecheck-baseline.json`, an patrún céanna forfheidhmithe seanaimsearthachta agus atá ag `check:known-symbols`) — ní theipeann ar an ngeata ach amháin de bharr earráidí NUA os cionn an chomhairimh bhunlíne; ísligh an raicín le `--update` nuair a shocraítear earráid réamhreatha. | Tá | ### Jab: `quality-gate` -Ritheann sé tar éis `test-coverage`. Cuireann sé bac ar chumasc má theipeann air. +Ritear é tar éis `test-coverage`. Cuireann teip bac ar chumasc. -| Script | Bailíochtaíonn sé | Blocála | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `quality:collect` | Gineann sé `quality-metrics.json` (líon rabhaidh ESLint, clúdach ón tuairisc chumaiscthe maidir le codanna) | Tá (roimh an raicín) | -| `quality:ratchet` | Níor chúlaigh aon mhéadracht in `quality-baseline.json` (rabhaidh ESLint ≤ bonnlíne; clúdach ≥ bonnlíne) | Tá | -| `check:duplication` | Ní sháraíonn dúbláil cóid (jscpd@4) an bhonnlíne in `quality-baseline.json` | Tá | -| `check:complexity` | Ní sháraíonn castacht chioglamatach ar leibhéal comhaid an uasteorainn (`complexity` croíúil ESLint + `max-lines-per-function`) | Tá | -| `check:cognitive-complexity` | Raicín castachta cognaíche (`eslint-plugin-sonarjs`) — pas ESLint ar leith; ritheann CI an dá cheann cumaiscthe mar an chéim aonair `check:complexity-ratchets` | Tá | -| `check:dead-code` | Ní théann raicín easpórtálacha / comhad neamhúsáidte (knip) in olcas i gcomparáid leis an mbonnlíne | Tá | -| `check:compression-budget` | Buiséad tagarmharcála comhbhrúite — ní mór nach rachadh íosleibhéil choigilteas comharthaí gach innill in olcas | Tá | -| `check:type-coverage` | Ní théann an raicín céatadáin chlóscríofa (`type-coverage`) in olcas; cuimsíonn sé `typecheck:noimplicit:core` den chuid is mó | Tá | -| `check:codeql-ratchet` | Ní théann líon foláireamh oscailte CodeQL in olcas (léann sé trí `gh api`; scipeáil mhaiseach gan chomhartha) — minicíocht athnuachana agus truicear láimhe: féach "Raicín CodeQL" thíos | Tá | +| Script | Bailíochtaíonn | Blocála | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `quality:collect` | Astaíonn `quality-metrics.json` (líon rabhaidh ESLint, clúdach ón tuairisc chomhcheangailte shardanna) | Tá (roimh an ratchet) | +| `quality:ratchet` | Níor chúlaigh aon mhéadracht in `quality-baseline.json` (rabhaidh ESLint ≤ bunlíne; clúdach ≥ bunlíne) | Tá | +| `check:duplication` | Ní sháraíonn dúbláil cóid (jscpd@4) an bhunlíne in `quality-baseline.json` | Tá | +| `check:complexity` | Ní sháraíonn castacht chioclamatach ar leibhéal comhaid an uasteorainn (croí-rialacha ESLint `complexity` + `max-lines-per-function`) | Tá | +| `check:cognitive-complexity` | Ratchet castachta cognaíche (`eslint-plugin-sonarjs`) — pas ESLint ar leith; ritheann CI an dá cheann cumaiscthe mar an chéim aonair `check:complexity-ratchets` | Tá | +| `check:dead-code` | Ní théann ratchet easpórtálacha / comhad neamhúsáidte (knip) in olcas i gcomparáid leis an mbunlíne | Tá | +| `check:compression-budget` | Buiséad tagarmhairc comhbhrúite — ní ceadmhach d’íosleibhéil choigilteas comharthaí in aghaidh an innill dul in olcas | Tá | +| `check:type-coverage` | Ní théann an ratchet céatadáin chlóscríofa (`type-coverage`) in olcas; tagann `typecheck:noimplicit:core` faoina raon den chuid is mó | Tá | +| `check:codeql-ratchet` | Ní théann líon na bhfoláireamh oscailte CodeQL in olcas (léann sé trí `gh api`; scipeáil shéimh gan chomhartha) — le haghaidh minicíocht athnuachana agus truicear láimhe: féach "Ratchet CodeQL" thíos | Tá | ### Jab: `quality-extended` -Is jab comhairleach é an jab iomlán (`continue-on-error: true`). Ritheann na raicíní atá bunaithe ar npm -i ndáiríre; suiteálann na scanóirí seachtracha trí `gh release download` agus scipeálann siad iad féin (cód scortha 0) -nuair atá dénártha fós in easnamh. +Is comhairleach é an jab iomlán (`continue-on-error: true`). Ritheann na ratchets bunaithe ar npm +i gceart; suiteálann na scanóirí seachtracha trí `gh release download` agus scipeálann siad iad féin (cód scoir 0) +nuair atá dénárthach fós in easnamh. -| Script | Bailíochtaíonn sé | Blocála | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:circular-deps` | Gan aon spleáchais chiorclacha (dpdm) | **Comhairleach** | -| `check:bundle-size` | Ní sháraíonn méid an bheartáin an uasteorainn | **Comhairleach** | -| `check:secrets` | Scanadh rúin (gitleaks) — scipeálann sé má tá an dénártha in easnamh | **Comhairleach** | -| `check:vuln-ratchet` | Ní théann leochaileachtaí spleáchais (osv-scanner) in olcas — scipeálann sé má tá an dénártha in easnamh | **Comhairleach** | -| `check:workflows` | Lintiú sreafa oibre (actionlint + zizmor); teipeann ar scanóirí in easnamh/briste, tuairiscí neamhbhailí nó bonnlíne raicín in easnamh mar INCOMPLETE. Leanann torthaí bailí an polasaí docht/comhairleach/raicín roghnaithe | Rith de dhíth; raicín zizmor blocála in CI | -| `check:openapi-breaking` | Athruithe bristeacha ar chonradh an API phoiblí (`openapi.yaml`) i gcomparáid leis an mbrainse bonn (oasdiff) — gineann sé `openapiBreaking=N`; scipeálann sé má tá oasdiff in easnamh nó mura féidir an tsonraíocht bhonn a réiteach | **Comhairleach** | +| Script | Bailíochtaíonn | Blocála | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:circular-deps` | Gan aon spleáchais chiorclacha (dpdm) | **Comhairleach** | +| `check:bundle-size` | Ní sháraíonn méid an bheartáin an uasteorainn | **Comhairleach** | +| `check:secrets` | Scanadh rúin (gitleaks) — scipeálann sé má tá an dénárthach in easnamh | **Comhairleach** | +| `check:vuln-ratchet` | Ní théann leochaileachtaí spleáchais (osv-scanner) in olcas — scipeálann sé má tá an dénárthach in easnamh | **Comhairleach** | +| `check:workflows` | Lintiú sreafa oibre (actionlint + zizmor); má bhíonn scanóirí in easnamh/briste, tuairiscí neamhbhailí nó bunlíne ratchet in easnamh, teipeann sé mar INCOMPLETE. Leanann torthaí bailí an polasaí docht/comhairleach/ratchet roghnaithe | Rith riachtanach; ratchet zizmor blocála in CI | +| `check:openapi-breaking` | Athruithe bristeacha ar chonradh poiblí an API (`openapi.yaml`) i gcomparáid leis an mbrainse bonn (oasdiff) — astaíonn `openapiBreaking=N`; scipeálann sé má tá oasdiff in easnamh nó mura féidir an tsonraíocht bhonn a réiteach | **Comhairleach** | ### Jab: `docs-sync-strict` -Ritheann sé ar gach PR chuig `main`. Cuireann sé bac ar chumasc má theipeann air. - -| Script | Bailíochtaíonn sé | Blocála | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `check:docs-all` | Meitigeata a ritheann na 6 fho-gheata thíos go seicheamhach | Tá | -| ↳ `check:docs-sync` | Comhsheasmhacht leaganacha CHANGELOG / OpenAPI / llm.txt | Tá | -| ↳ `check:docs-counts` | Tá na comhairimh sa phrós (líon soláthraithe, líon aistrithe, etc.) laistigh d'fhuinneog raicéid na bhfíorchomhaireamh | Tá | -| ↳ `check:env-doc-sync` | Tá gach athróg timpeallachta in `.env.example` doiciméadaithe i dtábla doiciméad, agus a mhalairt | Tá | -| ↳ `check:deprecated-versions` | Níl aon teaghráin leagain dhímheasta sna doiciméid | Tá | -| ↳ `check:doc-links` | Réitíonn naisc inmheánacha markdown sna doiciméid chuig fíorchomhaid (foirm `[text]`/`(path)`) | Tá | -| ↳ `check:fabricated-docs` | Tá na bealaí, na hathróga timpeallachta, na horduithe CLI, ainmneacha na gcrúcaí, agus na conairí comhaid a luaitear sna doiciméid sa bhunachar cód. Geata docht trí `--strict`; teip bhog gan an bhratach. | Tá (trí `--strict` in CI) | -| `check:cli-i18n` | Tá teaghráin orduithe CLI i ngach comhad logchaighdeáin i18n | Tá | -| `check:openapi-coverage` | Clúdaíonn sonraíocht OpenAPI íosleibhéal raicéadaithe de na fíorbhealaí ar a laghad | Tá | -| `check:openapi-security-tiers` | Tá nótaí na sraitheanna slándála in `openapi.yaml` comhsheasmhach le haicmithe `routeGuard.ts` | **Comhairleach** | -| `check:openapi-routes` | Réitíonn gach conair in `openapi.yaml` chuig fíorchomhad `route.ts` (frithshamhlú) | Tá | -| `check:docs-symbols` | Réitíonn gach tagairt `/api/...` in `docs/**/*.md` chuig fíorchomhad `route.ts` (frithshamhlú) | Tá | -| `i18n translation drift` | Eochracha neamhaistrithe i gcomhaid logchaighdeáin i18n — rabhadh amháin | **Comhairleach** | - -### Tasc: `i18n-ui-coverage` - -| Script | Bailíochtaíonn sé | Blocála | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -| `check-ui-keys-coverage` (inlíne) | Tá clúdach eochracha i18n an chomhéadain úsáideora ≥ 65% | Tá | -| `check-ui-value-drift` (inlíne) | Ní fhágann **luach** Béarla athscríofa aon aistriúchán seanchaite ina dhiaidh | Tá | -| `check-new-key-coverage` (inlíne) | Aistrítear eochair **nua** Bhéarla i ngach logchaighdeán — diúltaítear do mharcóir `__MISSING__:` | Tá | -| `check-translation-ratio` | Ní mór nach sáródh cóimheas na bhfíoraistriúchán de réir logchaighdeáin (duilleoga atá comhionann leis an mBéarla / ionadchoinneála / ar iarraidh lasmuigh den liosta ceadaithe) `config/quality/i18n-translation-baseline.json` + lamháil | **Comhairleach** | - -Teastaíonn `fetch-depth: 0` — déanann an geata athraithe luacha difríocht idir `en.json` agus an bonn cumaisc. - -#### `check-ui-value-drift` — geata aistriúchán seanchaite - -Aimsíonn sé an t-aon aischéimniú i18n nach féidir leis na geataí eile a fheiceáil ó thaobh struchtúir de: athscríobhtar luach Béarla -agus fágtar na haistriúcháin a díorthaíodh ón mBéarla _roimhe seo_ ina ndiaidh, sa chaoi go -leanann úsáideoirí nach bhfuil Béarla acu orthu ag léamh téacs atá muiníneach ach atá mícheart anois. - -Seoladh é seo i ndáiríre. Athscríobhadh `oauthModal.googleOAuthWarning` nuair a cuireadh an -cúntóir logála isteach Antigravity leis (#5203); choinnigh **39 as 43 logchaighdeán** téacs a dúirt le hoibreoirí “an -URL iomlán a chóipeáil agus é a ghreamú thíos” — sreabhadh nach féidir a chur i gcrích don soláthraí sin. Níor -tugadh faoi deara é go dtí #8463 mar: - -- ní líonann `sync-ui-keys` siar ach eochracha atá **in easnamh**, agus ní cinn atá **seanchaite** riamh; -- comhaireann `check-ui-keys-coverage` _láithreacht_ eochrach, mar sin áirítear aistriúchán seanchaite mar cheann atá clúdaithe; -- rianaíonn `check-translation-drift` na scátháin doiciméadúcháin `docs/i18n//**.md` — - ní léann sé `src/i18n/messages/*.json` riamh. Tá sé blocála sa tasc `docs-sync-strict` ó rinneadh - an t-athshioncronú 2026-09: cuir croídhoiciméad in eagar → `npm run i18n:run -- --files=` (ar leibhéal rannáin, saor). - -**Feasach ar dhifir, gan bonnlíne mar thaca.** Déanann sé `en.json` ag bonn na cumaisce a chur i gcomparáid leis an -gcrann oibre; i gcás gach eochrach ar athraíodh a luach Béarla, tá aon logchaighdeán a bhfuil -aistriúchán gan athrú aige fós as dáta. Déanann sé seo **fiachas atá ann cheana a reo** d’aon ghnó — ní féidir le difríocht -a thaispeáint cén seanleagan Béarla as ar tháinig aistriúchán seanbhunaithe, mar sin ní dhéanann an geata breithiúnas -ach ar a mbaineann an t-athrú reatha leis. Chosnódh an rogha eile (bonnlíne haise in aghaidh na heochrach) -comhad ginte ~600 KB, 3× níos mó ná an bhonnlíne reatha is mó, agus bheadh sé á athrú ar gach PR i18n. +Ritheann sé ar gach PR chuig `main`. Cuireann teip bac ar chumasc. + +| Script | Bailíochtaíonn sé | Blocála | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `check:docs-all` | Meiteachomhla a ritheann na 6 fho-chomhla thíos go seicheamhach | Tá | +| ↳ `check:docs-sync` | Comhsheasmhacht leaganacha idir CHANGELOG / OpenAPI / llm.txt | Tá | +| ↳ `check:docs-counts` | Tá na háirimh sa phrós (líon soláthraithe, líon ascnaimh, srl.) laistigh d'fhuinneog raicéid na bhfíor-áireamh | Tá | +| ↳ `check:env-doc-sync` | Tá gach athróg timpeallachta in `.env.example` doiciméadaithe i dtábla doiciméadachta, agus a mhalairt | Tá | +| ↳ `check:deprecated-versions` | Níl aon teaghráin leagain atá dímholta sna doiciméid | Tá | +| ↳ `check:doc-links` | Réitíonn naisc inmheánacha markdown sna doiciméid chuig fíorchomhaid (foirm `[text]`/`(path)`) | Tá | +| ↳ `check:fabricated-docs` | Tá na bealaí, na hathróga timpeallachta, na horduithe CLI, ainmneacha na gcrúcaí, agus na conairí comhaid a luaitear sna doiciméid ann sa bhunachar cód. Comhla chrua trí `--strict`; teip bhog gan an bhratach. | Tá (trí `--strict` in CI) | +| `check:cli-i18n` | Tá teaghráin orduithe CLI i láthair i ngach comhad logchaighdeáin i18n | Tá | +| `check:openapi-coverage` | Clúdaíonn sonraíocht OpenAPI ar a laghad íoslíon fíorbhealaí atá socraithe le raicéad | Tá | +| `check:openapi-security-tiers` | Tá anótálacha na sraitheanna slándála in `openapi.yaml` comhsheasmhach le haicmithe `routeGuard.ts` | **Comhairleach** | +| `check:openapi-routes` | Réitíonn gach conair in `openapi.yaml` chuig fíorchomhad `route.ts` (frith-shiamsú) | Tá | +| `check:docs-symbols` | Réitíonn gach tagairt `/api/...` in `docs/**/*.md` chuig fíorchomhad `route.ts` (frith-shiamsú) | Tá | +| `i18n translation drift` | Eochracha neamhaistrithe i gcomhaid logchaighdeáin i18n — rabhadh amháin | **Comhairleach** | + +### Jab: `i18n-ui-coverage` + +| Script | Bailíochtaíonn sé | Blocála | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `check-ui-keys-coverage` (inlíne) | Tá clúdach eochracha i18n an chomhéadain úsáideora ≥ 65% | Tá | +| `check-ui-value-drift` (inlíne) | Ní fhágann **luach** Béarla athscríofa aon aistriúchán seanchaite ina dhiaidh | Tá | +| `check-new-key-coverage` (inlíne) | Aistrítear eochair **nua** Bhéarla i ngach logchaighdeán — diúltaítear do mharcóir `__MISSING__:` | Tá | +| `check-translation-ratio` | Ní ceadmhach don chóimheas fíoraistriúcháin in aghaidh an logchaighdeáin (ionann leis an mBéarla / ionadchoinneálaí / iontrálacha in easnamh lasmuigh den liosta ceadaithe) dul thar `config/quality/i18n-translation-baseline.json` + lamháltas | **Comhairleach** | + +Teastaíonn `fetch-depth: 0` — déanann an chomhla um athrú luacha difríocht idir `en.json` agus an bonn cumaisc. + +#### `check-ui-value-drift` — comhla aistriúchán seanchaite + +Aimsíonn sé seo an t-aon aischéimniú i18n nach féidir leis na comhlaí eile a fheiceáil ó thaobh struchtúir de: athscríobhtar luach Béarla +agus fanann na haistriúcháin a díorthaíodh ón mBéarla _roimhe seo_ ina ndiaidh, sa chaoi go +leanann úsáideoirí nach labhraíonn Béarla orthu ag léamh téacs muiníneach atá mícheart anois. + +Seoladh é seo i ndáiríre. Athscríobhadh `oauthModal.googleOAuthWarning` nuair a cuireadh an cúntóir logála isteach Antigravity +i bhfeidhm (#5203); choinnigh **39 as 43 logchaighdeán** téacs a dúirt le hoibreoirí "an URL iomlán a chóipeáil +agus é a ghreamú thíos" — sreabhadh nach féidir a chríochnú don soláthraí sin. Níor tugadh +faoi deara é go dtí #8463 mar: + +- ní dhéanann `sync-ui-keys` ach eochracha atá **as láthair** a líonadh siar, ní eochracha atá **seanchaite**; +- áiríonn `check-ui-keys-coverage` _láithreacht_ eochrach, mar sin áirítear aistriúchán seanchaite mar cheann clúdaithe; +- rianaíonn `check-translation-drift` scátháin doiciméadachta `docs/i18n//**.md` — + ní léann sé `src/i18n/messages/*.json` riamh. Blocála sa jab `docs-sync-strict` ó rinneadh an + t-athshioncronú 2026-09: cuir croídhoiciméad in eagar → `npm run i18n:run -- --files=` (ar leibhéal rannáin, saor). + +**Feasach ar dhif, gan tacaíocht ó bhonnlíne.** Déanann sé comparáid idir `en.json` ag an gcomhbhonn cumaisc agus an +crann oibre; i gcás gach eochrach ar athraigh a luach Béarla, tá aon teanga ina bhfuil +aistriúchán nár athraíodh fós as dáta. Déanann sé seo **an fiachas atá ann cheana a reo** d’aon ghnó — ní féidir le dif +a nochtadh cén seanleagan Béarla as ar tháinig aistriúchán seanbhunaithe, mar sin ní dhéanann an geata breithiúnas +ach ar a mbaineann an t-athrú reatha leis. Bheadh comhad ginte ~600 KB ag teastáil ón rogha eile +(bonnlíne haise in aghaidh na heochrach), 3× níos mó ná an bhonnlíne is mó atá ann, agus é á athrú ar gach PR i18n. Tá dhá bhealach ann chun é a shásamh: @@ -221,7 +229,7 @@ Tá dhá bhealach ann chun é a shásamh: 2. socraigh iad mar `__MISSING__:` — soláthraíonn an t-am rite an Béarla ceartaithe ansin (`src/i18n/request.ts::deepMergeFallback`, #7258) agus cuirtear an eochair sa scuaine le haistriú. -Má tháinig athrú ar **bhrí** na teaghráin, is fearr **an eochair a athainmniú**: ní féidir le heochair nua +Má d’athraigh **brí** na teaghráin, is fearr **an eochair a athainmniú**: ní féidir le heochair nua aistriúchán as dáta a fháil le hoidhreacht. Sin é an patrún a d’úsáid #8463. ```bash @@ -230,48 +238,48 @@ npm run i18n:check-value-drift:warn # tuairisc amháin BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Scoireann sé le 0 agus `SKIP reason=base-unresolved` nuair nach féidir an chatalóg bhonnlíne a léamh (clón éadomhain -gan an tagairt bhonnlíne), ar aon dul le `check-openapi-breaking`. +Filleann sé le cód scoir 0 agus `SKIP reason=base-unresolved` nuair nach féidir an bunchatalóg a léamh (clón éadomhain +gan an buntagairt), ar aon dul le `check-openapi-breaking`. ### Jab: `i18n` -Maitrís iomlán bailíochtaithe i18n (jab amháin in aghaidh an logchaighdeáin). Is jab comhairleach é an jab iomlán. +Maitrís iomlán bailíochtaithe i18n (jab amháin in aghaidh na teanga). Is comhairleach an jab iomlán. -| Script | A bhailíochtaíonn sé | Bacach | -| ------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- | -| `validate_translation.py quick` | Iomláine an aistriúcháin in aghaidh an logchaighdeáin | **Comhairleach** (`continue-on-error: true` ar an jab iomlán) | +| Script | Bailíochtaíonn sé | Blocáil | +| ------------------------------- | --------------------------------------------- | ------------------------------------------------------------- | +| `validate_translation.py quick` | Iomláine an aistriúcháin in aghaidh na teanga | **Comhairleach** (`continue-on-error: true` ar an jab iomlán) | ### Jab: `pr-test-policy` -Ní ritheann sé ach ar iarratais tarraingthe. +Ritheann sé ar iarratais tarraingthe amháin. -| Script | A bhailíochtaíonn sé | Bacach | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| `check:pr-test-policy` | Ní mór do PRanna a athraíonn cód táirgeachta in `src/`, `open-sse/`, `electron/`, nó `bin/` tástálacha a chur san áireamh nó a nuashonrú (Riail Dhocht #8) | Tá | -| `check:test-masking` | Ní laghdaíonn comhaid tástála athraithe líon glan na ndearbhuithe ná ní chuireann siad tátaleolaíochtaí `assert.ok(true)` leis | Tá | -| `check:pr-evidence` | Luann corp an PR fianaise tástála/VPS don athrú (cuireann sé Riail Dhocht #18 i bhfeidhm go meicniúil trí phrós an PR a chuardach le grep — leochaileach, féach an Riaráiste) | Tá | +| Script | Bailíochtaíonn sé | Blocáil | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `check:pr-test-policy` | Ní mór tástálacha a chur san áireamh nó a nuashonrú i PRanna a athraíonn cód táirgthe in `src/`, `open-sse/`, `electron/`, nó `bin/` (Riail Dhocht #8) | Tá | +| `check:test-masking` | Ní laghdaíonn comhaid tástála athraithe líon glan na ndearbhuithe ná ní chuireann siad athráiteolaíochtaí `assert.ok(true)` leis | Tá | +| `check:pr-evidence` | Luann corp an PR fianaise tástála/VPS don athrú (cuireann sé Riail Dhocht #18 i bhfeidhm go meicniúil trí phrós an PR a chuardach le grep — sobhriste, féach Backlog) | Tá | ### Jab: `test-vitest` -Ritheann sé tar éis `build`. Cuireann teip bac ar chumasc. +Ritheann sé tar éis `build`. Cuireann sé bac ar chumasc má theipeann air. -| Sraith | A bhailíochtaíonn sí | Bacach | -| ---------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Freastalaí MCP (110 uirlis), autoCombo, taisce — reathaí vitest | Tá | -| `test:vitest:ui` | Tástálacha comhpháirteanna UI — reathaí vitest | **Bacach** — eisiatar teipeanna atá ann cheana go sainráite in `vitest.config.ts`; teipeann ar an jab de bharr teipeanna nua | +| Sraith | Bailíochtaíonn sé | Blocáil | +| ---------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Freastalaí MCP (110 uirlis), autoCombo, taisce — riteoir vitest | Tá | +| `test:vitest:ui` | Tástálacha comhpháirteanna UI — riteoir vitest | **Blocálach** — fágtar teipeanna a bhí ann cheana as an áireamh go sainráite in `vitest.config.ts`; cuireann teipeanna nua an jab ó rath | ### Sreafaí oibre oíche (sceidealaithe, comhairleach) -Ritheann siad seo de réir sceideal cron (agus `workflow_dispatch`), agus ní ritheann siad ar PRanna riamh. Tá siad uile comhairleach. +Ritheann siad seo de réir sceideal cron (agus `workflow_dispatch`), ach ní ritheann siad ar PRanna riamh. Tá siad uile comhairleach. -| Sreabhadh oibre | A bhailíochtaíonn sé | Bacach | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | tástálacha airí fast-check le síol randamach + líon ard rití | **Comhairleach** | -| `nightly-resilience` | geata fáis carn, instealladh lochtanna anordúla, ualach/maos k6 | **Comhairleach** | -| `nightly-llm-security` | cosaint insteallta promptfoo (mód blocála) + tóireadóirí garak (scipeáilte gan rún soláthraí) | **Comhairleach** | -| `nightly-schemathesis` | doiléiriú chonradh OpenAPI (schemathesis) i gcoinne OmniRoute beo ag úsáid `docs/openapi.yaml` — nochtann sé sáruithe sonraíochta / 500anna gan láimhseáil (Céim 8 B.4) | **Comhairleach** | -| `nightly-mutation` | scór tástála sócháin Stryker thar lána tapa na dtástálacha aonaid — nochtann sóiteáin a mhaireann dearbhuithe laga | **Comhairleach** | -| `nightly-compat` | maitrís chomhoiriúnachta innill Node thar na raonta `engines.node` a dtacaítear leo | **Comhairleach** | +| Sreabhadh oibre | Bailíochtaíonn sé | Blocáil | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | Tástálacha airí fast-check le síol randamach + líon ard rití | **Comhairleach** | +| `nightly-resilience` | Geata fáis carn, instealladh lochtanna anordúla, ualach/sáithiú k6 | **Comhairleach** | +| `nightly-llm-security` | Cosaint insteallta promptfoo (mód blocála) + tóireadóirí garak (scipeáiltear iad gan rún soláthraí) | **Comhairleach** | +| `nightly-schemathesis` | Doiléiriú conartha OpenAPI (schemathesis) in aghaidh OmniRoute beo ag úsáid `docs/openapi.yaml` — nochtann sé sáruithe sonraíochta / earráidí 500 nár láimhseáladh (Céim 8 B.4) | **Comhairleach** | +| `nightly-mutation` | Scór tástála sócháin Stryker thar an lána tapa aonadtástála — nochtann sócháin a mhaireann dearbhuithe laga | **Comhairleach** | +| `nightly-compat` | Maitrís chomhoiriúnachta innill Node thar na raonta `engines.node` a dtacaítear leo | **Comhairleach** | --- @@ -538,12 +546,12 @@ earráid cheangail a logáil agus ní bhriseann sí seisiúin choíche. ## Riaráiste Cuíchóirithe (athbhreithniú ROI — Céim 9 Tonn 3) -Réitíodh an fardal seo in aghaidh `ci.yml` an 2026-06-17 (fágadh +Réitíodh an fardal seo in aghaidh `ci.yml` ar 2026-06-17 (fágadh `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence` ar lár sa leagan roimhe seo). D’aithin athbhreithniú ROI ar an tacar réitithe na hiarrthóirí cuíchóirithe seo a leanas. **Athruithe meicniúla CI atá sna cumaisc; -is cinntí beartais iad na hathruithe stádais/na baintí atá forchoimeádta don oibreoir.** Níl aon ní thíos +is cinntí beartais iad na haischuir/na baintí atá curtha in áirithe don oibreoir.** Níl aon rud thíos curtha i bhfeidhm fós. **Nach bhfuil doiciméadaithe thuas ach oiread** (comhairleach, comhartha lag): an jab `docs-lint` @@ -552,27 +560,27 @@ curtha i bhfeidhm fós. `quality-baseline.json` ach níl sé ceangailte le raicín blocála in `ci.yml` — tá an mhéadracht ina dílleachta faoi láthair. -### Cumasc / dí-dhúbailt (meicniúil, riosca níos ísle) +### Cumasc / dí-dhúbláil (meicniúil, riosca níos ísle) -Fíoraíodh gach iarrthóir in aghaidh staid bheo na ngeataí an 2026-06-17 (muinín ach fíorú); -tharla sé gur cheil roinnt cumasc “soiléir” fiachas agus **ní** ionadaithe glana iad. +Fíoraíodh gach iarrthóir in aghaidh staid bheo na ngeataí ar 2026-06-17 (muinín ach fíorú); +tharla sé gur fholaigh roinnt cumasc “soiléir” fiachas agus **ní** ionadaithe gan dua iad. -- **Ritheann `check:docs-sync` faoi dhó** — go neamhspleách sa jab `lint` agus arís laistigh de `check:docs-all` (`docs-sync-strict`) agus crúca réamh-commit husky. ✅ **DÉANTA** — baineadh an glao neamhspleách `lint`. -- **Scanadh CVE** — ❌ **NÍ cumasc glan é.** Teipeann `audit:deps` go docht ar aon CVE ard/criticiúil; ní theipeann `check:vuln-ratchet` (osv) ach ar _chúlchéimniú_ i gcomparáid leis an mbonnlíne (1 MODERATE faoi láthair). Séimeantaic éagsúil — dá mbainfí `audit:deps`, chaillfí an geata absalóideach ard/criticiúil. Coinnigh an dá cheann. -- **Aimsiú timthriallta** — ❌ **NÍ cumasc glan é.** Tuairiscíonn `check:circular-deps` (dpdm) **91 timthriall** (sin an fáth a bhfuil sé comhairleach); ní féidir é a ardú go stádas blocála gan iad a réiteach ar dtús, agus tá raon feidhme níos leithne aige ná `check:cycles`, atá glas agus coimeádta. Coinnigh `check:cycles` ina sheiceáil bhlocála; is mír riaráiste ar leith é réiteach na 91 timthriall dpdm. -- **Castacht** — ✅ **DÉANTA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): trasnú ESLint amháin, comhaireamh de réir ruleId ionas go bhfanfaidh bonnlínte cioglómatacha+uaslínte agus cognaíocha neamhspleách; fanann `check:complexity` / `check:cognitive-complexity` aonair ann le haghaidh `--update` áitiúil. -- **Frithshiamsaíocht `/api`** — ✅ **DÉANTA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): fardal FS amháin de `src/app/api`, agus leanann openapi-routes + docs-symbols de bheith ag tuairisciú go neamhspleách; fanann na cinn aonair ann le haghaidh rite áitiúla. -- **Ritheann `check:node-runtime` in 11 jab** — ⚠️ **ROI íseal.** Is riteoir ar leith gach ceann acu agus tógann an tseiceáil <1s; coigilteas iomlán ~10s, ach chaillfí cosaint shaor in aghaidh an jаб dá bharr. Ní fiú an corraí é. +- **Ritheann `check:docs-sync` faoi dhó** — go neamhspleách sa jab `lint` agus arís laistigh de `check:docs-all` (`docs-sync-strict`) agus sa chrúca réamh-churtha husky. ✅ **DÉANTA** — baineadh an glao neamhspleách `lint`. +- **Scanadh CVE** — ❌ **NÍ cumasc glan é.** Teipeann `audit:deps` go crua ar aon CVE ard/criticiúil; ní theipeann `check:vuln-ratchet` (osv) ach ar _aischéimniú_ i gcomparáid leis an mbunlíne (1 MODERATE faoi láthair). Séimeantaic dhifriúil — dá mbainfí `audit:deps`, chaillfí an geata absalóideach ard/criticiúil. Coinnigh an dá cheann. +- **Aimsiú timthriallta** — ✅ **DÉANTA** (#15159 G-01/G-02). Thug an seantéacs anseo “an geata glas, coimeádta” ar `check:cycles` agus thug sé mar údar lena choinneáil blocála gur thuairiscigh `check:circular-deps` (dpdm) 91 timthriall. **Glas bréagach** a bhí sa ghlas sin: rinne `check:cycles` scanadh ar 5 fhochomhadlann (450 comhad), níor mheaitseáil sé ach `import|export … from` statach, agus chaith sé gach sonraitheoir `@/` agus `@omniroute/open-sse/` i leataobh, mar sin ní raibh sé in ann na timthriallta iompórtála dhinimiciúil + ailias a bhí chun tosaigh sa stór a fheiceáil. Ceartaithe: siúlann an geata trí `src` + `open-sse` anois (5023 comhad), bailíonn sé sonraitheoirí ón AST TypeScript (mar sin áirítear `import("…")` ach ní áirítear `typeof import("…")` i suíomh cineáil), agus réitíonn sé `paths` tsconfig. Aimsíonn sé **14** thimthriall, ní 0. Toisc nach féidir 14 thimthriall réamhbheitheacha a cheartú in PR geata, is **raicín** é `check:cycles` anois (`--ratchet`, uasteorainn `metrics.cycles.value = 14` in `quality-baseline.json`, `direction: down`) — blocálann sé aon _aischéimniú_ agus ní féidir leis an gcomhaireamh ach titim. Ritheann CI `npm run check:cycles:ratchet`. Déantar an laghdú de réir a chéile le **A-01**. Fanann `check:circular-deps` (dpdm) comhairleach mar an dara tuairim níos leithne. +- **Castacht** — ✅ **DÉANTA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): siúlóid ESLint amháin, comhaireamh de réir ruleId ionas go bhfanfaidh bunlínte cioglamatacha+uaslínte agus bunlínte cognaíocha neamhspleách; fanann `check:complexity` / `check:cognitive-complexity` aonair le haghaidh `--update` áitiúil. +- **Frithshamhlaíocht `/api`** — ✅ **DÉANTA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): fardal FS amháin de `src/app/api`; leanann openapi-routes + docs-symbols ag tuairisciú go neamhspleách; fanann na cinn aonair le haghaidh rití áitiúla. +- **Ritheann `check:node-runtime` in 11 jab** — ⚠️ **ROI íseal.** Is riteoir ar leith é gach ceann agus tógann an tseiceáil <1s; coigilteas iomlán ~10s, i gcoinne cosantóir saor in aghaidh an jab a chailleadh. Ní fiú an corraí é. - **`typecheck:noimplicit:core` ar lint CI** — ✅ **baineadh den jab lint é** (bhí sé comhairleach le `continue-on-error`); is iad `typecheck:core` + `check:type-coverage` an dromchla cineáil blocála. Coinníodh an script áitiúil. -### Athraigh an stádas / déan cinneadh (beartas oibreora) +### Athraigh / déan cinneadh (beartas oibreora) -- `check:openapi-security-tiers` (comhairleach) — ❌ **NÍ féidir a stádas a athrú go glan.** Críochnaíonn sé le 0 ach tugann sé rabhadh nach bhfuil an nóta `x-loopback-only: true` ar roinnt bealaí `traffic-inspector` faoi `LOCAL_ONLY_API_PREFIXES`. Chun é a fhorfheidhmiú, ní mór na nótaí sin a chur le `openapi.yaml` ar dtús. -- `typecheck:noimplicit:core` (comhairleach) — tá sé ionadaithe den chuid is mó ag an raicín blocála `check:type-coverage`. Athraigh go raicín é nó bain an dara pas iomarcach `tsc`. -- `test:vitest:ui` (**blocála** anois) — tá teipeanna a bhí ann cheana eisiata go sainráite in `vitest.config.ts` le nótaí tráchta rianaithe `// #8618`; cuirfidh teipeanna nua an jab ó rath. -- `check:secrets` (gitleaks, raicín blocála reoite ag 3 dhearbhú bréagacha doiciméadaithe) — cuir na 3 cinn ar an liosta ceadaithe chun 0 a bhaint amach, nó ísligh go stádas comhairleach é. Tá forluí ann le scanadh dúchasach rúin GitHub + `check:public-creds`. -- `check:pr-evidence` (blocála, déanann sé grep ar phrós chorp PR) — riosca ard dearbhuithe bréagacha; lagófaí forfheidhmiú Riail Dhocht #18 dá mbainfí é, mar sin is fíorchinneadh beartais é seo. -- `semgrep` (neamhspleách comhairleach) — tá forluí aige le CodeQL maidir le teaghlaigh OWASP; ceangail a bhonnlíne le raicín nó bain é. +- `check:openapi-security-tiers` (comhairleach) — ❌ **NÍ féidir é a athrú go glan.** Scoireann sé le 0 ach tugann sé rabhadh nach bhfuil an nóta `x-loopback-only: true` ag roinnt bealaí `traffic-inspector` faoi `LOCAL_ONLY_API_PREFIXES`. Chun é a fhorfheidhmiú, ní mór na nótaí sin a chur le `openapi.yaml` ar dtús. +- `typecheck:noimplicit:core` (comhairleach) — tá sé cuimsithe den chuid is mó ag an raicín blocála `check:type-coverage`. Athraigh go raicín é nó bain an dara pas iomarcach `tsc`. +- `test:vitest:ui` (**blocála** anois) — tá teipeanna réamhbheitheacha eisiata go sainráite in `vitest.config.ts` le nótaí tráchta rianaithe `// #8618`; cuireann teipeanna nua an jab ó rath. +- `check:secrets` (gitleaks, raicín blocála reoite ag 3 thoradh bréagacha doiciméadaithe) — cuir na 3 cinn ar an liosta ceadaithe chun 0 a bhaint amach, nó ísligh go stádas comhairleach é. Tá forluí aige le scanadh dúchasach rúin GitHub + `check:public-creds`. +- `check:pr-evidence` (blocála, déanann sé grep ar phrós i gcorp PR) — riosca ard torthaí bréagacha; lagófaí forfheidhmiú Riail Dhocht #18 dá mbainfí é, mar sin is fíorchinneadh beartais é seo. +- `semgrep` (neamhspleách comhairleach) — tá forluí aige le CodeQL i gcás theaghlaigh OWASP; ceangail a bhunlíne le raicín nó bain é. --- diff --git a/docs/i18n/gu/CONTRIBUTING.md b/docs/i18n/gu/CONTRIBUTING.md index 16e42a5fbb3..b7e90f5d67a 100644 --- a/docs/i18n/gu/CONTRIBUTING.md +++ b/docs/i18n/gu/CONTRIBUTING.md @@ -387,20 +387,20 @@ docs/ # Documentation ## Pull Request ચેકલિસ્ટ -- [ ] પરીક્ષણો સફળ થાય છે (`npm test`) -- [ ] લિન્ટિંગ સફળ થાય છે (`npm run lint`) +- [ ] ટેસ્ટ્સ પાસ થાય છે (`npm test`) +- [ ] લિન્ટિંગ પાસ થાય છે (`npm run lint`) - [ ] બિલ્ડ સફળ થાય છે (`npm run build`) -- [ ] નવા જાહેર ફંક્શન્સ અને ઇન્ટરફેસ માટે TypeScript પ્રકારો ઉમેર્યા છે -- [ ] કોઈ હાર્ડકોડ કરેલા સિક્રેટ્સ અથવા ફૉલબૅક મૂલ્યો નથી -- [ ] જાહેર અપસ્ટ્રીમ ક્રેડેન્શિયલ્સ `resolvePublicCred()` દ્વારા એમ્બેડ કર્યાં છે ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) જુઓ), ક્યારેય લિટરલ્સ તરીકે નહીં -- [ ] ભૂલ પ્રતિસાદો `buildErrorBody()` / `sanitizeErrorMessage()` મારફતે જાય છે — પ્રતિસાદ બોડીમાં કોઈ કાચા સ્ટૅક ટ્રેસ નથી ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) જુઓ) -- [ ] શેલ કમાન્ડ્સ (`exec` / `spawn`) રનટાઇમ મૂલ્યોને સ્ટ્રિંગ ઇન્ટરપોલેશન દ્વારા નહીં, પરંતુ `env` દ્વારા પસાર કરે છે -- [ ] તમામ ઇનપુટ્સ Zod સ્કીમા વડે માન્ય કર્યાં છે -- [ ] વપરાશકર્તાને અસર કરતા ફેરફારો માટે `changelog.d/{features|fixes|maintenance}/-.md` હેઠળ ચેન્જલૉગ **ફ્રૅગમેન્ટ** ઉમેર્યું છે ([`changelog.d/README.md`](./changelog.d/README.md) જુઓ) — `CHANGELOG.md` ને સીધું સંપાદિત **કરશો નહીં**; ફ્રૅગમેન્ટ્સ રિલીઝ સમયે એકત્રિત થાય છે અને PR વચ્ચે ક્યારેય સંઘર્ષ કરતા નથી +- [ ] નવા સાર્વજનિક ફંક્શન્સ અને ઇન્ટરફેસ માટે TypeScript પ્રકારો ઉમેર્યા છે +- [ ] કોઈ હાર્ડકોડેડ સિક્રેટ્સ અથવા ફૉલબૅક મૂલ્યો નથી +- [ ] સાર્વજનિક અપસ્ટ્રીમ ક્રેડેન્શિયલ્સ `resolvePublicCred()` મારફતે એમ્બેડ કર્યાં છે ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) જુઓ), ક્યારેય લિટરલ્સ તરીકે નહીં +- [ ] ભૂલ પ્રતિસાદો `buildErrorBody()` / `sanitizeErrorMessage()` મારફતે રૂટ થાય છે — પ્રતિસાદ બોડીમાં કોઈ કાચા સ્ટૅક ટ્રેસ નથી ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) જુઓ) +- [ ] શેલ કમાન્ડ્સ (`exec` / `spawn`) રનટાઇમ મૂલ્યોને સ્ટ્રિંગ ઇન્ટરપોલેશન મારફતે નહીં, પરંતુ `env` મારફતે પસાર કરે છે +- [ ] બધા ઇનપુટ્સ Zod સ્કીમા વડે માન્ય કરેલા છે +- [ ] વપરાશકર્તાને અસર કરતા ફેરફારો માટે `changelog.d/{features|fixes|maintenance}/-.md` હેઠળ ચેન્જલૉગ **ફ્રેગમેન્ટ** ઉમેર્યો છે ([`changelog.d/README.md`](./changelog.d/README.md) જુઓ) — `CHANGELOG.md`ને સીધું સંપાદિત કરશો **નહીં**; ફ્રેગમેન્ટ્સને રિલીઝ સમયે એકત્રિત કરવામાં આવે છે અને PRs વચ્ચે ક્યારેય સંઘર્ષ થતો નથી - [ ] દસ્તાવેજીકરણ અપડેટ કર્યું છે (જો લાગુ પડતું હોય) -- [ ] કોઈ નવા CodeQL / Secret-Scanning અલર્ટ ખોલાયા નથી, અથવા દરેકને સંબંધિત `docs/security/` દસ્તાવેજનો સંદર્ભ આપતા તકનીકી વાજબીકરણ સાથે રદ કર્યો છે -- [ ] ચાઇલ્ડ પ્રોસેસ શરૂ કરતા રૂટ્સ (`/api/mcp/`, `/api/cli-tools/runtime/`) ને `src/server/authz/routeGuard.ts` માં `isLocalOnlyPath()` તરીકે વર્ગીકૃત કર્યા છે — [કડક નિયમ #15](docs/security/ROUTE_GUARD_TIERS.md) જુઓ -- [ ] કમિટ સંદેશાઓમાં કોઈ `Co-Authored-By` ટ્રેલર્સ નથી — કમિટ્સ ફક્ત રિપોઝિટરી માલિકની Git ઓળખ હેઠળ જ દેખાવા જોઈએ (કડક નિયમ #16) +- [ ] કોઈ નવી CodeQL / Secret-Scanning ચેતવણીઓ ખોલવામાં આવી નથી, અથવા દરેકને સંબંધિત `docs/security/` દસ્તાવેજનો સંદર્ભ આપતા ટેક્નિકલ વાજબીકરણ સાથે રદ કરવામાં આવી છે +- [ ] ચાઇલ્ડ પ્રોસેસ શરૂ કરતા રૂટ્સ (`/api/mcp/`, `/api/cli-tools/runtime/`)ને `src/server/authz/routeGuard.ts`માં `isLocalOnlyPath()` તરીકે વર્ગીકૃત કર્યા છે — [કડક નિયમ #15](docs/security/ROUTE_GUARD_TIERS.md) જુઓ +- [ ] કમિટ સંદેશાઓમાં AI/બોટ `Co-authored-by` ટ્રેલર્સ નથી (કડક નિયમ #16) — જે માનવીય સહયોગીઓના કાર્યનો પુનઃઉપયોગ થયો છે તેમને પ્રમાણભૂત `Co-authored-by: Name ` ટ્રેલર્સ દ્વારા શ્રેય આપવામાં આવ્યો છે --- diff --git a/docs/i18n/gu/docs/architecture/QUALITY_GATES.md b/docs/i18n/gu/docs/architecture/QUALITY_GATES.md index fc7d897298a..240d3ece5fb 100644 --- a/docs/i18n/gu/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/gu/docs/architecture/QUALITY_GATES.md @@ -17,257 +17,256 @@ ratchet baseline અથવા pass/fail policy નો ઉપયોગ કરે ## ગેટ ઇન્વેન્ટરી અને એક્ઝિક્યુશન પ્રોફાઇલ્સ -### ઉમેદવારની સ્વીકૃતિ +### ઉમેદવાર સ્વીકૃતિ -CI અને Quality Gates વર્કફ્લો પ્રત્યેક એક સ્થિર ચુકાદો આપે છે: `Gate / CI` અને -`Gate / Quality`. તેમની વર્ઝન કરેલી સ્વીકૃતિ નીતિ દરેક અપસ્ટ્રીમ જૉબને -આવશ્યક અથવા સલાહરૂપ તરીકે સૂચિબદ્ધ કરે છે. લાગુ પડતી આવશ્યક જૉબ સફળ થવી જ જોઈએ: -ગેરહાજર, રદ કરાયેલા, સ્કિપ કરાયેલા, બાકી અને અજ્ઞાત પરિણામો PASS સ્થાપિત કરી શકતા નથી. +CI અને Quality Gates વર્કફ્લો દરેક એક સ્થિર ચુકાદો આપે છે: `Gate / CI` અને +`Gate / Quality`. તેમની વર્ઝન કરેલી સ્વીકૃતિ નીતિ દરેક અપસ્ટ્રીમ જોબને +આવશ્યક અથવા સલાહરૂપ તરીકે સૂચિબદ્ધ કરે છે. લાગુ પડતી આવશ્યક જોબ સફળ થવી જ જોઈએ: +ગેરહાજર, રદ થયેલ, છોડી દેવાયેલ, બાકી અને અજ્ઞાત પરિણામો PASS સ્થાપિત કરી શકતાં નથી. માન્ય માત્ર-ડૉક્સ અથવા માત્ર-કૅટલૉગ વર્ગીકરણ કોડ લેનને લાગુ ન પડતી બનાવી શકે છે; -ડ્રાફ્ટ PR સ્વીકૃત ઉમેદવાર નથી. `hotfix` લેબલ પુરાવાની આવશ્યકતામાંથી મુક્તિ આપતું નથી. - -બંને વર્કફ્લો PRs અને main/release બ્રાન્ચ પરના પુશ, મેન્યુઅલ ડિસ્પૅચ અને -merge-group ઇવેન્ટ્સને આવરી લે છે. પુશ, ડિસ્પૅચ અને merge-group સંપૂર્ણ પસંદગી ચલાવે છે. -ફોર્ક્સ અને merge groups એવી જૉબ્સ માટે હોસ્ટેડ રનર્સનો ઉપયોગ કરે છે જે અન્યથા -સેલ્ફ-હોસ્ટેડ રનર્સ પસંદ કરે છે; રોલઆઉટ પહેલાં પર્યાપ્ત હોસ્ટેડ ક્ષમતા ચકાસવી આવશ્યક છે. - -દરેક JSON રસીદ ચેકઆઉટ કરેલ SHA, વર્કફ્લો રન અને પ્રયાસ ઓળખાવે છે. -CLI ચેકઆઉટ/ઇવેન્ટ SHA અસંગતતાને નકારે છે. વર્કફ્લો પરીક્ષણો નીતિની સભ્યતાને -ચુકાદા જૉબની `needs` સૂચિ સાથે બાંધે છે, જેથી નવી અથવા દૂર કરેલી લેન મૌનપણે અદૃશ્ય ન થઈ શકે. -રસીદો તેમના પોતાના વર્કફ્લોને આવરી લે છે, પ્રકાશન, ડિપ્લોયમેન્ટ અથવા -હાલના સલાહરૂપ સ્કૅનરની આંતરિક પ્રક્રિયાઓને નહીં. બ્રાન્ચ નિયમોમાં બંને ચેક નામો સક્રિય કરવા એ -એક અલગ વહીવટી ફેરફાર છે; આ જૉબ્સ ઉમેરવાથી પોતે જ કોઈ બ્રાન્ચ સુરક્ષિત થતી નથી. - -### સ્ટૅટિક સ્કૅન ઇન્વેન્ટરી - -વર્ઝન કરેલી npm-alias ઇન્વેન્ટરી અને સ્ટૅટિક-સ્કૅન સભ્યતા -`config/quality/gate-manifest.json`માં છે. `package.json` સામે -સ્ક્રિપ્ટ નામો અને ચોક્કસ કમાન્ડ્સને માન્ય કરવા માટે `npm run check:gate-manifest` ચલાવો; -ઉમેરાઓ, દૂર કરાયેલી વસ્તુઓ અને કમાન્ડ ડ્રિફ્ટ, બંને લોકલ હૂક અને CIમાંની -ફેરફાર-વર્ગીકરણ જૉબ્સને નિષ્ફળ બનાવે છે. -એલિયાસ કોઈ વર્કફ્લો જૉબ, મેટ્રિક્સ ઇન્સ્ટન્સ અથવા ટેસ્ટ કેસ નથી: આ ગણતરીઓને -પરસ્પર વિનિમયક્ષમ તરીકે રજૂ કરવી જોઈએ નહીં. - -પસંદ કરેલા એલિયાસને ચલાવ્યા વિના તપાસવા માટે `npm run quality:scan -- --list` અથવા +ડ્રાફ્ટ PR સ્વીકૃત ઉમેદવાર નથી. `hotfix` લેબલ પુરાવાની આવશ્યકતા દૂર કરતું નથી. + +બંને વર્કફ્લો PRs અને main/release બ્રાન્ચમાં થતા પુશ, મેન્યુઅલ ડિસ્પેચ અને +મર્જ-ગ્રુપ ઇવેન્ટ્સને આવરી લે છે. પુશ, ડિસ્પેચ અને મર્જ-ગ્રુપ સંપૂર્ણ પસંદગી ચલાવે છે. +ફોર્ક્સ અને મર્જ ગ્રુપ્સ એવી જોબ્સ માટે હોસ્ટેડ રનર્સનો ઉપયોગ કરે છે જે અન્યથા +સેલ્ફ-હોસ્ટેડ રનર્સ પસંદ કરે છે; રોલઆઉટ પહેલાં પર્યાપ્ત હોસ્ટેડ ક્ષમતાની ચકાસણી કરવી આવશ્યક છે. + +દરેક JSON રસીદ ચેકઆઉટ કરેલ SHA, વર્કફ્લો રન અને પ્રયાસને ઓળખાવે છે. +CLI ચેકઆઉટ/ઇવેન્ટ SHA મિસમૅચને નકારે છે. વર્કફ્લો ટેસ્ટ્સ નીતિ સભ્યપદને +ચુકાદા જોબની `needs` સૂચિ સાથે બાંધે છે, જેથી નવી અથવા દૂર કરેલી લેન ચૂપચાપ અદૃશ્ય ન થઈ શકે. +રસીદો પોતાના વર્કફ્લોને આવરી લે છે, પ્રકાશન, ડિપ્લોયમેન્ટ અથવા +હાલના સલાહરૂપ સ્કેનરની આંતરિક કાર્યપ્રણાલીને નહીં. બ્રાન્ચ નિયમોમાં બંને ચેક નામ સક્રિય કરવાં +એક અલગ વહીવટી ફેરફાર છે; આ જોબ્સ ઉમેરવાથી આપમેળે કોઈ બ્રાન્ચ સુરક્ષિત થતી નથી. + +### સ્ટેટિક સ્કેન ઇન્વેન્ટરી + +વર્ઝન કરેલી npm-alias ઇન્વેન્ટરી અને સ્ટેટિક-સ્કેન સભ્યપદ +`config/quality/gate-manifest.json`માં રહેલાં છે. સ્ક્રિપ્ટનાં નામો અને ચોક્કસ કમાન્ડ્સને +`package.json` સામે માન્ય કરવા માટે `npm run check:gate-manifest` ચલાવો; ઉમેરાઓ, દૂર કરેલી વસ્તુઓ અને +કમાન્ડમાં ફેરફારથી લોકલ હૂક તથા CIની ચેન્જ-ક્લાસિફિકેશન જોબ્સ બંને નિષ્ફળ જાય છે. +અલિયાસ એ વર્કફ્લો જોબ, મેટ્રિક્સ ઇન્સ્ટન્સ અથવા ટેસ્ટ કેસ નથી: આ ગણતરીઓને +એકબીજાના સમકક્ષ તરીકે રજૂ કરવી જોઈએ નહીં. + +પસંદ કરેલા અલિયાસને ચલાવ્યા વિના તપાસવા માટે `npm run quality:scan -- --list` અથવા `npm run quality:scan:fast -- --list`નો ઉપયોગ કરો. રનર -npm એન્ટ્રીપૉઇન્ટને ઇન્વોક કરે છે, તેથી તેનો રનટાઇમ (કૉન્ફિગર કરેલું હોય ત્યાં Bun સહિત) જળવાઈ રહે છે. -મેનિફેસ્ટ આ પ્રોફાઇલ્સની બહારના એલિયાસને અલગથી ઇન્વોક થયેલા તરીકે નોંધે છે, અને -રીડ-ઓનલી સ્કૅન પ્રોફાઇલ્સમાં મેન્ટેનન્સ કમાન્ડ્સ પ્રતિબંધિત છે. +npm એન્ટ્રીપૉઇન્ટને ઇન્વોક કરે છે, તેથી તેનો રનટાઇમ (જ્યાં કૉન્ફિગર કરેલું હોય ત્યાં Bun સહિત) જળવાય છે. +મેનિફેસ્ટ આ પ્રોફાઇલ્સની બહારના અલિયાસને અલગથી ઇન્વોક કરાયેલા તરીકે નોંધે છે અને +રીડ-ઓનલી સ્કેન પ્રોફાઇલ્સમાં મેન્ટેનન્સ કમાન્ડ્સ પ્રતિબંધિત છે. -આ પ્રોફાઇલ્સ માત્ર સ્ટૅટિક સ્કૅનને આવરી લે છે. તેઓ પ્રોડક્ટ પરીક્ષણો, +આ પ્રોફાઇલ્સ માત્ર સ્ટેટિક સ્કેનને આવરી લે છે. તેઓ પ્રોડક્ટ ટેસ્ટ્સ, કવરેજ, પૅકેજિંગ, બાહ્ય ચેક્સ અથવા ઉમેદવારની સંપૂર્ણ રિલીઝ સ્વીકૃતિને પ્રમાણિત કરતા નથી. -વર્કફ્લો સ્વીકૃતિ લિંક કરેલી `config/quality/admission-policy.json` અને -`scripts/quality/admission-verdict.mjs`નો ઉપયોગ કરે છે. Release-observer પ્રોફાઇલ્સ અલગ રહે છે; -તેમના લાગુ પડતા ચેક્સ અને રસીદો સ્વતંત્ર રીતે તપાસો. નીચે આપેલી ગદ્યરૂપ -ઇન્વેન્ટરી સંદર્ભ છે, ગેટ ખરેખર ચાલ્યો હોવાનો પુરાવો નહીં. +વર્કફ્લો સ્વીકૃતિ લિંક કરેલા `config/quality/admission-policy.json` અને +`scripts/quality/admission-verdict.mjs`નો ઉપયોગ કરે છે. રિલીઝ-ઑબ્ઝર્વર પ્રોફાઇલ્સ અલગ રહે છે; +તેમના લાગુ પડતા ચેક્સ અને રસીદોનું સ્વતંત્ર રીતે નિરીક્ષણ કરો. નીચેની ગદ્યરૂપ +ઇન્વેન્ટરી એક સંદર્ભ છે, ગેટ ખરેખર ચાલ્યો હતો તેનો પુરાવો નહીં. -સ્ક્રિપ્ટ્સ `scripts/check/` (નીતિ ગેટ્સ) અને `scripts/quality/` (રૅચેટ એન્જિન) હેઠળ છે. +સ્ક્રિપ્ટ્સ `scripts/check/` (પૉલિસી ગેટ્સ) અને `scripts/quality/` (રૅચેટ એન્જિન) હેઠળ રહે છે. CI માટે સત્યનો અધિકૃત સ્રોત `.github/workflows/ci.yml` છે. ### રિલીઝ PR ફાસ્ટ-પાથ (`quality.yml`) `.github/workflows/quality.yml` main/release PRs, સુરક્ષિત-બ્રાન્ચ -પુશ, ડિસ્પૅચ અને merge groups પર CIને પૂરક બને છે. PRs પાથ-ફિલ્ટર કરેલા ઝડપી ચેક્સનો ઉપયોગ કરે છે. -કાયમી રીતે અક્ષમ કરાયેલ ડુપ્લિકેટ બિલ્ડ દૂર કરવામાં આવ્યું હતું; વાસ્તવિક -બિલ્ડ/પૅકેજ/બૂટ ચેક્સ CIમાં યથાવત્ છે. - -| જૉબ | વ્યાપ | અવરોધક | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | ડૉક્સ/કોડ PRs; API ડૉક્સ સંદર્ભો અને docs-all | હા | -| `Fast Quality Gates` | કોડ PRs; સ્ટૅટિક ચેક્સ, ટાઇપચેક, ડૅશબોર્ડ ટાઇપચેક, પ્રભાવિત યુનિટ ટેસ્ટ્સ | હા | -| `Forgotten sibling tests` | કોડ PRs; બદલાયેલા મોડ્યુલ્સને સ્ટૅટિક કન્ઝ્યુમર્સ અને સંભવિત સિબલિંગ ટેસ્ટ્સ સુધી ટ્રેસ કરવામાં આવે છે; બૅરલ અને ડાયનેમિક-ઇમ્પોર્ટ પાથ્સને સંદર્ભિત અલાઉલિસ્ટ અપવાદો સાથે સલાહરૂપ નિદાન તરીકે રિપોર્ટ કરવામાં આવે છે | **સલાહરૂપ** | -| `Vitest (fast-path)` | કોડ PRs; ઝડપી vitest સ્યુટ | હા | -| `Unit Tests fast-path` | કોડ PRs; 4-શાર્ડ યુનિટ સ્યુટ | હા | -| `No new ESLint warnings` | કોડ PRs; સપ્રેશન-અવેર લિન્ટ ગાર્ડ | હા, ફોર્ક્સ સહિત | -| `Merge integrity (changelog + generated skills)` | નૉન-ડ્રાફ્ટ PRs; ચેન્જલૉગ અને જનરેટેડ સ્કિલ સિંક | હા, ફોર્ક્સ સહિત | - -#### ભૂલી જવાયેલા સિબલિંગ ટેસ્ટ્સનો રિપોર્ટ - -`npm run check:forgotten-sibling-tests` ટેસ્ટ-ઇમ્પેક્ટ મૅપ પાછળના ઇમ્પોર્ટ રિઝૉલ્વરનો પુનઃઉપયોગ કરે છે. +પુશ, ડિસ્પેચ અને મર્જ ગ્રુપ્સ પર CIને પૂરક બને છે. PRs પાથ-ફિલ્ટર કરેલા ઝડપી ચેક્સનો ઉપયોગ કરે છે. +કાયમી રીતે નિષ્ક્રિય ડુપ્લિકેટ બિલ્ડ દૂર કરવામાં આવ્યું હતું; વાસ્તવિક બિલ્ડ/પૅકેજ/બૂટ ચેક્સ CIમાં રહે છે. + +| જોબ | વ્યાપ | અવરોધક | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `Docs Gates (fast-path)` | ડૉક્સ/કોડ PRs; API ડૉક્સ રેફરન્સ અને docs-all | હા | +| `Fast Quality Gates` | કોડ PRs; સ્ટેટિક ચેક્સ, ટાઇપચેક, ડૅશબોર્ડ ટાઇપચેક, અસરગ્રસ્ત યુનિટ ટેસ્ટ્સ | હા | +| `Forgotten sibling tests` | કોડ PRs; બદલાયેલા મોડ્યુલ્સથી સ્ટેટિક કન્ઝ્યુમર્સ અને સંભવિત સિબ્લિંગ ટેસ્ટ્સ સુધી ટ્રેસિંગ; બેરલ અને ડાયનેમિક-ઇમ્પોર્ટ પાથ્સ સંદર્ભિત અલાઉલિસ્ટ અપવાદો સાથે સલાહરૂપ ડાયગ્નોસ્ટિક્સ તરીકે રિપોર્ટ થાય છે | **સલાહરૂપ** | +| `Vitest (fast-path)` | કોડ PRs; ઝડપી vitest સ્યુટ | હા | +| `Unit Tests fast-path` | કોડ PRs; 4-શાર્ડ યુનિટ સ્યુટ | હા | +| `No new ESLint warnings` | કોડ PRs; સપ્રેશન-અવેર લિન્ટ ગાર્ડ | હા, ફોર્ક્સ સહિત | +| `Merge integrity (changelog + generated skills)` | નોન-ડ્રાફ્ટ PRs; ચેન્જલૉગ અને જનરેટ કરેલી સ્કિલ્સનું સિંક્રનાઇઝેશન | હા, ફોર્ક્સ સહિત | + +#### ભૂલી જવાયેલા સિબ્લિંગ ટેસ્ટ્સનો રિપોર્ટ + +`npm run check:forgotten-sibling-tests` ટેસ્ટ-ઇમ્પેક્ટ મૅપ પાછળના ઇમ્પોર્ટ રિઝોલ્વરનો પુનઃઉપયોગ કરે છે. દરેક બદલાયેલા પ્રોડક્શન મોડ્યુલ માટે, જ્યારે સંભવિત ટેસ્ટ pull-request ડિફમાં ગેરહાજર હોય ત્યારે તે નિર્ધારિત -`changed module/symbol -> static consumer -> candidate sibling test` શૃંખલાઓ રિપોર્ટ કરે છે. +`changed module/symbol -> static consumer -> candidate sibling test` ચેઇન્સ રિપોર્ટ કરે છે. કોઈપણ અવરોધક રોલઆઉટ પહેલાં કૅલિબ્રેશન માટે Markdown સારાંશ અને JSON પરિણામને -`forgotten-sibling-tests` વર્કફ્લો આર્ટિફૅક્ટ તરીકે જાળવી રાખવામાં આવે છે. +`forgotten-sibling-tests` વર્કફ્લો આર્ટિફેક્ટ તરીકે જાળવી રાખવામાં આવે છે. -Barrel રી-એક્સપોર્ટ્સ અને ડાયનેમિક ઇમ્પોર્ટ્સ માત્ર રિઝોલ્યુશન ડાયગ્નોસ્ટિક્સ છે; તેઓ ક્યારેય +બેરલ રી-એક્સપોર્ટ્સ અને ડાયનેમિક ઇમ્પોર્ટ્સ માત્ર રિઝોલ્યુશન ડાયગ્નોસ્ટિક્સ છે; તેઓ ક્યારેય અવરોધક તારણ બનાવતા નથી. સમીક્ષા કરાયેલા અપવાદો -`config/quality/forgotten-sibling-allowlist.json`માં રહે છે. દરેક એન્ટ્રીએ consumer અને candidate -ટેસ્ટનું નામ આપવું, ચોક્કસ તર્ક રજૂ કરવો અને GitHub issue અથવા pull requestની લિંક આપવી આવશ્યક છે. ખોટી રીતે રચાયેલી એન્ટ્રીઓ -બંધ સ્થિતિમાં નિષ્ફળ જાય છે. અપવાદો કાઢી નાખવામાં આવેલા candidate ટેસ્ટ અથવા `.skip`/`.todo` ઉમેરતા diffને દબાવી શકતા નથી; -assertionને નબળું બનાવવું અને અન્ય masking સ્વતંત્ર રીતે અવરોધક -`check:test-masking` gateની જવાબદારી હેઠળ રહે છે. +`config/quality/forgotten-sibling-allowlist.json`માં રહે છે. દરેક એન્ટ્રીએ કન્ઝ્યુમર અને ઉમેદવાર +ટેસ્ટનું નામ આપવું, ચોક્કસ કારણ રજૂ કરવું અને GitHub ઇશ્યૂ અથવા પુલ રિક્વેસ્ટની લિંક આપવી આવશ્યક છે. ખોટી રચનાવાળી એન્ટ્રીઓ +બંધ સ્થિતિમાં નિષ્ફળ જાય છે. અપવાદો કાઢી નાખવામાં આવેલી ઉમેદવાર ટેસ્ટ અથવા `.skip`/`.todo` ઉમેરતા ડિફને દબાવી શકતા નથી; +અસર્શનને નબળું પાડવું અને અન્ય માસ્કિંગ સ્વતંત્ર રીતે અવરોધક +`check:test-masking` ગેટની જવાબદારી હેઠળ રહે છે. ### જોબ: `lint` -`main` માટેના દરેક PR પર ચાલે છે. નિષ્ફળતા આવે તો mergeને અવરોધે છે. - -| સ્ક્રિપ્ટ (`npm run ...`) | શું માન્ય કરે છે | અવરોધક | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Node.jsનું version સમર્થિત શ્રેણીમાં છે | હા | -| `check:cycles` | Circular imports — બધા `src/` + `open-sse/` modules | હા | -| `check:route-validation:t06` | બધી routes પર Zod schemas હાજર છે (Tier 6 policy) | હા | -| `check:any-budget:t11` | `@ts-expect-error // any`ની સંખ્યા budgetથી વધારે નથી (Tier 11 catraca) | હા | -| `check:provider-consistency` | `providers.ts` માંના દરેક provider માટે `providerRegistry.ts` માં મેળ ખાતી entry છે (અને તેનાથી વિપરીત પણ, allowlist ની મર્યાદામાં) | હા | -| `check:model-lifecycle` | હાથથી જાળવવામાં આવતા ત્રણ routing table, check-in કરેલા lifecycle snapshot (#11503) સાથે સુસંગત રહે છે: `FITNESS_TABLE` (`taskFitness.ts`) એવા કોઈ retired id ને score આપતું નથી જેને `REGISTRY` route કરી શકે; દરેક `BUILT_IN_ALIASES` target `REGISTRY` માં હાજર છે અને retired-id snapshot માં ગેરહાજર છે; `REGISTRY` માં હજુ પણ રહેલા દરેક retired id ને forward કરવામાં આવ્યો છે અથવા `allowedRetiredInCatalog` માં સૂચિબદ્ધ કરવામાં આવ્યો છે; અને કોઈપણ `DEFAULT_DEGRADATION_MAP` source કે target તે snapshot માં retired તરીકે દેખાતું નથી. આ સાબિત કરતું નથી કે કોઈ model હાલમાં live upstream દ્વારા serve કરવામાં આવે છે. Offline — `config/quality/model-lifecycle.json` સાથે સરખામણી કરે છે, જેને `npm run quality:refresh-model-lifecycle` વડે હાથથી refresh કરવામાં આવે છે (network; CI સાથે જોડાયેલું નથી). `allowedRetiredInCatalog` એ burn-down ratchet છે: entry માત્ર tracking issue સાથે જ ઉમેરો. | હા | -| `check:fetch-targets` | client-side `src/` માંનું દરેક `fetch("/api/...")` વાસ્તવિક `route.ts` પર resolve થાય છે | હા | -| `check:deps` | repo માંના દરેક `package.json` માં રહેલી બધી `npm install` કરી શકાય તેવી deps `dependency-allowlist.json` માં છે; નવી unpinned અથવા slopsquatted packages ને flag કરવામાં આવે છે | હા | -| `audit:deps` | `npm audit` (root + electron) — કોઈ high/critical advisories નથી (osv `check:vuln-ratchet` સાથે overlap થાય છે; Rationalization Backlog જુઓ) | હા | -| `check:lockfile` | `package-lock.json` ની integrity — https registry, integrity hashes, કોઈ host overrides નહીં | હા | -| `check:licenses` | પ્રોડક્શન ડિપેન્ડન્સીઓ માટે SPDX લાઇસન્સ અનુમતિસૂચિ | હા | -| `check:tracked-artifacts` | કોઈ બિલ્ડ આર્ટિફેક્ટ્સ / કમિટ કરેલી `node_modules` સિમલિંક્સ નહીં (husky pre-commitમાં પણ ચાલે છે; pre-pushને ઇરાદાપૂર્વક હળવું રાખવામાં આવ્યું છે — #6716) | હા | -| `check:ai-attribution` | PR કમિટ્સ, શીર્ષક અથવા બોડીમાં કોઈ AI/bot `Co-Authored-By` ટ્રેલર અથવા AI-જનરેશન ફૂટર નહીં — કડક નિયમ #16 (`quality.yml`ના PR→`release/**` માટેના fast-gates લૂપમાં — ઇવેન્ટ પેલોડ વાંચે છે, PR ન હોય ત્યારે કંઈ કરતું નથી — અને PR→`main` માટે `ci.yml` lintમાં માત્ર-PR પગલું; તેમજ husky `commit-msg` હૂક; માનવીય સહ-લેખકોને મંજૂરી છે; #14436) | -| `check:vitest-exclusions` | દરેક Vitest એક્સક્લૂઝનમાં ટ્રેકિંગ ઇશ્યૂનો ઉલ્લેખ હોવો જોઈએ અને તે `config/quality/vitest-exclusions.json`માં દેખાવું જોઈએ (#13204) | હા | -| `check:file-size` | કોઈ સોર્સ ફાઇલ પ્રતિ-એક્સ્ટેન્શન મર્યાદાથી મોટી ન હોવી જોઈએ (રૅચેટ: `frozen` સૂચિમાં સ્થિર કરેલી મોટી ફાઇલો) | હા | -| `check:error-helper` | એક્ઝિક્યુટર્સ/હેન્ડલર્સમાં ભૂલ પ્રતિસાદો `buildErrorBody()` / `sanitizeErrorMessage()`નો ઉપયોગ કરે છે (કડક નિયમ #12) | હા | -| `check:migration-numbering` | Migration SQL ફાઇલો ક્રમિક રીતે નંબર થયેલી છે, તેમાં કોઈ ખાલી ક્રમ અથવા ડુપ્લિકેટ નથી | હા | -| `check:public-creds` | `publicCreds.ts`ની બહાર કોઈ શાબ્દિક OAuth `client_id`/`client_secret` અથવા Firebase Web કી નથી (કડક નિયમ #11) | હા | -| `check:db-rules` | `src/lib/db/` મોડ્યુલોની બહાર કોઈ કાચું SQL નથી; `localDb.ts`માંથી કોઈ બેરલ-ઇમ્પોર્ટ નથી (કડક નિયમો #2/#5) | હા | -| `check:known-symbols` | તેમની ડિસ્પેચ કોષ્ટકોમાં નોંધાયેલા પ્રદાતા એક્ઝિક્યુટર્સ, રાઉટિંગ વ્યૂહરચનાઓ અને અનુવાદકો ડિસ્ક પરની ફાઇલો સાથે મેળ ખાય છે — કોઈ અનાથ અથવા અઘોષિત સિમ્બોલ નથી | હા | -| `check:route-guard-membership` | ચાઇલ્ડ પ્રોસેસ શરૂ કરતો દરેક રૂટ `isLocalOnlyPath()` દ્વારા વર્ગીકૃત થયેલો છે (કડક નિયમો #15/#17) | હા | -| `check:test-discovery` | રેપોમાંની દરેક `*.test.ts` / `*.spec.ts` ફાઇલ ઓછામાં ઓછા એક ટેસ્ટ રનર દ્વારા એકત્રિત કરવામાં આવે છે (રેચેટ: `test-discovery-baseline.json`માંની અનાથ સૂચિ માત્ર ઘટી શકે છે) | હા | -| `check:agent-skills-sync` | જનરેટ કરેલા agent-skills આર્ટિફેક્ટ્સ તેમના સ્રોત કેટલોગ સાથે મેળ ખાય છે (કોઈ વિસંગતિ નથી) | -| `check:provider-asset-provenance` | પ્રોવાઇડર લોગો/એસેટ્સ માટે નોંધાયેલ મૂળસ્રોત એન્ટ્રી ઉપલબ્ધ છે | -| `lint:json` | JSON કન્ફિગ ફાઇલો પાર્સ થાય છે અને repoના lint નિયમોનું પાલન કરે છે | -| `typecheck:core` | ભૂલો વિના TypeScript કમ્પાઇલેશન (માત્ર સલાહરૂપ ચેતવણીઓ) | હા | -| `typecheck:noimplicit:core` | કડક `noImplicitAny` — ભવિષ્યલક્ષી; અગાઉથી અસ્તિત્વ ધરાવતી ઘણી call sitesને હજુ પણ annotationsની જરૂર છે | **સલાહરૂપ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` સુધી મર્યાદિત `tsc` (#7033) — `typecheck:core`ની કાળજીપૂર્વક પસંદ કરેલી 27-ફાઇલ allowlistમાં કોઈ dashboard TSX સામેલ નથી અને `next build` પણ ક્યારેય તેનું type-checking કરતું નથી (`next.config.mjs`માં `ignoreBuildErrors: true` સેટ છે), તેથી ત્યાંના orphaned-identifier regressions (#6625/#6909) CIને દેખાતા નહોતા. સ્થિર કરેલા પ્રતિ-ફાઇલ/પ્રતિ-TS-code ગણતરી baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` જેવી જ stale-enforcement પેટર્ન) સામેના તફાવતો — baselined ગણતરી કરતાં માત્ર નવી ભૂલો જ gateને નિષ્ફળ બનાવે છે; અગાઉથી અસ્તિત્વ ધરાવતી ભૂલ સુધારવામાં આવે ત્યારે `--update` વડે તેને ક્રમશઃ ઘટાડો. | હા | - -### જોબ: `quality-gate` +`main` માટેની દરેક PR પર ચાલે છે. નિષ્ફળતા આવે તો મર્જને અવરોધે છે. -`test-coverage` પછી ચાલે છે. નિષ્ફળતા થાય તો mergeને અવરોધે છે. - -| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `quality:collect` | `quality-metrics.json` ઉત્પન્ન કરે છે (ESLint ચેતવણીઓની સંખ્યા, મર્જ કરેલા શાર્ડ રિપોર્ટમાંથી કવરેજ) | હા (રૅચેટના અપસ્ટ્રીમમાં) | -| `quality:ratchet` | `quality-baseline.json` માંનું કોઈપણ મેટ્રિક કથળ્યું નથી (ESLint ચેતવણીઓ ≤ બેઝલાઇન; કવરેજ ≥ બેઝલાઇન) | હા | -| `check:duplication` | કોડ ડુપ્લિકેશન (jscpd@4) `quality-baseline.json` માંની બેઝલાઇન કરતાં વધી જતું નથી | હા | -| `check:complexity` | ફાઇલ-સ્તરની સાઇક્લોમેટિક જટિલતા મર્યાદાથી વધતી નથી (મુખ્ય ESLint `complexity` + `max-lines-per-function`) | હા | -| `check:cognitive-complexity` | કોગ્નિટિવ જટિલતા રૅચેટ (`eslint-plugin-sonarjs`) — અલગ ESLint પાસ; CI બંનેને એક જ `check:complexity-ratchets` સ્ટેપ તરીકે મર્જ કરીને ચલાવે છે | હા | -| `check:dead-code` | વણવપરાયેલા એક્સપોર્ટ્સ / ફાઇલોનું રૅચેટ (knip) બેઝલાઇનની સરખામણીમાં કથળતું નથી | હા | -| `check:compression-budget` | કમ્પ્રેશન બેન્ચમાર્ક બજેટ — દરેક એન્જિન માટે ટોકન-બચતની લઘુતમ મર્યાદાઓ કથળવી જોઈએ નહીં | હા | -| `check:type-coverage` | ટાઇપ કરેલી ટકાવારીનું રૅચેટ (`type-coverage`) કથળતું નથી; તે મોટાભાગે `typecheck:noimplicit:core` ને આવરી લે છે | હા | -| `check:codeql-ratchet` | ખુલ્લી CodeQL ચેતવણીઓની સંખ્યા કથળતી નથી (`gh api` દ્વારા વાંચે છે; ટોકન વિના સુગમતાથી સ્કિપ કરે છે) — રિફ્રેશ આવર્તન અને મેન્યુઅલ ટ્રિગર માટે: નીચે "CodeQL રૅચેટ" જુઓ | હા | - -### જોબ: `quality-extended` - -આખી જોબ સલાહાત્મક છે (`continue-on-error: true`). npm-આધારિત રૅચેટ્સ વાસ્તવમાં ચાલે છે; -બાહ્ય સ્કેનર્સ `gh release download` દ્વારા ઇન્સ્ટોલ થાય છે અને જો બાઇનરી હજી પણ -ગેરહાજર હોય તો આપમેળે સ્કિપ થાય છે (exit 0). - -| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | -| `check:circular-deps` | કોઈ સર્ક્યુલર ડિપેન્ડન્સી નથી (dpdm) | **સલાહાત્મક** | -| `check:bundle-size` | બંડલનું કદ મર્યાદાથી વધતું નથી | **સલાહાત્મક** | -| `check:secrets` | સિક્રેટ સ્કેનિંગ (gitleaks) — બાઇનરી ગેરહાજર હોય તો સ્કિપ કરે છે | **સલાહાત્મક** | -| `check:vuln-ratchet` | ડિપેન્ડન્સીની નબળાઈઓ (osv-scanner) કથળતી નથી — બાઇનરી ગેરહાજર હોય તો સ્કિપ કરે છે | **સલાહાત્મક** | -| `check:workflows` | વર્કફ્લો લિન્ટ (actionlint + zizmor); ગેરહાજર/ખામીયુક્ત સ્કેનર્સ, અમાન્ય રિપોર્ટ્સ અથવા ગેરહાજર રૅચેટ બેઝલાઇનને કારણે INCOMPLETE તરીકે નિષ્ફળ થાય છે. માન્ય તારણો પસંદ કરેલી કડક/સલાહાત્મક/રૅચેટ નીતિને અનુસરે છે | એક્ઝિક્યુશન આવશ્યક; CI માં zizmor રૅચેટ અવરોધક છે | -| `check:openapi-breaking` | બેઝ બ્રાન્ચની સરખામણીમાં જાહેર API કરાર (`openapi.yaml`) માં ભંગાણકારી ફેરફારો (oasdiff) — `openapiBreaking=N` ઉત્પન્ન કરે છે; oasdiff ગેરહાજર હોય અથવા બેઝ સ્પેકનું નિરાકરણ ન થઈ શકે તો સ્કિપ કરે છે | **સલાહાત્મક** | - -### જોબ: `docs-sync-strict` +| સ્ક્રિપ્ટ (`npm run ...`) | શું માન્ય કરે છે | અવરોધક | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Node.js વર્ઝન સમર્થિત શ્રેણીમાં છે | હા | +| `check:cycles` | સમગ્ર `src/` + `open-sse/`માં સર્ક્યુલર ઇમ્પોર્ટ્સ (AST-આધારિત, tsconfig `paths` રિઝોલ્વ કરેલા). બેર = સલાહરૂપ, સાયકલ્સની યાદી આપે છે. `check:cycles:ratchet` (જે CI ચલાવે છે) ત્યારે અવરોધે છે જ્યારે સંખ્યા `quality-baseline.json`માંની `metrics.cycles` મર્યાદા કરતાં વધી જાય — હાલમાં 14, `direction: down`, તેથી તે માત્ર ઘટી શકે છે (#15159 G-01/G-02) | હા (રૅચેટ) | +| `check:route-validation:t06` | તમામ રૂટ્સ પર Zod સ્કીમા હાજર છે (ટિયર 6 નીતિ) | હા | +| `check:any-budget:t11` | `@ts-expect-error // any`ની સંખ્યા બજેટ કરતાં વધી નથી (ટિયર 11 કાત્રાકા) | હા | +| `check:provider-consistency` | `providers.ts` માંનો દરેક provider `providerRegistry.ts` માં અનુરૂપ entry ધરાવે છે (અને allowlist ની મર્યાદામાં તેનાથી વિપરીત પણ) | હા | +| `check:model-lifecycle` | હાથથી જાળવવામાં આવતા ત્રણ routing tables checked-in lifecycle snapshot (#11503) સાથે સુસંગત રહે છે: `FITNESS_TABLE` (`taskFitness.ts`) એવા કોઈ retired id ને score આપતું નથી જેને `REGISTRY` route કરી શકે; દરેક `BUILT_IN_ALIASES` target `REGISTRY` માં હાજર છે અને retired-id snapshot માં ગેરહાજર છે; `REGISTRY` માં હજી રહેલી દરેક retired id ને forward કરવામાં આવી છે અથવા `allowedRetiredInCatalog` માં સૂચિબદ્ધ કરવામાં આવી છે; અને કોઈ પણ `DEFAULT_DEGRADATION_MAP` source અથવા target તે snapshot માં retired તરીકે દેખાતું નથી. આ સાબિત કરતું નથી કે કોઈ model હાલમાં live upstream દ્વારા serve કરવામાં આવે છે. Offline — `config/quality/model-lifecycle.json` સાથે તુલના કરે છે, જેને `npm run quality:refresh-model-lifecycle` વડે હાથથી refresh કરવામાં આવે છે (network; CI સાથે જોડાયેલ નથી). `allowedRetiredInCatalog` એક burn-down ratchet છે: માત્ર tracking issue સાથે જ entry ઉમેરો. | હા | +| `check:fetch-targets` | client-side `src/` માંનો દરેક `fetch("/api/...")` વાસ્તવિક `route.ts` તરફ resolve થાય છે | હા | +| `check:deps` | repo માંના દરેક `package.json` ની તમામ `npm install` કરી શકાય તેવી deps `dependency-allowlist.json` માં છે; નવા unpinned અથવા slopsquatted packages ને flag કરવામાં આવે છે | હા | +| `audit:deps` | `npm audit` (root + electron) — કોઈ high/critical advisories નથી (osv `check:vuln-ratchet` સાથે overlap થાય છે; Rationalization Backlog જુઓ) | હા | +| `check:lockfile` | `package-lock.json` ની integrity — https registry, integrity hashes, કોઈ host overrides નહીં | હા | +| `check:licenses` | પ્રોડક્શન ડિપેન્ડન્સીઓ માટે SPDX લાઇસન્સની મંજૂર સૂચિ | હા | +| `check:tracked-artifacts` | કોઈ બિલ્ડ આર્ટિફેક્ટ્સ / કમિટ કરેલી `node_modules` સિમલિંક્સ નહીં (husky pre-commitમાં પણ ચાલે છે; pre-pushને ઇરાદાપૂર્વક હળવું રાખવામાં આવ્યું છે — #6716) | હા | +| `check:ai-attribution` | PR કમિટ્સ, શીર્ષક અથવા મુખ્ય લખાણમાં કોઈ AI/bot `Co-Authored-By` ટ્રેલર અથવા AI-જનરેશન ફૂટર નહીં — કડક નિયમ #16 (`quality.yml`ના PR→`release/**` માટેના fast-gates લૂપમાં — ઇવેન્ટ પેલોડ વાંચે છે, PR ન હોય ત્યારે કંઈ કરતું નથી — અને `ci.yml` lintમાં PR→`main` માટે માત્ર-PR પગલું; તેમજ husky `commit-msg` હૂક; માનવીય સહ-લેખકોને મંજૂરી છે; #14436) | +| `check:vitest-exclusions` | દરેક Vitest બાકાત રાખવાની નોંધમાં ટ્રેકિંગ ઇશ્યૂનો ઉલ્લેખ હોવો જોઈએ અને તે `config/quality/vitest-exclusions.json`માં દેખાવી જોઈએ (#13204) | હા | +| `check:file-size` | કોઈ સોર્સ ફાઇલ પ્રતિ-એક્સ્ટેન્શન મર્યાદા કરતાં મોટી ન હોવી જોઈએ (રૅચેટ: `frozen` સૂચિમાં સ્થિર કરેલી મોટી ફાઇલો) | હા | +| `check:error-helper` | executors/handlersમાં ભૂલ પ્રતિસાદો `buildErrorBody()` / `sanitizeErrorMessage()`નો ઉપયોગ કરે છે (કડક નિયમ #12) | હા | +| `check:migration-numbering` | Migration SQL ફાઇલોને ક્રમિક રીતે નંબર આપવામાં આવ્યા છે, કોઈ ખાલી ક્રમ કે ડુપ્લિકેટ નથી | હા | +| `check:public-creds` | `publicCreds.ts` ની બહાર કોઈ લિટરલ OAuth `client_id`/`client_secret` અથવા Firebase Web કી નથી (કડક નિયમ #11) | હા | +| `check:db-rules` | `src/lib/db/` મોડ્યુલોની બહાર કોઈ રૉ SQL નથી; `localDb.ts` માંથી કોઈ બેરલ-ઇમ્પોર્ટ નથી (કડક નિયમો #2/#5) | હા | +| `check:known-symbols` | તેમના ડિસ્પેચ ટેબલમાં નોંધાયેલા પ્રોવાઇડર એક્ઝિક્યુટર્સ, રાઉટિંગ વ્યૂહરચનાઓ અને ટ્રાન્સલેટર્સ ડિસ્ક પરની ફાઇલો સાથે મેળ ખાય છે — કોઈ અનાથ અથવા અઘોષિત સિમ્બોલ નથી | હા | +| `check:route-guard-membership` | ચાઇલ્ડ પ્રોસેસ શરૂ કરતો દરેક રૂટ `isLocalOnlyPath()` દ્વારા વર્ગીકૃત થયેલો છે (કડક નિયમો #15/#17) | હા | +| `check:test-discovery` | રેપોમાંની દરેક `*.test.ts` / `*.spec.ts` ફાઇલ ઓછામાં ઓછા એક ટેસ્ટ રનર દ્વારા એકત્રિત કરવામાં આવે છે (રૅચેટ: `test-discovery-baseline.json` માંની અનાથ યાદી માત્ર નાની થઈ શકે છે) | હા | +| `check:agent-skills-sync` | જનરેટ કરેલી agent-skills આર્ટિફેક્ટ્સ તેમના સ્રોત કેટલોગ સાથે મેળ ખાય છે (કોઈ વિસંગતિ નથી) | +| `check:provider-asset-provenance` | પ્રદાતા લોગો/એસેટ્સ માટે નોંધાયેલ મૂળસ્રોતની એન્ટ્રી છે | +| `lint:json` | JSON કૉન્ફિગ ફાઇલો પાર્સ થાય છે અને રિપોઝિટરીના લિન્ટ નિયમોને સંતોષે છે | +| `typecheck:core` | ભૂલો વિનાનું TypeScript કમ્પાઇલેશન (માત્ર સલાહરૂપ ચેતવણીઓ) | હા | +| `typecheck:noimplicit:core` | કડક `noImplicitAny` — ભવિષ્યલક્ષી; અગાઉથી અસ્તિત્વમાં રહેલી ઘણી કૉલ સાઇટ્સને હજી પણ ઍનોટેશન્સની જરૂર છે | **સલાહરૂપ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` સુધી મર્યાદિત `tsc` (#7033) — `typecheck:core`ની પસંદ કરેલી 27-ફાઇલની મંજૂરીસૂચિમાં કોઈ dashboard TSX સામેલ નથી અને `next build` પણ તેને ક્યારેય ટાઇપ-ચેક કરતું નથી (`next.config.mjs`માં `ignoreBuildErrors: true` સેટ કરેલું છે), તેથી ત્યાંના અનાથ-આઇડેન્ટિફાયર રિગ્રેશન્સ (#6625/#6909) CI માટે અદૃશ્ય હતા. સ્થિર કરેલા પ્રતિ-ફાઇલ/પ્રતિ-TS-કોડ ગણતરી બેઝલાઇન (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` જેવી જ જૂની-સ્થિતિ અમલીકરણ પૅટર્ન) સામે તફાવતો તપાસે છે — બેઝલાઇન કરેલી ગણતરીથી વધુ માત્ર નવી ભૂલો જ ગેટને નિષ્ફળ બનાવે છે; અગાઉથી અસ્તિત્વમાં રહેલી ભૂલ સુધારવામાં આવે ત્યારે `--update` વડે બેઝલાઇન ઘટાડો. | હા | -`main` માટેની દરેક PR પર ચાલે છે. નિષ્ફળતા આવે તો મર્જને અવરોધે છે. +### જોબ: `quality-gate` -| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | નીચેના 6 પેટા-ગેટ્સને ક્રમશઃ ચલાવતું મેટા-ગેટ | હા | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt સંસ્કરણ સુસંગતતા | હા | -| ↳ `check:docs-counts` | ગદ્યમાં આપેલી ગણતરીઓ (પ્રદાતાની સંખ્યા, માઇગ્રેશનની સંખ્યા વગેરે) વાસ્તવિક ગણતરીઓની રેચેટ વિન્ડોની અંદર છે | હા | -| ↳ `check:env-doc-sync` | `.env.example` માંનો દરેક env var દસ્તાવેજોના કોષ્ટકમાં દસ્તાવેજીકૃત છે અને તેનાથી વિપરીત પણ | હા | -| ↳ `check:deprecated-versions` | દસ્તાવેજોમાં કોઈ અપ્રચલિત સંસ્કરણ સ્ટ્રિંગ નથી | હા | -| ↳ `check:doc-links` | દસ્તાવેજોમાંની આંતરિક markdown લિંક્સ વાસ્તવિક ફાઇલો તરફ નિર્દેશ કરે છે (`[text]`/`(path)` સ્વરૂપ) | હા | -| ↳ `check:fabricated-docs` | દસ્તાવેજોમાં ઉલ્લેખિત routes, env vars, CLI commands, hook names અને file paths કોડબેઝમાં અસ્તિત્વ ધરાવે છે. `--strict` દ્વારા હાર્ડ ગેટ; ફ્લૅગ વિના સોફ્ટ-ફેલ. | હા (CIમાં `--strict` દ્વારા) | -| `check:cli-i18n` | CLI command strings બધી i18n locale filesમાં હાજર છે | હા | -| `check:openapi-coverage` | OpenAPI spec વાસ્તવિક routesના ઓછામાં ઓછા રેચેટેડ ન્યૂનતમ પ્રમાણને આવરી લે છે | હા | -| `check:openapi-security-tiers` | `openapi.yaml` માંના security tier annotations `routeGuard.ts` classifications સાથે સુસંગત છે | **સલાહરૂપ** | -| `check:openapi-routes` | `openapi.yaml` માંનો દરેક path વાસ્તવિક `route.ts` તરફ નિર્દેશ કરે છે (ભ્રમજનિત માહિતી વિરોધી) | હા | -| `check:docs-symbols` | `docs/**/*.md` માંનો દરેક `/api/...` સંદર્ભ વાસ્તવિક `route.ts` તરફ નિર્દેશ કરે છે (ભ્રમજનિત માહિતી વિરોધી) | હા | -| `i18n translation drift` | i18n locale filesમાં અનુવાદ ન થયેલી keys — ફક્ત ચેતવણી | **સલાહરૂપ** | +`test-coverage` પછી ચાલે છે. નિષ્ફળતા આવે તો મર્જને અવરોધે છે. + +| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `quality:collect` | `quality-metrics.json` ઉત્પન્ન કરે છે (ESLint ચેતવણીઓની સંખ્યા, મર્જ કરેલા shard રિપોર્ટમાંથી coverage) | હા (ratchet પહેલાં) | +| `quality:ratchet` | `quality-baseline.json` માંનું દરેક metric ખરાબ થયું નથી (ESLint ચેતવણીઓ ≤ baseline; coverage ≥ baseline) | હા | +| `check:duplication` | કોડનું duplication (jscpd@4) `quality-baseline.json` માંના baseline કરતાં વધારે નથી | હા | +| `check:complexity` | ફાઇલ-સ્તરની cyclomatic complexity cap કરતાં વધારે નથી (મુખ્ય ESLint `complexity` + `max-lines-per-function`) | હા | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — અલગ ESLint pass; CI બંનેને એકમાત્ર `check:complexity-ratchets` પગલા તરીકે મર્જ કરીને ચલાવે છે | હા | +| `check:dead-code` | બિનઉપયોગી exports / files ratchet (knip) baseline ની સરખામણીમાં ખરાબ થતું નથી | હા | +| `check:compression-budget` | Compression benchmark budget — દરેક engine માટે token-savings ની લઘુતમ મર્યાદા ખરાબ થવી જોઈએ નહીં | હા | +| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) ખરાબ થતું નથી; મોટા ભાગે `typecheck:noimplicit:core` ને સમાવી લે છે | હા | +| `check:codeql-ratchet` | ખુલ્લા CodeQL alerts ની સંખ્યા ખરાબ થતી નથી (`gh api` દ્વારા વાંચે છે; token વિના સુગમ રીતે skip કરે છે) — refresh cadence અને manual trigger માટે: નીચે "CodeQL ratchet" જુઓ | હા | + +### Job: `quality-extended` + +સમગ્ર job સલાહરૂપ છે (`continue-on-error: true`). npm-આધારિત ratchets વાસ્તવમાં +ચાલે છે; બાહ્ય scanners `gh release download` દ્વારા install થાય છે અને binary હજુ પણ +ગેરહાજર હોય ત્યારે સ્વયં skip થાય છે (exit 0). + +| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:circular-deps` | કોઈ circular dependencies નથી (dpdm) | **સલાહરૂપ** | +| `check:bundle-size` | Bundle size cap કરતાં વધારે નથી | **સલાહરૂપ** | +| `check:secrets` | Secret scanning (gitleaks) — binary ગેરહાજર હોય તો skip કરે છે | **સલાહરૂપ** | +| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) ખરાબ થતી નથી — binary ગેરહાજર હોય તો skip કરે છે | **સલાહરૂપ** | +| `check:workflows` | Workflow lint (actionlint + zizmor); ગેરહાજર/ખામીયુક્ત scanners, અમાન્ય reports અથવા ગેરહાજર ratchet baseline ને કારણે INCOMPLETE તરીકે નિષ્ફળ થાય છે. માન્ય findings પસંદ કરેલી strict/advisory/ratchet policy અનુસરે છે | અમલ જરૂરી; CI માં zizmor ratchet અવરોધક | +| `check:openapi-breaking` | base branch (oasdiff) સામે public API contract (`openapi.yaml`) માં breaking changes — `openapiBreaking=N` ઉત્પન્ન કરે છે; oasdiff ગેરહાજર હોય અથવા base spec ઉકેલી ન શકાય તો skip કરે છે | **સલાહરૂપ** | + +### Job: `docs-sync-strict` + +`main` માટેની દરેક PR પર ચાલે છે. નિષ્ફળતા આવે તો merge અવરોધે છે. + +| સ્ક્રિપ્ટ | શું ચકાસે છે | અવરોધક | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | +| `check:docs-all` | નીચેના 6 સબ-ગેટ ક્રમિક રીતે ચલાવતો મેટા-ગેટ | હા | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt સંસ્કરણ સુસંગતતા | હા | +| ↳ `check:docs-counts` | ગદ્યમાં આપેલી સંખ્યાઓ (પ્રદાતા સંખ્યા, માઇગ્રેશન સંખ્યા વગેરે) વાસ્તવિક સંખ્યાઓની રેચેટ વિન્ડોની અંદર છે | હા | +| ↳ `check:env-doc-sync` | `.env.example` માંનો દરેક env var દસ્તાવેજોના કોષ્ટકમાં દસ્તાવેજીકૃત છે, અને તેનાથી વિપરીત પણ | હા | +| ↳ `check:deprecated-versions` | દસ્તાવેજોમાં કોઈ અપ્રચલિત સંસ્કરણ સ્ટ્રિંગ નથી | હા | +| ↳ `check:doc-links` | દસ્તાવેજોમાંની આંતરિક markdown લિંક્સ વાસ્તવિક ફાઇલો તરફ નિર્દેશ કરે છે (`[text]`/`(path)` સ્વરૂપ) | હા | +| ↳ `check:fabricated-docs` | દસ્તાવેજોમાં ઉલ્લેખિત રૂટ્સ, env vars, CLI કમાન્ડ્સ, હૂક નામો અને ફાઇલ પાથ્સ કોડબેઝમાં અસ્તિત્વ ધરાવે છે. `--strict` દ્વારા હાર્ડ ગેટ; ફ્લૅગ વિના સોફ્ટ-ફેલ. | હા (CI માં `--strict` દ્વારા) | +| `check:cli-i18n` | CLI કમાન્ડ સ્ટ્રિંગ્સ બધી i18n લોકેલ ફાઇલોમાં હાજર છે | હા | +| `check:openapi-coverage` | OpenAPI સ્પેક વાસ્તવિક રૂટ્સના ઓછામાં ઓછા રેચેટ કરેલા લઘુત્તમ સ્તરને આવરી લે છે | હા | +| `check:openapi-security-tiers` | `openapi.yaml` માંના સુરક્ષા સ્તરના ઍનોટેશન્સ `routeGuard.ts` ના વર્ગીકરણો સાથે સુસંગત છે | **સલાહરૂપ** | +| `check:openapi-routes` | `openapi.yaml` માંનો દરેક પાથ વાસ્તવિક `route.ts` તરફ નિર્દેશ કરે છે (ભ્રમ-વિરોધી) | હા | +| `check:docs-symbols` | `docs/**/*.md` માંનો દરેક `/api/...` સંદર્ભ વાસ્તવિક `route.ts` તરફ નિર્દેશ કરે છે (ભ્રમ-વિરોધી) | હા | +| `i18n translation drift` | i18n લોકેલ ફાઇલોમાં અનુવાદ ન થયેલી કીઓ — માત્ર ચેતવણી | **સલાહરૂપ** | ### જોબ: `i18n-ui-coverage` -| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check-ui-keys-coverage` (ઇનલાઇન) | UI i18n key coverage ≥ 65% છે | હા | -| `check-ui-value-drift` (ઇનલાઇન) | ફરી લખાયેલું અંગ્રેજી **value** કોઈ જૂનો અનુવાદ પાછળ છોડતું નથી | હા | -| `check-new-key-coverage` (ઇનલાઇન) | **નવી** અંગ્રેજી key દરેક localeમાં અનુવાદિત છે — `__MISSING__:` marker અસ્વીકારવામાં આવે છે | હા | -| `check-translation-ratio` | locale દીઠ વાસ્તવિક અનુવાદનું પ્રમાણ (allowlistની બહારનાં અંગ્રેજી-સમાન / placeholder / missing leaves) `config/quality/i18n-translation-baseline.json` + slack કરતાં વધુ ન હોવું જોઈએ | **સલાહરૂપ** | +| સ્ક્રિપ્ટ | શું ચકાસે છે | અવરોધક | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (ઇનલાઇન) | UI i18n કી કવરેજ ≥ 65% છે | હા | +| `check-ui-value-drift` (ઇનલાઇન) | ફરીથી લખાયેલું અંગ્રેજી **મૂલ્ય** પાછળ કોઈ જૂનો અનુવાદ બાકી રાખતું નથી | હા | +| `check-new-key-coverage` (ઇનલાઇન) | એક **નવી** અંગ્રેજી કી દરેક લોકેલમાં અનુવાદિત છે — `__MISSING__:` માર્કર અસ્વીકારવામાં આવે છે | હા | +| `check-translation-ratio` | લોકેલ દીઠ વાસ્તવિક અનુવાદનો ગુણોત્તર (અંગ્રેજી સમાન / પ્લેસહોલ્ડર / મંજૂરીસૂચિની બહારની ખૂટતી લાઇનો) `config/quality/i18n-translation-baseline.json` + છૂટ કરતાં વધુ ન હોવો જોઈએ | **સલાહરૂપ** | -`fetch-depth: 0` જરૂરી છે — value-drift gate merge base સામે `en.json` નો diff કરે છે. +`fetch-depth: 0` જરૂરી છે — value-drift ગેટ `en.json` ને merge base સામે diff કરે છે. -#### `check-ui-value-drift` — જૂના અનુવાદ માટેનો ગેટ +#### `check-ui-value-drift` — જૂના અનુવાદનો ગેટ -આ તે એક i18n regression પકડે છે જે બીજા gates માળખાકીય રીતે જોઈ શકતા નથી: કોઈ અંગ્રેજી value -ફરીથી લખાય છે અને _અગાઉના_ અંગ્રેજી પરથી ઉત્પન્ન થયેલા અનુવાદો યથાવત્ રહી જાય છે, જેથી -બિન-અંગ્રેજી વપરાશકર્તાઓ આત્મવિશ્વાસપૂર્વક લખાયેલું, પરંતુ હવે ખોટું લખાણ વાંચતા રહે છે. +આ એવી એક i18n રિગ્રેશન પકડે છે જેને બીજા ગેટ્સ માળખાકીય રીતે જોઈ શકતા નથી: અંગ્રેજી મૂલ્ય +ફરીથી લખાય છે અને _અગાઉના_ અંગ્રેજીમાંથી મેળવેલા અનુવાદો યથાવત્ રહી જાય છે, તેથી +બિન-અંગ્રેજી વપરાશકર્તાઓ વિશ્વાસપૂર્વક લખાયેલું, પરંતુ હવે ખોટું લખાણ વાંચતા રહે છે. -આ ખરેખર રિલીઝમાં પહોંચી ગયું હતું. Antigravity -login helper ઉમેરાયો ત્યારે (#5203) `oauthModal.googleOAuthWarning` ફરીથી લખવામાં આવ્યું હતું; **43માંથી 39 locales** માં operatorsને "સંપૂર્ણ -URL કૉપિ કરીને નીચે પેસ્ટ કરો" કહેતો ટેક્સ્ટ યથાવત્ રહ્યો — એવો flow જે તે provider માટે પૂર્ણ થઈ જ શકતો નથી. આ બાબત -#8463 સુધી ધ્યાન બહાર રહી, કારણ કે: +આ વાસ્તવમાં રિલીઝ થયું હતું. Antigravity લૉગિન હેલ્પર ઉમેરાયો ત્યારે (#5203) +`oauthModal.googleOAuthWarning` ફરીથી લખાયું હતું; **43 માંથી 39 લોકેલ્સ** માં ઓપરેટર્સને "સંપૂર્ણ +URL કૉપિ કરીને નીચે પેસ્ટ કરો" એવું કહેતો ટેક્સ્ટ યથાવત્ રહ્યો — એક એવી પ્રક્રિયા જે તે પ્રદાતા માટે પૂર્ણ થઈ શકતી નથી. આ +#8463 સુધી ધ્યાનમાં આવ્યું નહીં, કારણ કે: -- `sync-ui-keys` માત્ર **ગેરહાજર** keysને જ backfill કરે છે, **જૂની** keysને ક્યારેય નહીં; -- `check-ui-keys-coverage` keyની _હાજરી_ ગણે છે, તેથી જૂનો અનુવાદ પણ આવરી લેવાયેલો ગણાય છે; -- `check-translation-drift` `docs/i18n//**.md` documentation mirrorsને ટ્રૅક કરે છે — - તે ક્યારેય `src/i18n/messages/*.json` વાંચતું નથી. 2026-09ના પુનઃ-સિંકથી job `docs-sync-strict` માં અવરોધક છે: કોઈ core doc સંપાદિત કરો → `npm run i18n:run -- --files=` (વિભાગ-સ્તરીય, ઓછા ખર્ચવાળું). +- `sync-ui-keys` ફક્ત **ગેરહાજર** કીઓને જ બૅકફિલ કરે છે, **જૂની** કીઓને ક્યારેય નહીં; +- `check-ui-keys-coverage` કીની _હાજરી_ ગણે છે, તેથી જૂનો અનુવાદ પણ આવરી લેવાયેલો ગણાય છે; +- `check-translation-drift` `docs/i18n//**.md` દસ્તાવેજીકરણ મિરર્સને ટ્રૅક કરે છે — + તે ક્યારેય `src/i18n/messages/*.json` વાંચતું નથી. 2026-09 રિ-સિંકથી જોબ `docs-sync-strict` માં અવરોધક: + મુખ્ય દસ્તાવેજમાં ફેરફાર કરો → `npm run i18n:run -- --files=` (વિભાગ-સ્તરીય, સસ્તું). -**ડિફ-સચેત, આધારરેખા-સમર્થિત નહીં.** તે મર્જ બેઝ પરના `en.json`ની વર્કિંગ ટ્રી સાથે સરખામણી કરે છે; જે દરેક કીનું અંગ્રેજી મૂલ્ય બદલાયું હોય, તેના માટે હજુ પણ અસ્પર્શિત અનુવાદ ધરાવતું કોઈપણ લોકેલ જૂનું ગણાય છે. આ ઇરાદાપૂર્વક **પહેલેથી અસ્તિત્વમાં રહેલું ઋણ સ્થિર રાખે છે** — લાંબા સમયથી રહેલો અનુવાદ કયા જૂના અંગ્રેજી લખાણમાંથી આવ્યો હતો તે ડિફ જાહેર કરી શકતો નથી, તેથી ગેટ માત્ર વર્તમાન ફેરફાર જે ભાગને સ્પર્શે છે તેનું જ મૂલ્યાંકન કરે છે. વૈકલ્પિક રીત (પ્રતિ-કી હૅશ આધારરેખા) માટે ~600 KBની જનરેટ કરેલી ફાઇલ જરૂરી બને, જે હાલની સૌથી મોટી આધારરેખાથી 3× મોટી હોય અને દરેક i18n PR પર બદલાતી રહે. +**ડિફ-સચેત, બેઝલાઇન-આધારિત નહીં.** તે મર્જ બેઝ પરના `en.json`ની કાર્યરત ટ્રી સાથે સરખામણી કરે છે; જે દરેક કીનું અંગ્રેજી મૂલ્ય બદલાયું હોય, તેની અસ્પર્શિત અનુવાદ ધરાવતી કોઈપણ લોકેલ જૂની ગણાય છે. આ ઇરાદાપૂર્વક **પહેલેથી અસ્તિત્વમાં રહેલું ઋણ સ્થિર કરે છે** — લાંબા સમયથી રહેલો અનુવાદ કયા જૂના અંગ્રેજીમાંથી આવ્યો હતો તે ડિફ જણાવી શકતું નથી, તેથી ગેટ ફક્ત વર્તમાન ફેરફાર જે સ્પર્શે છે તેનું જ મૂલ્યાંકન કરે છે. વિકલ્પ (દરેક કી દીઠ હૅશ બેઝલાઇન) માટે ~600 KBની જનરેટ કરેલી ફાઇલની જરૂર પડે, જે હાલની સૌથી મોટી બેઝલાઇન કરતાં 3× મોટી હોય અને દરેક i18n PR પર બદલાતી રહે. તેને સંતોષવાની બે રીતો: -1. અસરગ્રસ્ત અનુવાદો અપડેટ કરો, અથવા +1. અસરગ્રસ્ત અનુવાદોને અપડેટ કરો, અથવા 2. તેમને `__MISSING__:` પર સેટ કરો — ત્યારબાદ રનટાઇમ સુધારેલું અંગ્રેજી પ્રદાન કરે છે - (`src/i18n/request.ts::deepMergeFallback`, #7258) અને કી અનુવાદ માટે કતારમાં ઉમેરાય છે. + (`src/i18n/request.ts::deepMergeFallback`, #7258) અને કી અનુવાદ માટે કતારમાં જાય છે. જો સ્ટ્રિંગનો **અર્થ** બદલાયો હોય, તો **કીનું નામ બદલવાનું** પસંદ કરો: નવી કી જૂનો અનુવાદ વારસામાં મેળવી શકતી નથી. #8463માં આ જ પેટર્નનો ઉપયોગ થયો હતો. ```bash npm run i18n:check-value-drift # કડક (CI જે ચલાવે છે) -npm run i18n:check-value-drift:warn # માત્ર અહેવાલ +npm run i18n:check-value-drift:warn # ફક્ત અહેવાલ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -જ્યારે આધાર કૅટલૉગ વાંચી શકાતો નથી (બેઝ રેફ વિનાનું શૅલો ક્લોન), ત્યારે `check-openapi-breaking`ની જેમ `SKIP reason=base-unresolved` સાથે 0 પર બહાર નીકળે છે. +જ્યારે બેઝ કૅટલૉગ વાંચી શકાતો નથી (બેઝ ref વિનાનો શેલો ક્લોન), ત્યારે `check-openapi-breaking`ની જેમ `SKIP reason=base-unresolved` સાથે 0 પર બહાર નીકળે છે. -### જોબ: `i18n` +### જૉબ: `i18n` -સંપૂર્ણ i18n માન્યતા મેટ્રિક્સ (દરેક લોકેલ માટે એક જોબ). આખી જોબ સલાહરૂપ છે. +સંપૂર્ણ i18n માન્યતા મેટ્રિક્સ (દરેક લોકેલ દીઠ એક જૉબ). આખી જૉબ સલાહાત્મક છે. -| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | -| ------------------------------- | -------------------------------- | -------------------------------------------------- | -| `validate_translation.py quick` | દરેક લોકેલ માટે અનુવાદની પૂર્ણતા | **સલાહરૂપ** (આખી જોબ પર `continue-on-error: true`) | +| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | +| ------------------------------- | ------------------------------- | ---------------------------------------------------- | +| `validate_translation.py quick` | દરેક લોકેલ દીઠ અનુવાદની પૂર્ણતા | **સલાહાત્મક** (આખી જૉબ પર `continue-on-error: true`) | -### જોબ: `pr-test-policy` +### જૉબ: `pr-test-policy` -માત્ર પુલ રિક્વેસ્ટ્સ પર ચાલે છે. +ફક્ત પુલ રિક્વેસ્ટ્સ પર ચાલે છે. -| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------ | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, અથવા `bin/`માં પ્રોડક્શન કોડ બદલતા PRમાં ટેસ્ટ સામેલ કે અપડેટ થયેલા હોવા જોઈએ (કડક નિયમ #8) | હા | -| `check:test-masking` | બદલાયેલી ટેસ્ટ ફાઇલો કુલ assert સંખ્યા ઘટાડતી નથી અથવા `assert.ok(true)` જેવી પુનરુક્તિઓ ઉમેરતી નથી | હા | -| `check:pr-evidence` | PR બોડી ફેરફાર માટે ટેસ્ટ/VPS પુરાવાનો ઉલ્લેખ કરે છે (PRના લખાણમાં grep કરીને કડક નિયમ #18ને યાંત્રિક બનાવે છે — નાજુક, Backlog જુઓ) | હા | +| સ્ક્રિપ્ટ | શું માન્ય કરે છે | અવરોધક | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, અથવા `bin/`માં પ્રોડક્શન કોડ બદલતા PRમાં ટેસ્ટ્સ સામેલ અથવા અપડેટ થયેલા હોવા જોઈએ (સખત નિયમ #8) | હા | +| `check:test-masking` | બદલાયેલી ટેસ્ટ ફાઇલો નેટ અસર્ટ ગણતરી ઘટાડતી નથી અથવા `assert.ok(true)` જેવી પુનરુક્તિઓ ઉમેરતી નથી | હા | +| `check:pr-evidence` | PR બોડીમાં ફેરફાર માટેના ટેસ્ટ/VPS પુરાવાનો ઉલ્લેખ હોય છે (PRના ગદ્યમાં grep કરીને સખત નિયમ #18ને યાંત્રિક બનાવે છે — નાજુક, Backlog જુઓ) | હા | -### જોબ: `test-vitest` +### જૉબ: `test-vitest` -`build` પછી ચાલે છે. નિષ્ફળતા થાય તો મર્જને અવરોધે છે. +`build` પછી ચાલે છે. નિષ્ફળતા આવે તો મર્જને અવરોધે છે. -| સ્યુટ | શું માન્ય કરે છે | અવરોધક | -| ---------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | MCP સર્વર (110 ટૂલ્સ), autoCombo, કૅશ — vitest રનર | હા | -| `test:vitest:ui` | UI કમ્પોનન્ટ ટેસ્ટ્સ — vitest રનર | **અવરોધક** — પહેલેથી અસ્તિત્વમાં રહેલી નિષ્ફળતાઓ `vitest.config.ts`માં સ્પષ્ટ રીતે બાકાત છે; નવી નિષ્ફળતાઓ જોબને નિષ્ફળ કરે છે | +| સ્યુટ | શું માન્ય કરે છે | અવરોધક | +| ---------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP સર્વર (110 ટૂલ્સ), autoCombo, કૅશ — vitest રનર | હા | +| `test:vitest:ui` | UI કમ્પોનન્ટ ટેસ્ટ્સ — vitest રનર | **અવરોધક** — પહેલેથી અસ્તિત્વમાં રહેલી નિષ્ફળતાઓ `vitest.config.ts`માં સ્પષ્ટપણે બાકાત રાખવામાં આવી છે; નવી નિષ્ફળતાઓ જૉબને નિષ્ફળ બનાવે છે | -### રાત્રિકાલીન વર્કફ્લોઝ (નિર્ધારિત, સલાહરૂપ) +### રાત્રિકાલીન વર્કફ્લોઝ (નિર્ધારિત, સલાહાત્મક) -આ cron શેડ્યૂલ પર (અને `workflow_dispatch` દ્વારા) ચાલે છે, PR પર ક્યારેય નહીં. બધા સલાહરૂપ છે. +આ cron શેડ્યૂલ પર (અને `workflow_dispatch` દ્વારા) ચાલે છે, PR પર ક્યારેય નહીં. બધા સલાહાત્મક છે. -| વર્કફ્લો | શું માન્ય કરે છે | અવરોધક | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `nightly-property` | રૅન્ડમ સીડ + વધુ રન સંખ્યા સાથેના fast-check પ્રોપર્ટી ટેસ્ટ્સ | **સલાહરૂપ** | -| `nightly-resilience` | હીપ-વૃદ્ધિ ગેટ, કેઓસ ફૉલ્ટ-ઇન્જેક્શન, k6 લોડ/સોક | **સલાહરૂપ** | -| `nightly-llm-security` | promptfoo ઇન્જેક્શન ગાર્ડ (બ્લૉક મોડ) + garak પ્રોબ્સ (પ્રોવાઇડર સિક્રેટ વિના છોડી દેવાય છે) | **સલાહરૂપ** | -| `nightly-schemathesis` | `docs/openapi.yaml`નો ઉપયોગ કરીને લાઇવ OmniRoute સામે OpenAPI કૉન્ટ્રાક્ટ ફઝિંગ (schemathesis) — સ્પેક ઉલ્લંઘનો / હેન્ડલ ન થયેલી 500 ભૂલો સામે લાવે છે (Fase 8 B.4) | **સલાહરૂપ** | -| `nightly-mutation` | ઝડપી યુનિટ લેન પર Stryker મ્યુટેશન-ટેસ્ટિંગ સ્કોર — ટકી રહેલા મ્યુટન્ટ્સ નબળા asserts સામે લાવે છે | **સલાહરૂપ** | -| `nightly-compat` | સમર્થિત `engines.node` રેન્જોમાં Node એન્જિન સુસંગતતા મેટ્રિક્સ | **સલાહરૂપ** | +| વર્કફ્લો | શું માન્ય કરે છે | અવરોધક | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `nightly-property` | રૅન્ડમ સીડ + વધુ રન ગણતરી સાથેના fast-check પ્રોપર્ટી ટેસ્ટ્સ | **સલાહાત્મક** | +| `nightly-resilience` | હીપ-વૃદ્ધિ ગેટ, કેઓસ ફૉલ્ટ-ઇન્જેક્શન, k6 લોડ/સોક | **સલાહાત્મક** | +| `nightly-llm-security` | promptfoo ઇન્જેક્શન ગાર્ડ (બ્લૉક મોડ) + garak પ્રોબ્સ (પ્રોવાઇડર સિક્રેટ વિના છોડવામાં આવે છે) | **સલાહાત્મક** | +| `nightly-schemathesis` | `docs/openapi.yaml`નો ઉપયોગ કરીને લાઇવ OmniRoute સામે OpenAPI કૉન્ટ્રૅક્ટ ફઝિંગ (schemathesis) — સ્પેક ઉલ્લંઘનો / ન સંભાળાયેલી 500 ભૂલો ઉજાગર કરે છે (તબક્કો 8 B.4) | **સલાહાત્મક** | +| `nightly-mutation` | ઝડપી યુનિટ લેન પર Stryker મ્યુટેશન-ટેસ્ટિંગ સ્કોર — બચી ગયેલા મ્યુટન્ટ્સ નબળા અસર્ટ્સને ઉજાગર કરે છે | **સલાહાત્મક** | +| `nightly-compat` | સમર્થિત `engines.node` રેન્જમાં Node એન્જિન સુસંગતતા મેટ્રિક્સ | **સલાહાત્મક** | --- @@ -531,43 +530,43 @@ CI ગેટ ઉપરાંત, OmniRoute એક **વૈકલ્પિક** ` --- -## તર્કસંગતીકરણ બેકલૉગ (ROI સમીક્ષા — તબક્કો 9 તરંગ 3) +## તર્કસંગતીકરણ બૅકલૉગ (ROI સમીક્ષા — તબક્કો 9 તરંગ 3) -આ ઇન્વેન્ટરીનું 2026-06-17ના રોજ `ci.yml` સાથે સમાધાન કરવામાં આવ્યું હતું (અગાઉના સંસ્કરણમાં +આ ઇન્વેન્ટરીનું 2026-06-17ના રોજ `ci.yml` સામે સમાધાન કરવામાં આવ્યું હતું (અગાઉની આવૃત્તિમાં `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` રહી ગયા હતા). સમાધાન કરેલા સમૂહની ROI સમીક્ષાએ -નીચેના તર્કસંગતીકરણ ઉમેદવારો ઓળખ્યા. **મર્જ યાંત્રિક CI -ફેરફારો છે; ફ્લિપ/ડ્રૉપ એ ઑપરેટર માટે આરક્ષિત નીતિગત નિર્ણયો છે.** નીચેનામાંથી કશું પણ -હજુ લાગુ કરવામાં આવ્યું નથી. +`check:codeql-ratchet`, `check:pr-evidence` છૂટી ગયાં હતાં). સમાધાન કરાયેલા સમૂહની ROI સમીક્ષાએ +નીચેના તર્કસંગતીકરણ ઉમેદવારો ઓળખ્યા. **મર્જ યાંત્રિક CI ફેરફારો છે; +ફ્લિપ/ડ્રૉપ ઓપરેટર માટે અનામત નીતિગત નિર્ણયો છે.** નીચેનું કશું હજી +લાગુ કરવામાં આવ્યું નથી. -**ઉપર દસ્તાવેજીકૃત ન થયેલું પણ** (સલાહરૂપ, ઓછું સિગ્નલ): `docs-lint` જૉબ -(markdownlint + Vale, સમગ્ર જૉબ માટે `continue-on-error`) અને સ્વતંત્ર સ્કૅનર વર્કફ્લો +**ઉપર દસ્તાવેજીકૃત ન થયેલું પણ** (સલાહરૂપ, ઓછો સંકેત): `docs-lint` જોબ +(markdownlint + Vale, સમગ્ર જોબ `continue-on-error`) અને સ્વતંત્ર સ્કૅનર વર્કફ્લો `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` -`quality-baseline.json`માં છે, પરંતુ `ci.yml`માં કોઈ બ્લૉકિંગ રૅચેટ સાથે જોડાયેલું નથી — આ મેટ્રિક +`quality-baseline.json`માં છે, પરંતુ `ci.yml`માં અવરોધક રૅચેટ સાથે જોડાયેલું નથી — મેટ્રિક હાલમાં અનાથ છે. -### મર્જ / ડીડુપ્લિકેશન (યાંત્રિક, ઓછું જોખમ) +### મર્જ / ડિડુપ્લિકેશન (યાંત્રિક, ઓછું જોખમ) -દરેક ઉમેદવારને 2026-06-17ના રોજ લાઇવ ગેટની સ્થિતિ સામે માન્ય કરવામાં આવ્યો હતો (વિશ્વાસ કરો, પણ ચકાસો); -કેટલાક "સ્પષ્ટ" મર્જ વાસ્તવમાં છુપાયેલું ઋણ ધરાવતા હોવાનું બહાર આવ્યું અને તે **સ્વચ્છ ડ્રૉપ-ઇન નથી**. +દરેક ઉમેદવારને 2026-06-17ના રોજ લાઇવ ગેટ સ્થિતિ સામે માન્ય કરવામાં આવ્યો હતો (વિશ્વાસ કરો, પણ ચકાસો); +કેટલાક "સ્પષ્ટ" મર્જ હકીકતમાં ટેક્નિકલ ઋણ છુપાવતા હોવાનું બહાર આવ્યું અને તે **સ્વચ્છ ડ્રૉપ-ઇન નથી**. -- **`check:docs-sync` બે વખત ચાલે છે** — `lint` જૉબમાં સ્વતંત્ર રીતે અને ફરી `check:docs-all` (`docs-sync-strict`)ની અંદર તથા husky pre-commit hookમાં. ✅ **પૂર્ણ** — સ્વતંત્ર `lint` ઇન્વોકેશન દૂર કરવામાં આવ્યું. -- **CVE સ્કૅનિંગ** — ❌ **સ્વચ્છ મર્જ નથી.** `audit:deps` કોઈપણ high/critical CVE પર નિષ્ફળતા સાથે અટકે છે; `check:vuln-ratchet` (osv) માત્ર બેઝલાઇનની સરખામણીમાં _રીગ્રેશન_ થાય ત્યારે નિષ્ફળ જાય છે (હાલમાં 1 MODERATE). અર્થવિધિ અલગ છે — `audit:deps` દૂર કરવાથી નિરપેક્ષ high/critical ગેટ ખોવાઈ જશે. બંને રાખો. -- **સાઇકલ શોધ** — ❌ **સ્વચ્છ મર્જ નથી.** `check:circular-deps` (dpdm) **91 સાઇકલ** દર્શાવે છે (એટલે જ તે સલાહરૂપ છે); પહેલાં તેમનું નિરાકરણ કર્યા વિના તેને બ્લૉકિંગ તરીકે પ્રમોટ કરી શકાતું નથી, અને તેનો વ્યાપ લીલા, ક્યુરેટ કરેલા `check:cycles` કરતાં વધુ વિસ્તૃત છે. `check:cycles`ને બ્લૉકિંગ રાખો; 91 dpdm સાઇકલનું નિરાકરણ પોતે એક અલગ બેકલૉગ છે. -- **જટિલતા** — ✅ **પૂર્ણ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): એક ESLint વૉક, ruleId પ્રમાણે ગણતરી કરે છે જેથી cyclomatic+max-lines અને cognitive બેઝલાઇન સ્વતંત્ર રહે; વ્યક્તિગત `check:complexity` / `check:cognitive-complexity` સ્થાનિક `--update` માટે યથાવત્ રહે છે. -- **`/api` એન્ટિ-હેલ્યુસિનેશન** — ✅ **પૂર્ણ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`ની એક FS ઇન્વેન્ટરી, openapi-routes + docs-symbols હજી પણ સ્વતંત્ર રીતે રિપોર્ટ કરે છે; વ્યક્તિગત ચેક્સ સ્થાનિક રન માટે યથાવત્ રહે છે. -- **`check:node-runtime` 11 જૉબમાં ચાલે છે** — ⚠️ **ઓછો ROI.** દરેક અલગ રનર છે અને ચેક <1s છે; સસ્તું પ્રતિ-જૉબ રક્ષણ ગુમાવવાની સામે કુલ બચત ~10s છે. આટલી ઉથલપાથલ યોગ્ય નથી. -- **CI lint પર `typecheck:noimplicit:core`** — ✅ **lint જૉબમાંથી દૂર કરાયું** (તે સલાહરૂપ `continue-on-error` હતું); બ્લૉકિંગ ટાઇપ સપાટી `typecheck:core` + `check:type-coverage` છે. સ્થાનિક સ્ક્રિપ્ટ જાળવી રાખવામાં આવી છે. +- **`check:docs-sync` બે વાર ચાલે છે** — `lint` જોબમાં સ્વતંત્ર રીતે અને ફરીથી `check:docs-all` (`docs-sync-strict`) તથા husky pre-commit હૂકની અંદર. ✅ **પૂર્ણ** — સ્વતંત્ર `lint` ઇન્વોકેશન દૂર કરવામાં આવ્યું. +- **CVE સ્કૅનિંગ** — ❌ **સ્વચ્છ મર્જ નથી.** `audit:deps` કોઈપણ high/critical CVE પર હાર્ડ-ફેઇલ થાય છે; `check:vuln-ratchet` (osv) માત્ર બેઝલાઇનની સરખામણીએ _રીગ્રેશન_ પર નિષ્ફળ થાય છે (હાલમાં 1 MODERATE). સિમેન્ટિક્સ અલગ છે — `audit:deps` દૂર કરવાથી નિરપેક્ષ high/critical ગેટ ગુમાવવો પડે. બંને રાખો. +- **સાઇકલ શોધ** — ✅ **પૂર્ણ** (#15159 G-01/G-02). અહીંના જૂના લખાણમાં `check:cycles`ને "લીલું, કાળજીપૂર્વક પસંદ કરેલું" ગેટ કહેવાયું હતું અને તેને અવરોધક રાખવાનું સમર્થન એ આધારે કરાયું હતું કે `check:circular-deps` (dpdm)એ 91 સાઇકલ દર્શાવ્યાં હતાં. એ લીલું પરિણામ **ખોટું લીલું પરિણામ** હતું: `check:cycles`એ 5 સબડિરેક્ટરી (450 ફાઇલ) સ્કૅન કરી હતી, માત્ર સ્થિર `import|export … from` સાથે મેળ સાધ્યો હતો અને દરેક `@/` તથા `@omniroute/open-sse/` સ્પેસિફાયર કાઢી નાખ્યો હતો, તેથી તે રિપોઝિટરીમાં પ્રભુત્વ ધરાવતી dynamic-import + alias સાઇકલ જોઈ શકતું નહોતું. સુધાર્યું: ગેટ હવે `src` + `open-sse` (5023 ફાઇલ)માં ફરે છે, TypeScript ASTમાંથી સ્પેસિફાયર એકત્ર કરે છે (જેથી `import("…")` ગણાય છે અને ટાઇપ-સ્થાનમાં `typeof import("…")` ગણાતું નથી), અને tsconfig `paths`નું રિઝોલ્યુશન કરે છે. તેને 0 નહીં, પરંતુ **14** સાઇકલ મળે છે. અગાઉથી અસ્તિત્વમાં રહેલી 14 સાઇકલને ગેટ PRમાં સુધારી શકાતી ન હોવાથી, `check:cycles` હવે **રૅચેટ** છે (`--ratchet`, `quality-baseline.json`માં ઉચ્ચતમ મર્યાદા `metrics.cycles.value = 14`, `direction: down`) — તે કોઈપણ _રીગ્રેશન_ને અવરોધે છે અને ગણતરી માત્ર ઘટી શકે છે. CI `npm run check:cycles:ratchet` ચલાવે છે. ઘટાડાની કામગીરી **A-01** સાથે આગળ વધે છે. વધુ વ્યાપક બીજા અભિપ્રાય તરીકે `check:circular-deps` (dpdm) સલાહરૂપ રહે છે. +- **જટિલતા** — ✅ **પૂર્ણ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): એક ESLint વૉક, ruleId પ્રમાણે ગણતરી કરે છે જેથી cyclomatic+max-lines અને cognitive બેઝલાઇન સ્વતંત્ર રહે; સ્થાનિક `--update` માટે વ્યક્તિગત `check:complexity` / `check:cognitive-complexity` યથાવત્ રહે છે. +- **`/api` ઍન્ટિ-હેલ્યુસિનેશન** — ✅ **પૂર્ણ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`ની એક FS ઇન્વેન્ટરી, openapi-routes + docs-symbols હજી પણ સ્વતંત્ર રીતે અહેવાલ આપે છે; સ્થાનિક રન માટે વ્યક્તિગત ચેક્સ યથાવત્ રહે છે. +- **`check:node-runtime` 11 જોબમાં ચાલે છે** — ⚠️ **ઓછું ROI.** દરેક અલગ રનર છે અને ચેક <1sનો છે; સસ્તું પ્રતિ-જોબ સુરક્ષા નિયંત્રણ ગુમાવવાની સામે કુલ બચત ~10s છે. આટલી ઉથલપાથલ યોગ્ય નથી. +- **CI lint પર `typecheck:noimplicit:core`** — ✅ **lint જોબમાંથી દૂર કરાયું** (સલાહરૂપ `continue-on-error` હતું); અવરોધક ટાઇપ સપાટી `typecheck:core` + `check:type-coverage` છે. સ્થાનિક સ્ક્રિપ્ટ જાળવી રાખવામાં આવી છે. -### ફ્લિપ / નિર્ણય (ઑપરેટર નીતિ) +### ફ્લિપ / નિર્ણય (ઓપરેટર નીતિ) -- `check:openapi-security-tiers` (સલાહરૂપ) — ❌ **સ્વચ્છ રીતે ફ્લિપ કરી શકાય તેમ નથી.** તે 0 સાથે બહાર નીકળે છે, પરંતુ ચેતવણી આપે છે કે `LOCAL_ONLY_API_PREFIXES` હેઠળના કેટલાક `traffic-inspector` રૂટમાં `x-loopback-only: true` ઍનોટેશન નથી. તેને અમલમાં મૂકવા માટે પહેલાં `openapi.yaml`માં તે ઍનોટેશનો ઉમેરવા જરૂરી છે. -- `typecheck:noimplicit:core` (સલાહરૂપ) — મોટા ભાગે બ્લૉકિંગ `check:type-coverage` રૅચેટમાં સમાવિષ્ટ છે. તેને રૅચેટમાં ફ્લિપ કરો અથવા વધારાનો બિનજરૂરી બીજો `tsc` પાસ દૂર કરો. -- `test:vitest:ui` (હવે **બ્લૉકિંગ**) — અગાઉથી રહેલી નિષ્ફળતાઓને `vitest.config.ts`માં `// #8618` ટ્રૅકિંગ ટિપ્પણીઓ સાથે સ્પષ્ટ રીતે બાકાત રાખવામાં આવી છે; નવી નિષ્ફળતાઓ જૉબને નિષ્ફળ બનાવે છે. -- `check:secrets` (gitleaks, 3 દસ્તાવેજીકૃત false-positive પર સ્થિર કરાયેલું બ્લૉકિંગ રૅચેટ) — 0 સુધી પહોંચવા માટે 3ને allowlistમાં ઉમેરો અથવા તેને સલાહરૂપ તરીકે ડિમોટ કરો. GitHubના મૂળ secret-scanning + `check:public-creds` સાથે ઓવરલેપ થાય છે. -- `check:pr-evidence` (બ્લૉકિંગ, PR-body ગદ્યને greps કરે છે) — false-positiveનું જોખમ ઊંચું છે; તેને દૂર કરવાથી Hard Rule #18નો અમલ નબળો પડે છે, તેથી આ એક વાસ્તવિક નીતિગત નિર્ણય છે. -- `semgrep` (સલાહરૂપ સ્વતંત્ર) — OWASP પરિવારો માટે CodeQL સાથે ઓવરલેપ થાય છે; તેની બેઝલાઇનને રૅચેટ સાથે જોડો અથવા તેને દૂર કરો. +- `check:openapi-security-tiers` (સલાહરૂપ) — ❌ **સ્વચ્છ રીતે ફ્લિપ કરી શકાય તેમ નથી.** તે 0 સાથે એક્ઝિટ થાય છે, પરંતુ ચેતવણી આપે છે કે `LOCAL_ONLY_API_PREFIXES` હેઠળના કેટલાક `traffic-inspector` રૂટમાં `x-loopback-only: true` ઍનોટેશન નથી. તેને અમલમાં મૂકતાં પહેલાં `openapi.yaml`માં એ ઍનોટેશન ઉમેરવા જરૂરી છે. +- `typecheck:noimplicit:core` (સલાહરૂપ) — અવરોધક `check:type-coverage` રૅચેટ દ્વારા મોટા ભાગે આવરી લેવાય છે. તેને રૅચેટમાં ફ્લિપ કરો અથવા બિનજરૂરી બીજા `tsc` પાસને દૂર કરો. +- `test:vitest:ui` (હવે **અવરોધક**) — અગાઉથી અસ્તિત્વમાં રહેલી નિષ્ફળતાઓને `vitest.config.ts`માં `// #8618` ટ્રૅકિંગ ટિપ્પણીઓ સાથે સ્પષ્ટ રીતે બાકાત રાખવામાં આવી છે; નવી નિષ્ફળતાઓ જોબને નિષ્ફળ બનાવે છે. +- `check:secrets` (gitleaks, 3 દસ્તાવેજીકૃત false-positive પર સ્થિર કરાયેલ અવરોધક રૅચેટ) — 0 સુધી પહોંચવા માટે એ 3ને allowlist કરો અથવા તેને સલાહરૂપ સ્તરે ઉતારો. GitHubના મૂળ secret-scanning + `check:public-creds` સાથે ઓવરલેપ થાય છે. +- `check:pr-evidence` (અવરોધક, PR-bodyના ગદ્યમાં greps કરે છે) — false-positiveનું ઊંચું જોખમ; તેને દૂર કરવાથી Hard Rule #18નો અમલ નબળો પડે છે, તેથી આ ખરેખર નીતિગત નિર્ણય છે. +- `semgrep` (સલાહરૂપ સ્વતંત્ર) — OWASP ફૅમિલી માટે CodeQL સાથે ઓવરલેપ થાય છે; તેની બેઝલાઇનને રૅચેટ સાથે જોડો અથવા તેને દૂર કરો. --- diff --git a/docs/i18n/ha/CONTRIBUTING.md b/docs/i18n/ha/CONTRIBUTING.md index f158416eb67..4ec7f2f5a49 100644 --- a/docs/i18n/ha/CONTRIBUTING.md +++ b/docs/i18n/ha/CONTRIBUTING.md @@ -401,20 +401,20 @@ Rubuta unit tests a `tests/unit/` waɗanda aƙalla za su rufe: ## Jerin Dubawa na Pull Request -- [ ] Tests sun yi nasara (`npm test`) -- [ ] Linting ya yi nasara (`npm run lint`) -- [ ] Build ya yi nasara (`npm run build`) -- [ ] An ƙara TypeScript types don sabbin public functions da interfaces -- [ ] Babu hardcoded secrets ko fallback values -- [ ] An saka public upstream credentials ta hanyar `resolvePublicCred()` (duba [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ba a matsayin literals ba -- [ ] Error responses suna bi ta `buildErrorBody()` / `sanitizeErrorMessage()` — babu ainihin stack traces a jikin responses (duba [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell commands (`exec` / `spawn`) suna tura runtime values ta `env`, ba ta string interpolation ba -- [ ] An tabbatar da ingancin duk inputs da Zod schemas -- [ ] An ƙara **fragment** na changelog a ƙarƙashin `changelog.d/{features|fixes|maintenance}/-.md` don sauye-sauyen da masu amfani za su gani (duba [`changelog.d/README.md`](./changelog.d/README.md)) — **kar a** gyara `CHANGELOG.md` kai tsaye; ana haɗa fragments a lokacin release kuma ba sa taɓa samun rikici tsakanin PRs -- [ ] An sabunta documentation (idan ya dace) -- [ ] Babu sababbin faɗakarwar CodeQL / Secret-Scanning da aka buɗe, ko kuma an yi watsi da kowacce tare da hujjar fasaha mai nuni ga takardar `docs/security/` da ta dace -- [ ] Routes da ke ƙaddamar da child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) an rarraba su a matsayin `isLocalOnlyPath()` a `src/server/authz/routeGuard.ts` — duba [Ƙa'ida Mai Tsauri #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Babu trailers na `Co-Authored-By` a cikin commit messages — dole commits su bayyana a ƙarƙashin Git identity na mai repository kawai (Ƙa'ida Mai Tsauri #16) +- [ ] Gwaje-gwaje sun yi nasara (`npm test`) +- [ ] Binciken lint ya yi nasara (`npm run lint`) +- [ ] Gina ya yi nasara (`npm run build`) +- [ ] An ƙara nau'ikan TypeScript don sabbin public functions da interfaces +- [ ] Babu secrets ko fallback values da aka rubuta kai tsaye +- [ ] An saka public upstream credentials ta hanyar `resolvePublicCred()` (duba [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ba a taɓa saka su kai tsaye a matsayin literals ba +- [ ] Error responses suna bi ta `buildErrorBody()` / `sanitizeErrorMessage()` — babu raw stack traces a cikin response bodies (duba [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell commands (`exec` / `spawn`) suna aika runtime values ta `env`, ba ta hanyar string interpolation ba +- [ ] An tantance dukkan inputs da Zod schemas +- [ ] An ƙara **fragment** na changelog a ƙarƙashin `changelog.d/{features|fixes|maintenance}/-.md` don canje-canjen da masu amfani za su gani (duba [`changelog.d/README.md`](./changelog.d/README.md)) — **kada** a gyara `CHANGELOG.md` kai tsaye; ana haɗa fragments lokacin release kuma ba sa taɓa cin karo tsakanin PRs +- [ ] An sabunta takardu (idan ya dace) +- [ ] Ba a buɗe sabbin faɗakarwar CodeQL / Secret-Scanning ba, ko kuma an yi watsi da kowannensu tare da hujjar fasaha mai nuni zuwa takardar `docs/security/` da ta dace +- [ ] An rarraba routes da ke ƙaddamar da child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) a matsayin `isLocalOnlyPath()` a cikin `src/server/authz/routeGuard.ts` — duba [Ƙa'ida Mai Tsauri #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Babu trailers na AI/bot na `Co-authored-by` a cikin commit messages (Ƙa'ida Mai Tsauri #16) — ana yaba wa human collaborators waɗanda aka sake amfani da aikinsu da daidaitattun trailers na `Co-authored-by: Name ` --- diff --git a/docs/i18n/ha/docs/architecture/QUALITY_GATES.md b/docs/i18n/ha/docs/architecture/QUALITY_GATES.md index a867a28cc3d..e2c27beefc3 100644 --- a/docs/i18n/ha/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ha/docs/architecture/QUALITY_GATES.md @@ -15,264 +15,257 @@ maimaitawa wanda bai dogara da takamaiman kayan aiki ba na wannan tsarin, duba --- -## Kundin ƙofofin tantancewa da bayanan martabar aiwatarwa +## Jerin gate da bayanan martabar aiwatarwa ### Karɓar ɗan takara -Tsarukan aiki na CI da Quality Gates kowannensu yana fitar da tabbataccen hukunci: `Gate / CI` da -`Gate / Quality`. Manufofin karɓarsu masu sigar da aka kayyade suna lissafa kowane aikin sama -a matsayin wajibi ko na shawara. Duk wani aikin wajibi da ya dace dole ne ya yi nasara: sakamakon da -babu, aka soke, aka tsallake, yake jira, ko ba a sani ba ba zai iya tabbatar da PASS ba. Ingantaccen -rarrabuwar docs-only ko catalog-only na iya sa layin lamba bai dace ba; -amma draft PR ba ɗan takarar da aka amince da shi ba ne. Alamar `hotfix` ba ta kawar da buƙatar hujja. - -Dukkan tsarukan aikin biyu suna rufe PRs da turawa zuwa rassan main/release, farawa da hannu da -abubuwan merge-group. Push, dispatch da merge-group suna gudanar da cikakken zaɓi. Forks -da merge groups suna amfani da hosted runners ga ayyukan da in ba haka ba za su zaɓi self-hosted -runners; dole ne a tabbatar da isasshen ƙarfin hosted kafin ƙaddamarwa. - -Kowane rasidin JSON yana bayyana SHA da aka checkout, workflow run da attempt. -CLI yana ƙin rashin daidaituwar SHA na checkout/event. Gwaje-gwajen workflow suna ɗaure kasancewa cikin manufa -da jerin `needs` na aikin hukunci don kada sabon layi ko wanda aka cire ya ɓace ba tare da an lura ba. -Rasidodin suna rufe workflow ɗinsu ne kawai, ba wallafawa, turawa, ko bayanan cikin gida -na advisory scanner da ya riga ya wanzu ba. Kunna sunayen binciken biyu a cikin dokokin reshe -wani sauyin gudanarwa ne daban; ƙara waɗannan ayyukan ba ya kare reshe da kansa. - -### Kundin binciken tsaye - -Kundin npm-alias mai sigar da aka kayyade da membobin static-scan suna cikin -`config/quality/gate-manifest.json`. Gudanar da `npm run check:gate-manifest` don tabbatar da -sunayen scripts da ainihin umarni bisa `package.json`; ƙari, cirewa da -sauyin umarni suna sa duka local hook da ayyukan rarraba sauyi a CI su gaza. -Alias ba workflow job ba ne, matrix instance ba ne, kuma test case ba ne: ba dole ba ne -a gabatar da waɗannan ƙididdiga kamar za a iya musanya su. +Tsarukan aikin CI da Quality Gates kowannensu yana fitar da tabbataccen hukunci: `Gate / CI` da +`Gate / Quality`. Manufar karɓarsu mai sigar da aka ƙayyade tana lissafa kowane aikin upstream +a matsayin wajibi ko na shawarwari. Dole ne aikin wajibi da ya dace ya yi nasara: sakamakon da +babu shi, aka soke, aka tsallake, yake jiran kammalawa ko ba a san shi ba ba zai iya tabbatar da PASS ba. Ingantaccen +rarrabuwar docs-only ko catalog-only na iya sa wani layin code bai dace ba; +draft PR ba ɗan takarar da aka amince da shi ba ne. Alamar `hotfix` ba ta soke buƙatar hujja. + +Dukkan tsarukan aikin suna rufe PRs da pushes zuwa rassan main/release, manual dispatch da +merge-group events. Push, dispatch da merge-group suna gudanar da cikakken zaɓi. Forks +da merge groups suna amfani da hosted runners don ayyukan da in ba haka ba za su zaɓi self-hosted +runners; dole ne a tabbatar da isasshen hosted capacity kafin rollout. + +Kowane JSON receipt yana tantance SHA da aka checkout, workflow run da attempt. +CLI yana ƙin checkout/event SHA mismatch. Gwaje-gwajen workflow suna ɗaure kasancewa cikin policy +da jerin `needs` na aikin verdict domin sabon lane ko wanda aka cire kada ya ɓace a ɓoye. +Receipts ɗin suna rufe workflow nasu ne kawai, ba publication, deployment, ko internals +na advisory scanner da yake akwai ba. Kunna dukkan check names biyun a cikin branch rules +wani canjin gudanarwa ne na daban; ƙara waɗannan jobs ba ya kare branch da kansa. + +### Jerin static scan + +Jerin npm-alias mai sigar da aka ƙayyade da kasancewar static-scan suna cikin +`config/quality/gate-manifest.json`. Gudanar da `npm run check:gate-manifest` domin tabbatar da +script names da ainihin commands ta hanyar kwatanta su da `package.json`; additions, removals da +command drift suna sa local hook da change-classification jobs a CI su gaza. +Alias ba workflow job, matrix instance ko test case ba ne: kada a gabatar da waɗannan ƙididdiga +kamar suna musanyawa da juna. Yi amfani da `npm run quality:scan -- --list` ko `npm run quality:scan:fast -- --list` -don duba aliases da aka zaɓa ba tare da aiwatar da su ba. Runner yana kiran -npm entrypoint, don haka ana kiyaye runtime ɗinsa (har da Bun inda aka saita shi). -Manifest yana rubuta aliases da ke wajen waɗannan profiles a matsayin waɗanda ake kira dabam, kuma +domin duba aliases da aka zaɓa ba tare da aiwatar da su ba. Runner yana kiran +npm entrypoint, don haka runtime ɗinsa (har da Bun inda aka saita shi) yana nan yadda yake. +Manifest yana rubuta aliases da ke wajen waɗannan profiles a matsayin waɗanda ake kira daban, kuma an hana maintenance commands a cikin read-only scan profiles. Waɗannan profiles suna rufe static scan ne kawai. Ba sa tabbatar da product tests, -coverage, packaging, external checks ko cikakken amincewar fitar da ɗan takara. -Karɓar workflow yana amfani da `config/quality/admission-policy.json` mai alaƙa da +coverage, packaging, external checks ko cikakken release acceptance na ɗan takara. +Workflow admission yana amfani da `config/quality/admission-policy.json` da aka haɗa da `scripts/quality/admission-verdict.mjs`. Release-observer profiles suna ci gaba da kasancewa daban; -a duba applicable checks da receipts nasu daban. Kundin bayani -da ke ƙasa manuni ne, ba hujjar cewa an gudanar da gate ba. +a duba applicable checks da receipts nasu da kansu. Bayanin rubutu +da ke ƙasa madogara ce, ba hujjar cewa an gudanar da gate a zahiri ba. Scripts suna ƙarƙashin `scripts/check/` (policy gates) da `scripts/quality/` (ratchet engine). -Tushen gaskiyar CI shi ne `.github/workflows/ci.yml`. +Madogarar gaskiya ta CI ita ce `.github/workflows/ci.yml`. ### Hanya mai sauri ta Release PR (`quality.yml`) -`.github/workflows/quality.yml` yana ƙara wa CI ƙarfi a kan main/release PRs, turawa zuwa protected-branch, -dispatch da merge groups. PRs suna amfani da fast checks da aka tace bisa path. An cire duplicate build -da aka kashe dindindin; ainihin build/package/boot checks suna nan a CI. +`.github/workflows/quality.yml` yana cika CI a kan main/release PRs, protected-branch +pushes, dispatch da merge groups. PRs suna amfani da fast checks da aka tace bisa path. An cire +duplicate build da aka kashe na dindindin; ainihin build/package/boot checks suna nan a CI. -| Aiki | Iyaka | Mai hana wucewa | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `Docs Gates (fast-path)` | Docs/code PRs; bayanan API docs da docs-all | E | -| `Fast Quality Gates` | Code PRs; static checks, typecheck, dashboard typecheck, impacted unit tests | E | -| `Forgotten sibling tests` | Code PRs; ana bi sawun changed modules zuwa static consumers da candidate sibling tests; ana bayar da rahoton barrel da dynamic-import paths a matsayin advisory diagnostics, tare da referenced allowlist exceptions | **Na shawara** | -| `Vitest (fast-path)` | Code PRs; rukunin fast vitest | E | -| `Unit Tests fast-path` | Code PRs; rukunin unit mai shards 4 | E | -| `No new ESLint warnings` | Code PRs; lint guard mai la'akari da suppressions | E, har da forks | -| `Merge integrity (changelog + generated skills)` | PRs da ba draft ba; changelog da generated skill sync | E, har da forks | +| Aiki | Iyaka | Mai hana ci gaba | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `Docs Gates (fast-path)` | Docs/code PRs; API docs refs da docs-all | Ee | +| `Fast Quality Gates` | Code PRs; static checks, typecheck, dashboard typecheck, impacted unit tests | Ee | +| `Forgotten sibling tests` | Code PRs; changed modules da aka bi zuwa static consumers da candidate sibling tests; barrel da dynamic-import paths ana bayar da rahotonsu a matsayin advisory diagnostics, tare da referenced allowlist exceptions | **Na shawarwari** | +| `Vitest (fast-path)` | Code PRs; fast vitest suite | Ee | +| `Unit Tests fast-path` | Code PRs; 4-shard unit suite | Ee | +| `No new ESLint warnings` | Code PRs; suppressions-aware lint guard | Ee, har da forks | +| `Merge integrity (changelog + generated skills)` | Non-draft PRs; changelog da generated skill sync | Ee, har da forks | #### Rahoton forgotten sibling tests `npm run check:forgotten-sibling-tests` yana sake amfani da import resolver da ke bayan test-impact map. -Ga kowane changed production module, yana bayar da rahoton tabbatattun jerin -`changed module/symbol -> static consumer -> candidate sibling test` lokacin da candidate -test ba ya cikin pull-request diff. Ana adana taƙaitaccen Markdown da sakamakon JSON a matsayin -workflow artifact na `forgotten-sibling-tests` don daidaitawa kafin duk wani blocking rollout. - -Sake-fitarwa na barrel da shigo da kayayyaki masu sauyawa binciken gano matsalar resolution ne kawai; ba sa taɓa haifar da -wani sakamakon da zai hana ci gaba. Keɓantattun abubuwan da aka duba suna cikin -`config/quality/forgotten-sibling-allowlist.json`. Dole ne kowace shigarwa ta ambaci consumer da candidate -test, ta bayar da takamaiman dalili, sannan ta haɗa mahaɗin GitHub issue ko pull request. Shigarwar da ba ta da ingantaccen tsari tana haifar da -rashin amincewa kai tsaye. Keɓantattun abubuwa ba za su iya ɓoye candidate test da aka goge ko diff da ya ƙara `.skip`/`.todo` ba; -raunana assertion da sauran hanyoyin ɓoyewa suna ci gaba da kasancewa ƙarƙashin gate mai zaman kansa kuma mai hana ci gaba na -`check:test-masking`. +Ga kowane changed production module, yana bayar da deterministic +`changed module/symbol -> static consumer -> candidate sibling test` chains idan candidate +test ba ya cikin pull-request diff. Ana adana Markdown summary da JSON result a matsayin +`forgotten-sibling-tests` workflow artifact domin calibration kafin kowane blocking rollout. + +Sake-fitarwa ta barrel da shigo da kayayyaki masu sauyawa binciken warwarewa ne kawai; ba sa taɓa haifar da +wani sakamakon da zai hana ci gaba. Keɓance-keɓancen da aka duba suna cikin +`config/quality/forgotten-sibling-allowlist.json`. Dole ne kowace shigarwa ta ambaci mabukaci da gwajin +ɗan takara, ta bayar da takamaiman dalili, sannan ta haɗa da hanyar haɗin wata matsalar GitHub ko buƙatar haɗa canji. Shigarwar da ba ta da ingantaccen tsari tana haifar da +ƙin amincewa ta tsohuwa. Keɓance-keɓance ba za su iya danne gwajin ɗan takara da aka goge ko diff da ke ƙara `.skip`/`.todo` ba; +raunana assertion da sauran hanyoyin ɓoye matsala suna ci gaba da kasancewa ƙarƙashin shingen +`check:test-masking` mai zaman kansa wanda ke hana ci gaba. ### Aiki: `lint` -Yana gudana a kan kowane PR zuwa `main`. Yana hana merge idan ya gaza. - -| Script (`npm run ...`) | Abin da yake tabbatarwa | Mai hana ci gaba | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Sigar Node.js tana cikin kewayon da ake tallafawa | E | -| `check:cycles` | Shigo da kayayyaki masu zagayawa — dukkan modules na `src/` + `open-sse/` | E | -| `check:route-validation:t06` | Akwai schemas na Zod a kan dukkan routes (manufar Tier 6) | E | -| `check:any-budget:t11` | Adadin `@ts-expect-error // any` bai wuce budget ba (catraca na Tier 11) | E | -| `check:provider-consistency` | Kowane mai samarwa a cikin `providers.ts` yana da shigarwa mai dacewa a cikin `providerRegistry.ts` (haka ma akasin haka, a cikin jerin izini) | Eh | -| `check:model-lifecycle` | Teburan turawa guda uku da ake kula da su da hannu suna ci gaba da daidaituwa da hoton yanayin rayuwa da aka shigar (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ba ya ba wa kowane tsohon id da `REGISTRY` zai iya turawa maki; kowace manufa ta `BUILT_IN_ALIASES` tana cikin `REGISTRY` kuma ba ta cikin hoton tsofaffin id; kowane tsohon id da har yanzu yake cikin `REGISTRY` ana tura shi gaba ko kuma an jera shi a cikin `allowedRetiredInCatalog`; sannan babu tushen ko manufa ta `DEFAULT_DEGRADATION_MAP` da ta bayyana a matsayin tsohuwa a cikin wannan hoton. Wannan ba ya tabbatar da cewa a halin yanzu wata hanyar sama mai aiki tana samar da samfurin. Ba tare da intanet ba — yana kwatantawa da `config/quality/model-lifecycle.json`, wanda ake sabunta shi da hannu ta amfani da `npm run quality:refresh-model-lifecycle` (yana buƙatar hanyar sadarwa; ba a haɗa shi cikin CI ba). `allowedRetiredInCatalog` wata makamar ragewa ce: a ƙara shigarwa kawai tare da batun bin diddigi. | Eh | -| `check:fetch-targets` | Kowane `fetch("/api/...")` a cikin `src/` na ɓangaren abokin hulɗa yana kaiwa ga ainihin `route.ts` | Eh | -| `check:deps` | Duk abubuwan dogaro da za a iya girkawa ta `npm install` a cikin kowane `package.json` da ke ma’ajiyar lambar suna cikin `dependency-allowlist.json`; ana yi wa sabbin fakitoci marasa tsayayyen sigar ko masu kama da sunan wani fakiti alama | Eh | -| `audit:deps` | `npm audit` (tushe + electron) — babu shawarwarin tsaro masu haɗari sosai/masu matuƙar haɗari (yana cakuɗuwa da osv `check:vuln-ratchet`; duba Rationalization Backlog) | Eh | -| `check:lockfile` | Ingancin `package-lock.json` — rajistar https, hash-hash na tabbatar da inganci, babu sauya runduna | Eh | -| `check:licenses` | Jerin izinin lasisin SPDX don abubuwan dogaro na samarwa | Eh | -| `check:tracked-artifacts` | Babu kayan gini / symlink na `node_modules` da aka commit (yana kuma gudana a husky pre-commit; an sauƙaƙa pre-push da gangan — #6716) | Eh | -| `check:ai-attribution` | Babu trailer na AI/bot `Co-Authored-By` ko footer na ƙirƙirawa ta AI a cikin commit, take ko bayanin PR — Ƙa'ida Mai Tsauri #16 (a cikin madaukin fast-gates na `quality.yml` don PR→`release/**` — yana karanta event payload, ba ya yin komai a wajen PR — da kuma mataki na PR-kawai a lint na `ci.yml` don PR→`main`; haka kuma hook na husky `commit-msg`; an yarda da marubuta-tare na ɗan adam; #14436) | -| `check:vitest-exclusions` | Kowane keɓancewar Vitest yana ambaton tracking issue kuma yana bayyana a cikin `config/quality/vitest-exclusions.json` (#13204) | Eh | -| `check:file-size` | Babu fayil ɗin tushe da ya wuce iyakar da aka sa wa kowane extension (ratchet: manyan fayilolin da aka daskare a jerin `frozen`) | Eh | -| `check:error-helper` | Amsoshin kuskure a cikin executors/handlers suna amfani da `buildErrorBody()` / `sanitizeErrorMessage()` (Ƙa'ida Mai Tsauri #12) | Eh | -| `check:migration-numbering` | Fayilolin Migration SQL suna da lambobi a jere, babu gibi ko maimaitawa | E | -| `check:public-creds` | Babu ƙayyadaddun OAuth `client_id`/`client_secret` ko maɓallan Firebase Web a wajen `publicCreds.ts` (Ƙa'ida Mai Tsauri #11) | E | -| `check:db-rules` | Babu ɗanyen SQL a wajen modulolin `src/lib/db/`; babu shigo-da-su-gaba-ɗaya daga `localDb.ts` (Ƙa'idoji Masu Tsauri #2/#5) | E | -| `check:known-symbols` | Masu aiwatar da provider, dabarun routing, da masu fassara da aka yi wa rajista a cikin dispatch tables ɗinsu sun dace da fayilolin da ke kan faifai — babu symbols marasa alaƙa ko waɗanda ba a ayyana ba | E | -| `check:route-guard-membership` | Kowace route da ke ƙaddamar da child process an rarraba ta ta hanyar `isLocalOnlyPath()` (Ƙa'idoji Masu Tsauri #15/#17) | E | -| `check:test-discovery` | Kowane fayil na `*.test.ts` / `*.spec.ts` a cikin repo ana tattara shi ta aƙalla test runner ɗaya (ratchet: jerin fayilolin marasa alaƙa a cikin `test-discovery-baseline.json` zai iya raguwa kawai) | E | -| `check:agent-skills-sync` | Abubuwan agent-skills da aka samar sun yi daidai da kundin tushensu (babu karkacewa) | -| `check:provider-asset-provenance` | Tambura/kadarorin masu samarwa suna ɗauke da shigarwar asali da aka rubuta | -| `lint:json` | Ana iya fassara fayilolin saitin JSON kuma sun cika ƙa'idodin lint na repo | -| `typecheck:core` | Harhada TypeScript ba tare da kurakurai ba (gargaɗin shawarwari kawai) | Eh | -| `typecheck:noimplicit:core` | Tsauraran `noImplicitAny` — don gaba; wuraren kira da yawa da suka riga suka kasance har yanzu suna buƙatar bayanin nau'i | **Na shawara** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` da aka iyakance ga `src/app/(dashboard)/**` (#7033) — zaɓaɓɓen jerin fayiloli 27 da aka yarda da su na `typecheck:core` bai haɗa da kowane dashboard TSX ba, kuma `next build` ma ba ya duba nau'insa (`next.config.mjs` yana saita `ignoreBuildErrors: true`), don haka koma-bayan masu gano suna marasa tushe a can (#6625/#6909) ba su bayyana ga CI ba. Ana kwatanta bambance-bambancen da daskararren ma'aunin asali na adadin kowace fayil/kowace lambar TS (`config/quality/dashboard-typecheck-baseline.json`, irin tsarin tilasta tsufa ɗaya da `check:known-symbols`) — SABABBIN kurakurai kawai da suka zarce adadin da aka kafa a ma'aunin asali ne ke sa ƙofar ta gaza; rage ma'aunin da `--update` idan an gyara kuskuren da ya riga ya kasance. | Eh | +Yana gudana a kan kowace PR zuwa `main`. Yana hana haɗawa idan an samu gazawa. + +| Skrif (`npm run ...`) | Abin da yake tabbatarwa | Mai hana ci gaba | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | Sigar Node.js tana cikin kewayon da ake tallafawa | E | +| `check:cycles` | Shigo da kayayyaki masu zagaye a duk faɗin `src/` + `open-sse/` (wanda ya dogara da AST, an warware `paths` na tsconfig). Bare = shawara kawai, yana jera zagayen. `check:cycles:ratchet` (abin da CI ke gudanarwa) yana hana ci gaba idan adadin ya wuce iyakar `metrics.cycles` a cikin `quality-baseline.json` — a halin yanzu 14, `direction: down`, don haka zai iya raguwa kawai (#15159 G-01/G-02) | E (ratchet) | +| `check:route-validation:t06` | Akwai schemas na Zod a kan dukkan routes (manufar Tier 6) | E | +| `check:any-budget:t11` | Adadin `@ts-expect-error // any` bai wuce kasafin da aka ware ba (catraca na Tier 11) | E | +| `check:provider-consistency` | Kowane mai samarwa a cikin `providers.ts` yana da shigarwar da ta dace a cikin `providerRegistry.ts` (haka kuma akasin haka, a cikin jerin izini) | Ee | +| `check:model-lifecycle` | Teburan sarrafa hanya guda uku da ake kula da su da hannu suna ci gaba da dacewa da hoton yanayin rayuwa da aka ajiye (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ba ya ba wa wani id da aka yi ritaya wanda `REGISTRY` zai iya tura masa hanya maki; kowace manufa ta `BUILT_IN_ALIASES` tana cikin `REGISTRY` kuma ba ta cikin hoton id ɗin da aka yi wa ritaya; kowane id da aka yi wa ritaya amma har yanzu yana cikin `REGISTRY` ana tura shi gaba ko an jera shi a cikin `allowedRetiredInCatalog`; kuma babu tushen ko manufar `DEFAULT_DEGRADATION_MAP` da ta bayyana a matsayin wadda aka yi wa ritaya a cikin wannan hoton. Wannan ba ya tabbatar da cewa a halin yanzu wani tsarin yana samun sabis daga tushen sama mai aiki. Ba tare da intanet ba — yana kwatantawa da `config/quality/model-lifecycle.json`, wanda ake sabunta shi da hannu ta amfani da `npm run quality:refresh-model-lifecycle` (yana buƙatar hanyar sadarwa; ba a haɗa shi da CI ba). `allowedRetiredInCatalog` mataki ne na ragewa a hankali: ƙara shigarwa kawai tare da batun bin diddigi. | Ee | +| `check:fetch-targets` | Kowane `fetch("/api/...")` a cikin `src/` na ɓangaren abokin ciniki yana kaiwa ga ainihin `route.ts` | Ee | +| `check:deps` | Duk abubuwan dogaro da za a iya sakawa ta `npm install` a duk `package.json` da ke cikin ma'ajiyar lambar suna cikin `dependency-allowlist.json`; ana nuna sabbin fakitoci marasa ƙayyadadden siga ko waɗanda aka yi wa slopsquatting | Ee | +| `audit:deps` | `npm audit` (tushen aiki + electron) — babu sanarwar haɗari mai tsanani/matukar tsanani (yana yin ruɓanya da osv `check:vuln-ratchet`; duba Jerin Ayyukan Daidaita Dalilai) | Ee | +| `check:lockfile` | Ingancin `package-lock.json` — wurin rajista na https, hashes na inganci, babu sauya rundunar mai masauki | Ee | +| `check:licenses` | Jerin amincewar lasisin SPDX don abubuwan dogaro na samarwa | Ee | +| `check:tracked-artifacts` | Babu kayan aikin gini / mahaɗan alama na `node_modules` da aka tura (ana kuma gudanar da shi a husky pre-commit; da gangan aka sauƙaƙa pre-push — #6716) | Ee | +| `check:ai-attribution` | Babu ƙarshen `Co-Authored-By` na AI/bot ko bayanin ƙasa na samarwa ta AI a cikin commits, take, ko jikin PR — Ƙa'ida Mai Tsauri #16 (a cikin madaukin ƙofofin sauri na `quality.yml` don PR→`release/**` — yana karanta bayanan event, ba ya yin komai idan ba PR ba ne — da kuma matakin PR-kawai a lint na `ci.yml` don PR→`main`; haka kuma hook ɗin husky na `commit-msg`; an yarda da marubuta-'yan-adam na haɗin gwiwa; #14436) | +| `check:vitest-exclusions` | Kowane keɓancewar Vitest yana ambaton batun sa ido kuma yana bayyana a cikin `config/quality/vitest-exclusions.json` (#13204) | Ee | +| `check:file-size` | Babu fayil ɗin tushe da ya wuce iyakar da aka sa wa kowace extension (ratchet: manyan fayilolin da aka daskarar a jerin `frozen`) | Ee | +| `check:error-helper` | Amsoshin kuskure a cikin executors/handlers suna amfani da `buildErrorBody()` / `sanitizeErrorMessage()` (Ƙa'ida Mai Tsauri #12) | Ee | +| `check:migration-numbering` | Fayilolin SQL na migration suna da lambobi a jere, ba tare da gibi ko maimaitawa ba | Ee | +| `check:public-creds` | Babu OAuth `client_id`/`client_secret` ko maɓallan Firebase Web na zahiri a wajen `publicCreds.ts` (Ƙa'ida Mai Tsauri #11) | Ee | +| `check:db-rules` | Babu ɗanyen SQL a wajen modules na `src/lib/db/`; babu barrel-imports daga `localDb.ts` (Ƙa'idoji Masu Tsauri #2/#5) | Ee | +| `check:known-symbols` | Masu aiwatar da provider, dabarun routing, da translators da aka yi wa rajista a cikin dispatch tables ɗinsu sun dace da fayilolin da ke kan disk — babu symbols marasa alaƙa ko waɗanda ba a ayyana ba | Ee | +| `check:route-guard-membership` | Kowace route da ke ƙaddamar da child process an rarraba ta da `isLocalOnlyPath()` (Ƙa'idoji Masu Tsauri #15/#17) | Ee | +| `check:test-discovery` | Kowane fayil na `*.test.ts` / `*.spec.ts` a cikin repo yana tattaruwa ta aƙalla test runner guda ɗaya (ratchet: jerin marasa alaƙa a cikin `test-discovery-baseline.json` zai iya raguwa kawai) | Ee | +| `check:agent-skills-sync` | Abubuwan agent-skills da aka samar sun yi daidai da kundin tushensu (babu sauyi marar izini) | +| `check:provider-asset-provenance` | Tambura/kadarorin masu samarwa suna ɗauke da shigarwar bayanin asalinsu da aka rubuta | +| `lint:json` | Fayilolin saitin JSON suna iya parse kuma suna bin ƙa'idodin lint na repo | +| `typecheck:core` | Harhada TypeScript ba tare da kurakurai ba (gargaɗin shawarwari kawai) | Ee | +| `typecheck:noimplicit:core` | Tsauraran `noImplicitAny` — don ci gaba ne; wuraren kira da yawa da suka riga suka kasance har yanzu suna buƙatar annotations | **Na shawara** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` da aka taƙaita zuwa `src/app/(dashboard)/**` (#7033) — jerin fayiloli 27 da `typecheck:core` ya ware bai haɗa da kowane dashboard TSX ba, sannan `next build` ma ba ya yin type-check ɗinsa (`next.config.mjs` yana saita `ignoreBuildErrors: true`), don haka koma-bayan orphaned-identifier a wurin (#6625/#6909) ba su bayyana ga CI ba. Ana kwatanta bambance-bambancen da baseline daskararre na adadin kurakurai na kowane fayil/kowane lambar TS (`config/quality/dashboard-typecheck-baseline.json`, irin tsarin tilasta sabunta bayanai na `check:known-symbols`) — sabbin kurakurai KAWAI da suka zarce adadin da ke cikin baseline ne ke sa matakin ya gaza; rage baseline ɗin a hankali da `--update` idan an gyara kuskuren da ya riga ya kasance. | Ee | ### Aiki: `quality-gate` -Yana gudana bayan `test-coverage`. Yana hana haɗewa idan an samu gazawa. +Yana gudana bayan `test-coverage`. Yana hana merge idan ya gaza. -| Script | Abin da yake tabbatarwa | Mai toshewa | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `quality:collect` | Yana fitar da `quality-metrics.json` (adadin gargadin ESLint, ɗaukar gwaji daga rahoton shard da aka haɗe) | Eh (yana gaban ratchet) | -| `quality:ratchet` | Kowace ma'auni a cikin `quality-baseline.json` ba ta taɓarɓare ba (gargadin ESLint ≤ baseline; ɗaukar gwaji ≥ baseline) | Eh | -| `check:duplication` | Maimaituwar lamba (jscpd@4) ba ta wuce baseline da ke cikin `quality-baseline.json` ba | Eh | -| `check:complexity` | Rikitarwar cyclomatic a matakin fayil ba ta wuce iyakar da aka sa ba (ainihin ESLint `complexity` + `max-lines-per-function`) | Eh | -| `check:cognitive-complexity` | Ratchet na rikitarwar fahimta (`eslint-plugin-sonarjs`) — zagayen ESLint na daban; CI yana gudanar da duka biyun a haɗe a matsayin mataki guda na `check:complexity-ratchets` | Eh | -| `check:dead-code` | Ratchet na exports / fayilolin da ba a amfani da su (knip) ba ya taɓarɓarewa idan aka kwatanta da baseline | Eh | -| `check:compression-budget` | Kasafin ma'aunin gwajin matsawa — dole ne mafi ƙarancin adana token na kowane engine kada ya taɓarɓare | Eh | -| `check:type-coverage` | Ratchet na kason da aka sanya wa nau'i (`type-coverage`) ba ya taɓarɓarewa; ya kusan maye gurbin `typecheck:noimplicit:core` gaba ɗaya | Eh | -| `check:codeql-ratchet` | Adadin buɗaɗɗun faɗakarwar CodeQL ba ya taɓarɓarewa (yana karantawa ta `gh api`; yana tsallakewa cikin aminci idan babu token) — don jadawalin sabuntawa da kunnawa da hannu: duba "Ratchet na CodeQL" a ƙasa | Eh | +| Script | Abin da yake tantancewa | Toshewa | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | +| `quality:collect` | Yana fitar da `quality-metrics.json` (adadin gargadin ESLint, coverage daga rahoton shard da aka haɗe) | Eh (kafin ratchet) | +| `quality:ratchet` | Kowace metric a cikin `quality-baseline.json` ba ta taɓarɓare ba (gargadin ESLint ≤ baseline; coverage ≥ baseline) | Eh | +| `check:duplication` | Maimaita lamba (jscpd@4) bai wuce baseline da ke cikin `quality-baseline.json` ba | Eh | +| `check:complexity` | Cyclomatic complexity na matakin fayil bai wuce iyaka ba (ainihin ESLint `complexity` + `max-lines-per-function`) | Eh | +| `check:cognitive-complexity` | Ratchet na cognitive complexity (`eslint-plugin-sonarjs`) — gwajin ESLint na daban; CI yana gudanar da duka biyun a haɗe a matsayin mataki guda na `check:complexity-ratchets` | Eh | +| `check:dead-code` | Ratchet na exports / fayilolin da ba a amfani da su (knip) bai taɓarɓare idan aka kwatanta da baseline ba | Eh | +| `check:compression-budget` | Kasafin benchmark na matsewa — mafi ƙarancin adana tokens na kowane engine kada ya taɓarɓare | Eh | +| `check:type-coverage` | Ratchet na yawan kaso mai type (`type-coverage`) bai taɓarɓare ba; galibi yana maye gurbin `typecheck:noimplicit:core` | Eh | +| `check:codeql-ratchet` | Adadin faɗakarwar CodeQL da suke buɗe bai taɓarɓare ba (yana karantawa ta `gh api`; yana tsallakewa cikin sauƙi idan babu token) — don jadawalin sabuntawa da kunnawa da hannu: duba "CodeQL ratchet" a ƙasa | Eh | ### Aiki: `quality-extended` -Dukkan aikin na ba da shawara ne (`continue-on-error: true`). Ratchets masu tushen npm suna aiki +Dukkan aikin na shawarwari ne (`continue-on-error: true`). Ratchets masu amfani da npm suna gudana da gaske; external scanners suna shigarwa ta `gh release download` kuma suna tsallake kansu (exit 0) idan har yanzu babu binary. -| Script | Abin da yake tabbatarwa | Mai toshewa | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | -| `check:circular-deps` | Babu circular dependencies (dpdm) | **Na shawara** | -| `check:bundle-size` | Girman bundle bai wuce iyakar da aka sa ba | **Na shawara** | -| `check:secrets` | Binciken sirrika (gitleaks) — yana tsallakewa idan babu binary | **Na shawara** | -| `check:vuln-ratchet` | Raunukan tsaro na dependencies (osv-scanner) ba sa taɓarɓarewa — yana tsallakewa idan babu binary | **Na shawara** | -| `check:workflows` | Lint na workflow (actionlint + zizmor); scanners da suka ɓace/lalace, rahotanni marasa inganci ko rashin baseline na ratchet suna haifar da gazawar INCOMPLETE. Ingantattun sakamakon bincike suna bin ƙa'idar strict/advisory/ratchet da aka zaɓa | Ana buƙatar aiwatarwa; ratchet na zizmor yana toshewa a CI | -| `check:openapi-breaking` | Sauye-sauye masu karya yarjejeniyar API ta jama'a (`openapi.yaml`) idan aka kwatanta da base branch (oasdiff) — yana fitar da `openapiBreaking=N`; yana tsallakewa idan babu oasdiff ko ba za a iya warware base spec ba | **Na shawara** | +| Script | Abin da yake tantancewa | Toshewa | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| `check:circular-deps` | Babu circular dependencies (dpdm) | **Na shawarwari** | +| `check:bundle-size` | Girman bundle bai wuce iyaka ba | **Na shawarwari** | +| `check:secrets` | Binciken sirrika (gitleaks) — yana tsallakewa idan babu binary | **Na shawarwari** | +| `check:vuln-ratchet` | Raunin tsaro na dependencies (osv-scanner) bai taɓarɓare ba — yana tsallakewa idan babu binary | **Na shawarwari** | +| `check:workflows` | Lint na workflow (actionlint + zizmor); scanners da suka ɓace/lalace, rahotanni marasa inganci ko rashin ratchet baseline suna sa gazawa a matsayin INCOMPLETE. Sakamakon bincike masu inganci suna bin manufofin strict/advisory/ratchet da aka zaɓa | Ana buƙatar aiwatarwa; zizmor ratchet yana toshewa a CI | +| `check:openapi-breaking` | Sauye-sauyen da ke karya public API contract (`openapi.yaml`) idan aka kwatanta da base branch (oasdiff) — yana fitar da `openapiBreaking=N`; yana tsallakewa idan babu oasdiff ko ba za a iya warware base spec ba | **Na shawarwari** | ### Aiki: `docs-sync-strict` -Yana gudana a kan kowane PR zuwa `main`. Yana hana merge idan an samu gazawa. - -| Skrif | Abin da yake tabbatarwa | Mai hana ci gaba | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `check:docs-all` | Babbar ƙofa da ke gudanar da ƙananan ƙofofi 6 da ke ƙasa ɗaya bayan ɗaya | Ee | -| ↳ `check:docs-sync` | Daidaiton sigar CHANGELOG / OpenAPI / llm.txt | Ee | -| ↳ `check:docs-counts` | Ƙididdiga a cikin rubutu (adadin masu samarwa, adadin ƙaura, da sauransu) suna cikin iyakar ratchet ta ainihin ƙididdigar | Ee | -| ↳ `check:env-doc-sync` | Kowace env var da ke cikin `.env.example` tana da bayanai a teburin takardu, haka kuma akasin haka | Ee | -| ↳ `check:deprecated-versions` | Babu tsoffin sigogin da aka daina amfani da su a cikin takardu | Ee | -| ↳ `check:doc-links` | Mahaɗan markdown na ciki a cikin takardu suna kaiwa ga fayiloli na gaske (tsarin `[text]`/`(path)`) | Ee | -| ↳ `check:fabricated-docs` | Routes, env vars, umarnin CLI, sunayen hook, da file paths da aka ambata a takardu suna cikin codebase. Ƙofa mai tsauri ta `--strict`; gazawa mai laushi ba tare da wannan flag ba. | Ee (ta `--strict` a CI) | -| `check:cli-i18n` | Kirtanin umarnin CLI suna cikin dukkan fayilolin locale na i18n | Ee | -| `check:openapi-coverage` | Ƙayyadaddun OpenAPI sun ƙunshi aƙalla mafi ƙarancin matakin routes na gaske da aka sa wa ratchet | Ee | -| `check:openapi-security-tiers` | Bayanan matakan tsaro a cikin `openapi.yaml` sun yi daidai da rarrabewar `routeGuard.ts` | **Na shawara** | -| `check:openapi-routes` | Kowace path a cikin `openapi.yaml` tana kaiwa ga `route.ts` na gaske (hana ƙirƙirar bayanan bogi) | Ee | -| `check:docs-symbols` | Kowace manuniya ta `/api/...` a cikin `docs/**/*.md` tana kaiwa ga `route.ts` na gaske (hana ƙirƙirar bayanan bogi) | Ee | -| `i18n translation drift` | Maɓallan da ba a fassara ba a cikin fayilolin locale na i18n — gargaɗi kawai | **Na shawara** | +Yana gudana a kan kowane PR zuwa `main`. Yana hana haɗawa idan an samu gazawa. + +| Script | Abin da yake tantancewa | Mai hana ci gaba | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `check:docs-all` | Babban ƙofa da ke gudanar da ƙananan ƙofofi 6 da ke ƙasa ɗaya bayan ɗaya | Ee | +| ↳ `check:docs-sync` | Daidaiton sigar CHANGELOG / OpenAPI / llm.txt | Ee | +| ↳ `check:docs-counts` | Ƙididdiga a cikin rubutu (yawan masu samarwa, yawan ƙaura, da sauransu) suna cikin iyakar ratchet ta ainihin ƙididdiga | Ee | +| ↳ `check:env-doc-sync` | Kowace env var a cikin `.env.example` an rubuta bayaninta a teburin takardu, kuma haka ma akasin haka | Ee | +| ↳ `check:deprecated-versions` | Babu tsofaffin kirtanin siga da aka daina amfani da su a cikin takardu | Ee | +| ↳ `check:doc-links` | Mahaɗan markdown na cikin gida a takardu suna kaiwa ga fayiloli na ainihi (tsarin `[text]`/`(path)`) | Ee | +| ↳ `check:fabricated-docs` | Routes, env vars, umarnin CLI, sunayen hook, da hanyoyin fayil da aka ambata a takardu suna cikin codebase. Ƙofa mai tsauri ta `--strict`; gazawa mai sauƙi ba tare da flag ba. | Ee (ta `--strict` a CI) | +| `check:cli-i18n` | Kirtanin umarnin CLI suna cikin duk fayilolin locale na i18n | Ee | +| `check:openapi-coverage` | Bayanin OpenAPI ya ƙunshi aƙalla mafi ƙarancin adadin routes na ainihi da aka ƙayyade ta ratchet | Ee | +| `check:openapi-security-tiers` | Bayanan matakan tsaro a cikin `openapi.yaml` sun yi daidai da rabe-raben `routeGuard.ts` | **Na shawara** | +| `check:openapi-routes` | Kowace path a cikin `openapi.yaml` tana kaiwa ga ainihin `route.ts` (hana ƙirƙirar bayanan bogi) | Ee | +| `check:docs-symbols` | Kowace maƙalar `/api/...` a cikin `docs/**/*.md` tana kaiwa ga ainihin `route.ts` (hana ƙirƙirar bayanan bogi) | Ee | +| `i18n translation drift` | Keys da ba a fassara ba a cikin fayilolin locale na i18n — gargadi kawai | **Na shawara** | ### Aiki: `i18n-ui-coverage` -| Skrif | Abin da yake tabbatarwa | Mai hana ci gaba | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (a ciki) | Rufin maɓallan i18n na UI ya kai ≥ 65% | Ee | -| `check-ui-value-drift` (a ciki) | Sake rubuta **ƙima** ta Turanci ba ya barin wata tsohuwar fassara a baya | Ee | -| `check-new-key-coverage` (a ciki) | An fassara **sabon** maɓallin Turanci a kowane locale — ana ƙin alamar `__MISSING__:` | Ee | -| `check-translation-ratio` | Rabon ainihin fassara na kowane locale (daidai-da-Turanci / placeholder / abubuwan da suka ɓace a wajen allowlist) ba dole ya wuce `config/quality/i18n-translation-baseline.json` + slack ba | **Na shawara** | +| Script | Abin da yake tantancewa | Mai hana ci gaba | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `check-ui-keys-coverage` (inline) | Rufin key na i18n na UI ya kai ≥ 65% | Ee | +| `check-ui-value-drift` (inline) | Sake rubuta **value** na Turanci ba ya barin wani tsohon fassara a baya | Ee | +| `check-new-key-coverage` (inline) | An fassara **sabon** key na Turanci a kowane locale — ana ƙin alamar `__MISSING__:` | Ee | +| `check-translation-ratio` | Rabon fassara na ainihi ga kowane locale (daidai da Turanci / placeholder / abubuwan da suka ɓace waɗanda ba sa cikin allowlist) kada ya wuce `config/quality/i18n-translation-baseline.json` + slack | **Na shawara** | Yana buƙatar `fetch-depth: 0` — ƙofar value-drift tana kwatanta bambancin `en.json` da merge base. #### `check-ui-value-drift` — ƙofar tsohuwar fassara -Tana gano koma-bayan i18n guda ɗaya da sauran ƙofofi ba za su iya gani ta tsarin su ba: ana sake rubuta wata ƙima ta Turanci +Tana gano matsalar koma-bayan i18n guda ɗaya da sauran ƙofofi ba za su iya gani ta fuskar tsari ba: ana sake rubuta value na Turanci, amma fassarorin da aka samo daga Turancin _da ya gabata_ suna nan, don haka -masu amfani da ba Turanci ba suna ci gaba da karanta rubutu mai nuna tabbaci amma wanda yanzu ya zama kuskure. - -Wannan ya taɓa shiga samfurin gaske. An sake rubuta `oauthModal.googleOAuthWarning` lokacin da -mataimakin shiga na Antigravity ya iso (#5203); **39 daga cikin locales 43** sun ci gaba da riƙe rubutun da ke gaya wa masu gudanarwa su "kwafi -cikakken URL sannan su liƙa shi a ƙasa" — tsarin da ba zai iya kammaluwa ga wannan provider ba. Ba a -lura da shi ba sai #8463 saboda: - -- `sync-ui-keys` yana cike maɓallan da suka **ɓace** ne kawai, ba waɗanda suka zama **tsofaffi** ba; -- `check-ui-keys-coverage` yana ƙirga _kasancewar_ maɓalli, don haka tsohuwar fassara tana samun maki a matsayin wadda aka rufe; -- `check-translation-drift` yana bibiyar kwafin takardu na `docs/i18n//**.md` — - ba ya taɓa karanta `src/i18n/messages/*.json`. Yana hana ci gaba a aikin `docs-sync-strict` tun daga - sake daidaitawar 2026-09: gyara babban takarda → `npm run i18n:run -- --files=` (a matakin sashe, mara tsada). - -**Yana lura da diff, ba ya dogaro da baseline.** Yana kwatanta `en.json` a merge base da -working tree; ga kowane key da ƙimar Turancinsa ta canza, duk locale da har yanzu yake riƙe da -fassarar da ba a taɓa ba, ta tsufa. Wannan da gangan yana **daskare bashin da ya riga ya kasance** — diff -ba zai iya bayyana daga wane tsohon rubutun Turanci fassarar da ta daɗe ta samo asali ba, don haka gate ɗin yana tantance -abin da canjin yanzu ya taɓa kawai. Madadin (baseline na hash ga kowane key) zai buƙaci -generated file mai kusan 600 KB, wanda ya ninka baseline mafi girma da ake da shi sau 3, yana canzawa a kowane i18n PR. +masu amfani da ba sa amfani da Turanci suna ci gaba da karanta rubutu mai cike da tabbaci amma wanda yanzu ba daidai ba ne. + +Wannan ya taɓa fitowa a zahiri. An sake rubuta `oauthModal.googleOAuthWarning` lokacin da aka ƙara +mataimakin shiga na Antigravity (#5203); **39 daga cikin locales 43** sun ci gaba da riƙe rubutun da ke gaya wa masu gudanarwa su "kwafi +cikakken URL su liƙa shi a ƙasa" — tsarin da ba zai iya kammaluwa ga wannan provider ba. Ba a +lura da shi ba har sai #8463 saboda: + +- `sync-ui-keys` yana cike keys ne kawai idan **ba su nan**, ba waɗanda suka zama **tsofaffi** ba; +- `check-ui-keys-coverage` yana ƙirga _kasancewar_ key, don haka ana ɗaukar tsohuwar fassara a matsayin wadda aka rufe; +- `check-translation-drift` yana bibiyar madubin takardu na `docs/i18n//**.md` — + ba ya taɓa karanta `src/i18n/messages/*.json`. Yana hana ci gaba a aikin `docs-sync-strict` tun bayan + sake daidaitawar 2026-09: gyara babban takarda → `npm run i18n:run -- --files=` (a matakin sashe, mai sauƙin aiwatarwa). + +**Mai lura da diff, ba mai dogaro da baseline ba.** Yana kwatanta `en.json` a merge base da working tree; ga kowane key da ƙimar Turancinsa ta canza, duk locale da har yanzu yake riƙe da fassarar da ba a taɓa ba ya zama tsohon yayi. Wannan da gangan yana **daskarar da bashin da ya riga ya kasance** — diff ba zai iya bayyana daga wane tsohon rubutun Turanci wata fassara da ta daɗe ta fito ba, don haka gate ɗin yana tantance abin da canjin yanzu ya taɓa ne kawai. Madadin (baseline na hash ga kowane key) zai buƙaci generated file mai girman kusan 600 KB, wanda ya ninka baseline mafi girma da ake da shi sau 3, kuma yana canzawa a kowane i18n PR. Akwai hanyoyi biyu na cika wannan: 1. sabunta fassarorin da abin ya shafa, ko -2. saita su zuwa `__MISSING__:` — runtime zai gabatar da ingantaccen Turancin +2. saita su zuwa `__MISSING__:` — daga nan runtime zai nuna ingantaccen Turancin (`src/i18n/request.ts::deepMergeFallback`, #7258), sannan key ɗin ya shiga jerin jiran fassara. -Idan **ma’anar** string ɗin ta canza, a fi son **sake wa key suna**: sabon key ba zai iya gaji -fassarar da ta tsufa ba. Wannan shi ne tsarin da #8463 ya yi amfani da shi. +Idan **ma’anar** string ɗin ta canza, ya fi kyau a **sake wa key suna**: sabon key ba zai iya gado tsohuwar fassara ba. Wannan shi ne tsarin da #8463 ya yi amfani da shi. ```bash -npm run i18n:check-value-drift # tsaurara (abin da CI ke gudanarwa) -npm run i18n:check-value-drift:warn # bayar da rahoto kawai +npm run i18n:check-value-drift # mai tsauri (abin da CI ke gudanarwa) +npm run i18n:check-value-drift:warn # rahoto kawai BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Yana fita da 0 tare da `SKIP reason=base-unresolved` idan ba za a iya karanta base catalog ba (shallow -clone ba tare da base ref ba), daidai da yadda `check-openapi-breaking` yake yi. +Yana fita da 0 tare da `SKIP reason=base-unresolved` idan ba za a iya karanta base catalog ba (shallow clone ba tare da base ref ba), daidai da halayen `check-openapi-breaking`. -### Job: `i18n` +### Aiki: `i18n` -Cikakken matrix na tabbatar da i18n (job ɗaya ga kowane locale). Dukkan job ɗin na shawara ne. +Cikakken matrix na tantance i18n (aiki ɗaya ga kowane locale). Dukkan aikin na ba da shawara ne kawai. -| Script | Abin da yake tabbatarwa | Toshewa | -| ------------------------------- | ------------------------------ | --------------------------------------------------------------- | -| `validate_translation.py quick` | Cikar fassara ga kowane locale | **Na shawara** (`continue-on-error: true` a kan dukkan job ɗin) | +| Script | Abin da yake tantancewa | Toshewa | +| ------------------------------- | ------------------------------ | ------------------------------------------------------ | +| `validate_translation.py quick` | Cikar fassara ga kowane locale | **Na shawara** (`continue-on-error: true` a duk aikin) | -### Job: `pr-test-policy` +### Aiki: `pr-test-policy` Yana gudana a kan pull requests kawai. -| Script | Abin da yake tabbatarwa | Toshewa | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `check:pr-test-policy` | PRs da suka canza production code a cikin `src/`, `open-sse/`, `electron/`, ko `bin/` dole ne su haɗa ko su sabunta tests (Hard Rule #8) | Eh | -| `check:test-masking` | Test files da aka canza ba sa rage jimillar adadin assert ko ƙara tautologies na `assert.ok(true)` | Eh | -| `check:pr-evidence` | Jikin PR ya ambaci shaidar test/VPS don canjin (yana sarrafa Hard Rule #18 ta hanyar binciken rubutun PR — mai rauni, duba Backlog) | Eh | +| Script | Abin da yake tantancewa | Toshewa | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `check:pr-test-policy` | PRs da suka canza production code a `src/`, `open-sse/`, `electron/`, ko `bin/` dole ne su haɗa ko su sabunta gwaje-gwaje (Doka Mai Tsauri #8) | Eh | +| `check:test-masking` | Test files da aka canza ba sa rage jimillar adadin assert ko ƙara tautologies na `assert.ok(true)` | Eh | +| `check:pr-evidence` | Jikin PR yana ambaton shaidar test/VPS ta canjin (yana sarrafa Doka Mai Tsauri #18 ta hanyar binciken rubutun PR — mai rauni, duba Backlog) | Eh | -### Job: `test-vitest` +### Aiki: `test-vitest` Yana gudana bayan `build`. Yana hana merge idan ya gaza. -| Suite | Abin da yake tabbatarwa | Toshewa | -| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (tools 110), autoCombo, cache — vitest runner | Eh | -| `test:vitest:ui` | Tests na UI components — vitest runner | **Yana toshewa** — an cire gazawar da ta riga ta kasance a sarari cikin `vitest.config.ts`; sabbin gazawa suna sa job ɗin ya gaza | +| Suite | Abin da yake tantancewa | Toshewa | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP server (tools 110), autoCombo, cache — vitest runner | Eh | +| `test:vitest:ui` | Gwaje-gwajen UI component — vitest runner | **Mai toshewa** — an cire gazawar da ta riga ta kasance a fili a `vitest.config.ts`; sabbin gazawa suna sa aikin ya gaza | ### Nightly workflows (masu jadawali, na shawara) -Waɗannan suna gudana bisa cron schedule (da `workflow_dispatch`), ba sa gudana a kan PRs. Dukkansu na shawara ne. +Waɗannan suna gudana bisa cron schedule (da `workflow_dispatch`), ba sa taɓa gudana a kan PRs. Dukkansu na shawara ne kawai. -| Workflow | Abin da yake tabbatarwa | Toshewa | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | fast-check property tests tare da random seed + adadin run mai yawa | **Na shawara** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **Na shawara** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (ana tsallake su idan babu provider secret) | **Na shawara** | -| `nightly-schemathesis` | OpenAPI contract fuzzing (schemathesis) a kan OmniRoute mai aiki ta amfani da `docs/openapi.yaml` — yana fito da keta spec / 500s da ba a sarrafa ba (Mataki 8 B.4) | **Na shawara** | -| `nightly-mutation` | Stryker mutation-testing score a kan fast unit lane — mutants da suka tsira suna nuna asserts marasa ƙarfi | **Na shawara** | -| `nightly-compat` | Matrix na dacewar Node engine a duk faɗin ranges na `engines.node` da ake tallafawa | **Na shawara** | +| Workflow | Abin da yake tantancewa | Toshewa | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | fast-check property tests tare da random seed + adadin runs mai yawa | **Na shawara** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **Na shawara** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (ana tsallake su idan babu provider secret) | **Na shawara** | +| `nightly-schemathesis` | OpenAPI contract fuzzing (schemathesis) a kan OmniRoute mai aiki ta amfani da `docs/openapi.yaml` — yana fito da take-taken spec / 500s da ba a sarrafa ba (Mataki 8 B.4) | **Na shawara** | +| `nightly-mutation` | Stryker mutation-testing score a kan fast unit lane — mutants da suka tsira suna bayyana assert marasa ƙarfi | **Na shawara** | +| `nightly-compat` | Matrix na dacewar Node engine a duk ranges na `engines.node` da ake tallafawa | **Na shawara** | --- @@ -536,43 +529,43 @@ kuskuren haɗi ne kawai kuma ba ta taɓa karya zaman aiki ba. --- -## Jerin Ayyukan Da Aka Jinkirta Don Daidaitawa (bita ta ROI — Mataki na 9 Zango na 3) +## Jerin Ayyukan Da Aka Jira Don Daidaitawa (bitar ROI — Mataki 9 Zagaye 3) An daidaita wannan kundin da `ci.yml` a ranar 2026-06-17 (sigar da ta gabata ba ta haɗa da `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` ba). Bitar ROI ta jerin da aka daidaita -ta gano waɗannan abubuwan da za a iya sauƙaƙawa. **Haɗe-haɗen sauye-sauyen CI ne na -kai-tsaye; sauya matsayi/cirewa kuwa shawarwarin manufofi ne da aka keɓe wa mai gudanarwa.** Har yanzu ba a -aiwatar da komai daga cikin abubuwan da ke ƙasa ba. +`check:codeql-ratchet`, `check:pr-evidence` ba). Bitar ROI kan jerin da aka daidaita +ta gano waɗannan ayyukan da za a iya sauƙaƙawa. **Haɗe-haɗen sauye-sauyen CI ne na +inji kawai; sauya matsayi/cirewa kuwa shawarwarin manufofi ne da aka keɓe wa mai gudanarwa.** Babu wani abu a ƙasa +da aka fara aiwatarwa tukuna. -**Abubuwan da su ma ba a rubuta bayaninsu a sama ba** (na shawara, ƙarancin sigina): aikin `docs-lint` -(markdownlint + Vale, gaba ɗaya aikin yana da `continue-on-error`) da kuma ayyukan bincike masu zaman kansu +**Haka kuma ba a rubuta bayaninsu a sama ba** (na shawara, alama mai rauni): aikin `docs-lint` +(markdownlint + Vale, dukan aikin yana da `continue-on-error`) da kuma workflows na na'urorin dubawa masu zaman kansu `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` yana cikin -`quality-baseline.json` amma ba a haɗa shi da wani ratchet mai toshewa a `ci.yml` ba — a halin yanzu ma'aunin -ba shi da abin da yake sarrafawa. +`quality-baseline.json` amma ba a haɗa shi da ratchet mai toshewa a `ci.yml` ba — a halin yanzu +ma'aunin ba shi da abin da yake sarrafawa. -### Haɗewa / cire maimaitawa (na kai-tsaye, ƙarancin haɗari) +### Haɗewa / cire maimaituwa (na inji, haɗari kaɗan) -An tabbatar da kowane ɗan takara ta hanyar kwatanta shi da yanayin gate na ainihi a ranar 2026-06-17 (amince amma a tabbatar); -haɗe-haɗe da dama da suka yi kama da “bayyane” sun zama suna ɓoye bashin fasaha kuma **ba** sauye-sauye ne masu sauƙin maye gurbi ba. +An tabbatar da kowane zaɓi bisa halin gate na ainihi a ranar 2026-06-17 (amince amma a tabbatar); +haɗe-haɗe da dama da suka yi kama da “bayyane” sun ɓoye bashi, don haka **ba** za a iya maye gurbinsu kai tsaye cikin sauƙi ba. -- **`check:docs-sync` yana gudana sau biyu** — shi kaɗai a aikin `lint`, sannan kuma a cikin `check:docs-all` (`docs-sync-strict`) da husky pre-commit hook. ✅ **AN KAMMALA** — an cire kiran da ke gudana shi kaɗai na `lint`. -- **Binciken CVE** — ❌ **BA haɗewa ce mai sauƙi ba.** `audit:deps` yana kasa kai-tsaye idan aka samu kowace CVE mai high/critical; `check:vuln-ratchet` (osv) kuwa yana kasa ne kawai idan an sami _koma-baya_ idan aka kwatanta da baseline (a halin yanzu 1 MODERATE). Ma'anarsu ta bambanta — cire `audit:deps` zai kawar da cikakken gate na high/critical. A bar dukansu. -- **Gano zagaye** — ❌ **BA haɗewa ce mai sauƙi ba.** `check:circular-deps` (dpdm) yana bayar da rahoton **zagaye 91** (shi ya sa yake na shawara); ba za a iya mayar da shi mai toshewa ba sai an fara warware su, kuma iyakar abin da yake dubawa ta fi ta koren `check:cycles` da aka zaɓa da kyau faɗi. A bar `check:cycles` yana toshewa; warware zagayen dpdm guda 91 wani aikin backlog ne na daban. -- **Sarƙaƙƙiya** — ✅ **AN KAMMALA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): zagayen ESLint guda ɗaya, yana ƙirgawa bisa ruleId domin cyclomatic+max-lines da cognitive baselines su ci gaba da kasancewa masu zaman kansu; `check:complexity` / `check:cognitive-complexity` na ɗaiɗaiku sun ci gaba da kasancewa don `--update` na cikin gida. -- **Kariya daga ƙagaggen `/api`** — ✅ **AN KAMMALA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): kundin FS guda ɗaya na `src/app/api`, openapi-routes + docs-symbols har yanzu suna bayar da rahoto daban-daban; na ɗaiɗaiku sun ci gaba da kasancewa don gudanarwa a cikin gida. -- **`check:node-runtime` yana gudana a ayyuka 11** — ⚠️ **ƙarancin ROI.** Kowannensu yana kan runner daban kuma binciken bai kai 1s ba; jimillar tanadi ~10s, amma hakan zai sa a rasa kariya mai sauƙi a kowane aiki. Bai cancanci hargitsin sauyin ba. -- **`typecheck:noimplicit:core` a CI lint** — ✅ **an cire daga aikin lint** (a baya na shawara ne da `continue-on-error`); shimfidar nau'ikan da ke toshewa ita ce `typecheck:core` + `check:type-coverage`. An bar script na cikin gida. +- **`check:docs-sync` yana gudana sau biyu** — shi kaɗai a aikin `lint`, sannan kuma a cikin `check:docs-all` (`docs-sync-strict`) da husky pre-commit hook. ✅ **AN KAMMALA** — an cire kiran da ke gudana shi kaɗai daga `lint`. +- **Binciken CVE** — ❌ **BA haɗewa ce mai sauƙi ba.** `audit:deps` yana gaza kai tsaye idan ya ga kowane CVE mai haɗari/babban haɗari; `check:vuln-ratchet` (osv) kuwa yana gaza ne kawai idan an samu _taɓarɓarewa_ idan aka kwatanta da baseline (a halin yanzu 1 MODERATE). Ma'anoninsu sun bambanta — cire `audit:deps` zai kawar da cikakken gate na haɗari/babban haɗari. A bar su duka. +- **Gano madauwari** — ✅ **AN KAMMALA** (#15159 G-01/G-02). Tsohon rubutun nan ya kira `check:cycles` gate “mai kore, da aka zaɓa a tsanake” kuma ya ba da hujjar ci gaba da sanya shi mai toshewa saboda `check:circular-deps` (dpdm) ya bayar da rahoton madauwari 91. Wannan koren sakamakon **koren ƙarya ne**: `check:cycles` ya binciki ƙananan kundin adireshi 5 (fayiloli 450), ya dace da static `import|export … from` kawai, sannan ya yi watsi da duk wani specifier na `@/` da `@omniroute/open-sse/`, don haka bai iya ganin madauwuran dynamic-import + alias da suka mamaye repo ba. An gyara: yanzu gate ɗin yana ratsa `src` + `open-sse` (fayiloli 5023), yana tattara specifiers daga TypeScript AST (don haka `import("…")` yana ƙidayuwa amma `typeof import("…")` da ke matsayin type ba ya ƙidayuwa), kuma yana warware tsconfig `paths`. Yana gano madauwari **14**, ba 0 ba. Saboda ba za a iya gyara madauwari 14 da suka riga suka kasance a cikin gate PR ba, yanzu `check:cycles` ya zama **ratchet** (`--ratchet`, iyaka `metrics.cycles.value = 14` a cikin `quality-baseline.json`, `direction: down`) — yana toshe duk wata _taɓarɓarewa_ kuma adadin zai iya raguwa ne kawai. CI yana gudanar da `npm run check:cycles:ratchet`. Rage adadin a hankali yana tafiya tare da **A-01**. `check:circular-deps` (dpdm) zai ci gaba da zama na shawara a matsayin ra'ayi na biyu mai faɗi. +- **Sarƙaƙiya** — ✅ **AN KAMMALA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): zagayen ESLint guda ɗaya, yana ƙirga bisa ruleId domin cyclomatic+max-lines da cognitive baselines su ci gaba da kasancewa masu zaman kansu; `check:complexity` / `check:cognitive-complexity` na ɗaiɗaiku suna nan don `--update` na gida. +- **Hana ruɗin `/api`** — ✅ **AN KAMMALA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): lissafin FS guda ɗaya na `src/app/api`, openapi-routes + docs-symbols har yanzu suna bayar da rahoto daban-daban; na ɗaiɗaiku suna nan don gudanarwa ta gida. +- **`check:node-runtime` yana gudana a ayyuka 11** — ⚠️ **ROI kaɗan.** Kowanne yana da runner daban kuma binciken bai kai sakan 1 ba; jimillar abin da za a adana kusan sakan 10 ne, amma hakan zai sa a rasa kariyar kowane aiki mai arha. Bai cancanci rikicin sauyin ba. +- **`typecheck:noimplicit:core` a CI lint** — ✅ **an cire daga aikin lint** (a baya na shawara ne da `continue-on-error`); ɓangaren type mai toshewa shi ne `typecheck:core` + `check:type-coverage`. An riƙe script na gida. ### Sauya matsayi / yanke shawara (manufar mai gudanarwa) -- `check:openapi-security-tiers` (na shawara) — ❌ **BA za a iya sauya matsayinsa kai-tsaye ba.** Yana fita da 0 amma yana gargadin cewa wasu routes na `traffic-inspector` da ke ƙarƙashin `LOCAL_ONLY_API_PREFIXES` ba su da alamar `x-loopback-only: true`. Tilasta shi yana buƙatar fara ƙara waɗannan alamomin zuwa `openapi.yaml`. -- `typecheck:noimplicit:core` (na shawara) — ratchet mai toshewa na `check:type-coverage` ya riga ya rufe galibinsa. A sauya shi zuwa ratchet ko a cire zagayen `tsc` na biyu mai maimaituwa. -- `test:vitest:ui` (yanzu **mai toshewa**) — an ware gazawowin da suka riga suka wanzu a `vitest.config.ts` tare da sharhin bibiyar `// #8618`; sabbin gazawowi suna sa aikin ya kasa. -- `check:secrets` (gitleaks, ratchet mai toshewa da aka daskarar a kan false-positives 3 da aka rubuta bayaninsu) — a sanya ukun a allowlist domin a kai 0, ko a saukar da shi zuwa na shawara. Yana yin aikin da ya yi karo da GitHub native secret-scanning + `check:public-creds`. -- `check:pr-evidence` (mai toshewa, yana amfani da greps a rubutun jikin PR) — haɗarin false-positive mai yawa; cire shi zai raunana tilasta Hard Rule #18, don haka wannan shawarar manufa ce ta gaske. -- `semgrep` (na shawara mai zaman kansa) — yana yin aikin da ya yi karo da CodeQL ga rukunonin OWASP; a haɗa baseline ɗinsa da ratchet ko a cire shi. +- `check:openapi-security-tiers` (na shawara) — ❌ **BA za a iya sauya matsayinsa kai tsaye cikin sauƙi ba.** Yana fita da 0 amma yana gargadin cewa routes na `traffic-inspector` da dama a ƙarƙashin `LOCAL_ONLY_API_PREFIXES` ba su da annotation na `x-loopback-only: true`. Tilasta shi yana buƙatar fara ƙara waɗannan annotations zuwa `openapi.yaml`. +- `typecheck:noimplicit:core` (na shawara) — ratchet mai toshewa na `check:type-coverage` ya riga ya rufe yawancin aikinsa. A sauya shi zuwa ratchet ko a cire zagayen `tsc` na biyu mai maimaituwa. +- `test:vitest:ui` (yanzu **mai toshewa**) — an ware gazawar da ta riga ta kasance a sarari cikin `vitest.config.ts` tare da sharhin bin diddigi na `// #8618`; sababbin gazawa za su sa aikin ya gaza. +- `check:secrets` (gitleaks, ratchet mai toshewa da aka daskarar a sakamakon ƙarya 3 da aka rubuta bayaninsu) — a saka ukun cikin allowlist domin a kai 0, ko a saukar da shi zuwa na shawara. Yana maimaita wani ɓangare na aikin GitHub native secret-scanning + `check:public-creds`. +- `check:pr-evidence` (mai toshewa, yana grep rubutun PR-body) — haɗarin sakamakon ƙarya yana da yawa; cire shi zai raunana aiwatar da Hard Rule #18, don haka wannan shawarar manufa ce ta gaske. +- `semgrep` (na shawara mai zaman kansa) — yana maimaita aikin CodeQL ga rukunin OWASP; a haɗa baseline ɗinsa da ratchet ko a cire shi. --- diff --git a/docs/i18n/he/CONTRIBUTING.md b/docs/i18n/he/CONTRIBUTING.md index 3c4eb7a4af7..c66af7f0a41 100644 --- a/docs/i18n/he/CONTRIBUTING.md +++ b/docs/i18n/he/CONTRIBUTING.md @@ -392,16 +392,16 @@ docs/ # Documentation - [ ] בדיקת הסגנון עוברת (`npm run lint`) - [ ] הבנייה מצליחה (`npm run build`) - [ ] נוספו טיפוסי TypeScript עבור פונקציות וממשקים ציבוריים חדשים -- [ ] אין סודות או ערכי ברירת מחדל המקודדים באופן קשיח -- [ ] פרטי גישה ציבוריים לשירותי upstream מוטמעים באמצעות `resolvePublicCred()` (ראו [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ולעולם לא כליטרלים -- [ ] תגובות שגיאה מנותבות דרך `buildErrorBody()` / `sanitizeErrorMessage()` — ללא עקבות מחסנית גולמיים בגופי התגובות (ראו [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] פקודות מעטפת (`exec` / `spawn`) מעבירות ערכי זמן ריצה באמצעות `env`, ולא באמצעות אינטרפולציית מחרוזות +- [ ] אין סודות או ערכי ברירת מחדל מקודדים בקוד +- [ ] פרטי גישה ציבוריים של upstream מוטמעים באמצעות `resolvePublicCred()` (ראו [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ולעולם לא כערכים מילוליים +- [ ] תגובות שגיאה עוברות דרך `buildErrorBody()` / `sanitizeErrorMessage()` — אין עקבות מחסנית גולמיים בגופי התגובות (ראו [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] פקודות מעטפת (`exec` / `spawn`) מעבירות ערכים בזמן ריצה באמצעות `env`, ולא באמצעות אינטרפולציית מחרוזות - [ ] כל הקלטים מאומתים באמצעות סכמות Zod -- [ ] נוסף **מקטע** יומן שינויים תחת `changelog.d/{features|fixes|maintenance}/-.md` עבור שינויים הנראים למשתמש (ראו [`changelog.d/README.md`](./changelog.d/README.md)) — **אין** לערוך את `CHANGELOG.md` ישירות; המקטעים מאוגדים בזמן ההפצה ולעולם אינם יוצרים התנגשויות בין בקשות משיכה +- [ ] נוסף **מקטע** יומן שינויים תחת `changelog.d/{features|fixes|maintenance}/-.md` עבור שינויים הנראים למשתמשים (ראו [`changelog.d/README.md`](./changelog.d/README.md)) — **אין** לערוך את `CHANGELOG.md` ישירות; המקטעים מאוגדים בעת ההפצה ולעולם אינם יוצרים התנגשויות בין בקשות משיכה - [ ] התיעוד עודכן (אם רלוונטי) -- [ ] לא נפתחו התראות CodeQL / Secret-Scanning חדשות, או שכל אחת מהן נדחתה בצירוף הצדקה טכנית המפנה למסמך הרלוונטי תחת `docs/security/` -- [ ] נתיבים שמפעילים תהליכי־בן (`/api/mcp/`, `/api/cli-tools/runtime/`) מסווגים כ־`isLocalOnlyPath()` בתוך `src/server/authz/routeGuard.ts` — ראו [כלל מחייב מס' 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] אין שורות סיום מסוג `Co-Authored-By` בהודעות commit — ה־commits חייבים להופיע אך ורק תחת זהות ה־Git של בעלי המאגר (כלל מחייב מס' 16) +- [ ] לא נפתחו התראות CodeQL / סריקת סודות חדשות, או שכל אחת מהן נדחתה בצירוף הצדקה טכנית המפנה למסמך הרלוונטי תחת `docs/security/` +- [ ] נתיבים שמפעילים תהליכי-בן (`/api/mcp/`, `/api/cli-tools/runtime/`) מסווגים כ-`isLocalOnlyPath()` בתוך `src/server/authz/routeGuard.ts` — ראו [כלל מחייב מס' 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] אין סיומות `Co-authored-by` של AI/בוט בהודעות commit (כלל מחייב מס' 16) — שותפים אנושיים שעבודתם נעשה שימוש חוזר מקבלים קרדיט באמצעות סיומות `Co-authored-by: Name ` תקניות --- diff --git a/docs/i18n/he/docs/architecture/QUALITY_GATES.md b/docs/i18n/he/docs/architecture/QUALITY_GATES.md index ab762e88c3e..6e160cfd0fe 100644 --- a/docs/i18n/he/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/he/docs/architecture/QUALITY_GATES.md @@ -15,193 +15,193 @@ --- -## מלאי שערים ופרופילי הרצה +## מלאי השערים ופרופילי ההרצה ### קבלת מועמדים -תהליכי העבודה של CI ושל שערי האיכות מפיקים כל אחד פסק דין יציב: `Gate / CI` ו־ -`Gate / Quality`. מדיניות הקבלה שלהם, המנוהלת לפי גרסאות, מונה כל משימת upstream -כנדרשת או כמייעצת. משימה נדרשת ורלוונטית חייבת להצליח: תוצאות חסרות, -מבוטלות, מדולגות, ממתינות או לא ידועות אינן יכולות לקבוע PASS. סיווג תקין +תהליכי העבודה של CI ושל שערי האיכות מפיקים כל אחד הכרעה יציבה: `Gate / CI` ו- +`Gate / Quality`. מדיניות הקבלה שלהם, שלה יש גרסאות, מונה כל משימה במעלה הזרם +כנדרשת או כמייעצת. משימה נדרשת ורלוונטית חייבת להסתיים בהצלחה: תוצאות חסרות, +מבוטלות, שדולגו, ממתינות או לא ידועות אינן יכולות לקבוע PASS. סיווג תקף של תיעוד בלבד או קטלוג בלבד יכול להפוך מסלול קוד ללא רלוונטי; -PR במצב טיוטה אינו מועמד קביל. תווית `hotfix` אינה פוטרת מהצגת ראיות. +טיוטת PR אינה מועמדת קבילה. תווית `hotfix` אינה פוטרת מהצגת ראיות. -שני תהליכי העבודה מכסים PR-ים ודחיפות לענפי main/release, הפעלה ידנית ואירועי -merge-group. דחיפה, הפעלה ו־merge-group מריצים את הבחירה המלאה. פיצולים -וקבוצות מיזוג משתמשים במריצים מתארחים עבור משימות שאחרת היו בוחרות מריצים -באירוח עצמי; יש לוודא קיבולת מתארחת מספקת לפני ההשקה. +שני תהליכי העבודה מכסים בקשות PR ודחיפות לענפי main/release, הפעלה ידנית ואירועי +merge-group. דחיפה, הפעלה ו-merge-group מריצים את הבחירה המלאה. מזלגות +וקבוצות מיזוג משתמשים ב-hosted runners עבור משימות שאחרת היו בוחרות ב-self-hosted +runners; יש לוודא קיבולת מספקת ב-hosted runners לפני הפריסה. -כל קבלת JSON מזהה את ה־SHA שנשלף, את הרצת תהליך העבודה ואת ניסיון ההרצה. -ה־CLI דוחה אי־התאמה בין SHA של השליפה לזה של האירוע. בדיקות תהליך העבודה קושרות את החברות במדיניות -לרשימת `needs` של משימת פסק הדין, כך שמסלול חדש או שהוסר לא יוכל להיעלם ללא התרעה. -הקבלות מכסות את תהליך העבודה שלהן עצמן, ולא פרסום, פריסה או את המנגנונים הפנימיים +כל קבלת JSON מזהה את ה-SHA שנשלף, את הרצת תהליך העבודה ואת ניסיון ההרצה. +ה-CLI דוחה אי-התאמה בין ה-SHA של השליפה לזה של האירוע. בדיקות תהליך העבודה קושרות את החברות במדיניות +לרשימת `needs` של משימת ההכרעה, כך שמסלול חדש או שהוסר לא יוכל להיעלם ללא התרעה. +הקבלות מכסות את תהליך העבודה שלהן בלבד, ולא פרסום, פריסה או את הרכיבים הפנימיים של סורק מייעץ קיים. הפעלת שני שמות הבדיקות בכללי הענף היא -שינוי מנהלי נפרד; הוספת המשימות האלה אינה מגינה כשלעצמה על ענף. +שינוי ניהולי נפרד; הוספת המשימות האלה אינה מגינה על ענף בפני עצמה. -### מלאי סריקות סטטיות +### מלאי הסריקות הסטטיות -מלאי כינויי npm המנוהל לפי גרסאות והחברות בסריקה הסטטית נמצאים ב־ +מלאי כינויי npm בעל הגרסאות והחברות בסריקה הסטטית נמצאים ב- `config/quality/gate-manifest.json`. הריצו `npm run check:gate-manifest` כדי לאמת -שמות סקריפטים ופקודות מדויקות מול `package.json`; הוספות, הסרות ושינויים -בפקודות מכשילים הן את ה־hook המקומי והן את משימות סיווג השינויים ב־CI. +שמות סקריפטים ופקודות מדויקות מול `package.json`; הוספות, הסרות +וסטייה בפקודות מכשילות הן את ה-hook המקומי והן את משימות סיווג השינויים ב-CI. כינוי אינו משימת תהליך עבודה, מופע מטריצה או מקרה בדיקה: אין -להציג ספירות אלה כאילו הן ניתנות להחלפה זו בזו. +להציג ספירות אלה כבנות-החלפה. -השתמשו ב־`npm run quality:scan -- --list` או ב־`npm run quality:scan:fast -- --list` -כדי לבחון את הכינויים שנבחרו מבלי להריץ אותם. המריץ מפעיל את -נקודת הכניסה של npm, ולכן סביבת זמן הריצה שלה (כולל Bun כאשר הוא מוגדר) נשמרת. -המניפסט מתעד כינויים שמחוץ לפרופילים האלה כמופעלים בנפרד, -ופקודות תחזוקה אסורות בפרופילי סריקה לקריאה בלבד. +השתמשו ב-`npm run quality:scan -- --list` או ב-`npm run quality:scan:fast -- --list` +כדי לבדוק את הכינויים שנבחרו מבלי להפעיל אותם. ה-runner מפעיל את +נקודת הכניסה של npm, ולכן סביבת הריצה שלה (כולל Bun, כאשר הוגדר) נשמרת. +המניפסט מתעד כינויים שמחוץ לפרופילים האלה כמופעלים בנפרד, ופקודות +תחזוקה אסורות בפרופילי סריקה לקריאה בלבד. -פרופילים אלה מכסים רק את הסריקה הסטטית. הם אינם מאשרים בדיקות מוצר, -כיסוי, אריזה, בדיקות חיצוניות או קבלת גרסה מלאה של מועמד. -קבלה בתהליך העבודה משתמשת ב־`config/quality/admission-policy.json` המקושר וב־ +פרופילים אלה מכסים את הסריקה הסטטית בלבד. הם אינם מאשרים בדיקות מוצר, +כיסוי, אריזה, בדיקות חיצוניות או קבלה מלאה של מועמד להפצה. +הקבלה בתהליך העבודה משתמשת ב-`config/quality/admission-policy.json` המקושר וב- `scripts/quality/admission-verdict.mjs`. פרופילי release-observer נשארים נפרדים; -יש לבחון באופן עצמאי את הבדיקות והקבלות הרלוונטיות שלהם. המלאי -המילולי שלהלן הוא חומר עזר, ולא הוכחה לכך ששער אכן הופעל. +יש לבדוק באופן עצמאי את הבדיקות והקבלות הרלוונטיות שלהם. המלאי +הטקסטואלי שלהלן הוא חומר עזר, ולא הוכחה לכך ששער אכן הופעל. -הסקריפטים נמצאים תחת `scripts/check/` (שערי מדיניות) ו־`scripts/quality/` (מנוע ratchet). +הסקריפטים נמצאים תחת `scripts/check/` (שערי מדיניות) ו-`scripts/quality/` (מנוע ההקשחה). מקור האמת של CI הוא `.github/workflows/ci.yml`. -### נתיב מהיר ל־PR של גרסה (`quality.yml`) +### הנתיב המהיר ל-PR של הפצה (`quality.yml`) -`.github/workflows/quality.yml` משלים את CI ב־PR-ים של main/release, בדחיפות לענפים -מוגנים, בהפעלה ובקבוצות מיזוג. PR-ים משתמשים בבדיקות מהירות המסוננות לפי נתיבים. בניית -הכפילות שהושבתה לצמיתות הוסרה; בדיקות הבנייה/האריזה/האתחול האמיתיות נשארות ב־CI. +`.github/workflows/quality.yml` משלים את CI בבקשות PR לענפי main/release, בדחיפות +לענפים מוגנים, בהפעלה ובקבוצות מיזוג. בקשות PR משתמשות בבדיקות מהירות המסוננות לפי נתיב. בניית +הכפילות שהושבתה לצמיתות הוסרה; בדיקות הבנייה/האריזה/האתחול האמיתיות נשארות ב-CI. -| משימה | תחום | חוסמת | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | PR-ים של תיעוד/קוד; הפניות לתיעוד API ו־docs-all | כן | -| `Fast Quality Gates` | PR-ים של קוד; בדיקות סטטיות, בדיקת טיפוסים, בדיקת טיפוסים של לוח המחוונים, בדיקות יחידה מושפעות | כן | -| `Forgotten sibling tests` | PR-ים של קוד; מעקב אחר מודולים ששונו עד לצרכנים סטטיים ולבדיקות sibling מועמדות; נתיבי barrel וייבוא דינמי מדווחים כאבחונים מייעצים, עם חריגים המופנים מרשימת ההיתרים | **מייעצת** | -| `Vitest (fast-path)` | PR-ים של קוד; חבילת בדיקות vitest מהירה | כן | -| `Unit Tests fast-path` | PR-ים של קוד; חבילת בדיקות יחידה המחולקת ל־4 shards | כן | -| `No new ESLint warnings` | PR-ים של קוד; שומר lint המתחשב בהשתקות | כן, כולל פיצולים | -| `Merge integrity (changelog + generated skills)` | PR-ים שאינם טיוטה; סנכרון changelog ומיומנויות שנוצרו | כן, כולל פיצולים | +| משימה | היקף | חוסמת | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `Docs Gates (fast-path)` | בקשות PR של תיעוד/קוד; הפניות לתיעוד API ו-docs-all | כן | +| `Fast Quality Gates` | בקשות PR של קוד; בדיקות סטטיות, typecheck,‏ typecheck של לוח המחוונים ובדיקות יחידה מושפעות | כן | +| `Forgotten sibling tests` | בקשות PR של קוד; מעקב ממודולים שהשתנו אל צרכנים סטטיים ואל בדיקות sibling מועמדות; נתיבי barrel ו-dynamic-import מדווחים כאבחונים מייעצים, עם חריגים מתוך allowlist שהוזכרו | **מייעצת** | +| `Vitest (fast-path)` | בקשות PR של קוד; חבילת vitest מהירה | כן | +| `Unit Tests fast-path` | בקשות PR של קוד; חבילת בדיקות יחידה המחולקת ל-4 shards | כן | +| `No new ESLint warnings` | בקשות PR של קוד; הגנת lint המודעת ל-suppressions | כן, כולל מזלגות | +| `Merge integrity (changelog + generated skills)` | בקשות PR שאינן טיוטה; סנכרון changelog ומיומנויות שנוצרו | כן, כולל מזלגות | #### דוח בדיקות sibling שנשכחו -`npm run check:forgotten-sibling-tests` עושה שימוש חוזר בפותר הייבואים שמאחורי מפת השפעת הבדיקות. -עבור כל מודול ייצור ששונה, הוא מדווח על שרשראות דטרמיניסטיות של -`changed module/symbol -> static consumer -> candidate sibling test` כאשר בדיקת המועמד -אינה קיימת בהבדלי בקשת המשיכה. תקציר ה־Markdown ותוצאת ה־JSON נשמרים כארטיפקט -`forgotten-sibling-tests` של תהליך העבודה לצורך כיול לפני כל השקה במצב חוסם. +`npm run check:forgotten-sibling-tests` עושה שימוש חוזר בפותר הייבוא שמאחורי מפת השפעת הבדיקות. +עבור כל מודול ייצור שהשתנה, הוא מדווח על שרשראות דטרמיניסטיות של +`changed module/symbol -> static consumer -> candidate sibling test` כאשר הבדיקה המועמדת +חסרה מה-diff של בקשת המשיכה. סיכום ה-Markdown ותוצאת ה-JSON נשמרים כארטיפקט +תהליך העבודה `forgotten-sibling-tests` לצורך כיול לפני פריסה חוסמת כלשהי. -ייצוא מחדש מסוג barrel וייבוא דינמי משמשים לאבחון רזולוציה בלבד; הם לעולם אינם יוצרים +ייצואים מחדש מסוג barrel וייבואים דינמיים משמשים לאבחון רזולוציה בלבד; הם לעולם אינם יוצרים ממצא חוסם. חריגים שנבדקו נמצאים ב- `config/quality/forgotten-sibling-allowlist.json`. כל רשומה חייבת לציין את בדיקת הצרכן ואת הבדיקה המועמדת, לספק נימוק ספציפי ולקשר לבעיה או לבקשת משיכה ב-GitHub. רשומות פגומות נכשלות -באופן סגור. חריגים אינם יכולים להסתיר בדיקה מועמדת שנמחקה או שינוי שמוסיף `.skip`/`.todo`; -החלשת טענות אימות ודרכי הסתרה אחרות נותרות באחריות שער +במצב סגור. חריגים אינם יכולים להסתיר בדיקה מועמדת שנמחקה או diff שמוסיף `.skip`/`.todo`; +החלשת assertions והסתרות אחרות נשארות באחריות שער `check:test-masking`, שחוסם באופן עצמאי. ### משימה: `lint` -מופעלת בכל PR אל `main`. כשל חוסם מיזוג. - -| סקריפט (`npm run ...`) | מה נבדק | חוסם | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| `check:node-runtime` | גרסת Node.js נמצאת בטווח הנתמך | כן | -| `check:cycles` | ייבואים מעגליים — כל המודולים תחת `src/` + `open-sse/` | כן | -| `check:route-validation:t06` | סכמות Zod קיימות בכל הנתיבים (מדיניות שכבה 6) | כן | -| `check:any-budget:t11` | מספר מופעי `@ts-expect-error // any` אינו חורג מהתקציב (מחסום שכבה 11) | כן | -| `check:provider-consistency` | לכל ספק ב-`providers.ts` קיימת רשומה תואמת ב-`providerRegistry.ts` (ולהפך, במסגרת רשימת ההיתרים) | כן | -| `check:model-lifecycle` | שלוש טבלאות הניתוב המתוחזקות ידנית נשארות עקביות עם תמונת המצב של מחזור החיים שבמאגר (#11503): ‏`FITNESS_TABLE` ‏(`taskFitness.ts`) אינה מעניקה ציון למזהה שהוצא משימוש וש-`REGISTRY` יכולה לנתב; כל יעד של `BUILT_IN_ALIASES` קיים ב-`REGISTRY` ואינו מופיע בתמונת המצב של המזהים שהוצאו משימוש; כל מזהה שהוצא משימוש ועדיין נמצא ב-`REGISTRY` מועבר הלאה או רשום ב-`allowedRetiredInCatalog`; ואף מקור או יעד של `DEFAULT_DEGRADATION_MAP` אינו מופיע כמזהה שהוצא משימוש בתמונת מצב זו. בדיקה זו אינה מוכיחה שמודל מסופק כעת על ידי שירות מקור פעיל. לא מקוון — משווה מול `config/quality/model-lifecycle.json`, שמתעדכן ידנית באמצעות `npm run quality:refresh-model-lifecycle` (דורש רשת; אינו משולב ב-CI). ‏`allowedRetiredInCatalog` הוא מנגנון צמצום הדרגתי: יש להוסיף רשומה רק בצירוף סוגיית מעקב. | כן | -| `check:fetch-targets` | כל `fetch("/api/...")` בצד הלקוח תחת `src/` מופנה אל `route.ts` ממשי | כן | -| `check:deps` | כל התלויות שניתן להתקין באמצעות `npm install` בכל קובצי `package.json` במאגר נכללות ב-`dependency-allowlist.json`; חבילות חדשות ללא הצמדת גרסה או חבילות החשודות ב-slopsquatting מסומנות | כן | -| `audit:deps` | `npm audit` (שורש + electron) — אין התרעות בחומרה גבוהה/קריטית (חופף ל-`check:vuln-ratchet` של osv; ראו רשימת משימות לרציונליזציה) | כן | -| `check:lockfile` | תקינות `package-lock.json` — מאגר https, גיבובי תקינות, ללא דריסות מארח | כן | -| `check:licenses` | רשימת היתרים של רישיונות SPDX עבור תלויות ייצור | כן | -| `check:tracked-artifacts` | ללא תוצרי בנייה / קישורי `node_modules` שנשמרו במאגר (רץ גם ב־pre-commit של husky; ‏pre-push קל בכוונה — #6716) | כן | -| `check:ai-attribution` | ללא שורת סיום `Co-Authored-By` של AI/בוט או כיתוב המעיד על יצירה באמצעות AI ב־commits, בכותרת או בגוף של PR — כלל קשיח מס' 16 (בלולאת הבדיקות המהירות של `quality.yml` עבור PR→`release/**` — קורא את מטען האירוע ואינו עושה דבר מחוץ ל־PR — ובשלב המיועד ל־PR בלבד בבדיקת ה־lint של `ci.yml` עבור PR→`main`; גם ב־hook ‏`commit-msg` של husky; מחברים־שותפים אנושיים מותרים; #14436) | -| `check:vitest-exclusions` | כל החרגה של Vitest מציינת סוגיית מעקב ומופיעה ב־`config/quality/vitest-exclusions.json` (#13204) | כן | -| `check:file-size` | אף קובץ מקור אינו חורג מהמגבלה לפי סיומת (מנגנון החמרה הדרגתי: קבצים גדולים שהוקפאו ברשימת `frozen`) | כן | -| `check:error-helper` | תגובות שגיאה ב־executors/handlers משתמשות ב־`buildErrorBody()` / `sanitizeErrorMessage()` (כלל קשיח מס' 12) | כן | -| `check:migration-numbering` | קובצי ה-SQL של המיגרציות ממוספרים ברצף, ללא פערים או כפילויות | כן | -| `check:public-creds` | אין ערכי OAuth מילוליים של `client_id`/`client_secret` או מפתחות Firebase Web מחוץ ל-`publicCreds.ts` (כלל קשיח #11) | כן | -| `check:db-rules` | אין SQL גולמי מחוץ למודולים שב-`src/lib/db/`; אין ייבואי barrel מ-`localDb.ts` (כללים קשיחים #2/#5) | כן | -| `check:known-symbols` | מבצעי ספקים, אסטרטגיות ניתוב ומתרגמים הרשומים בטבלאות הניתוב שלהם תואמים לקבצים בדיסק — ללא סמלים יתומים או לא מוצהרים | כן | -| `check:route-guard-membership` | כל נתיב שמפעיל תהליך צאצא מסווג על ידי `isLocalOnlyPath()` (כללים קשיחים #15/#17) | כן | -| `check:test-discovery` | כל קובץ `*.test.ts` / `*.spec.ts` במאגר נאסף על ידי לפחות מריץ בדיקות אחד (מנגנון הידוק: רשימת היתומים ב-`test-discovery-baseline.json` יכולה רק להצטמצם) | כן | -| `check:agent-skills-sync` | ארטיפקטי agent-skills שנוצרו תואמים לקטלוג המקור שלהם (ללא סטייה) | -| `check:provider-asset-provenance` | לסמלי הלוגו/לנכסים של הספקים יש רשומת מקור מתועדת | -| `lint:json` | קובצי התצורה של JSON ניתנים לניתוח ועומדים בכללי ה-lint של המאגר | -| `typecheck:core` | הידור TypeScript ללא שגיאות (אזהרות מייעצות בלבד) | כן | -| `typecheck:noimplicit:core` | `noImplicitAny` מחמיר — כהיערכות לעתיד; אתרי קריאה קיימים רבים עדיין זקוקים להערות טיפוסים | **מייעץ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` שמוגבל ל-`src/app/(dashboard)/**` (#7033) — רשימת ההיתרים המצומצמת של `typecheck:core`, הכוללת 27 קבצים, אינה כוללת אף קובץ TSX של לוח המחוונים, וגם `next build` לעולם אינו בודק את הטיפוסים שלו (`next.config.mjs` מגדיר `ignoreBuildErrors: true`), ולכן רגרסיות של מזהים מיותמים שם (#6625/#6909) לא היו גלויות ל-CI. מתבצעת השוואה מול קו בסיס קפוא של ספירת שגיאות לפי קובץ ולפי קוד TS (`config/quality/dashboard-typecheck-baseline.json`, באותה תבנית אכיפת התיישנות כמו `check:known-symbols`) — רק שגיאות חדשות מעבר לספירה שבקו הבסיס מכשילות את השער; יש להדק את קו הבסיס באמצעות `--update` כאשר שגיאה קיימת מתוקנת. | כן | +פועלת בכל PR אל `main`. חוסמת מיזוג במקרה של כשל. + +| סקריפט (`npm run ...`) | מה מאומת | חוסם | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| `check:node-runtime` | גרסת Node.js נמצאת בטווח הנתמך | כן | +| `check:cycles` | ייבואים מעגליים בכל `src/` + `open-sse/` (מבוסס AST, עם רזולוציה של `paths` מתוך tsconfig). הרצה בסיסית = ייעוץ בלבד, ומציגה את המחזורים. `check:cycles:ratchet` (מה ש-CI מריץ) חוסם כאשר הכמות חורגת מהתקרה `metrics.cycles` שב-`quality-baseline.json` — נכון לעכשיו 14, עם `direction: down`, ולכן היא יכולה רק לרדת (#15159 G-01/G-02) | כן (ratchet) | +| `check:route-validation:t06` | סכמות Zod קיימות בכל הנתיבים (מדיניות Tier 6) | כן | +| `check:any-budget:t11` | מספר המופעים של `@ts-expect-error // any` אינו חורג מהתקציב (catraca של Tier 11) | כן | +| `check:provider-consistency` | לכל ספק ב-`providers.ts` קיימת רשומה תואמת ב-`providerRegistry.ts` (ולהפך, במסגרת רשימת ההיתרים) | כן | +| `check:model-lifecycle` | שלוש טבלאות הניתוב המתוחזקות ידנית נשארות עקביות עם תמונת מצב מחזור החיים שבמאגר (#11503): ‏`FITNESS_TABLE`‏ (`taskFitness.ts`) אינה מעניקה ציון למזהה שהוצא משימוש וש-`REGISTRY` יכולה לנתב אליו; כל יעד של `BUILT_IN_ALIASES` קיים ב-`REGISTRY` ואינו מופיע בתמונת המצב של המזהים שהוצאו משימוש; כל מזהה שהוצא משימוש ועדיין נמצא ב-`REGISTRY` מועבר הלאה או רשום ב-`allowedRetiredInCatalog`; ואף מקור או יעד של `DEFAULT_DEGRADATION_MAP` אינו מופיע בתמונת מצב זו כמזהה שהוצא משימוש. בדיקה זו אינה מוכיחה שמודל מסופק כעת על ידי שירות upstream פעיל. לא מקוון — מתבצעת השוואה מול `config/quality/model-lifecycle.json`, המרוענן ידנית באמצעות `npm run quality:refresh-model-lifecycle` (דורש רשת; אינו משולב ב-CI). ‏`allowedRetiredInCatalog` הוא מנגנון מחגר לצמצום הדרגתי: יש להוסיף רשומה רק בצירוף issue למעקב. | כן | +| `check:fetch-targets` | כל `fetch("/api/...")` בצד הלקוח תחת `src/` מפנה לקובץ `route.ts` קיים | כן | +| `check:deps` | כל יחסי התלות שניתן להתקין באמצעות `npm install`, בכל קובץ `package.json` במאגר, נמצאים ב-`dependency-allowlist.json`; חבילות חדשות שאינן מקובעות לגרסה או חשודות ב-slopsquatting מסומנות | כן | +| `audit:deps` | `npm audit` (שורש + Electron) — ללא התראות בדרגת חומרה גבוהה/קריטית (חופף ל-`check:vuln-ratchet` של OSV; ראו צבר הרציונליזציה) | כן | +| `check:lockfile` | תקינות `package-lock.json` — רישום HTTPS, גיבובי תקינות, ללא דריסות מארח | כן | +| `check:licenses` | רשימת היתרים של רישיונות SPDX עבור תלויות ייצור | כן | +| `check:tracked-artifacts` | ללא תוצרי בנייה / קישורי `node_modules` שנוספו למעקב (רץ גם ב־pre-commit של husky; ‏pre-push קל במכוון — #6716) | כן | +| `check:ai-attribution` | ללא שורת סיום `Co-Authored-By` של AI/בוט או כותרת תחתונה המעידה על יצירה באמצעות AI ב־commits, בכותרת או בגוף של PR — כלל מחייב #16 (בלולאת הבדיקות המהירות של `quality.yml` עבור PR→`release/**` — קורא את מטען האירוע ואינו מבצע פעולה מחוץ ל־PRs — ובשלב המיועד ל־PR בלבד בבדיקת ה־lint של `ci.yml` עבור PR→`main`; גם ב־hook‏ `commit-msg` של husky; מחברים־שותפים אנושיים מותרים; #14436) | +| `check:vitest-exclusions` | כל החרגה של Vitest מציינת issue למעקב ומופיעה ב־`config/quality/vitest-exclusions.json` (#13204) | כן | +| `check:file-size` | אף קובץ מקור אינו חורג מהמכסה לכל סיומת (מנגנון ratchet: קבצים גדולים שהוקפאו ברשימת `frozen`) | כן | +| `check:error-helper` | תגובות שגיאה ב־executors/handlers משתמשות ב־`buildErrorBody()` / `sanitizeErrorMessage()` (כלל מחייב #12) | כן | +| `check:migration-numbering` | קובצי Migration SQL ממוספרים ברצף, ללא פערים או כפילויות | כן | +| `check:public-creds` | אין ערכי OAuth מילוליים של `client_id`/`client_secret` או מפתחות Firebase Web מחוץ ל-`publicCreds.ts` (כלל קשיח #11) | כן | +| `check:db-rules` | אין SQL גולמי מחוץ למודולים שב-`src/lib/db/`; אין ייבואי barrel מ-`localDb.ts` (כללים קשיחים #2/#5) | כן | +| `check:known-symbols` | רכיבי ההרצה של הספקים, אסטרטגיות הניתוב והמתרגמים הרשומים בטבלאות הניתוב שלהם תואמים לקבצים שבדיסק — ללא סמלים יתומים או לא מוצהרים | כן | +| `check:route-guard-membership` | כל נתיב שמפעיל תהליך בן מסווג באמצעות `isLocalOnlyPath()` (כללים קשיחים #15/#17) | כן | +| `check:test-discovery` | כל קובץ `*.test.ts` / `*.spec.ts` במאגר נאסף על ידי לפחות מריץ בדיקות אחד (ratchet: רשימת הקבצים היתומים ב-`test-discovery-baseline.json` יכולה רק להצטמצם) | כן | +| `check:agent-skills-sync` | ארטיפקטים שנוצרו עבור agent-skills תואמים לקטלוג המקור שלהם (ללא סטייה) | +| `check:provider-asset-provenance` | סמלי לוגו/נכסים של ספקים כוללים רשומת מקור מתועדת | +| `lint:json` | קובצי תצורה מסוג JSON עוברים ניתוח תחבירי ועומדים בכללי ה-lint של המאגר | +| `typecheck:core` | הידור TypeScript ללא שגיאות (אזהרות מייעצות בלבד) | כן | +| `typecheck:noimplicit:core` | `noImplicitAny` מחמיר — מיועד להמשך הדרך; אתרי קריאה קיימים רבים עדיין זקוקים לאנוטציות | **מייעץ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` המוגבל ל-`src/app/(dashboard)/**` (#7033) — רשימת ההיתרים המצומצמת של `typecheck:core`, הכוללת 27 קבצים, אינה כוללת אף קובץ TSX של לוח המחוונים, וגם `next build` לעולם אינו מבצע עבורו בדיקת טיפוסים (`next.config.mjs` מגדיר `ignoreBuildErrors: true`), ולכן רגרסיות של מזהים יתומים שם (#6625/#6909) לא היו גלויות ל-CI. מתבצעת השוואה מול קו בסיס קפוא של ספירת שגיאות לכל קובץ ולכל קוד TS (`config/quality/dashboard-typecheck-baseline.json`, באותה תבנית אכיפה נגד התיישנות כמו `check:known-symbols`) — רק שגיאות חדשות מעבר לספירה שבקו הבסיס גורמות לכשל בשער; יש להדק את קו הבסיס באמצעות `--update` כאשר שגיאה קיימת מתוקנת. | כן | ### משימה: `quality-gate` -פועלת לאחר `test-coverage`. חוסמת מיזוג במקרה של כשל. +רצה לאחר `test-coverage`. חוסמת מיזוג במקרה של כשל. -| סקריפט | מה הוא מאמת | חוסם | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | -| `quality:collect` | מפיק את `quality-metrics.json` (מספר אזהרות ESLint, כיסוי מהדוח הממוזג של ה-shards) | כן (לפני ה-ratchet) | -| `quality:ratchet` | אף מדד ב-`quality-baseline.json` לא נסוג (אזהרות ESLint ≤ קו הבסיס; כיסוי ≥ קו הבסיס) | כן | -| `check:duplication` | שכפול קוד (jscpd@4) אינו חורג מקו הבסיס שב-`quality-baseline.json` | כן | -| `check:complexity` | המורכבות הציקלומטית ברמת הקובץ אינה חורגת מהתקרה (`complexity` של ליבת ESLint + `max-lines-per-function`) | כן | -| `check:cognitive-complexity` | Ratchet למורכבות קוגניטיבית (`eslint-plugin-sonarjs`) — מעבר ESLint נפרד; CI מריץ את שניהם במיזוג כשלב היחיד `check:complexity-ratchets` | כן | -| `check:dead-code` | Ratchet לייצואים / קבצים שאינם בשימוש (knip) אינו נסוג לעומת קו הבסיס | כן | -| `check:compression-budget` | תקציב benchmark לדחיסה — ערכי הסף המינימליים לחיסכון בטוקנים לכל מנוע אינם רשאים לסגת | כן | -| `check:type-coverage` | Ratchet לאחוז הקוד המוקלד (`type-coverage`) אינו נסוג; מחליף במידה רבה את `typecheck:noimplicit:core` | כן | -| `check:codeql-ratchet` | מספר התראות CodeQL הפתוחות אינו נסוג (נקרא באמצעות `gh api`; דילוג תקין ללא אסימון) — לתדירות הרענון ולהפעלה ידנית: ראו "Ratchet של CodeQL" להלן | כן | +| סקריפט | מאמת | חוסם | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `quality:collect` | מפיק את `quality-metrics.json` (מספר אזהרות ESLint, כיסוי מדוח הרסיסים הממוזג) | כן (לפני מנגנון הסף) | +| `quality:ratchet` | אף מדד ב-`quality-baseline.json` לא נסוג (אזהרות ESLint ≤ קו הבסיס; כיסוי ≥ קו הבסיס) | כן | +| `check:duplication` | שכפול קוד (jscpd@4) אינו חורג מקו הבסיס שב-`quality-baseline.json` | כן | +| `check:complexity` | המורכבות הציקלומטית ברמת הקובץ אינה חורגת מהתקרה (כללי הליבה של ESLint‏ `complexity` + `max-lines-per-function`) | כן | +| `check:cognitive-complexity` | מנגנון סף למורכבות קוגניטיבית (`eslint-plugin-sonarjs`) — מעבר ESLint נפרד; CI מריץ את שניהם במאוחד כשלב היחיד `check:complexity-ratchets` | כן | +| `check:dead-code` | מנגנון הסף לייצואים / קבצים שאינם בשימוש (knip) אינו נסוג ביחס לקו הבסיס | כן | +| `check:compression-budget` | תקציב מדד ביצועי הדחיסה — ערכי הסף המזעריים לחיסכון באסימונים עבור כל מנוע אינם יכולים לסגת | כן | +| `check:type-coverage` | מנגנון הסף לאחוז הקוד המוקלד (`type-coverage`) אינו נסוג; מחליף במידה רבה את `typecheck:noimplicit:core` | כן | +| `check:codeql-ratchet` | מספר התראות CodeQL הפתוחות אינו נסוג (נקרא באמצעות `gh api`; דילוג תקין ללא אסימון) — לתדירות הרענון ולהפעלה ידנית: ראו "מנגנון הסף של CodeQL" להלן | כן | ### משימה: `quality-extended` -המשימה כולה היא בגדר המלצה (`continue-on-error: true`). ה-ratchets המבוססים על npm אכן -רצים; הסורקים החיצוניים מותקנים באמצעות `gh release download` ומדלגים על עצמם (exit 0) +המשימה כולה היא בגדר המלצה (`continue-on-error: true`). מנגנוני הסף מבוססי npm מופעלים +בפועל; הסורקים החיצוניים מותקנים באמצעות `gh release download` ומדלגים בעצמם (יציאה עם קוד 0) כאשר קובץ בינארי עדיין חסר. -| סקריפט | מה הוא מאמת | חוסם | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | -| `check:circular-deps` | אין תלויות מעגליות (dpdm) | **בגדר המלצה** | -| `check:bundle-size` | גודל החבילה אינו חורג מהתקרה | **בגדר המלצה** | -| `check:secrets` | סריקת סודות (gitleaks) — מדלג אם הקובץ הבינארי חסר | **בגדר המלצה** | -| `check:vuln-ratchet` | פגיעויות בתלויות (osv-scanner) אינן נסוגות — מדלג אם הקובץ הבינארי חסר | **בגדר המלצה** | -| `check:workflows` | בדיקת תקינות workflows‏ (actionlint + zizmor); סורקים חסרים/תקולים, דוחות לא תקינים או קו בסיס חסר ל-ratchet גורמים לכשל מסוג INCOMPLETE. ממצאים תקינים פועלים לפי מדיניות strict/advisory/ratchet שנבחרה | נדרשת הרצה; ה-ratchet של zizmor חוסם ב-CI | -| `check:openapi-breaking` | שינויים שוברים בחוזה ה-API הציבורי (`openapi.yaml`) לעומת ענף הבסיס (oasdiff) — מפיק `openapiBreaking=N`; מדלג אם oasdiff חסר או אם לא ניתן לפענח את מפרט הבסיס | **בגדר המלצה** | +| סקריפט | מאמת | חוסם | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:circular-deps` | אין תלויות מעגליות (dpdm) | **בגדר המלצה** | +| `check:bundle-size` | גודל החבילה אינו חורג מהתקרה | **בגדר המלצה** | +| `check:secrets` | סריקת סודות (gitleaks) — מדלג אם הקובץ הבינארי חסר | **בגדר המלצה** | +| `check:vuln-ratchet` | חולשות בתלויות (osv-scanner) אינן נסוגות — מדלג אם הקובץ הבינארי חסר | **בגדר המלצה** | +| `check:workflows` | בדיקת תקינות של תהליכי עבודה (actionlint + zizmor); סורקים חסרים/תקולים, דוחות לא תקינים או קו בסיס חסר למנגנון הסף גורמים לכשל במצב INCOMPLETE. ממצאים תקפים מטופלים בהתאם למדיניות המחמירה/המייעצת/מבוססת-הסף שנבחרה | נדרשת הפעלה; מנגנון הסף של zizmor חוסם ב-CI | +| `check:openapi-breaking` | שינויים שוברים בחוזה ה-API הציבורי (`openapi.yaml`) ביחס לענף הבסיס (oasdiff) — מפיק `openapiBreaking=N`; מדלג אם oasdiff חסר או שלא ניתן לפענח את מפרט הבסיס | **בגדר המלצה** | ### משימה: `docs-sync-strict` -רצה בכל PR אל `main`. חוסמת מיזוג במקרה של כשל. - -| סקריפט | מה הוא מאמת | חוסם | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | שער־על שמריץ ברצף את 6 שערי המשנה שלהלן | כן | -| ↳ `check:docs-sync` | עקביות גרסאות בין CHANGELOG / OpenAPI / llm.txt | כן | -| ↳ `check:docs-counts` | ספירות בטקסט (מספר ספקים, מספר מיגרציות וכו') נמצאות בתוך חלון ההידוק של הספירות בפועל | כן | -| ↳ `check:env-doc-sync` | כל משתנה סביבה ב־`.env.example` מתועד בטבלת תיעוד, ולהפך | כן | -| ↳ `check:deprecated-versions` | אין מחרוזות גרסה שהוצאו משימוש בתיעוד | כן | -| ↳ `check:doc-links` | קישורי Markdown פנימיים בתיעוד מפנים לקבצים קיימים (בתבנית `[text]`/`(path)`) | כן | -| ↳ `check:fabricated-docs` | נתיבים, משתני סביבה, פקודות CLI, שמות hooks ונתיבי קבצים המוזכרים בתיעוד קיימים בבסיס הקוד. שער קשיח באמצעות `--strict`; כשל רך ללא הדגל. | כן (באמצעות `--strict` ב־CI) | -| `check:cli-i18n` | מחרוזות פקודות CLI קיימות בכל קובצי הלוקאל של i18n | כן | -| `check:openapi-coverage` | מפרט OpenAPI מכסה לפחות סף מהודק של הנתיבים הקיימים בפועל | כן | -| `check:openapi-security-tiers` | הערות רמות האבטחה ב־`openapi.yaml` עקביות עם הסיווגים ב־`routeGuard.ts` | **מייעץ** | -| `check:openapi-routes` | כל נתיב ב־`openapi.yaml` מפנה ל־`route.ts` אמיתי (מניעת הזיות) | כן | -| `check:docs-symbols` | כל הפניית `/api/...` ב־`docs/**/*.md` מפנה ל־`route.ts` אמיתי (מניעת הזיות) | כן | -| `i18n translation drift` | מפתחות שלא תורגמו בקובצי הלוקאל של i18n — אזהרה בלבד | **מייעץ** | +מופעלת בכל PR אל `main`. חוסמת מיזוג במקרה של כשל. + +| סקריפט | מה הוא מאמת | חוסם | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `check:docs-all` | שער־על שמריץ ברצף את 6 שערי־המשנה שלהלן | כן | +| ↳ `check:docs-sync` | עקביות הגרסאות בין CHANGELOG / OpenAPI / llm.txt | כן | +| ↳ `check:docs-counts` | הספירות בטקסט (מספר ספקים, מספר מיגרציות וכו׳) נמצאות בתוך חלון ההידוק של הספירות בפועל | כן | +| ↳ `check:env-doc-sync` | כל משתנה סביבה ב־`.env.example` מתועד בטבלת תיעוד, ולהפך | כן | +| ↳ `check:deprecated-versions` | אין בתיעוד מחרוזות של גרסאות שהוצאו משימוש | כן | +| ↳ `check:doc-links` | קישורי Markdown פנימיים בתיעוד מפנים לקבצים קיימים (בתבנית `[text]`/`(path)`) | כן | +| ↳ `check:fabricated-docs` | הנתיבים, משתני הסביבה, פקודות ה־CLI, שמות ה־hooks ונתיבי הקבצים המוזכרים בתיעוד קיימים בבסיס הקוד. שער קשיח עם `--strict`; כשל רך ללא הדגל. | כן (באמצעות `--strict` ב־CI) | +| `check:cli-i18n` | מחרוזות פקודות ה־CLI קיימות בכל קובצי אזורי ה־i18n | כן | +| `check:openapi-coverage` | מפרט OpenAPI מכסה לפחות סף תחתון מהודק של הנתיבים בפועל | כן | +| `check:openapi-security-tiers` | הערות רמות האבטחה ב־`openapi.yaml` תואמות לסיווגים ב־`routeGuard.ts` | **מייעץ** | +| `check:openapi-routes` | כל נתיב ב־`openapi.yaml` מפנה ל־`route.ts` אמיתי (מניעת הזיות) | כן | +| `check:docs-symbols` | כל הפניה מסוג `/api/...` בתוך `docs/**/*.md` מפנה ל־`route.ts` אמיתי (מניעת הזיות) | כן | +| `i18n translation drift` | מפתחות שלא תורגמו בקובצי אזורי ה־i18n — אזהרה בלבד | **מייעץ** | ### משימה: `i18n-ui-coverage` | סקריפט | מה הוא מאמת | חוסם | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | -| `check-ui-keys-coverage` (מוטבע) | כיסוי מפתחות i18n בממשק המשתמש הוא ≥ 65% | כן | -| `check-ui-value-drift` (מוטבע) | לאחר שכתוב **ערך** באנגלית לא נשאר מאחור תרגום מיושן | כן | -| `check-new-key-coverage` (מוטבע) | מפתח אנגלי **חדש** מתורגם בכל לוקאל — הסמן `__MISSING__:` נדחה | כן | -| `check-translation-ratio` | יחס התרגומים האמיתיים בכל לוקאל (ערכים זהים לאנגלית / מצייני מקום / ערכים חסרים שאינם ברשימת ההחרגות) אינו יכול לחרוג מ־`config/quality/i18n-translation-baseline.json` בתוספת מרווח | **מייעץ** | +| `check-ui-keys-coverage` (מוטמע) | כיסוי מפתחות ה־i18n של ממשק המשתמש הוא ≥ 65% | כן | +| `check-ui-value-drift` (מוטמע) | שינוי של **ערך** באנגלית אינו משאיר אחריו תרגום מיושן | כן | +| `check-new-key-coverage` (מוטמע) | מפתח אנגלי **חדש** מתורגם בכל אזור — הסמן `__MISSING__:` נדחה | כן | +| `check-translation-ratio` | יחס התרגומים האמיתיים בכל אזור (ערכים הזהים לאנגלית / מצייני מקום / ערכים חסרים שאינם ברשימת ההחרגות) אינו יכול לחרוג מ־`config/quality/i18n-translation-baseline.json` בתוספת מרווח | **מייעץ** | נדרש `fetch-depth: 0` — שער סטיית הערכים משווה את `en.json` מול בסיס המיזוג. #### `check-ui-value-drift` — שער תרגומים מיושנים -מזהה את רגרסיית ה־i18n היחידה שהשערים האחרים אינם יכולים לזהות מבחינה מבנית: ערך באנגלית -משוכתב, והתרגומים שנגזרו מהנוסח האנגלי _הקודם_ נשארים מאחור, כך -שמשתמשים שאינם דוברי אנגלית ממשיכים לקרוא נוסח החלטי שכעת הוא שגוי. +מאתר את נסיגת ה־i18n היחידה ששאר השערים אינם יכולים לזהות מבחינה מבנית: ערך באנגלית +נכתב מחדש, אך התרגומים שנגזרו מהאנגלית _הקודמת_ נשארים במקומם, ולכן +משתמשים שאינם דוברי אנגלית ממשיכים לקרוא נוסח נחרץ שכעת הוא שגוי. -התקלה הזו אכן הגיעה לגרסת הפצה. `oauthModal.googleOAuthWarning` שוכתב כאשר כלי העזר להתחברות של Antigravity -נוסף (#5203); ב־**39 מתוך 43 לוקאלים** נשאר טקסט שהורה למפעילים "להעתיק את -כתובת ה־URL המלאה ולהדביק אותה למטה" — תהליך שלא ניתן להשלים עבור ספק זה. הבעיה -לא התגלתה עד #8463, משום ש: +התקלה הזו אכן הגיעה לגרסה שפורסמה. `oauthModal.googleOAuthWarning` נכתב מחדש כאשר מסייע +ההתחברות של Antigravity נוסף (#5203); ב־**39 מתוך 43 אזורים** נשאר טקסט שהורה למפעילים +״להעתיק את כתובת ה־URL המלאה ולהדביק אותה למטה״ — תהליך שלא ניתן להשלים עבור ספק זה. הדבר +לא התגלה עד #8463, משום ש: - `sync-ui-keys` משלים רק מפתחות ש**חסרים**, ולעולם לא מפתחות ש**התיישנו**; - `check-ui-keys-coverage` סופר את _נוכחות_ המפתח, ולכן תרגום מיושן נחשב כמכוסה; @@ -209,24 +209,24 @@ merge-group. דחיפה, הפעלה ו־merge-group מריצים את הבחיר הוא לעולם אינו קורא את `src/i18n/messages/*.json`. חוסם במשימה `docs-sync-strict` מאז הסנכרון מחדש של 2026-09: עריכת מסמך ליבה → `npm run i18n:run -- --files=` (ברמת המקטע, זול). -**מודע להבדלים, ללא הסתמכות על קו בסיס.** הוא משווה את `en.json` בבסיס המיזוג מול -עץ העבודה; עבור כל מפתח שהערך שלו באנגלית השתנה, כל שפה שעדיין מכילה תרגום -שלא עודכן נחשבת מיושנת. הדבר **מקפיא במכוון חוב קיים** — הבדל אינו יכול לחשוף מאיזו -גרסה ישנה באנגלית הגיע תרגום ותיק, ולכן שער הבדיקה בוחן רק את מה שהשינוי הנוכחי -נוגע בו. החלופה (קו בסיס של גיבוב לכל מפתח) הייתה מוסיפה קובץ שנוצר אוטומטית בגודל -של כ־600 KB, פי 3 מקו הבסיס הקיים הגדול ביותר, ומשתנה בכל PR של i18n. +**מודע להבדלים, ללא הסתמכות על קו בסיס.** הוא משווה את `en.json` בנקודת המיזוג המשותפת לעץ +העבודה; עבור כל מפתח שהערך שלו באנגלית השתנה, כל אזור שפה שעדיין מחזיק בתרגום +שלא עודכן נחשב מיושן. כך **מוקפא במכוון חוב קיים** — הבדל אינו יכול לחשוף מאיזו +גרסה ישנה באנגלית הגיע תרגום ותיק, ולכן שער הבדיקה בוחן רק את מה שהשינוי הנוכחי נוגע +בו. החלופה (קו בסיס של גיבוב לכל מפתח) הייתה כרוכה בקובץ שנוצר אוטומטית בגודל של כ־600 KB, +פי 3 מקו הבסיס הקיים הגדול ביותר, והייתה משתנה בכל PR של i18n. יש שתי דרכים לעמוד בדרישה: 1. לעדכן את התרגומים המושפעים, או -2. להגדיר אותם כ־`__MISSING__:` — בזמן הריצה תוצג אז הגרסה המתוקנת באנגלית - (`src/i18n/request.ts::deepMergeFallback`, #7258), והמפתח ייכנס לתור לתרגום. +2. להגדיר אותם כ־`__MISSING__:` — לאחר מכן, בזמן ריצה, מוגש הטקסט המתוקן באנגלית + (`src/i18n/request.ts::deepMergeFallback`, #7258), והמפתח נכנס לתור לתרגום. -אם **משמעות** המחרוזת השתנתה, עדיף **לשנות את שם המפתח**: מפתח חדש אינו יכול לרשת +אם **המשמעות** של המחרוזת השתנתה, עדיף **לשנות את שם המפתח**: מפתח חדש אינו יכול לרשת תרגום מיושן. זהו הדפוס שבו נעשה שימוש ב־#8463. ```bash -npm run i18n:check-value-drift # מצב מחמיר (מה שמופעל ב-CI) +npm run i18n:check-value-drift # מחמיר (מה שמופעל ב־CI) npm run i18n:check-value-drift:warn # דיווח בלבד BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` @@ -236,43 +236,43 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ### משימה: `i18n` -מטריצת אימות i18n מלאה (משימה אחת לכל שפה). המשימה כולה היא בגדר המלצה. +מטריצת אימות i18n מלאה (משימה אחת לכל אזור שפה). המשימה כולה היא בגדר המלצה. -| סקריפט | מה מאומת | חוסם | -| ------------------------------- | -------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | שלמות התרגום בכל שפה | **בגדר המלצה** (`continue-on-error: true` על המשימה כולה) | +| סקריפט | מה מאומת | חוסם | +| ------------------------------- | ------------------------- | --------------------------------------------------------- | +| `validate_translation.py quick` | שלמות התרגום לכל אזור שפה | **בגדר המלצה** (`continue-on-error: true` על המשימה כולה) | ### משימה: `pr-test-policy` -מופעלת בבקשות משיכה בלבד. +פועלת בבקשות משיכה בלבד. | סקריפט | מה מאומת | חוסם | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---- | -| `check:pr-test-policy` | בקשות משיכה שמשנות קוד ייצור ב־`src/`, ב־`open-sse/`, ב־`electron/` או ב־`bin/` חייבות לכלול או לעדכן בדיקות (כלל קשיח #8) | כן | -| `check:test-masking` | קובצי בדיקה שהשתנו אינם מפחיתים את המספר הכולל נטו של טענות אימות ואינם מוסיפים טאוטולוגיות מסוג `assert.ok(true)` | כן | -| `check:pr-evidence` | גוף בקשת המשיכה מציין ראיות מבדיקות/VPS עבור השינוי (ממכן את כלל קשיח #18 באמצעות חיפוש בטקסט של בקשת המשיכה — שברירי, ראו Backlog) | כן | +| `check:pr-test-policy` | בקשות משיכה שמשנות קוד ייצור ב־`src/`, ב־`open-sse/`, ב־`electron/` או ב־`bin/` חייבות לכלול בדיקות או לעדכן אותן (כלל מחייב מס' 8) | כן | +| `check:test-masking` | קובצי בדיקות שהשתנו אינם מפחיתים את המספר הכולל נטו של טענות אימות ואינם מוסיפים טאוטולוגיות מסוג `assert.ok(true)` | כן | +| `check:pr-evidence` | גוף ה־PR מציין ראיות מבדיקות/VPS עבור השינוי (ממכן את כלל מחייב מס' 18 באמצעות חיפוש בטקסט ה־PR — שברירי, ראו רשימת משימות) | כן | ### משימה: `test-vitest` -מופעלת לאחר `build`. כישלון חוסם את המיזוג. +פועלת לאחר `build`. כשל חוסם מיזוג. | חבילת בדיקות | מה מאומת | חוסם | | ---------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| `test:vitest` | שרת MCP‏ (110 כלים), autoCombo, מטמון — מריץ vitest | כן | +| `test:vitest` | שרת MCP ‏(110 כלים), autoCombo, מטמון — מריץ vitest | כן | | `test:vitest:ui` | בדיקות רכיבי ממשק משתמש — מריץ vitest | **חוסם** — כשלים קיימים מוחרגים במפורש ב־`vitest.config.ts`; כשלים חדשים מכשילים את המשימה | ### תהליכי עבודה ליליים (מתוזמנים, בגדר המלצה) -אלה מופעלים לפי לוח זמנים של cron (וכן באמצעות `workflow_dispatch`), ולעולם לא בבקשות משיכה. כולם בגדר המלצה. +אלה פועלים לפי לוח זמנים של cron (וכן באמצעות `workflow_dispatch`), ולעולם לא בבקשות משיכה. כולם בגדר המלצה. -| תהליך עבודה | מה מאומת | חוסם | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | בדיקות מבוססות־תכונות של fast-check עם seed אקראי ומספר הרצות גבוה | **בגדר המלצה** | -| `nightly-resilience` | שער גידול ערימה, הזרקת תקלות כאוס, בדיקות עומס/מאמץ ממושך באמצעות k6 | **בגדר המלצה** | -| `nightly-llm-security` | הגנה מפני הזרקות של promptfoo (מצב חסימה) + בדיקות garak (מדולגות ללא סוד של ספק) | **בגדר המלצה** | -| `nightly-schemathesis` | בדיקות fuzzing של חוזה OpenAPI‏ (schemathesis) מול OmniRoute פעיל באמצעות `docs/openapi.yaml` — חושפות הפרות מפרט / שגיאות 500 שלא טופלו (שלב 8 B.4) | **בגדר המלצה** | -| `nightly-mutation` | ציון בדיקות מוטציה של Stryker במסלול בדיקות היחידה המהיר — מוטנטים ששרדו חושפים טענות אימות חלשות | **בגדר המלצה** | -| `nightly-compat` | מטריצת תאימות למנוע Node בטווחי `engines.node` הנתמכים | **בגדר המלצה** | +| תהליך עבודה | מה מאומת | חוסם | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | בדיקות מבוססות־מאפיינים של fast-check עם seed אקראי ומספר הרצות גבוה | **בגדר המלצה** | +| `nightly-resilience` | שער גידול ערימה, הזרקת תקלות כאוס, בדיקות עומס/שהייה ממושכת של k6 | **בגדר המלצה** | +| `nightly-llm-security` | הגנה מפני הזרקה של promptfoo (מצב חסימה) + בדיקות garak (מדולגות ללא סוד של ספק) | **בגדר המלצה** | +| `nightly-schemathesis` | בדיקות fuzzing לחוזה OpenAPI ‏(schemathesis) מול OmniRoute פעיל באמצעות `docs/openapi.yaml` — חושפות הפרות מפרט / שגיאות 500 שלא טופלו (שלב 8 B.4) | **בגדר המלצה** | +| `nightly-mutation` | ציון בדיקות מוטציה של Stryker עבור מסלול בדיקות היחידה המהיר — מוטנטים ששורדים חושפים טענות אימות חלשות | **בגדר המלצה** | +| `nightly-compat` | מטריצת תאימות למנוע Node בכל טווחי `engines.node` הנתמכים | **בגדר המלצה** | --- @@ -535,43 +535,43 @@ bot שיכול להעלות תקרה יהיה גרוע משמעותית מהמצ --- -## צבר משימות לרציונליזציה (בחינת ROI — שלב 9 גל 3) +## צבר משימות לרציונליזציה (סקירת ROI — שלב 9 גל 3) -מלאי זה הותאם מול `ci.yml` בתאריך 2026-06-17 (הגרסה הקודמת השמיטה את -`audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, -`check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). בחינת ROI של הקבוצה המותאמת -זיהתה את המועמדים הבאים לרציונליזציה. **המיזוגים הם שינויים מכניים ב-CI; -ההקשחות/ההסרות הן החלטות מדיניות השמורות למפעיל.** דבר מהאמור להלן -טרם הוחל. +מצאי זה הותאם מול `ci.yml` ב-2026-06-17 (הגרסה הקודמת השמיטה את +`audit:deps`,‏ `check:tracked-artifacts`,‏ `check:lockfile`,‏ `check:licenses`, +`check:dead-code`,‏ `check:cognitive-complexity`,‏ `check:type-coverage`, +`check:codeql-ratchet`,‏ `check:pr-evidence`). סקירת ROI של הקבוצה המותאמת +זיהתה את המועמדים הבאים לרציונליזציה. **המיזוגים הם שינויי CI מכניים; +השינויים/ההסרות הם החלטות מדיניות השמורות למפעיל.** דבר מהמפורט להלן +טרם יושם. -**פריטים נוספים שלא תועדו לעיל** (מייעצים, אות חלש): משימת `docs-lint` -(markdownlint + Vale, כל המשימה עם `continue-on-error`) ותהליכי העבודה העצמאיים של הסורקים +**גם אלה אינם מתועדים לעיל** (מייעצים, אות חלש): משימת `docs-lint` +(markdownlint + Vale, כאשר `continue-on-error` חל על המשימה כולה) ותהליכי העבודה העצמאיים של הסורקים `semgrep.yml` / `codeql.yml` / `scorecard.yml`. הערך `semgrepFindings: 0` נמצא -ב-`quality-baseline.json`, אך אינו מחובר למחגר חוסם ב-`ci.yml` — המדד -מיותם כעת. +ב-`quality-baseline.json`, אך אינו מחובר למנגנון מחגר חוסם ב-`ci.yml` — המדד +יתום כרגע. ### מיזוג / הסרת כפילויות (מכני, סיכון נמוך יותר) -כל מועמד אומת מול מצב שערי הבקרה הפעיל בתאריך 2026-06-17 (לתת אמון אך לוודא); -התברר שכמה מיזוגים "ברורים מאליהם" מסתירים חוב, ולכן הם **אינם** תחליפים ישירים ונקיים. +כל מועמד אומת מול מצב שערי הבקרה הפעיל ב-2026-06-17 (לתת אמון אך לאמת); +כמה מיזוגים "ברורים מאליהם" התגלו כמסתירים חוב, ולכן **אינם** תחליפים ישירים ונקיים. -- **`check:docs-sync` רץ פעמיים** — באופן עצמאי במשימת `lint` ושוב בתוך `check:docs-all` (`docs-sync-strict`) וב-hook של husky לפני commit. ✅ **בוצע** — ההפעלה העצמאית ב-`lint` הוסרה. -- **סריקת CVE** — ❌ **אינה מיזוג נקי.** `audit:deps` נכשל באופן קשיח בכל CVE ברמת high/critical;‏ `check:vuln-ratchet` (osv) נכשל רק במקרה של _נסיגה_ לעומת קו הבסיס (כרגע 1 ברמת MODERATE). המשמעויות שונות — הסרת `audit:deps` תבטל את שער הבקרה המוחלט לרמות high/critical. יש להשאיר את שניהם. -- **זיהוי מחזורים** — ❌ **אינו מיזוג נקי.** `check:circular-deps` (dpdm) מדווח על **91 מחזורים** (לכן הוא מייעץ); אי אפשר להפוך אותו לחוסם לפני פתרונם, וההיקף שלו רחב מזה של `check:cycles`, הירוק והמותאם. יש להשאיר את `check:cycles` כחוסם; פתרון 91 מחזורי dpdm הוא פריט נפרד בצבר המשימות. -- **מורכבות** — ✅ **בוצע** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): מעבר ESLint יחיד, עם ספירה לפי ruleId כך שקווי הבסיס של cyclomatic+max-lines ושל cognitive נשארים עצמאיים; `check:complexity` / `check:cognitive-complexity` הנפרדים נשארים לצורך `--update` מקומי. -- **מניעת הזיות ב-`/api`** — ✅ **בוצע** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): אינוונטר FS יחיד של `src/app/api`;‏ openapi-routes ו-docs-symbols עדיין מדווחים בנפרד; הפקודות הנפרדות נשארות להרצות מקומיות. -- **`check:node-runtime` רץ ב-11 משימות** — ⚠️ **ROI נמוך.** כל אחת מהן משתמשת ב-runner נפרד והבדיקה נמשכת פחות משנייה; החיסכון הכולל הוא כ-10 שניות, במחיר אובדן הגנה זולה לכל משימה. השינוי אינו מצדיק את הטלטלה. -- **`typecheck:noimplicit:core` ב-CI lint** — ✅ **הוסר ממשימת lint** (היה מייעץ עם `continue-on-error`); מעטפת הטיפוסים החוסמת היא `typecheck:core` + `check:type-coverage`. הסקריפט המקומי נשמר. +- **`check:docs-sync` מופעל פעמיים** — באופן עצמאי במשימת `lint` ושוב בתוך `check:docs-all` (`docs-sync-strict`) וב-hook של husky לפני commit. ✅ **בוצע** — ההפעלה העצמאית ב-`lint` הוסרה. +- **סריקת CVE** — ❌ **אינה מיזוג נקי.** `audit:deps` נכשל באופן קשיח בכל CVE ברמת high/critical;‏ `check:vuln-ratchet` (osv) נכשל רק במקרה של _נסיגה_ ביחס לקו הבסיס (כרגע 1 MODERATE). הסמנטיקה שונה — הסרת `audit:deps` תבטל את השער המוחלט לרמות high/critical. יש להשאיר את שניהם. +- **זיהוי מחזורים** — ✅ **בוצע** (#15159 G-01/G-02). הנוסח הישן כאן כינה את `check:cycles` שער "ירוק ואצור", והצדיק את השארתו כחוסם משום ש-`check:circular-deps` (dpdm) דיווח על 91 מחזורים. המצב הירוק הזה היה **ירוק כוזב**: `check:cycles` סרק 5 תתי-ספריות (450 קבצים), התאים רק ל-`import|export … from` סטטיים, והשמיט כל specifier מסוג `@/` ו-`@omniroute/open-sse/`, כך שלא היה יכול לזהות את מחזורי הייבוא הדינמי וה-alias ששלטו במאגר. תוקן: השער עובר כעת על `src` + `open-sse` (5023 קבצים), אוסף specifiers מתוך ה-AST של TypeScript (כך ש-`import("…")` נספר, אך `typeof import("…")` במיקום של טיפוס אינו נספר), ופותר את `paths` של tsconfig. הוא מוצא **14** מחזורים, ולא 0. מכיוון שלא ניתן לתקן 14 מחזורים קיימים מראש במסגרת PR של שער בקרה, `check:cycles` הוא כעת **מחגר** (`--ratchet`, תקרה `metrics.cycles.value = 14` בתוך `quality-baseline.json`,‏ `direction: down`) — הוא חוסם כל _נסיגה_, והספירה יכולה רק לרדת. CI מפעיל את `npm run check:cycles:ratchet`. צמצום החוב מתבצע במסגרת **A-01**. `check:circular-deps` (dpdm) נשאר מייעץ כחוות דעת שנייה רחבה יותר. +- **מורכבות** — ✅ **בוצע** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): מעבר ESLint יחיד, עם ספירה לפי ruleId כדי שקווי הבסיס של cyclomatic+max-lines ושל cognitive יישארו בלתי תלויים; `check:complexity` / `check:cognitive-complexity` הנפרדים נשארים לצורך `--update` מקומי. +- **מניעת הזיות עבור `/api`** — ✅ **בוצע** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): מצאי FS יחיד של `src/app/api`;‏ openapi-routes ו-docs-symbols עדיין מדווחים בנפרד; הבדיקות הנפרדות נשארות לצורך הרצות מקומיות. +- **`check:node-runtime` מופעל ב-11 משימות** — ⚠️ **ROI נמוך.** כל אחת מהן משתמשת ב-runner נפרד והבדיקה אורכת פחות משנייה; החיסכון הכולל הוא כ-10 שניות, במחיר אובדן אמצעי הגנה זול לכל משימה. לא שווה את הטלטלה. +- **`typecheck:noimplicit:core` ב-lint של CI** — ✅ **הוסר ממשימת lint** (היה מייעץ עם `continue-on-error`); משטח הטיפוסים החוסם הוא `typecheck:core` + `check:type-coverage`. הסקריפט המקומי נשמר. -### הקשחה / הכרעה (מדיניות המפעיל) +### שינוי / החלטה (מדיניות המפעיל) -- `check:openapi-security-tiers` (מייעץ) — ❌ **לא ניתן להפוך אותו לחוסם באופן נקי.** הוא מסיים עם 0, אך מזהיר שלכמה נתיבי `traffic-inspector` תחת `LOCAL_ONLY_API_PREFIXES` חסרה ההערה `x-loopback-only: true`. אכיפתו מחייבת הוספה מוקדמת של ההערות האלה ל-`openapi.yaml`. -- `typecheck:noimplicit:core` (מייעץ) — נכלל במידה רבה במחגר החוסם `check:type-coverage`. יש להפוך אותו למחגר או להסיר את מעבר ה-`tsc` השני והמיותר. +- `check:openapi-security-tiers` (מייעץ) — ❌ **לא ניתן להפוך אותו לחוסם באופן נקי.** הוא מסיים עם קוד 0, אך מזהיר שכמה נתיבי `traffic-inspector` תחת `LOCAL_ONLY_API_PREFIXES` חסרים את ההערה `x-loopback-only: true`. אכיפתו מחייבת להוסיף תחילה את ההערות האלה ל-`openapi.yaml`. +- `typecheck:noimplicit:core` (מייעץ) — נכלל ברובו במחגר החוסם `check:type-coverage`. יש להפוך אותו למחגר או להסיר את מעבר ה-`tsc` השני והמיותר. - `test:vitest:ui` (כעת **חוסם**) — כשלים קיימים מראש מוחרגים במפורש ב-`vitest.config.ts` באמצעות הערות מעקב `// #8618`; כשלים חדשים מכשילים את המשימה. -- `check:secrets` (gitleaks, מחגר חוסם שקפוא על 3 תוצאות חיוביות כוזבות מתועדות) — יש להוסיף את השלוש לרשימת ההחרגות כדי להגיע ל-0, או להוריד אותו למעמד מייעץ. קיימת חפיפה עם סריקת הסודות המובנית של GitHub ועם `check:public-creds`. -- `check:pr-evidence` (חוסם, מבצע grep על הפרוזה בגוף ה-PR) — סיכון גבוה לתוצאות חיוביות כוזבות; הסרתו מחלישה את אכיפת כלל קשיח מס' 18, ולכן זו החלטת מדיניות אמיתית. -- `semgrep` (תהליך עצמאי מייעץ) — חופף ל-CodeQL עבור משפחות OWASP; יש לחבר את קו הבסיס שלו למחגר או להסירו. +- `check:secrets` (gitleaks, מחגר חוסם המקובע על 3 זיהויים חיוביים כוזבים מתועדים) — יש להוסיף את השלושה לרשימת ההיתרים כדי להגיע ל-0, או להורידו למעמד מייעץ. קיימת חפיפה עם סריקת הסודות המובנית של GitHub ועם `check:public-creds`. +- `check:pr-evidence` (חוסם, מבצע grep על הטקסט החופשי בגוף ה-PR) — סיכון גבוה לזיהויים חיוביים כוזבים; הסרתו תחליש את האכיפה של כלל קשיח מס' 18, ולכן זו החלטת מדיניות אמיתית. +- `semgrep` (עצמאי ומייעץ) — חופף ל-CodeQL במשפחות OWASP; יש לחבר את קו הבסיס שלו למחגר או להסירו. --- diff --git a/docs/i18n/hi/CONTRIBUTING.md b/docs/i18n/hi/CONTRIBUTING.md index 97463e1137d..e7770572d1b 100644 --- a/docs/i18n/hi/CONTRIBUTING.md +++ b/docs/i18n/hi/CONTRIBUTING.md @@ -385,22 +385,22 @@ OAuth क्रेडेंशियल्स को `src/lib/oauth/constants/oa --- -## पुल अनुरोध चेकलिस्ट +## पुल रिक्वेस्ट चेकलिस्ट - [ ] परीक्षण सफल हैं (`npm test`) - [ ] लिंटिंग सफल है (`npm run lint`) - [ ] बिल्ड सफल है (`npm run build`) -- [ ] नए सार्वजनिक फ़ंक्शन और इंटरफ़ेस के लिए TypeScript प्रकार जोड़े गए हैं -- [ ] कोई हार्डकोड किया गया सीक्रेट या फ़ॉलबैक मान नहीं है +- [ ] नए सार्वजनिक फ़ंक्शनों और इंटरफ़ेस के लिए TypeScript प्रकार जोड़े गए हैं +- [ ] कोई हार्डकोडेड सीक्रेट या फ़ॉलबैक मान नहीं है - [ ] सार्वजनिक अपस्ट्रीम क्रेडेंशियल `resolvePublicCred()` के माध्यम से एम्बेड किए गए हैं ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) देखें), कभी भी लिटरल के रूप में नहीं -- [ ] त्रुटि प्रतिक्रियाएँ `buildErrorBody()` / `sanitizeErrorMessage()` के माध्यम से भेजी जाती हैं — प्रतिक्रिया बॉडी में कोई रॉ स्टैक ट्रेस नहीं है ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) देखें) +- [ ] त्रुटि प्रतिक्रियाएँ `buildErrorBody()` / `sanitizeErrorMessage()` के माध्यम से भेजी जाती हैं — प्रतिक्रिया बॉडी में कोई रॉ स्टैक ट्रेस नहीं ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) देखें) - [ ] शेल कमांड (`exec` / `spawn`) रनटाइम मानों को स्ट्रिंग इंटरपोलेशन के बजाय `env` के माध्यम से पास करते हैं -- [ ] सभी इनपुट Zod स्कीमा से सत्यापित किए गए हैं -- [ ] उपयोगकर्ता को प्रभावित करने वाले परिवर्तनों के लिए `changelog.d/{features|fixes|maintenance}/-.md` के अंतर्गत चेंजलॉग **फ़्रैगमेंट** जोड़ा गया है ([`changelog.d/README.md`](./changelog.d/README.md) देखें) — `CHANGELOG.md` को सीधे संपादित **न करें**; फ़्रैगमेंट रिलीज़ के समय एकत्रित किए जाते हैं और PR के बीच कभी टकराव उत्पन्न नहीं करते -- [ ] दस्तावेज़ अपडेट किए गए हैं (यदि लागू हो) -- [ ] कोई नया CodeQL / Secret-Scanning अलर्ट नहीं खुला है, या प्रत्येक को संबंधित `docs/security/` दस्तावेज़ का संदर्भ देने वाले तकनीकी औचित्य के साथ खारिज किया गया है -- [ ] चाइल्ड प्रोसेस शुरू करने वाले रूट (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` में `isLocalOnlyPath()` के रूप में वर्गीकृत किए गए हैं — [कठोर नियम #15](docs/security/ROUTE_GUARD_TIERS.md) देखें -- [ ] कमिट संदेशों में कोई `Co-Authored-By` ट्रेलर नहीं है — कमिट केवल रिपॉज़िटरी स्वामी की Git पहचान के अंतर्गत दिखाई देने चाहिए (कठोर नियम #16) +- [ ] सभी इनपुट Zod स्कीमा के साथ सत्यापित किए गए हैं +- [ ] उपयोगकर्ता-दृश्य परिवर्तनों के लिए `changelog.d/{features|fixes|maintenance}/-.md` के अंतर्गत चेंजलॉग **फ़्रैगमेंट** जोड़ा गया है ([`changelog.d/README.md`](./changelog.d/README.md) देखें) — `CHANGELOG.md` को सीधे संपादित **न करें**; फ़्रैगमेंट रिलीज़ के समय एकत्रित किए जाते हैं और PR के बीच कभी टकराव नहीं करते +- [ ] दस्तावेज़ीकरण अपडेट किया गया है (यदि लागू हो) +- [ ] कोई नया CodeQL / Secret-Scanning अलर्ट नहीं खुला है, या प्रत्येक को संबंधित `docs/security/` दस्तावेज़ का संदर्भ देते हुए तकनीकी औचित्य के साथ खारिज किया गया है +- [ ] चाइल्ड प्रोसेस शुरू करने वाले रूट (`/api/mcp/`, `/api/cli-tools/runtime/`) को `src/server/authz/routeGuard.ts` में `isLocalOnlyPath()` के रूप में वर्गीकृत किया गया है — [कठोर नियम #15](docs/security/ROUTE_GUARD_TIERS.md) देखें +- [ ] कमिट संदेशों में AI/बॉट `Co-authored-by` ट्रेलर नहीं हैं (कठोर नियम #16) — जिन मानव सहयोगियों के कार्य का पुनः उपयोग किया गया है, उन्हें मानक `Co-authored-by: Name ` ट्रेलर के साथ श्रेय दिया गया है --- diff --git a/docs/i18n/hi/docs/architecture/QUALITY_GATES.md b/docs/i18n/hi/docs/architecture/QUALITY_GATES.md index dd2c737c048..100bf73165b 100644 --- a/docs/i18n/hi/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/hi/docs/architecture/QUALITY_GATES.md @@ -21,78 +21,78 @@ CI और Quality Gates वर्कफ़्लो में से प्रत्येक एक स्थिर निर्णय देता है: `Gate / CI` और `Gate / Quality`। उनकी संस्करणबद्ध स्वीकृति नीति प्रत्येक अपस्ट्रीम जॉब को -अनिवार्य या परामर्शात्मक के रूप में सूचीबद्ध करती है। किसी लागू अनिवार्य जॉब का सफल होना आवश्यक है: -अनुपलब्ध, रद्द, छोड़े गए, लंबित और अज्ञात परिणाम PASS स्थापित नहीं कर सकते। एक मान्य +आवश्यक या परामर्शात्मक के रूप में सूचीबद्ध करती है। लागू होने वाला आवश्यक जॉब सफल होना चाहिए: +अनुपस्थित, रद्द, छोड़े गए, लंबित और अज्ञात परिणाम PASS स्थापित नहीं कर सकते। एक मान्य केवल-दस्तावेज़ या केवल-कैटलॉग वर्गीकरण किसी कोड लेन को अनुपयुक्त बना सकता है; -ड्राफ़्ट PR को स्वीकृत उम्मीदवार नहीं माना जाता। `hotfix` लेबल साक्ष्य की आवश्यकता समाप्त नहीं करता। +ड्राफ़्ट PR स्वीकार्य उम्मीदवार नहीं है। `hotfix` लेबल साक्ष्य की आवश्यकता समाप्त नहीं करता। दोनों वर्कफ़्लो PR, main/release ब्रांच पर पुश, मैन्युअल डिस्पैच और -मर्ज-ग्रुप इवेंट को कवर करते हैं। पुश, डिस्पैच और मर्ज-ग्रुप पूर्ण चयन चलाते हैं। फ़ोर्क -और मर्ज ग्रुप उन जॉब के लिए होस्टेड रनर का उपयोग करते हैं जो अन्यथा सेल्फ-होस्टेड +merge-group इवेंट को कवर करते हैं। पुश, डिस्पैच और merge-group पूर्ण चयन चलाते हैं। फ़ोर्क +और merge group उन जॉब के लिए होस्टेड रनर का उपयोग करते हैं जो अन्यथा self-hosted रनर चुनते हैं; रोलआउट से पहले पर्याप्त होस्टेड क्षमता सत्यापित की जानी चाहिए। प्रत्येक JSON रसीद चेक-आउट किए गए SHA, वर्कफ़्लो रन और प्रयास की पहचान करती है। -CLI, चेकआउट/इवेंट SHA के बेमेल होने को अस्वीकार करता है। वर्कफ़्लो परीक्षण नीति सदस्यता को +CLI, checkout/event SHA के बेमेल को अस्वीकार करता है। वर्कफ़्लो परीक्षण नीति सदस्यता को निर्णय जॉब की `needs` सूची से बाँधते हैं, ताकि कोई नई या हटाई गई लेन चुपचाप गायब न हो सके। रसीदें अपने स्वयं के वर्कफ़्लो को कवर करती हैं, प्रकाशन, परिनियोजन या किसी मौजूदा -परामर्शात्मक स्कैनर के आंतरिक भागों को नहीं। ब्रांच नियमों में दोनों चेक नाम सक्रिय करना +परामर्शात्मक स्कैनर की आंतरिक कार्यप्रणाली को नहीं। ब्रांच नियमों में दोनों चेक नाम सक्रिय करना एक अलग प्रशासनिक परिवर्तन है; इन जॉब को जोड़ना अपने आप किसी ब्रांच को सुरक्षित नहीं करता। -### स्टैटिक स्कैन इन्वेंटरी +### स्थैतिक स्कैन इन्वेंटरी -संस्करणबद्ध npm-अलियास इन्वेंटरी और स्टैटिक-स्कैन सदस्यता +संस्करणबद्ध npm-alias इन्वेंटरी और स्थैतिक-स्कैन सदस्यता `config/quality/gate-manifest.json` में मौजूद हैं। स्क्रिप्ट नामों और सटीक कमांड को -`package.json` के विरुद्ध सत्यापित करने के लिए `npm run check:gate-manifest` चलाएँ; जोड़, -हटाने और कमांड में बदलाव होने पर लोकल हुक तथा CI में परिवर्तन-वर्गीकरण जॉब, दोनों विफल हो जाते हैं। -कोई अलियास वर्कफ़्लो जॉब, मैट्रिक्स इंस्टेंस या टेस्ट केस नहीं होता: इन गणनाओं को +`package.json` के विरुद्ध सत्यापित करने के लिए `npm run check:gate-manifest` चलाएँ; जोड़ने, हटाने +और कमांड में विचलन होने पर स्थानीय हुक और CI में परिवर्तन-वर्गीकरण जॉब, दोनों विफल हो जाते हैं। +कोई alias वर्कफ़्लो जॉब, मैट्रिक्स इंस्टेंस या परीक्षण केस नहीं होता: इन संख्याओं को परस्पर विनिमेय के रूप में प्रस्तुत नहीं किया जाना चाहिए। -चयनित अलियास को निष्पादित किए बिना उनका निरीक्षण करने के लिए -`npm run quality:scan -- --list` या `npm run quality:scan:fast -- --list` का उपयोग करें। -रनर npm एंट्रीपॉइंट को इनवोक करता है, इसलिए उसका रनटाइम (कॉन्फ़िगर किए जाने पर Bun सहित) -संरक्षित रहता है। मैनिफ़ेस्ट उन प्रोफ़ाइल से बाहर के अलियास को अलग से इनवोक किए गए के रूप में -दर्ज करता है, और केवल-पढ़ने योग्य स्कैन प्रोफ़ाइल में रखरखाव कमांड निषिद्ध हैं। +चयनित alias को निष्पादित किए बिना देखने के लिए `npm run quality:scan -- --list` या +`npm run quality:scan:fast -- --list` का उपयोग करें। रनर npm entrypoint को आमंत्रित करता है, +इसलिए उसका रनटाइम (जहाँ कॉन्फ़िगर किया गया हो वहाँ Bun सहित) संरक्षित रहता है। +मैनिफ़ेस्ट उन प्रोफ़ाइल के बाहर के alias को अलग से आमंत्रित किए गए के रूप में दर्ज करता है, और +केवल-पढ़ने योग्य स्कैन प्रोफ़ाइल में रखरखाव कमांड निषिद्ध हैं। -ये प्रोफ़ाइल केवल स्टैटिक स्कैन को कवर करती हैं। ये उत्पाद परीक्षण, +ये प्रोफ़ाइल केवल स्थैतिक स्कैन को कवर करती हैं। वे उत्पाद परीक्षण, कवरेज, पैकेजिंग, बाहरी जाँच या किसी उम्मीदवार की पूर्ण रिलीज़ स्वीकृति को प्रमाणित नहीं करतीं। वर्कफ़्लो स्वीकृति लिंक किए गए `config/quality/admission-policy.json` और `scripts/quality/admission-verdict.mjs` का उपयोग करती है। Release-observer प्रोफ़ाइल अलग रहती हैं; -उनकी लागू जाँचों और रसीदों का स्वतंत्र रूप से निरीक्षण करें। नीचे दी गई वर्णनात्मक -इन्वेंटरी एक संदर्भ है, यह इस बात का प्रमाण नहीं है कि कोई गेट वास्तव में चला था। +उनकी लागू जाँचों और रसीदों का स्वतंत्र रूप से निरीक्षण करें। नीचे दी गई गद्य +इन्वेंटरी एक संदर्भ है, इस बात का प्रमाण नहीं कि कोई गेट वास्तव में चला था। -स्क्रिप्ट `scripts/check/` (नीति गेट) और `scripts/quality/` (रैचेट इंजन) के अंतर्गत होती हैं। +स्क्रिप्ट `scripts/check/` (नीति गेट) और `scripts/quality/` (ratchet इंजन) के अंतर्गत मौजूद हैं। CI का प्रामाणिक स्रोत `.github/workflows/ci.yml` है। ### रिलीज़ PR फ़ास्ट-पाथ (`quality.yml`) `.github/workflows/quality.yml`, main/release PR, संरक्षित-ब्रांच -पुश, डिस्पैच और मर्ज ग्रुप पर CI का पूरक है। PR पाथ-फ़िल्टर की गई तेज़ जाँचों का उपयोग करते हैं। स्थायी रूप से -अक्षम डुप्लिकेट बिल्ड हटा दिया गया था; वास्तविक बिल्ड/पैकेज/बूट जाँचें CI में बनी रहती हैं। - -| जॉब | दायरा | अवरोधक | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | दस्तावेज़/कोड PR; API दस्तावेज़ संदर्भ और सभी दस्तावेज़ | हाँ | -| `Fast Quality Gates` | कोड PR; स्टैटिक जाँचें, टाइपचेक, डैशबोर्ड टाइपचेक, प्रभावित यूनिट परीक्षण | हाँ | -| `Forgotten sibling tests` | कोड PR; परिवर्तित मॉड्यूल से स्टैटिक उपभोक्ताओं और संभावित सिबलिंग परीक्षणों तक ट्रेसिंग; बैरल और डायनेमिक-इम्पोर्ट पाथ को संदर्भित अलाउलिस्ट अपवादों के साथ परामर्शात्मक डायग्नोस्टिक के रूप में रिपोर्ट किया जाता है | **परामर्शात्मक** | -| `Vitest (fast-path)` | कोड PR; तेज़ vitest सुइट | हाँ | -| `Unit Tests fast-path` | कोड PR; 4-शार्ड यूनिट सुइट | हाँ | -| `No new ESLint warnings` | कोड PR; सप्रेशन-जागरूक लिंट गार्ड | हाँ, फ़ोर्क सहित | -| `Merge integrity (changelog + generated skills)` | गैर-ड्राफ़्ट PR; चेंजलॉग और जनरेटेड स्किल सिंक | हाँ, फ़ोर्क सहित | - -#### भूले हुए सिबलिंग परीक्षणों की रिपोर्ट - -`npm run check:forgotten-sibling-tests`, टेस्ट-इम्पैक्ट मैप के पीछे मौजूद इम्पोर्ट रिज़ॉल्वर का पुनः उपयोग करता है। -प्रत्येक परिवर्तित प्रोडक्शन मॉड्यूल के लिए, जब संभावित -परीक्षण पुल-रिक्वेस्ट डिफ़ में अनुपस्थित होता है, तो यह नियतात्मक +पुश, डिस्पैच और merge group पर CI का पूरक है। PR पाथ-फ़िल्टर की गई तेज़ जाँचों का उपयोग करते हैं। स्थायी रूप से +अक्षम डुप्लिकेट बिल्ड हटा दिया गया था; वास्तविक build/package/boot जाँचें CI में बनी हुई हैं। + +| जॉब | दायरा | अवरोधक | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `Docs Gates (fast-path)` | Docs/code PR; API docs संदर्भ और docs-all | हाँ | +| `Fast Quality Gates` | Code PR; स्थैतिक जाँचें, typecheck, dashboard typecheck, प्रभावित unit tests | हाँ | +| `Forgotten sibling tests` | Code PR; बदले हुए मॉड्यूल से स्थैतिक उपभोक्ताओं और संभावित sibling tests तक अनुरेखण; barrel और dynamic-import पाथ को परामर्शात्मक निदान के रूप में रिपोर्ट किया जाता है, साथ ही संदर्भित allowlist अपवाद भी | **परामर्शात्मक** | +| `Vitest (fast-path)` | Code PR; तेज़ vitest suite | हाँ | +| `Unit Tests fast-path` | Code PR; 4-shard unit suite | हाँ | +| `No new ESLint warnings` | Code PR; suppression-aware lint guard | हाँ, फ़ोर्क सहित | +| `Merge integrity (changelog + generated skills)` | गैर-ड्राफ़्ट PR; changelog और जनरेटेड skill sync | हाँ, फ़ोर्क सहित | + +#### भूले हुए sibling tests की रिपोर्ट + +`npm run check:forgotten-sibling-tests`, test-impact map के पीछे मौजूद import resolver का पुनः उपयोग करता है। +प्रत्येक बदले हुए production module के लिए, जब संभावित +test pull-request diff में अनुपस्थित होता है, तो यह नियतात्मक `changed module/symbol -> static consumer -> candidate sibling test` शृंखलाओं की रिपोर्ट करता है। किसी भी अवरोधक रोलआउट से पहले अंशांकन के लिए Markdown सारांश और JSON परिणाम को `forgotten-sibling-tests` वर्कफ़्लो आर्टिफ़ैक्ट के रूप में बनाए रखा जाता है। -बैरल री-एक्सपोर्ट और डायनेमिक इम्पोर्ट केवल रिज़ॉल्यूशन डायग्नोस्टिक्स हैं; वे कभी भी +बैरल री-एक्सपोर्ट और डायनेमिक इंपोर्ट केवल रिज़ॉल्यूशन डायग्नोस्टिक्स हैं; वे कभी भी ब्लॉकिंग निष्कर्ष उत्पन्न नहीं करते। समीक्षा किए गए अपवाद -`config/quality/forgotten-sibling-allowlist.json` में होते हैं। प्रत्येक प्रविष्टि में कंज़्यूमर और उम्मीदवार -टेस्ट का नाम, एक विशिष्ट औचित्य, और किसी GitHub इश्यू या पुल रिक्वेस्ट का लिंक होना आवश्यक है। विकृत प्रविष्टियाँ -डिफ़ॉल्ट रूप से विफल होती हैं। अपवाद किसी हटाए गए उम्मीदवार टेस्ट या `.skip`/`.todo` जोड़ने वाले डिफ़ को दबा नहीं सकते; +`config/quality/forgotten-sibling-allowlist.json` में मौजूद हैं। प्रत्येक प्रविष्टि में उपभोक्ता और उम्मीदवार +टेस्ट का नाम होना चाहिए, एक विशिष्ट औचित्य दिया जाना चाहिए, और GitHub इश्यू या पुल रिक्वेस्ट से लिंक होना चाहिए। विकृत प्रविष्टियाँ +क्लोज़्ड स्थिति में विफल होती हैं। अपवाद किसी हटाए गए उम्मीदवार टेस्ट या `.skip`/`.todo` जोड़ने वाले डिफ़ को दबा नहीं सकते; असर्शन को कमज़ोर करना और अन्य मास्किंग स्वतंत्र रूप से ब्लॉक करने वाले `check:test-masking` गेट के अधीन रहते हैं। @@ -100,131 +100,131 @@ CI का प्रामाणिक स्रोत `.github/workflows/ci.yml` `main` के प्रत्येक PR पर चलता है। विफलता होने पर मर्ज को ब्लॉक करता है। -| स्क्रिप्ट (`npm run ...`) | सत्यापित करता है | ब्लॉकिंग | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Node.js संस्करण समर्थित सीमा के भीतर है | हाँ | -| `check:cycles` | सर्कुलर इम्पोर्ट — सभी `src/` + `open-sse/` मॉड्यूल | हाँ | -| `check:route-validation:t06` | सभी रूट पर Zod स्कीमा मौजूद हैं (टियर 6 नीति) | हाँ | -| `check:any-budget:t11` | `@ts-expect-error // any` की संख्या बजट से अधिक नहीं है (टियर 11 catraca) | हाँ | -| `check:provider-consistency` | `providers.ts` में प्रत्येक प्रदाता की `providerRegistry.ts` में एक संगत प्रविष्टि है (और इसके विपरीत, अनुमति-सूची के भीतर) | हाँ | -| `check:model-lifecycle` | हाथ से अनुरक्षित तीन रूटिंग तालिकाएँ चेक-इन किए गए जीवनचक्र स्नैपशॉट (#11503) के अनुरूप रहती हैं: `FITNESS_TABLE` (`taskFitness.ts`) ऐसे किसी सेवानिवृत्त id को स्कोर नहीं करती जिसे `REGISTRY` रूट कर सकती है; प्रत्येक `BUILT_IN_ALIASES` लक्ष्य `REGISTRY` में मौजूद है और सेवानिवृत्त-id स्नैपशॉट में अनुपस्थित है; `REGISTRY` में अब भी मौजूद प्रत्येक सेवानिवृत्त id को अग्रेषित किया गया है या `allowedRetiredInCatalog` में सूचीबद्ध किया गया है; और कोई भी `DEFAULT_DEGRADATION_MAP` स्रोत या लक्ष्य उस स्नैपशॉट में सेवानिवृत्त नहीं दिखता। इससे यह सिद्ध नहीं होता कि कोई मॉडल वर्तमान में किसी सक्रिय अपस्ट्रीम द्वारा उपलब्ध कराया जा रहा है। ऑफ़लाइन — `config/quality/model-lifecycle.json` से तुलना करता है, जिसे `npm run quality:refresh-model-lifecycle` (नेटवर्क; CI से संबद्ध नहीं) के साथ हाथ से रीफ़्रेश किया जाता है। `allowedRetiredInCatalog` एक क्रमिक कटौती वाला रैचेट है: केवल ट्रैकिंग इश्यू के साथ ही कोई प्रविष्टि जोड़ें। | हाँ | -| `check:fetch-targets` | क्लाइंट-साइड `src/` में प्रत्येक `fetch("/api/...")` किसी वास्तविक `route.ts` पर रिज़ॉल्व होता है | हाँ | -| `check:deps` | रिपॉज़िटरी में प्रत्येक `package.json` की सभी `npm install`-योग्य निर्भरताएँ `dependency-allowlist.json` में हैं; नए अनपिन किए गए या स्लॉपस्क्वाट किए गए पैकेज चिह्नित किए जाते हैं | हाँ | -| `audit:deps` | `npm audit` (रूट + इलेक्ट्रॉन) — कोई उच्च/गंभीर परामर्श नहीं (osv `check:vuln-ratchet` के साथ ओवरलैप करता है; युक्तिकरण बैकलॉग देखें) | हाँ | -| `check:lockfile` | `package-lock.json` की अखंडता — https रजिस्ट्री, अखंडता हैश, कोई होस्ट ओवरराइड नहीं | हाँ | -| `check:licenses` | प्रोडक्शन डिपेंडेंसीज़ के लिए SPDX लाइसेंस अनुमत-सूची | हाँ | -| `check:tracked-artifacts` | कोई बिल्ड आर्टिफ़ैक्ट / कमिट किए गए `node_modules` सिमलिंक नहीं (husky pre-commit में भी चलता है; pre-push को जानबूझकर हल्का रखा गया है — #6716) | हाँ | -| `check:ai-attribution` | PR कमिट्स, शीर्षक या बॉडी में कोई AI/bot `Co-Authored-By` ट्रेलर या AI-जनरेशन फ़ुटर नहीं — कठोर नियम #16 (`quality.yml` के PR→`release/**` फ़ास्ट-गेट्स लूप में — इवेंट पेलोड पढ़ता है, PR के बाहर कोई कार्रवाई नहीं करता — और PR→`main` के लिए `ci.yml` लिंट में केवल-PR चरण; साथ ही husky `commit-msg` हुक; मानव सह-लेखकों की अनुमति है; #14436) | -| `check:vitest-exclusions` | प्रत्येक Vitest अपवर्जन में एक ट्रैकिंग इश्यू का उल्लेख हो और वह `config/quality/vitest-exclusions.json` में मौजूद हो (#13204) | हाँ | -| `check:file-size` | कोई भी सोर्स फ़ाइल प्रति-एक्सटेंशन सीमा से अधिक न हो (रैचेट: `frozen` सूची में फ़्रीज़ की गई बड़ी फ़ाइलें) | हाँ | -| `check:error-helper` | एक्ज़ीक्यूटर्स/हैंडलर्स में त्रुटि प्रतिक्रियाएँ `buildErrorBody()` / `sanitizeErrorMessage()` का उपयोग करती हैं (कठोर नियम #12) | हाँ | -| `check:migration-numbering` | माइग्रेशन SQL फ़ाइलें क्रमिक रूप से क्रमांकित हैं, बिना किसी अंतराल या डुप्लिकेट के | हाँ | -| `check:public-creds` | `publicCreds.ts` के बाहर कोई भी शाब्दिक OAuth `client_id`/`client_secret` या Firebase Web कुंजी नहीं है (कठोर नियम #11) | हाँ | -| `check:db-rules` | `src/lib/db/` मॉड्यूल के बाहर कोई रॉ SQL नहीं है; `localDb.ts` से कोई बैरल-इम्पोर्ट नहीं है (कठोर नियम #2/#5) | हाँ | -| `check:known-symbols` | अपनी डिस्पैच तालिकाओं में पंजीकृत प्रोवाइडर एक्ज़ीक्यूटर, रूटिंग रणनीतियाँ और ट्रांसलेटर डिस्क पर मौजूद फ़ाइलों से मेल खाते हैं—कोई अनाथ या अघोषित सिंबल नहीं है | हाँ | -| `check:route-guard-membership` | चाइल्ड प्रोसेस शुरू करने वाला प्रत्येक रूट `isLocalOnlyPath()` द्वारा वर्गीकृत है (कठोर नियम #15/#17) | हाँ | -| `check:test-discovery` | रिपॉज़िटरी की प्रत्येक `*.test.ts` / `*.spec.ts` फ़ाइल कम-से-कम एक टेस्ट रनर द्वारा एकत्र की जाती है (रैचेट: `test-discovery-baseline.json` में अनाथ फ़ाइलों की सूची केवल छोटी हो सकती है) | हाँ | -| `check:agent-skills-sync` | जनरेट किए गए agent-skills आर्टिफ़ैक्ट उनकी स्रोत कैटलॉग से मेल खाते हैं (कोई विचलन नहीं) | -| `check:provider-asset-provenance` | Provider लोगो/एसेट के साथ एक दर्ज provenance प्रविष्टि होती है | -| `lint:json` | JSON कॉन्फ़िगरेशन फ़ाइलें सफलतापूर्वक पार्स होती हैं और repo के lint नियमों का पालन करती हैं | -| `typecheck:core` | त्रुटियों के बिना TypeScript संकलन (केवल परामर्शात्मक चेतावनियाँ) | हाँ | -| `typecheck:noimplicit:core` | सख़्त `noImplicitAny` — भविष्य-उन्मुख; पहले से मौजूद कई call sites में अब भी annotations की आवश्यकता है | **परामर्शात्मक** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, `src/app/(dashboard)/**` तक सीमित है (#7033) — `typecheck:core` की चयनित 27-फ़ाइल allowlist में कोई dashboard TSX शामिल नहीं है, और `next build` भी कभी इसका type-check नहीं करता (`next.config.mjs` में `ignoreBuildErrors: true` सेट है), इसलिए वहाँ orphaned-identifier regressions (#6625/#6909) CI को दिखाई नहीं देते थे। एक स्थिर, प्रति-फ़ाइल/प्रति-TS-code गणना baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` के समान stale-enforcement पैटर्न) के विरुद्ध अंतर निकाला जाता है — baseline की गई गणना से अधिक केवल नई त्रुटियाँ ही gate को विफल करती हैं; पहले से मौजूद त्रुटि ठीक होने पर `--update` के साथ इसे क्रमशः कम करें। | हाँ | +| स्क्रिप्ट (`npm run ...`) | सत्यापित करता है | ब्लॉकिंग | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Node.js संस्करण समर्थित सीमा के भीतर है | हाँ | +| `check:cycles` | पूरे `src/` + `open-sse/` में सर्कुलर इंपोर्ट (AST-आधारित, tsconfig `paths` रिज़ॉल्व किए गए)। Bare = परामर्शात्मक, साइकल सूचीबद्ध करता है। `check:cycles:ratchet` (जिसे CI चलाता है) तब ब्लॉक करता है जब संख्या `quality-baseline.json` में `metrics.cycles` की अधिकतम सीमा से अधिक हो जाती है — वर्तमान में 14, `direction: down`, इसलिए यह केवल घट सकती है (#15159 G-01/G-02) | हाँ (रैचेट) | +| `check:route-validation:t06` | सभी रूट पर Zod स्कीमा मौजूद हैं (Tier 6 नीति) | हाँ | +| `check:any-budget:t11` | `@ts-expect-error // any` की संख्या बजट से अधिक नहीं है (Tier 11 catraca) | हाँ | +| `check:provider-consistency` | `providers.ts` में प्रत्येक provider की `providerRegistry.ts` में एक संगत entry है (और इसके विपरीत भी, allowlist के भीतर) | हाँ | +| `check:model-lifecycle` | हाथ से अनुरक्षित तीनों routing tables, checked-in lifecycle snapshot (#11503) के साथ संगत रहती हैं: `FITNESS_TABLE` (`taskFitness.ts`) ऐसे किसी retired id को score नहीं करती जिसे `REGISTRY` route कर सकती है; प्रत्येक `BUILT_IN_ALIASES` target `REGISTRY` में मौजूद है और retired-id snapshot में अनुपस्थित है; `REGISTRY` में अब भी मौजूद प्रत्येक retired id को forward किया गया है या `allowedRetiredInCatalog` में सूचीबद्ध किया गया है; और कोई भी `DEFAULT_DEGRADATION_MAP` source या target उस snapshot में retired नहीं दिखता। इससे यह सिद्ध नहीं होता कि कोई model वर्तमान में किसी live upstream द्वारा उपलब्ध कराया जा रहा है। Offline — `config/quality/model-lifecycle.json` के साथ तुलना करता है, जिसे `npm run quality:refresh-model-lifecycle` से हाथ से refresh किया जाता है (network; CI में शामिल नहीं)। `allowedRetiredInCatalog` एक burn-down ratchet है: कोई entry केवल tracking issue के साथ ही जोड़ें। | हाँ | +| `check:fetch-targets` | client-side `src/` में प्रत्येक `fetch("/api/...")` किसी वास्तविक `route.ts` पर resolve होता है | हाँ | +| `check:deps` | repo के प्रत्येक `package.json` में मौजूद सभी `npm install`-योग्य deps `dependency-allowlist.json` में हैं; नए unpinned या slopsquatted packages को flag किया जाता है | हाँ | +| `audit:deps` | `npm audit` (root + electron) — कोई high/critical advisory नहीं (`check:vuln-ratchet` osv के साथ overlap करता है; Rationalization Backlog देखें) | हाँ | +| `check:lockfile` | `package-lock.json` की integrity — https registry, integrity hashes, कोई host override नहीं | हाँ | +| `check:licenses` | प्रोडक्शन डिपेंडेंसीज़ के लिए SPDX लाइसेंस अनुमत-सूची | हाँ | +| `check:tracked-artifacts` | कोई बिल्ड आर्टिफ़ैक्ट / कमिट किए गए `node_modules` सिमलिंक नहीं (husky pre-commit में भी चलता है; pre-push को जानबूझकर हल्का रखा गया है — #6716) | हाँ | +| `check:ai-attribution` | PR कमिट्स, शीर्षक या बॉडी में कोई AI/bot `Co-Authored-By` ट्रेलर या AI-जेनरेशन फ़ुटर नहीं — कठोर नियम #16 (`quality.yml` के PR→`release/**` फ़ास्ट-गेट्स लूप में — इवेंट पेलोड पढ़ता है, PR के बाहर कोई कार्रवाई नहीं करता — और PR→`main` के लिए `ci.yml` लिंट में एक केवल-PR चरण; साथ ही husky `commit-msg` हुक; मानव सह-लेखकों की अनुमति है; #14436) | +| `check:vitest-exclusions` | प्रत्येक Vitest अपवर्जन में किसी ट्रैकिंग इश्यू का उल्लेख होता है और वह `config/quality/vitest-exclusions.json` में मौजूद होता है (#13204) | हाँ | +| `check:file-size` | कोई भी स्रोत फ़ाइल प्रति-एक्सटेंशन सीमा से अधिक नहीं होती (रैचेट: `frozen` सूची में फ़्रीज़ की गई बड़ी फ़ाइलें) | हाँ | +| `check:error-helper` | एक्ज़ीक्यूटर/हैंडलर में त्रुटि प्रतिक्रियाएँ `buildErrorBody()` / `sanitizeErrorMessage()` का उपयोग करती हैं (कठोर नियम #12) | हाँ | +| `check:migration-numbering` | Migration SQL फ़ाइलें क्रमिक रूप से क्रमांकित हैं, जिनमें कोई अंतराल या डुप्लिकेट नहीं है | हाँ | +| `check:public-creds` | `publicCreds.ts` के बाहर कोई शाब्दिक OAuth `client_id`/`client_secret` या Firebase Web कुंजी नहीं है (कठोर नियम #11) | हाँ | +| `check:db-rules` | `src/lib/db/` मॉड्यूल के बाहर कोई रॉ SQL नहीं है; `localDb.ts` से कोई बैरल-इम्पोर्ट नहीं है (कठोर नियम #2/#5) | हाँ | +| `check:known-symbols` | अपनी डिस्पैच तालिकाओं में पंजीकृत प्रदाता एक्ज़ीक्यूटर, रूटिंग रणनीतियाँ और ट्रांसलेटर डिस्क पर मौजूद फ़ाइलों से मेल खाते हैं—कोई अनाथ या अघोषित सिंबल नहीं है | हाँ | +| `check:route-guard-membership` | चाइल्ड प्रोसेस आरंभ करने वाला प्रत्येक रूट `isLocalOnlyPath()` द्वारा वर्गीकृत है (कठोर नियम #15/#17) | हाँ | +| `check:test-discovery` | रिपॉज़िटरी की प्रत्येक `*.test.ts` / `*.spec.ts` फ़ाइल कम-से-कम एक टेस्ट रनर द्वारा एकत्र की जाती है (रैचेट: `test-discovery-baseline.json` में अनाथ सूची केवल छोटी हो सकती है) | हाँ | +| `check:agent-skills-sync` | जनरेट किए गए agent-skills आर्टिफ़ैक्ट अपनी स्रोत कैटलॉग से मेल खाते हैं (कोई अंतर नहीं) | +| `check:provider-asset-provenance` | Provider लोगो/एसेट के लिए दर्ज provenance प्रविष्टि मौजूद है | +| `lint:json` | JSON कॉन्फ़िग फ़ाइलें सफलतापूर्वक पार्स होती हैं और repo के lint नियमों को पूरा करती हैं | +| `typecheck:core` | बिना त्रुटियों के TypeScript कंपाइलेशन (केवल परामर्शात्मक चेतावनियाँ) | हाँ | +| `typecheck:noimplicit:core` | सख़्त `noImplicitAny` — भविष्य-उन्मुख; पहले से मौजूद कई call sites में अभी भी annotations की आवश्यकता है | **परामर्शात्मक** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, `src/app/(dashboard)/**` तक सीमित है (#7033) — `typecheck:core` की चयनित 27-फ़ाइल allowlist में कोई dashboard TSX शामिल नहीं है, और `next build` भी कभी इसका type-check नहीं करता (`next.config.mjs` में `ignoreBuildErrors: true` सेट है), इसलिए वहाँ orphaned-identifier regressions (#6625/#6909) CI को दिखाई नहीं देते थे। एक स्थिर की गई प्रति-फ़ाइल/प्रति-TS-code गणना baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` के समान stale-enforcement पैटर्न) के विरुद्ध अंतर की जाँच करता है — baseline गणना से परे केवल नई त्रुटियाँ ही gate को विफल करती हैं; पहले से मौजूद त्रुटि ठीक होने पर `--update` के साथ सीमा घटाएँ। | हाँ | ### Job: `quality-gate` `test-coverage` के बाद चलता है। विफलता होने पर merge को रोकता है। -| स्क्रिप्ट | सत्यापित करता है | अवरोधक | -| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `quality:collect` | `quality-metrics.json` उत्सर्जित करता है (ESLint चेतावनियों की संख्या, मर्ज की गई शार्ड रिपोर्ट से कवरेज) | हाँ (रैचेट से पहले) | -| `quality:ratchet` | `quality-baseline.json` में प्रत्येक मेट्रिक में गिरावट नहीं हुई है (ESLint चेतावनियाँ ≤ बेसलाइन; कवरेज ≥ बेसलाइन) | हाँ | -| `check:duplication` | कोड दोहराव (jscpd@4) `quality-baseline.json` में निर्धारित बेसलाइन से अधिक नहीं है | हाँ | -| `check:complexity` | फ़ाइल-स्तरीय साइक्लोमैटिक जटिलता निर्धारित सीमा से अधिक नहीं है (कोर ESLint `complexity` + `max-lines-per-function`) | हाँ | -| `check:cognitive-complexity` | संज्ञानात्मक जटिलता रैचेट (`eslint-plugin-sonarjs`) — अलग ESLint पास; CI दोनों को एकल `check:complexity-ratchets` चरण के रूप में मर्ज करके चलाता है | हाँ | -| `check:dead-code` | अप्रयुक्त एक्सपोर्ट / फ़ाइलों का रैचेट (knip) बेसलाइन की तुलना में खराब नहीं होता | हाँ | -| `check:compression-budget` | कम्प्रेशन बेंचमार्क बजट — प्रत्येक इंजन के लिए टोकन-बचत की न्यूनतम सीमाओं में गिरावट नहीं होनी चाहिए | हाँ | -| `check:type-coverage` | टाइप किए गए प्रतिशत का रैचेट (`type-coverage`) खराब नहीं होता; यह मोटे तौर पर `typecheck:noimplicit:core` को समाहित करता है | हाँ | -| `check:codeql-ratchet` | खुले CodeQL अलर्ट की संख्या में वृद्धि नहीं होती (`gh api` के माध्यम से पढ़ता है; टोकन के बिना सुचारु रूप से छोड़ देता है) — रीफ़्रेश आवृत्ति और मैन्युअल ट्रिगर के लिए: नीचे "CodeQL रैचेट" देखें | हाँ | +| स्क्रिप्ट | सत्यापित करता है | अवरोधक | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `quality:collect` | `quality-metrics.json` उत्सर्जित करता है (ESLint चेतावनी संख्या, मर्ज की गई शार्ड रिपोर्ट से कवरेज) | हाँ (रैचेट से पहले) | +| `quality:ratchet` | `quality-baseline.json` में प्रत्येक मेट्रिक में गिरावट नहीं हुई है (ESLint चेतावनियाँ ≤ बेसलाइन; कवरेज ≥ बेसलाइन) | हाँ | +| `check:duplication` | कोड दोहराव (jscpd@4), `quality-baseline.json` में निर्धारित बेसलाइन से अधिक नहीं है | हाँ | +| `check:complexity` | फ़ाइल-स्तरीय साइक्लोमैटिक जटिलता निर्धारित सीमा से अधिक नहीं है (कोर ESLint `complexity` + `max-lines-per-function`) | हाँ | +| `check:cognitive-complexity` | संज्ञानात्मक जटिलता रैचेट (`eslint-plugin-sonarjs`) — अलग ESLint पास; CI दोनों को एकल `check:complexity-ratchets` चरण के रूप में मर्ज करके चलाता है | हाँ | +| `check:dead-code` | अप्रयुक्त एक्सपोर्ट / फ़ाइलों का रैचेट (knip), बेसलाइन की तुलना में खराब नहीं होता | हाँ | +| `check:compression-budget` | संपीड़न बेंचमार्क बजट — प्रति-इंजन टोकन-बचत की न्यूनतम सीमाओं में गिरावट नहीं होनी चाहिए | हाँ | +| `check:type-coverage` | टाइप किए गए प्रतिशत का रैचेट (`type-coverage`) खराब नहीं होता; यह बड़े पैमाने पर `typecheck:noimplicit:core` को समाहित करता है | हाँ | +| `check:codeql-ratchet` | खुले CodeQL अलर्ट की संख्या में बढ़ोतरी नहीं होती (`gh api` के माध्यम से पढ़ता है; टोकन न होने पर सुचारु रूप से छोड़ देता है) — रीफ़्रेश आवृत्ति और मैन्युअल ट्रिगर: नीचे "CodeQL रैचेट" देखें | हाँ | ### जॉब: `quality-extended` पूरा जॉब परामर्शात्मक है (`continue-on-error: true`)। npm-आधारित रैचेट वास्तव में चलते हैं; बाहरी स्कैनर `gh release download` के माध्यम से इंस्टॉल होते हैं और बाइनरी -अभी भी अनुपस्थित होने पर स्वयं छोड़ देते हैं (exit 0)। +अब भी अनुपस्थित होने पर स्वयं को छोड़ देते हैं (exit 0)। -| स्क्रिप्ट | सत्यापित करता है | अवरोधक स्थिति | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| `check:circular-deps` | कोई सर्कुलर डिपेंडेंसी नहीं है (dpdm) | **परामर्शात्मक** | -| `check:bundle-size` | बंडल का आकार निर्धारित सीमा से अधिक नहीं है | **परामर्शात्मक** | -| `check:secrets` | सीक्रेट स्कैनिंग (gitleaks) — बाइनरी अनुपस्थित होने पर छोड़ देता है | **परामर्शात्मक** | -| `check:vuln-ratchet` | डिपेंडेंसी कमज़ोरियाँ (osv-scanner) नहीं बढ़तीं — बाइनरी अनुपस्थित होने पर छोड़ देता है | **परामर्शात्मक** | -| `check:workflows` | वर्कफ़्लो लिंट (actionlint + zizmor); अनुपस्थित/खराब स्कैनर, अमान्य रिपोर्ट या अनुपस्थित रैचेट बेसलाइन को INCOMPLETE मानकर विफल करता है। मान्य निष्कर्ष चयनित सख्त/परामर्शात्मक/रैचेट नीति का पालन करते हैं | निष्पादन आवश्यक; CI में zizmor रैचेट अवरोधक है | -| `check:openapi-breaking` | बेस ब्रांच की तुलना में सार्वजनिक API अनुबंध (`openapi.yaml`) में ब्रेकिंग परिवर्तन (oasdiff) — `openapiBreaking=N` उत्सर्जित करता है; oasdiff अनुपस्थित होने या बेस स्पेसिफ़िकेशन हल न हो पाने पर छोड़ देता है | **परामर्शात्मक** | +| स्क्रिप्ट | सत्यापित करता है | अवरोधक | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:circular-deps` | कोई चक्रीय निर्भरता नहीं है (dpdm) | **परामर्शात्मक** | +| `check:bundle-size` | बंडल का आकार निर्धारित सीमा से अधिक नहीं है | **परामर्शात्मक** | +| `check:secrets` | सीक्रेट स्कैनिंग (gitleaks) — बाइनरी अनुपस्थित होने पर छोड़ देता है | **परामर्शात्मक** | +| `check:vuln-ratchet` | निर्भरता संबंधी कमजोरियाँ (osv-scanner) खराब नहीं होतीं — बाइनरी अनुपस्थित होने पर छोड़ देता है | **परामर्शात्मक** | +| `check:workflows` | वर्कफ़्लो लिंट (actionlint + zizmor); अनुपस्थित/खराब स्कैनर, अमान्य रिपोर्ट या अनुपस्थित रैचेट बेसलाइन INCOMPLETE के रूप में विफल होते हैं। मान्य निष्कर्ष चयनित सख्त/परामर्शात्मक/रैचेट नीति का पालन करते हैं | निष्पादन आवश्यक; CI में zizmor रैचेट अवरोधक है | +| `check:openapi-breaking` | बेस ब्रांच की तुलना में सार्वजनिक API अनुबंध (`openapi.yaml`) में ब्रेकिंग बदलाव (oasdiff) — `openapiBreaking=N` उत्सर्जित करता है; oasdiff अनुपस्थित होने या बेस स्पेक का समाधान न हो पाने पर छोड़ देता है | **परामर्शात्मक** | ### जॉब: `docs-sync-strict` -`main` की प्रत्येक PR पर चलता है। विफलता होने पर मर्ज को अवरुद्ध करता है। +`main` के प्रत्येक PR पर चलता है। विफल होने पर मर्ज को रोकता है। -| स्क्रिप्ट | सत्यापित करता है | अवरोधक | +| Script | सत्यापित करता है | अवरोधक | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | | `check:docs-all` | मेटा-गेट, जो नीचे दिए गए 6 उप-गेट क्रमिक रूप से चलाता है | हाँ | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt संस्करण संगतता | हाँ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt संस्करण की संगति | हाँ | | ↳ `check:docs-counts` | गद्य में दी गई संख्याएँ (प्रदाता संख्या, माइग्रेशन संख्या आदि) वास्तविक संख्याओं की रैचेट विंडो के भीतर हैं | हाँ | -| ↳ `check:env-doc-sync` | `.env.example` में मौजूद प्रत्येक env var किसी दस्तावेज़ तालिका में प्रलेखित है, और इसके विपरीत भी | हाँ | -| ↳ `check:deprecated-versions` | दस्तावेज़ों में कोई अप्रचलित संस्करण स्ट्रिंग नहीं है | हाँ | -| ↳ `check:doc-links` | दस्तावेज़ों में आंतरिक markdown लिंक वास्तविक फ़ाइलों पर रिज़ॉल्व होते हैं (`[text]`/`(path)` प्रारूप) | हाँ | -| ↳ `check:fabricated-docs` | दस्तावेज़ों में उल्लिखित रूट, env vars, CLI कमांड, हुक नाम और फ़ाइल पथ कोडबेस में मौजूद हैं। `--strict` के माध्यम से हार्ड गेट; फ़्लैग के बिना सॉफ्ट-फ़ेल। | हाँ (CI में `--strict` के माध्यम से) | -| `check:cli-i18n` | CLI कमांड स्ट्रिंग सभी i18n लोकेल फ़ाइलों में मौजूद हैं | हाँ | -| `check:openapi-coverage` | OpenAPI विनिर्देश वास्तविक रूट के कम-से-कम रैचेट किए गए न्यूनतम स्तर को कवर करता है | हाँ | +| ↳ `check:env-doc-sync` | `.env.example` का प्रत्येक env var दस्तावेज़ीकरण तालिका में दर्ज है, और इसके विपरीत भी | हाँ | +| ↳ `check:deprecated-versions` | दस्तावेज़ों में कोई बहिष्कृत संस्करण स्ट्रिंग नहीं है | हाँ | +| ↳ `check:doc-links` | दस्तावेज़ों के आंतरिक markdown लिंक वास्तविक फ़ाइलों तक पहुँचते हैं (`[text]`/`(path)` प्रारूप) | हाँ | +| ↳ `check:fabricated-docs` | दस्तावेज़ों में उल्लिखित रूट, env var, CLI कमांड, हुक नाम और फ़ाइल पथ codebase में मौजूद हैं। `--strict` के माध्यम से हार्ड गेट; फ़्लैग के बिना सॉफ्ट-फेल। | हाँ (CI में `--strict` के माध्यम से) | +| `check:cli-i18n` | CLI कमांड स्ट्रिंग सभी i18n locale फ़ाइलों में मौजूद हैं | हाँ | +| `check:openapi-coverage` | OpenAPI spec वास्तविक रूट की कम-से-कम रैचेट की गई न्यूनतम सीमा को कवर करता है | हाँ | | `check:openapi-security-tiers` | `openapi.yaml` में सुरक्षा स्तर एनोटेशन `routeGuard.ts` वर्गीकरणों के अनुरूप हैं | **परामर्शात्मक** | -| `check:openapi-routes` | `openapi.yaml` का प्रत्येक पथ वास्तविक `route.ts` पर रिज़ॉल्व होता है (भ्रम-रोधी) | हाँ | -| `check:docs-symbols` | `docs/**/*.md` में प्रत्येक `/api/...` संदर्भ वास्तविक `route.ts` पर रिज़ॉल्व होता है (भ्रम-रोधी) | हाँ | -| `i18n translation drift` | i18n लोकेल फ़ाइलों में अनूदित न की गई कुंजियाँ — केवल चेतावनी | **परामर्शात्मक** | +| `check:openapi-routes` | `openapi.yaml` का प्रत्येक पथ वास्तविक `route.ts` तक पहुँचता है (भ्रम-रोधी) | हाँ | +| `check:docs-symbols` | `docs/**/*.md` का प्रत्येक `/api/...` संदर्भ वास्तविक `route.ts` तक पहुँचता है (भ्रम-रोधी) | हाँ | +| `i18n translation drift` | i18n locale फ़ाइलों में अनूदित न की गई keys — केवल चेतावनी | **परामर्शात्मक** | ### जॉब: `i18n-ui-coverage` -| स्क्रिप्ट | सत्यापित करता है | अवरोधक | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (इनलाइन) | UI i18n कुंजी कवरेज ≥ 65% है | हाँ | -| `check-ui-value-drift` (इनलाइन) | दोबारा लिखा गया अंग्रेज़ी **मान** किसी पुराने अनुवाद को पीछे नहीं छोड़ता | हाँ | -| `check-new-key-coverage` (इनलाइन) | एक **नई** अंग्रेज़ी कुंजी प्रत्येक लोकेल में अनूदित है — `__MISSING__:` मार्कर अस्वीकार कर दिया जाता है | हाँ | -| `check-translation-ratio` | प्रति लोकेल वास्तविक-अनुवाद अनुपात (अनुमति-सूची से बाहर अंग्रेज़ी के समान / प्लेसहोल्डर / अनुपस्थित लीफ़) `config/quality/i18n-translation-baseline.json` + स्लैक से अधिक नहीं होना चाहिए | **परामर्शात्मक** | +| Script | सत्यापित करता है | अवरोधक | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `check-ui-keys-coverage` (इनलाइन) | UI i18n key कवरेज ≥ 65% है | हाँ | +| `check-ui-value-drift` (इनलाइन) | दोबारा लिखा गया अंग्रेज़ी **value** कोई पुराना अनुवाद पीछे नहीं छोड़ता | हाँ | +| `check-new-key-coverage` (इनलाइन) | एक **नई** अंग्रेज़ी key प्रत्येक locale में अनूदित है — `__MISSING__:` मार्कर अस्वीकार किया जाता है | हाँ | +| `check-translation-ratio` | प्रति locale वास्तविक-अनुवाद अनुपात (allowlist के बाहर अंग्रेज़ी के समान / placeholder / अनुपस्थित leaves) `config/quality/i18n-translation-baseline.json` + slack से अधिक नहीं होना चाहिए | **परामर्शात्मक** | -`fetch-depth: 0` आवश्यक है — मान-ड्रिफ़्ट गेट मर्ज बेस के विरुद्ध `en.json` का अंतर निकालता है। +`fetch-depth: 0` आवश्यक है — value-drift गेट merge base की तुलना में `en.json` का diff करता है। -#### `check-ui-value-drift` — पुराना-अनुवाद गेट +#### `check-ui-value-drift` — पुराने अनुवाद का गेट -यह उस एक i18n रिग्रेशन को पकड़ता है जिसे अन्य गेट संरचनात्मक रूप से नहीं देख सकते: किसी अंग्रेज़ी मान को -दोबारा लिखा जाता है और _पिछले_ अंग्रेज़ी मान से बने अनुवाद पीछे रह जाते हैं, जिससे -गैर-अंग्रेज़ी उपयोगकर्ता आत्मविश्वासपूर्ण शब्दों में लिखी, लेकिन अब गलत सामग्री पढ़ते रहते हैं। +यह उस एक i18n रिग्रेशन को पकड़ता है जिसे अन्य गेट संरचनात्मक रूप से नहीं देख सकते: किसी अंग्रेज़ी value को +दोबारा लिखा जाता है और _पिछले_ अंग्रेज़ी पाठ से बनाए गए अनुवाद पीछे रह जाते हैं, जिससे +गैर-अंग्रेज़ी उपयोगकर्ता आत्मविश्वासपूर्ण शैली में लिखी, लेकिन अब गलत जानकारी पढ़ते रहते हैं। -यह वास्तव में रिलीज़ हो चुका था। Antigravity लॉगिन सहायक जोड़े जाने पर (#5203) -`oauthModal.googleOAuthWarning` को दोबारा लिखा गया था; **43 में से 39 लोकेल** में वह पाठ बना रहा जो ऑपरेटरों को -"पूरा URL कॉपी करके नीचे पेस्ट करने" के लिए कहता था — ऐसी प्रक्रिया जो उस प्रदाता के लिए पूरी नहीं हो सकती। -#8463 तक इस पर ध्यान नहीं गया, क्योंकि: +यह वास्तव में रिलीज़ हो चुका है। Antigravity लॉगिन हेल्पर जोड़े जाने (#5203) पर `oauthModal.googleOAuthWarning` +को दोबारा लिखा गया था; **43 में से 39 locales** में ऑपरेटरों को "पूरा URL कॉपी करके नीचे पेस्ट करें" बताने वाला +पाठ बना रहा — ऐसा प्रवाह जो उस प्रदाता के लिए पूरा नहीं हो सकता। #8463 तक इस पर +ध्यान नहीं गया, क्योंकि: -- `sync-ui-keys` केवल उन कुंजियों को बैकफ़िल करता है जो **अनुपस्थित** हैं, **पुरानी** कुंजियों को कभी नहीं; -- `check-ui-keys-coverage` कुंजी की _उपस्थिति_ गिनता है, इसलिए पुराने अनुवाद को भी कवर किया हुआ माना जाता है; -- `check-translation-drift` `docs/i18n//**.md` दस्तावेज़ीकरण मिरर ट्रैक करता है — - यह कभी भी `src/i18n/messages/*.json` नहीं पढ़ता। 2026-09 के पुनः-सिंक के बाद से जॉब `docs-sync-strict` में अवरोधक: - कोई मुख्य दस्तावेज़ संपादित करें → `npm run i18n:run -- --files=` (अनुभाग-स्तरीय, कम खर्चीला)। +- `sync-ui-keys` केवल **अनुपस्थित** keys को backfill करता है, **पुरानी** keys को कभी नहीं; +- `check-ui-keys-coverage` key की _उपस्थिति_ गिनता है, इसलिए पुराने अनुवाद को कवर किया हुआ माना जाता है; +- `check-translation-drift` `docs/i18n//**.md` दस्तावेज़ीकरण mirrors को ट्रैक करता है — + यह `src/i18n/messages/*.json` को कभी नहीं पढ़ता। 2026-09 re-sync से जॉब `docs-sync-strict` में अवरोधक: + किसी मुख्य दस्तावेज़ को संपादित करें → `npm run i18n:run -- --files=` (अनुभाग-स्तरीय, कम खर्चीला)। -**डिफ़-अवेयर, बेसलाइन-समर्थित नहीं।** यह मर्ज बेस पर मौजूद `en.json` की तुलना -वर्किंग ट्री से करता है; ऐसी प्रत्येक कुंजी के लिए जिसका अंग्रेज़ी मान बदला है, कोई भी लोकेल जिसमें अभी भी -अपरिवर्तित अनुवाद मौजूद है, पुराना माना जाता है। यह जानबूझकर **पहले से मौजूद ऋण को स्थिर रखता है** — कोई डिफ़ -यह नहीं बता सकता कि लंबे समय से मौजूद अनुवाद किस पुराने अंग्रेज़ी पाठ से आया था, इसलिए गेट केवल -वर्तमान बदलाव द्वारा प्रभावित हिस्से का ही आकलन करता है। विकल्प (प्रति-कुंजी हैश बेसलाइन) के लिए -लगभग 600 KB की जनरेट की गई फ़ाइल की आवश्यकता होगी, जो सबसे बड़ी मौजूदा बेसलाइन से 3× बड़ी होगी और प्रत्येक i18n PR पर बदलेगी। +**डिफ़-सजग, बेसलाइन-समर्थित नहीं।** यह मर्ज बेस पर मौजूद `en.json` की तुलना +वर्किंग ट्री से करता है; जिन कुंजियों का अंग्रेज़ी मान बदला है, उनके लिए अब भी +अपरिवर्तित अनुवाद रखने वाला कोई भी लोकेल पुराना माना जाता है। यह जानबूझकर **पहले से मौजूद ऋण को स्थिर रखता है** — कोई डिफ़ +यह नहीं बता सकता कि लंबे समय से मौजूद अनुवाद किस पुराने अंग्रेज़ी पाठ से आया था, इसलिए गेट +केवल वर्तमान बदलाव द्वारा प्रभावित चीज़ों का आकलन करता है। विकल्प (प्रति-कुंजी हैश बेसलाइन) के लिए +लगभग 600 KB की जनरेट की गई फ़ाइल चाहिए होगी, जो सबसे बड़ी मौजूदा बेसलाइन से 3× बड़ी है और प्रत्येक i18n PR पर बदलती रहेगी। इसे संतुष्ट करने के दो तरीके हैं: 1. प्रभावित अनुवादों को अपडेट करें, या -2. उन्हें `__MISSING__:` पर सेट करें — इसके बाद रनटाइम संशोधित अंग्रेज़ी पाठ प्रदान करता है - (`src/i18n/request.ts::deepMergeFallback`, #7258) और कुंजी अनुवाद की कतार में चली जाती है। +2. उन्हें `__MISSING__:` पर सेट करें — इसके बाद रनटाइम संशोधित अंग्रेज़ी + (`src/i18n/request.ts::deepMergeFallback`, #7258) प्रदान करता है और कुंजी अनुवाद के लिए कतारबद्ध हो जाती है। -यदि स्ट्रिंग का **अर्थ** बदल गया है, तो **कुंजी का नाम बदलना** बेहतर है: नई कुंजी को -पुराना अनुवाद विरासत में नहीं मिल सकता। #8463 में इसी पैटर्न का उपयोग किया गया था। +यदि स्ट्रिंग का **अर्थ** बदल गया है, तो **कुंजी का नाम बदलना** बेहतर है: नई कुंजी +पुराना अनुवाद विरासत में नहीं ले सकती। #8463 में इसी पैटर्न का उपयोग किया गया था। ```bash npm run i18n:check-value-drift # सख़्त (CI यही चलाता है) @@ -232,48 +232,48 @@ npm run i18n:check-value-drift:warn # केवल रिपोर्ट BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -जब आधार कैटलॉग को पढ़ा नहीं जा सकता (बेस रेफ़ के बिना शैलो -क्लोन), तब यह `SKIP reason=base-unresolved` के साथ 0 पर समाप्त होता है, जो `check-openapi-breaking` के व्यवहार को दर्शाता है। +जब बेस कैटलॉग को पढ़ा नहीं जा सकता (बेस रेफ़ के बिना शैलो +क्लोन), तब `SKIP reason=base-unresolved` के साथ 0 पर समाप्त होता है, जो `check-openapi-breaking` के व्यवहार को प्रतिबिंबित करता है। ### जॉब: `i18n` -पूर्ण i18n सत्यापन मैट्रिक्स (प्रति लोकेल एक जॉब)। पूरा जॉब परामर्शात्मक है। +पूर्ण i18n सत्यापन मैट्रिक्स (प्रत्येक लोकेल के लिए एक जॉब)। पूरा जॉब परामर्शात्मक है। -| स्क्रिप्ट | सत्यापन करता है | अवरोधक | -| ------------------------------- | ----------------------------- | -------------------------------------------------------- | -| `validate_translation.py quick` | प्रति लोकेल अनुवाद की पूर्णता | **परामर्शात्मक** (पूरे जॉब पर `continue-on-error: true`) | +| स्क्रिप्ट | सत्यापित करता है | अवरोधक | +| ------------------------------- | --------------------------------------- | -------------------------------------------------------- | +| `validate_translation.py quick` | प्रत्येक लोकेल के लिए अनुवाद की पूर्णता | **परामर्शात्मक** (पूरे जॉब पर `continue-on-error: true`) | ### जॉब: `pr-test-policy` केवल पुल रिक्वेस्ट पर चलता है। -| स्क्रिप्ट | सत्यापन करता है | अवरोधक | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, या `bin/` में प्रोडक्शन कोड बदलने वाले PR में टेस्ट शामिल या अपडेट होने चाहिए (कठोर नियम #8) | हाँ | -| `check:test-masking` | बदली गई टेस्ट फ़ाइलें कुल assert संख्या को कम नहीं करतीं या `assert.ok(true)` जैसी स्वतःसिद्ध अभिव्यक्तियाँ नहीं जोड़तीं | हाँ | -| `check:pr-evidence` | PR विवरण में बदलाव के लिए टेस्ट/VPS साक्ष्य दिया गया है (PR गद्य में खोज करके कठोर नियम #18 को स्वचालित करता है — नाज़ुक, Backlog देखें) | हाँ | +| स्क्रिप्ट | सत्यापित करता है | अवरोधक | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, या `bin/` में प्रोडक्शन कोड बदलने वाले PR में टेस्ट शामिल या अपडेट होने चाहिए (कठोर नियम #8) | हाँ | +| `check:test-masking` | बदली गई टेस्ट फ़ाइलें कुल assert संख्या कम नहीं करतीं या `assert.ok(true)` जैसी पुनरुक्तियाँ नहीं जोड़तीं | हाँ | +| `check:pr-evidence` | PR बॉडी बदलाव के लिए टेस्ट/VPS साक्ष्य उद्धृत करती है (PR गद्य को grep करके कठोर नियम #18 को स्वचालित बनाता है — नाज़ुक, Backlog देखें) | हाँ | ### जॉब: `test-vitest` -`build` के बाद चलता है। विफल होने पर मर्ज को अवरुद्ध करता है। +`build` के बाद चलता है। विफलता पर मर्ज को रोकता है। -| सुइट | सत्यापन करता है | अवरोधक | -| ---------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP सर्वर (110 टूल), autoCombo, कैश — vitest रनर | हाँ | -| `test:vitest:ui` | UI कंपोनेंट टेस्ट — vitest रनर | **अवरोधक** — पहले से मौजूद विफलताओं को `vitest.config.ts` में स्पष्ट रूप से बाहर रखा गया है; नई विफलताएँ जॉब को विफल कर देती हैं | +| सुइट | सत्यापित करता है | अवरोधक | +| ---------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP सर्वर (110 टूल), autoCombo, कैश — vitest रनर | हाँ | +| `test:vitest:ui` | UI कॉम्पोनेंट टेस्ट — vitest रनर | **अवरोधक** — पहले से मौजूद विफलताओं को `vitest.config.ts` में स्पष्ट रूप से बाहर रखा गया है; नई विफलताएँ जॉब को विफल करती हैं | ### रात्रिकालीन वर्कफ़्लो (शेड्यूल किए गए, परामर्शात्मक) -ये cron शेड्यूल पर (और `workflow_dispatch` के माध्यम से) चलते हैं, PR पर कभी नहीं। सभी परामर्शात्मक हैं। +ये cron शेड्यूल पर (और `workflow_dispatch` से) चलते हैं, PR पर कभी नहीं। सभी परामर्शात्मक हैं। -| वर्कफ़्लो | सत्यापन करता है | अवरोधक | +| वर्कफ़्लो | सत्यापित करता है | अवरोधक | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | यादृच्छिक seed और उच्च run count के साथ fast-check प्रॉपर्टी टेस्ट | **परामर्शात्मक** | -| `nightly-resilience` | heap-growth गेट, chaos fault-injection, k6 load/soak | **परामर्शात्मक** | -| `nightly-llm-security` | promptfoo injection guard (block मोड) + garak probes (प्रदाता secret के बिना छोड़ दिए जाते हैं) | **परामर्शात्मक** | -| `nightly-schemathesis` | `docs/openapi.yaml` का उपयोग करके लाइव OmniRoute के विरुद्ध OpenAPI कॉन्ट्रैक्ट फ़ज़िंग (schemathesis) — स्पेक उल्लंघनों / अनहैंडल्ड 500s को उजागर करता है (चरण 8 B.4) | **परामर्शात्मक** | -| `nightly-mutation` | तेज़ यूनिट लेन पर Stryker mutation-testing स्कोर — बचे हुए mutants कमज़ोर asserts को उजागर करते हैं | **परामर्शात्मक** | -| `nightly-compat` | समर्थित `engines.node` रेंज में Node engine संगतता मैट्रिक्स | **परामर्शात्मक** | +| `nightly-property` | रैंडम सीड और उच्च रन संख्या वाले fast-check प्रॉपर्टी टेस्ट | **परामर्शात्मक** | +| `nightly-resilience` | हीप-वृद्धि गेट, केऑस फ़ॉल्ट-इंजेक्शन, k6 लोड/सोक | **परामर्शात्मक** | +| `nightly-llm-security` | promptfoo इंजेक्शन गार्ड (ब्लॉक मोड) + garak प्रोब (प्रोवाइडर सीक्रेट के बिना छोड़ दिए जाते हैं) | **परामर्शात्मक** | +| `nightly-schemathesis` | `docs/openapi.yaml` का उपयोग करके लाइव OmniRoute के विरुद्ध OpenAPI कॉन्ट्रैक्ट फ़ज़िंग (schemathesis) — स्पेक उल्लंघनों / अनहैंडल्ड 500 को उजागर करता है (Fase 8 B.4) | **परामर्शात्मक** | +| `nightly-mutation` | तेज़ यूनिट लेन पर Stryker म्यूटेशन-टेस्टिंग स्कोर — जीवित बचे म्यूटेंट कमज़ोर assert को उजागर करते हैं | **परामर्शात्मक** | +| `nightly-compat` | समर्थित `engines.node` रेंज में Node इंजन संगतता मैट्रिक्स | **परामर्शात्मक** | --- @@ -536,43 +536,43 @@ CI गेट से आगे, OmniRoute एक **ऑप्ट-इन** `agent-l --- -## युक्तिसंगतीकरण बैकलॉग (ROI समीक्षा — चरण 9 लहर 3) +## युक्तिसंगतीकरण बैकलॉग (ROI समीक्षा — चरण 9 तरंग 3) -इस इन्वेंटरी का `ci.yml` के साथ 2026-06-17 को मिलान किया गया था (पिछले संस्करण में +इस इन्वेंट्री का मिलान 2026-06-17 को `ci.yml` से किया गया था (पिछले संस्करण में `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence` छूट गए थे)। मिलान किए गए सेट की ROI समीक्षा में निम्नलिखित युक्तिसंगतीकरण उम्मीदवारों की पहचान हुई। **मर्ज यांत्रिक CI -परिवर्तन हैं; फ्लिप/ड्रॉप ऑपरेटर के लिए आरक्षित नीतिगत निर्णय हैं।** नीचे दिया गया कुछ भी -अभी लागू नहीं किया गया है। +परिवर्तन हैं; फ्लिप/हटाने के निर्णय ऑपरेटर के लिए आरक्षित नीतिगत निर्णय हैं।** नीचे दिया गया +कुछ भी अभी लागू नहीं किया गया है। -**ऊपर इसका भी दस्तावेज़ीकरण नहीं किया गया है** (परामर्शात्मक, कम संकेत): `docs-lint` जॉब +**ऊपर ये भी प्रलेखित नहीं हैं** (परामर्शी, कम संकेत): `docs-lint` जॉब (markdownlint + Vale, पूरे जॉब पर `continue-on-error`) और स्वतंत्र स्कैनर वर्कफ़्लो `semgrep.yml` / `codeql.yml` / `scorecard.yml`। `semgrepFindings: 0` -`quality-baseline.json` में है, लेकिन `ci.yml` में इसे किसी ब्लॉकिंग रैचेट से नहीं जोड़ा गया है — यह मेट्रिक +`quality-baseline.json` में है, लेकिन `ci.yml` में किसी अवरोधक रैचेट से जुड़ा नहीं है — यह मेट्रिक फ़िलहाल अनाथ है। -### मर्ज / डिडुप्लिकेशन (यांत्रिक, कम जोखिम) +### मर्ज / डुप्लीकेशन हटाना (यांत्रिक, कम जोखिम) -प्रत्येक उम्मीदवार को 2026-06-17 की लाइव गेट स्थिति के विरुद्ध सत्यापित किया गया था (भरोसा करें, लेकिन सत्यापित भी करें); -कई "स्पष्ट" मर्ज वास्तव में छिपे हुए तकनीकी ऋण वाले निकले और वे **साफ़-सुथरे** ड्रॉप-इन नहीं हैं। +प्रत्येक उम्मीदवार को 2026-06-17 को लाइव गेट स्थिति के विरुद्ध सत्यापित किया गया था (भरोसा करें, लेकिन सत्यापित भी करें); +कई "स्पष्ट" मर्ज वास्तव में छिपे हुए ऋण वाले निकले और **साफ़-सुथरे प्रत्यक्ष प्रतिस्थापन नहीं** हैं। - **`check:docs-sync` दो बार चलता है** — `lint` जॉब में स्वतंत्र रूप से और फिर `check:docs-all` (`docs-sync-strict`) तथा husky pre-commit हुक के भीतर। ✅ **पूर्ण** — स्वतंत्र `lint` इनवोकेशन हटा दिया गया। -- **CVE स्कैनिंग** — ❌ **साफ़-सुथरा मर्ज नहीं है।** `audit:deps` किसी भी उच्च/गंभीर CVE पर हार्ड-फेल होता है; `check:vuln-ratchet` (osv) केवल बेसलाइन की तुलना में किसी _प्रतिगमन_ पर विफल होता है (वर्तमान में 1 MODERATE)। अर्थ-विज्ञान अलग हैं — `audit:deps` हटाने से पूर्ण उच्च/गंभीर गेट समाप्त हो जाएगा। दोनों को बनाए रखें। -- **चक्र पहचान** — ❌ **साफ़-सुथरा मर्ज नहीं है।** `check:circular-deps` (dpdm) **91 चक्रों** की रिपोर्ट करता है (इसीलिए यह परामर्शात्मक है); पहले उन्हें हल किए बिना इसे ब्लॉकिंग में प्रोमोट नहीं किया जा सकता, और इसका दायरा हरे, चयनित `check:cycles` से व्यापक है। `check:cycles` को ब्लॉकिंग बनाए रखें; 91 dpdm चक्रों का समाधान स्वयं में एक अलग बैकलॉग है। -- **जटिलता** — ✅ **पूर्ण** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): एक ESLint वॉक, ruleId के अनुसार गणना करता है ताकि cyclomatic+max-lines और cognitive बेसलाइन स्वतंत्र रहें; अलग-अलग `check:complexity` / `check:cognitive-complexity` स्थानीय `--update` के लिए बने रहेंगे। -- **`/api` एंटी-हैलुसिनेशन** — ✅ **पूर्ण** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` की एक FS इन्वेंटरी, openapi-routes + docs-symbols अभी भी स्वतंत्र रूप से रिपोर्ट करते हैं; अलग-अलग जाँच स्थानीय रन के लिए बनी रहेंगी। -- **`check:node-runtime` 11 जॉब में चलता है** — ⚠️ **कम ROI।** प्रत्येक एक अलग रनर है और जाँच <1s लेती है; सस्ती प्रति-जॉब सुरक्षा खोने के बदले कुल बचत ~10s है। इस बदलाव की उठापटक उचित नहीं है। -- **CI lint पर `typecheck:noimplicit:core`** — ✅ **lint जॉब से हटा दिया गया** (यह परामर्शात्मक `continue-on-error` था); ब्लॉकिंग टाइप सतह `typecheck:core` + `check:type-coverage` है। स्थानीय स्क्रिप्ट बरकरार रखी गई। +- **CVE स्कैनिंग** — ❌ **साफ़ मर्ज नहीं है।** `audit:deps` किसी भी high/critical CVE पर हार्ड-फेल होता है; `check:vuln-ratchet` (osv) केवल बेसलाइन की तुलना में किसी _प्रतिगमन_ पर विफल होता है (वर्तमान में 1 MODERATE)। अर्थविज्ञान अलग हैं — `audit:deps` हटाने से निरपेक्ष high/critical गेट समाप्त हो जाएगा। दोनों को रखें। +- **चक्र पहचान** — ✅ **पूर्ण** (#15159 G-01/G-02)। यहाँ पुराने पाठ में `check:cycles` को "हरा, चयनित" गेट कहा गया था और इसे अवरोधक बनाए रखने का औचित्य यह दिया गया था कि `check:circular-deps` (dpdm) ने 91 चक्र रिपोर्ट किए थे। वह हरा परिणाम **भ्रामक रूप से हरा** था: `check:cycles` ने 5 उप-डायरेक्टरियाँ (450 फ़ाइलें) स्कैन कीं, केवल स्थिर `import|export … from` का मिलान किया, और प्रत्येक `@/` तथा `@omniroute/open-sse/` स्पेसिफ़ायर को छोड़ दिया, इसलिए यह उन dynamic-import + alias चक्रों को नहीं देख सका जो रिपॉज़िटरी में प्रमुख थे। सुधार किया गया: गेट अब `src` + `open-sse` (5023 फ़ाइलें) को ट्रैवर्स करता है, TypeScript AST से स्पेसिफ़ायर एकत्र करता है (इसलिए `import("…")` गिना जाता है और टाइप-स्थिति वाला `typeof import("…")` नहीं), और tsconfig `paths` को रिज़ॉल्व करता है। इसे 0 नहीं, बल्कि **14** चक्र मिलते हैं। चूँकि गेट PR में पहले से मौजूद 14 चक्र ठीक नहीं किए जा सकते, इसलिए `check:cycles` अब एक **रैचेट** है (`--ratchet`, `quality-baseline.json` में अधिकतम सीमा `metrics.cycles.value = 14`, `direction: down`) — यह किसी भी _प्रतिगमन_ को रोकता है और संख्या केवल घट सकती है। CI `npm run check:cycles:ratchet` चलाता है। क्रमिक कमी **A-01** के साथ चलेगी। व्यापक द्वितीय राय के रूप में `check:circular-deps` (dpdm) परामर्शी बना रहेगा। +- **जटिलता** — ✅ **पूर्ण** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): एक ESLint ट्रैवर्सल, `ruleId` के आधार पर गणना ताकि cyclomatic+max-lines और cognitive बेसलाइन स्वतंत्र रहें; अलग-अलग `check:complexity` / `check:cognitive-complexity` स्थानीय `--update` के लिए बने रहेंगे। +- **`/api` एंटी-हैलुसिनेशन** — ✅ **पूर्ण** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` की एक FS इन्वेंट्री, openapi-routes + docs-symbols अब भी स्वतंत्र रूप से रिपोर्ट करते हैं; अलग-अलग जाँचें स्थानीय रन के लिए बनी रहेंगी। +- **`check:node-runtime` 11 जॉब में चलता है** — ⚠️ **कम ROI।** प्रत्येक एक अलग रनर है और जाँच <1s की है; सस्ती प्रति-जॉब सुरक्षा खोने के मुकाबले कुल बचत ~10s है। इतने बदलाव के लायक नहीं है। +- **CI lint पर `typecheck:noimplicit:core`** — ✅ **lint जॉब से हटा दिया गया** (यह परामर्शी `continue-on-error` था); अवरोधक टाइप सतह `typecheck:core` + `check:type-coverage` है। स्थानीय स्क्रिप्ट बरकरार रखी गई। ### फ्लिप / निर्णय (ऑपरेटर नीति) -- `check:openapi-security-tiers` (परामर्शात्मक) — ❌ **साफ़-सुथरे ढंग से फ्लिप नहीं किया जा सकता।** यह 0 के साथ बाहर निकलता है, लेकिन चेतावनी देता है कि `LOCAL_ONLY_API_PREFIXES` के अंतर्गत कई `traffic-inspector` रूट में `x-loopback-only: true` एनोटेशन नहीं है। इसे लागू करने के लिए पहले उन एनोटेशन को `openapi.yaml` में जोड़ना आवश्यक है। -- `typecheck:noimplicit:core` (परामर्शात्मक) — इसे ब्लॉकिंग `check:type-coverage` रैचेट बड़े पैमाने पर समाहित करता है। इसे रैचेट में फ्लिप करें या अनावश्यक दूसरे `tsc` पास को हटा दें। -- `test:vitest:ui` (अब **ब्लॉकिंग**) — पहले से मौजूद विफलताओं को `vitest.config.ts` में `// #8618` ट्रैकिंग टिप्पणियों के साथ स्पष्ट रूप से बाहर रखा गया है; नई विफलताओं से जॉब विफल होगा। -- `check:secrets` (gitleaks, 3 दस्तावेज़ीकृत false-positive पर स्थिर किया गया ब्लॉकिंग रैचेट) — 0 तक पहुँचने के लिए उन 3 को allowlist करें, या इसे परामर्शात्मक में डिमोट करें। यह GitHub की मूल secret-scanning + `check:public-creds` के साथ ओवरलैप करता है। -- `check:pr-evidence` (ब्लॉकिंग, PR-body गद्य को grep करता है) — false-positive का उच्च जोखिम; इसे हटाने से कठोर नियम #18 का प्रवर्तन कमज़ोर होता है, इसलिए यह वास्तव में नीतिगत निर्णय है। -- `semgrep` (परामर्शात्मक स्वतंत्र जाँच) — OWASP परिवारों के लिए CodeQL के साथ ओवरलैप करता है; इसकी बेसलाइन को किसी रैचेट से जोड़ें या इसे हटा दें। +- `check:openapi-security-tiers` (परामर्शी) — ❌ **साफ़ तौर पर फ्लिप करने योग्य नहीं।** यह 0 के साथ समाप्त होता है, लेकिन चेतावनी देता है कि `LOCAL_ONLY_API_PREFIXES` के अंतर्गत कई `traffic-inspector` रूट में `x-loopback-only: true` एनोटेशन नहीं है। इसे लागू करने से पहले उन एनोटेशन को `openapi.yaml` में जोड़ना आवश्यक है। +- `typecheck:noimplicit:core` (परामर्शी) — अवरोधक `check:type-coverage` रैचेट में काफ़ी हद तक समाहित है। इसे रैचेट में फ्लिप करें या अनावश्यक दूसरे `tsc` पास को हटा दें। +- `test:vitest:ui` (अब **अवरोधक**) — पहले से मौजूद विफलताओं को `vitest.config.ts` में `// #8618` ट्रैकिंग टिप्पणियों के साथ स्पष्ट रूप से बाहर रखा गया है; नई विफलताएँ जॉब को विफल करती हैं। +- `check:secrets` (gitleaks, 3 प्रलेखित false-positive पर स्थिर अवरोधक रैचेट) — 0 तक पहुँचने के लिए उन 3 को allowlist करें, या इसे परामर्शी स्तर पर घटाएँ। GitHub की मूल secret-scanning + `check:public-creds` के साथ ओवरलैप करता है। +- `check:pr-evidence` (अवरोधक, PR-body गद्य पर grep करता है) — false-positive का उच्च जोखिम; हटाने पर Hard Rule #18 का प्रवर्तन कमज़ोर होता है, इसलिए यह वास्तव में नीतिगत निर्णय है। +- `semgrep` (परामर्शी स्वतंत्र जाँच) — OWASP श्रेणियों के लिए CodeQL के साथ ओवरलैप करता है; इसकी बेसलाइन को किसी रैचेट से जोड़ें या इसे हटा दें। --- diff --git a/docs/i18n/hr/CONTRIBUTING.md b/docs/i18n/hr/CONTRIBUTING.md index cf19b3e31a8..ee64bc6955c 100644 --- a/docs/i18n/hr/CONTRIBUTING.md +++ b/docs/i18n/hr/CONTRIBUTING.md @@ -397,22 +397,24 @@ Napišite jedinične testove u `tests/unit/` koji pokrivaju minimalno: --- -## Kontrolni Popis za Pull Request +## Kontrolni popis za Pull Request - [ ] Testovi prolaze (`npm test`) -- [ ] Lintanje prolazi (`npm run lint`) -- [ ] Izgradnja uspijeva (`npm run build`) -- [ ] TypeScript tipovi dodani za nove javne funkcije i sučelja -- [ ] Nema hardkodiranih tajni niti rezervnih vrijednosti -- [ ] Javne uzvodne vjerodajnice ugrađene putem `resolvePublicCred()` (pogledajte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikada kao literali -- [ ] Odgovori na pogreške prolaze kroz `buildErrorBody()` / `sanitizeErrorMessage()` — nema sirovih tragova stoga u tijelima odgovora (pogledajte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Naredbe ljuske (`exec` / `spawn`) prosljeđuju vrijednosti za izvođenje putem `env`, ne putem string interpolacije -- [ ] Svi ulazni podaci validirani Zod shemama -- [ ] Fragment zapisa promjena dodan pod `changelog.d/{features|fixes|maintenance}/-.md` za promjene vidljive korisniku (pogledajte [`changelog.d/README.md`](./changelog.d/README.md)) — **nemojte** izravno uređivati `CHANGELOG.md`; fragmenti se agregiraju pri izdavanju verzije i nikada ne dolaze u konflikt između pull requestova -- [ ] Dokumentacija ažurirana (ako je primjenjivo) -- [ ] Nema novih CodeQL / Secret-Scanning upozorenja, ili je svako odbačeno s tehničkim obrazloženjem koje upućuje na odgovarajući dokument iz `docs/security/` -- [ ] Rute koje pokreću podprocese (`/api/mcp/`, `/api/cli-tools/runtime/`) klasificirane su kao `isLocalOnlyPath()` u `src/server/authz/routeGuard.ts` — pogledajte [Strogo Pravilo #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Nema `Co-Authored-By` oznaka u porukama commita — commiti moraju biti isključivo pod Git identitetom vlasnika repozitorija (Strogo Pravilo #16) +- [ ] Linting prolazi (`npm run lint`) +- [ ] Izgradnja je uspješna (`npm run build`) +- [ ] Dodani su TypeScript tipovi za nove javne funkcije i sučelja +- [ ] Nema tvrdo kodiranih tajni ni pričuvnih vrijednosti +- [ ] Javne vjerodajnice uzvodnih sustava ugrađene su putem `resolvePublicCred()` (pogledajte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikada kao literali +- [ ] Odgovori o pogreškama prolaze kroz `buildErrorBody()` / `sanitizeErrorMessage()` — nema neobrađenih tragova stoga u tijelima odgovora (pogledajte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Naredbe ljuske (`exec` / `spawn`) prosljeđuju vrijednosti tijekom izvođenja putem `env`, a ne interpolacijom niza +- [ ] Svi su ulazni podaci validirani Zod shemama +- [ ] **Fragment** dnevnika promjena dodan je u `changelog.d/{features|fixes|maintenance}/-.md` za promjene vidljive korisnicima (pogledajte [`changelog.d/README.md`](./changelog.d/README.md)) — **nemojte** izravno uređivati `CHANGELOG.md`; fragmenti se objedinjuju pri objavi izdanja i nikada ne uzrokuju sukobe među PR-ovima +- [ ] Dokumentacija je ažurirana (ako je primjenjivo) +- [ ] Nisu otvorena nova upozorenja alata CodeQL / Secret-Scanning ili je svako odbačeno uz tehničko obrazloženje koje upućuje na relevantni dokument u `docs/security/` +- [ ] Rute koje pokreću podređene procese (`/api/mcp/`, `/api/cli-tools/runtime/`) klasificirane su kao `isLocalOnlyPath()` u `src/server/authz/routeGuard.ts` — pogledajte [Strogo pravilo #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Nema AI/bot najavnih redaka `Co-authored-by` u porukama predaje (Strogo pravilo #16) — ljudskim suradnicima čiji se rad ponovno koristi odaje se priznanje standardnim najavnim redcima `Co-authored-by: Name ` + +--- ## Objavljivanje diff --git a/docs/i18n/hr/docs/architecture/QUALITY_GATES.md b/docs/i18n/hr/docs/architecture/QUALITY_GATES.md index 90468b2e767..91cc50b6348 100644 --- a/docs/i18n/hr/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/hr/docs/architecture/QUALITY_GATES.md @@ -19,211 +19,216 @@ replikacije istog sustava neovisan o alatima pogledajte ### Prihvat kandidata -Radni tijekovi CI i Quality Gates objavljuju stabilne ishode: `Gate / CI` i -`Gate / Quality`. Njihova verzionirana pravila prihvata navode svaki prethodni zadatak -kao obavezan ili savjetodavan. Primjenjivi obavezni zadatak mora uspjeti: nedostajući, -otkazani, preskočeni, neriješeni i nepoznati rezultati ne mogu potvrditi PASS. Valjana -klasifikacija samo za dokumentaciju ili samo za katalog može učiniti programsku granu neprimjenjivom; -nacrt PR-a nije prihvaćen kandidat. Oznaka `hotfix` ne ukida zahtjev za dokazima. - -Oba radna tijeka obuhvaćaju PR-ove i slanja na glavne grane/grane izdanja, ručno pokretanje i -događaje grupe za spajanje. Slanje, ručno pokretanje i grupa za spajanje izvršavaju puni odabir. Forkovi -i grupe za spajanje upotrebljavaju hostirane izvršitelje za zadatke koji bi inače odabrali samostalno hostirane -izvršitelje; prije uvođenja mora se provjeriti dostatan hostirani kapacitet. - -Svaka JSON potvrda identificira odjavljeni SHA, izvršavanje radnog tijeka i pokušaj. -CLI odbija nepodudaranje SHA-a odjave i događaja. Testovi radnog tijeka povezuju članstvo u pravilima -s popisom `needs` zadatka za donošenje ishoda kako nova ili uklonjena grana izvršavanja ne bi mogla neprimjetno nestati. -Potvrde obuhvaćaju vlastiti radni tijek, a ne objavljivanje, implementaciju ili unutarnji rad -postojećeg savjetodavnog skenera. Aktiviranje oba naziva provjera u pravilima grane -zasebna je administrativna promjena; dodavanje ovih zadataka samo po sebi ne štiti granu. +Tijekovi rada CI i Quality Gates daju stabilne ishode: `Gate / CI` i +`Gate / Quality`. Njihova verzionirana pravila prihvata navode svaki prethodni posao +kao obavezan ili savjetodavan. Primjenjivi obavezni posao mora uspjeti: rezultati koji +nedostaju, koji su otkazani, preskočeni, na čekanju ili nepoznati ne mogu utvrditi PASS. +Valjana klasifikacija samo za dokumentaciju ili samo za katalog može učiniti programsku +stazu neprimjenjivom; radni PR nije prihvaćen kandidat. Oznaka `hotfix` ne ukida +obvezu pružanja dokaza. + +Oba tijeka rada obuhvaćaju PR-ove i slanja na glavne/release grane, ručno pokretanje i +događaje grupa za spajanje. Slanje, ručno pokretanje i grupa za spajanje pokreću puni +odabir. Forkovi i grupe za spajanje upotrebljavaju hostane izvršitelje za poslove koji +bi inače odabrali samostalno hostane izvršitelje; prije uvođenja mora se provjeriti +dostatan hostani kapacitet. + +Svaka JSON potvrda identificira dohvaćeni SHA, pokretanje tijeka rada i pokušaj. +CLI odbija nepodudaranje SHA-a dohvaćenog stanja i događaja. Testovi tijeka rada povezuju +članstvo u pravilima s popisom `needs` posla koji donosi ishod kako nova ili uklonjena +staza ne bi mogla neprimjetno nestati. Potvrde obuhvaćaju vlastiti tijek rada, a ne +objavljivanje, implementaciju ili unutarnji rad postojećeg savjetodavnog skenera. +Aktiviranje obaju naziva provjera u pravilima grane zasebna je administrativna promjena; +dodavanje ovih poslova samo po sebi ne štiti granu. ### Inventar statičkog skeniranja Verzionirani inventar npm aliasa i članstvo u statičkom skeniranju nalaze se u -`config/quality/gate-manifest.json`. Pokrenite `npm run check:gate-manifest` kako biste provjerili -nazive skripti i točne naredbe u odnosu na `package.json`; dodavanja, uklanjanja i -odstupanja naredbi uzrokuju neuspjeh lokalne kuke i zadataka klasifikacije promjena u CI-ju. -Alias nije zadatak radnog tijeka, instanca matrice ni testni slučaj: ti se brojevi -ne smiju prikazivati kao međusobno zamjenjivi. +`config/quality/gate-manifest.json`. Pokrenite `npm run check:gate-manifest` kako biste +provjerili nazive skripti i točne naredbe u odnosu na `package.json`; dodavanja, uklanjanja +i odstupanja naredbi uzrokuju neuspjeh i lokalne kuke i poslova za klasifikaciju promjena u CI-ju. +Alias nije posao tijeka rada, instanca matrice ni testni slučaj: ti se brojevi ne smiju +prikazivati kao međusobno zamjenjivi. Upotrijebite `npm run quality:scan -- --list` ili `npm run quality:scan:fast -- --list` kako biste pregledali odabrane aliase bez njihova izvršavanja. Izvršitelj poziva -npm ulaznu točku, pa se njezino izvršno okruženje (uključujući Bun gdje je konfiguriran) zadržava. -Manifest bilježi aliase izvan tih profila kao zasebno pozivane, a -naredbe za održavanje zabranjene su u profilima skeniranja samo za čitanje. +npm ulaznu točku, čime se čuva njezino izvršno okruženje (uključujući Bun gdje je konfiguriran). +Manifest bilježi aliase izvan tih profila kao zasebno pozvane, a naredbe za održavanje +zabranjene su u profilima skeniranja koji služe samo za čitanje. -Ovi profili obuhvaćaju samo statičko skeniranje. Ne potvrđuju testove proizvoda, +Ti profili obuhvaćaju samo statičko skeniranje. Ne certificiraju testove proizvoda, pokrivenost, pakiranje, vanjske provjere ni potpuni prihvat kandidata za izdanje. -Prihvat u radnom tijeku upotrebljava povezane `config/quality/admission-policy.json` i -`scripts/quality/admission-verdict.mjs`. Profili promatrača izdanja ostaju zasebni; -njihove primjenjive provjere i potvrde pregledajte neovisno. Tekstualni -inventar u nastavku služi kao referenca, a ne kao dokaz da je kontrola doista izvršena. +Prihvat tijeka rada upotrebljava povezane `config/quality/admission-policy.json` i +`scripts/quality/admission-verdict.mjs`. Profili za praćenje izdanja ostaju odvojeni; +neovisno pregledajte njihove primjenjive provjere i potvrde. Tekstualni +inventar u nastavku služi kao referenca, a ne kao dokaz da je kontrola doista pokrenuta. -Skripte se nalaze u `scripts/check/` (kontrole pravila) i `scripts/quality/` (mehanizam postupnog pooštravanja). +Skripte se nalaze pod `scripts/check/` (kontrole pravila) i `scripts/quality/` (mehanizam postupnog postrožavanja). Izvor istine za CI jest `.github/workflows/ci.yml`. -### Ubrzani put za PR izdanja (`quality.yml`) +### Brza putanja PR-a izdanja (`quality.yml`) -`.github/workflows/quality.yml` nadopunjuje CI za PR-ove na glavnim granama/granama izdanja, slanja -na zaštićene grane, ručna pokretanja i grupe za spajanje. PR-ovi upotrebljavaju brze provjere filtrirane prema putanji. Trajno -onemogućena duplicirana izgradnja uklonjena je; stvarne provjere izgradnje/pakiranja/pokretanja ostaju u CI-ju. +`.github/workflows/quality.yml` nadopunjuje CI za PR-ove na glavnim/release granama, slanja +na zaštićene grane, ručna pokretanja i grupe za spajanje. PR-ovi upotrebljavaju brze provjere +filtrirane prema putanjama. Trajno onemogućena duplicirana izgradnja uklonjena je; stvarne +provjere izgradnje/pakiranja/pokretanja ostaju u CI-ju. -| Zadatak | Opseg | Blokirajuće | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `Docs Gates (fast-path)` | PR-ovi dokumentacije/koda; reference API dokumentacije i cjelokupna dokumentacija | Da | -| `Fast Quality Gates` | PR-ovi koda; statičke provjere, provjera tipova, provjera tipova nadzorne ploče, obuhvaćeni jedinični testovi | Da | -| `Forgotten sibling tests` | PR-ovi koda; promijenjeni moduli praćeni do statičkih potrošača i kandidatskih srodnih testova; putanje bačvastih modula i dinamičkog uvoza prijavljuju se kao savjetodavna dijagnostika, uz navedene iznimke s popisa dopuštenih | **Savjetodavno** | -| `Vitest (fast-path)` | PR-ovi koda; brzi paket vitest testova | Da | -| `Unit Tests fast-path` | PR-ovi koda; paket jediničnih testova s 4 particije | Da | -| `No new ESLint warnings` | PR-ovi koda; zaštita lintanja koja uzima u obzir potiskivanja | Da, uključujući forkove | -| `Merge integrity (changelog + generated skills)` | PR-ovi koji nisu nacrti; sinkronizacija dnevnika promjena i generiranih vještina | Da, uključujući forkove | +| Posao | Opseg | Blokira | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | +| `Docs Gates (fast-path)` | PR-ovi dokumentacije/koda; reference API dokumentacije i cjelokupna dokumentacija | Da | +| `Fast Quality Gates` | PR-ovi koda; statičke provjere, provjera tipova, provjera tipova nadzorne ploče, pogođeni jedinični testovi | Da | +| `Forgotten sibling tests` | PR-ovi koda; promijenjeni moduli prate se do statičkih potrošača i kandidata za povezane testove; putanje bačvastih modula i dinamičkih uvoza prijavljuju se kao savjetodavna dijagnostika, uz navedene iznimke s popisa dopuštenih stavki | **Savjetodavno** | +| `Vitest (fast-path)` | PR-ovi koda; brzi paket vitest testova | Da | +| `Unit Tests fast-path` | PR-ovi koda; paket jediničnih testova u 4 segmenta | Da | +| `No new ESLint warnings` | PR-ovi koda; zaštita lintanja koja uvažava potiskivanja | Da, uključujući forkove | +| `Merge integrity (changelog + generated skills)` | PR-ovi koji nisu radni; sinkronizacija dnevnika promjena i generiranih vještina | Da, uključujući forkove | -#### Izvješće o zaboravljenim srodnim testovima +#### Izvješće o zaboravljenim povezanim testovima -`npm run check:forgotten-sibling-tests` ponovno upotrebljava razrješivač uvoza koji stoji iza mape utjecaja testova. +`npm run check:forgotten-sibling-tests` ponovno upotrebljava razrješivač uvoza na kojem se temelji karta utjecaja testova. Za svaki promijenjeni produkcijski modul prijavljuje determinističke lance -`promijenjeni modul/simbol -> statički potrošač -> kandidatski srodni test` kada kandidatski -test nije prisutan u razlici zahtjeva za povlačenje. Markdown sažetak i JSON rezultat zadržavaju se kao -artefakt radnog tijeka `forgotten-sibling-tests` radi kalibracije prije bilo kakvog uvođenja blokiranja. - -Ponovni izvozi putem barrel datoteka i dinamički uvozi služe samo za dijagnostiku razrješavanja; nikada ne stvaraju -blokirajući nalaz. Pregledane iznimke nalaze se u -`config/quality/forgotten-sibling-allowlist.json`. Svaki unos mora navesti potrošački i kandidatski -test, sadržavati konkretno obrazloženje i poveznicu na GitHub issue ili pull request. Neispravni unosi uzrokuju -neuspjeh. Iznimke ne mogu prikriti izbrisani kandidatski test ni diff koji dodaje `.skip`/`.todo`; -slabljenje tvrdnji i druga prikrivanja ostaju u nadležnosti neovisno blokirajućeg -`check:test-masking` gatea. - -### Job: `lint` - -Izvodi se za svaki PR prema `main`. Blokira spajanje u slučaju neuspjeha. - -| Skripta (`npm run ...`) | Provjerava | Blokira | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- | -| `check:node-runtime` | Verzija Node.js nalazi se unutar podržanog raspona | Da | -| `check:cycles` | Kružne uvoze — svi moduli u `src/` + `open-sse/` | Da | -| `check:route-validation:t06` | Zod sheme prisutne su na svim rutama (pravilo razine 6) | Da | -| `check:any-budget:t11` | Broj pojavljivanja `@ts-expect-error // any` ne premašuje dopušteni prag (catraca razine 11) | Da | -| `check:provider-consistency` | Svaki pružatelj u `providers.ts` ima odgovarajući unos u `providerRegistry.ts` (i obratno, unutar popisa dopuštenih) | Da | -| `check:model-lifecycle` | Tri ručno održavane tablice usmjeravanja ostaju usklađene s pohranjenom snimkom životnog ciklusa (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ne boduje nijedan povučeni id koji `REGISTRY` može usmjeriti; svaki cilj iz `BUILT_IN_ALIASES` prisutan je u `REGISTRY` i nije prisutan u snimci povučenih id-ova; svaki povučeni id koji je još uvijek u `REGISTRY` prosljeđuje se ili je naveden u `allowedRetiredInCatalog`; i nijedan izvor ili cilj iz `DEFAULT_DEGRADATION_MAP` nije označen kao povučen u toj snimci. To ne dokazuje da model trenutačno poslužuje aktivni uzvodni servis. Izvanmrežno — uspoređuje s `config/quality/model-lifecycle.json`, koji se ručno osvježava naredbom `npm run quality:refresh-model-lifecycle` (zahtijeva mrežu; nije uključen u CI). `allowedRetiredInCatalog` je jednosmjerna kontrola postupnog uklanjanja: unos dodajte samo uz problem za praćenje. | Da | -| `check:fetch-targets` | Svaki `fetch("/api/...")` u klijentskom `src/` razrješava se na stvarni `route.ts` | Da | -| `check:deps` | Sve ovisnosti koje se mogu instalirati naredbom `npm install` u svakoj datoteci `package.json` u repozitoriju nalaze se u `dependency-allowlist.json`; nove ovisnosti bez fiksirane verzije ili paketi nastali slopsquattingom označavaju se | Da | -| `audit:deps` | `npm audit` (korijenski direktorij + Electron) — nema upozorenja visoke/kritične razine (preklapa se s OSV provjerom `check:vuln-ratchet`; pogledajte Popis za naknadnu racionalizaciju) | Da | -| `check:lockfile` | Integritet datoteke `package-lock.json` — HTTPS registar, sažeci integriteta, bez nadjačavanja domaćina | Da | -| `check:licenses` | Popis dopuštenih SPDX licenci za produkcijske ovisnosti | Da | -| `check:tracked-artifacts` | Nema artefakata izgradnje ni predanih simboličkih poveznica `node_modules` (pokreće se i u husky pre-commit provjeri; pre-push je namjerno jednostavan — #6716) | Da | -| `check:ai-attribution` | Nema AI/bot `Co-Authored-By` oznake ni podnožja o AI generiranju u commitovima, naslovu ili tijelu PR-a — Strogo pravilo #16 (u petlji brzih provjera datoteke `quality.yml` za PR→`release/**` — čita sadržaj događaja, ne radi ništa izvan PR-ova — te kao korak samo za PR u lint provjeri datoteke `ci.yml` za PR→`main`; također i husky `commit-msg` hook; ljudski suautori su dopušteni; #14436) | -| `check:vitest-exclusions` | Svako Vitest izuzimanje navodi problem za praćenje i nalazi se u `config/quality/vitest-exclusions.json` (#13204) | Da | -| `check:file-size` | Nijedna izvorna datoteka ne premašuje ograničenje za svoju ekstenziju (zapinjač: velike zamrznute datoteke na popisu `frozen`) | Da | -| `check:error-helper` | Odgovori o pogreškama u izvršiteljima/rukovateljima koriste `buildErrorBody()` / `sanitizeErrorMessage()` (Strogo pravilo #12) | Da | -| `check:migration-numbering` | Migracijske SQL datoteke numerirane su uzastopno, bez praznina ili duplikata | Da | -| `check:public-creds` | Nema doslovnih OAuth vrijednosti `client_id`/`client_secret` ni Firebase Web ključeva izvan datoteke `publicCreds.ts` (strogo pravilo #11) | Da | -| `check:db-rules` | Nema neobrađenog SQL-a izvan modula `src/lib/db/`; nema zbirnih uvoza iz `localDb.ts` (stroga pravila #2/#5) | Da | -| `check:known-symbols` | Izvršitelji pružatelja usluga, strategije usmjeravanja i prevoditelji registrirani u svojim tablicama otpreme odgovaraju datotekama na disku — nema napuštenih ni nedeklariranih simbola | Da | -| `check:route-guard-membership` | Svaka ruta koja pokreće podređeni proces klasificirana je funkcijom `isLocalOnlyPath()` (stroga pravila #15/#17) | Da | -| `check:test-discovery` | Svaku datoteku `*.test.ts` / `*.spec.ts` u repozitoriju prikuplja barem jedan pokretač testova (čegrtaljka: popis napuštenih datoteka u `test-discovery-baseline.json` može se samo smanjivati) | Da | -| `check:agent-skills-sync` | Generirani artefakti agent-skills podudaraju se sa svojim izvornim katalogom (nema odstupanja) | -| `check:provider-asset-provenance` | Logotipi/resursi pružatelja imaju zabilježen unos o podrijetlu | -| `lint:json` | JSON konfiguracijske datoteke mogu se parsirati i zadovoljavaju pravila lintanja repozitorija | -| `typecheck:core` | Kompilacija TypeScripta bez pogrešaka (samo savjetodavna upozorenja) | Da | -| `typecheck:noimplicit:core` | Strogi `noImplicitAny` — usmjeren na budućnost; mnoga već postojeća mjesta poziva još trebaju anotacije | **Savjetodavno** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ograničen na `src/app/(dashboard)/**` (#7033) — pažljivo odabran popis dopuštenih 27 datoteka u `typecheck:core` ne uključuje nijednu TSX datoteku nadzorne ploče, a ni `next build` je nikada ne provjerava tipovima (`next.config.mjs` postavlja `ignoreBuildErrors: true`), pa su regresije s nepronađenim identifikatorima u njima (#6625/#6909) bile nevidljive CI-ju. Razlike se uspoređuju sa zamrznutom osnovnom vrijednošću broja pogrešaka po datoteci i TS kodu (`config/quality/dashboard-typecheck-baseline.json`, isti obrazac provođenja zastarjelosti kao za `check:known-symbols`) — samo NOVE pogreške iznad osnovnog broja uzrokuju pad provjere; smanjite osnovnu vrijednost s `--update` kada se ispravi već postojeća pogreška. | Da | - -### Posao: `quality-gate` +`promijenjeni modul/simbol -> statički potrošač -> kandidat za povezani test` kada kandidat +za test nije prisutan u razlikama zahtjeva za povlačenje. Markdown sažetak i JSON rezultat čuvaju se kao +artefakt tijeka rada `forgotten-sibling-tests` radi kalibracije prije eventualnog uvođenja blokiranja. + +Ponovni izvozi iz zbirnih modula i dinamički uvozi služe samo za dijagnostiku razrješavanja; nikada ne stvaraju +nalaz koji blokira. Pregledane iznimke nalaze se u +`config/quality/forgotten-sibling-allowlist.json`. Svaki unos mora navesti potrošača i kandidatski +test, dati konkretno obrazloženje i sadržavati poveznicu na GitHub problem ili zahtjev za povlačenje. Neispravni unosi rezultiraju +blokiranjem. Iznimke ne mogu zanemariti izbrisani kandidatski test ni razliku koja dodaje `.skip`/`.todo`; +slabljenje tvrdnji i ostalo prikrivanje i dalje su u nadležnosti neovisno blokirajuće +kontrole `check:test-masking`. + +### Zadatak: `lint` + +Pokreće se za svaki PR prema grani `main`. U slučaju neuspjeha blokira spajanje. + +| Skripta (`npm run ...`) | Provjerava | Blokira | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Je li verzija Node.js-a unutar podržanog raspona | Da | +| `check:cycles` | Kružne uvoze kroz cijeli `src/` + `open-sse/` (na temelju AST-a, uz razriješene `paths` iz tsconfiga). Samostalno pokretanje = savjetodavno, navodi cikluse. `check:cycles:ratchet` (koji CI pokreće) blokira kada broj premaši gornju granicu `metrics.cycles` u datoteci `quality-baseline.json` — trenutačno 14, `direction: down`, pa se može samo smanjivati (#15159 G-01/G-02) | Da (ratchet) | +| `check:route-validation:t06` | Prisutnost Zod shema na svim rutama (pravilo razine 6) | Da | +| `check:any-budget:t11` | Broj pojavljivanja `@ts-expect-error // any` ne premašuje dopušteni prag (zapinjača razine 11) | Da | +| `check:provider-consistency` | Svaki pružatelj u `providers.ts` ima odgovarajući unos u `providerRegistry.ts` (i obratno, unutar popisa dopuštenih) | Da | +| `check:model-lifecycle` | Tri ručno održavane tablice usmjeravanja ostaju usklađene s pohranjenom snimkom životnog ciklusa (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ne boduje nijedan povučeni ID koji `REGISTRY` može usmjeriti; svaki cilj iz `BUILT_IN_ALIASES` prisutan je u `REGISTRY` i nije prisutan u snimci povučenih ID-ova; svaki povučeni ID koji je još uvijek u `REGISTRY` prosljeđuje se ili je naveden u `allowedRetiredInCatalog`; te se nijedan izvor ni cilj iz `DEFAULT_DEGRADATION_MAP` ne pojavljuje kao povučen u toj snimci. To ne dokazuje da model trenutačno poslužuje aktivni uzvodni servis. Izvanmrežno — uspoređuje se s `config/quality/model-lifecycle.json`, koji se ručno osvježava naredbom `npm run quality:refresh-model-lifecycle` (zahtijeva mrežu; nije uključen u CI). `allowedRetiredInCatalog` je zaporni mehanizam postupnog smanjivanja: unos dodajte samo uz problem za praćenje. | Da | +| `check:fetch-targets` | Svaki `fetch("/api/...")` u klijentskom `src/` razrješava se na stvarni `route.ts` | Da | +| `check:deps` | Sve ovisnosti koje je moguće instalirati naredbom `npm install` u svim datotekama `package.json` u repozitoriju nalaze se u `dependency-allowlist.json`; novi paketi bez fiksirane verzije ili paketi nastali slopsquattingom označavaju se | Da | +| `audit:deps` | `npm audit` (korijen + electron) — nema upozorenja visoke/kritične razine (preklapa se s osv `check:vuln-ratchet`; pogledajte popis za racionalizaciju) | Da | +| `check:lockfile` | Integritet datoteke `package-lock.json` — https registar, sažeci integriteta, bez nadjačavanja poslužitelja | Da | +| `check:licenses` | Popis dopuštenih SPDX licenci za produkcijske ovisnosti | Da | +| `check:tracked-artifacts` | Nema artefakata izgradnje / predanih simboličkih poveznica `node_modules` (također se pokreće u husky pre-commit; pre-push je namjerno jednostavan — #6716) | Da | +| `check:ai-attribution` | Nema AI/bot prikolice `Co-Authored-By` ni podnožja o AI generiranju u predajama PR-a, naslovu ili tijelu — strogo pravilo #16 (u petlji brzih provjera `quality.yml` za PR→`release/**` — čita sadržaj događaja, ne radi ništa izvan PR-ova — i koraku samo za PR u provjeri lint datoteke `ci.yml` za PR→`main`; također husky kuka `commit-msg`; ljudski suautori su dopušteni; #14436) | +| `check:vitest-exclusions` | Svako izuzimanje iz Vitesta navodi problem za praćenje i nalazi se u `config/quality/vitest-exclusions.json` (#13204) | Da | +| `check:file-size` | Nijedna izvorna datoteka ne premašuje ograničenje za svoj nastavak (postupno ograničenje: zamrznute velike datoteke na popisu `frozen`) | Da | +| `check:error-helper` | Odgovori o pogreškama u izvršiteljima/obrađivačima upotrebljavaju `buildErrorBody()` / `sanitizeErrorMessage()` (strogo pravilo #12) | Da | +| `check:migration-numbering` | Migracijske SQL datoteke numerirane su uzastopno, bez praznina ili duplikata | Da | +| `check:public-creds` | Nema doslovnih OAuth vrijednosti `client_id`/`client_secret` ni Firebase Web ključeva izvan `publicCreds.ts` (strogo pravilo #11) | Da | +| `check:db-rules` | Nema sirovog SQL-a izvan modula `src/lib/db/`; nema zbirnih uvoza iz `localDb.ts` (stroga pravila #2/#5) | Da | +| `check:known-symbols` | Izvršitelji pružatelja usluga, strategije usmjeravanja i prevoditelji registrirani u svojim tablicama otpreme odgovaraju datotekama na disku — nema nepovezanih ili nedeklariranih simbola | Da | +| `check:route-guard-membership` | Svaka ruta koja pokreće podređeni proces klasificirana je funkcijom `isLocalOnlyPath()` (stroga pravila #15/#17) | Da | +| `check:test-discovery` | Svaku datoteku `*.test.ts` / `*.spec.ts` u repozitoriju prikuplja barem jedan pokretač testova (mehanizam zapinjače: popis nepovezanih datoteka u `test-discovery-baseline.json` može se samo smanjivati) | Da | +| `check:agent-skills-sync` | Generirani artefakti agent-skills odgovaraju svojem izvornom katalogu (bez odstupanja) | +| `check:provider-asset-provenance` | Logotipi/resursi pružatelja imaju zabilježen podatak o podrijetlu | +| `lint:json` | JSON konfiguracijske datoteke mogu se parsirati i zadovoljavaju pravila lintanja repozitorija | +| `typecheck:core` | Kompilacija TypeScripta bez pogrešaka (samo savjetodavna upozorenja) | Da | +| `typecheck:noimplicit:core` | Strogi `noImplicitAny` — usmjeren na budućnost; mnoga postojeća mjesta poziva i dalje trebaju anotacije | **Savjetodavno** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ograničen na `src/app/(dashboard)/**` (#7033) — uređeni popis dopuštenih 27 datoteka za `typecheck:core` ne uključuje nijedan TSX nadzorne ploče, a ni `next build` ga nikada ne provjerava tipovima (`next.config.mjs` postavlja `ignoreBuildErrors: true`), pa su regresije nepovezanih identifikatora ondje (#6625/#6909) bile nevidljive CI-ju. Razlike se uspoređuju sa zamrznutom osnovnom vrijednošću broja pogrešaka po datoteci i po TS kodu (`config/quality/dashboard-typecheck-baseline.json`, isti obrazac provedbe zastarjelosti kao za `check:known-symbols`) — samo NOVE pogreške iznad osnovnog broja uzrokuju neuspjeh provjere; smanjite prag s `--update` kada se ispravi postojeća pogreška. | Da | + +### Zadatak: `quality-gate` Pokreće se nakon `test-coverage`. U slučaju neuspjeha blokira spajanje. | Skripta | Provjerava | Blokira | | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `quality:collect` | Generira `quality-metrics.json` (broj ESLint upozorenja, pokrivenost iz objedinjenog izvješća segmenata) | Da (prethodi mehanizmu ratchet) | -| `quality:ratchet` | Nijedna metrika u `quality-baseline.json` nije nazadovala (ESLint upozorenja ≤ početna vrijednost; pokrivenost ≥ početna vrijednost) | Da | -| `check:duplication` | Dupliciranje koda (jscpd@4) ne premašuje početnu vrijednost iz `quality-baseline.json` | Da | +| `quality:collect` | Stvara `quality-metrics.json` (broj ESLint upozorenja, pokrivenost iz objedinjenog izvješća fragmenata) | Da (prethodi mehanizmu ratchet) | +| `quality:ratchet` | Nijedna metrika u `quality-baseline.json` nije nazadovala (ESLint upozorenja ≤ referentna vrijednost; pokrivenost ≥ referentna vrijednost) | Da | +| `check:duplication` | Dupliciranje koda (jscpd@4) ne premašuje referentnu vrijednost u `quality-baseline.json` | Da | | `check:complexity` | Ciklomatska složenost na razini datoteke ne premašuje ograničenje (osnovni ESLint `complexity` + `max-lines-per-function`) | Da | -| `check:cognitive-complexity` | Ratchet kognitivne složenosti (`eslint-plugin-sonarjs`) — zasebno ESLint pokretanje; CI objedinjuje oba u jedan korak `check:complexity-ratchets` | Da | -| `check:dead-code` | Ratchet nekorištenih izvoza / datoteka (knip) ne nazaduje u odnosu na početnu vrijednost | Da | -| `check:compression-budget` | Ograničenje referentnog mjerenja kompresije — minimalne uštede tokena po mehanizmu ne smiju nazadovati | Da | +| `check:cognitive-complexity` | Ratchet kognitivne složenosti (`eslint-plugin-sonarjs`) — zaseban prolaz ESLint-a; CI oba pokreće objedinjeno kao jedan korak `check:complexity-ratchets` | Da | +| `check:dead-code` | Ratchet nekorištenih izvoza / datoteka (knip) ne nazaduje u odnosu na referentnu vrijednost | Da | +| `check:compression-budget` | Ograničenje referentnog testa kompresije — minimalne uštede tokena po mehanizmu ne smiju nazadovati | Da | | `check:type-coverage` | Ratchet postotka tipiziranog koda (`type-coverage`) ne nazaduje; uglavnom obuhvaća `typecheck:noimplicit:core` | Da | -| `check:codeql-ratchet` | Broj otvorenih CodeQL upozorenja ne raste (čita putem `gh api`; uredno se preskače bez tokena) — učestalost osvježavanja i ručno pokretanje: pogledajte „CodeQL ratchet” u nastavku | Da | - -### Zadatak: `quality-extended` - -Cijeli je zadatak savjetodavan (`continue-on-error: true`). Ratchet provjere temeljene na npm-u -izvršavaju se stvarno; vanjski se skeneri instaliraju putem `gh release download` i sami se -preskaču (izlazni kod 0) kada binarna datoteka još uvijek nije prisutna. - -| Skripta | Provjerava | Blokiranje | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| `check:circular-deps` | Nema kružnih ovisnosti (dpdm) | **Savjetodavno** | -| `check:bundle-size` | Veličina paketa ne premašuje ograničenje | **Savjetodavno** | -| `check:secrets` | Skeniranje tajni (gitleaks) — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | -| `check:vuln-ratchet` | Ranjivosti ovisnosti (osv-scanner) ne nazaduju — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | -| `check:workflows` | Provjera radnih tijekova (actionlint + zizmor); nedostajući/neispravni skeneri, nevažeća izvješća ili nedostajuća početna vrijednost ratcheta završavaju statusom INCOMPLETE. Valjani nalazi slijede odabrana stroga/savjetodavna/ratchet pravila | Izvršavanje je obvezno; zizmor ratchet blokira u CI-ju | -| `check:openapi-breaking` | Neusklađene promjene javnog API ugovora (`openapi.yaml`) u odnosu na osnovnu granu (oasdiff) — generira `openapiBreaking=N`; preskače se ako oasdiff nije prisutan ili se osnovna specifikacija ne može razriješiti | **Savjetodavno** | - -### Zadatak: `docs-sync-strict` - -Pokreće se pri svakom PR-u prema `main`. U slučaju neuspjeha blokira spajanje. - -| Skripta | Provjerava | Blokirajuće | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | -| `check:docs-all` | Meta-kontrola koja redom pokreće 6 podređenih kontrola u nastavku | Da | -| ↳ `check:docs-sync` | Usklađenost verzija u datotekama CHANGELOG / OpenAPI / llm.txt | Da | -| ↳ `check:docs-counts` | Brojevi u proznom tekstu (broj pružatelja, broj migracija itd.) nalaze se unutar dopuštenog raspona stvarnih vrijednosti | Da | -| ↳ `check:env-doc-sync` | Svaka varijabla okruženja iz `.env.example` dokumentirana je u tablici dokumentacije i obratno | Da | -| ↳ `check:deprecated-versions` | U dokumentaciji nema zastarjelih oznaka verzija | Da | -| ↳ `check:doc-links` | Interne markdown poveznice u dokumentaciji vode do stvarnih datoteka (oblik `[text]`/`(path)`) | Da | -| ↳ `check:fabricated-docs` | Rute, varijable okruženja, CLI naredbe, nazivi hookova i putanje datoteka navedeni u dokumentaciji postoje u bazi koda. Stroga kontrola putem `--strict`; bez te zastavice ne blokira. | Da (putem `--strict` u CI-ju) | -| `check:cli-i18n` | Nizovi CLI naredbi prisutni su u svim i18n datotekama lokalizacije | Da | -| `check:openapi-coverage` | OpenAPI specifikacija pokriva barem postupno podizani minimalni prag stvarnih ruta | Da | -| `check:openapi-security-tiers` | Oznake sigurnosnih razina u `openapi.yaml` usklađene su s klasifikacijama u `routeGuard.ts` | **Savjetodavno** | -| `check:openapi-routes` | Svaka putanja u `openapi.yaml` odgovara stvarnoj datoteci `route.ts` (zaštita od halucinacija) | Da | -| `check:docs-symbols` | Svaka referenca `/api/...` u `docs/**/*.md` odgovara stvarnoj datoteci `route.ts` (zaštita od halucinacija) | Da | -| `i18n translation drift` | Neprevedeni ključevi u i18n datotekama lokalizacije — samo upozorenje | **Savjetodavno** | +| `check:codeql-ratchet` | Broj otvorenih CodeQL upozorenja ne nazaduje (čita putem `gh api`; uredno preskače bez tokena) — učestalost osvježavanja i ručno pokretanje: pogledajte „CodeQL ratchet” u nastavku | Da | + +### Posao: `quality-extended` + +Cijeli je posao savjetodavan (`continue-on-error: true`). Ratchet provjere temeljene na npm-u zaista se +izvršavaju; vanjski se skeneri instaliraju putem `gh release download` i sami se preskaču (izlaz 0) +ako binarna datoteka i dalje nije prisutna. + +| Skripta | Provjerava | Blokira | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| `check:circular-deps` | Nema kružnih ovisnosti (dpdm) | **Savjetodavno** | +| `check:bundle-size` | Veličina paketa ne premašuje ograničenje | **Savjetodavno** | +| `check:secrets` | Skeniranje tajni (gitleaks) — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | +| `check:vuln-ratchet` | Ranjivosti ovisnosti (osv-scanner) ne nazaduju — preskače se ako binarna datoteka nije prisutna | **Savjetodavno** | +| `check:workflows` | Provjera tijekova rada (actionlint + zizmor); nedostajući/neispravni skeneri, nevaljana izvješća ili nedostajuća referentna vrijednost ratcheta završavaju kao INCOMPLETE. Valjani nalazi slijede odabrana pravila stroge/savjetodavne/ratchet provjere | Izvršavanje je obvezno; zizmor ratchet blokira u CI-ju | +| `check:openapi-breaking` | Kompatibilnost promjena javnog API ugovora (`openapi.yaml`) u odnosu na osnovnu granu (oasdiff) — stvara `openapiBreaking=N`; preskače se ako oasdiff nije prisutan ili osnovnu specifikaciju nije moguće razriješiti | **Savjetodavno** | + +### Posao: `docs-sync-strict` + +Pokreće se pri svakom PR-u prema grani `main`. U slučaju neuspjeha blokira spajanje. + +| Skripta | Provjerava | Blokirajuće | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | Meta-provjera koja redom pokreće 6 podređenih provjera | Da | +| ↳ `check:docs-sync` | Usklađenost verzija u CHANGELOG-u / OpenAPI-ju / llm.txt-u | Da | +| ↳ `check:docs-counts` | Brojevi u tekstu (broj pružatelja, broj migracija itd.) unutar su postupno postroženog raspona stvarnih vrijednosti | Da | +| ↳ `check:env-doc-sync` | Svaka varijabla okruženja u `.env.example` dokumentirana je u tablici dokumentacije i obratno | Da | +| ↳ `check:deprecated-versions` | U dokumentaciji nema zastarjelih nizova verzija | Da | +| ↳ `check:doc-links` | Interne markdown poveznice u dokumentaciji upućuju na stvarne datoteke (oblik `[tekst]`/`(putanja)`) | Da | +| ↳ `check:fabricated-docs` | Rute, varijable okruženja, CLI naredbe, nazivi hookova i putanje datoteka navedeni u dokumentaciji postoje u bazi koda. Stroga provjera uz `--strict`; bez te zastavice neuspjeh je upozorenje. | Da (uz `--strict` u CI-ju) | +| `check:cli-i18n` | Nizovi CLI naredbi prisutni su u svim datotekama i18n lokalizacija | Da | +| `check:openapi-coverage` | OpenAPI specifikacija pokriva barem postupno postroženu donju granicu stvarnih ruta | Da | +| `check:openapi-security-tiers` | Oznake sigurnosnih razina u `openapi.yaml` usklađene su s klasifikacijama u `routeGuard.ts` | **Savjetodavno** | +| `check:openapi-routes` | Svaka putanja u `openapi.yaml` upućuje na stvarni `route.ts` (sprječavanje haluciniranja) | Da | +| `check:docs-symbols` | Svaka referenca `/api/...` u `docs/**/*.md` upućuje na stvarni `route.ts` (sprječavanje haluciniranja) | Da | +| `i18n translation drift` | Neprevedeni ključevi u datotekama i18n lokalizacija — samo upozorenje | **Savjetodavno** | ### Posao: `i18n-ui-coverage` -| Skripta | Provjerava | Blokirajuće | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (inline) | Pokrivenost UI i18n ključeva iznosi ≥ 65% | Da | -| `check-ui-value-drift` (inline) | Prepisana engleska **vrijednost** ne ostavlja zastarjeli prijevod | Da | -| `check-new-key-coverage` (inline) | **Novi** engleski ključ preveden je u svakoj lokalizaciji — oznaka `__MISSING__:` nije dopuštena | Da | -| `check-translation-ratio` | Omjer stvarnih prijevoda po lokalizaciji (stavke identične engleskom izvorniku / rezervirana mjesta / nedostajuće stavke izvan popisa dopuštenih) ne smije premašiti `config/quality/i18n-translation-baseline.json` + toleranciju | **Savjetodavno** | +| Skripta | Provjerava | Blokirajuće | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `check-ui-keys-coverage` (ugrađeno) | Pokrivenost UI i18n ključeva iznosi ≥ 65% | Da | +| `check-ui-value-drift` (ugrađeno) | Nakon prepisivanja engleske **vrijednosti** ne ostaje nijedan zastarjeli prijevod | Da | +| `check-new-key-coverage` (ugrađeno) | **Novi** engleski ključ preveden je u svakoj lokalizaciji — oznaka `__MISSING__:` nije dopuštena | Da | +| `check-translation-ratio` | Omjer stvarnih prijevoda po lokalizaciji (vrijednosti identične engleskima / rezervirana mjesta / nedostajući listovi izvan popisa dopuštenih) ne smije premašiti `config/quality/i18n-translation-baseline.json` + toleranciju | **Savjetodavno** | -Zahtijeva `fetch-depth: 0` — kontrola promjene vrijednosti uspoređuje `en.json` s bazom spajanja. +Zahtijeva `fetch-depth: 0` — provjera odstupanja vrijednosti uspoređuje `en.json` s bazom spajanja. -#### `check-ui-value-drift` — kontrola zastarjelih prijevoda +#### `check-ui-value-drift` — provjera zastarjelih prijevoda -Otkriva jednu i18n regresiju koju ostale kontrole strukturno ne mogu uočiti: engleska je vrijednost -prepisana, a prijevodi izvedeni iz _prethodnog_ engleskog teksta ostaju nepromijenjeni, pa +Otkriva onu i18n regresiju koju ostale provjere strukturno ne mogu uočiti: engleska se vrijednost +prepiše, a prijevodi izvedeni iz _prethodne_ engleske vrijednosti ostanu, pa korisnici koji ne govore engleski nastavljaju čitati samouvjereno formuliran, ali sada netočan tekst. -To se doista dogodilo u produkciji. `oauthModal.googleOAuthWarning` prepisan je kada je uveden pomoćnik -za prijavu Antigravity (#5203); u **39 od 43 lokalizacije** ostao je tekst koji operaterima govori da "kopiraju -cijeli URL i zalijepe ga ispod" — tijek koji za tog pružatelja nije moguće dovršiti. Problem je -ostao neprimijećen sve do #8463 jer: +To se doista dogodilo u produkciji. `oauthModal.googleOAuthWarning` prepisan je kada je uveden pomoćnik za +prijavu Antigravity (#5203); u **39 od 43 lokalizacije** ostao je tekst koji operaterima govori da "kopiraju +cijeli URL i zalijepe ga ispod" — postupak koji se za tog pružatelja ne može dovršiti. To je ostalo +neprimijećeno sve do #8463 jer: -- `sync-ui-keys` nadopunjuje samo ključeve koji **nedostaju**, nikada one koji su **zastarjeli**; -- `check-ui-keys-coverage` broji _prisutnost_ ključeva, pa se zastarjeli prijevod smatra pokrivenim; -- `check-translation-drift` prati dokumentacijske preslike `docs/i18n//**.md` — - nikada ne čita `src/i18n/messages/*.json`. Blokira u poslu `docs-sync-strict` od ponovne - sinkronizacije 2026-09: uredite temeljni dokument → `npm run i18n:run -- --files=` (na razini odjeljka, brzo). +- `sync-ui-keys` dodaje samo ključeve koji **nedostaju**, nikada one koji su **zastarjeli**; +- `check-ui-keys-coverage` broji _prisutnost_ ključa, pa se zastarjeli prijevod smatra pokrivenim; +- `check-translation-drift` prati zrcalne kopije dokumentacije `docs/i18n//**.md` — + nikada ne čita `src/i18n/messages/*.json`. Blokirajuće u poslu `docs-sync-strict` od + ponovne sinkronizacije 2026-09: uredite temeljni dokument → `npm run i18n:run -- --files=` (na razini odjeljka, brzo). -**Uvažava razlike, ne oslanja se na osnovno stanje.** Uspoređuje `en.json` u zajedničkoj bazi spajanja s -radnim stablom; za svaki ključ čija se engleska vrijednost promijenila zastario je svaki lokalitet koji još uvijek sadrži -neizmijenjeni prijevod. Time se namjerno **zamrzava postojeći dug** — razlika -ne može otkriti iz koje je stare engleske vrijednosti nastao dugogodišnji prijevod, pa kontrola procjenjuje -samo ono što trenutačna promjena dotiče. Alternativa (osnovno stanje s hashom za svaki ključ) zahtijevala bi -generiranu datoteku od ~600 KB, 3× veću od najvećeg postojećeg osnovnog stanja, koja bi se mijenjala sa svakim i18n PR-om. +**Svjestan razlika, bez oslanjanja na osnovno stanje.** Uspoređuje `en.json` u bazi spajanja s +radnim stablom; za svaki ključ čija se engleska vrijednost promijenila zastario je svaki lokalitet +koji još sadržava neizmijenjeni prijevod. Time se namjerno **zamrzava postojeći dug** — razlika +ne može otkriti iz koje je stare engleske vrijednosti nastao dugotrajni prijevod, pa kontrola +procjenjuje samo ono što trenutačna promjena obuhvaća. Alternativa (osnovno stanje s hashom za +svaki ključ) zahtijevala bi generiranu datoteku od ~600 KB, 3× veću od najvećeg postojećeg +osnovnog stanja, koja bi se mijenjala pri svakom i18n PR-u. -Postoje dva načina da se uvjet zadovolji: +Postoje dva načina da se provjera zadovolji: -1. ažurirajte zahvaćene prijevode ili -2. postavite ih na `__MISSING__:` — tada se tijekom izvođenja poslužuje ispravljeni engleski tekst - (`src/i18n/request.ts::deepMergeFallback`, #7258), a ključ se stavlja u red za prevođenje. +1. ažurirati obuhvaćene prijevode ili +2. postaviti ih na `__MISSING__:` — izvođenje tada poslužuje ispravljeni + engleski tekst (`src/i18n/request.ts::deepMergeFallback`, #7258), a ključ se stavlja u red za prijevod. -Ako se promijenilo **značenje** niza, radije **preimenujte ključ**: novi ključ ne može naslijediti -zastarjeli prijevod. Taj je obrazac upotrijebljen u #8463. +Ako se promijenilo **značenje** teksta, preporučuje se **preimenovati ključ**: novi ključ ne može +naslijediti zastarjeli prijevod. Taj je obrazac upotrijebljen u #8463. ```bash npm run i18n:check-value-drift # strogo (ono što CI pokreće) @@ -231,16 +236,16 @@ npm run i18n:check-value-drift:warn # samo izvješće BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Završava s kodom 0 i porukom `SKIP reason=base-unresolved` kada se osnovni katalog ne može pročitati (plitki -klon bez osnovne reference), u skladu s ponašanjem `check-openapi-breaking`. +Završava s kodom 0 i porukom `SKIP reason=base-unresolved` kada se osnovni katalog ne može +pročitati (plitki klon bez osnovne reference), slijedeći ponašanje `check-openapi-breaking`. ### Zadatak: `i18n` -Potpuna matrica provjere i18n-a (jedan zadatak po lokalitetu). Cijeli je zadatak savjetodavan. +Potpuna matrica provjere valjanosti i18n-a (jedan zadatak po lokalitetu). Cijeli je zadatak savjetodavan. -| Skripta | Provjerava | Blokiranje | -| ------------------------------- | -------------------------------------- | -------------------------------------------------------------- | -| `validate_translation.py quick` | Potpunost prijevoda za svaki lokalitet | **Savjetodavno** (`continue-on-error: true` za cijeli zadatak) | +| Skripta | Provjerava | Blokiranje | +| ------------------------------- | --------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | Potpunost prijevoda po lokalitetu | **Savjetodavno** (`continue-on-error: true` za cijeli zadatak) | ### Zadatak: `pr-test-policy` @@ -261,18 +266,18 @@ Pokreće se nakon `build`. U slučaju neuspjeha blokira spajanje. | `test:vitest` | MCP poslužitelj (110 alata), autoCombo, predmemorija — vitest pokretač | Da | | `test:vitest:ui` | Testovi komponenti korisničkog sučelja — vitest pokretač | **Blokira** — postojeći neuspjesi izričito su izuzeti u `vitest.config.ts`; novi neuspjesi uzrokuju neuspjeh zadatka | -### Noćni tijekovi rada (planirani, savjetodavni) +### Noćni tijekovi rada (zakazani, savjetodavni) Pokreću se prema cron rasporedu (i putem `workflow_dispatch`), nikada za PR-ove. Svi su savjetodavni. -| Tijek rada | Provjerava | Blokiranje | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | fast-check testovi svojstava s nasumičnim početnim brojem i velikim brojem izvođenja | **Savjetodavno** | -| `nightly-resilience` | kontrola rasta hrpe, ubrizgavanje kaotičnih kvarova, k6 testovi opterećenja/izdržljivosti | **Savjetodavno** | -| `nightly-llm-security` | promptfoo zaštita od umetanja (način blokiranja) + garak sonde (preskaču se bez tajne pružatelja usluge) | **Savjetodavno** | -| `nightly-schemathesis` | Neizrazito testiranje OpenAPI ugovora (schemathesis) na aktivnom OmniRouteu uz `docs/openapi.yaml` — otkriva kršenja specifikacije / neobrađene pogreške 500 (Faza 8 B.4) | **Savjetodavno** | -| `nightly-mutation` | Rezultat Stryker mutacijskog testiranja nad brzom jedinicom testiranja — preživjeli mutanti otkrivaju slabe provjere | **Savjetodavno** | -| `nightly-compat` | Matrica kompatibilnosti Node pogona u podržanim rasponima `engines.node` | **Savjetodavno** | +| Tijek rada | Provjerava | Blokiranje | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | fast-check testovi svojstava s nasumičnom početnom vrijednošću i velikim brojem izvođenja | **Savjetodavno** | +| `nightly-resilience` | kontrola rasta hrpe, kaotično ubrizgavanje pogrešaka, k6 testovi opterećenja/izdržljivosti | **Savjetodavno** | +| `nightly-llm-security` | promptfoo zaštita od ubrizgavanja (način blokiranja) + garak sonde (preskaču se bez tajne pružatelja usluge) | **Savjetodavno** | +| `nightly-schemathesis` | Fuzz testiranje OpenAPI ugovora (schemathesis) na aktivnom OmniRouteu koristeći `docs/openapi.yaml` — otkriva kršenja specifikacije / neobrađene pogreške 500 (Faza 8 B.4) | **Savjetodavno** | +| `nightly-mutation` | Rezultat Stryker mutacijskog testiranja na brzoj jedinici — preživjeli mutanti otkrivaju slabe provjere | **Savjetodavno** | +| `nightly-compat` | Matrica kompatibilnosti Node pogona za podržane raspone `engines.node` | **Savjetodavno** | --- @@ -537,43 +542,43 @@ pogrešku povezivanja i nikada ne prekida sesije. --- -## Zaostatak racionalizacije (pregled ROI-ja — Faza 9 Val 3) +## Zaostatak racionalizacije (pregled ROI-ja — faza 9, val 3) -Ovaj je popis usklađen s `ci.yml` 2026-06-17 (u prethodnoj su verziji izostavljeni +Ovaj je inventar usklađen s `ci.yml` 2026-06-17 (u prethodnoj su verziji izostavljeni `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Pregled ROI-ja usklađenog skupa utvrdio je sljedeće kandidate za racionalizaciju. **Spajanja su mehaničke promjene CI-ja; -promjene statusa/uklanjanja odluke su o pravilima rezervirane za operatera.** Ništa od -navedenog još nije primijenjeno. +promjene statusa/uklanjanja političke su odluke rezervirane za operatera.** Ništa navedeno +u nastavku još nije primijenjeno. -**Također prethodno nedokumentirano** (savjetodavno, slab signal): zadatak `docs-lint` -(markdownlint + Vale, cijeli zadatak ima `continue-on-error`) i samostalni tijekovi rada skenera +**Također nije dokumentirano iznad** (savjetodavno, slab signal): posao `docs-lint` +(markdownlint + Vale, cijeli posao s `continue-on-error`) i samostalni tijekovi rada skenera `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` nalazi se u -`quality-baseline.json`, ali nije povezan s blokirajućim zapornim mehanizmom u `ci.yml` — metrika je +`quality-baseline.json`, ali nije povezan s blokirajućom čegrtaljkom u `ci.yml` — metrika je trenutačno nepovezana. -### Spajanje / uklanjanje duplikata (mehaničko, manji rizik) +### Spajanje / uklanjanje duplikata (mehanički, manji rizik) -Svaki je kandidat provjeren u odnosu na aktivno stanje kontrolnih točaka 2026-06-17 (vjeruj, ali provjeri); -pokazalo se da nekoliko „očiglednih” spajanja skriva dug i **nisu** izravne zamjene bez poteškoća. +Svaki je kandidat provjeren u odnosu na aktivno stanje kontrola 2026-06-17 (vjeruj, ali provjeri); +pokazalo se da nekoliko „očiglednih” spajanja skriva dug i **nisu** izravno primjenjive zamjene. -- **`check:docs-sync` izvodi se dvaput** — samostalno u zadatku `lint` i ponovno unutar `check:docs-all` (`docs-sync-strict`) te u husky pre-commit kuki. ✅ **DOVRŠENO** — uklonjeno je samostalno pokretanje iz zadatka `lint`. -- **Skeniranje CVE-ova** — ❌ **NIJE jednostavno spajanje.** `audit:deps` strogo ne prolazi u slučaju bilo kojeg CVE-a visoke/kritične razine; `check:vuln-ratchet` (osv) ne prolazi samo u slučaju _regresije_ u odnosu na osnovnu vrijednost (trenutačno 1 MODERATE). Različita semantika — uklanjanjem `audit:deps` izgubila bi se apsolutna kontrolna točka za visoku/kritičnu razinu. Zadržati oboje. -- **Otkrivanje ciklusa** — ❌ **NIJE jednostavno spajanje.** `check:circular-deps` (dpdm) prijavljuje **91 ciklus** (zbog toga je savjetodavan); ne može postati blokirajući bez njihova prethodnog rješavanja, a ima širi opseg od zelenog, ciljano odabranog `check:cycles`. Zadržati `check:cycles` kao blokirajući; rješavanje 91 dpdm ciklusa zasebna je stavka zaostatka. -- **Složenost** — ✅ **DOVRŠENO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jedan ESLint prolaz, brojanje po ruleId-u kako bi osnovne vrijednosti za ciklomatsku složenost + najveći broj redaka i kognitivnu složenost ostale neovisne; pojedinačni `check:complexity` / `check:cognitive-complexity` ostaju za lokalni `--update`. -- **Sprječavanje halucinacija za `/api`** — ✅ **DOVRŠENO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jedan FS popis za `src/app/api`, openapi-routes + docs-symbols i dalje izvještavaju neovisno; pojedinačne provjere ostaju za lokalna pokretanja. -- **`check:node-runtime` izvodi se u 11 zadataka** — ⚠️ **nizak ROI.** Svaki se izvršava na zasebnom izvršitelju, a provjera traje <1 s; ukupna ušteda ~10 s, uz gubitak jeftine zaštite po zadatku. Nije vrijedno promjena. -- **`typecheck:noimplicit:core` u CI zadatku lint** — ✅ **uklonjen iz zadatka lint** (bio je savjetodavan uz `continue-on-error`); blokirajuću tipsku površinu čine `typecheck:core` + `check:type-coverage`. Lokalna je skripta zadržana. +- **`check:docs-sync` izvodi se dvaput** — samostalno u poslu `lint` i ponovno unutar `check:docs-all` (`docs-sync-strict`) te husky pre-commit kuke. ✅ **GOTOVO** — uklonjeno je samostalno pozivanje iz posla `lint`. +- **Skeniranje CVE-ova** — ❌ **NIJE jednostavno spajanje.** `audit:deps` završava neuspjehom pri bilo kojem CVE-u visoke/kritične razine; `check:vuln-ratchet` (osv) završava neuspjehom samo pri _regresiji_ u odnosu na osnovnu vrijednost (trenutačno 1 MODERATE). Semantike se razlikuju — uklanjanjem `audit:deps` izgubila bi se apsolutna kontrola za visoku/kritičnu razinu. Zadržati oboje. +- **Otkrivanje ciklusa** — ✅ **GOTOVO** (#15159 G-01/G-02). Stari je tekst ovdje nazivao `check:cycles` „zelenom, selektivnom” kontrolom i opravdavao njezino zadržavanje kao blokirajuće jer je `check:circular-deps` (dpdm) prijavljivao 91 ciklus. To zeleno stanje bilo je **lažno zeleno**: `check:cycles` skenirao je 5 poddirektorija (450 datoteka), prepoznavao samo statičke obrasce `import|export … from` te odbacivao svaki specifikator `@/` i `@omniroute/open-sse/`, pa nije mogao uočiti cikluse dinamičkog uvoza i aliasa koji su prevladavali u repozitoriju. Ispravljeno: kontrola sada obilazi `src` + `open-sse` (5023 datoteke), prikuplja specifikatore iz TypeScript AST-a (tako da se `import("…")` računa, a `typeof import("…")` na položaju tipa ne računa) te razrješava tsconfig `paths`. Pronalazi **14** ciklusa, a ne 0. Budući da se 14 postojećih ciklusa ne može ispraviti u PR-u kontrole, `check:cycles` sada je **čegrtaljka** (`--ratchet`, gornja granica `metrics.cycles.value = 14` u `quality-baseline.json`, `direction: down`) — blokira svaku _regresiju_, a broj se može samo smanjivati. CI izvodi `npm run check:cycles:ratchet`. Postupno smanjivanje provodi se uz **A-01**. `check:circular-deps` (dpdm) ostaje savjetodavan kao šire drugo mišljenje. +- **Složenost** — ✅ **GOTOVO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jedan ESLint prolaz, brojanje prema ruleId-u kako bi osnovne vrijednosti ciklomatske složenosti + maksimalnog broja redaka i kognitivne složenosti ostale neovisne; pojedinačni `check:complexity` / `check:cognitive-complexity` ostaju za lokalni `--update`. +- **Zaštita `/api` od halucinacija** — ✅ **GOTOVO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jedan inventar datotečnog sustava za `src/app/api`; openapi-routes + docs-symbols i dalje izvješćuju neovisno; pojedinačne provjere ostaju za lokalna izvođenja. +- **`check:node-runtime` izvodi se u 11 poslova** — ⚠️ **nizak ROI.** Svaki je zaseban izvršitelj, a provjera traje <1 s; ukupna ušteda iznosi ~10 s, uz gubitak jeftine zaštite po poslu. Nije vrijedno previranja. +- **`typecheck:noimplicit:core` u CI poslu lint** — ✅ **uklonjeno iz posla lint** (bilo je savjetodavno uz `continue-on-error`); blokirajuću površinu tipova čine `typecheck:core` + `check:type-coverage`. Lokalna skripta je zadržana. -### Promijeniti status / odlučiti (pravila operatera) +### Promijeniti status / odlučiti (politika operatera) -- `check:openapi-security-tiers` (savjetodavan) — ❌ **NIJE moguće jednostavno učiniti blokirajućim.** Završava kodom 0, ali upozorava da nekoliko ruta `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` nema oznaku `x-loopback-only: true`. Za njegovo provođenje najprije treba dodati te oznake u `openapi.yaml`. -- `typecheck:noimplicit:core` (savjetodavan) — u velikoj ga mjeri zamjenjuje blokirajući zaporni mehanizam `check:type-coverage`. Pretvoriti ga u zaporni mehanizam ili ukloniti suvišan drugi prolaz `tsc`. -- `test:vitest:ui` (sada **blokirajući**) — postojeći kvarovi izričito su izuzeti u `vitest.config.ts` uz komentare za praćenje `// #8618`; novi kvarovi uzrokuju neuspjeh zadatka. -- `check:secrets` (gitleaks, blokirajući zaporni mehanizam zamrznut na 3 dokumentirana lažno pozitivna nalaza) — dodati ta 3 nalaza na popis dopuštenih kako bi se došlo do 0 ili ga degradirati na savjetodavni. Preklapa se s GitHubovim izvornim skeniranjem tajni + `check:public-creds`. -- `check:pr-evidence` (blokirajući, pretražuje prozni tekst tijela PR-a) — visok rizik od lažno pozitivnih nalaza; uklanjanje slabi provedbu strogog pravila br. 18, pa je ovo stvarna odluka o pravilima. -- `semgrep` (savjetodavni samostalni tijek rada) — preklapa se s CodeQL-om za OWASP obitelji; povezati njegovu osnovnu vrijednost sa zapornim mehanizmom ili ga ukloniti. +- `check:openapi-security-tiers` (savjetodavno) — ❌ **NE može se jednostavno prebaciti.** Završava s 0, ali upozorava da nekoliko ruta `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` nema oznaku `x-loopback-only: true`. Za njegovo nametanje najprije je potrebno dodati te oznake u `openapi.yaml`. +- `typecheck:noimplicit:core` (savjetodavno) — uglavnom ga zamjenjuje blokirajuća čegrtaljka `check:type-coverage`. Prebaciti na čegrtaljku ili ukloniti suvišni drugi prolaz `tsc`. +- `test:vitest:ui` (sada **blokirajuće**) — postojeći neuspjesi izričito su isključeni u `vitest.config.ts` uz komentare za praćenje `// #8618`; novi neuspjesi uzrokuju neuspjeh posla. +- `check:secrets` (gitleaks, blokirajuća čegrtaljka zamrznuta na 3 dokumentirana lažno pozitivna rezultata) — dodati ta 3 rezultata na popis dopuštenih kako bi se došlo do 0 ili spustiti na savjetodavni status. Preklapa se s GitHubovim izvornim skeniranjem tajni + `check:public-creds`. +- `check:pr-evidence` (blokirajuće, pretražuje prozni tekst tijela PR-a) — visok rizik od lažno pozitivnih rezultata; uklanjanje slabi provedbu strogog pravila br. 18, stoga je ovo stvarna politička odluka. +- `semgrep` (savjetodavni samostalni tijek) — preklapa se s CodeQL-om za OWASP obitelji; povezati njegovu osnovnu vrijednost s čegrtaljkom ili ga ukloniti. --- diff --git a/docs/i18n/hu/CONTRIBUTING.md b/docs/i18n/hu/CONTRIBUTING.md index 2c50943ddab..5111b52b809 100644 --- a/docs/i18n/hu/CONTRIBUTING.md +++ b/docs/i18n/hu/CONTRIBUTING.md @@ -392,18 +392,18 @@ Adja hozzá a modelldefiníciókat az `open-sse/config/providerRegistry.ts` fáj - [ ] A tesztek sikeresen lefutnak (`npm test`) - [ ] A lintelés sikeresen lefut (`npm run lint`) -- [ ] A build sikeresen elkészül (`npm run build`) -- [ ] TypeScript-típusok hozzáadva az új nyilvános függvényekhez és interfészekhez +- [ ] A build sikeresen lefut (`npm run build`) +- [ ] Az új nyilvános függvényekhez és interfészekhez TypeScript-típusok lettek hozzáadva - [ ] Nincsenek beégetett titkos adatok vagy tartalékértékek -- [ ] A nyilvános upstream hitelesítő adatok beágyazása a `resolvePublicCred()` használatával történik (lásd: [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), soha nem literálként -- [ ] A hibaválaszok a `buildErrorBody()` / `sanitizeErrorMessage()` függvényeken keresztül haladnak — a válaszok törzsében nincsenek nyers veremkiírások (lásd: [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] A shell-parancsok (`exec` / `spawn`) a futásidejű értékeket az `env` használatával, nem pedig karakterlánc-interpolációval adják át +- [ ] A nyilvános upstream hitelesítő adatok a `resolvePublicCred()` segítségével vannak beágyazva (lásd: [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), soha nem literálként +- [ ] A hibaválaszok a `buildErrorBody()` / `sanitizeErrorMessage()` függvényeken haladnak keresztül — a válasz törzsében nincsenek nyers veremkivonatok (lásd: [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] A shell-parancsok (`exec` / `spawn`) a futásidejű értékeket az `env` segítségével, nem pedig sztringinterpolációval adják át - [ ] Minden bemenet Zod-sémákkal van validálva -- [ ] A felhasználókat érintő változásokhoz **változásnapló-töredék** hozzáadva a `changelog.d/{features|fixes|maintenance}/-.md` alatt (lásd: [`changelog.d/README.md`](./changelog.d/README.md)) — a `CHANGELOG.md` fájlt **ne** szerkeszd közvetlenül; a töredékeket a kiadáskor összesítik, és soha nem okoznak ütközést a PR-ok között -- [ ] A dokumentáció frissítve (ha alkalmazható) -- [ ] Nem keletkezett új CodeQL- vagy Secret-Scanning-riasztás, vagy mindegyik el lett utasítva a vonatkozó `docs/security/` dokumentumra hivatkozó műszaki indoklással -- [ ] A gyermekfolyamatokat indító útvonalak (`/api/mcp/`, `/api/cli-tools/runtime/`) `isLocalOnlyPath()` besorolást kaptak a `src/server/authz/routeGuard.ts` fájlban — lásd: [15. szigorú szabály](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] A commitüzenetekben nincsenek `Co-Authored-By` zárósorok — a commitoknak kizárólag a tároló tulajdonosának Git-identitása alatt kell megjelenniük (16. szigorú szabály) +- [ ] A felhasználókat érintő változásokhoz changelog-**töredék** lett hozzáadva a `changelog.d/{features|fixes|maintenance}/-.md` alatt (lásd: [`changelog.d/README.md`](./changelog.d/README.md)) — a `CHANGELOG.md` fájlt **ne** szerkeszd közvetlenül; a töredékek kiadáskor kerülnek összesítésre, és soha nem ütköznek a PR-ok között +- [ ] A dokumentáció frissítve lett (ha alkalmazható) +- [ ] Nem keletkeztek új CodeQL- vagy titokészlelési riasztások, illetve mindegyik el lett utasítva a vonatkozó `docs/security/` dokumentumra hivatkozó műszaki indoklással +- [ ] A gyermekfolyamatokat indító útvonalak (`/api/mcp/`, `/api/cli-tools/runtime/`) `isLocalOnlyPath()` besorolást kaptak az `src/server/authz/routeGuard.ts` fájlban — lásd: [15. szigorú szabály](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] A commitüzenetekben nincsenek AI-/bot-eredetű `Co-authored-by` zárósorok (16. szigorú szabály) — azok az emberi közreműködők, akiknek a munkája újra fel lett használva, szabványos `Co-authored-by: Name ` zárósorokkal kapnak elismerést --- diff --git a/docs/i18n/hu/docs/architecture/QUALITY_GATES.md b/docs/i18n/hu/docs/architecture/QUALITY_GATES.md index 57097daae3f..587e3741cc7 100644 --- a/docs/i18n/hu/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/hu/docs/architecture/QUALITY_GATES.md @@ -17,223 +17,222 @@ replikációs tervét lásd a ## Kapukészlet és végrehajtási profilok -### Jelöltek befogadása - -A CI és a Quality Gates munkafolyamat egyaránt stabil eredményt ad: `Gate / CI` és -`Gate / Quality`. A verziózott befogadási szabályzatuk minden felsőbb szintű feladatot -kötelezőként vagy tájékoztató jellegűként sorol fel. Minden alkalmazandó kötelező -feladatnak sikeresen kell lefutnia: a hiányzó, megszakított, kihagyott, függőben lévő -és ismeretlen eredmények nem alapozhatják meg a PASS állapotot. Az érvényes, csak -dokumentációt vagy csak katalógust érintő besorolás miatt egy kódsáv nem alkalmazható; -a piszkozat állapotú PR nem elfogadott jelölt. A `hotfix` címke nem teszi mellőzhetővé -a bizonyítékokat. - -Mindkét munkafolyamat lefedi a PR-eket, a main/release ágakra történő pushokat, a kézi -indítást és a merge-group eseményeket. A push, a dispatch és a merge-group a teljes -kiválasztást futtatja. A forkok és a merge groupok hosztolt futtatókat használnak azokhoz -a feladatokhoz, amelyek egyébként saját üzemeltetésű futtatókat választanának; a bevezetés -előtt ellenőrizni kell, hogy elegendő hosztolt kapacitás áll-e rendelkezésre. - -Minden JSON-nyugta azonosítja a checkout során lekért SHA-t, a munkafolyamat futását és -a próbálkozást. A CLI elutasítja a checkout és az esemény SHA-jának eltérését. A -munkafolyamat-tesztek a szabályzathoz való tartozást az eredményfeladat `needs` listájához -kötik, így egy új vagy eltávolított sáv nem tűnhet el észrevétlenül. A nyugták a saját -munkafolyamatukat fedik le, nem pedig a közzétételt, a telepítést vagy egy meglévő, -tájékoztató jellegű ellenőrző belső működését. Mindkét ellenőrzési név aktiválása az -ágszabályokban külön adminisztratív módosítás; e feladatok hozzáadása önmagában nem védi -az ágat. - -### Statikus ellenőrzési készlet - -A verziózott npm-alias-készlet és a statikus ellenőrzés tagsága a -`config/quality/gate-manifest.json` fájlban található. Futtassa az -`npm run check:gate-manifest` parancsot a szkriptnevek és a pontos parancsok -`package.json` fájllal való összevetéséhez; a hozzáadások, eltávolítások és -parancsváltozások mind a helyi hook, mind a CI változásbesorolási feladatainak -sikertelenségét okozzák. Egy alias nem munkafolyamat-feladat, mátrixpéldány vagy -teszteset: ezek darabszámai nem tüntethetők fel egymással felcserélhetőként. - -A kiválasztott aliasok végrehajtás nélküli áttekintéséhez használja az +### Jelöltek elfogadása + +A CI és a Quality Gates munkafolyamatok egyaránt stabil eredményt adnak ki: `Gate / CI` és +`Gate / Quality`. Verziózott elfogadási szabályzatuk minden upstream feladatot +kötelezőként vagy tanácsadó jellegűként sorol fel. Minden alkalmazandó kötelező feladatnak +sikeresen kell teljesülnie: a hiányzó, megszakított, kihagyott, függőben lévő és ismeretlen +eredmények nem alapozhatnak meg PASS állapotot. Egy érvényes, csak dokumentációt vagy +csak katalógust érintő besorolás miatt egy kódsáv nem alkalmazhatóvá válhat; +egy piszkozat állapotú PR nem elfogadott jelölt. A `hotfix` címke nem teszi +elhagyhatóvá a bizonyítékokat. + +Mindkét munkafolyamat lefedi a PR-okat és a main/release ágakra történő pushokat, a kézi indítást, +valamint a merge-group eseményeket. Push, kézi indítás és merge-group esetén a teljes kiválasztás +fut le. A forkok és merge groupok hosztolt futtatókat használnak azokhoz a feladatokhoz, amelyek +egyébként saját üzemeltetésű futtatókat választanának; a bevezetés előtt ellenőrizni kell, hogy +elegendő hosztolt kapacitás áll-e rendelkezésre. + +Minden JSON-nyugta azonosítja a checkout során kivett SHA-t, a munkafolyamat futását és a próbálkozást. +A CLI elutasítja, ha a checkout és az esemény SHA-ja nem egyezik. A munkafolyamat-tesztek a szabályzati +tagságot az eredményfeladat `needs` listájához kötik, így egy új vagy eltávolított sáv nem tűnhet el +észrevétlenül. A nyugták a saját munkafolyamatukat fedik le, nem pedig a közzétételt, a telepítést +vagy egy meglévő tanácsadó szkenner belső működését. Mindkét ellenőrzési név aktiválása az ágszabályokban +külön adminisztratív módosítás; e feladatok hozzáadása önmagában nem védi az ágat. + +### Statikus vizsgálatok készlete + +A verziózott npm-alias-készlet és a statikus vizsgálatok tagsága a +`config/quality/gate-manifest.json` fájlban található. Futtassa az `npm run check:gate-manifest` +parancsot a szkriptnevek és a pontos parancsok `package.json` fájlhoz viszonyított ellenőrzéséhez; +a hozzáadások, eltávolítások és parancsváltozások egyaránt meghiúsítják a helyi hookot és a CI +változásbesorolási feladatait. Egy alias nem munkafolyamat-feladat, mátrixpéldány vagy teszteset: +ezeket a darabszámokat nem szabad egymással felcserélhetőként bemutatni. + +A kiválasztott aliasok végrehajtás nélküli megtekintéséhez használja az `npm run quality:scan -- --list` vagy az `npm run quality:scan:fast -- --list` parancsot. A futtató az npm belépési pontját hívja meg, így annak futtatókörnyezete -— beleértve a Bunt is, ahol az be van állítva — megmarad. A jegyzék a profilokon -kívüli aliasokat külön meghívottként rögzíti, és a karbantartási parancsok tiltottak -a csak olvasható ellenőrzési profilokban. - -Ezek a profilok csak a statikus ellenőrzést fedik le. Nem tanúsítják a terméktesztek, -a lefedettség, a csomagolás, a külső ellenőrzések vagy egy jelölt teljes kiadási -elfogadásának megfelelőségét. A munkafolyamat befogadása a kapcsolódó -`config/quality/admission-policy.json` és `scripts/quality/admission-verdict.mjs` -fájlokat használja. A kiadásmegfigyelő profilok továbbra is különállók; az alkalmazandó -ellenőrzéseiket és nyugtáikat egymástól függetlenül vizsgálja meg. Az alábbi szöveges -készlet referencia, nem pedig bizonyíték arra, hogy egy kapu ténylegesen lefutott. - -A szkriptek a `scripts/check/` (szabályzatkapuk) és a `scripts/quality/` (ratchet-motor) +— beleértve a Bunt is, ahol az konfigurálva van — megmarad. +A jegyzék a profilokon kívüli aliasokat külön meghívottként rögzíti, a csak olvasható +vizsgálati profilokban pedig tilosak a karbantartási parancsok. + +Ezek a profilok kizárólag a statikus vizsgálatot fedik le. Nem tanúsítják a terméktesztek, +a lefedettség, a csomagolás, a külső ellenőrzések vagy egy jelölt teljes kiadási elfogadásának +eredményét. A munkafolyamatbeli elfogadás a kapcsolódó `config/quality/admission-policy.json` +és `scripts/quality/admission-verdict.mjs` fájlokat használja. A kiadásmegfigyelő profilok +különállók maradnak; alkalmazandó ellenőrzéseiket és nyugtáikat egymástól függetlenül +vizsgálja meg. Az alábbi szöveges készlet referencia, nem pedig annak bizonyítéka, hogy egy +kapu ténylegesen lefutott. + +A szkriptek a `scripts/check/` (szabályzati kapuk) és a `scripts/quality/` (ratchet-motor) könyvtárakban találhatók. A CI hiteles forrása a `.github/workflows/ci.yml`. -### Kiadási PR gyors útvonala (`quality.yml`) +### Release PR gyorsított útvonala (`quality.yml`) -A `.github/workflows/quality.yml` kiegészíti a CI-t a main/release ágakat célzó PR-ek, -a védett ágakra történő pushok, a dispatch és a merge groupok esetén. A PR-ek -útvonalszűrt gyors ellenőrzéseket használnak. A véglegesen letiltott, duplikált -buildet eltávolították; a tényleges build-, csomag- és rendszerindítási ellenőrzések -továbbra is a CI-ban maradnak. +A `.github/workflows/quality.yml` kiegészíti a CI-t a main/release ágakra irányuló PR-ok, +a védett ágakra történő pushok, a kézi indítások és a merge groupok esetében. A PR-ok +útvonal alapján szűrt gyors ellenőrzéseket használnak. A véglegesen letiltott, duplikált +buildet eltávolították; a tényleges build-/csomagolási-/indítási ellenőrzések továbbra is +a CI-ben maradnak. -| Feladat | Hatókör | Blokkoló | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `Docs Gates (fast-path)` | Dokumentációs/kód PR-ek; API-dokumentációs hivatkozások és teljes dokumentáció | Igen | -| `Fast Quality Gates` | Kód PR-ek; statikus ellenőrzések, típusellenőrzés, az irányítópult típusellenőrzése, érintett egységtesztek | Igen | -| `Forgotten sibling tests` | Kód PR-ek; a módosított modulok visszakövetése statikus fogyasztókig és lehetséges testvértesztekig; a barrel- és dinamikusimportálási útvonalak tájékoztató diagnosztikaként jelennek meg, a hivatkozott engedélyezőlistás kivételekkel | **Tájékoztató jellegű** | -| `Vitest (fast-path)` | Kód PR-ek; gyors vitest tesztcsomag | Igen | -| `Unit Tests fast-path` | Kód PR-ek; 4 shardos egységtesztcsomag | Igen | -| `No new ESLint warnings` | Kód PR-ek; az elnyomásokat figyelembe vevő lint-őr | Igen, forkoknál is | -| `Merge integrity (changelog + generated skills)` | Nem piszkozat állapotú PR-ek; a változásnapló és a generált skillek szinkronizálása | Igen, forkoknál is | +| Feladat | Hatókör | Blokkoló | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `Docs Gates (fast-path)` | Dokumentációs/kód-PR-ok; API-dokumentációs hivatkozások és docs-all | Igen | +| `Fast Quality Gates` | Kód-PR-ok; statikus ellenőrzések, típusellenőrzés, az irányítópult típusellenőrzése, érintett egységtesztek | Igen | +| `Forgotten sibling tests` | Kód-PR-ok; a módosított modulok visszakövetése statikus fogyasztókhoz és lehetséges testvértesztekhez; a barrel- és dinamikusimport-útvonalak tanácsadó jellegű diagnosztikaként jelennek meg, a hivatkozott engedélyezésilista-kivételekkel | **Tanácsadó jellegű** | +| `Vitest (fast-path)` | Kód-PR-ok; gyors vitest tesztkészlet | Igen | +| `Unit Tests fast-path` | Kód-PR-ok; 4 shardos egységtesztkészlet | Igen | +| `No new ESLint warnings` | Kód-PR-ok; a kivételeket figyelembe vevő lint-védelem | Igen, a forkokat is beleértve | +| `Merge integrity (changelog + generated skills)` | Nem piszkozat PR-ok; a változásnapló és a generált készségek szinkronizálása | Igen, a forkokat is beleértve | #### Elfelejtett testvértesztek jelentése -Az `npm run check:forgotten-sibling-tests` újra felhasználja a teszthatás-térkép mögötti -importfeloldót. Minden módosított éles modulhoz determinisztikus -`módosított modul/szimbólum -> statikus fogyasztó -> lehetséges testvérteszt` láncokat -jelent, ha a lehetséges teszt hiányzik a pull request diffjéből. A Markdown-összefoglalót -és a JSON-eredményt a rendszer `forgotten-sibling-tests` munkafolyamat-műtermékként őrzi -meg a blokkoló bevezetést megelőző kalibráláshoz. +Az `npm run check:forgotten-sibling-tests` újra felhasználja a teszthatás-térkép mögötti importfeloldót. +Minden módosított éles modulnál determinisztikus +`módosított modul/szimbólum -> statikus fogyasztó -> lehetséges testvérteszt` láncokat jelent, ha a +lehetséges teszt hiányzik a pull request diffjéből. A Markdown-összefoglalót és a JSON-eredményt +a rendszer `forgotten-sibling-tests` munkafolyamat-műtermékként őrzi meg a blokkoló bevezetést +megelőző kalibrációhoz. -A barrel re-exportok és a dinamikus importok csak feloldási diagnosztikák; soha nem eredményeznek -blokkoló megállapítást. A felülvizsgált kivételek helye: -`config/quality/forgotten-sibling-allowlist.json`. Minden bejegyzésnek meg kell neveznie a fogyasztót és a jelölt +A barrel re-exportok és a dinamikus importok kizárólag feloldási diagnosztikák; soha nem eredményeznek +blokkoló megállapítást. A felülvizsgált kivételek a +`config/quality/forgotten-sibling-allowlist.json` fájlban találhatók. Minden bejegyzésnek meg kell neveznie a fogyasztót és a jelölt tesztet, konkrét indoklást kell adnia, valamint egy GitHub-issue-ra vagy pull requestre kell hivatkoznia. A hibás formátumú bejegyzések -zárt módon hibát okoznak. A kivételek nem fedhetnek el törölt jelölt tesztet vagy olyan diffet, amely `.skip`/`.todo` elemet ad hozzá; -az ellenőrzések gyengítése és az egyéb elfedések továbbra is a különálló, blokkoló +biztonságosan elutasításra kerülnek. A kivételek nem fedhetnek el törölt jelölt tesztet vagy olyan diffet, amely `.skip`/`.todo` elemet ad hozzá; +az ellenőrzések gyengítése és más elfedések továbbra is a függetlenül blokkoló `check:test-masking` kapu hatáskörébe tartoznak. ### Feladat: `lint` Minden, a `main` ágra irányuló PR esetén lefut. Hiba esetén blokkolja az egyesítést. -| Szkript (`npm run ...`) | Ellenőrzi | Blokkoló | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | A Node.js verziója a támogatott tartományon belül van | Igen | -| `check:cycles` | Körkörös importok — az összes `src/` + `open-sse/` modul | Igen | -| `check:route-validation:t06` | Minden útvonalon jelen vannak a Zod-sémák (6. szintű szabályzat) | Igen | -| `check:any-budget:t11` | Az `@ts-expect-error // any` előfordulásainak száma nem haladja meg a keretet (11. szintű catraca) | Igen | -| `check:provider-consistency` | A `providers.ts` minden szolgáltatójához tartozik megfelelő bejegyzés a `providerRegistry.ts` fájlban (és fordítva, az engedélyezési listán belül) | Igen | -| `check:model-lifecycle` | A három kézzel karbantartott útválasztási tábla konzisztens marad a repozitóriumban tárolt életciklus-pillanatképpel (#11503): a `FITNESS_TABLE` (`taskFitness.ts`) nem pontoz olyan kivezetett azonosítót, amelyhez a `REGISTRY` útvonalat tud rendelni; minden `BUILT_IN_ALIASES`-cél megtalálható a `REGISTRY`-ben, és hiányzik a kivezetett azonosítók pillanatképéből; minden, a `REGISTRY`-ben továbbra is szereplő kivezetett azonosító továbbításra kerül, vagy szerepel az `allowedRetiredInCatalog` listában; továbbá a `DEFAULT_DEGRADATION_MAP` egyetlen forrása vagy célja sem jelenik meg kivezetettként ebben a pillanatképben. Ez nem bizonyítja, hogy egy modellt jelenleg kiszolgál valamely élő felsőbb szintű szolgáltatás. Offline — összehasonlítást végez a `config/quality/model-lifecycle.json` fájllal, amely kézzel frissíthető az `npm run quality:refresh-model-lifecycle` paranccsal (hálózatot igényel; nincs bekötve a CI-be). Az `allowedRetiredInCatalog` egy fokozatos leépítést kikényszerítő mechanizmus: csak nyomonkövetési hibajeggyel együtt adj hozzá új bejegyzést. | Igen | -| `check:fetch-targets` | A kliensoldali `src/` minden `fetch("/api/...")` hívása egy valódi `route.ts` fájlra oldódik fel | Igen | -| `check:deps` | A repozitórium minden `package.json` fájljában található összes, `npm install` paranccsal telepíthető függőség szerepel a `dependency-allowlist.json` fájlban; az új, nem rögzített verziójú vagy néveltérítéses csomagok megjelölésre kerülnek | Igen | -| `audit:deps` | `npm audit` (gyökér + electron) — nincs magas/kritikus súlyosságú biztonsági figyelmeztetés (átfedésben van az osv `check:vuln-ratchet` ellenőrzésével; lásd: Racionalizálási hátralék) | Igen | -| `check:lockfile` | A `package-lock.json` integritása — https-nyilvántartás, integritási hashek, gazdagép-felülbírálások nélkül | Igen | -| `check:licenses` | SPDX-licenc engedélyezési lista az éles függőségekhez | Igen | -| `check:tracked-artifacts` | Nincsenek buildelési melléktermékek / verziókövetésbe bevitt `node_modules` szimbolikus linkek (a husky pre-commit során is lefut; a pre-push szándékosan kevés ellenőrzést végez — #6716) | Igen | -| `check:ai-attribution` | Nincs MI/bot `Co-Authored-By` zárósor vagy MI-generálásra utaló lábléc a PR commitjaiban, címében vagy törzsében — 16. szigorú szabály (a `quality.yml` gyors ellenőrzési ciklusában a PR→`release/**` esetén — beolvassa az esemény adatait, PR-en kívül nem végez műveletet —, valamint egy csak PR-ekre vonatkozó lépésként a `ci.yml` lintelésében a PR→`main` esetén; továbbá a husky `commit-msg` hookban; emberi társszerzők engedélyezettek; #14436) | -| `check:vitest-exclusions` | Minden Vitest-kizárás megnevez egy nyomon követési hibajegyet, és szerepel a `config/quality/vitest-exclusions.json` fájlban (#13204) | Igen | -| `check:file-size` | Egyetlen forrásfájl sem lépi túl a kiterjesztésenkénti korlátot (fokozatos szigorítás: a nagy, befagyasztott fájlok a `frozen` listában vannak) | Igen | -| `check:error-helper` | A végrehajtókban/kezelőkben található hibaválaszok a `buildErrorBody()` / `sanitizeErrorMessage()` függvényt használják (12. szigorú szabály) | Igen | -| `check:migration-numbering` | A migrációs SQL-fájlok sorszámozása folyamatos, nincsenek kihagyások vagy ismétlődések | Igen | -| `check:public-creds` | Nincsenek literális OAuth `client_id`/`client_secret` értékek vagy Firebase Web-kulcsok a `publicCreds.ts` fájlon kívül (11. szigorú szabály) | Igen | -| `check:db-rules` | Nincs nyers SQL a `src/lib/db/` modulokon kívül; nincsenek gyűjtőimportok a `localDb.ts` fájlból (2./5. szigorú szabály) | Igen | -| `check:known-symbols` | A diszpécsertáblákban regisztrált szolgáltató-végrehajtók, útválasztási stratégiák és fordítók megfelelnek a lemezen található fájloknak — nincsenek árva vagy deklarálatlan szimbólumok | Igen | -| `check:route-guard-membership` | Minden olyan útvonalat, amely gyermekfolyamatot indít, az `isLocalOnlyPath()` osztályoz (15./17. szigorú szabály) | Igen | -| `check:test-discovery` | A repó minden `*.test.ts` / `*.spec.ts` fájlját legalább egy tesztfuttató begyűjti (racsnis szabály: a `test-discovery-baseline.json` fájlban lévő árvalista csak csökkenhet) | Igen | -| `check:agent-skills-sync` | A generált agent-skills összetevők megfelelnek a forráskatalógusuknak (nincs eltérés) | -| `check:provider-asset-provenance` | A szolgáltatói logókhoz/összetevőkhöz rögzített származási bejegyzés tartozik | -| `lint:json` | A JSON-konfigurációs fájlok feldolgozhatók, és megfelelnek a repó lintelési szabályainak | -| `typecheck:core` | TypeScript-fordítás hibák nélkül (csak tájékoztató jellegű figyelmeztetések) | Igen | -| `typecheck:noimplicit:core` | Szigorú `noImplicitAny` — jövőorientált; számos már meglévő hívási helyen továbbra is szükség van annotációkra | **Tájékoztató** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | A `tsc` futtatása a `src/app/(dashboard)/**` körére korlátozva (#7033) — a `typecheck:core` gondosan összeállított, 27 fájlból álló engedélyezési listája egyetlen dashboard TSX-fájlt sem tartalmaz, és a `next build` sem végez rajtuk típusellenőrzést (`next.config.mjs` esetén az `ignoreBuildErrors: true` van beállítva), ezért az ottani árvaazonosító-regressziók (#6625/#6909) láthatatlanok voltak a CI számára. Az ellenőrzés egy befagyasztott, fájlonkénti és TS-hibakódonkénti darabszám-alapértékhez (`config/quality/dashboard-typecheck-baseline.json`) viszonyít (ugyanazzal az elavultság-ellenőrzési mintával, mint a `check:known-symbols`) — csak az alapértékben szereplő darabszámot meghaladó ÚJ hibák okozzák az ellenőrzési kapu sikertelenségét; ha egy már meglévő hibát kijavítottak, az alapérték az `--update` kapcsolóval csökkenthető. | Igen | +| Szkript (`npm run ...`) | Mit ellenőriz | Blokkoló | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | A Node.js verziója a támogatott tartományon belül van | Igen | +| `check:cycles` | Körkörös importok a teljes `src/` + `open-sse/` területén (AST-alapú, a tsconfig `paths` feloldásával). Önállóan futtatva tájékoztató jellegű, és felsorolja a ciklusokat. A `check:cycles:ratchet` (amelyet a CI futtat) blokkol, ha a szám meghaladja a `quality-baseline.json` fájlban szereplő `metrics.cycles` felső korlátot — ez jelenleg 14, `direction: down`, így csak csökkenhet (#15159 G-01/G-02) | Igen (ratchet) | +| `check:route-validation:t06` | Minden útvonalon megtalálhatók a Zod-sémák (6. szintű szabályzat) | Igen | +| `check:any-budget:t11` | Az `@ts-expect-error // any` előfordulásainak száma nem haladja meg a keretet (11. szintű catraca) | Igen | +| `check:provider-consistency` | A `providers.ts` minden szolgáltatójához tartozik megfelelő bejegyzés a `providerRegistry.ts` fájlban (és fordítva, az engedélyezési listán belül) | Igen | +| `check:model-lifecycle` | A három kézzel karbantartott útválasztási tábla konzisztens marad a verziókezelőben tárolt életciklus-pillanatképpel (#11503): a `FITNESS_TABLE` (`taskFitness.ts`) nem pontoz olyan kivezetett azonosítót, amelyet a `REGISTRY` képes útválasztani; minden `BUILT_IN_ALIASES`-cél megtalálható a `REGISTRY` jegyzékben, és hiányzik a kivezetett azonosítók pillanatképéből; minden, a `REGISTRY` jegyzékben még szereplő kivezetett azonosító továbbításra kerül, vagy szerepel az `allowedRetiredInCatalog` listában; továbbá a `DEFAULT_DEGRADATION_MAP` egyetlen forrása vagy célja sem szerepel kivezetettként ebben a pillanatképben. Ez nem bizonyítja, hogy egy modellt jelenleg kiszolgál egy élő külső szolgáltatás. Offline — az összehasonlítás a `config/quality/model-lifecycle.json` fájllal történik, amely kézzel frissíthető az `npm run quality:refresh-model-lifecycle` paranccsal (hálózatot igényel; nincs bekötve a CI-ba). Az `allowedRetiredInCatalog` egy fokozatos leépítést kikényszerítő mechanizmus: csak nyomonkövetési feladattal együtt adjon hozzá bejegyzést. | Igen | +| `check:fetch-targets` | Az ügyféloldali `src/` könyvtárban található minden `fetch("/api/...")` egy valódi `route.ts` fájlra oldódik fel | Igen | +| `check:deps` | A tároló minden `package.json` fájljában szereplő, `npm install` segítségével telepíthető összes függőség megtalálható a `dependency-allowlist.json` fájlban; az új, nem rögzített verziójú vagy elírásos csomagnévvel visszaélő csomagok megjelölésre kerülnek | Igen | +| `audit:deps` | `npm audit` (gyökér + electron) — nincs magas/kritikus súlyosságú biztonsági figyelmeztetés (átfedésben van az osv `check:vuln-ratchet` ellenőrzésével; lásd: Rationalizálási hátralék) | Igen | +| `check:lockfile` | A `package-lock.json` integritása — https-beállításjegyzék, integritási hashek, nincsenek gazdagép-felülbírálások | Igen | +| `check:licenses` | SPDX-licenc engedélyezési lista az éles környezet függőségeihez | Igen | +| `check:tracked-artifacts` | Nincsenek buildműtermékek / commitolt `node_modules` szimbolikus linkek (a husky pre-commit során is fut; a pre-push szándékosan könnyű — #6716) | Igen | +| `check:ai-attribution` | Nincs AI/bot `Co-Authored-By` előzetes vagy AI-generálásra utaló záradék a PR commitjaiban, címében vagy törzsében — 16. szigorú szabály (a `quality.yml` gyors ellenőrzési ciklusában a PR→`release/**` esetén — beolvassa az esemény adatait, PR-eken kívül nem végez műveletet —, valamint egy csak PR-ekre vonatkozó lépésként a `ci.yml` lintelésében a PR→`main` esetén; továbbá a husky `commit-msg` hookban; emberi társszerzők megengedettek; #14436) | +| `check:vitest-exclusions` | Minden Vitest-kizárás megnevez egy nyomon követési hibajegyet, és szerepel a `config/quality/vitest-exclusions.json` fájlban (#13204) | Igen | +| `check:file-size` | Egyetlen forrásfájl sem lépi túl a kiterjesztésenkénti korlátot (racsni: befagyasztott nagy fájlok a `frozen` listában) | Igen | +| `check:error-helper` | A végrehajtókban/kezelőkben található hibaválaszok a `buildErrorBody()` / `sanitizeErrorMessage()` függvényt használják (12. szigorú szabály) | Igen | +| `check:migration-numbering` | A migrációs SQL-fájlok sorszámozása folyamatos, nincsenek kihagyások vagy ismétlődések | Igen | +| `check:public-creds` | Nincsenek literálisan megadott OAuth `client_id`/`client_secret` értékek vagy Firebase Web-kulcsok a `publicCreds.ts` fájlon kívül (11. szigorú szabály) | Igen | +| `check:db-rules` | Nincs nyers SQL a `src/lib/db/` modulokon kívül; nincsenek gyűjtőimportok a `localDb.ts` fájlból (2./5. szigorú szabály) | Igen | +| `check:known-symbols` | A diszpécsertábláikban regisztrált szolgáltatói végrehajtók, útválasztási stratégiák és fordítók megfelelnek a lemezen található fájloknak — nincsenek árva vagy nem deklarált szimbólumok | Igen | +| `check:route-guard-membership` | Minden gyermekfolyamatot indító útvonalat besorol az `isLocalOnlyPath()` (15./17. szigorú szabály) | Igen | +| `check:test-discovery` | A repóban található minden `*.test.ts` / `*.spec.ts` fájlt legalább egy tesztfuttató begyűjt (kilincsmű: a `test-discovery-baseline.json` árvalistája csak rövidülhet) | Igen | +| `check:agent-skills-sync` | A generált agent-skills artefaktumok megfelelnek a forráskatalógusuknak (nincs eltérés) | +| `check:provider-asset-provenance` | A szolgáltatói logókhoz/erőforrásokhoz rögzített eredetbejegyzés tartozik | +| `lint:json` | A JSON-konfigurációs fájlok feldolgozhatók, és megfelelnek a repó lintelési szabályainak | +| `typecheck:core` | TypeScript-fordítás hibák nélkül (csak tájékoztató jellegű figyelmeztetések) | Igen | +| `typecheck:noimplicit:core` | Szigorú `noImplicitAny` — jövőorientált; számos már meglévő hívási helyhez továbbra is annotációk szükségesek | **Tájékoztató** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | A `tsc` hatóköre a `src/app/(dashboard)/**` útvonalra korlátozódik (#7033) — a `typecheck:core` gondosan összeállított, 27 fájlból álló engedélyezési listája egyetlen dashboard TSX-fájlt sem tartalmaz, és a `next build` sem végez rajtuk típusellenőrzést (a `next.config.mjs` fájlban az `ignoreBuildErrors: true` van beállítva), ezért az ottani gazdátlanazonosító-regressziók (#6625/#6909) láthatatlanok voltak a CI számára. Az ellenőrzés egy befagyasztott, fájlonkénti és TS-kódonkénti hibaszám-alapértékhez (`config/quality/dashboard-typecheck-baseline.json`, ugyanazzal az elavulás elleni kikényszerítési mintával, mint a `check:known-symbols`) viszonyít — csak az alapértékben rögzített darabszámot meghaladó ÚJ hibák miatt bukik el az ellenőrzési kapu; egy már meglévő hiba javításakor az alapérték az `--update` kapcsolóval csökkenthető. | Igen | ### Feladat: `quality-gate` -A `test-coverage` után fut. Sikertelenség esetén blokkolja az összevonást. +A `test-coverage` után fut. Hiba esetén blokkolja az összevonást. -| Szkript | Ellenőrzés | Blokkoló | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `quality:collect` | Létrehozza a `quality-metrics.json` fájlt (ESLint-figyelmeztetések száma, lefedettség az egyesített részjelentésből) | Igen (a ratchet előtt fut) | -| `quality:ratchet` | A `quality-baseline.json` egyetlen metrikája sem romlott (ESLint-figyelmeztetések ≤ alapérték; lefedettség ≥ alapérték) | Igen | -| `check:duplication` | A kódduplikáció (jscpd@4) nem haladja meg a `quality-baseline.json` alapértékét | Igen | -| `check:complexity` | A fájlszintű ciklomatikus komplexitás nem haladja meg a felső korlátot (alap ESLint `complexity` + `max-lines-per-function`) | Igen | -| `check:cognitive-complexity` | Kognitív komplexitási ratchet (`eslint-plugin-sonarjs`) — külön ESLint-futtatás; a CI mindkettőt egyesítve, egyetlen `check:complexity-ratchets` lépésként futtatja | Igen | -| `check:dead-code` | A nem használt exportok/fájlok ratchetje (knip) nem romlik az alapértékhez képest | Igen | -| `check:compression-budget` | Tömörítési benchmark kerete — a motoronkénti minimális tokenmegtakarítás nem romolhat | Igen | -| `check:type-coverage` | A típusokkal ellátott kód százalékos arányának ratchetje (`type-coverage`) nem romlik; nagyrészt kiváltja a `typecheck:noimplicit:core` ellenőrzést | Igen | -| `check:codeql-ratchet` | A nyitott CodeQL-riasztások száma nem nő (a `gh api` segítségével olvassa be; token nélkül szabályosan kihagyja) — a frissítési gyakoriságot és a kézi indítást lásd alább, a „CodeQL ratchet” szakaszban | Igen | +| Szkript | Ellenőrzés | Blokkoló | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `quality:collect` | Létrehozza a `quality-metrics.json` fájlt (ESLint-figyelmeztetések száma, lefedettség az egyes részek egyesített jelentéséből) | Igen (a ratchet előfeltétele) | +| `quality:ratchet` | A `quality-baseline.json` egyetlen metrikája sem romlott (ESLint-figyelmeztetések ≤ alapérték; lefedettség ≥ alapérték) | Igen | +| `check:duplication` | A kódduplikáció (jscpd@4) nem haladja meg a `quality-baseline.json` fájlban meghatározott alapértéket | Igen | +| `check:complexity` | A fájlszintű ciklomatikus komplexitás nem haladja meg a felső korlátot (alapvető ESLint `complexity` + `max-lines-per-function`) | Igen | +| `check:cognitive-complexity` | Kognitívkomplexitás-ratchet (`eslint-plugin-sonarjs`) — külön ESLint-futtatás; a CI mindkettőt összevonva, egyetlen `check:complexity-ratchets` lépésként futtatja | Igen | +| `check:dead-code` | A nem használt exportok/fájlok ratchetje (knip) nem romlik az alapértékhez képest | Igen | +| `check:compression-budget` | Tömörítési teljesítménymérés kerete — a motoronkénti tokenmegtakarítási minimumértékek nem romolhatnak | Igen | +| `check:type-coverage` | A típusozottsági százalék ratchetje (`type-coverage`) nem romlik; nagyrészt kiváltja a `typecheck:noimplicit:core` ellenőrzést | Igen | +| `check:codeql-ratchet` | A nyitott CodeQL-riasztások száma nem nő (beolvasás a `gh api` használatával; token nélkül szabályosan kihagyja) — frissítési gyakoriság és kézi indítás: lásd alább: „CodeQL-ratchet” | Igen | ### Feladat: `quality-extended` A teljes feladat tájékoztató jellegű (`continue-on-error: true`). Az npm-alapú ratchetek -ténylegesen lefutnak; a külső ellenőrzők a `gh release download` segítségével települnek, és automatikusan kihagyják magukat (0-s kilépési kóddal), -ha egy bináris továbbra sem érhető el. - -| Szkript | Ellenőrzés | Blokkoló | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | -| `check:circular-deps` | Nincsenek körkörös függőségek (dpdm) | **Tájékoztató jellegű** | -| `check:bundle-size` | A csomag mérete nem haladja meg a felső korlátot | **Tájékoztató jellegű** | -| `check:secrets` | Titkok keresése (gitleaks) — kihagyja, ha a bináris hiányzik | **Tájékoztató jellegű** | -| `check:vuln-ratchet` | A függőségek sebezhetőségei (osv-scanner) nem romlanak — kihagyja, ha a bináris hiányzik | **Tájékoztató jellegű** | -| `check:workflows` | Munkafolyamat-ellenőrzés (actionlint + zizmor); a hiányzó/hibás ellenőrzők, érvénytelen jelentések vagy hiányzó ratchet-alapérték INCOMPLETE eredménnyel meghiúsítják. Az érvényes találatok a kiválasztott szigorú/tájékoztató/ratchet szabályzatot követik | A végrehajtás kötelező; a zizmor ratchet blokkoló a CI-ben | -| `check:openapi-breaking` | A nyilvános API-szerződés (`openapi.yaml`) visszafelé nem kompatibilis változásai az alapághoz képest (oasdiff) — `openapiBreaking=N` értéket ad ki; kihagyja, ha az oasdiff hiányzik vagy az alapspecifikáció nem oldható fel | **Tájékoztató jellegű** | +ténylegesen lefutnak; a külső ellenőrzők telepítése a `gh release download` használatával +történik, és automatikusan kihagyják az ellenőrzést (exit 0), ha a bináris továbbra sem érhető el. + +| Szkript | Ellenőrzés | Blokkoló | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | +| `check:circular-deps` | Nincsenek körkörös függőségek (dpdm) | **Tájékoztató jellegű** | +| `check:bundle-size` | A csomag mérete nem haladja meg a felső korlátot | **Tájékoztató jellegű** | +| `check:secrets` | Titkok keresése (gitleaks) — kihagyja, ha a bináris nem érhető el | **Tájékoztató jellegű** | +| `check:vuln-ratchet` | A függőségek sebezhetőségei (osv-scanner) nem romlanak — kihagyja, ha a bináris nem érhető el | **Tájékoztató jellegű** | +| `check:workflows` | Munkafolyamatok lintelése (actionlint + zizmor); a hiányzó/hibás ellenőrzők, az érvénytelen jelentések vagy a hiányzó ratchet-alapérték INCOMPLETE állapottal hibát okoznak. Az érvényes találatokra a kiválasztott szigorú/tájékoztató/ratchet szabályzat vonatkozik | A végrehajtás kötelező; a zizmor-ratchet blokkol a CI-ben | +| `check:openapi-breaking` | A nyilvános API-szerződés (`openapi.yaml`) kompatibilitást megszakító módosításai az alapághoz képest (oasdiff) — `openapiBreaking=N` értéket állít elő; kihagyja, ha az oasdiff nem érhető el, vagy az alapspecifikáció nem oldható fel | **Tájékoztató jellegű** | ### Feladat: `docs-sync-strict` Minden, a `main` ágra irányuló PR esetén lefut. Hiba esetén blokkolja az egyesítést. -| Szkript | Ellenőrzi | Blokkoló | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `check:docs-all` | Metakapu, amely egymás után futtatja az alábbi 6 alkaput | Igen | -| ↳ `check:docs-sync` | A CHANGELOG / OpenAPI / llm.txt verzióinak konzisztenciája | Igen | -| ↳ `check:docs-counts` | A prózában szereplő számok (szolgáltatók száma, migrációk száma stb.) a tényleges értékekhez tartozó szigorítási tartományon belül vannak | Igen | -| ↳ `check:env-doc-sync` | A `.env.example` minden környezeti változója dokumentálva van egy dokumentációs táblázatban, és fordítva | Igen | -| ↳ `check:deprecated-versions` | A dokumentáció nem tartalmaz elavult verziókarakterláncokat | Igen | -| ↳ `check:doc-links` | A dokumentáció belső markdown-hivatkozásai valódi fájlokra mutatnak (`[szöveg]`/`(útvonal)` formában) | Igen | -| ↳ `check:fabricated-docs` | A dokumentációban említett útvonalak, környezeti változók, CLI-parancsok, hooknevek és fájlútvonalak léteznek a kódbázisban. Szigorú kapu a `--strict` használatával; a kapcsoló nélkül csak enyhe hibát jelez. | Igen (CI-ben a `--strict` használatával) | -| `check:cli-i18n` | A CLI-parancsok karakterláncai minden i18n területi beállítási fájlban megtalálhatók | Igen | -| `check:openapi-coverage` | Az OpenAPI-specifikáció legalább a valós útvonalak szigorított alsó küszöbéig biztosít lefedettséget | Igen | -| `check:openapi-security-tiers` | Az `openapi.yaml` biztonsági szintjeinek annotációi összhangban vannak a `routeGuard.ts` besorolásaival | **Tájékoztató jellegű** | -| `check:openapi-routes` | Az `openapi.yaml` minden útvonala valódi `route.ts` fájlra oldható fel (hallucináció elleni védelem) | Igen | -| `check:docs-symbols` | A `docs/**/*.md` fájlok minden `/api/...` hivatkozása valódi `route.ts` fájlra oldható fel (hallucináció elleni védelem) | Igen | -| `i18n translation drift` | Lefordítatlan kulcsok az i18n területi beállítási fájlokban — csak figyelmeztetés | **Tájékoztató jellegű** | +| Szkript | Mit ellenőriz | Blokkoló | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `check:docs-all` | Metakapu, amely egymás után futtatja az alábbi 6 alkaput | Igen | +| ↳ `check:docs-sync` | A CHANGELOG / OpenAPI / llm.txt verzióinak konzisztenciája | Igen | +| ↳ `check:docs-counts` | A prózában szereplő számok (szolgáltatók száma, migrációk száma stb.) a valós értékekhez tartozó szigorodó tartományon belül vannak | Igen | +| ↳ `check:env-doc-sync` | A `.env.example` minden környezeti változója dokumentálva van egy dokumentációs táblázatban, és fordítva | Igen | +| ↳ `check:deprecated-versions` | A dokumentáció nem tartalmaz elavult verziókarakterláncokat | Igen | +| ↳ `check:doc-links` | A dokumentáció belső markdown-hivatkozásai létező fájlokra mutatnak (`[szöveg]`/`(útvonal)` forma) | Igen | +| ↳ `check:fabricated-docs` | A dokumentációban hivatkozott útvonalak, környezeti változók, CLI-parancsok, hooknevek és fájlútvonalak léteznek a kódbázisban. Szigorú kapu a `--strict` kapcsolóval; nélküle csak figyelmeztető hibát jelez. | Igen (CI-ben a `--strict` révén) | +| `check:cli-i18n` | A CLI-parancsok karakterláncai minden i18n területi beállítás fájljában megtalálhatók | Igen | +| `check:openapi-coverage` | Az OpenAPI-specifikáció legalább a valós útvonalak számához igazított, fokozatosan emelt minimumot lefedi | Igen | +| `check:openapi-security-tiers` | Az `openapi.yaml` biztonsági szintre vonatkozó annotációi összhangban vannak a `routeGuard.ts` besorolásaival | **Tájékoztató jellegű** | +| `check:openapi-routes` | Az `openapi.yaml` minden útvonala egy valós `route.ts` fájlra oldódik fel (hallucináció elleni védelem) | Igen | +| `check:docs-symbols` | A `docs/**/*.md` fájlok minden `/api/...` hivatkozása egy valós `route.ts` fájlra oldódik fel (hallucináció elleni védelem) | Igen | +| `i18n translation drift` | Lefordítatlan kulcsok az i18n területi beállítások fájljaiban — csak figyelmeztetés | **Tájékoztató jellegű** | ### Feladat: `i18n-ui-coverage` -| Szkript | Ellenőrzi | Blokkoló | -| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `check-ui-keys-coverage` (beágyazott) | A felhasználói felület i18n-kulcsainak lefedettsége ≥ 65% | Igen | -| `check-ui-value-drift` (beágyazott) | Egy átírt angol **érték** nem hagy maga után elavult fordítást | Igen | -| `check-new-key-coverage` (beágyazott) | Egy **új** angol kulcs minden területi beállításhoz le van fordítva — a `__MISSING__:` jelölő elutasításra kerül | Igen | -| `check-translation-ratio` | A valódi fordítások területi beállításonkénti aránya (az angollal azonos / helyőrző / hiányzó levelek az engedélyezési listán kívül) nem haladhatja meg a `config/quality/i18n-translation-baseline.json` értékét és a ráhagyást | **Tájékoztató jellegű** | +| Szkript | Mit ellenőriz | Blokkoló | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `check-ui-keys-coverage` (inline) | A felhasználói felület i18n-kulcsainak lefedettsége ≥ 65% | Igen | +| `check-ui-value-drift` (inline) | Egy átírt angol **érték** nem hagy maga után elavult fordítást | Igen | +| `check-new-key-coverage` (inline) | Egy **új** angol kulcs minden területi beállításban le van fordítva — a `__MISSING__:` jelölő elutasításra kerül | Igen | +| `check-translation-ratio` | A tényleges fordítások területi beállításonkénti aránya (az angollal megegyező / helyőrző / hiányzó levelek az engedélyezési listán kívül) nem haladhatja meg a `config/quality/i18n-translation-baseline.json` értékét + a tűrést | **Tájékoztató jellegű** | -`fetch-depth: 0` szükséges — az értékeltérés-kapu az `en.json` fájlt a beolvasztási bázissal hasonlítja össze. +`fetch-depth: 0` szükséges — az értékváltozási kapu az `en.json` fájlt a beolvasztási bázissal hasonlítja össze. -#### `check-ui-value-drift` — elavult fordítások kapuja +#### `check-ui-value-drift` — elavult fordításokat kiszűrő kapu -Azt az egyetlen i18n-regressziót észleli, amelyet a többi kapu szerkezetéből adódóan nem képes felismerni: egy angol értéket -átírnak, miközben a _korábbi_ angol szövegből származó fordítások változatlanul maradnak, így -a nem angol nyelvű felhasználók továbbra is magabiztosan megfogalmazott, de immár helytelen szöveget olvasnak. +Azt az egy i18n-regressziót észleli, amelyet a többi kapu szerkezetileg nem képes felismerni: egy angol értéket +átírnak, de a _korábbi_ angol szövegből származó fordítások megmaradnak, így +a nem angol nyelvű felhasználók továbbra is magabiztosan megfogalmazott, de immár hibás szöveget olvasnak. -Ez valóban éles kiadásba került. Az `oauthModal.googleOAuthWarning` szövegét átírták, amikor bekerült az Antigravity -bejelentkezési segéd (#5203); **43 területi beállításból 39** megtartotta azt a szöveget, amely arra utasította az üzemeltetőket, hogy „másolják ki -a teljes URL-t, és illesszék be alább” — ennél a szolgáltatónál azonban ez a folyamat nem hajtható végre. A probléma +Ez valóban éles rendszerbe került. Az `oauthModal.googleOAuthWarning` át lett írva, amikor az Antigravity +bejelentkezési segéd bekerült (#5203); **43 területi beállításból 39** továbbra is azt közölte az üzemeltetőkkel, hogy „másolják ki a +teljes URL-t, és illesszék be alább” — ez a folyamat ennél a szolgáltatónál nem hajtható végre. A hiba #8463-ig észrevétlen maradt, mert: -- a `sync-ui-keys` csak a **hiányzó** kulcsokat tölti ki, az **elavultakat** soha; -- a `check-ui-keys-coverage` a kulcsok _jelenlétét_ számolja, így az elavult fordítás lefedettnek minősül; -- a `check-translation-drift` a `docs/i18n//**.md` dokumentációs tükröket követi nyomon — - a `src/i18n/messages/*.json` fájlokat soha nem olvassa. A 2026-09-es újraszinkronizálás óta blokkoló a `docs-sync-strict` feladatban: alapdokumentum szerkesztése → `npm run i18n:run -- --files=` (szakaszszintű, kis költségű). +- a `sync-ui-keys` csak a **hiányzó** kulcsokat pótolja, az **elavultakat** soha; +- a `check-ui-keys-coverage` a kulcsok _jelenlétét_ számolja, ezért az elavult fordítás is lefedettnek minősül; +- a `check-translation-drift` a `docs/i18n//**.md` dokumentációs tükröket követi — + a `src/i18n/messages/*.json` fájlokat soha nem olvassa. A 2026-09-es újraszinkronizálás óta blokkoló a `docs-sync-strict` feladatban: alapvető dokumentum szerkesztése → `npm run i18n:run -- --files=` (szakaszszintű, gyors). -**Diff-alapú, nem alapállapotra támaszkodó.** Az egyesítés alapjául szolgáló commit `en.json` fájlját hasonlítja össze a -munkafával; minden olyan kulcsnál, amelynek angol értéke megváltozott, elavultnak számít minden olyan területi beállítás, amely továbbra is -érintetlen fordítást tartalmaz. Ez szándékosan **befagyasztja a már meglévő adósságot** — egy diff -nem tudja megmutatni, hogy egy régóta létező fordítás melyik régi angol szövegből származik, ezért az ellenőrzés -csak azt vizsgálja, amit az aktuális módosítás érint. Az alternatíva (kulcsonkénti hash-alapállapot) -egy ~600 KB-os generált fájlt igényelne, amely háromszor akkora, mint a legnagyobb meglévő alapállapot, és minden i18n PR-nél módosulna. +**Diff-alapú, nem alapállapotra támaszkodik.** A merge-alapnál lévő `en.json` fájlt hasonlítja össze a +munkafával; minden olyan kulcs esetében, amelynek angol értéke megváltozott, elavultnak +minősül minden olyan területi beállítás, amely még érintetlen fordítást tartalmaz. Ez szándékosan +**befagyasztja a már meglévő adósságot** — egy diff nem képes megmutatni, hogy egy régóta meglévő +fordítás melyik korábbi angol szövegből származik, ezért az ellenőrzés csak azt vizsgálja, amit az +aktuális módosítás érint. Az alternatíva (egy kulcsonkénti hash-alapállapot) egy körülbelül +600 KB-os generált fájlba kerülne, amely háromszor akkora, mint a jelenlegi legnagyobb alapállapot, +és minden i18n PR-nél módosulna. Kétféleképpen teljesíthető: 1. frissítse az érintett fordításokat, vagy -2. állítsa őket `__MISSING__:` értékre — futásidőben ekkor a javított angol szöveg jelenik meg - (`src/i18n/request.ts::deepMergeFallback`, #7258), a kulcs pedig bekerül a fordítási sorba. +2. állítsa őket `__MISSING__:` értékre — ekkor futásidőben a javított angol + szöveg jelenik meg (`src/i18n/request.ts::deepMergeFallback`, #7258), a kulcs pedig bekerül a fordítási sorba. -Ha a karakterlánc **jelentése** változott, inkább **nevezze át a kulcsot**: egy új kulcs nem örökölhet -elavult fordítást. Ezt a mintát használta a #8463. +Ha a karakterlánc **jelentése** változott meg, inkább **nevezze át a kulcsot**: egy új kulcs nem +örökölhet elavult fordítást. A #8463 ezt a mintát alkalmazta. ```bash npm run i18n:check-value-drift # szigorú (ezt futtatja a CI) @@ -241,48 +240,48 @@ npm run i18n:check-value-drift:warn # csak jelentés BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -0-s kilépési kóddal és `SKIP reason=base-unresolved` üzenettel fejeződik be, ha az alapkatalógus nem olvasható (sekély -klónozás az alap-referencia nélkül), a `check-openapi-breaking` működését követve. +0-s kóddal és `SKIP reason=base-unresolved` üzenettel lép ki, ha az alapkatalógus nem olvasható +(sekély klón az alaphivatkozás nélkül), a `check-openapi-breaking` működését követve. ### Feladat: `i18n` Teljes i18n-ellenőrzési mátrix (területi beállításonként egy feladat). A teljes feladat tájékoztató jellegű. -| Szkript | Ellenőrzi | Blokkoló | -| ------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------- | -| `validate_translation.py quick` | A fordítás teljességét területi beállításonként | **Tájékoztató jellegű** (`continue-on-error: true` a teljes feladaton) | +| Szkript | Ellenőrzés | Blokkoló | +| ------------------------------- | ---------------------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | A fordítás teljessége területi beállításonként | **Tájékoztató** (`continue-on-error: true` a teljes feladaton) | ### Feladat: `pr-test-policy` Csak pull requestek esetén fut. -| Szkript | Ellenőrzi | Blokkoló | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -| `check:pr-test-policy` | A `src/`, `open-sse/`, `electron/` vagy `bin/` éles kódját módosító PR-eknek teszteket is tartalmazniuk vagy frissíteniük kell (8. szigorú szabály) | Igen | -| `check:test-masking` | A módosított tesztfájlok nem csökkentik az assertionök nettó számát, és nem adnak hozzá `assert.ok(true)` tautológiákat | Igen | -| `check:pr-evidence` | A PR leírása hivatkozik a módosításhoz tartozó teszt-/VPS-bizonyítékokra (a 18. szigorú szabály gépesítése a PR szövegének grep segítségével történő vizsgálatával — törékeny, lásd a Backlogot) | Igen | +| Szkript | Ellenőrzés | Blokkoló | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | A `src/`, `open-sse/`, `electron/` vagy `bin/` termelési kódját módosító PR-eknek teszteket is tartalmazniuk vagy frissíteniük kell (8. szigorú szabály) | Igen | +| `check:test-masking` | A módosított tesztfájlok nem csökkentik az assertionök nettó számát, és nem adnak hozzá `assert.ok(true)` tautológiákat | Igen | +| `check:pr-evidence` | A PR törzse tesztelési/VPS-bizonyítékot hivatkozik a módosításhoz (a 18. szigorú szabályt a PR szövegében végzett kereséssel automatizálja — törékeny, lásd: Backlog) | Igen | ### Feladat: `test-vitest` -A `build` után fut. Sikertelenség esetén blokkolja az egyesítést. +A `build` után fut. Hiba esetén blokkolja a merge-et. -| Tesztcsomag | Ellenőrzi | Blokkoló | -| ---------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-kiszolgáló (110 eszköz), autoCombo, gyorsítótár — vitest futtató | Igen | -| `test:vitest:ui` | UI-komponenstesztek — vitest futtató | **Blokkoló** — a már meglévő hibák kifejezetten ki vannak zárva a `vitest.config.ts` fájlban; az új hibák sikertelenné teszik a feladatot | +| Tesztcsomag | Ellenőrzés | Blokkoló | +| ---------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP-kiszolgáló (110 eszköz), autoCombo, gyorsítótár — vitest futtató | Igen | +| `test:vitest:ui` | UI-komponenstesztek — vitest futtató | **Blokkoló** — a már meglévő hibák kifejezetten ki vannak zárva a `vitest.config.ts` fájlban; az új hibák meghiúsítják a feladatot | ### Éjszakai munkafolyamatok (ütemezett, tájékoztató jellegű) -Ezek cron-ütemezés szerint (és `workflow_dispatch` esetén) futnak, PR-eken soha. Mindegyik tájékoztató jellegű. +Ezek cron-ütemezés szerint (és `workflow_dispatch` útján) futnak, PR-ek esetén soha. Mindegyik tájékoztató jellegű. -| Munkafolyamat | Ellenőrzi | Blokkoló | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | -| `nightly-property` | fast-check tulajdonságtesztek véletlenszerű kezdőértékkel és magas futtatásszámmal | **Tájékoztató jellegű** | -| `nightly-resilience` | heapnövekedési ellenőrzés, kaotikus hibainjektálás, k6 terhelési/tartóssági teszt | **Tájékoztató jellegű** | -| `nightly-llm-security` | promptfoo injekcióvédelem (blokkolási mód) + garak próbák (szolgáltatói titok nélkül kihagyva) | **Tájékoztató jellegű** | -| `nightly-schemathesis` | OpenAPI-szerződés fuzz tesztelése (schemathesis) egy élő OmniRoute példánnyal a `docs/openapi.yaml` használatával — felszínre hozza a specifikáció megsértéseit / a nem kezelt 500-as hibákat (8. fázis B.4) | **Tájékoztató jellegű** | -| `nightly-mutation` | Stryker mutációtesztelési pontszám a gyors egységteszt-sávon — a túlélő mutánsok gyenge assertionöket jeleznek | **Tájékoztató jellegű** | -| `nightly-compat` | Node-motor kompatibilitási mátrixa a támogatott `engines.node` tartományokban | **Tájékoztató jellegű** | +| Munkafolyamat | Ellenőrzés | Blokkoló | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `nightly-property` | fast-check tulajdonságtesztek véletlenszerű kezdőértékkel és magas futtatásszámmal | **Tájékoztató** | +| `nightly-resilience` | heap-növekedési kapu, káoszalapú hibainjektálás, k6 terhelési/tartós terhelési teszt | **Tájékoztató** | +| `nightly-llm-security` | promptfoo injekció elleni védelem (blokkoló mód) + garak próbák (szolgáltatói titok nélkül kihagyva) | **Tájékoztató** | +| `nightly-schemathesis` | OpenAPI-szerződés fuzzing (schemathesis) egy élő OmniRoute példányon a `docs/openapi.yaml` használatával — felszínre hozza a specifikáció megsértéseit / a nem kezelt 500-as hibákat (8. fázis, B.4) | **Tájékoztató** | +| `nightly-mutation` | Stryker mutációtesztelési pontszám a gyors egységteszt-sávon — a túlélő mutánsok gyenge assertionöket jeleznek | **Tájékoztató** | +| `nightly-compat` | Node-motor kompatibilitási mátrixa a támogatott `engines.node` tartományokban | **Tájékoztató** | --- @@ -557,41 +556,41 @@ kapcsolódási hibát naplóz, és soha nem szakítja meg a munkameneteket. ## Racionalizálási hátralék (ROI-felülvizsgálat — 9. fázis, 3. hullám) -Ezt a leltárt 2026-06-17-én egyeztettük a `ci.yml` fájllal (az előző verzióból kimaradt az +Ezt a leltárt 2026-06-17-én összevetettük a `ci.yml` tartalmával (az előző verzióból kimaradt az `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Az egyeztetett készlet ROI-felülvizsgálata -az alábbi racionalizálási jelölteket azonosította. **Az összevonások mechanikus CI-módosítások; -az átállítások/eltávolítások az üzemeltető számára fenntartott szabályzati döntések.** Az alábbiak -közül még semmi sincs alkalmazva. +a következő racionalizálási jelölteket azonosította. **Az összevonások mechanikus CI-módosítások; +az átállítások/eltávolítások az üzemeltető számára fenntartott szabályzati döntések.** Az alábbiak közül +még semmi sem lett alkalmazva. -**A fentieken túl szintén nem dokumentált** (tanácsadó jellegű, alacsony jelértékű): a `docs-lint` feladat -(markdownlint + Vale, a teljes feladatnál `continue-on-error`), valamint az önálló ellenőrzési munkafolyamatok: +**Fent szintén nem dokumentált** (tanácsadó jellegű, alacsony jelértékű): a `docs-lint` feladat +(markdownlint + Vale, a teljes feladaton `continue-on-error`), valamint az önálló ellenőrző munkafolyamatok: `semgrep.yml` / `codeql.yml` / `scorecard.yml`. A `semgrepFindings: 0` szerepel a -`quality-baseline.json` fájlban, de nincs blokkoló racsnis ellenőrzéshez kapcsolva a `ci.yml` fájlban — a mérőszám +`quality-baseline.json` fájlban, de nincs blokkoló racsnihoz kötve a `ci.yml` fájlban — a metrika jelenleg árva. -### Összevonás / deduplikálás (mechanikus, alacsonyabb kockázat) +### Összevonás / deduplikáció (mechanikus, alacsonyabb kockázat) -Minden jelöltet ellenőriztünk az aktív kapuállapot alapján 2026-06-17-én (bízz, de ellenőrizd); -több „kézenfekvő” összevonásról is kiderült, hogy rejtett adósságot takar, ezért **nem** alkalmazható közvetlenül. +Minden jelöltet ellenőriztünk az éles kapuállapot alapján 2026-06-17-én (bízz, de ellenőrizd); +több „kézenfekvő” összevonásról kiderült, hogy rejtett adósságot takar, ezért **nem** alkalmazhatók közvetlenül. -- **A `check:docs-sync` kétszer fut** — önállóan a `lint` feladatban, majd ismét a `check:docs-all` részeként (`docs-sync-strict`), továbbá a husky pre-commit hookban. ✅ **KÉSZ** — az önálló `lint`-meghívás eltávolítva. -- **CVE-ellenőrzés** — ❌ **NEM vonható össze közvetlenül.** Az `audit:deps` bármely magas/kritikus CVE esetén azonnal hibát jelez; a `check:vuln-ratchet` (osv) csak az alapértékhez képesti _visszaesés_ esetén jelez hibát (jelenleg 1 MODERATE). Eltérő szemantika — az `audit:deps` eltávolításával elveszne az abszolút magas/kritikus kapu. Mindkettő megtartandó. -- **Ciklusészlelés** — ❌ **NEM vonható össze közvetlenül.** A `check:circular-deps` (dpdm) **91 ciklust** jelez (ezért tanácsadó jellegű); ezek előzetes megszüntetése nélkül nem tehető blokkolóvá, és szélesebb hatókörű, mint a hibamentes, gondosan összeállított `check:cycles`. A `check:cycles` maradjon blokkoló; a 91 dpdm-ciklus megszüntetése külön hátraléktétel. -- **Komplexitás** — ✅ **KÉSZ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): egyetlen ESLint-bejárás, `ruleId` szerinti számlálással, így a ciklomatikus+max-lines és a kognitív alapértékek függetlenek maradnak; az egyedi `check:complexity` / `check:cognitive-complexity` megmarad a helyi `--update` futtatásokhoz. -- **`/api` hallucináció elleni védelem** — ✅ **KÉSZ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): a `src/app/api` fájlrendszerének egyszeri leltározása, miközben az openapi-routes + docs-symbols továbbra is egymástól függetlenül jelent; az egyedi ellenőrzések megmaradnak a helyi futtatásokhoz. -- **A `check:node-runtime` 11 feladatban fut** — ⚠️ **alacsony ROI.** Mindegyik külön futtatókörnyezet, az ellenőrzés pedig <1 mp; a teljes megtakarítás ~10 mp lenne, miközben elveszne egy olcsó, feladatonkénti védőellenőrzés. Nem éri meg a felfordulást. +- **A `check:docs-sync` kétszer fut** — önállóan a `lint` feladatban, majd ismét a `check:docs-all` (`docs-sync-strict`) részeként és a husky pre-commit hookban. ✅ **KÉSZ** — az önálló `lint`-meghívás eltávolítva. +- **CVE-ellenőrzés** — ❌ **NEM vonható össze tisztán.** Az `audit:deps` minden magas/kritikus CVE esetén hibával leáll; a `check:vuln-ratchet` (osv) csak az alapértékhez viszonyított _regresszió_ esetén áll le hibával (jelenleg 1 MODERATE). Eltérő szemantika — az `audit:deps` eltávolításával elveszne az abszolút magas/kritikus kapu. Mindkettőt meg kell tartani. +- **Ciklusészlelés** — ✅ **KÉSZ** (#15159 G-01/G-02). A korábbi szöveg a `check:cycles` ellenőrzést „zöld, gondosan összeállított” kapunak nevezte, és azzal indokolta blokkolóként való megtartását, hogy a `check:circular-deps` (dpdm) 91 ciklust jelzett. Ez a zöld állapot **hamis zöld** volt: a `check:cycles` 5 alkönyvtárat (450 fájlt) vizsgált, csak a statikus `import|export … from` mintára illeszkedett, és minden `@/` és `@omniroute/open-sse/` specifikátort eldobott, így nem láthatta a repót uraló dinamikus importálási és aliasciklusokat. Javítva: a kapu most bejárja a `src` + `open-sse` könyvtárakat (5023 fájl), a TypeScript AST-ből gyűjti a specifikátorokat (így az `import("…")` számít, a típuspozícióban lévő `typeof import("…")` viszont nem), és feloldja a tsconfig `paths` beállításait. **14** ciklust talál, nem 0-t. Mivel 14 már meglévő ciklus nem javítható ki egy kapu-PR-ben, a `check:cycles` mostantól **racsni** (`--ratchet`, a felső korlát `metrics.cycles.value = 14` a `quality-baseline.json` fájlban, `direction: down`) — minden _regressziót_ blokkol, és az érték csak csökkenhet. A CI az `npm run check:cycles:ratchet` parancsot futtatja. A fokozatos leépítés az **A-01** részeként történik. A `check:circular-deps` (dpdm) tanácsadó jelleggel megmarad szélesebb körű másodvéleményként. +- **Komplexitás** — ✅ **KÉSZ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): egyetlen ESLint-bejárás, ruleId szerinti számlálással, így a ciklomatikus+max-lines és a kognitív alapértékek függetlenek maradnak; az egyedi `check:complexity` / `check:cognitive-complexity` ellenőrzések megmaradnak a helyi `--update` használatához. +- **`/api` hallucináció elleni védelem** — ✅ **KÉSZ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): a `src/app/api` egyetlen fájlrendszer-leltározása; az openapi-routes + docs-symbols továbbra is egymástól függetlenül jelent; az egyedi ellenőrzések megmaradnak helyi futtatáshoz. +- **A `check:node-runtime` 11 feladatban fut** — ⚠️ **alacsony ROI.** Mindegyik külön futtatókörnyezet, az ellenőrzés pedig <1 másodperc; a teljes megtakarítás ~10 másodperc lenne, miközben elveszne egy olcsó, feladatonkénti védőkorlát. Nem éri meg a vele járó változtatás. - **`typecheck:noimplicit:core` a CI lintelésében** — ✅ **eltávolítva a lint feladatból** (tanácsadó jellegű `continue-on-error` volt); a blokkoló típusfelületet a `typecheck:core` + `check:type-coverage` biztosítja. A helyi szkript megmaradt. ### Átállítás / döntés (üzemeltetői szabályzat) -- `check:openapi-security-tiers` (tanácsadó jellegű) — ❌ **NEM állítható át közvetlenül.** 0-s kilépési kóddal fejeződik be, de figyelmeztet, hogy a `LOCAL_ONLY_API_PREFIXES` alá tartozó több `traffic-inspector` útvonalról hiányzik az `x-loopback-only: true` annotáció. A kikényszerítéshez előbb hozzá kell adni ezeket az annotációkat az `openapi.yaml` fájlhoz. -- `typecheck:noimplicit:core` (tanácsadó jellegű) — nagyrészt lefedi a blokkoló `check:type-coverage` racsnis ellenőrzés. Állítsa át racsnis ellenőrzésre, vagy távolítsa el a redundáns második `tsc`-menetet. -- `test:vitest:ui` (most már **blokkoló**) — a már meglévő hibák explicit módon ki vannak zárva a `vitest.config.ts` fájlban, `// #8618` nyomonkövetési megjegyzésekkel; az új hibák meghiúsítják a feladatot. -- `check:secrets` (gitleaks, blokkoló racsnis ellenőrzés 3 dokumentált téves pozitívnál rögzítve) — vegye fel a 3 esetet az engedélyezési listára a 0 eléréséhez, vagy minősítse vissza tanácsadó jellegűvé. Átfedésben van a GitHub natív titokellenőrzésével és a `check:public-creds` ellenőrzéssel. -- `check:pr-evidence` (blokkoló, grep-pel vizsgálja a PR-törzs prózáját) — magas a téves pozitív eredmények kockázata; eltávolítása gyengíti a 18. szigorú szabály kikényszerítését, ezért ez valódi szabályzati döntés. -- `semgrep` (tanácsadó jellegű, önálló) — az OWASP-családok tekintetében átfedésben van a CodeQL-lel; kösse az alapértékét racsnis ellenőrzéshez, vagy távolítsa el. +- `check:openapi-security-tiers` (tanácsadó jellegű) — ❌ **NEM állítható át tisztán.** 0-s kilépési kódot ad, de figyelmeztet arra, hogy a `LOCAL_ONLY_API_PREFIXES` alá tartozó több `traffic-inspector` útvonalról hiányzik az `x-loopback-only: true` annotáció. A kikényszerítéséhez először hozzá kell adni ezeket az annotációkat az `openapi.yaml` fájlhoz. +- `typecheck:noimplicit:core` (tanácsadó jellegű) — nagyrészt lefedi a blokkoló `check:type-coverage` racsni. Állítsa át racsnivá, vagy távolítsa el a redundáns második `tsc` futtatást. +- `test:vitest:ui` (most **blokkoló**) — a már meglévő hibák kifejezetten ki vannak zárva a `vitest.config.ts` fájlban `// #8618` nyomonkövetési megjegyzésekkel; az új hibák meghiúsítják a feladatot. +- `check:secrets` (gitleaks, blokkoló racsni, 3 dokumentált téves pozitívnál befagyasztva) — tegye engedélyezési listára a 3 találatot a 0 eléréséhez, vagy minősítse vissza tanácsadó jellegűvé. Átfedésben van a GitHub natív titokellenőrzésével és a `check:public-creds` ellenőrzéssel. +- `check:pr-evidence` (blokkoló, grep segítségével vizsgálja a PR-törzs prózáját) — magas a téves pozitív eredmények kockázata; eltávolítása gyengítené a 18. szigorú szabály kikényszerítését, így ez valódi szabályzati döntés. +- `semgrep` (tanácsadó jellegű, önálló) — az OWASP-családok tekintetében átfedésben van a CodeQL-lel; kösse az alapértékét racsnihoz, vagy távolítsa el. --- diff --git a/docs/i18n/hy/CONTRIBUTING.md b/docs/i18n/hy/CONTRIBUTING.md index fe1b19028c4..92edaa34314 100644 --- a/docs/i18n/hy/CONTRIBUTING.md +++ b/docs/i18n/hy/CONTRIBUTING.md @@ -397,22 +397,22 @@ docs/ --- -## Pull Request-ի ստուգացանկ +## Pull Request-ի ստուգաթերթ -- [ ] Թեստերը հաջողությամբ անցնում են (`npm test`) -- [ ] Լինթինգն հաջողությամբ անցնում է (`npm run lint`) +- [ ] Թեստերն անցնում են (`npm test`) +- [ ] Լինտինգն անցնում է (`npm run lint`) - [ ] Կառուցումը հաջողվում է (`npm run build`) - [ ] Նոր հանրային ֆունկցիաների և ինտերֆեյսների համար ավելացվել են TypeScript տիպեր - [ ] Չկան կոդում ուղղակիորեն գրված գաղտնիքներ կամ պահուստային արժեքներ -- [ ] Վերին հոսքի հանրային հավատարմագրերը ներդրված են `resolvePublicCred()`-ի միջոցով (տե՛ս [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), և երբեք՝ որպես լիտերալներ -- [ ] Սխալի պատասխաններն անցնում են `buildErrorBody()` / `sanitizeErrorMessage()` ֆունկցիաներով՝ պատասխանների մարմիններում առանց չմշակված սթեքի հետագծերի (տե՛ս [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell հրամանները (`exec` / `spawn`) կատարման ժամանակի արժեքները փոխանցում են `env`-ի միջոցով, այլ ոչ թե տողային ինտերպոլացիայով -- [ ] Բոլոր մուտքային տվյալները վավերացվում են Zod սխեմաներով -- [ ] Օգտատիրոջը տեսանելի փոփոխությունների համար փոփոխությունների մատյանի **ֆրագմենտ** է ավելացվել `changelog.d/{features|fixes|maintenance}/-.md`-ում (տե՛ս [`changelog.d/README.md`](./changelog.d/README.md)) — **մի՛** խմբագրեք `CHANGELOG.md`-ն ուղղակիորեն․ ֆրագմենտները միավորվում են թողարկման ժամանակ և երբեք հակասություններ չեն առաջացնում PR-ների միջև +- [ ] Հանրային վերին հոսքի հավատարմագրերը ներդրված են `resolvePublicCred()`-ի միջոցով (տե՛ս [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), երբեք՝ որպես լիտերալներ +- [ ] Սխալների պատասխաններն անցնում են `buildErrorBody()` / `sanitizeErrorMessage()`-ի միջոցով. պատասխանների մարմիններում չկան չմշակված stack trace-եր (տե՛ս [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell հրամանները (`exec` / `spawn`) կատարման ժամանակի արժեքները փոխանցում են `env`-ի միջոցով, ոչ թե տողային ինտերպոլյացիայով +- [ ] Բոլոր մուտքային տվյալները վավերացված են Zod սխեմաներով +- [ ] Օգտատերերին տեսանելի փոփոխությունների համար `changelog.d/{features|fixes|maintenance}/-.md`-ում ավելացվել է փոփոխությունների մատյանի **հատված** (տե՛ս [`changelog.d/README.md`](./changelog.d/README.md)). մի՛ խմբագրեք `CHANGELOG.md`-ն անմիջապես. թողարկման ժամանակ հատվածները համախմբվում են և երբեք չեն հակասում տարբեր PR-ների միջև - [ ] Փաստաթղթերը թարմացվել են (եթե կիրառելի է) -- [ ] Չեն բացվել CodeQL / Secret-Scanning-ի նոր ահազանգեր, կամ յուրաքանչյուրն անտեսվել է տեխնիկական հիմնավորմամբ՝ համապատասխան `docs/security/` փաստաթղթին հղումով -- [ ] Դուստր գործընթացներ գործարկող երթուղիները (`/api/mcp/`, `/api/cli-tools/runtime/`) դասակարգված են որպես `isLocalOnlyPath()`՝ `src/server/authz/routeGuard.ts`-ում — տե՛ս [Խիստ կանոն #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Commit-ի հաղորդագրություններում չկան `Co-Authored-By` վերջնագրեր․ commit-ները պետք է ներկայացվեն բացառապես պահոցի սեփականատիրոջ Git ինքնության ներքո (Խիստ կանոն #16) +- [ ] CodeQL-ի / Secret-Scanning-ի նոր զգուշացումներ չեն բացվել, կամ յուրաքանչյուրն անտեսվել է՝ համապատասխան `docs/security/` փաստաթղթին հղում կատարող տեխնիկական հիմնավորմամբ +- [ ] Դուստր պրոցեսներ գործարկող երթուղիները (`/api/mcp/`, `/api/cli-tools/runtime/`) դասակարգված են որպես `isLocalOnlyPath()`՝ `src/server/authz/routeGuard.ts`-ում. տե՛ս [Խիստ կանոն #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Commit-ի հաղորդագրություններում չկան AI-ի/բոտի `Co-authored-by` վերջնատողեր (Խիստ կանոն #16). մարդկային համահեղինակները, որոնց աշխատանքը վերաօգտագործվել է, նշվում են ստանդարտ `Co-authored-by: Name ` վերջնատողերով --- diff --git a/docs/i18n/hy/docs/architecture/QUALITY_GATES.md b/docs/i18n/hy/docs/architecture/QUALITY_GATES.md index b47fd3eaf54..fe63a8b1245 100644 --- a/docs/i18n/hy/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/hy/docs/architecture/QUALITY_GATES.md @@ -15,214 +15,214 @@ --- -## Գեյթերի ցանկը և կատարման պրոֆիլները +## Դարպասների գույքացանկը և կատարման պրոֆիլները ### Թեկնածուի ընդունում CI և Quality Gates աշխատանքային հոսքերից յուրաքանչյուրն արձակում է կայուն վճիռ՝ `Gate / CI` և -`Gate / Quality`։ Դրանց տարբերակավորված ընդունման քաղաքականությունը թվարկում է վերին հոսքի յուրաքանչյուր աշխատանք՝ -որպես պարտադիր կամ խորհրդատվական։ Կիրառելի պարտադիր աշխատանքը պետք է հաջողվի․ բացակայող, +`Gate / Quality`։ Դրանց տարբերակավորված ընդունման քաղաքականությունը թվարկում է վերին հոսքի յուրաքանչյուր առաջադրանք՝ +որպես պարտադիր կամ խորհրդատվական։ Կիրառելի պարտադիր առաջադրանքը պետք է հաջողվի․ բացակայող, չեղարկված, բաց թողնված, սպասման մեջ գտնվող և անհայտ արդյունքները չեն կարող հաստատել PASS կարգավիճակը։ Վավեր -միայն փաստաթղթային կամ միայն կատալոգային դասակարգումը կարող է կոդի ուղին դարձնել անկիրառելի, -իսկ սևագիր PR-ը չի համարվում ընդունված թեկնածու։ `hotfix` պիտակը չի վերացնում ապացույցի պահանջը։ +միայն փաստաթղթերին կամ միայն կատալոգին վերաբերող դասակարգումը կարող է կոդի ուղին դարձնել ոչ կիրառելի․ +սևագիր PR-ը չի համարվում ընդունված թեկնածու։ `hotfix` պիտակը չի վերացնում ապացույցների պահանջը։ -Երկու աշխատանքային հոսքերն էլ ընդգրկում են PR-ները և main/release ճյուղեր կատարվող push-երը, ձեռքով գործարկումն ու +Երկու աշխատանքային հոսքերն էլ ընդգրկում են PR-ները և main/release ճյուղեր կատարվող push-երը, ձեռքով գործարկումը և merge-group իրադարձությունները։ Push-ը, dispatch-ը և merge-group-ը գործարկում են ամբողջական ընտրանին։ Fork-երը -և merge group-երը hosted runner-ներ են օգտագործում այն աշխատանքների համար, որոնք այլապես ընտրում են self-hosted -runner-ներ․ գործարկումից առաջ պետք է հաստատվի hosted միջավայրի բավարար հզորությունը։ +և merge group-երն օգտագործում են սպասարկվող runner-ներ այն առաջադրանքների համար, որոնք այլապես ընտրում են ինքնուրույն սպասարկվող +runner-ներ․ նախքան ներդրումը պետք է ստուգվի սպասարկվող runner-ների բավարար հզորությունը։ -Յուրաքանչյուր JSON ստացական նույնականացնում է checkout արված SHA-ն, աշխատանքային հոսքի գործարկումն ու փորձը։ -CLI-ն մերժում է checkout/event SHA-ների անհամապատասխանությունը։ Աշխատանքային հոսքի թեստերը քաղաքականության անդամակցությունը -կապում են վճիռ արձակող աշխատանքի `needs` ցանկին, որպեսզի նոր կամ հեռացված ուղին չկարողանա աննկատ անհետանալ։ -Ստացականներն ընդգրկում են իրենց իսկ աշխատանքային հոսքը, այլ ոչ թե հրապարակումը, տեղակայումը կամ -գոյություն ունեցող խորհրդատվական սկանավորիչի ներքին գործառույթները։ Ճյուղերի կանոններում երկու ստուգման անուններն էլ ակտիվացնելը -առանձին վարչական փոփոխություն է․ այս աշխատանքների ավելացումն ինքնին չի պաշտպանում ճյուղը։ +Յուրաքանչյուր JSON անդորրագիր նույնականացնում է checkout արված SHA-ն, աշխատանքային հոսքի գործարկումը և փորձը։ +CLI-ն մերժում է checkout/event SHA-ների անհամապատասխանությունը։ Աշխատանքային հոսքի թեստերը քաղաքականության անդամակցությունը կապում են +վճռի առաջադրանքի `needs` ցանկին, որպեսզի նոր կամ հեռացված ուղին չկարողանա աննկատ անհետանալ։ +Անդորրագրերն ընդգրկում են իրենց սեփական աշխատանքային հոսքը, այլ ոչ հրապարակումը, տեղակայումը կամ +գոյություն ունեցող խորհրդատվական սկաների ներքին աշխատանքը։ Ճյուղի կանոններում ստուգումների երկու անունների ակտիվացումը +առանձին վարչական փոփոխություն է․ այս առաջադրանքների ավելացումն ինքնին չի պաշտպանում ճյուղը։ -### Ստատիկ սկանավորման ցանկը +### Ստատիկ սկանավորման գույքացանկ -Տարբերակավորված npm alias-ների ցանկը և ստատիկ սկանավորման անդամակցությունը գտնվում են +Տարբերակավորված npm-alias գույքացանկը և ստատիկ սկանավորման անդամակցությունը գտնվում են `config/quality/gate-manifest.json`-ում։ Գործարկեք `npm run check:gate-manifest`՝ -սկրիպտների անուններն ու ճշգրիտ հրամանները `package.json`-ի համեմատ վավերացնելու համար․ ավելացումները, հեռացումները և -հրամանների շեղումները ձախողում են ինչպես տեղային hook-ը, այնպես էլ CI-ի փոփոխությունների դասակարգման աշխատանքները։ -Alias-ը աշխատանքային հոսքի աշխատանք, matrix-ի օրինակ կամ թեստային դեպք չէ․ այս քանակները -չպետք է ներկայացվեն որպես փոխարինելի։ - -Ընտրված alias-ներն առանց դրանք կատարելու դիտարկելու համար օգտագործեք `npm run quality:scan -- --list` կամ `npm run quality:scan:fast -- --list`։ -Runner-ը կանչում է -npm entrypoint-ը, ուստի դրա կատարման միջավայրը՝ ներառյալ Bun-ը, որտեղ այն կազմաձևված է, պահպանվում է։ +սկրիպտների անունները և ճշգրիտ հրամանները `package.json`-ի համեմատ վավերացնելու համար․ ավելացումները, հեռացումները և +հրամանների շեղումները ձախողում են և՛ տեղային hook-ը, և՛ CI-ում փոփոխությունների դասակարգման առաջադրանքները։ +Alias-ը աշխատանքային հոսքի առաջադրանք, matrix-ի օրինակ կամ թեստային դեպք չէ․ այս քանակները չպետք է +ներկայացվեն որպես փոխարինելի։ + +Օգտագործեք `npm run quality:scan -- --list` կամ `npm run quality:scan:fast -- --list` +ընտրված alias-ները առանց դրանք գործարկելու ստուգելու համար։ Runner-ը կանչում է +npm մուտքի կետը, ուստի դրա կատարման միջավայրը (ներառյալ Bun-ը, որտեղ այն կազմաձևված է) պահպանվում է։ Manifest-ը գրանցում է այդ պրոֆիլներից դուրս գտնվող alias-ները որպես առանձին կանչվող, իսկ -սպասարկման հրամաններն արգելված են միայն կարդալու համար նախատեսված սկանավորման պրոֆիլներում։ +սպասարկման հրամաններն արգելված են միայն ընթերցման համար նախատեսված սկանավորման պրոֆիլներում։ -Այս պրոֆիլներն ընդգրկում են միայն ստատիկ սկանավորումը։ Դրանք չեն հավաստագրում արտադրանքի թեստերը, +Այս պրոֆիլներն ընդգրկում են միայն ստատիկ սկանավորումը։ Դրանք չեն հավաստում արտադրանքի թեստերը, ծածկույթը, փաթեթավորումը, արտաքին ստուգումները կամ թեկնածուի թողարկման ամբողջական ընդունումը։ Աշխատանքային հոսքի ընդունումն օգտագործում է կապակցված `config/quality/admission-policy.json`-ը և `scripts/quality/admission-verdict.mjs`-ը։ Release-observer պրոֆիլները մնում են առանձին․ -դրանց կիրառելի ստուգումներն ու ստացականները դիտարկեք անկախ կերպով։ Ստորև բերված տեքստային -ցանկը տեղեկատու է, այլ ոչ թե ապացույց, որ գեյթն իրականում գործարկվել է։ +դրանց կիրառելի ստուգումներն ու անդորրագրերը ստուգեք անկախորեն։ Ստորև բերված տեքստային +գույքացանկը տեղեկանք է, այլ ոչ ապացույց, որ դարպասն իրականում գործարկվել է։ -Սկրիպտները գտնվում են `scripts/check/`-ում (քաղաքականության գեյթեր) և `scripts/quality/`-ում (ratchet շարժիչ)։ +Սկրիպտները գտնվում են `scripts/check/`-ի (քաղաքականության դարպասներ) և `scripts/quality/`-ի (ratchet շարժիչ) ներքո։ CI-ի ճշմարտության աղբյուրը `.github/workflows/ci.yml`-ն է։ -### Release PR-ի արագ ուղի (`quality.yml`) +### Թողարկման PR-ի արագ ուղի (`quality.yml`) -`.github/workflows/quality.yml`-ը լրացնում է CI-ն main/release PR-ների, պաշտպանված ճյուղեր կատարվող -push-երի, dispatch-ի և merge group-երի համար։ PR-ներն օգտագործում են ըստ ուղիների զտված արագ ստուգումներ։ Մշտապես +`.github/workflows/quality.yml`-ը լրացնում է CI-ն main/release PR-ների, պաշտպանված ճյուղերի +push-երի, dispatch-ի և merge group-երի համար։ PR-ներն օգտագործում են ուղիներով զտված արագ ստուգումներ։ Մշտապես անջատված կրկնօրինակ build-ը հեռացվել է․ իրական build/package/boot ստուգումները մնում են CI-ում։ -| Աշխատանք | Շրջանակ | Արգելափակող | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `Docs Gates (fast-path)` | Փաստաթղթային/կոդային PR-ներ․ API փաստաթղթերի հղումներ և docs-all | Այո | -| `Fast Quality Gates` | Կոդային PR-ներ․ ստատիկ ստուգումներ, typecheck, dashboard-ի typecheck, ազդեցության ենթարկված միավորային թեստեր | Այո | -| `Forgotten sibling tests` | Կոդային PR-ներ․ փոփոխված մոդուլներից հետագծում դեպի ստատիկ սպառողներ և թեկնածու հարակից թեստեր․ barrel և dynamic-import ուղիները հաղորդվում են որպես խորհրդատվական ախտորոշումներ՝ հղված allowlist բացառություններով | **Խորհրդատվական** | -| `Vitest (fast-path)` | Կոդային PR-ներ․ արագ vitest հավաքակազմ | Այո | -| `Unit Tests fast-path` | Կոդային PR-ներ․ 4-shard միավորային հավաքակազմ | Այո | -| `No new ESLint warnings` | Կոդային PR-ներ․ suppressions-ին իրազեկ lint պաշտպանիչ | Այո, ներառյալ fork-երը | -| `Merge integrity (changelog + generated skills)` | Ոչ սևագիր PR-ներ․ changelog-ի և գեներացված skill-երի համաժամացում | Այո, ներառյալ fork-երը | +| Առաջադրանք | Շրջանակ | Արգելափակող | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `Docs Gates (fast-path)` | Փաստաթղթերի/կոդի PR-ներ․ API փաստաթղթերի հղումներ և docs-all | Այո | +| `Fast Quality Gates` | Կոդի PR-ներ․ ստատիկ ստուգումներ, typecheck, dashboard-ի typecheck, ազդեցություն կրած միավորային թեստեր | Այո | +| `Forgotten sibling tests` | Կոդի PR-ներ․ փոփոխված մոդուլներից հետևում դեպի ստատիկ սպառողներ և հավանական sibling թեստեր․ barrel և dynamic-import ուղիները հաղորդվում են որպես խորհրդատվական ախտորոշումներ՝ նշված allowlist բացառություններով | **Խորհրդատվական** | +| `Vitest (fast-path)` | Կոդի PR-ներ․ արագ vitest հավաքակազմ | Այո | +| `Unit Tests fast-path` | Կոդի PR-ներ․ 4-shard միավորային հավաքակազմ | Այո | +| `No new ESLint warnings` | Կոդի PR-ներ․ suppression-ները հաշվի առնող lint պահակ | Այո, ներառյալ fork-երը | +| `Merge integrity (changelog + generated skills)` | Ոչ սևագիր PR-ներ․ changelog-ի և գեներացված skill-երի համաժամացում | Այո, ներառյալ fork-երը | -#### Մոռացված հարակից թեստերի հաշվետվություն +#### Մոռացված sibling թեստերի հաշվետվություն -`npm run check:forgotten-sibling-tests`-ը կրկին օգտագործում է թեստերի ազդեցության քարտեզի հիմքում ընկած import resolver-ը։ +`npm run check:forgotten-sibling-tests`-ը կրկին օգտագործում է թեստերի ազդեցության քարտեզի հիմքում գտնվող import resolver-ը։ Յուրաքանչյուր փոփոխված production մոդուլի համար այն հաղորդում է որոշակի -`փոփոխված մոդուլ/խորհրդանիշ -> ստատիկ սպառող -> թեկնածու հարակից թեստ` շղթաներ, երբ թեկնածու +`changed module/symbol -> static consumer -> candidate sibling test` շղթաներ, երբ թեկնածու թեստը բացակայում է pull-request-ի diff-ից։ Markdown ամփոփագիրը և JSON արդյունքը պահպանվում են որպես -`forgotten-sibling-tests` աշխատանքային հոսքի artifact՝ նախքան որևէ արգելափակող ներդրում calibration կատարելու համար։ +`forgotten-sibling-tests` աշխատանքային հոսքի artifact՝ նախքան որևէ արգելափակող ներդրում չափաբերման համար։ -Barrel վերաարտահանումները և դինամիկ ներմուծումները միայն լուծման ախտորոշումներ են․ դրանք երբեք արգելափակող խնդիր չեն ստեղծում։ Վերանայված բացառությունները գտնվում են +Barrel վերաարտահանումները և դինամիկ ներմուծումները միայն լուծման ախտորոշման համար են․ դրանք երբեք արգելափակող խախտում չեն ստեղծում։ +Վերանայված բացառությունները գտնվում են `config/quality/forgotten-sibling-allowlist.json`-ում։ Յուրաքանչյուր գրառում պետք է նշի սպառող և թեկնածու -թեստերը, ներկայացնի հստակ հիմնավորում և հղում պարունակի դեպի GitHub-ի խնդիր կամ pull request։ Սխալ ձևաչափված գրառումները -մերժվում են լռելյայն։ Բացառությունները չեն կարող անտեսել ջնջված թեկնածու թեստը կամ `.skip`/`.todo` ավելացնող տարբերությունը․ -assertion-ների թուլացումը և քողարկման այլ ձևերը շարունակում են վերահսկվել առանձին արգելափակող -`check:test-masking` դարպասի կողմից։ +թեստերը, ներկայացնի կոնկրետ հիմնավորում և հղում պարունակի GitHub issue-ի կամ pull request-ի։ Սխալ ձևաչափված գրառումների դեպքում ստուգումը +փակ սկզբունքով ձախողվում է։ Բացառությունները չեն կարող անտեսել ջնջված թեկնածու թեստը կամ `.skip`/`.todo` ավելացնող diff-ը․ +assertion-ի թուլացումը և քողարկման այլ ձևերը շարունակում են վերահսկվել անկախորեն արգելափակող +`check:test-masking` դարպասով։ ### Առաջադրանք՝ `lint` -Գործարկվում է դեպի `main` ուղղված յուրաքանչյուր PR-ի դեպքում։ Ձախողման դեպքում արգելափակում է միաձուլումը։ - -| Սկրիպտ (`npm run ...`) | Ստուգում է | Արգելափակող | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `check:node-runtime` | Node.js-ի տարբերակը գտնվում է աջակցվող միջակայքում | Այո | -| `check:cycles` | Ցիկլային ներմուծումներ՝ բոլոր `src/` + `open-sse/` մոդուլներում | Այո | -| `check:route-validation:t06` | Zod սխեմաների առկայությունը բոլոր route-երում (6-րդ մակարդակի քաղաքականություն) | Այո | -| `check:any-budget:t11` | `@ts-expect-error // any`-ի քանակը չի գերազանցում սահմանաչափը (11-րդ մակարդակի catraca) | Այո | -| `check:provider-consistency` | `providers.ts`-ի յուրաքանչյուր մատակարար ունի համապատասխան գրառում `providerRegistry.ts`-ում (և հակառակը՝ թույլատրելի ցանկի սահմաններում) | Այո | -| `check:model-lifecycle` | Ձեռքով սպասարկվող երթուղավորման երեք աղյուսակները համահունչ են պահվում պահոցում գրանցված կենսացիկլի ակնթարթային պատկերի հետ (#11503). `FITNESS_TABLE`-ը (`taskFitness.ts`) չի գնահատում որևէ շահագործումից հանված id, որը `REGISTRY`-ն կարող է երթուղավորել, `BUILT_IN_ALIASES`-ի յուրաքանչյուր թիրախ առկա է `REGISTRY`-ում և բացակայում է շահագործումից հանված id-ների ակնթարթային պատկերից, `REGISTRY`-ում դեռևս առկա յուրաքանչյուր շահագործումից հանված id վերահղվում է կամ նշված է `allowedRetiredInCatalog`-ում, և `DEFAULT_DEGRADATION_MAP`-ի ոչ մի աղբյուր կամ թիրախ այդ ակնթարթային պատկերում նշված չէ որպես շահագործումից հանված։ Սա չի ապացուցում, որ մոդելը ներկայումս սպասարկվում է գործող վերին մակարդակի ծառայության կողմից։ Անցանց է՝ համեմատում է `config/quality/model-lifecycle.json`-ի հետ, որը ձեռքով թարմացվում է `npm run quality:refresh-model-lifecycle` հրամանով (պահանջում է ցանց, ներառված չէ CI-ում)։ `allowedRetiredInCatalog`-ը աստիճանական կրճատման արգելանիվ է. գրառում ավելացրեք միայն հետևման խնդրի առկայության դեպքում։ | Այո | -| `check:fetch-targets` | Հաճախորդի կողմի `src/`-ում յուրաքանչյուր `fetch("/api/...")` հանգուցալուծվում է իրական `route.ts`-ի | Այո | -| `check:deps` | Պահոցի յուրաքանչյուր `package.json`-ում առկա՝ `npm install`-ով տեղադրվող բոլոր կախվածությունները ներառված են `dependency-allowlist.json`-ում. նոր՝ չամրագրված տարբերակով կամ slopsquatting-ի ենթադրյալ փաթեթները նշագրվում են | Այո | -| `audit:deps` | `npm audit` (արմատային + electron) — բարձր/կրիտիկական մակարդակի ոչ մի զգուշացում (մասամբ համընկնում է osv-ի `check:vuln-ratchet`-ի հետ. տե՛ս Հիմնավորման կուտակված աշխատանքները) | Այո | -| `check:lockfile` | `package-lock.json`-ի ամբողջականություն՝ https ռեեստր, ամբողջականության հեշեր, հոսթի ոչ մի վերասահմանում | Այո | -| `check:licenses` | Արտադրական կախվածությունների SPDX լիցենզիաների թույլատրելի ցանկ | Այո | -| `check:tracked-artifacts` | Կառուցման արտեֆակտների / commit արված `node_modules` սիմվոլիկ հղումների բացակայություն (գործարկվում է նաև husky pre-commit-ում․ pre-push-ը միտումնավոր թեթև է — #6716) | Այո | -| `check:ai-attribution` | PR-ի commit-ներում, վերնագրում կամ բովանդակությունում AI/բոտի `Co-Authored-By` վերջնագրի կամ AI-ի միջոցով գեներացման նշման բացակայություն — Խիստ կանոն #16 (`quality.yml`-ի արագ ստուգումների ցիկլում՝ PR→`release/**`-ի համար — կարդում է իրադարձության payload-ը, PR-ներից դուրս ոչինչ չի անում — և `ci.yml`-ի lint-ում՝ միայն PR→`main`-ի համար նախատեսված քայլում․ նաև husky-ի `commit-msg` hook-ում․ մարդկանց՝ որպես համահեղինակներ նշելը թույլատրվում է․ #14436) | -| `check:vitest-exclusions` | Vitest-ի յուրաքանչյուր բացառություն նշում է հետևման issue և առկա է `config/quality/vitest-exclusions.json`-ում (#13204) | Այո | -| `check:file-size` | Ոչ մի սկզբնաղբյուրային ֆայլ չի գերազանցում իր ընդլայնման համար սահմանված առավելագույն չափը (ratchet՝ մեծ ֆայլերը ամրագրված են `frozen` ցանկում) | Այո | -| `check:error-helper` | Կատարիչներում/մշակիչներում սխալի պատասխաններն օգտագործում են `buildErrorBody()` / `sanitizeErrorMessage()` (Խիստ կանոն #12) | Այո | -| `check:migration-numbering` | Միգրացիոն SQL ֆայլերը համարակալված են հաջորդականորեն՝ առանց բացթողումների կամ կրկնությունների | Այո | -| `check:public-creds` | `publicCreds.ts`-ից դուրս չկան OAuth-ի բառացի `client_id`/`client_secret` կամ Firebase Web բանալիներ (Խիստ կանոն #11) | Այո | -| `check:db-rules` | `src/lib/db/` մոդուլներից դուրս չկան անմշակ SQL հարցումներ, իսկ `localDb.ts`-ից չկան միջնորդավորված ներմուծումներ (Խիստ կանոններ #2/#5) | Այո | -| `check:known-symbols` | Մատակարարների կատարիչները, երթուղավորման ռազմավարությունները և թարգմանիչները, որոնք գրանցված են իրենց դիսպետչերական աղյուսակներում, համապատասխանում են սկավառակի ֆայլերին՝ առանց չօգտագործվող կամ չհայտարարված սիմվոլների | Այո | -| `check:route-guard-membership` | Յուրաքանչյուր երթուղի, որը ստեղծում է ենթապրոցես, դասակարգվում է `isLocalOnlyPath()`-ի միջոցով (Խիստ կանոններ #15/#17) | Այո | -| `check:test-discovery` | Շտեմարանի յուրաքանչյուր `*.test.ts` / `*.spec.ts` ֆայլ հավաքվում է առնվազն մեկ թեստային գործարկիչի կողմից (արգելակ՝ `test-discovery-baseline.json`-ում որբ ֆայլերի ցանկը կարող է միայն կրճատվել) | Այո | -| `check:agent-skills-sync` | Գեներացված agent-skills արտեֆակտները համապատասխանում են իրենց սկզբնաղբյուր կատալոգին (շեղում չկա) | -| `check:provider-asset-provenance` | Պրովայդերների լոգոները/ռեսուրսներն ունեն գրանցված ծագման գրառում | -| `lint:json` | JSON կազմաձևման ֆայլերը վերլուծվում են և բավարարում են ռեպոզիտորիայի lint կանոնները | -| `typecheck:core` | TypeScript-ի կոմպիլյացիա՝ առանց սխալների (միայն խորհրդատվական զգուշացումներ) | Այո | -| `typecheck:noimplicit:core` | Խիստ `noImplicitAny` — ապագային միտված է. նախապես գոյություն ունեցող բազմաթիվ կանչման կետեր դեռևս անոտացիաների կարիք ունեն | **Խորհրդատվական** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`՝ սահմանափակված `src/app/(dashboard)/**`-ով (#7033) — `typecheck:core`-ի հատուկ ընտրված 27 ֆայլից բաղկացած թույլատրված ցանկը չի ներառում dashboard-ի որևէ TSX ֆայլ, իսկ `next build`-ը նույնպես երբեք չի կատարում դրանց տիպերի ստուգում (`next.config.mjs`-ում սահմանված է `ignoreBuildErrors: true`), ուստի այնտեղի որբ նույնացուցիչների հետընթացները (#6625/#6909) անտեսանելի էին CI-ի համար։ Տարբերությունները համեմատվում են ըստ ֆայլի/TS կոդի քանակի սառեցված ելակետային տվյալների հետ (`config/quality/dashboard-typecheck-baseline.json`, նույն հնացած տվյալների պարտադրման ձևանմուշը, ինչ `check:known-symbols`-ի դեպքում) — շեմի ձախողման են հանգեցնում միայն ելակետային քանակը գերազանցող ՆՈՐ սխալները. երբ նախապես գոյություն ունեցող սխալը շտկվում է, նվազեցրեք շեմը `--update`-ով։ | Այո | +Գործարկվում է դեպի `main` ուղղված յուրաքանչյուր PR-ի համար։ Ձախողման դեպքում արգելափակում է միավորումը։ + +| Սկրիպտ (`npm run ...`) | Ստուգում է | Արգելափակող | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:node-runtime` | Node.js-ի տարբերակը աջակցվող միջակայքում է | Այո | +| `check:cycles` | `src/` + `open-sse/` ամբողջ տարածքում շրջանաձև ներմուծումները (AST-ի վրա հիմնված, tsconfig-ի `paths`-ը լուծված է)։ Սովորական ռեժիմը խորհրդատվական է և ցուցադրում է ցիկլերը։ `check:cycles:ratchet`-ը (որը գործարկում է CI-ն) արգելափակում է, երբ քանակը գերազանցում է `quality-baseline.json`-ում սահմանված `metrics.cycles` վերին շեմը՝ ներկայումս 14, `direction: down`, ուստի այն կարող է միայն նվազել (#15159 G-01/G-02) | Այո (ratchet) | +| `check:route-validation:t06` | Zod սխեմաների առկայությունը բոլոր route-երում (Tier 6 քաղաքականություն) | Այո | +| `check:any-budget:t11` | `@ts-expect-error // any`-ների քանակը չի գերազանցում բյուջեն (Tier 11 catraca) | Այո | +| `check:provider-consistency` | `providers.ts`-ի յուրաքանչյուր մատակարար ունի համապատասխան գրառում `providerRegistry.ts`-ում (և հակառակը՝ թույլատրվածների ցանկի սահմաններում) | Այո | +| `check:model-lifecycle` | Ձեռքով սպասարկվող երթուղավորման երեք աղյուսակները մնում են համահունչ պահոցում ներառված կենսացիկլի ակնապատկերին (#11503). `FITNESS_TABLE`-ը (`taskFitness.ts`) չի գնահատում որևէ շահագործումից հանված id, որը `REGISTRY`-ն կարող է երթուղավորել, `BUILT_IN_ALIASES`-ի յուրաքանչյուր թիրախ առկա է `REGISTRY`-ում և բացակայում է շահագործումից հանված id-ների ակնապատկերից, `REGISTRY`-ում դեռ առկա յուրաքանչյուր շահագործումից հանված id վերահասցեավորվում է կամ նշված է `allowedRetiredInCatalog`-ում, իսկ `DEFAULT_DEGRADATION_MAP`-ի ոչ մի աղբյուր կամ թիրախ այդ ակնապատկերում նշված չէ որպես շահագործումից հանված։ Սա չի ապացուցում, որ մոդելը ներկայումս սպասարկվում է գործող վերին մակարդակի ծառայության կողմից։ Անցանց է՝ համեմատում է `config/quality/model-lifecycle.json`-ի հետ, որը ձեռքով թարմացվում է `npm run quality:refresh-model-lifecycle` հրամանով (պահանջում է ցանցային կապ և ինտեգրված չէ CI-ին)։ `allowedRetiredInCatalog`-ը աստիճանական կրճատման արգելանիվ է. գրառում ավելացրեք միայն հետևման խնդրի առկայության դեպքում։ | Այո | +| `check:fetch-targets` | Հաճախորդի կողմի `src/`-ում յուրաքանչյուր `fetch("/api/...")` հղվում է իրական `route.ts`-ի | Այո | +| `check:deps` | Պահոցի յուրաքանչյուր `package.json`-ում `npm install`-ով տեղադրվող բոլոր կախվածությունները ներառված են `dependency-allowlist.json`-ում. նոր՝ տարբերակով չամրագրված կամ slopsquatting-ի ենթարկված փաթեթները նշագրվում են | Այո | +| `audit:deps` | `npm audit` (արմատային + electron) — բարձր/կրիտիկական մակարդակի զգուշացումներ չկան (համընկնում է osv `check:vuln-ratchet`-ի հետ. տե՛ս Հիմնավորման չմշակված խնդիրների ցանկը) | Այո | +| `check:lockfile` | `package-lock.json`-ի ամբողջականություն՝ https ռեեստր, ամբողջականության հեշեր, առանց հոսթի վերասահմանումների | Այո | +| `check:licenses` | Արտադրական կախվածությունների SPDX լիցենզիաների թույլատրելի ցանկ | Այո | +| `check:tracked-artifacts` | Կառուցման արտեֆակտներ / commit արված `node_modules` խորհրդանշական հղումներ չկան (գործարկվում է նաև husky pre-commit-ում․ pre-push-ը միտումնավոր թեթև է — #6716) | Այո | +| `check:ai-attribution` | PR commit-ներում, վերնագրում կամ նկարագրության մեջ չկան AI/bot `Co-Authored-By` վերջնատող կամ AI-ով գեներացման ստորատող — Խիստ կանոն #16 (`quality.yml`-ի արագ ստուգումների ցիկլում՝ PR→`release/**`-ի համար — կարդում է իրադարձության payload-ը, PR-ներից դուրս ոչինչ չի անում — և `ci.yml`-ի lint-ում՝ միայն PR-ի համար նախատեսված քայլով, PR→`main`-ի դեպքում․ նաև husky-ի `commit-msg` hook-ում․ մարդկային համահեղինակները թույլատրված են․ #14436) | +| `check:vitest-exclusions` | Vitest-ի յուրաքանչյուր բացառություն նշում է հետևման issue և առկա է `config/quality/vitest-exclusions.json`-ում (#13204) | Այո | +| `check:file-size` | Ոչ մի սկզբնաղբյուր ֆայլ չի գերազանցում տվյալ ընդլայնման համար սահմանված առավելագույն չափը (ratchet․ սառեցված մեծ ֆայլերը՝ `frozen` ցանկում) | Այո | +| `check:error-helper` | Executor-ներում/handler-ներում սխալների պատասխաններն օգտագործում են `buildErrorBody()` / `sanitizeErrorMessage()` (Խիստ կանոն #12) | Այո | +| `check:migration-numbering` | Միգրացիոն SQL ֆայլերը համարակալված են հաջորդականորեն՝ առանց բացերի կամ կրկնությունների | Այո | +| `check:public-creds` | `publicCreds.ts`-ից դուրս չկան OAuth-ի բառացի `client_id`/`client_secret` կամ Firebase Web բանալիներ (Խիստ կանոն #11) | Այո | +| `check:db-rules` | `src/lib/db/` մոդուլներից դուրս չկա անմիջական SQL. `localDb.ts`-ից չկան barrel ներմուծումներ (Խիստ կանոններ #2/#5) | Այո | +| `check:known-symbols` | Մատակարարների կատարիչները, երթուղավորման ռազմավարությունները և թարգմանիչները, որոնք գրանցված են իրենց dispatch աղյուսակներում, համապատասխանում են սկավառակի ֆայլերին՝ չկան չկապակցված կամ չհայտարարված սիմվոլներ | Այո | +| `check:route-guard-membership` | Յուրաքանչյուր երթուղի, որը ստեղծում է ենթագործընթաց, դասակարգված է `isLocalOnlyPath()`-ի միջոցով (Խիստ կանոններ #15/#17) | Այո | +| `check:test-discovery` | Պահոցում գտնվող յուրաքանչյուր `*.test.ts` / `*.spec.ts` ֆայլ հավաքվում է առնվազն մեկ թեստային գործարկիչի կողմից (ratchet. `test-discovery-baseline.json`-ում չկապակցված ֆայլերի ցանկը կարող է միայն կրճատվել) | Այո | +| `check:agent-skills-sync` | Գեներացված agent-skills արտեֆակտները համապատասխանում են իրենց սկզբնաղբյուր կատալոգին (շեղումներ չկան) | +| `check:provider-asset-provenance` | Մատակարարների լոգոների/ռեսուրսների ծագման գրանցված գրառում առկա է | +| `lint:json` | JSON կազմաձևման ֆայլերը վերլուծվում են և համապատասխանում են ռեպոզիտորիայի lint կանոններին | +| `typecheck:core` | TypeScript-ի կոմպիլյացիա՝ առանց սխալների (միայն խորհրդատվական նախազգուշացումներ) | Այո | +| `typecheck:noimplicit:core` | Խիստ `noImplicitAny` — նախատեսված է ապագայի համար. նախկինում գոյություն ունեցող բազմաթիվ կանչի կետեր դեռևս անոտացիաների կարիք ունեն | **Խորհրդատվական** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, որի շրջանակը սահմանափակված է `src/app/(dashboard)/**`-ով (#7033) — `typecheck:core`-ի հատուկ ընտրված 27 ֆայլից բաղկացած թույլատրացուցակը չի ներառում dashboard-ի որևէ TSX ֆայլ, իսկ `next build`-ը նույնպես երբեք չի ստուգում դրա տիպերը (`next.config.mjs`-ում սահմանված է `ignoreBuildErrors: true`), ուստի այնտեղ առկա չկապակցված նույնացուցիչների հետընթացները (#6625/#6909) անտեսանելի էին CI-ի համար։ Տարբերությունները համեմատվում են ըստ ֆայլի և TS կոդի քանակների անփոփոխ բազային ցուցանիշի հետ (`config/quality/dashboard-typecheck-baseline.json`, նույն հնացածության վերահսկման ձևանմուշը, ինչ `check:known-symbols`-ի դեպքում) — միայն բազային քանակը գերազանցող ՆՈՐ սխալներն են ձախողում անցակետը. երբ նախկինում գոյություն ունեցող սխալը շտկվում է, բազային ցուցանիշը նվազեցրեք `--update`-ով։ | Այո | ### Առաջադրանք՝ `quality-gate` Գործարկվում է `test-coverage`-ից հետո։ Ձախողման դեպքում արգելափակում է միավորումը։ -| Սկրիպտ | Ստուգում է | Արգելափակող | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- | -| `quality:collect` | Ստեղծում է `quality-metrics.json`-ը (ESLint-ի զգուշացումների քանակը, ծածկույթը՝ միավորված shard հաշվետվությունից) | Այո (ratchet-ից առաջ) | -| `quality:ratchet` | `quality-baseline.json`-ի յուրաքանչյուր չափանիշ չի վատթարացել (ESLint-ի զգուշացումներ ≤ ելակետային արժեքը, ծածկույթ ≥ ելակետային արժեքը) | Այո | -| `check:duplication` | Կոդի կրկնօրինակումը (jscpd@4) չի գերազանցում `quality-baseline.json`-ի ելակետային արժեքը | Այո | -| `check:complexity` | Ֆայլի մակարդակի ցիկլոմատիկ բարդությունը չի գերազանցում սահմանաչափը (հիմնական ESLint-ի `complexity` + `max-lines-per-function`) | Այո | -| `check:cognitive-complexity` | Կոգնիտիվ բարդության ratchet (`eslint-plugin-sonarjs`)՝ ESLint-ի առանձին անցում. CI-ն երկուսն էլ միավորված գործարկում է որպես մեկ `check:complexity-ratchets` քայլ | Այո | -| `check:dead-code` | Չօգտագործվող արտահանումների / ֆայլերի ratchet-ը (knip) չի վատթարանում ելակետային արժեքի համեմատ | Այո | -| `check:compression-budget` | Սեղմման հենանիշի բյուջեն՝ յուրաքանչյուր շարժիչի համար token-ների խնայողության նվազագույն շեմերը չպետք է վատթարանան | Այո | -| `check:type-coverage` | Տիպավորվածության տոկոսի ratchet-ը (`type-coverage`) չի վատթարանում. հիմնականում ներառում է `typecheck:noimplicit:core`-ի գործառույթները | Այո | -| `check:codeql-ratchet` | Բաց CodeQL ահազանգերի քանակը չի վատթարանում (ընթերցում է `gh api`-ի միջոցով. առանց token-ի՝ անվտանգ բաց է թողնում) — թարմացման հաճախականության և ձեռքով գործարկման համար տե՛ս ստորև «CodeQL ratchet»-ը | Այո | +| Սկրիպտ | Ստուգում է | Արգելակող | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `quality:collect` | Ստեղծում է `quality-metrics.json`-ը (ESLint-ի զգուշացումների քանակը, միավորված հատվածային հաշվետվությունից ստացված ծածկույթը) | Այո (հետընթացի արգելքի նախորդ քայլն է) | +| `quality:ratchet` | `quality-baseline.json`-ի յուրաքանչյուր չափանիշ չի վատթարացել (ESLint-ի զգուշացումները ≤ ելակետային արժեքը, ծածկույթը ≥ ելակետային արժեքը) | Այո | +| `check:duplication` | Կոդի կրկնօրինակումը (jscpd@4) չի գերազանցում `quality-baseline.json`-ի ելակետային արժեքը | Այո | +| `check:complexity` | Ֆայլի մակարդակի ցիկլոմատիկ բարդությունը չի գերազանցում սահմանաչափը (հիմնական ESLint-ի `complexity` + `max-lines-per-function`) | Այո | +| `check:cognitive-complexity` | Ճանաչողական բարդության հետընթացի արգելք (`eslint-plugin-sonarjs`)՝ ESLint-ի առանձին անցում․ CI-ն երկուսն էլ միավորված գործարկում է որպես մեկ `check:complexity-ratchets` քայլ | Այո | +| `check:dead-code` | Չօգտագործվող արտահանումների / ֆայլերի հետընթացի արգելքը (knip) չի վատթարանում ելակետային արժեքի համեմատ | Այո | +| `check:compression-budget` | Սեղմման հենանիշային թեստի սահմանաչափ՝ յուրաքանչյուր շարժիչի թոքենների խնայողության նվազագույն շեմերը չպետք է վատթարանան | Այո | +| `check:type-coverage` | Տիպավորվածության տոկոսի հետընթացի արգելքը (`type-coverage`) չի վատթարանում․ հիմնականում ներառում է `typecheck:noimplicit:core`-ի գործառույթը | Այո | +| `check:codeql-ratchet` | CodeQL-ի բաց զգուշացումների քանակը չի վատթարանում (կարդում է `gh api`-ի միջոցով, առանց թոքենի բարեհաջող բաց է թողնում)․ թարմացման հաճախականության և ձեռքով գործարկման համար տե՛ս ստորև՝ «CodeQL-ի հետընթացի արգելք» | Այո | ### Առաջադրանք՝ `quality-extended` -Ամբողջ առաջադրանքը խորհրդատվական է (`continue-on-error: true`)։ npm-ի վրա հիմնված ratchet-ներն իրականում գործարկվում են, -իսկ արտաքին սկանավորիչները տեղադրվում են `gh release download`-ի միջոցով և ինքնուրույն բաց են թողնում ստուգումը (ելքի կոդ՝ 0), -եթե բինար ֆայլը դեռ բացակայում է։ +Ամբողջ առաջադրանքը խորհրդատվական է (`continue-on-error: true`)։ npm-ի վրա հիմնված հետընթացի արգելքներն իրականում գործարկվում են, +իսկ արտաքին սկանավորիչները տեղադրվում են `gh release download`-ի միջոցով և ինքնուրույն բաց են թողնում ստուգումը (ելքի կոդը՝ 0), +եթե երկուական ֆայլը դեռ բացակայում է։ -| Սկրիպտ | Ստուգում է | Արգելափակող | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | -| `check:circular-deps` | Շրջանաձև կախվածություններ չկան (dpdm) | **Խորհրդատվական** | -| `check:bundle-size` | Փաթեթի չափը չի գերազանցում սահմանաչափը | **Խորհրդատվական** | -| `check:secrets` | Գաղտնիքների սկանավորում (gitleaks)՝ բաց է թողնում, եթե բինար ֆայլը բացակայում է | **Խորհրդատվական** | -| `check:vuln-ratchet` | Կախվածությունների խոցելիությունները (osv-scanner) չեն վատթարանում՝ բաց է թողնում, եթե բինար ֆայլը բացակայում է | **Խորհրդատվական** | -| `check:workflows` | Workflow-ների lint ստուգում (actionlint + zizmor). բացակայող/չաշխատող սկանավորիչները, անվավեր հաշվետվությունները կամ բացակայող ratchet ելակետը հանգեցնում են INCOMPLETE ձախողման։ Վավեր արդյունքները հետևում են ընտրված strict/advisory/ratchet քաղաքականությանը | Կատարումը պարտադիր է. zizmor ratchet-ը CI-ում արգելափակող է | -| `check:openapi-breaking` | Հանրային API պայմանագրի (`openapi.yaml`) խախտող փոփոխությունները՝ համեմատած հիմնական ճյուղի հետ (oasdiff) — արտածում է `openapiBreaking=N`. բաց է թողնում, եթե oasdiff-ը բացակայում է կամ հիմնական սպեցիֆիկացիան հնարավոր չէ որոշել | **Խորհրդատվական** | +| Սկրիպտ | Ստուգում է | Արգելակող | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- | +| `check:circular-deps` | Շրջանաձև կախվածությունների բացակայություն (dpdm) | **Խորհրդատվական** | +| `check:bundle-size` | Փաթեթի չափը չի գերազանցում սահմանաչափը | **Խորհրդատվական** | +| `check:secrets` | Գաղտնի տվյալների սկանավորում (gitleaks)՝ բաց է թողնվում, եթե երկուական ֆայլը բացակայում է | **Խորհրդատվական** | +| `check:vuln-ratchet` | Կախվածությունների խոցելիությունները (osv-scanner) չեն վատթարանում՝ բաց է թողնվում, եթե երկուական ֆայլը բացակայում է | **Խորհրդատվական** | +| `check:workflows` | Աշխատանքային հոսքերի լինտինգ (actionlint + zizmor)․ բացակայող/անսարք սկանավորիչները, անվավեր հաշվետվությունները կամ հետընթացի արգելքի բացակայող ելակետային արժեքը հանգեցնում են INCOMPLETE ձախողման։ Վավեր արդյունքները հետևում են ընտրված խիստ/խորհրդատվական/հետընթացի արգելքի քաղաքականությանը | Կատարումը պարտադիր է․ zizmor-ի հետընթացի արգելքը CI-ում արգելակող է | +| `check:openapi-breaking` | Հանրային API պայմանագրի (`openapi.yaml`) անհամատեղելի փոփոխություններ՝ համեմատած բազային ճյուղի հետ (oasdiff)․ ստեղծում է `openapiBreaking=N`․ բաց է թողնվում, եթե oasdiff-ը բացակայում է կամ բազային բնութագիրը հնարավոր չէ վերծանել | **Խորհրդատվական** | ### Առաջադրանք՝ `docs-sync-strict` -Գործարկվում է դեպի `main` ուղղված յուրաքանչյուր PR-ի համար։ Ձախողման դեպքում արգելափակում է միավորումը։ - -| Սկրիպտ | Ստուգում է | Արգելափակող | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -| `check:docs-all` | Մետա-շեմ, որը ստորև նշված 6 ենթաշեմերը գործարկում է հաջորդաբար | Այո | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt տարբերակների համապատասխանությունը | Այո | -| ↳ `check:docs-counts` | Շարադրանքում նշված քանակները (մատակարարների քանակ, միգրացիաների քանակ և այլն) գտնվում են իրական քանակների սահմանած աստիճանական խստացման միջակայքում | Այո | -| ↳ `check:env-doc-sync` | `.env.example`-ի յուրաքանչյուր միջավայրի փոփոխական փաստագրված է փաստաթղթերի աղյուսակում, և հակառակը | Այո | -| ↳ `check:deprecated-versions` | Փաստաթղթերում հնացած տարբերակների տողեր չկան | Այո | -| ↳ `check:doc-links` | Փաստաթղթերի ներքին markdown հղումները մատնանշում են գոյություն ունեցող ֆայլեր (`[text]`/`(path)` ձևաչափով) | Այո | -| ↳ `check:fabricated-docs` | Փաստաթղթերում հիշատակված երթուղիները, միջավայրի փոփոխականները, CLI հրամանները, hook-երի անունները և ֆայլերի ուղիները գոյություն ունեն կոդային բազայում։ Խիստ շեմ՝ `--strict`-ի միջոցով, առանց դրոշակի՝ ոչ արգելափակող ձախողում։ | Այո (CI-ում `--strict`-ի միջոցով) | -| `check:cli-i18n` | CLI հրամանների տողերը առկա են i18n տեղայնացման բոլոր ֆայլերում | Այո | -| `check:openapi-coverage` | OpenAPI սպեցիֆիկացիան ընդգրկում է իրական երթուղիների՝ աստիճանաբար բարձրացվող նվազագույն շեմը | Այո | -| `check:openapi-security-tiers` | `openapi.yaml`-ի անվտանգության մակարդակների նշումները համապատասխանում են `routeGuard.ts`-ի դասակարգումներին | **Խորհրդատվական** | -| `check:openapi-routes` | `openapi.yaml`-ի յուրաքանչյուր ուղի համապատասխանում է իրական `route.ts`-ի (հորինվածքների կանխարգելում) | Այո | -| `check:docs-symbols` | `docs/**/*.md`-ում յուրաքանչյուր `/api/...` հղում համապատասխանում է իրական `route.ts`-ի (հորինվածքների կանխարգելում) | Այո | -| `i18n translation drift` | i18n տեղայնացման ֆայլերում չթարգմանված բանալիներ — միայն նախազգուշացում | **Խորհրդատվական** | +Գործարկվում է `main` ուղղված յուրաքանչյուր PR-ի համար։ Ձախողման դեպքում արգելափակում է միավորումը։ + +| Սկրիպտ | Ստուգում է | Արգելափակող | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `check:docs-all` | Մետա-դարպաս, որը հաջորդաբար գործարկում է ստորև նշված 6 ենթադարպասները | Այո | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt տարբերակների համապատասխանությունը | Այո | +| ↳ `check:docs-counts` | Տեքստում նշված քանակները (մատակարարների քանակ, միգրացիաների քանակ և այլն) գտնվում են իրական քանակների համար սահմանված աստիճանական միջակայքում | Այո | +| ↳ `check:env-doc-sync` | `.env.example`-ի յուրաքանչյուր միջավայրի փոփոխական փաստաթղթավորված է փաստաթղթերի աղյուսակում, և հակառակը | Այո | +| ↳ `check:deprecated-versions` | Փաստաթղթերում չկան հնացած տարբերակների տողեր | Այո | +| ↳ `check:doc-links` | Փաստաթղթերի ներքին markdown հղումները տանում են դեպի գոյություն ունեցող ֆայլեր (`[տեքստ]`/`(path)` ձևաչափ) | Այո | +| ↳ `check:fabricated-docs` | Փաստաթղթերում նշված երթուղիները, միջավայրի փոփոխականները, CLI հրամանները, hook-երի անունները և ֆայլերի ուղիները գոյություն ունեն կոդային բազայում։ Խիստ դարպաս՝ `--strict`-ի միջոցով, իսկ առանց դրոշակի՝ ոչ խիստ ձախողում։ | Այո (CI-ում `--strict`-ի միջոցով) | +| `check:cli-i18n` | CLI հրամանների տողերը առկա են i18n տեղայնացման բոլոր ֆայլերում | Այո | +| `check:openapi-coverage` | OpenAPI սպեցիֆիկացիան ընդգրկում է իրական երթուղիների՝ առնվազն աստիճանաբար սահմանված նվազագույն քանակը | Այո | +| `check:openapi-security-tiers` | `openapi.yaml`-ի անվտանգության մակարդակների նշումները համապատասխանում են `routeGuard.ts`-ի դասակարգումներին | **Խորհրդատվական** | +| `check:openapi-routes` | `openapi.yaml`-ի յուրաքանչյուր ուղի համապատասխանում է իրական `route.ts`-ի (հորինվածքների կանխարգելում) | Այո | +| `check:docs-symbols` | `docs/**/*.md`-ում `/api/...`-ի յուրաքանչյուր հղում համապատասխանում է իրական `route.ts`-ի (հորինվածքների կանխարգելում) | Այո | +| `i18n translation drift` | i18n տեղայնացման ֆայլերում չթարգմանված բանալիներ՝ միայն նախազգուշացում | **Խորհրդատվական** | ### Առաջադրանք՝ `i18n-ui-coverage` -| Սկրիպտ | Ստուգում է | Արգելափակող | -| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `check-ui-keys-coverage` (ներկառուցված) | UI-ի i18n բանալիների ծածկույթը ≥ 65% է | Այո | -| `check-ui-value-drift` (ներկառուցված) | Վերաշարադրված անգլերեն **արժեքից** հետո հնացած թարգմանություն չի մնում | Այո | -| `check-new-key-coverage` (ներկառուցված) | Անգլերենի **նոր** բանալին թարգմանված է յուրաքանչյուր տեղայնացման մեջ. `__MISSING__:` նշիչը մերժվում է | Այո | -| `check-translation-ratio` | Յուրաքանչյուր տեղայնացման իրական թարգմանությունների հարաբերակցությունը (թույլատրելի ցանկից դուրս անգլերենին նույնական / տեղապահ / բացակայող տերևային արժեքներ) չպետք է գերազանցի `config/quality/i18n-translation-baseline.json`-ը + թույլատրելի շեղումը | **Խորհրդատվական** | +| Սկրիպտ | Ստուգում է | Արգելափակող | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `check-ui-keys-coverage` (ներդրված) | UI-ի i18n բանալիների ծածկույթը ≥ 65% է | Այո | +| `check-ui-value-drift` (ներդրված) | Վերաշարադրված անգլերեն **արժեքը** չի թողնում հնացած թարգմանություն | Այո | +| `check-new-key-coverage` (ներդրված) | Անգլերեն **նոր** բանալին թարգմանված է յուրաքանչյուր տեղայնացման համար. `__MISSING__:` նշիչը մերժվում է | Այո | +| `check-translation-ratio` | Յուրաքանչյուր տեղայնացման իրական թարգմանությունների հարաբերակցությունը (անգլերենին նույնական / տեղապահ / թույլատրված ցանկից դուրս բացակայող արժեքներ) չպետք է գերազանցի `config/quality/i18n-translation-baseline.json`-ը՝ գումարած թույլատրելի շեղումը | **Խորհրդատվական** | -Պահանջվում է `fetch-depth: 0` — արժեքների շեղման շեմը `en.json`-ը համեմատում է միաձուլման բազայի հետ։ +Պահանջում է `fetch-depth: 0` — արժեքների շեղման դարպասը համեմատում է `en.json`-ը միաձուլման բազայի հետ։ -#### `check-ui-value-drift` — հնացած թարգմանությունների շեմ +#### `check-ui-value-drift` — հնացած թարգմանությունների դարպաս -Հայտնաբերում է i18n-ի այն մեկ հետընթացը, որը մյուս շեմերը կառուցվածքային առումով չեն կարող տեսնել. անգլերեն արժեքը -վերաշարադրվում է, իսկ _նախորդ_ անգլերենից ստացված թարգմանությունները մնում են տեղում, ինչի հետևանքով -ոչ անգլախոս օգտատերերը շարունակում են կարդալ վստահ ձևակերպված, բայց արդեն սխալ տեքստը։ +Հայտնաբերում է i18n-ի այն մեկ հետընթացը, որը մյուս դարպասները կառուցվածքային առումով չեն կարող տեսնել. անգլերեն արժեքը +վերաշարադրվում է, իսկ _նախորդ_ անգլերենից ստացված թարգմանությունները մնում են, ինչի հետևանքով +ոչ անգլախոս օգտատերերը շարունակում են կարդալ վստահորեն ձևակերպված, սակայն այժմ սխալ տեքստ։ -Սա իրականում թողարկվել է։ `oauthModal.googleOAuthWarning`-ը վերաշարադրվել էր, երբ ավելացվեց Antigravity-ի -մուտքի օգնականը (#5203), սակայն **43 տեղայնացումներից 39-ում** մնացել էր օպերատորներին հուշող տեքստը՝ «պատճենել -ամբողջ URL-ը և տեղադրել այն ստորև», մինչդեռ այդ մատակարարի դեպքում այս հոսքը հնարավոր չէ ավարտել։ Այն -չէր նկատվել մինչև #8463-ը, քանի որ՝ +Սա իրականում հասել է թողարկման։ `oauthModal.googleOAuthWarning`-ը վերաշարադրվել էր, երբ ավելացվեց Antigravity +մուտքի օգնականը (#5203). **43 տեղայնացումներից 39-ը** պահպանել էին տեքստ, որն օպերատորներին ասում էր՝ «պատճենել +ամբողջական URL-ը և տեղադրել այն ստորև»՝ ընթացակարգ, որն այդ մատակարարի դեպքում չի կարող ավարտվել։ Այն +աննկատ էր մնացել մինչև #8463, քանի որ՝ -- `sync-ui-keys`-ը լրացնում է միայն **բացակայող** բանալիները, ոչ երբեք **հնացածները**, -- `check-ui-keys-coverage`-ը հաշվում է բանալու _առկայությունը_, ուստի հնացած թարգմանությունը համարվում է ծածկված, -- `check-translation-drift`-ը հետևում է `docs/i18n//**.md` փաստաթղթային հայելիներին՝ - այն երբեք չի կարդում `src/i18n/messages/*.json`։ Արգելափակող է `docs-sync-strict` առաջադրանքում՝ սկսած - 2026-09-ի վերասինքրոնացումից. խմբագրեք հիմնական փաստաթուղթը → `npm run i18n:run -- --files=` (բաժնի մակարդակով, քիչ ռեսուրսատար)։ +- `sync-ui-keys`-ը լրացնում է միայն **բացակայող** բանալիները, բայց երբեք՝ **հնացածները**. +- `check-ui-keys-coverage`-ը հաշվում է բանալու _առկայությունը_, ուստի հնացած թարգմանությունը համարվում է ծածկված. +- `check-translation-drift`-ը հետևում է `docs/i18n//**.md` փաստաթղթային հայելիներին — + այն երբեք չի կարդում `src/i18n/messages/*.json`։ 2026-09-ի վերասինքրոնացումից ի վեր արգելափակող է `docs-sync-strict` առաջադրանքում. խմբագրեք հիմնական փաստաթուղթ → `npm run i18n:run -- --files=` (բաժնի մակարդակով, քիչ ծախսատար)։ -**Տարբերությունները հաշվի առնող, ոչ թե բազային տարբերակի վրա հիմնված։** Այն միաձուլման բազայում գտնվող `en.json`-ը համեմատում է +**Տարբերությունները հաշվի առնող, ոչ թե բազային վիճակի վրա հիմնված։** Այն միաձուլման բազայում գտնվող `en.json`-ը համեմատում է աշխատանքային ծառի հետ․ յուրաքանչյուր բանալու համար, որի անգլերեն արժեքը փոխվել է, անփոփոխ -թարգմանություն դեռ պարունակող ցանկացած տեղայնացում համարվում է հնացած։ Սա միտումնավոր **սառեցնում է նախկինում կուտակված պարտքը**․ տարբերությունը -չի կարող բացահայտել, թե վաղուց գոյություն ունեցող թարգմանությունը որ հին անգլերեն տարբերակից է առաջացել, ուստի դարպասը գնահատում է -միայն այն, ինչին առնչվում է ընթացիկ փոփոխությունը։ Այլընտրանքը՝ ըստ բանալիների հեշերի բազային տարբերակը, կպահանջեր -մոտ 600 KB ծավալով գեներացված ֆայլ՝ 3 անգամ մեծ գոյություն ունեցող ամենախոշոր բազային տարբերակից, որը կփոփոխվեր յուրաքանչյուր i18n PR-ի ժամանակ։ +թարգմանություն դեռևս պարունակող ցանկացած տեղայնացում համարվում է հնացած։ Սա միտումնավոր **սառեցնում է նախկինում առկա պարտքը**․ տարբերությունը +չի կարող բացահայտել, թե վաղուց գոյություն ունեցող թարգմանությունը որ հին անգլերեն տարբերակից է առաջացել, ուստի արգելքը գնահատում է +միայն այն, ինչին վերաբերում է ընթացիկ փոփոխությունը։ Այլընտրանքը (յուրաքանչյուր բանալու համար հեշերի բազային վիճակ) կպահանջեր +մոտ 600 KB ծավալով գեներացված ֆայլ՝ ամենամեծ գոյություն ունեցող բազային ֆայլից 3× մեծ, որը կփոփոխվեր յուրաքանչյուր i18n PR-ի ժամանակ։ -Պահանջը բավարարելու երկու եղանակ կա․ +Այն բավարարելու երկու եղանակ կա․ 1. թարմացնել համապատասխան թարգմանությունները, կամ -2. դրանց արժեքը սահմանել որպես `__MISSING__:`․ այդ դեպքում կատարման միջավայրը վերադարձնում է շտկված անգլերենը - (`src/i18n/request.ts::deepMergeFallback`, #7258), իսկ բանալին ավելացվում է թարգմանության հերթին։ +2. սահմանել դրանք որպես `__MISSING__:<նոր անգլերեն տեքստ>`․ այդ դեպքում կատարման միջավայրը տրամադրում է ուղղված անգլերենը + (`src/i18n/request.ts::deepMergeFallback`, #7258), իսկ բանալին ավելացվում է թարգմանության հերթում։ Եթե փոխվել է տողի **իմաստը**, նախընտրելի է **վերանվանել բանալին**․ նոր բանալին չի կարող -ժառանգել հնացած թարգմանություն։ Այդ օրինաչափությունն է կիրառվել #8463-ում։ +ժառանգել հնացած թարգմանություն։ #8463-ում կիրառվել է հենց այդ ձևանմուշը։ ```bash npm run i18n:check-value-drift # խիստ ռեժիմ (այն, ինչ գործարկում է CI-ը) @@ -231,47 +231,47 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` Ավարտվում է 0 կոդով և `SKIP reason=base-unresolved` հաղորդագրությամբ, երբ բազային կատալոգը հնարավոր չէ կարդալ (մակերեսային -կլոն՝ առանց բազային հղման)՝ նմանակելով `check-openapi-breaking`-ի վարքագիծը։ +կլոն՝ առանց բազային հղման)՝ կրկնելով `check-openapi-breaking`-ի վարքագիծը։ ### Առաջադրանք՝ `i18n` -i18n-ի վավերացման ամբողջական մատրիցա (մեկ առաջադրանք՝ յուրաքանչյուր տեղայնացման համար)։ Ամբողջ առաջադրանքը խորհրդատվական է։ +i18n-ի ամբողջական վավերացման մատրիցա (մեկ առաջադրանք յուրաքանչյուր տեղայնացման համար)։ Ամբողջ առաջադրանքը խորհրդատվական է։ -| Սկրիպտ | Ինչն է վավերացնում | Արգելափակող | -| ------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------- | -| `validate_translation.py quick` | Թարգմանության ամբողջականությունը՝ ըստ տեղայնացման | **Խորհրդատվական** (`continue-on-error: true` ամբողջ առաջադրանքի համար) | +| Սկրիպտ | Ինչն է վավերացնում | Արգելափակող | +| ------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------- | +| `validate_translation.py quick` | Թարգմանության ամբողջականությունը՝ ըստ տեղայնացման | **Խորհրդատվական** (`continue-on-error: true`՝ ամբողջ առաջադրանքի համար) | ### Առաջադրանք՝ `pr-test-policy` Գործարկվում է միայն pull request-ների համար։ -| Սկրիպտ | Ինչն է վավերացնում | Արգելափակող | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` կամ `bin/` պանակներում արտադրական կոդը փոխող PR-ները պետք է ներառեն կամ թարմացնեն թեստեր (Խիստ կանոն #8) | Այո | -| `check:test-masking` | Փոփոխված թեստային ֆայլերը չեն նվազեցնում assert-ների զուտ քանակը և չեն ավելացնում `assert.ok(true)` տավտոլոգիաներ | Այո | -| `check:pr-evidence` | PR-ի նկարագրությունը նշում է փոփոխության համար թեստերի/VPS-ի ապացույցները (մեխանիկացնում է Խիստ կանոն #18-ը՝ PR-ի տեքստում որոնելով համապատասխան արտահայտություններ․ փխրուն է, տե՛ս Backlog-ը) | Այո | +| Սկրիպտ | Ինչն է վավերացնում | Արգելափակող | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check:pr-test-policy` | Այն PR-ները, որոնք փոխում են արտադրական կոդը `src/`, `open-sse/`, `electron/` կամ `bin/` ուղիներում, պետք է ներառեն կամ թարմացնեն թեստերը (Խիստ կանոն #8) | Այո | +| `check:test-masking` | Փոփոխված թեստային ֆայլերը չեն նվազեցնում assert-ների զուտ քանակը և չեն ավելացնում `assert.ok(true)` տավտոլոգիաներ | Այո | +| `check:pr-evidence` | PR-ի նկարագրությունը պարունակում է փոփոխության թեստային/VPS ապացույցներ (մեքենայացնում է Խիստ կանոն #18-ը՝ PR-ի տեքստում որոնելով․ փխրուն է, տե՛ս Հետագա աշխատանքների ցանկը) | Այո | ### Առաջադրանք՝ `test-vitest` Գործարկվում է `build`-ից հետո։ Ձախողման դեպքում արգելափակում է միաձուլումը։ -| Փաթեթ | Ինչն է վավերացնում | Արգելափակող | -| ---------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP սերվեր (110 գործիք), autoCombo, քեշ — vitest գործարկիչ | Այո | -| `test:vitest:ui` | UI բաղադրիչների թեստեր — vitest գործարկիչ | **Արգելափակող** — նախկինում գոյություն ունեցող ձախողումները բացահայտորեն բացառված են `vitest.config.ts`-ում․ նոր ձախողումները ձախողում են առաջադրանքը | +| Փաթեթ | Ինչն է վավերացնում | Արգելափակող | +| ---------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP սերվեր (110 գործիք), autoCombo, քեշ — vitest գործարկիչ | Այո | +| `test:vitest:ui` | UI բաղադրիչների թեստեր — vitest գործարկիչ | **Արգելափակող** — նախկինում առկա ձախողումները բացահայտորեն բացառված են `vitest.config.ts`-ում․ նոր ձախողումները ձախողում են առաջադրանքը | ### Գիշերային աշխատանքային հոսքեր (պլանավորված, խորհրդատվական) -Սրանք գործարկվում են cron ժամանակացույցով (և `workflow_dispatch`-ով), երբեք՝ PR-ների համար։ Բոլորը խորհրդատվական են։ +Դրանք գործարկվում են cron ժամանակացույցով (և `workflow_dispatch`-ով), երբեք՝ PR-ների համար։ Բոլորը խորհրդատվական են։ | Աշխատանքային հոսք | Ինչն է վավերացնում | Արգելափակող | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `nightly-property` | fast-check հատկությունների թեստեր՝ պատահական seed-ով և գործարկումների մեծ քանակով | **Խորհրդատվական** | -| `nightly-resilience` | heap-ի աճի դարպաս, խափանումների քաոսային ներարկում, k6 բեռնվածության/տևական ծանրաբեռնվածության թեստավորում | **Խորհրդատվական** | -| `nightly-llm-security` | promptfoo ներարկումների պաշտպանություն (արգելափակման ռեժիմ) + garak ստուգումներ (բաց են թողնվում առանց մատակարարի գաղտնիքի) | **Խորհրդատվական** | -| `nightly-schemathesis` | OpenAPI պայմանագրի ֆազինգ (schemathesis)՝ կենդանի OmniRoute-ի նկատմամբ, օգտագործելով `docs/openapi.yaml`-ը․ բացահայտում է սպեցիֆիկացիայի խախտումները / չմշակված 500 սխալները (Փուլ 8 B.4) | **Խորհրդատվական** | -| `nightly-mutation` | Stryker մուտացիոն թեստավորման գնահատականը արագ միավորային թեստերի ուղու համար․ գոյատևած մուտանտները բացահայտում են թույլ assert-ները | **Խորհրդատվական** | -| `nightly-compat` | Node շարժիչի համատեղելիության մատրիցան՝ աջակցվող `engines.node` միջակայքերում | **Խորհրդատվական** | +| `nightly-property` | fast-check հատկությունների թեստեր՝ պատահական սկզբնական արժեքով և գործարկումների մեծ քանակով | **Խորհրդատվական** | +| `nightly-resilience` | heap-ի աճի արգելք, խափանումների քաոսային ներարկում, k6 բեռնվածության/երկարատև ծանրաբեռնվածության թեստավորում | **Խորհրդատվական** | +| `nightly-llm-security` | promptfoo ներարկումների պաշտպանություն (արգելափակման ռեժիմ) + garak զոնդեր (բաց են թողնվում առանց մատակարարի գաղտնիքի) | **Խորհրդատվական** | +| `nightly-schemathesis` | OpenAPI պայմանագրի fuzzing (schemathesis)՝ գործող OmniRoute-ի նկատմամբ, օգտագործելով `docs/openapi.yaml`-ը․ բացահայտում է սպեցիֆիկացիայի խախտումները / չմշակված 500 սխալները (Փուլ 8 B.4) | **Խորհրդատվական** | +| `nightly-mutation` | Stryker մուտացիոն թեստավորման գնահատական՝ արագ մոդուլային ուղու համար․ գոյատևած մուտանտները բացահայտում են թույլ assert-ները | **Խորհրդատվական** | +| `nightly-compat` | Node շարժիչի համատեղելիության մատրիցա՝ աջակցվող `engines.node` միջակայքերի համար | **Խորհրդատվական** | --- @@ -534,43 +534,43 @@ CI ստուգիչներից բացի, OmniRoute-ը ներառում է **ըստ --- -## Ռացիոնալացման կուտակված աշխատանքներ (ROI-ի վերանայում — Փուլ 9 Ալիք 3) +## Ռացիոնալացման հետագա աշխատանքների ցանկ (ROI-ի վերանայում — Փուլ 9 Ալիք 3) -Այս գույքացանկը 2026-06-17-ին համադրվել է `ci.yml`-ի հետ (նախորդ տարբերակում բաց էին թողնվել +Այս գույքացանկը 2026-06-17-ին համադրվել է `ci.yml`-ի հետ (նախորդ տարբերակում բացակայում էին `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`)։ Համադրված հավաքածուի ROI-ի վերանայմամբ -բացահայտվել են ռացիոնալացման հետևյալ թեկնածուները։ **Միավորումները CI-ի մեխանիկական -փոփոխություններ են, իսկ փոխարկումները/հեռացումները՝ օպերատորին վերապահված քաղաքականության որոշումներ։** Ստորև -նշվածներից դեռ ոչինչ չի կիրառվել։ - -**Վերևում նաև փաստագրված չեն** (խորհրդատվական, թույլ ազդանշանով)՝ `docs-lint` առաջադրանքը -(markdownlint + Vale, ամբողջ առաջադրանքի համար՝ `continue-on-error`) և ինքնուրույն սկանավորման աշխատանքային հոսքերը՝ -`semgrep.yml` / `codeql.yml` / `scorecard.yml`։ `semgrepFindings: 0`-ն առկա է -`quality-baseline.json`-ում, սակայն կապված չէ `ci.yml`-ում արգելափակող ճշգրտիչի հետ․ չափորոշիչը -ներկայումս որբ է։ - -### Միավորում / կրկնությունների վերացում (մեխանիկական, ավելի ցածր ռիսկով) - -Յուրաքանչյուր թեկնածու 2026-06-17-ին վավերացվել է գործող անցակետի վիճակի նկատմամբ (վստահել, բայց ստուգել)․ -մի քանի «ակնհայտ» միավորումներ, պարզվեց, թաքցնում են տեխնիկական պարտք և **չեն** կարող կիրառվել որպես մաքուր ուղղակի փոխարինումներ։ - -- **`check:docs-sync`-ը գործարկվում է երկու անգամ** — առանձին՝ `lint` առաջադրանքում, և կրկին՝ `check:docs-all`-ի (`docs-sync-strict`) ու husky-ի pre-commit hook-ի ներսում։ ✅ **ԱՎԱՐՏՎԱԾ Է** — առանձին `lint` կանչը հեռացվել է։ -- **CVE սկանավորում** — ❌ **Մաքուր միավորում ՉԷ։** `audit:deps`-ը կոշտ ձախողվում է ցանկացած բարձր/կրիտիկական CVE-ի դեպքում, իսկ `check:vuln-ratchet`-ը (osv) ձախողվում է միայն ելակետի համեմատ _հետընթացի_ դեպքում (ներկայումս՝ 1 MODERATE)։ Իմաստաբանությունը տարբեր է․ `audit:deps`-ի հեռացումը կվերացնի բարձր/կրիտիկական մակարդակի բացարձակ անցակետը։ Պահել երկուսն էլ։ -- **Ցիկլերի հայտնաբերում** — ❌ **Մաքուր միավորում ՉԷ։** `check:circular-deps`-ը (dpdm) հաղորդում է **91 ցիկլի** մասին (հենց այդ պատճառով էլ այն խորհրդատվական է)․ այն չի կարող դառնալ արգելափակող՝ առանց դրանք նախապես վերացնելու, և դրա ընդգրկույթն ավելի լայն է, քան հաջող անցնող, նպատակային `check:cycles`-ինը։ `check:cycles`-ը պահել արգելափակող․ dpdm-ի 91 ցիկլերի վերացումն առանձին կուտակված աշխատանք է։ -- **Բարդություն** — ✅ **ԱՎԱՐՏՎԱԾ Է** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)․ ESLint-ի մեկ անցում, հաշվարկը՝ ըստ ruleId-ի, որպեսզի ցիկլոմատիկ+max-lines և կոգնիտիվ ելակետերը մնան անկախ․ առանձին `check:complexity` / `check:cognitive-complexity` հրամանները պահպանվել են տեղային `--update`-ի համար։ -- **`/api` հակահալյուցինացիոն ստուգում** — ✅ **ԱՎԱՐՏՎԱԾ Է** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)․ `src/app/api`-ի ֆայլային համակարգի մեկ գույքագրում, openapi-routes + docs-symbols-ը դեռ զեկուցում են առանձին․ առանձին հրամանները պահպանվել են տեղային գործարկումների համար։ -- **`check:node-runtime`-ը գործարկվում է 11 առաջադրանքում** — ⚠️ **ցածր ROI։** Յուրաքանչյուրն առանձին runner է, իսկ ստուգումը տևում է <1 վրկ․ ընդհանուր խնայողությունը մոտ ~10 վրկ է՝ յուրաքանչյուր առաջադրանքի համար էժան պաշտպանիչ ստուգումը կորցնելու դիմաց։ Չարժե նման փոփոխությունների իրարանցումը։ -- **`typecheck:noimplicit:core`-ը CI-ի lint-ում** — ✅ **հեռացվել է lint առաջադրանքից** (խորհրդատվական էր՝ `continue-on-error`)․ տիպերի արգելափակող մակերեսն ապահովում են `typecheck:core` + `check:type-coverage`։ Տեղային սկրիպտը պահպանվել է։ - -### Փոխարկել / որոշել (օպերատորի քաղաքականություն) - -- `check:openapi-security-tiers` (խորհրդատվական) — ❌ **Հնարավոր չէ մաքուր կերպով փոխարկել։** Այն ավարտվում է 0 կոդով, սակայն զգուշացնում է, որ `LOCAL_ONLY_API_PREFIXES`-ի տակ գտնվող մի քանի `traffic-inspector` երթուղիներում բացակայում է `x-loopback-only: true` նշագրումը։ Դրա պարտադրումը նախ պահանջում է այդ նշագրումներն ավելացնել `openapi.yaml`-ում։ -- `typecheck:noimplicit:core` (խորհրդատվական) — հիմնականում ներառված է արգելափակող `check:type-coverage` ճշգրտիչի մեջ։ Փոխարկել ճշգրտիչի կամ հեռացնել կրկնվող երկրորդ `tsc` անցումը։ -- `test:vitest:ui` (այժմ **արգելափակող**) — նախապես գոյություն ունեցող ձախողումները բացահայտորեն բացառված են `vitest.config.ts`-ում՝ `// #8618` հետագծման մեկնաբանություններով․ նոր ձախողումները ձախողում են առաջադրանքը։ -- `check:secrets` (gitleaks, արգելափակող ճշգրտիչ՝ սառեցված 3 փաստագրված կեղծ դրական արդյունքի վրա) — այդ 3-ը ներառել թույլատրելի ցանկում՝ 0-ի հասնելու համար, կամ իջեցնել խորհրդատվականի մակարդակի։ Համընկնում է GitHub-ի ներկառուցված գաղտնիքների սկանավորման + `check:public-creds`-ի հետ։ -- `check:pr-evidence` (արգելափակող, grep-ով որոնում է PR-ի մարմնի արձակ տեքստում) — կեղծ դրական արդյունքների բարձր ռիսկ․ հեռացնելու դեպքում թուլացնում է Խիստ կանոն #18-ի կիրառումը, ուստի սա իսկական քաղաքականության որոշում է։ -- `semgrep` (առանձին խորհրդատվական) — OWASP ընտանիքների մասով համընկնում է CodeQL-ի հետ․ դրա ելակետը կապել ճշգրտիչի հետ կամ հեռացնել։ +`check:codeql-ratchet`, `check:pr-evidence`)։ Համադրված բազմության ROI-ի վերանայումը +բացահայտեց ռացիոնալացման հետևյալ թեկնածուները։ **Միավորումները CI-ի մեխանիկական +փոփոխություններ են, իսկ ռեժիմի փոփոխությունները/հեռացումները քաղաքականության որոշումներ են, որոնք վերապահված են օպերատորին։** Ստորև նշվածից +դեռ ոչինչ չի կիրառվել։ + +**Վերևում նույնպես փաստաթղթավորված չեն** (խորհրդատվական, թույլ ազդանշան)՝ `docs-lint` առաջադրանքը +(markdownlint + Vale, ամբողջ առաջադրանքի համար՝ `continue-on-error`) և առանձին սկանավորիչների աշխատանքային հոսքերը՝ +`semgrep.yml` / `codeql.yml` / `scorecard.yml`։ `semgrepFindings: 0`-ը գտնվում է +`quality-baseline.json`-ում, սակայն կապված չէ `ci.yml`-ի արգելափակող սահմանափակիչի հետ. ներկայում այս չափանիշը +կապազուրկ է։ + +### Միավորում / կրկնությունների վերացում (մեխանիկական, ավելի ցածր ռիսկ) + +Յուրաքանչյուր թեկնածու 2026-06-17-ին ստուգվել է ակտիվ անցակետի վիճակի համեմատ (վստահել, բայց ստուգել). +մի քանի «ակնհայտ» միավորումներ, պարզվեց, թաքցնում են տեխնիկական պարտք և **չեն** կարող ուղղակիորեն փոխարինել առկան։ + +- **`check:docs-sync`-ը գործարկվում է երկու անգամ**՝ առանձին՝ `lint` առաջադրանքում, և կրկին՝ `check:docs-all`-ի (`docs-sync-strict`) ու husky pre-commit hook-ի ներսում։ ✅ **ԿԱՏԱՐՎԱԾ Է** — առանձին `lint` կանչը հեռացվել է։ +- **CVE սկանավորում** — ❌ **Մաքուր միավորում ՉԷ։** `audit:deps`-ը կոշտ ձախողվում է ցանկացած բարձր/կրիտիկական CVE-ի դեպքում, իսկ `check:vuln-ratchet`-ը (osv) ձախողվում է միայն ելակետային մակարդակի համեմատ _հետընթացի_ դեպքում (ներկայում՝ 1 MODERATE)։ Իմաստաբանությունը տարբեր է. `audit:deps`-ի հեռացումը կվերացներ բացարձակ բարձր/կրիտիկական անցակետը։ Պահել երկուսն էլ։ +- **Ցիկլերի հայտնաբերում** — ✅ **ԿԱՏԱՐՎԱԾ Է** (#15159 G-01/G-02)։ Այստեղ եղած հին տեքստը `check:cycles`-ն անվանում էր «կանաչ, խնամքով ընտրված» անցակետ և դրա արգելափակող լինելը հիմնավորում էր նրանով, որ `check:circular-deps`-ը (dpdm) հաղորդում էր 91 ցիկլի մասին։ Այդ կանաչ վիճակը **կեղծ կանաչ** էր. `check:cycles`-ը սկանավորում էր 5 ենթագրացուցակ (450 ֆայլ), համընկնում էր միայն ստատիկ `import|export … from`-ին և բաց էր թողնում բոլոր `@/` ու `@omniroute/open-sse/` նշիչները, ուստի չէր կարող տեսնել պահոցում գերակշռող դինամիկ import + alias ցիկլերը։ Ուղղված է. անցակետն այժմ շրջանցում է `src` + `open-sse`-ը (5023 ֆայլ), նշիչները հավաքում է TypeScript AST-ից (այդպիսով `import("…")`-ը հաշվվում է, իսկ տիպային դիրքում գտնվող `typeof import("…")`-ը՝ ոչ) և լուծում է tsconfig-ի `paths`-ը։ Այն գտնում է **14** ցիկլ, ոչ թե 0։ Քանի որ նախկինից առկա 14 ցիկլը հնարավոր չէ ուղղել անցակետի PR-ում, `check:cycles`-ն այժմ **սահմանափակիչ** է (`--ratchet`, վերին սահմանը՝ `metrics.cycles.value = 14`՝ `quality-baseline.json`-ում, `direction: down`). այն արգելափակում է ցանկացած _հետընթաց_, իսկ քանակը կարող է միայն նվազել։ CI-ն գործարկում է `npm run check:cycles:ratchet`։ Աստիճանական նվազեցումը կատարվում է **A-01**-ի հետ։ `check:circular-deps`-ը (dpdm) մնում է խորհրդատվական՝ որպես ավելի լայն երկրորդ կարծիք։ +- **Բարդություն** — ✅ **ԿԱՏԱՐՎԱԾ Է** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)՝ ESLint-ի մեկ շրջանցում, հաշվարկ ըստ ruleId-ի, որպեսզի ցիկլոմատիկ+max-lines և կոգնիտիվ ելակետային մակարդակները մնան անկախ. առանձին `check:complexity` / `check:cognitive-complexity` հրամանները պահպանվում են տեղային `--update`-ի համար։ +- **`/api` հակահալյուցինացիոն ստուգում** — ✅ **ԿԱՏԱՐՎԱԾ Է** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)՝ `src/app/api`-ի ֆայլային համակարգի մեկ գույքագրում, openapi-routes + docs-symbols-ը շարունակում են հաշվետվություն ներկայացնել անկախ. առանձին հրամանները պահպանվում են տեղային գործարկումների համար։ +- **`check:node-runtime`-ը գործարկվում է 11 առաջադրանքում** — ⚠️ **ցածր ROI։** Յուրաքանչյուրն առանձին runner է, իսկ ստուգումը տևում է <1վ. ընդհանուր խնայողությունը մոտավորապես 10վ է՝ էժան, յուրաքանչյուր առաջադրանքի համար առանձին պաշտպանությունը կորցնելու դիմաց։ Չարժե փոփոխությունների աղմուկը։ +- **`typecheck:noimplicit:core`-ը CI lint-ում** — ✅ **հեռացվել է lint առաջադրանքից** (խորհրդատվական էր՝ `continue-on-error`). արգելափակող տիպային մակերեսը `typecheck:core` + `check:type-coverage` է։ Տեղային սկրիպտը պահպանվել է։ + +### Փոխել ռեժիմը / որոշել (օպերատորի քաղաքականություն) + +- `check:openapi-security-tiers` (խորհրդատվական) — ❌ **Հնարավոր չէ մաքուր ձևով դարձնել արգելափակող։** Այն ավարտվում է 0 կոդով, սակայն զգուշացնում է, որ `LOCAL_ONLY_API_PREFIXES`-ի ներքո գտնվող մի քանի `traffic-inspector` երթուղիներ չունեն `x-loopback-only: true` նշագրումը։ Դրա պարտադրումը պահանջում է նախ այդ նշագրումներն ավելացնել `openapi.yaml`-ում։ +- `typecheck:noimplicit:core` (խորհրդատվական) — հիմնականում ներառված է արգելափակող `check:type-coverage` սահմանափակիչի մեջ։ Դարձնել սահմանափակիչ կամ հեռացնել կրկնվող երկրորդ `tsc` անցումը։ +- `test:vitest:ui` (այժմ **արգելափակող**) — նախկինից առկա ձախողումները բացահայտորեն բացառված են `vitest.config.ts`-ում՝ `// #8618` հետևման մեկնաբանություններով. նոր ձախողումները հանգեցնում են առաջադրանքի ձախողման։ +- `check:secrets` (gitleaks, արգելափակող սահմանափակիչ՝ սառեցված 3 փաստաթղթավորված կեղծ դրական արդյունքի վրա) — թույլատրելի ցանկում ներառել այդ 3-ը՝ 0-ի հասնելու համար, կամ իջեցնել մինչև խորհրդատվական։ Համընկնում է GitHub-ի ներկառուցված գաղտնիքների սկանավորման + `check:public-creds`-ի հետ։ +- `check:pr-evidence` (արգելափակող, grep-ով որոնում է PR-ի հիմնական տեքստում) — կեղծ դրական արդյունքների բարձր ռիսկ. հեռացնելու դեպքում թուլացնում է Hard Rule #18-ի պարտադրումը, ուստի սա քաղաքականության իրական որոշում է։ +- `semgrep` (խորհրդատվական առանձին աշխատանքային հոսք) — OWASP ընտանիքների մասով համընկնում է CodeQL-ի հետ. դրա ելակետային մակարդակը միացնել սահմանափակիչին կամ հեռացնել։ --- diff --git a/docs/i18n/id/CONTRIBUTING.md b/docs/i18n/id/CONTRIBUTING.md index 68182d01d48..f21271275f0 100644 --- a/docs/i18n/id/CONTRIBUTING.md +++ b/docs/i18n/id/CONTRIBUTING.md @@ -405,16 +405,16 @@ Tulis pengujian unit di `tests/unit/` yang sekurang-kurangnya mencakup: - [ ] Linting lulus (`npm run lint`) - [ ] Build berhasil (`npm run build`) - [ ] Tipe TypeScript ditambahkan untuk fungsi dan antarmuka publik baru -- [ ] Tidak ada secret atau nilai fallback yang di-hardcode -- [ ] Kredensial upstream publik disematkan melalui `resolvePublicCred()` (lihat [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), jangan pernah sebagai literal -- [ ] Respons kesalahan diproses melalui `buildErrorBody()` / `sanitizeErrorMessage()` — tidak ada stack trace mentah dalam body respons (lihat [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Tidak ada rahasia atau nilai fallback yang di-hardcode +- [ ] Kredensial upstream publik disematkan melalui `resolvePublicCred()` (lihat [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), tidak pernah sebagai literal +- [ ] Respons kesalahan diproses melalui `buildErrorBody()` / `sanitizeErrorMessage()` — tidak ada stack trace mentah dalam isi respons (lihat [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Perintah shell (`exec` / `spawn`) meneruskan nilai runtime melalui `env`, bukan melalui interpolasi string - [ ] Semua input divalidasi dengan skema Zod -- [ ] **Fragmen** changelog ditambahkan di bawah `changelog.d/{features|fixes|maintenance}/-.md` untuk perubahan yang terlihat oleh pengguna (lihat [`changelog.d/README.md`](./changelog.d/README.md)) — **jangan** mengedit `CHANGELOG.md` secara langsung; fragmen digabungkan saat rilis dan tidak pernah menimbulkan konflik antar-PR +- [ ] **Fragmen** changelog ditambahkan di bawah `changelog.d/{features|fixes|maintenance}/-.md` untuk perubahan yang terlihat oleh pengguna (lihat [`changelog.d/README.md`](./changelog.d/README.md)) — **jangan** mengedit `CHANGELOG.md` secara langsung; fragmen diagregasikan saat rilis dan tidak pernah berkonflik antar-PR - [ ] Dokumentasi diperbarui (jika berlaku) -- [ ] Tidak ada peringatan CodeQL / Secret-Scanning baru yang dibuka, atau setiap peringatan telah ditutup dengan justifikasi teknis yang merujuk pada dokumen `docs/security/` yang relevan -- [ ] Route yang menjalankan proses anak (`/api/mcp/`, `/api/cli-tools/runtime/`) diklasifikasikan sebagai `isLocalOnlyPath()` di `src/server/authz/routeGuard.ts` — lihat [Aturan Ketat #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Tidak ada trailer `Co-Authored-By` dalam pesan commit — commit harus ditampilkan hanya di bawah identitas Git pemilik repositori (Aturan Ketat #16) +- [ ] Tidak ada peringatan CodeQL / Secret-Scanning baru yang dibuka, atau setiap peringatan ditolak dengan justifikasi teknis yang merujuk pada dokumen `docs/security/` yang relevan +- [ ] Rute yang menjalankan proses turunan (`/api/mcp/`, `/api/cli-tools/runtime/`) diklasifikasikan sebagai `isLocalOnlyPath()` dalam `src/server/authz/routeGuard.ts` — lihat [Aturan Ketat #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Tidak ada trailer `Co-authored-by` dari AI/bot dalam pesan commit (Aturan Ketat #16) — kolaborator manusia yang karyanya digunakan kembali diberi kredit dengan trailer standar `Co-authored-by: Name ` --- diff --git a/docs/i18n/id/docs/architecture/QUALITY_GATES.md b/docs/i18n/id/docs/architecture/QUALITY_GATES.md index dea9f728e32..0a031899d6a 100644 --- a/docs/i18n/id/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/id/docs/architecture/QUALITY_GATES.md @@ -19,47 +19,48 @@ yang tidak bergantung pada alat untuk sistem yang sama, lihat ### Penerimaan kandidat -Workflow CI dan Quality Gates masing-masing menghasilkan putusan stabil: `Gate / CI` dan -`Gate / Quality`. Kebijakan penerimaan berversi miliknya mencantumkan setiap job hulu -sebagai wajib atau advisori. Job wajib yang berlaku harus berhasil: hasil yang hilang, +Workflow CI dan Quality Gates masing-masing menghasilkan putusan yang stabil: `Gate / CI` dan +`Gate / Quality`. Kebijakan penerimaan berversi milik keduanya mencantumkan setiap job upstream +sebagai wajib atau advisori. Job wajib yang berlaku harus berhasil: hasil yang tidak ada, dibatalkan, dilewati, tertunda, dan tidak diketahui tidak dapat menetapkan PASS. Klasifikasi -khusus dokumentasi atau khusus katalog yang valid dapat membuat lane kode tidak berlaku; +docs-only atau catalog-only yang valid dapat membuat lane kode tidak berlaku; PR draf bukan kandidat yang diterima. Label `hotfix` tidak menggugurkan persyaratan bukti. Kedua workflow mencakup PR dan push ke branch main/release, dispatch manual, serta -peristiwa merge-group. Push, dispatch, dan merge-group menjalankan pilihan lengkap. Fork -dan merge group menggunakan hosted runner untuk job yang biasanya memilih self-hosted -runner; kapasitas hosted yang memadai harus diverifikasi sebelum peluncuran. - -Setiap bukti JSON mengidentifikasi SHA yang di-checkout, workflow run, dan attempt. -CLI menolak ketidakcocokan SHA checkout/peristiwa. Pengujian workflow mengikat keanggotaan -kebijakan ke daftar `needs` milik job putusan sehingga lane baru atau yang dihapus tidak -dapat menghilang tanpa terdeteksi. Bukti tersebut mencakup workflow-nya sendiri, bukan -publikasi, deployment, atau bagian internal dari pemindai advisori yang sudah ada. -Mengaktifkan kedua nama pemeriksaan dalam aturan branch merupakan perubahan administratif -terpisah; menambahkan job ini tidak serta-merta melindungi branch. +event merge-group. Push, dispatch, dan merge-group menjalankan seluruh pilihan. Fork +dan merge group menggunakan runner terkelola untuk job yang jika tidak demikian akan +memilih runner self-hosted; kapasitas runner terkelola yang memadai harus diverifikasi +sebelum peluncuran. + +Setiap tanda terima JSON mengidentifikasi SHA yang di-checkout, workflow run, dan attempt. +CLI menolak ketidakcocokan SHA checkout/event. Pengujian workflow mengikat keanggotaan kebijakan +ke daftar `needs` milik job putusan sehingga lane baru atau yang dihapus tidak dapat menghilang +secara diam-diam. Tanda terima tersebut mencakup workflow-nya sendiri, bukan publikasi, +deployment, atau aspek internal dari scanner advisori yang sudah ada. Mengaktifkan kedua nama +check dalam aturan branch merupakan perubahan administratif terpisah; penambahan job ini +tidak secara otomatis melindungi branch. ### Inventaris pemindaian statis Inventaris npm-alias berversi dan keanggotaan pemindaian statis berada di `config/quality/gate-manifest.json`. Jalankan `npm run check:gate-manifest` untuk memvalidasi -nama skrip dan perintah persis terhadap `package.json`; penambahan, penghapusan, dan -perubahan perintah menyebabkan kegagalan pada hook lokal maupun job klasifikasi perubahan -di CI. Alias bukanlah job workflow, instance matriks, atau kasus pengujian: jumlah ini -tidak boleh disajikan sebagai hal yang dapat dipertukarkan. +nama skrip dan perintah yang tepat terhadap `package.json`; penambahan, penghapusan, dan +perubahan perintah akan menggagalkan hook lokal serta job klasifikasi perubahan di CI. +Alias bukanlah job workflow, instance matriks, atau test case: jumlah ini tidak boleh +disajikan seolah-olah dapat saling dipertukarkan. Gunakan `npm run quality:scan -- --list` atau `npm run quality:scan:fast -- --list` -untuk memeriksa alias yang dipilih tanpa mengeksekusinya. Runner memanggil entrypoint -npm, sehingga runtime-nya (termasuk Bun jika dikonfigurasi) tetap dipertahankan. -Manifes mencatat alias di luar profil tersebut sebagai dipanggil secara terpisah, dan -perintah pemeliharaan dilarang dalam profil pemindaian hanya-baca. +untuk memeriksa alias yang dipilih tanpa mengeksekusinya. Runner memanggil +entrypoint npm sehingga runtime-nya (termasuk Bun jika dikonfigurasi) tetap dipertahankan. +Manifest mencatat alias di luar profil tersebut sebagai alias yang dipanggil secara terpisah, +dan perintah pemeliharaan dilarang dalam profil pemindaian read-only. -Profil ini hanya mencakup pemindaian statis. Profil ini tidak menyertifikasi pengujian -produk, cakupan, pengemasan, pemeriksaan eksternal, atau penerimaan rilis lengkap kandidat. +Profil ini hanya mencakup pemindaian statis. Profil ini tidak menyertifikasi pengujian produk, +coverage, packaging, check eksternal, atau penerimaan rilis penuh suatu kandidat. Penerimaan workflow menggunakan `config/quality/admission-policy.json` yang ditautkan dan `scripts/quality/admission-verdict.mjs`. Profil release-observer tetap terpisah; -periksa pemeriksaan dan bukti yang berlaku secara independen. Inventaris naratif -di bawah ini merupakan referensi, bukan bukti bahwa gate benar-benar dijalankan. +periksa check dan tanda terima yang berlaku secara independen. Inventaris naratif +di bawah ini merupakan referensi, bukan bukti bahwa suatu gate benar-benar dijalankan. Skrip berada di bawah `scripts/check/` (gate kebijakan) dan `scripts/quality/` (mesin ratchet). Sumber kebenaran CI adalah `.github/workflows/ci.yml`. @@ -67,101 +68,101 @@ Sumber kebenaran CI adalah `.github/workflows/ci.yml`. ### Jalur cepat PR rilis (`quality.yml`) `.github/workflows/quality.yml` melengkapi CI pada PR main/release, push ke branch -terlindungi, dispatch, dan merge group. PR menggunakan pemeriksaan cepat yang difilter -berdasarkan path. Build duplikat yang dinonaktifkan secara permanen telah dihapus; -pemeriksaan build/package/boot yang sebenarnya tetap berada di CI. - -| Job | Cakupan | Memblokir | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `Docs Gates (fast-path)` | PR dokumentasi/kode; referensi dokumentasi API dan seluruh dokumentasi | Ya | -| `Fast Quality Gates` | PR kode; pemeriksaan statis, pemeriksaan tipe, pemeriksaan tipe dasbor, pengujian unit terdampak | Ya | -| `Forgotten sibling tests` | PR kode; modul yang diubah ditelusuri ke konsumen statis dan kandidat pengujian saudara; path barrel dan impor dinamis dilaporkan sebagai diagnostik advisori, dengan pengecualian allowlist yang dirujuk | **Advisori** | -| `Vitest (fast-path)` | PR kode; rangkaian vitest cepat | Ya | -| `Unit Tests fast-path` | PR kode; rangkaian unit 4-shard | Ya | -| `No new ESLint warnings` | PR kode; pelindung lint yang menyadari supresi | Ya, termasuk fork | -| `Merge integrity (changelog + generated skills)` | PR non-draf; sinkronisasi changelog dan skill yang dihasilkan | Ya, termasuk fork | - -#### Laporan pengujian saudara yang terlupakan +yang dilindungi, dispatch, dan merge group. PR menggunakan check cepat yang difilter berdasarkan +path. Build duplikat yang dinonaktifkan secara permanen telah dihapus; check build/package/boot +yang sebenarnya tetap berada di CI. + +| Job | Cakupan | Memblokir | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `Docs Gates (fast-path)` | PR docs/kode; referensi docs API dan docs-all | Ya | +| `Fast Quality Gates` | PR kode; check statis, typecheck, typecheck dashboard, unit test terdampak | Ya | +| `Forgotten sibling tests` | PR kode; modul yang diubah ditelusuri ke konsumen statis dan kandidat sibling test; path barrel dan dynamic-import dilaporkan sebagai diagnostik advisori, dengan pengecualian allowlist yang dirujuk | **Advisori** | +| `Vitest (fast-path)` | PR kode; rangkaian vitest cepat | Ya | +| `Unit Tests fast-path` | PR kode; rangkaian unit 4-shard | Ya | +| `No new ESLint warnings` | PR kode; guard lint yang mempertimbangkan suppression | Ya, termasuk fork | +| `Merge integrity (changelog + generated skills)` | PR non-draf; sinkronisasi changelog dan skill yang dihasilkan | Ya, termasuk fork | + +#### Laporan forgotten sibling tests `npm run check:forgotten-sibling-tests` menggunakan kembali resolver impor di balik peta dampak pengujian. Untuk setiap modul produksi yang diubah, perintah ini melaporkan rantai deterministik -`changed module/symbol -> static consumer -> candidate sibling test` ketika pengujian kandidat +`changed module/symbol -> static consumer -> candidate sibling test` ketika test kandidat tidak ada dalam diff pull request. Ringkasan Markdown dan hasil JSON disimpan sebagai -artefak workflow `forgotten-sibling-tests` untuk kalibrasi sebelum peluncuran apa pun yang memblokir. +artefak workflow `forgotten-sibling-tests` untuk kalibrasi sebelum peluncuran yang bersifat memblokir. Ekspor ulang barrel dan impor dinamis hanya merupakan diagnostik resolusi; keduanya tidak pernah menghasilkan temuan yang memblokir. Pengecualian yang telah ditinjau berada di -`config/quality/forgotten-sibling-allowlist.json`. Setiap entri harus mencantumkan konsumen dan pengujian +`config/quality/forgotten-sibling-allowlist.json`. Setiap entri harus menyebutkan pengonsumsi dan pengujian kandidat, memberikan alasan yang spesifik, serta menautkan issue atau pull request GitHub. Entri yang tidak valid -akan gagal secara tertutup. Pengecualian tidak dapat menyembunyikan pengujian kandidat yang dihapus atau diff yang menambahkan `.skip`/`.todo`; -pelemahan assertion dan penyamaran lainnya tetap menjadi tanggung jawab gate +akan ditolak secara default. Pengecualian tidak dapat menyembunyikan pengujian kandidat yang dihapus atau diff yang menambahkan `.skip`/`.todo`; +pelemahan asersi dan penyamaran lainnya tetap menjadi tanggung jawab gate `check:test-masking` yang memblokir secara independen. ### Job: `lint` Berjalan pada setiap PR ke `main`. Memblokir penggabungan jika gagal. -| Skrip (`npm run ...`) | Memvalidasi | Memblokir | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | -| `check:node-runtime` | Versi Node.js berada dalam rentang yang didukung | Ya | -| `check:cycles` | Impor melingkar — semua modul `src/` + `open-sse/` | Ya | -| `check:route-validation:t06` | Skema Zod tersedia pada semua rute (kebijakan Tier 6) | Ya | -| `check:any-budget:t11` | Jumlah `@ts-expect-error // any` tidak melebihi anggaran (catraca Tier 11) | Ya | -| `check:provider-consistency` | Setiap penyedia di `providers.ts` memiliki entri yang cocok di `providerRegistry.ts` (dan sebaliknya, dalam allowlist) | Ya | -| `check:model-lifecycle` | Ketiga tabel perutean yang dipelihara secara manual tetap konsisten dengan snapshot siklus hidup yang disimpan (#11503): `FITNESS_TABLE` (`taskFitness.ts`) tidak memberikan skor pada id yang sudah dihentikan dan masih dapat dirutekan oleh `REGISTRY`; setiap target `BUILT_IN_ALIASES` terdapat di `REGISTRY` dan tidak terdapat dalam snapshot id yang dihentikan; setiap id yang dihentikan dan masih berada di `REGISTRY` diteruskan atau tercantum dalam `allowedRetiredInCatalog`; dan tidak ada sumber atau target `DEFAULT_DEGRADATION_MAP` yang ditandai telah dihentikan dalam snapshot tersebut. Pemeriksaan ini tidak membuktikan bahwa suatu model saat ini dilayani oleh upstream aktif. Luring — membandingkan dengan `config/quality/model-lifecycle.json`, yang diperbarui secara manual menggunakan `npm run quality:refresh-model-lifecycle` (memerlukan jaringan; tidak diintegrasikan ke CI). `allowedRetiredInCatalog` adalah mekanisme ratchet pengurangan bertahap: tambahkan entri hanya jika disertai masalah pelacakan. | Ya | -| `check:fetch-targets` | Setiap `fetch("/api/...")` di `src/` sisi klien mengarah ke `route.ts` yang benar-benar ada | Ya | -| `check:deps` | Semua dependensi yang dapat dipasang dengan `npm install` dari setiap `package.json` dalam repositori tercantum di `dependency-allowlist.json`; paket baru yang versinya tidak dikunci atau berpotensi merupakan slopsquatting akan ditandai | Ya | -| `audit:deps` | `npm audit` (root + electron) — tidak ada advisori tingkat tinggi/kritis (tumpang tindih dengan `check:vuln-ratchet` osv; lihat Backlog Rasionalisasi) | Ya | -| `check:lockfile` | Integritas `package-lock.json` — registry https, hash integritas, tanpa penggantian host | Ya | -| `check:licenses` | Daftar izin lisensi SPDX untuk dependensi produksi | Ya | -| `check:tracked-artifacts` | Tidak ada artefak build / symlink `node_modules` yang di-commit (juga dijalankan dalam pre-commit husky; pre-push sengaja dibuat ringan — #6716) | Ya | -| `check:ai-attribution` | Tidak ada trailer `Co-Authored-By` AI/bot atau footer pembuatan oleh AI dalam commit, judul, atau isi PR — Aturan Tegas #16 (dalam perulangan pemeriksaan cepat `quality.yml` untuk PR→`release/**` — membaca payload peristiwa, tidak melakukan apa pun di luar PR — dan langkah khusus PR dalam lint `ci.yml` untuk PR→`main`; juga hook `commit-msg` husky; rekan penulis manusia diizinkan; #14436) | -| `check:vitest-exclusions` | Setiap pengecualian Vitest menyebutkan isu pelacakan dan tercantum dalam `config/quality/vitest-exclusions.json` (#13204) | Ya | -| `check:file-size` | Tidak ada file sumber yang melebihi batas per ekstensi (ratchet: file besar yang dibekukan dalam daftar `frozen`) | Ya | -| `check:error-helper` | Respons galat dalam eksekutor/handler menggunakan `buildErrorBody()` / `sanitizeErrorMessage()` (Aturan Tegas #12) | Ya | -| `check:migration-numbering` | File SQL migrasi diberi nomor secara berurutan, tanpa nomor yang terlewat atau duplikat | Ya | -| `check:public-creds` | Tidak ada OAuth `client_id`/`client_secret` literal atau kunci Firebase Web di luar `publicCreds.ts` (Aturan Ketat #11) | Ya | -| `check:db-rules` | Tidak ada SQL mentah di luar modul `src/lib/db/`; tidak ada impor barrel dari `localDb.ts` (Aturan Ketat #2/#5) | Ya | -| `check:known-symbols` | Eksekutor penyedia, strategi perutean, dan penerjemah yang terdaftar dalam tabel dispatch masing-masing cocok dengan file pada disk—tidak ada simbol yatim atau yang tidak dideklarasikan | Ya | -| `check:route-guard-membership` | Setiap rute yang membuat proses anak diklasifikasikan oleh `isLocalOnlyPath()` (Aturan Ketat #15/#17) | Ya | -| `check:test-discovery` | Setiap file `*.test.ts` / `*.spec.ts` dalam repo dikumpulkan oleh setidaknya satu test runner (ratchet: daftar yatim dalam `test-discovery-baseline.json` hanya dapat menyusut) | Ya | -| `check:agent-skills-sync` | Artefak agent-skills yang dihasilkan cocok dengan katalog sumbernya (tanpa penyimpangan) | -| `check:provider-asset-provenance` | Logo/aset penyedia memiliki entri asal-usul yang tercatat | -| `lint:json` | File konfigurasi JSON dapat diurai dan memenuhi aturan lint repositori | -| `typecheck:core` | Kompilasi TypeScript tanpa kesalahan (hanya peringatan informatif) | Ya | -| `typecheck:noimplicit:core` | `noImplicitAny` ketat — berorientasi ke masa depan; banyak lokasi pemanggilan yang sudah ada masih memerlukan anotasi | **Informatif** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` yang dibatasi ke `src/app/(dashboard)/**` (#7033) — daftar yang diizinkan berisi 27 file yang telah dikurasi milik `typecheck:core` tidak menyertakan TSX dasbor apa pun, dan `next build` juga tidak pernah memeriksa tipenya (`next.config.mjs` menetapkan `ignoreBuildErrors: true`), sehingga regresi pengidentifikasi yatim di sana (#6625/#6909) tidak terlihat oleh CI. Perubahan dibandingkan dengan tolok ukur jumlah per file/per kode TS yang dibekukan (`config/quality/dashboard-typecheck-baseline.json`, pola penerapan terhadap data usang yang sama seperti `check:known-symbols`) — hanya kesalahan BARU yang melebihi jumlah dalam tolok ukur yang menggagalkan gerbang; turunkan tolok ukur secara bertahap dengan `--update` ketika kesalahan yang sudah ada diperbaiki. | Ya | - -### Pekerjaan: `quality-gate` - -Berjalan setelah `test-coverage`. Memblokir penggabungan jika terjadi kegagalan. - -| Skrip | Memvalidasi | Memblokir | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `quality:collect` | Menghasilkan `quality-metrics.json` (jumlah peringatan ESLint, cakupan dari laporan shard gabungan) | Ya (sebelum ratchet) | -| `quality:ratchet` | Setiap metrik dalam `quality-baseline.json` tidak mengalami regresi (peringatan ESLint ≤ baseline; cakupan ≥ baseline) | Ya | -| `check:duplication` | Duplikasi kode (jscpd@4) tidak melebihi baseline dalam `quality-baseline.json` | Ya | -| `check:complexity` | Kompleksitas siklomatik tingkat file tidak melebihi batas (ESLint inti `complexity` + `max-lines-per-function`) | Ya | -| `check:cognitive-complexity` | Ratchet kompleksitas kognitif (`eslint-plugin-sonarjs`) — proses ESLint terpisah; CI menjalankan keduanya secara gabungan sebagai satu langkah `check:complexity-ratchets` | Ya | -| `check:dead-code` | Ratchet ekspor/file yang tidak digunakan (knip) tidak mengalami regresi dibandingkan baseline | Ya | -| `check:compression-budget` | Anggaran tolok ukur kompresi — batas minimum penghematan token per mesin tidak boleh mengalami regresi | Ya | -| `check:type-coverage` | Ratchet persentase kode bertipe (`type-coverage`) tidak mengalami regresi; sebagian besar mencakup `typecheck:noimplicit:core` | Ya | -| `check:codeql-ratchet` | Jumlah peringatan CodeQL terbuka tidak mengalami regresi (dibaca melalui `gh api`; dilewati secara wajar tanpa token) — frekuensi pembaruan dan pemicu manual: lihat "Ratchet CodeQL" di bawah | Ya | +| Skrip (`npm run ...`) | Memvalidasi | Memblokir | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `check:node-runtime` | Versi Node.js berada dalam rentang yang didukung | Ya | +| `check:cycles` | Impor melingkar di seluruh `src/` + `open-sse/` (berbasis AST, `paths` tsconfig di-resolve). Bare = bersifat saran, menampilkan daftar siklus. `check:cycles:ratchet` (yang dijalankan CI) memblokir ketika jumlahnya melebihi batas atas `metrics.cycles` dalam `quality-baseline.json` — saat ini 14, `direction: down`, sehingga nilainya hanya dapat berkurang (#15159 G-01/G-02) | Ya (ratchet) | +| `check:route-validation:t06` | Skema Zod tersedia pada semua route (kebijakan Tier 6) | Ya | +| `check:any-budget:t11` | Jumlah `@ts-expect-error // any` tidak melebihi anggaran (catraca Tier 11) | Ya | +| `check:provider-consistency` | Setiap provider di `providers.ts` memiliki entri yang sesuai di `providerRegistry.ts` (dan sebaliknya, dalam allowlist) | Ya | +| `check:model-lifecycle` | Tiga tabel routing yang dikelola secara manual tetap konsisten dengan snapshot siklus hidup yang disimpan (#11503): `FITNESS_TABLE` (`taskFitness.ts`) tidak memberikan skor pada id yang sudah dihentikan dan masih dapat dirutekan oleh `REGISTRY`; setiap target `BUILT_IN_ALIASES` terdapat di `REGISTRY` dan tidak ada dalam snapshot id yang dihentikan; setiap id yang dihentikan dan masih ada di `REGISTRY` diteruskan atau tercantum dalam `allowedRetiredInCatalog`; dan tidak ada sumber atau target `DEFAULT_DEGRADATION_MAP` yang ditandai telah dihentikan dalam snapshot tersebut. Ini tidak membuktikan bahwa suatu model saat ini dilayani oleh upstream aktif. Offline — dibandingkan dengan `config/quality/model-lifecycle.json`, diperbarui secara manual menggunakan `npm run quality:refresh-model-lifecycle` (memerlukan jaringan; tidak diintegrasikan ke CI). `allowedRetiredInCatalog` adalah mekanisme ratchet burn-down: tambahkan entri hanya jika disertai issue pelacakan. | Ya | +| `check:fetch-targets` | Setiap `fetch("/api/...")` dalam `src/` sisi klien mengarah ke `route.ts` yang benar-benar ada | Ya | +| `check:deps` | Semua dependensi yang dapat diinstal dengan `npm install` di seluruh `package.json` dalam repositori tercantum di `dependency-allowlist.json`; paket baru yang tidak dikunci versinya atau berpotensi slopsquatting akan ditandai | Ya | +| `audit:deps` | `npm audit` (root + electron) — tidak ada advisory tingkat tinggi/kritis (tumpang tindih dengan osv `check:vuln-ratchet`; lihat Backlog Rasionalisasi) | Ya | +| `check:lockfile` | Integritas `package-lock.json` — registry https, hash integritas, tanpa penggantian host | Ya | +| `check:licenses` | Daftar izin lisensi SPDX untuk dependensi produksi | Ya | +| `check:tracked-artifacts` | Tidak ada artefak build / symlink `node_modules` yang di-commit (juga dijalankan dalam pre-commit husky; pre-push sengaja dibuat ringan — #6716) | Ya | +| `check:ai-attribution` | Tidak ada trailer `Co-Authored-By` AI/bot atau footer pembuatan oleh AI dalam commit, judul, atau isi PR — Aturan Ketat #16 (dalam loop gerbang cepat `quality.yml` untuk PR→`release/**` — membaca payload event, tidak melakukan apa pun di luar PR — dan langkah khusus PR dalam lint `ci.yml` untuk PR→`main`; juga hook `commit-msg` husky; rekan penulis manusia diperbolehkan; #14436) | +| `check:vitest-exclusions` | Setiap pengecualian Vitest mencantumkan issue pelacakan dan tercantum dalam `config/quality/vitest-exclusions.json` (#13204) | Ya | +| `check:file-size` | Tidak ada file sumber yang melebihi batas per ekstensi (ratchet: file besar yang dibekukan dalam daftar `frozen`) | Ya | +| `check:error-helper` | Respons error dalam eksekutor/handler menggunakan `buildErrorBody()` / `sanitizeErrorMessage()` (Aturan Ketat #12) | Ya | +| `check:migration-numbering` | File SQL migrasi diberi nomor secara berurutan, tanpa celah atau duplikat | Ya | +| `check:public-creds` | Tidak ada nilai literal OAuth `client_id`/`client_secret` atau kunci Firebase Web di luar `publicCreds.ts` (Aturan Ketat #11) | Ya | +| `check:db-rules` | Tidak ada SQL mentah di luar modul `src/lib/db/`; tidak ada impor barrel dari `localDb.ts` (Aturan Ketat #2/#5) | Ya | +| `check:known-symbols` | Eksekutor penyedia, strategi perutean, dan penerjemah yang terdaftar dalam tabel dispatch masing-masing cocok dengan file pada disk — tidak ada simbol yatim atau yang tidak dideklarasikan | Ya | +| `check:route-guard-membership` | Setiap rute yang menjalankan proses anak diklasifikasikan oleh `isLocalOnlyPath()` (Aturan Ketat #15/#17) | Ya | +| `check:test-discovery` | Setiap file `*.test.ts` / `*.spec.ts` dalam repositori dikumpulkan oleh setidaknya satu test runner (ratchet: daftar file yatim dalam `test-discovery-baseline.json` hanya dapat menyusut) | Ya | +| `check:agent-skills-sync` | Artefak agent-skills yang dihasilkan cocok dengan katalog sumbernya (tanpa penyimpangan) | +| `check:provider-asset-provenance` | Logo/aset penyedia memiliki entri asal-usul yang tercatat | +| `lint:json` | File konfigurasi JSON dapat diurai dan memenuhi aturan lint repositori | +| `typecheck:core` | Kompilasi TypeScript tanpa kesalahan (hanya peringatan advisori) | Ya | +| `typecheck:noimplicit:core` | `noImplicitAny` ketat — berorientasi ke depan; banyak lokasi pemanggilan yang sudah ada masih memerlukan anotasi | **Advisori** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` yang dicakup untuk `src/app/(dashboard)/**` (#7033) — daftar yang diizinkan dan dikurasi yang berisi 27 file milik `typecheck:core` tidak menyertakan TSX dasbor apa pun, dan `next build` juga tidak pernah melakukan pemeriksaan tipe terhadapnya (`next.config.mjs` menetapkan `ignoreBuildErrors: true`), sehingga regresi pengidentifikasi yatim di sana (#6625/#6909) tidak terlihat oleh CI. Membandingkan dengan baseline jumlah per file/per kode TS yang dibekukan (`config/quality/dashboard-typecheck-baseline.json`, pola penegakan kedaluwarsa yang sama seperti `check:known-symbols`) — hanya kesalahan BARU yang melampaui jumlah dalam baseline yang menggagalkan gate; turunkan baseline secara bertahap dengan `--update` ketika kesalahan yang sudah ada diperbaiki. | Ya | + +### Job: `quality-gate` + +Berjalan setelah `test-coverage`. Memblokir penggabungan jika gagal. + +| Skrip | Memvalidasi | Memblokir | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `quality:collect` | Menghasilkan `quality-metrics.json` (jumlah peringatan ESLint, cakupan dari laporan shard gabungan) | Ya (sebelum ratchet) | +| `quality:ratchet` | Setiap metrik dalam `quality-baseline.json` tidak mengalami regresi (peringatan ESLint ≤ baseline; cakupan ≥ baseline) | Ya | +| `check:duplication` | Duplikasi kode (jscpd@4) tidak melebihi baseline dalam `quality-baseline.json` | Ya | +| `check:complexity` | Kompleksitas siklomatik tingkat file tidak melebihi batas (aturan inti ESLint `complexity` + `max-lines-per-function`) | Ya | +| `check:cognitive-complexity` | Ratchet kompleksitas kognitif (`eslint-plugin-sonarjs`) — lintasan ESLint terpisah; CI menjalankan keduanya yang digabung sebagai satu langkah `check:complexity-ratchets` | Ya | +| `check:dead-code` | Ratchet ekspor/file yang tidak digunakan (knip) tidak mengalami regresi dibandingkan baseline | Ya | +| `check:compression-budget` | Anggaran benchmark kompresi — batas minimum penghematan token per mesin tidak boleh mengalami regresi | Ya | +| `check:type-coverage` | Ratchet persentase kode bertipe (`type-coverage`) tidak mengalami regresi; sebagian besar mencakup `typecheck:noimplicit:core` | Ya | +| `check:codeql-ratchet` | Jumlah peringatan CodeQL yang terbuka tidak mengalami regresi (dibaca melalui `gh api`; dilewati secara anggun tanpa token) — frekuensi pembaruan dan pemicu manual: lihat "Ratchet CodeQL" di bawah | Ya | ### Job: `quality-extended` -Seluruh job bersifat anjuran (`continue-on-error: true`). Ratchet berbasis npm benar-benar -dijalankan; pemindai eksternal diinstal melalui `gh release download` dan melewati pemeriksaan -secara mandiri (exit 0) ketika biner masih tidak tersedia. +Seluruh job bersifat sebagai saran (`continue-on-error: true`). Ratchet berbasis npm benar-benar +dijalankan; pemindai eksternal diinstal melalui `gh release download` dan melewati prosesnya sendiri (exit 0) +ketika biner masih tidak tersedia. -| Skrip | Memvalidasi | Memblokir | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| `check:circular-deps` | Tidak ada dependensi sirkular (dpdm) | **Anjuran** | -| `check:bundle-size` | Ukuran bundle tidak melebihi batas | **Anjuran** | -| `check:secrets` | Pemindaian rahasia (gitleaks) — dilewati jika biner tidak tersedia | **Anjuran** | -| `check:vuln-ratchet` | Kerentanan dependensi (osv-scanner) tidak mengalami regresi — dilewati jika biner tidak tersedia | **Anjuran** | -| `check:workflows` | Lint workflow (actionlint + zizmor); pemindai yang hilang/rusak, laporan yang tidak valid, atau baseline ratchet yang tidak tersedia akan gagal sebagai INCOMPLETE. Temuan yang valid mengikuti kebijakan ketat/anjuran/ratchet yang dipilih | Eksekusi wajib; ratchet zizmor memblokir di CI | -| `check:openapi-breaking` | Perubahan yang merusak kontrak API publik (`openapi.yaml`) dibandingkan dengan branch dasar (oasdiff) — menghasilkan `openapiBreaking=N`; dilewati jika oasdiff tidak tersedia atau spesifikasi dasar tidak dapat di-resolve | **Anjuran** | +| Skrip | Memvalidasi | Memblokir | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | +| `check:circular-deps` | Tidak ada dependensi melingkar (dpdm) | **Saran** | +| `check:bundle-size` | Ukuran bundle tidak melebihi batas | **Saran** | +| `check:secrets` | Pemindaian rahasia (gitleaks) — dilewati jika biner tidak tersedia | **Saran** | +| `check:vuln-ratchet` | Kerentanan dependensi (osv-scanner) tidak mengalami regresi — dilewati jika biner tidak tersedia | **Saran** | +| `check:workflows` | Lint alur kerja (actionlint + zizmor); pemindai yang tidak tersedia/rusak, laporan tidak valid, atau baseline ratchet yang tidak tersedia akan gagal sebagai INCOMPLETE. Temuan yang valid mengikuti kebijakan ketat/saran/ratchet yang dipilih | Eksekusi diwajibkan; ratchet zizmor memblokir di CI | +| `check:openapi-breaking` | Perubahan yang merusak kontrak API publik (`openapi.yaml`) dibandingkan cabang dasar (oasdiff) — menghasilkan `openapiBreaking=N`; dilewati jika oasdiff tidak tersedia atau spesifikasi dasar tidak dapat diresolusi | **Saran** | ### Job: `docs-sync-strict` @@ -169,67 +170,67 @@ Dijalankan pada setiap PR ke `main`. Memblokir penggabungan jika gagal. | Skrip | Memvalidasi | Memblokir | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | -| `check:docs-all` | Gerbang meta yang menjalankan 6 subgerbang di bawah ini secara berurutan | Ya | +| `check:docs-all` | Meta-gate yang menjalankan 6 sub-gate di bawah ini secara berurutan | Ya | | ↳ `check:docs-sync` | Konsistensi versi CHANGELOG / OpenAPI / llm.txt | Ya | | ↳ `check:docs-counts` | Jumlah dalam prosa (jumlah penyedia, jumlah migrasi, dll.) berada dalam rentang ratchet dari jumlah sebenarnya | Ya | -| ↳ `check:env-doc-sync` | Setiap variabel lingkungan dalam `.env.example` didokumentasikan dalam tabel dokumentasi, dan sebaliknya | Ya | +| ↳ `check:env-doc-sync` | Setiap env var dalam `.env.example` didokumentasikan dalam tabel dokumentasi, dan sebaliknya | Ya | | ↳ `check:deprecated-versions` | Tidak ada string versi yang sudah tidak digunakan lagi dalam dokumentasi | Ya | -| ↳ `check:doc-links` | Tautan markdown internal dalam dokumentasi mengarah ke file nyata (format `[text]`/`(path)`) | Ya | -| ↳ `check:fabricated-docs` | Rute, variabel lingkungan, perintah CLI, nama hook, dan jalur file yang disebutkan dalam dokumentasi ada di basis kode. Gerbang keras melalui `--strict`; gagal lunak tanpa flag. | Ya (melalui `--strict` di CI) | -| `check:cli-i18n` | String perintah CLI tersedia dalam semua file locale i18n | Ya | -| `check:openapi-coverage` | Spesifikasi OpenAPI mencakup setidaknya batas minimum yang diratchet dari rute nyata | Ya | +| ↳ `check:doc-links` | Tautan markdown internal dalam dokumentasi mengarah ke file yang benar-benar ada (format `[text]`/`(path)`) | Ya | +| ↳ `check:fabricated-docs` | Rute, env var, perintah CLI, nama hook, dan jalur file yang disebutkan dalam dokumentasi benar-benar ada dalam basis kode. Gate ketat melalui `--strict`; gagal lunak tanpa flag. | Ya (melalui `--strict` di CI) | +| `check:cli-i18n` | String perintah CLI tersedia di semua file locale i18n | Ya | +| `check:openapi-coverage` | Spesifikasi OpenAPI mencakup setidaknya batas minimum rute nyata yang telah di-ratchet | Ya | | `check:openapi-security-tiers` | Anotasi tingkat keamanan dalam `openapi.yaml` konsisten dengan klasifikasi `routeGuard.ts` | **Rekomendasi** | -| `check:openapi-routes` | Setiap path dalam `openapi.yaml` mengarah ke `route.ts` yang nyata (antihalusinasi) | Ya | -| `check:docs-symbols` | Setiap referensi `/api/...` dalam `docs/**/*.md` mengarah ke `route.ts` yang nyata (antihalusinasi) | Ya | -| `i18n translation drift` | Key yang belum diterjemahkan dalam file locale i18n — hanya peringatan | **Rekomendasi** | +| `check:openapi-routes` | Setiap path dalam `openapi.yaml` mengarah ke `route.ts` yang benar-benar ada (anti-halusinasi) | Ya | +| `check:docs-symbols` | Setiap referensi `/api/...` dalam `docs/**/*.md` mengarah ke `route.ts` yang benar-benar ada (anti-halusinasi) | Ya | +| `i18n translation drift` | Kunci yang belum diterjemahkan dalam file locale i18n — hanya peringatan | **Rekomendasi** | ### Job: `i18n-ui-coverage` | Skrip | Memvalidasi | Memblokir | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (inline) | Cakupan key i18n UI adalah ≥ 65% | Ya | -| `check-ui-value-drift` (inline) | **Nilai** bahasa Inggris yang ditulis ulang tidak menyisakan terjemahan usang | Ya | -| `check-new-key-coverage` (inline) | **Key** bahasa Inggris baru diterjemahkan dalam setiap locale — penanda `__MISSING__:` akan ditolak | Ya | +| `check-ui-keys-coverage` (inline) | Cakupan kunci i18n UI adalah ≥ 65% | Ya | +| `check-ui-value-drift` (inline) | **Nilai** bahasa Inggris yang ditulis ulang tidak meninggalkan terjemahan usang | Ya | +| `check-new-key-coverage` (inline) | Kunci bahasa Inggris **baru** diterjemahkan di setiap locale — penanda `__MISSING__:` ditolak | Ya | | `check-translation-ratio` | Rasio terjemahan nyata per locale (sama dengan bahasa Inggris / placeholder / entri yang hilang di luar daftar yang diizinkan) tidak boleh melebihi `config/quality/i18n-translation-baseline.json` + toleransi | **Rekomendasi** | -Memerlukan `fetch-depth: 0` — gerbang value-drift membandingkan perbedaan `en.json` terhadap basis penggabungan. +Memerlukan `fetch-depth: 0` — gate penyimpangan nilai membandingkan diff `en.json` terhadap basis penggabungan. -#### `check-ui-value-drift` — gerbang terjemahan usang +#### `check-ui-value-drift` — gate terjemahan usang -Menangkap satu regresi i18n yang secara struktural tidak dapat dideteksi oleh gerbang lainnya: sebuah nilai bahasa Inggris +Menangkap satu regresi i18n yang secara struktural tidak dapat dilihat oleh gate lain: sebuah nilai bahasa Inggris ditulis ulang dan terjemahan yang berasal dari bahasa Inggris _sebelumnya_ tetap tertinggal, sehingga -pengguna non-Inggris terus membaca teks yang terdengar meyakinkan, tetapi kini keliru. +pengguna non-Inggris terus membaca teks yang terdengar meyakinkan, tetapi kini salah. -Ini benar-benar pernah dirilis. `oauthModal.googleOAuthWarning` ditulis ulang ketika pembantu login -Antigravity diluncurkan (#5203); **39 dari 43 locale** tetap menyimpan teks yang menginstruksikan operator untuk "menyalin +Ini benar-benar pernah dirilis. `oauthModal.googleOAuthWarning` ditulis ulang ketika helper login Antigravity +ditambahkan (#5203); **39 dari 43 locale** mempertahankan teks yang memberi tahu operator untuk "menyalin URL lengkap dan menempelkannya di bawah" — alur yang tidak dapat diselesaikan untuk penyedia tersebut. Hal ini -tidak terdeteksi hingga #8463 karena: +tidak diketahui hingga #8463 karena: -- `sync-ui-keys` hanya mengisi ulang key yang **tidak ada**, tidak pernah key yang **usang**; -- `check-ui-keys-coverage` menghitung _keberadaan_ key, sehingga terjemahan usang dianggap tercakup; -- `check-translation-drift` melacak cerminan dokumentasi `docs/i18n//**.md` — +- `sync-ui-keys` hanya mengisi ulang kunci yang **tidak ada**, bukan yang **usang**; +- `check-ui-keys-coverage` menghitung _keberadaan_ kunci, sehingga terjemahan usang dianggap telah tercakup; +- `check-translation-drift` melacak mirror dokumentasi `docs/i18n//**.md` — skrip ini tidak pernah membaca `src/i18n/messages/*.json`. Memblokir dalam job `docs-sync-strict` sejak - sinkronisasi ulang 2026-09: edit dokumen inti → `npm run i18n:run -- --files=` (per bagian, ringan). + sinkronisasi ulang 2026-09: edit dokumen inti → `npm run i18n:run -- --files=` (tingkat bagian, ringan). -**Peka terhadap diff, bukan ditopang baseline.** Pemeriksaan ini membandingkan `en.json` pada basis penggabungan dengan -working tree; untuk setiap kunci yang nilai bahasa Inggrisnya berubah, locale yang masih memiliki -terjemahan yang belum diubah dianggap kedaluwarsa. Hal ini sengaja **membekukan utang yang sudah ada** — sebuah diff -tidak dapat mengungkapkan dari teks bahasa Inggris lama mana suatu terjemahan yang sudah lama ada berasal, sehingga pemeriksaan -hanya menilai apa yang disentuh oleh perubahan saat ini. Alternatifnya (baseline hash per kunci) akan membutuhkan +**Peka terhadap diff, bukan berbasis baseline.** Pemeriksaan ini membandingkan `en.json` pada basis penggabungan dengan +pohon kerja; untuk setiap kunci yang nilai bahasa Inggrisnya berubah, locale mana pun yang masih menyimpan +terjemahan yang belum disentuh dianggap usang. Ini sengaja **membekukan utang yang sudah ada** — sebuah diff +tidak dapat menunjukkan dari teks bahasa Inggris lama mana suatu terjemahan yang telah lama ada berasal, sehingga pemeriksaan +hanya menilai apa yang disentuh oleh perubahan saat ini. Alternatifnya (baseline hash per kunci) akan memerlukan file hasil generasi berukuran ~600 KB, 3× lebih besar daripada baseline terbesar yang ada, dan berubah pada setiap PR i18n. -Dua cara untuk memenuhinya: +Ada dua cara untuk memenuhinya: 1. perbarui terjemahan yang terdampak, atau -2. atur nilainya menjadi `__MISSING__:` — runtime kemudian menyajikan teks bahasa Inggris yang telah diperbaiki - (`src/i18n/request.ts::deepMergeFallback`, #7258), dan kunci tersebut masuk ke antrean penerjemahan. +2. atur nilainya menjadi `__MISSING__:` — runtime kemudian menyajikan teks bahasa Inggris yang telah dikoreksi + (`src/i18n/request.ts::deepMergeFallback`, #7258), dan kunci tersebut masuk antrean untuk diterjemahkan. -Jika **makna** string berubah, sebaiknya **ganti nama kuncinya**: kunci baru tidak dapat mewarisi -terjemahan yang kedaluwarsa. Itulah pola yang digunakan #8463. +Jika **makna** string berubah, sebaiknya **ganti nama kunci**: kunci baru tidak dapat mewarisi +terjemahan yang usang. Itulah pola yang digunakan oleh #8463. ```bash npm run i18n:check-value-drift # ketat (yang dijalankan CI) -npm run i18n:check-value-drift:warn # hanya laporan +npm run i18n:check-value-drift:warn # hanya melaporkan BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` @@ -240,7 +241,7 @@ tanpa ref dasar), mengikuti perilaku `check-openapi-breaking`. Matriks validasi i18n lengkap (satu job per locale). Seluruh job bersifat advisori. -| Skrip | Yang divalidasi | Pemblokiran | +| Skrip | Memvalidasi | Pemblokiran | | ------------------------------- | --------------------------------- | --------------------------------------------------------- | | `validate_translation.py quick` | Kelengkapan terjemahan per locale | **Advisori** (`continue-on-error: true` pada seluruh job) | @@ -248,32 +249,32 @@ Matriks validasi i18n lengkap (satu job per locale). Seluruh job bersifat adviso Hanya dijalankan pada pull request. -| Skrip | Yang divalidasi | Pemblokiran | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | PR yang mengubah kode produksi di `src/`, `open-sse/`, `electron/`, atau `bin/` harus menyertakan atau memperbarui pengujian (Aturan Keras #8) | Ya | -| `check:test-masking` | File pengujian yang diubah tidak mengurangi jumlah asersi bersih atau menambahkan tautologi `assert.ok(true)` | Ya | -| `check:pr-evidence` | Isi PR menyebutkan bukti pengujian/VPS untuk perubahan tersebut (mengotomatiskan Aturan Keras #18 dengan grep pada prosa PR — rapuh, lihat Backlog) | Ya | +| Skrip | Memvalidasi | Pemblokiran | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check:pr-test-policy` | PR yang mengubah kode produksi di `src/`, `open-sse/`, `electron/`, atau `bin/` harus menyertakan atau memperbarui pengujian (Aturan Keras #8) | Ya | +| `check:test-masking` | File pengujian yang diubah tidak mengurangi jumlah bersih assertion atau menambahkan tautologi `assert.ok(true)` | Ya | +| `check:pr-evidence` | Isi PR mencantumkan bukti pengujian/VPS untuk perubahan tersebut (mengotomatiskan Aturan Keras #18 dengan melakukan grep pada prosa PR — rapuh, lihat Backlog) | Ya | ### Job: `test-vitest` Dijalankan setelah `build`. Memblokir penggabungan jika gagal. -| Suite | Yang divalidasi | Pemblokiran | -| ---------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Server MCP (110 alat), autoCombo, cache — runner vitest | Ya | -| `test:vitest:ui` | Pengujian komponen UI — runner vitest | **Memblokir** — kegagalan yang sudah ada secara eksplisit dikecualikan dalam `vitest.config.ts`; kegagalan baru membuat job gagal | +| Suite | Memvalidasi | Pemblokiran | +| ---------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | Server MCP (110 alat), autoCombo, cache — runner vitest | Ya | +| `test:vitest:ui` | Pengujian komponen UI — runner vitest | **Memblokir** — kegagalan yang sudah ada secara eksplisit dikecualikan di `vitest.config.ts`; kegagalan baru membuat job gagal | ### Workflow nightly (terjadwal, advisori) Workflow ini dijalankan berdasarkan jadwal cron (dan `workflow_dispatch`), tidak pernah pada PR. Semuanya bersifat advisori. -| Workflow | Yang divalidasi | Pemblokiran | +| Workflow | Memvalidasi | Pemblokiran | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | | `nightly-property` | Pengujian properti fast-check dengan seed acak + jumlah eksekusi tinggi | **Advisori** | | `nightly-resilience` | Pemeriksaan pertumbuhan heap, injeksi kegagalan chaos, beban/soak k6 | **Advisori** | | `nightly-llm-security` | Perlindungan injeksi promptfoo (mode blokir) + probe garak (dilewati tanpa secret penyedia) | **Advisori** | | `nightly-schemathesis` | Fuzzing kontrak OpenAPI (schemathesis) terhadap OmniRoute aktif menggunakan `docs/openapi.yaml` — mengungkap pelanggaran spesifikasi / 500 yang tidak ditangani (Fase 8 B.4) | **Advisori** | -| `nightly-mutation` | Skor pengujian mutasi Stryker pada jalur unit cepat — mutan yang bertahan mengungkap asersi yang lemah | **Advisori** | +| `nightly-mutation` | Skor pengujian mutasi Stryker pada jalur unit cepat — mutan yang bertahan mengungkap assertion yang lemah | **Advisori** | | `nightly-compat` | Matriks kompatibilitas engine Node di seluruh rentang `engines.node` yang didukung | **Advisori** | --- @@ -539,41 +540,41 @@ kesalahan koneksi dan tidak pernah mengganggu sesi. ## Backlog Rasionalisasi (tinjauan ROI — Fase 9 Gelombang 3) -Inventaris ini direkonsiliasi terhadap `ci.yml` pada 2026-06-17 (versi sebelumnya tidak mencantumkan +Inventaris ini direkonsiliasi dengan `ci.yml` pada 2026-06-17 (versi sebelumnya menghilangkan `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Tinjauan ROI atas set yang telah direkonsiliasi +`check:codeql-ratchet`, `check:pr-evidence`). Tinjauan ROI terhadap kumpulan yang telah direkonsiliasi mengidentifikasi kandidat rasionalisasi berikut. **Penggabungan merupakan perubahan CI -mekanis; pengubahan/penghapusan merupakan keputusan kebijakan yang dicadangkan bagi operator.** Belum ada hal di bawah ini -yang diterapkan. +mekanis; pengubahan/penghapusan merupakan keputusan kebijakan yang diperuntukkan bagi operator.** Belum ada +hal di bawah ini yang diterapkan. **Juga belum didokumentasikan di atas** (bersifat saran, sinyal rendah): job `docs-lint` (markdownlint + Vale, seluruh job menggunakan `continue-on-error`) dan workflow pemindai mandiri -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` terdapat di -`quality-baseline.json`, tetapi tidak terhubung ke ratchet yang memblokir di `ci.yml` — metrik ini +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` terdapat dalam +`quality-baseline.json`, tetapi tidak terhubung ke ratchet pemblokir di `ci.yml` — metrik tersebut saat ini tidak terpakai. ### Gabungkan / deduplikasi (mekanis, risiko lebih rendah) -Setiap kandidat divalidasi terhadap status gate aktif pada 2026-06-17 (percaya, tetapi verifikasi); -beberapa penggabungan yang tampak "jelas" ternyata menyembunyikan utang dan **bukan** pengganti langsung yang bersih. +Setiap kandidat telah divalidasi terhadap status gate aktif pada 2026-06-17 (percaya tetapi tetap verifikasi); +beberapa penggabungan yang tampak "jelas" ternyata menyembunyikan utang dan **bukan** pengganti langsung yang aman. -- **`check:docs-sync` dijalankan dua kali** — secara mandiri di job `lint` dan sekali lagi di dalam `check:docs-all` (`docs-sync-strict`) serta hook pre-commit husky. ✅ **SELESAI** — pemanggilan mandiri di `lint` telah dihapus. -- **Pemindaian CVE** — ❌ **BUKAN penggabungan yang bersih.** `audit:deps` langsung gagal saat menemukan CVE tinggi/kritis apa pun; `check:vuln-ratchet` (osv) hanya gagal jika terjadi _regresi_ terhadap baseline (saat ini 1 MODERATE). Semantiknya berbeda — menghapus `audit:deps` akan menghilangkan gate absolut untuk tingkat tinggi/kritis. Pertahankan keduanya. -- **Deteksi siklus** — ❌ **BUKAN penggabungan yang bersih.** `check:circular-deps` (dpdm) melaporkan **91 siklus** (itulah sebabnya bersifat saran); pemeriksaan ini tidak dapat dipromosikan menjadi pemblokir tanpa menyelesaikan semuanya terlebih dahulu, dan cakupannya lebih luas daripada `check:cycles` terkurasi yang berstatus hijau. Pertahankan `check:cycles` sebagai pemblokir; penyelesaian 91 siklus dpdm merupakan backlog tersendiri. -- **Kompleksitas** — ✅ **SELESAI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): satu kali penelusuran ESLint, menghitung berdasarkan ruleId agar baseline siklomatik+max-lines dan kognitif tetap independen; masing-masing `check:complexity` / `check:cognitive-complexity` dipertahankan untuk `--update` lokal. +- **`check:docs-sync` berjalan dua kali** — secara mandiri dalam job `lint`, lalu kembali di dalam `check:docs-all` (`docs-sync-strict`) dan hook pre-commit husky. ✅ **SELESAI** — pemanggilan mandiri dalam `lint` telah dihapus. +- **Pemindaian CVE** — ❌ **BUKAN penggabungan yang aman.** `audit:deps` langsung gagal jika menemukan CVE high/critical; `check:vuln-ratchet` (osv) hanya gagal jika terjadi _regresi_ dibandingkan baseline (saat ini 1 MODERATE). Semantiknya berbeda — menghapus `audit:deps` akan menghilangkan gate absolut untuk tingkat high/critical. Pertahankan keduanya. +- **Deteksi siklus** — ✅ **SELESAI** (#15159 G-01/G-02). Teks lama di sini menyebut `check:cycles` sebagai gate "hijau dan terkurasi" serta membenarkan untuk mempertahankannya sebagai pemblokir karena `check:circular-deps` (dpdm) melaporkan 91 siklus. Status hijau tersebut merupakan **hijau palsu**: `check:cycles` memindai 5 subdirektori (450 file), hanya mencocokkan `import|export … from` statis, dan membuang setiap specifier `@/` serta `@omniroute/open-sse/`, sehingga tidak dapat mendeteksi siklus dynamic-import + alias yang mendominasi repo. Telah diperbaiki: gate tersebut kini menelusuri `src` + `open-sse` (5023 file), mengumpulkan specifier dari AST TypeScript (sehingga `import("…")` dihitung dan `typeof import("…")` pada posisi tipe tidak dihitung), serta menyelesaikan `paths` tsconfig. Gate tersebut menemukan **14** siklus, bukan 0. Karena 14 siklus yang sudah ada sebelumnya tidak dapat diperbaiki dalam PR gate, `check:cycles` kini menjadi **ratchet** (`--ratchet`, batas atas `metrics.cycles.value = 14` dalam `quality-baseline.json`, `direction: down`) — ratchet tersebut memblokir setiap _regresi_ dan jumlahnya hanya dapat turun. CI menjalankan `npm run check:cycles:ratchet`. Penurunan bertahap dilakukan bersama **A-01**. `check:circular-deps` (dpdm) tetap bersifat saran sebagai opini kedua yang lebih luas. +- **Kompleksitas** — ✅ **SELESAI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): satu penelusuran ESLint, menghitung berdasarkan ruleId agar baseline cyclomatic+max-lines dan cognitive tetap independen; masing-masing `check:complexity` / `check:cognitive-complexity` tetap tersedia untuk `--update` lokal. - **Anti-halusinasi `/api`** — ✅ **SELESAI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): satu inventaris FS untuk `src/app/api`, openapi-routes + docs-symbols tetap melaporkan secara independen; masing-masing tetap tersedia untuk eksekusi lokal. -- **`check:node-runtime` dijalankan di 11 job** — ⚠️ **ROI rendah.** Masing-masing menggunakan runner terpisah dan pemeriksaannya berlangsung <1 dtk; total penghematan ~10 dtk, dengan konsekuensi kehilangan pengaman per-job yang murah. Tidak sepadan dengan perubahan yang diperlukan. -- **`typecheck:noimplicit:core` pada lint CI** — ✅ **dihapus dari job lint** (sebelumnya bersifat saran dengan `continue-on-error`); permukaan tipe yang memblokir adalah `typecheck:core` + `check:type-coverage`. Skrip lokal dipertahankan. +- **`check:node-runtime` berjalan dalam 11 job** — ⚠️ **ROI rendah.** Masing-masing menggunakan runner terpisah dan pemeriksaannya berlangsung <1 detik; total penghematan ~10 detik, dengan konsekuensi kehilangan pengaman murah per job. Tidak sepadan dengan perubahan yang ditimbulkan. +- **`typecheck:noimplicit:core` pada lint CI** — ✅ **dihapus dari job lint** (sebelumnya bersifat saran dengan `continue-on-error`); permukaan tipe pemblokir adalah `typecheck:core` + `check:type-coverage`. Skrip lokal dipertahankan. ### Ubah / putuskan (kebijakan operator) -- `check:openapi-security-tiers` (bersifat saran) — ❌ **TIDAK dapat diubah secara langsung dengan aman.** Pemeriksaan ini keluar dengan kode 0, tetapi memperingatkan bahwa beberapa route `traffic-inspector` di bawah `LOCAL_ONLY_API_PREFIXES` tidak memiliki anotasi `x-loopback-only: true`. Penerapannya memerlukan penambahan anotasi tersebut ke `openapi.yaml` terlebih dahulu. -- `typecheck:noimplicit:core` (bersifat saran) — sebagian besar telah tercakup oleh ratchet `check:type-coverage` yang memblokir. Ubah menjadi ratchet atau hapus pass `tsc` kedua yang redundan. -- `test:vitest:ui` (sekarang **memblokir**) — kegagalan yang sudah ada secara eksplisit dikecualikan di `vitest.config.ts` dengan komentar pelacakan `// #8618`; kegagalan baru akan menggagalkan job. -- `check:secrets` (gitleaks, ratchet pemblokir yang dibekukan pada 3 positif palsu terdokumentasi) — masukkan ketiganya ke allowlist agar mencapai 0, atau turunkan menjadi bersifat saran. Tumpang tindih dengan pemindaian rahasia bawaan GitHub + `check:public-creds`. -- `check:pr-evidence` (memblokir, menggunakan grep pada prosa isi PR) — berisiko tinggi menghasilkan positif palsu; menghapusnya akan melemahkan penegakan Aturan Keras #18, sehingga ini benar-benar merupakan keputusan kebijakan. -- `semgrep` (pemindai mandiri yang bersifat saran) — tumpang tindih dengan CodeQL untuk kelompok OWASP; hubungkan baseline-nya ke ratchet atau hapus. +- `check:openapi-security-tiers` (bersifat saran) — ❌ **TIDAK dapat langsung diubah dengan aman.** Pemeriksaan ini keluar dengan kode 0, tetapi memperingatkan bahwa beberapa rute `traffic-inspector` di bawah `LOCAL_ONLY_API_PREFIXES` tidak memiliki anotasi `x-loopback-only: true`. Penerapannya sebagai kewajiban mengharuskan anotasi tersebut ditambahkan ke `openapi.yaml` terlebih dahulu. +- `typecheck:noimplicit:core` (bersifat saran) — sebagian besar telah tercakup oleh ratchet pemblokir `check:type-coverage`. Ubah menjadi ratchet atau hapus lintasan `tsc` kedua yang redundan. +- `test:vitest:ui` (sekarang **memblokir**) — kegagalan yang sudah ada sebelumnya secara eksplisit dikecualikan dalam `vitest.config.ts` dengan komentar pelacakan `// #8618`; kegagalan baru akan menggagalkan job. +- `check:secrets` (gitleaks, ratchet pemblokir yang dibekukan pada 3 false-positive terdokumentasi) — masukkan ketiganya ke allowlist agar mencapai 0, atau turunkan menjadi bersifat saran. Tumpang tindih dengan pemindaian secret bawaan GitHub + `check:public-creds`. +- `check:pr-evidence` (memblokir, melakukan grep terhadap prosa isi PR) — risiko false-positive tinggi; penghapusannya akan melemahkan penegakan Hard Rule #18, sehingga ini benar-benar merupakan keputusan kebijakan. +- `semgrep` (mandiri dan bersifat saran) — tumpang tindih dengan CodeQL untuk kelompok OWASP; hubungkan baseline-nya ke ratchet atau hapus. --- diff --git a/docs/i18n/ig/CONTRIBUTING.md b/docs/i18n/ig/CONTRIBUTING.md index df500a9b802..ba412c32ec5 100644 --- a/docs/i18n/ig/CONTRIBUTING.md +++ b/docs/i18n/ig/CONTRIBUTING.md @@ -399,22 +399,22 @@ Dee unit tests na `tests/unit/` nke ga-ekpuchi ma ọ dịkarịa ala: --- -## Ndepụta Nnyocha Pull Request +## Ndepụta Nlele Pull Request -- [ ] Tests gafere (`npm test`) +- [ ] Nnwale gafere (`npm test`) - [ ] Linting gafere (`npm run lint`) -- [ ] Build gara nke ọma (`npm run build`) -- [ ] Agbakwunyere ụdị TypeScript maka functions na interfaces ọhaneze ọhụrụ -- [ ] Enweghị secrets ma ọ bụ fallback values e dere ozugbo na koodu -- [ ] E tinyere public upstream credentials site na `resolvePublicCred()` (lee [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ọ bụghị dịka literals -- [ ] Error responses na-agafe na `buildErrorBody()` / `sanitizeErrorMessage()` — enweghị raw stack traces n'ime response bodies (lee [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell commands (`exec` / `spawn`) na-ebufe runtime values site na `env`, ọ bụghị site na string interpolation -- [ ] E ji Zod schemas nyochaa inputs niile -- [ ] Agbakwunyere **fragment** changelog n'okpuru `changelog.d/{features|fixes|maintenance}/-.md` maka mgbanwe ndị users ga-ahụ (lee [`changelog.d/README.md`](./changelog.d/README.md)) — **edezigharịla** `CHANGELOG.md` ozugbo; a na-achịkọta fragments n'oge release, ha anaghịkwa enwe conflict n'etiti PRs -- [ ] Emelitere documentation (ọ bụrụ na ọ dị mkpa) -- [ ] Enweghị alerts ọhụrụ nke CodeQL / Secret-Scanning e mepere, ma ọ bụ a kagburu nke ọ bụla site na technical justification nke na-ezo aka na doc kwesịrị ekwesị dị na `docs/security/` -- [ ] Routes ndị na-emepụta child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) ka e kewara dịka `isLocalOnlyPath()` na `src/server/authz/routeGuard.ts` — lee [Iwu Siri Ike #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Enweghị trailers `Co-Authored-By` n'ime commit messages — commits ga-apụta naanị n'okpuru Git identity nke onye nwe repository (Iwu Siri Ike #16) +- [ ] Nrụpụta gara nke ọma (`npm run build`) +- [ ] Agbakwunyere ụdị TypeScript maka ọrụ na interface ọhụụ ndị ọha na-eji +- [ ] Enweghị ihe nzuzo ma ọ bụ fallback values e dere kpọmkwem n'ime koodu +- [ ] E tinyere credentials ọha nke upstream site na `resolvePublicCred()` (lee [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ọ bụghị dị ka literals +- [ ] Nzaghachi njehie na-agafe na `buildErrorBody()` / `sanitizeErrorMessage()` — enweghị raw stack traces n'ime response bodies (lee [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Iwu shell (`exec` / `spawn`) na-ebufe runtime values site na `env`, ọ bụghị site na string interpolation +- [ ] E jiri Zod schemas nyochaa inputs niile +- [ ] Agbakwunyere **fragment** nke changelog n'okpuru `changelog.d/{features|fixes|maintenance}/-.md` maka mgbanwe ndị ọrụ ga-ahụ (lee [`changelog.d/README.md`](./changelog.d/README.md)) — **edezila** `CHANGELOG.md` ozugbo; a na-achịkọta fragments n'oge release, ha anaghịkwa enwe esemokwu n'etiti PR dị iche iche +- [ ] Emelitere documentation (ma ọ bụrụ na ọ dị mkpa) +- [ ] Enweghị alerts ọhụrụ nke CodeQL / Secret-Scanning e mepere, ma ọ bụ a kagburu nke ọ bụla site na technical justification nke na-arụtụ aka na doc kwesịrị ekwesị dị na `docs/security/` +- [ ] E kọwara routes ndị na-amalite child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) dị ka `isLocalOnlyPath()` n'ime `src/server/authz/routeGuard.ts` — lee [Iwu Siri Ike #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Enweghị trailers AI/bot `Co-authored-by` n'ime commit messages (Iwu Siri Ike #16) — a na-enye ndị mmadụ rụkọrọ ọrụ, ndị e ji ọrụ ha mee ihe ọzọ, otuto site na trailers ọkọlọtọ `Co-authored-by: Name ` --- diff --git a/docs/i18n/ig/docs/architecture/QUALITY_GATES.md b/docs/i18n/ig/docs/architecture/QUALITY_GATES.md index f6f0bece8bb..e95389496cd 100644 --- a/docs/i18n/ig/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ig/docs/architecture/QUALITY_GATES.md @@ -17,262 +17,262 @@ nke otu sistemụ ahụ na-adabereghị na ngwá ọrụ ọ bụla, lee ## Ndepụta ọnụ ụzọ na profaịlụ mmezu -### Ịnabata onye a na-atụle - -Usoro ọrụ CI na Quality Gates na-ewepụta mkpebi kwụsiri ike nke ọ bụla: `Gate / CI` na -`Gate / Quality`. Iwu nnabata ha nwere ụdị e depụtara na-akọwa ọrụ niile dị n'elu -dị ka nke achọrọ ma ọ bụ nke ndụmọdụ. Ọrụ achọrọ nke metụtara ga-aga nke ọma: nsonaazụ -na-efu efu, nke a kagburu, nke a mafere, nke ka na-eche, na nke a na-amaghị enweghị ike igosi PASS. Nkewa ziri ezi -nke naanị docs ma ọ bụ naanị catalog nwere ike ime ka ụzọ code ghara ịdị mkpa; -a naghị anabata PR nke bụ draft dị ka onye a na-atụle. Label `hotfix` anaghị ewepụ mkpa ihe akaebe. - -Usoro ọrụ abụọ ahụ na-ekpuchi PR na push gaa na branch main/release, dispatch e ji aka mee na -event merge-group. Push, dispatch na merge-group na-eme nhọrọ zuru ezu. Fork -na merge group na-eji runner ndị a na-akwado n'ebe ọzọ maka ọrụ ndị gaara ahọrọ runner -nke a na-akwado n'onwe ya; a ga-enyocha na ikike runner ndị a na-akwado n'ebe ọzọ zuru oke tupu rollout. - -Receipt JSON ọ bụla na-akọwapụta SHA e checkout-rị, workflow run na attempt. -CLI na-ajụ ma SHA nke checkout na event ekwekọghị. Nnwale workflow na-ejikọta ịbụ onye otu policy -na ndepụta `needs` nke ọrụ verdict ka lane ọhụrụ ma ọ bụ nke ewepụrụ ghara ịla n'iyi n'amaghị ama. -Receipt ndị ahụ na-ekpuchi workflow nke ha, ọ bụghị publication, deployment, ma ọ bụ ihe ime -nke advisory scanner dị adị. Ime ka aha check abụọ ahụ rụọ ọrụ na branch rules bụ +### Nnabata onye a na-atụle + +Usoro ọrụ CI na Quality Gates ọ bụla na-ewepụta mkpebi kwụsiri ike: `Gate / CI` na +`Gate / Quality`. Iwu nnabata ha nwere ụdị mbipụta na-edepụta ọrụ upstream ọ bụla +dị ka nke a chọrọ ma ọ bụ nke ndụmọdụ. Ọrụ a chọrọ nke metụtara ọnọdụ ahụ ga-aga nke ọma: nsonaazụ +na-efu efu, a kagburu, a mafere, ka na-echere na nke amaghị enweghị ike igosi PASS. Nhazi ziri ezi +nke docs-only ma ọ bụ catalog-only nwere ike ime ka lane koodu ghara ịdị mkpa; +draft PR abụghị onye a na-anabata. Label `hotfix` anaghị ewepụ mkpa ihe akaebe. + +Usoro ọrụ abụọ ahụ na-ekpuchi PR na push gaa na ngalaba main/release, dispatch nke aka na +mmemme merge-group. Push, dispatch na merge-group na-eme nhọrọ zuru ezu. Fork +na merge group na-eji hosted runners maka ọrụ ndị gaara ahọrọ self-hosted +runners; a ga-enyocha na hosted capacity zuru oke tupu rollout. + +Receipt JSON ọ bụla na-akọwa SHA nke checkout, workflow run na attempt. +CLI na-ajụ ma SHA checkout/event ekwekọghị. Nnwale workflow na-ejikọta ndị otu policy +na ndepụta `needs` nke ọrụ mkpebi ka lane ọhụrụ ma ọ bụ nke ewepụrụ ghara ịpụ n'amaghị ama. +Receipt ndị ahụ na-ekpuchi workflow nke ha, ọ bụghị publication, deployment, ma ọ bụ ihe ndị dị n'ime +advisory scanner dị ugbu a. Ime ka aha check abụọ ahụ rụọ ọrụ na branch rules bụ mgbanwe nchịkwa dị iche; ịgbakwunye ọrụ ndị a anaghị echebe branch n'onwe ya. ### Ndepụta static scan -Ndepụta npm-alias nwere ụdị e depụtara na ịbụ onye otu static-scan dị na +Ndepụta npm-alias nwere ụdị mbipụta na ndị otu static-scan dị na `config/quality/gate-manifest.json`. Gbaa `npm run check:gate-manifest` iji nyochaa aha script na command ndị kpọmkwem megide `package.json`; mgbakwunye, mwepụ na -mgbanwe command na-eme ka ma hook mpaghara ma ọrụ change-classification dị na CI daa. -Alias abụghị workflow job, matrix instance ma ọ bụ test case: a gaghị egosi ọnụ ọgụgụ ndị a -dị ka ihe ndị nwere ike dochie ibe ha. +mgbanwe command na-eme ka ma local hook ma ọrụ nhazi mgbanwe dị na CI daa. +Alias abụghị ọrụ workflow, matrix instance ma ọ bụ test case: a gaghị +egosi ọnụ ọgụgụ ndị a dịka ihe ndị nwere ike dochie ibe ha. Jiri `npm run quality:scan -- --list` ma ọ bụ `npm run quality:scan:fast -- --list` -iji nyochaa alias ndị ahọrọghị n'emeghị ha. Runner na-akpọ +iji nyochaa alias ndị ahọpụtara n'emeghị ha. Runner na-akpọ npm entrypoint, ya mere a na-echekwa runtime ya (gụnyere Bun ebe ahaziri ya). -Manifest na-edekọ alias ndị na-adịghị na profaịlụ ndị ahụ dị ka ndị a na-akpọ iche, a machibidoro -maintenance command na profaịlụ scan nke bụ read-only. +Manifest na-edekọ alias ndị na-anọghị na profaịlụ ndị ahụ dịka ndị a na-akpọ iche, ma +a machibidoro maintenance commands na profaịlụ scan nke read-only. -Profaịlụ ndị a na-ekpuchi naanị static scan. Ha anaghị akwado product test, -coverage, packaging, external check ma ọ bụ nnabata release zuru ezu nke onye a na-atụle. +Profaịlụ ndị a na-ekpuchi naanị static scan. Ha anaghị akwado product tests, +coverage, packaging, external checks ma ọ bụ nnabata release zuru ezu nke onye a na-atụle. Nnabata workflow na-eji `config/quality/admission-policy.json` ejikọrọ na `scripts/quality/admission-verdict.mjs`. Profaịlụ release-observer ka dị iche; -nyochaa check na receipt ndị metụtara ha n'onwe ha. Ndepụta e dere n'okpuru -bụ ntụaka, ọ bụghị ihe akaebe na gate gara n'ezie. - -Script dị n'okpuru `scripts/check/` (policy gate) na `scripts/quality/` (ratchet engine). -Ebe eziokwu CI si abịa bụ `.github/workflows/ci.yml`. - -### Ụzọ ngwa ngwa nke Release PR (`quality.yml`) - -`.github/workflows/quality.yml` na-agbakwụnye CI maka PR main/release, push -gaa na protected-branch, dispatch na merge group. PR na-eji fast check a na-enyocha site na path. E wepụrụ duplicate build -a gbanyụrụ kpamkpam; ezigbo check build/package/boot ka dị na CI. - -| Ọrụ | Oke | Na-egbochi | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | PR docs/code; ntụaka API docs na docs-all | Ee | -| `Fast Quality Gates` | PR code; static check, typecheck, dashboard typecheck, unit test ndị mgbanwe metụtara | Ee | -| `Forgotten sibling tests` | PR code; module gbanwere ndị a soro ruo static consumer na candidate sibling test; a na-akọ path barrel na dynamic-import dị ka nchọpụta ndụmọdụ, tinyere allowlist exception ndị e zoro aka na ha | **Ndụmọdụ** | -| `Vitest (fast-path)` | PR code; vitest suite ngwa ngwa | Ee | -| `Unit Tests fast-path` | PR code; unit suite nwere shard 4 | Ee | -| `No new ESLint warnings` | PR code; lint guard maara suppression | Ee, gụnyere fork | -| `Merge integrity (changelog + generated skills)` | PR na-abụghị draft; changelog na mmekọrịta generated skill | Ee, gụnyere fork | - -#### Akụkọ forgotten sibling tests - -`npm run check:forgotten-sibling-tests` na-eji ọzọ import resolver dị n'azụ map test-impact. -Maka production module ọ bụla gbanwere, ọ na-akọ chain ndị a pụrụ ikwughachi n'otu usoro -`changed module/symbol -> static consumer -> candidate sibling test` mgbe candidate -test adịghị na diff pull-request. A na-edobe nchịkọta Markdown na nsonaazụ JSON dị ka -artifact workflow `forgotten-sibling-tests` maka calibration tupu rollout ọ bụla na-egbochi. - -Mbupụgharị site na barrel na mbubata dynamic bụ naanị maka nchọpụta nsogbu resolution; ha anaghị emepụta -nchọpụta na-egbochi ihe. Mwepu ndị enyochara dị na +nyochaa check na receipt ndị metụtara ha n'onwe ha. Ndepụta nkọwa +dị n'okpuru bụ ntụaka, ọ bụghị ihe akaebe na gate gbara ọsọ n'ezie. + +Script dị n'okpuru `scripts/check/` (policy gates) na `scripts/quality/` (ratchet engine). +Isi mmalite eziokwu nke CI bụ `.github/workflows/ci.yml`. + +### Ụzọ-ngwa-ngwa maka Release PR (`quality.yml`) + +`.github/workflows/quality.yml` na-emeju CI na main/release PR, push gaa na protected-branch, +dispatch na merge group. PR na-eji fast checks nke path-filtered. E wepụrụ duplicate build +nke agbanyụrụ kpamkpam; ezigbo check build/package/boot ka dị na CI. + +| Ọrụ | Oke | Na-egbochi | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `Docs Gates (fast-path)` | PR docs/koodu; ntụaka docs API na docs-all | Ee | +| `Fast Quality Gates` | PR koodu; static checks, typecheck, dashboard typecheck, unit tests ndị mgbanwe metụtara | Ee | +| `Forgotten sibling tests` | PR koodu; a na-esochi module gbanwere ruo static consumers na candidate sibling tests; a na-akọ ụzọ barrel na dynamic-import dịka advisory diagnostics, tinyere mwepu allowlist ndị e zoro aka na ha | **Ndụmọdụ** | +| `Vitest (fast-path)` | PR koodu; fast vitest suite | Ee | +| `Unit Tests fast-path` | PR koodu; unit suite nwere shard 4 | Ee | +| `No new ESLint warnings` | PR koodu; lint guard na-eburu suppressions n'uche | Ee, gụnyere fork | +| `Merge integrity (changelog + generated skills)` | PR ndị na-abụghị draft; mmekọrịta changelog na generated skill | Ee, gụnyere fork | + +#### Akụkọ Forgotten sibling tests + +`npm run check:forgotten-sibling-tests` na-eji ọzọ import resolver dị n'azụ test-impact map. +Maka production module ọ bụla gbanwere, ọ na-akọ usoro +`changed module/symbol -> static consumer -> candidate sibling test` ndị na-agbanweghi agbanwe mgbe candidate +test adịghị na diff nke pull-request. A na-edobe nchịkọta Markdown na nsonaazụ JSON dịka +workflow artifact `forgotten-sibling-tests` maka calibration tupu rollout ọ bụla na-egbochi ihe. + +Mbugharị-ọpụpụ barrel na mbubata dynamic bụ naanị nyocha mkpebi ụzọ; ha anaghị emepụta +nchọpụta na-egbochi ihe. Ewezuga ndị a nyochara dị na `config/quality/forgotten-sibling-allowlist.json`. Ntinye ọ bụla ga-akpọrịrị consumer na candidate -test aha, nye ezi ihe kpatara ya kpọmkwem, ma jikọọ GitHub issue ma ọ bụ pull request. Ntinye ndị ahazighị nke ọma na-eme ka -usoro mechie. Mwepu enweghị ike izochi candidate test ehichapụrụ ma ọ bụ diff nke na-agbakwunye `.skip`/`.todo`; -ime ka assertion ghara isi ike na ụdị izochi ndị ọzọ ka bụ ọrụ nke gate -`check:test-masking` nke na-egbochi ihe n'onwe ya. +test aha, nye ihe kpatara ya kpọmkwem, ma jikọọ na GitHub issue ma ọ bụ pull request. Ntinye ndị ahazighị +nke ọma na-ada n'ọnọdụ mechiri emechi. Ewezuga enweghị ike izochi candidate test ehichapụla ma ọ bụ diff na-agbakwunye `.skip`/`.todo`; +ime ka assertion ghara isi ike na ụdị nzuzo ndị ọzọ ka bụ ọrụ nke gate +`check:test-masking` nke na-egbochi n'onwe ya. ### Ọrụ: `lint` -Ọ na-agba na PR ọ bụla gaa na `main`. Ọ na-egbochi merge ma ọ bụrụ na ọ daa. - -| Script (`npm run ...`) | Ihe ọ na-enyocha | Na-egbochi | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Ụdị Node.js dị n'ime oke ndị a na-akwado | Ee | -| `check:cycles` | Mbubata ndị na-eme okirikiri — modul `src/` + `open-sse/` niile | Ee | -| `check:route-validation:t06` | Zod schemas dị na route niile (amụma Tier 6) | Ee | -| `check:any-budget:t11` | Ọnụọgụ `@ts-expect-error // any` anaghị agafe budget (catraca Tier 11) | Ee | -| `check:provider-consistency` | Provider ọ bụla dị na `providers.ts` nwere ndenye kwekọrọ na ya na `providerRegistry.ts` (otu ahụkwa n’aka nke ọzọ, n’ime allowlist) | Ee | -| `check:model-lifecycle` | Tebụl routing atọ a na-eji aka elekọta na-anọgide kwekọọ na lifecycle snapshot echekwara n’ime repo (#11503): `FITNESS_TABLE` (`taskFitness.ts`) anaghị enye retired id ọ bụla `REGISTRY` nwere ike iziga akara; target ọ bụla nke `BUILT_IN_ALIASES` dị na `REGISTRY` ma ọ dịghị na retired-id snapshot; retired id ọ bụla ka dị na `REGISTRY` ka a na-ebuga n’ebe ọzọ ma ọ bụ depụta ya na `allowedRetiredInCatalog`; source ma ọ bụ target ọ bụla nke `DEFAULT_DEGRADATION_MAP` adịghị ka nke lara ezumike nka na snapshot ahụ. Nke a anaghị egosi na upstream dị ndụ na-enye model ugbu a. Offline — ọ na-atụnyere ya na `config/quality/model-lifecycle.json`, nke a na-eji aka eme ka ọ dị ọhụrụ site na `npm run quality:refresh-model-lifecycle` (netwọk; ejikọghị ya na CI). `allowedRetiredInCatalog` bụ burn-down ratchet: tinye ndenye naanị ma ọ bụrụ na e nwere tracking issue. | Ee | -| `check:fetch-targets` | `fetch("/api/...")` ọ bụla dị na `src/` nke akụkụ client na-ezo aka na `route.ts` dị adị n’ezie | Ee | -| `check:deps` | Dep niile enwere ike iji `npm install` wụnye n’ofe `package.json` ọ bụla dị na repo nọ na `dependency-allowlist.json`; a na-akanye package ọhụrụ ndị a na-etinyeghị version kpọmkwem ma ọ bụ ndị e slopsquat | Ee | -| `audit:deps` | `npm audit` (root + electron) — enweghị ndụmọdụ nwere ogo high/critical (ọ na-adakọ n’akụkụ ụfọdụ na osv `check:vuln-ratchet`; lee Rationalization Backlog) | Ee | -| `check:lockfile` | Izu oke nke `package-lock.json` — https registry, integrity hashes, enweghị host overrides | Ee | -| `check:licenses` | Ndepụta ikike SPDX anabatara maka ndabere mmepụta | Ee | -| `check:tracked-artifacts` | Enweghị artefaktị nrụpụta / symlink `node_modules` e tinyere na commit (ọ na-agbakwa na husky pre-commit; pre-push bụ nke e kpachapụrụ anya mee ka ọ dị mfe — #6716) | Ee | -| `check:ai-attribution` | Enweghị trailer AI/bot `Co-Authored-By` ma ọ bụ footer nke na-egosi mmepụta AI na commit, aha, ma ọ bụ ahụ PR — Iwu Siri Ike #16 (n'ime loop fast-gates nke `quality.yml` maka PR→`release/**` — ọ na-agụ payload event, ọ naghị eme ihe ma ọ bụrụ na ọ bụghị PR — yana nzọụkwụ naanị maka PR na lint nke `ci.yml` maka PR→`main`; tinyekwara hook husky `commit-msg`; a na-anabata ndị mmadụ dịka ndị odee ibe; #14436) | -| `check:vitest-exclusions` | Mwepụ Vitest ọ bụla na-akpọ aha issue nsuso ma pụta na `config/quality/vitest-exclusions.json` (#13204) | Ee | -| `check:file-size` | Ọ dịghị faịlụ source gafere oke e debere maka extension ọ bụla (ratchet: faịlụ buru ibu a kpọchiri akpọchi dị na ndepụta `frozen`) | Ee | -| `check:error-helper` | Nzaghachi njehie dị na executors/handlers na-eji `buildErrorBody()` / `sanitizeErrorMessage()` (Iwu Siri Ike #12) | Ee | -| `check:migration-numbering` | A na-enye faịlụ SQL migration nọmba n’usoro, na-enweghị oghere ma ọ bụ nọmba ndị emegharịrị | Ee | -| `check:public-creds` | Enweghị OAuth `client_id`/`client_secret` ma ọ bụ igodo Firebase Web e dere ozugbo n’èzí `publicCreds.ts` (Iwu Siri Ike #11) | Ee | -| `check:db-rules` | Enweghị SQL raw n’èzí modulu `src/lib/db/`; enweghị barrel-imports sitere na `localDb.ts` (Iwu Siri Ike #2/#5) | Ee | -| `check:known-symbols` | Ndị mmejuputa provider, atụmatụ routing, na ndị ntụgharị edebanyere na dispatch tables ha dabara na faịlụ ndị dị na disk — enweghị symbols ndị na-enweghị njikọ ma ọ bụ ndị a na-ekwupụtaghị | Ee | -| `check:route-guard-membership` | Route ọ bụla na-ebido child process bụ nke `isLocalOnlyPath()` kewara n’ụdị kwesịrị ekwesị (Iwu Siri Ike #15/#17) | Ee | -| `check:test-discovery` | Faịlụ `*.test.ts` / `*.spec.ts` ọ bụla dị na repo bụ ma ọ dịkarịa ala otu test runner na-anakọta ya (ratchet: ndepụta faịlụ na-enweghị njikọ dị na `test-discovery-baseline.json` nwere ike naanị ibelata) | Ee | -| `check:agent-skills-sync` | Ihe arụpụtara maka agent-skills kwekọrọ na katalọgụ isi mmalite ha (enweghị mgbanwe na-ekwesịghị ekwesị) | -| `check:provider-asset-provenance` | Akara/logo na akụ ndị provider nwere ndekọ ebe ha si bịa | -| `lint:json` | Faịlụ nhazi JSON na-agụpụta nke ọma ma na-emezu iwu lint nke repo | -| `typecheck:core` | Nchịkọta TypeScript na-enweghị njehie (naanị ịdọ aka ná ntị ndụmọdụ) | Ee | -| `typecheck:noimplicit:core` | `noImplicitAny` siri ike — nke a lekwasịrị anya n'ọdịnihu; ọtụtụ ebe oku dịbu adị ka chọrọ nkọwa ụdị | **Ndụmọdụ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` nke akọwapụtara naanị maka `src/app/(dashboard)/**` (#7033) — ndepụta ikike faịlụ 27 ahọpụtara nke `typecheck:core` anaghị etinye dashboard TSX ọ bụla, `next build` anaghị enyocha ụdị ya (`next.config.mjs` na-edobe `ignoreBuildErrors: true`), ya mere regressions nke identifier na-enweghị njikọ nọ ebe ahụ (#6625/#6909) anaghị apụta ìhè nye CI. A na-atụnyere ya na baseline ọnụ ọgụgụ emechiri emechi maka faịlụ ọ bụla/koodu TS ọ bụla (`config/quality/dashboard-typecheck-baseline.json`, otu usoro mmanye maka ihe ochie dị ka `check:known-symbols`) — naanị njehie ỌHỤRỤ karịrị ọnụ ọgụgụ baseline ga-eme ka gate daa; jiri `--update` belata baseline mgbe edozi njehie dịbu adị. | Ee | +Ọ na-agba na PR ọ bụla gaa `main`. Ọ na-egbochi merge ma ọ bụrụ na ọ daa. + +| Skripti (`npm run ...`) | Ihe ọ na-enyocha | Na-egbochi | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | +| `check:node-runtime` | Ụdị Node.js dị n'ime oke a na-akwado | Ee | +| `check:cycles` | Mbubata okirikiri n'ime `src/` + `open-sse/` niile (dabere na AST, e doziela `paths` nke tsconfig). Bare = ndụmọdụ, ọ na-edepụta okirikiri ndị ahụ. `check:cycles:ratchet` (nke CI na-agba) na-egbochi mgbe ọnụọgụ ahụ gafere oke `metrics.cycles` dị na `quality-baseline.json` — ugbu a ọ bụ 14, `direction: down`, ya mere ọ nwere ike naanị ibelata (#15159 G-01/G-02) | Ee (ratchet) | +| `check:route-validation:t06` | Schema Zod dị na route niile (iwu Tier 6) | Ee | +| `check:any-budget:t11` | Ọnụọgụ `@ts-expect-error // any` anaghị agafe budget (catraca Tier 11) | Ee | +| `check:provider-consistency` | Provider ọ bụla dị na `providers.ts` nwere ntinye kwekọrọ na ya na `providerRegistry.ts` (nakwa n’aka nke ọzọ, n’ime allowlist) | Ee | +| `check:model-lifecycle` | Tebụl routing atọ a na-eji aka elekọta na-anọgide kwekọọ na lifecycle snapshot e tinyere na repository (#11503): `FITNESS_TABLE` (`taskFitness.ts`) anaghị enye retired id ọ bụla `REGISTRY` nwere ike iziga akara; target ọ bụla nke `BUILT_IN_ALIASES` dị na `REGISTRY` ma ọ dịghị na retired-id snapshot; retired id ọ bụla ka dị na `REGISTRY` ka a na-ebuga n’ebe ọzọ ma ọ bụ depụta ya na `allowedRetiredInCatalog`; source ma ọ bụ target ọ bụla nke `DEFAULT_DEGRADATION_MAP` adịghịkwa ka nke retired na snapshot ahụ. Nke a anaghị egosi na upstream dị ndụ na-enye model ugbu a. Offline — ọ na-atụnyere ya na `config/quality/model-lifecycle.json`, nke a na-eji aka eme ka ọ dị ọhụrụ site na `npm run quality:refresh-model-lifecycle` (network; ejikọghị ya na CI). `allowedRetiredInCatalog` bụ burn-down ratchet: tinye entry naanị ma ọ bụrụ na e nwere tracking issue. | Ee | +| `check:fetch-targets` | `fetch("/api/...")` ọ bụla dị na client-side `src/` na-ejikọ na `route.ts` dị adị | Ee | +| `check:deps` | Dep niile enwere ike iji `npm install` wụnye n’ofe `package.json` ọ bụla dị na repo nọ na `dependency-allowlist.json`; a na-akọ package ọhụrụ ndị a na-etinyeghị pin ma ọ bụ ndị e mere slopsquat | Ee | +| `audit:deps` | `npm audit` (root + electron) — enweghị advisory dị elu/critical (ọ na-ekpuchi otu akụkụ nke osv `check:vuln-ratchet`; lee Rationalization Backlog) | Ee | +| `check:lockfile` | Iguzosi ike n’ezi ihe nke `package-lock.json` — HTTPS registry, integrity hashes, enweghị host overrides | Ee | +| `check:licenses` | Ndepụta ikike SPDX akwadoro maka ndabere mmepụta | Ee | +| `check:tracked-artifacts` | Enweghị ihe nrụpụta / symlink `node_modules` etinyere na commit (ọ na-agbakwa na husky pre-commit; e mere pre-push ka ọ dị mfe n'ebumnuche — #6716) | Ee | +| `check:ai-attribution` | Enweghị trailer AI/bot `Co-Authored-By` ma ọ bụ ederede ngwụcha na-egosi mmepụta AI n'ime commit, aha, ma ọ bụ ọdịnaya PR — Iwu Siri Ike #16 (n'ime loop fast-gates nke `quality.yml` maka PR→`release/**` — na-agụ payload nke event, ọ naghị eme ihe ma ọ bụrụ na ọ bụghị PR — yana nzọụkwụ naanị maka PR n'ime lint nke `ci.yml` maka PR→`main`; nakwa hook husky `commit-msg`; a na-ekwe ka ndị mmadụ bụrụ ndị odekọrọ ọnụ; #14436) | +| `check:vitest-exclusions` | Mwepu Vitest ọ bụla na-akpọ aha issue nsuso ma pụta na `config/quality/vitest-exclusions.json` (#13204) | Ee | +| `check:file-size` | Ọ dịghị faịlụ source gafere oke edobere maka extension ọ bụla (ratchet: faịlụ buru ibu ndị akpọchiri n'ime ndepụta `frozen`) | Ee | +| `check:error-helper` | Nzaghachi njehie n'ime executors/handlers na-eji `buildErrorBody()` / `sanitizeErrorMessage()` (Iwu Siri Ike #12) | Ee | +| `check:migration-numbering` | Faịlụ SQL migration nwere nọmba na-aga n'usoro, enweghị oghere ma ọ bụ nọmba e megharịrị ugboro abụọ | Ee | +| `check:public-creds` | Enweghị OAuth `client_id`/`client_secret` e dere ozugbo ma ọ bụ igodo Firebase Web n'èzí `publicCreds.ts` (Iwu Siri Ike #11) | Ee | +| `check:db-rules` | Enweghị SQL raw n'èzí modul `src/lib/db/`; enweghị barrel-imports sitere na `localDb.ts` (Iwu Siri Ike #2/#5) | Ee | +| `check:known-symbols` | Ndị executor nke provider, usoro routing, na ndị translator edebanyere aha na dispatch tables ha kwekọrọ na faịlụ ndị dị na disk — enweghị symbols ndị na-enweghị njikọ ma ọ bụ ndị a na-ekwupụtaghị | Ee | +| `check:route-guard-membership` | Route ọ bụla na-amalite child process ka `isLocalOnlyPath()` na-ekewa n'ụdị kwesịrị ekwesị (Iwu Siri Ike #15/#17) | Ee | +| `check:test-discovery` | Faịlụ `*.test.ts` / `*.spec.ts` ọ bụla dị na repo ka ọ dịkarịa ala otu test runner na-achịkọta (ratchet: ndepụta orphan dị na `test-discovery-baseline.json` nwere ike naanị ibelata) | Ee | +| `check:agent-skills-sync` | Artifakt ndị agent-skills emepụtara dabara na katalọgụ isi mmalite ha (enweghị mgbanwe na-atụghị anya ya) | +| `check:provider-asset-provenance` | Akara na akụ ndị provider nwere ndekọ ebe ha si | +| `lint:json` | A na-agụ faịlụ nhazi JSON nke ọma ma ha na-emezu iwu lint nke repo | +| `typecheck:core` | Nchịkọta TypeScript na-enweghị njehie (naanị ịdọ aka ná ntị ndụmọdụ) | Ee | +| `typecheck:noimplicit:core` | `noImplicitAny` siri ike — maka ọdịnihu; ọtụtụ ebe oku ndị dịbu adị ka chọrọ nkọwa ụdị | **Ndụmọdụ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` nke ejedebere na `src/app/(dashboard)/**` (#7033) — ndepụta nnabata faịlụ 27 ahọpụtara nke `typecheck:core` anaghị etinye TSX dashboard ọ bụla, `next build` anaghịkwa enyocha ụdị ya (`next.config.mjs` na-ahazi `ignoreBuildErrors: true`), ya mere mmeghachi omume ọjọọ nke njirimara na-enweghị onye nwe ha n'ebe ahụ (#6625/#6909) anaghị apụta ìhè nye CI. A na-atụnyere ya na baseline ọnụọgụ maka faịlụ ọ bụla/koodu TS ọ bụla nke agaghị agbanwe (`config/quality/dashboard-typecheck-baseline.json`, otu usoro mmanye maka ihe ochie dịka `check:known-symbols`) — naanị njehie ỌHỤRỤ karịrị ọnụọgụ dị na baseline ga-eme ka gate daa; jiri `--update` belata ya mgbe e meziri njehie dịbu adị. | Ee | ### Ọrụ: `quality-gate` -Ọ na-agba mgbe `test-coverage` gasịrị. Ọ na-egbochi merge ma ọ bụrụ na ọ daa. +Ọ na-agba mgbe `test-coverage` gachara. Ọ na-egbochi ijikọta ma ọ bụrụ na ọ daa. -| Skripụ | Ihe ọ na-enyocha | Na-egbochi | -| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `quality:collect` | Na-emepụta `quality-metrics.json` (ọnụọgụ ịdọ aka ná ntị ESLint, mkpuchi sitere na akụkọ shard ndị ejikọtara ọnụ) | Ee (ọ na-ebu ratchet ụzọ) | -| `quality:ratchet` | Metric ọ bụla dị na `quality-baseline.json` alaghị azụ (ịdọ aka ná ntị ESLint ≤ ntọala; mkpuchi ≥ ntọala) | Ee | -| `check:duplication` | Mmegharị koodu ugboro ugboro (jscpd@4) anaghị agafe ntọala dị na `quality-baseline.json` | Ee | -| `check:complexity` | Mgbagwoju anya cyclomatic n'ọkwa faịlụ anaghị agafe oke ahụ (ESLint `complexity` bụ isi + `max-lines-per-function`) | Ee | -| `check:cognitive-complexity` | Ratchet mgbagwoju anya nke uche (`eslint-plugin-sonarjs`) — ngafe ESLint dị iche; CI na-agba ha abụọ ọnụ dịka otu nzọụkwụ `check:complexity-ratchets` | Ee | -| `check:dead-code` | Ratchet mbupụ / faịlụ ndị a na-ejighị (knip) anaghị ala azụ ma e jiri ya tụnyere ntọala | Ee | -| `check:compression-budget` | Oke benchmark mkpakọ — opekempe nchekwa token maka engine ọ bụla agaghị ala azụ | Ee | -| `check:type-coverage` | Ratchet pasent nke e nyere ụdị (`type-coverage`) anaghị ala azụ; ọ na-anọchi ọtụtụ ọrụ `typecheck:noimplicit:core` | Ee | -| `check:codeql-ratchet` | Ọnụọgụ ọkwa ịdọ aka ná ntị CodeQL mepere emepe anaghị ala azụ (na-agụ site na `gh api`; na-awụfe n'enweghị nsogbu ma ọ bụrụ na token adịghị) — maka oge mmelite na mkpalite aka: lee "CodeQL ratchet" n'okpuru | Ee | +| Skript | Ihe ọ na-enyocha | Na-egbochi | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `quality:collect` | Na-emepụta `quality-metrics.json` (ọnụọgụ ịdọ aka ná ntị ESLint, mkpuchi sitere na akụkọ shard ejikọtara ọnụ) | Ee (ọ na-ebute ratchet) | +| `quality:ratchet` | Metrik ọ bụla dị na `quality-baseline.json` alaghachighị azụ (ịdọ aka ná ntị ESLint ≤ ntọala; mkpuchi ≥ ntọala) | Ee | +| `check:duplication` | Mmegharị koodu ugboro ugboro (jscpd@4) anaghị agafe ntọala dị na `quality-baseline.json` | Ee | +| `check:complexity` | Mgbagwoju anya cyclomatic n'ọkwa faịlụ anaghị agafe oke ahụ (ESLint `complexity` nke isi + `max-lines-per-function`) | Ee | +| `check:cognitive-complexity` | Ratchet mgbagwoju anya nke echiche (`eslint-plugin-sonarjs`) — nnyefe ESLint dị iche; CI na-eme ha abụọ n'otu nzọụkwụ `check:complexity-ratchets` | Ee | +| `check:dead-code` | Ratchet mbupụ / faịlụ ndị a na-ejighị (knip) anaghị alaghachi azụ ma e jiri ya tụnyere ntọala | Ee | +| `check:compression-budget` | Mmefu benchmark mkpakọ — oke kacha nta nke nchekwa token maka engine ọ bụla agaghị alaghachi azụ | Ee | +| `check:type-coverage` | Ratchet pasentị e nyere ụdị (`type-coverage`) anaghị alaghachi azụ; ọ na-anọchi ihe ka ukwuu n'ime `typecheck:noimplicit:core` | Ee | +| `check:codeql-ratchet` | Ọnụọgụ ịdọ aka ná ntị CodeQL mepere emepe anaghị alaghachi azụ (na-agụ site na `gh api`; na-amapụ n'enweghị nsogbu ma token adịghị) — maka ugboro ume ọhụrụ na mkpali aka: lee "CodeQL ratchet" n'okpuru | Ee | ### Ọrụ: `quality-extended` -Ọrụ a dum bụ nke ndụmọdụ (`continue-on-error: true`). Ratchet ndị dabeere na npm na-agba -n'ezie; scanner ndị mpụga na-etinye site na `gh release download` ma na-awụfe onwe ha (exit 0) +Ọrụ a dum bụ naanị ndụmọdụ (`continue-on-error: true`). Ratchet ndị dabeere na npm +na-arụ ọrụ n'ezie; a na-etinye ndị nyocha mpụga site na `gh release download`, ha na-amapụ onwe ha (exit 0) mgbe binary ka na-adịghị. -| Skripụ | Ihe ọ na-enyocha | Na-egbochi | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -| `check:circular-deps` | Enweghị dependency ndị na-agba okirikiri (dpdm) | **Ndụmọdụ** | -| `check:bundle-size` | Nha bundle anaghị agafe oke ahụ | **Ndụmọdụ** | -| `check:secrets` | Nnyocha ihe nzuzo (gitleaks) — na-awụfe ma ọ bụrụ na binary adịghị | **Ndụmọdụ** | -| `check:vuln-ratchet` | Ọghọm nchekwa dependency (osv-scanner) anaghị ala azụ — na-awụfe ma ọ bụrụ na binary adịghị | **Ndụmọdụ** | -| `check:workflows` | Nnyocha lint workflow (actionlint + zizmor); scanner na-efu/rụrụ arụ, akụkọ na-ezighi ezi ma ọ bụ ntọala ratchet na-efu na-eme ka ọ daa dịka INCOMPLETE. Nchọpụta ziri ezi na-agbaso iwu strict/advisory/ratchet ahọpụtara | A chọrọ ka ọ gbaa; ratchet zizmor na-egbochi na CI | -| `check:openapi-breaking` | Mgbanwe na-emebi nkwekọrịta API ọha (`openapi.yaml`) ma e jiri ya tụnyere alaka ntọala (oasdiff) — na-emepụta `openapiBreaking=N`; na-awụfe ma ọ bụrụ na oasdiff adịghị ma ọ bụ enweghị ike ịchọta nkọwa ntọala | **Ndụmọdụ** | +| Skript | Ihe ọ na-enyocha | Na-egbochi | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ | +| `check:circular-deps` | Enweghị dependency na-agba okirikiri (dpdm) | **Ndụmọdụ** | +| `check:bundle-size` | Ogo bundle anaghị agafe oke ahụ | **Ndụmọdụ** | +| `check:secrets` | Nnyocha ihe nzuzo (gitleaks) — na-amapụ ma binary adịghị | **Ndụmọdụ** | +| `check:vuln-ratchet` | Adịghị ike nchekwa nke dependency (osv-scanner) anaghị alaghachi azụ — na-amapụ ma binary adịghị | **Ndụmọdụ** | +| `check:workflows` | Nnyocha workflow (actionlint + zizmor); ndị nyocha na-adịghị/ndị mebiri emebi, akụkọ na-ezighi ezi ma ọ bụ enweghị ntọala ratchet na-eme ka ọ daa dịka INCOMPLETE. Nchọpụta ziri ezi na-agbaso iwu strict/advisory/ratchet ahọpụtara | A ghaghị ime ya; ratchet zizmor na-egbochi na CI | +| `check:openapi-breaking` | Mgbanwe ndị na-emebi nkwekọrịta API ọha (`openapi.yaml`) ma e jiri ya tụnyere alaka ntọala (oasdiff) — na-emepụta `openapiBreaking=N`; na-amapụ ma oasdiff adịghị ma ọ bụ enweghị ike ịchọta nkọwa ntọala | **Ndụmọdụ** | ### Ọrụ: `docs-sync-strict` -Ọ na-agba na PR ọ bụla gaa na `main`. Ọ na-egbochi njikọta ma ọ bụrụ na ọ daa. - -| Skript | Ihe ọ na-enyocha | Na-egbochi | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | -| `check:docs-all` | Ọnụ ụzọ nyocha ukwu nke na-agba ọnụ ụzọ nyocha nta 6 dị n'okpuru n'otu n'otu | Ee | -| ↳ `check:docs-sync` | Ndakọrịta ụdị nke CHANGELOG / OpenAPI / llm.txt | Ee | -| ↳ `check:docs-counts` | Ọnụọgụ dị n'ime ederede (ọnụọgụ ndị na-eweta ọrụ, ọnụọgụ mbugharị, wdg.) nọ n'ime oke ratchet nke ọnụọgụ ndị dị adị | Ee | -| ↳ `check:env-doc-sync` | E depụtara env var ọ bụla dị na `.env.example` n'ime tebụl docs, ma nke ọ bụla dị na tebụl ahụ dịkwa na `.env.example` | Ee | -| ↳ `check:deprecated-versions` | Enweghị eriri ụdị a kagburu akwado n'ime docs | Ee | -| ↳ `check:doc-links` | Njikọ markdown ime dị na docs na-eduga na faịlụ ndị dị adị (usoro `[text]`/`(path)`) | Ee | -| ↳ `check:fabricated-docs` | Routes, env vars, iwu CLI, aha hook, na ụzọ faịlụ ndị e zoro aka na ha n'ime docs dị n'ime codebase. Ọnụ ụzọ siri ike site na `--strict`; ọ na-enye naanị ịdọ aka ná ntị ma flag adịghị. | Ee (site na `--strict` na CI) | -| `check:cli-i18n` | Eriri iwu CLI dị n'ime faịlụ locale i18n niile | Ee | -| `check:openapi-coverage` | Nkọwapụta OpenAPI na-ekpuchi ma ọ dịkarịa ala oke ala e ji ratchet tọọ nke routes ndị dị adị | Ee | -| `check:openapi-security-tiers` | Nkọwa ọkwa nchekwa dị na `openapi.yaml` dabara na nhazi nke `routeGuard.ts` | **Ndụmọdụ** | -| `check:openapi-routes` | Path ọ bụla dị na `openapi.yaml` na-eduga na `route.ts` dị adị (mgbochi echiche ụgha) | Ee | -| `check:docs-symbols` | Ntụaka `/api/...` ọ bụla dị na `docs/**/*.md` na-eduga na `route.ts` dị adị (mgbochi echiche ụgha) | Ee | -| `i18n translation drift` | Keys ndị a na-atụgharịbeghị n'ime faịlụ locale i18n — naanị dọọ aka ná ntị | **Ndụmọdụ** | +Na-arụ na PR ọ bụla gaa `main`. Na-egbochi ijikọ ma ọ daa. + +| Skripti | Ihe ọ na-enyocha | Na-egbochi | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | +| `check:docs-all` | Ọnụ ụzọ nchịkọta nke na-eme obere ọnụ ụzọ 6 ndị dị n'okpuru n'otu n'otu | Ee | +| ↳ `check:docs-sync` | Nkwekọrịta ụdị nke CHANGELOG / OpenAPI / llm.txt | Ee | +| ↳ `check:docs-counts` | Ọnụọgụ ndị dị n'ihe edere (ọnụọgụ ndị na-eweta ọrụ, ọnụọgụ mbugharị, wdg.) dị n'ime oke ratchet nke ọnụọgụ ndị bụ eziokwu | Ee | +| ↳ `check:env-doc-sync` | A kọwara env var ọ bụla dị na `.env.example` n'ime tebụl dọkụmentị, otu ahụkwa n'akụkụ nke ọzọ | Ee | +| ↳ `check:deprecated-versions` | Enweghị eriri ụdị a kagburu akwado n'ime dọkụmentị | Ee | +| ↳ `check:doc-links` | Njikọ markdown ime n'ime dọkụmentị na-eduga na faịlụ ndị dị adị (ụdị `[text]`/`(path)`) | Ee | +| ↳ `check:fabricated-docs` | Routes, env vars, iwu CLI, aha hook, na ụzọ faịlụ ndị e zoro aka na ha n'ime dọkụmentị dị n'ime codebase. Ọnụ ụzọ siri ike site na `--strict`; ọ na-ada nwayọ ma ọkọlọtọ ahụ adịghị. | Ee (site na `--strict` na CI) | +| `check:cli-i18n` | Eriri iwu CLI dị n'ime faịlụ locale i18n niile | Ee | +| `check:openapi-coverage` | Nkọwapụta OpenAPI na-ekpuchi ma ọ dịkarịa ala oke ala e ji ratchet tụọ nke routes ndị dị adị | Ee | +| `check:openapi-security-tiers` | Nkọwa ọkwa nchekwa dị na `openapi.yaml` kwekọrọ na nhazi ọkwa dị na `routeGuard.ts` | **Ndụmọdụ** | +| `check:openapi-routes` | Path ọ bụla dị na `openapi.yaml` na-eduga na `route.ts` dị adị (mgbochi echiche ụgha) | Ee | +| `check:docs-symbols` | Ntugharị aka `/api/...` ọ bụla dị na `docs/**/*.md` na-eduga na `route.ts` dị adị (mgbochi echiche ụgha) | Ee | +| `i18n translation drift` | Key ndị a na-atụgharịghị asụsụ n'ime faịlụ locale i18n — naanị ịdọ aka ná ntị | **Ndụmọdụ** | ### Ọrụ: `i18n-ui-coverage` -| Skript | Ihe ọ na-enyocha | Na-egbochi | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | -| `check-ui-keys-coverage` (inline) | Mkpuchi key i18n nke UI bụ ≥ 65% | Ee | -| `check-ui-value-drift` (inline) | **Value** Bekee e degharịrị anaghị ahapụ ntụgharị ochie ọ bụla | Ee | -| `check-new-key-coverage` (inline) | A tụgharịrị key Bekee **ọhụrụ** n'ime locale ọ bụla — a na-ajụ akara `__MISSING__:` | Ee | -| `check-translation-ratio` | Oke ntụgharị n'ezie n'otu locale (ihe yiri Bekee kpọmkwem / placeholder / ihe na-efu ndị na-anọghị na allowlist) agaghị agafe `config/quality/i18n-translation-baseline.json` + ohere mgbakwunye | **Ndụmọdụ** | +| Skripti | Ihe ọ na-enyocha | Na-egbochi | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (inline) | Mkpuchi key i18n nke UI bụ ≥ 65% | Ee | +| `check-ui-value-drift` (inline) | Idegharị **value** Bekee anaghị ahapụ ntụgharị asụsụ ochie ọ bụla | Ee | +| `check-new-key-coverage` (inline) | A tụgharịrị key Bekee **ọhụrụ** n'ime locale ọ bụla — a na-ajụ akara `__MISSING__:` | Ee | +| `check-translation-ratio` | Oke ntụgharị asụsụ n'ezie maka locale ọ bụla (nke yiri Bekee / placeholder / ihe na-efu ndị na-anọghị na allowlist) agaghị agafe `config/quality/i18n-translation-baseline.json` + ohere mgbakwunye | **Ndụmọdụ** | -Ọ chọrọ `fetch-depth: 0` — ọnụ ụzọ value-drift na-atụnyere mgbanwe dị n'etiti `en.json` na merge base. +Ọ chọrọ `fetch-depth: 0` — ọnụ ụzọ value-drift na-atụnyere ọdịiche dị n'etiti `en.json` na merge base. -#### `check-ui-value-drift` — ọnụ ụzọ ntụgharị ochie +#### `check-ui-value-drift` — ọnụ ụzọ ntụgharị asụsụ ochie -Ọ na-achọpụta otu mmejọ i18n nke ọnụ ụzọ ndị ọzọ enweghị ike ịhụ site n'usoro ha: a na-edegharị value Bekee -ma ntụgharị ndị e si na Bekee _ochie_ mepụta ka na-adị, ya mere -ndị ọrụ na-abụghị ndị Bekee ka na-agụ ederede e dere n'olu nwere ntụkwasị obi, mana nke na-ezighi ezi ugbu a. +Ọ na-ejide otu ndaghachi azụ i18n nke ọnụ ụzọ ndị ọzọ enweghị ike ịhụ site n'ụdị nhazi: a na-edegharị value Bekee +ma ntụgharị asụsụ ndị sitere na Bekee _gara aga_ ka na-adị, nke mere na +ndị ọrụ na-abụghị ndị Bekee na-aga n'ihu na-agụ ozi e ji obi ike dee ma bụrụzi nke na-ezighị ezi. -Nke a abanyela n'ezie na mbipụta. E degharịrị `oauthModal.googleOAuthWarning` mgbe enyemaka nbanye Antigravity -batara (#5203); **39 n'ime locale 43** ka nwere ederede na-agwa ndị njikwa ka ha "detuo URL -zuru ezu ma mado ya n'okpuru" — usoro na-enweghị ike ịrụcha maka provider ahụ. A chọpụtaghị ya -ruo #8463 n'ihi na: +Nke a mere n'ezie mgbe ewepụtara ya. E degharịrị `oauthModal.googleOAuthWarning` mgbe onye enyemaka nbanye Antigravity +rutere (#5203); **39 n'ime locale 43** ka nwere ederede na-agwa ndị na-ahụ maka sistemụ ka ha “detuo +URL zuru ezu ma mado ya n'okpuru” — usoro nke na-enweghị ike ịrụcha maka onye na-eweta ọrụ ahụ. Ọ +ghị ihe a chọpụtara ruo #8463 n'ihi na: -- `sync-ui-keys` na-agbakwunye naanị keys ndị **na-adịghị**, ọ naghị agbakwunye ndị **ochie**; -- `check-ui-keys-coverage` na-agụ ọnụnọ key, ya mere a na-agụ ntụgharị ochie dịka nke e kpuchiri; -- `check-translation-drift` na-esochi oyiri akwụkwọ `docs/i18n//**.md` — - ọ naghị agụ `src/i18n/messages/*.json`. Ọ na-egbochi n'ime ọrụ `docs-sync-strict` kemgbe - re-sync nke 2026-09: dezie core doc → `npm run i18n:run -- --files=` (n'ọkwa section, dị ọnụ ala). +- `sync-ui-keys` na-agbakwunye naanị key ndị **na-adịghị**, ọ naghị agbakwunye ndị **merela ochie**; +- `check-ui-keys-coverage` na-agụ ọnụnọ key, ya mere a na-ewere ntụgharị asụsụ ochie dị ka nke ekpuchiri; +- `check-translation-drift` na-esochi dọkụmentị oyiri `docs/i18n//**.md` — + ọ naghị agụ `src/i18n/messages/*.json`. Ọ na-egbochi n'ọrụ `docs-sync-strict` kemgbe + mmekọrịta ọzọ nke 2026-09: dezie dọkụmentị isi → `npm run i18n:run -- --files=` (n'ogo ngalaba, dị ọnụ ala). -**Ọ na-aghọta diff, ọ bụghị nke baseline na-akwado.** Ọ na-atụnyere `en.json` dị na merge base na -working tree; maka key ọ bụla nke uru Bekee ya gbanwere, locale ọ bụla ka nwere +**Ọ na-elebara diff anya, ọ naghị adabere na baseline.** Ọ na-atụnyere `en.json` dị na merge base na +working tree; maka key ọ bụla nke value Bekee ya gbanwere, locale ọ bụla ka nwere ntụgharị a na-emetụghị aka abụrụla nke ochie. Nke a kpachapụrụ anya **na-eme ka ụgwọ dịbu adị ghara ịgbanwe** — diff -enweghị ike igosi ụdị Bekee ochie ntụgharị dịtere aka siri na ya pụta, ya mere gate ahụ na-enyocha -naanị ihe mgbanwe dị ugbu a metụrụ. Nhọrọ ọzọ (baseline hash maka key ọ bụla) ga-achọ -faịlụ emepụtara nke ruru ~600 KB, nke ji okpukpu 3 karịa baseline kachasị ukwuu dị ugbu a, ma na-agbanwe na PR i18n ọ bụla. +enweghị ike igosi ụdị Bekee ochie ntụgharị dịteworo aka si na ya pụta, ya mere gate ahụ na-enyocha +naanị ihe mgbanwe dị ugbu a metụtara. Nhọrọ ọzọ (baseline hash maka key ọ bụla) ga-achọ +faịlụ emepụtara nke ruru ~600 KB, okpukpu 3 nke baseline kachasị ukwuu dị ugbu a, ma na-agbanwe na PR i18n ọ bụla. E nwere ụzọ abụọ iji mezuo ya: 1. melite ntụgharị ndị emetụtara, ma ọ bụ -2. tọọ ha ka ha bụrụ `__MISSING__:` — runtime ga-enyezi Bekee e doziri - (`src/i18n/request.ts::deepMergeFallback`, #7258), key ahụ abanyezie n'ahịrị ntụgharị. +2. tọọ ha ka ha bụrụ `__MISSING__:` — mgbe ahụ runtime ga-enye Bekee e meziri + (`src/i18n/request.ts::deepMergeFallback`, #7258), key ahụ ga-abanyekwa n'ahịrị ntụgharị. -Ọ bụrụ na **pụtara** eriri ahụ gbanwere, ọ ka mma **ịgbanwe aha key ahụ**: key ọhụrụ agaghị eketa +Ọ bụrụ na **ihe eriri ahụ pụtara** gbanwere, họrọ **ịgbanwe aha key ahụ**: key ọhụrụ enweghị ike iketa ntụgharị ochie. Nke ahụ bụ usoro #8463 jiri. ```bash -npm run i18n:check-value-drift # siri ike (nke CI na-agba) +npm run i18n:check-value-drift # nke siri ike (nke CI na-agba) npm run i18n:check-value-drift:warn # naanị nye akụkọ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Ọ na-eji 0 pụta tinyere `SKIP reason=base-unresolved` mgbe enweghị ike ịgụ catalog dị na base (shallow +Ọ na-eji 0 pụọ yana `SKIP reason=base-unresolved` mgbe enweghị ike ịgụ catalog ntọala ahụ (shallow clone na-enweghị base ref), dịka `check-openapi-breaking`. ### Ọrụ: `i18n` -Matrix nyocha i18n zuru ezu (otu ọrụ maka locale ọ bụla). Ọrụ ahụ dum bụ ndụmọdụ. +Matrix nkwado i18n zuru ezu (otu ọrụ maka locale ọ bụla). Ọrụ ahụ dum bụ ndụmọdụ. -| Script | Ihe ọ na-enyocha | Mgbochi | -| ------------------------------- | ----------------------------------- | ----------------------------------------------------- | -| `validate_translation.py quick` | Izu oke ntụgharị maka locale ọ bụla | **Ndụmọdụ** (`continue-on-error: true` n'ọrụ ahụ dum) | +| Script | Ihe ọ na-enyocha | Ọ na-egbochi | +| ------------------------------- | --------------------------------- | ----------------------------------------------------- | +| `validate_translation.py quick` | Izuzu ntụgharị maka locale ọ bụla | **Ndụmọdụ** (`continue-on-error: true` n'ọrụ ahụ dum) | ### Ọrụ: `pr-test-policy` -Ọ na-agba naanị na pull requests. +Ọ na-agba naanị na pull request. -| Script | Ihe ọ na-enyocha | Mgbochi | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `check:pr-test-policy` | PR ndị gbanwere production code na `src/`, `open-sse/`, `electron/`, ma ọ bụ `bin/` ga-etinyerịrị ma ọ bụ melite tests (Hard Rule #8) | Ee | -| `check:test-masking` | Faịlụ test ndị gbanwere anaghị ebelata mkpokọta assert ma ọ bụ tinye tautology `assert.ok(true)` | Ee | -| `check:pr-evidence` | Ahụ PR na-akpọtụrụ ihe akaebe test/VPS maka mgbanwe ahụ (ọ na-eme Hard Rule #18 ka ọ rụọ ọrụ site n'iji grep nyochaa prose PR — adịghị ike, lee Backlog) | Ee | +| Script | Ihe ọ na-enyocha | Ọ na-egbochi | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `check:pr-test-policy` | PR ndị na-agbanwe production code na `src/`, `open-sse/`, `electron/`, ma ọ bụ `bin/` ga-etinyerịrị ma ọ bụ melite test (Iwu Siri Ike #8) | Ee | +| `check:test-masking` | Faịlụ test ndị gbanwere anaghị ebelata ngụkọta assert ma ọ bụ tinye tautology `assert.ok(true)` | Ee | +| `check:pr-evidence` | Ahụ PR na-ezo aka na ihe akaebe test/VPS maka mgbanwe ahụ (na-eme Iwu Siri Ike #18 ka igwe rụọ site n'ịchọgharị ederede PR — adịghị ike, lee Backlog) | Ee | ### Ọrụ: `test-vitest` Ọ na-agba mgbe `build` gachara. Ọ na-egbochi merge ma ọ bụrụ na ọ daa. -| Suite | Ihe ọ na-enyocha | Mgbochi | -| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Sava MCP (ngwaọrụ 110), autoCombo, cache — vitest runner | Ee | -| `test:vitest:ui` | Tests nke component UI — vitest runner | **Na-egbochi** — e wepụrụ ọdịda ndị dịbu adị kpọmkwem na `vitest.config.ts`; ọdịda ọhụrụ na-eme ka ọrụ ahụ daa | +| Suite | Ihe ọ na-enyocha | Ọ na-egbochi | +| ---------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (ngwaọrụ 110), autoCombo, cache — vitest runner | Ee | +| `test:vitest:ui` | Test UI component — vitest runner | **Na-egbochi** — e wepụrụ ọdịda ndị dịbu adị n'ụzọ doro anya na `vitest.config.ts`; ọdịda ọhụrụ ga-eme ka ọrụ ahụ daa | -### Workflows abalị (ahaziri oge, ndụmọdụ) +### Workflow abalị (ahaziri oge, ndụmọdụ) -Ndị a na-agba dịka nhazi cron si dị (yana `workflow_dispatch`), ọ dịghị mgbe ha na-agba na PR. Ha niile bụ ndụmọdụ. +Ndị a na-agba dịka nhazi cron si dị (nakwa `workflow_dispatch`), ọ dịghị mgbe ha na-agba na PR. Ha niile bụ ndụmọdụ. -| Workflow | Ihe ọ na-enyocha | Mgbochi | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `nightly-property` | fast-check property tests nwere random seed + ọnụ ọgụgụ run dị elu | **Ndụmọdụ** | -| `nightly-resilience` | gate uto heap, chaos fault-injection, ibu/soak k6 | **Ndụmọdụ** | -| `nightly-llm-security` | nche injection promptfoo (block mode) + nyocha garak (a na-awụli ha ma ọ bụrụ na enweghị provider secret) | **Ndụmọdụ** | -| `nightly-schemathesis` | fuzzing contract OpenAPI (schemathesis) megide OmniRoute dị ndụ site n'iji `docs/openapi.yaml` — na-ekpughe mmebi spec / 500 ndị a na-ejighị aka (Fase 8 B.4) | **Ndụmọdụ** | -| `nightly-mutation` | akara mutation-testing Stryker n'elu fast unit lane — mutants ndị lanarịrị na-ekpughe assert ndị na-adịghị ike | **Ndụmọdụ** | -| `nightly-compat` | matrix ndakọrịta engine Node n'ofe oke `engines.node` ndị a na-akwado | **Ndụmọdụ** | +| Workflow | Ihe ọ na-enyocha | Ọ na-egbochi | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | Test property fast-check nwere seed enweghị usoro + ọnụ ọgụgụ mgbagharị dị elu | **Ndụmọdụ** | +| `nightly-resilience` | gate uto heap, chaos fault-injection, ibu/soak k6 | **Ndụmọdụ** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + probe garak (a na-amafe ha ma ọ bụrụ na provider secret adịghị) | **Ndụmọdụ** | +| `nightly-schemathesis` | Fuzzing nkwekọrịta OpenAPI (schemathesis) megide OmniRoute dị ndụ site n'iji `docs/openapi.yaml` — na-ekpughe mmebi spec / 500 ndị a na-edozighị (Nkeji 8 B.4) | **Ndụmọdụ** | +| `nightly-mutation` | Akara mutation-testing Stryker n'elu fast unit lane — mutant ndị lanarịrị na-ekpughe assert ndị na-adịghị ike | **Ndụmọdụ** | +| `nightly-compat` | Matrix ndakọrịta engine Node gafee oke `engines.node` ndị a na-akwado | **Ndụmọdụ** | --- @@ -537,43 +537,43 @@ njehie njikọ, ọ naghịkwa emebi oge ọrụ. --- -## Ndepụta Ihe A Ga-eme Maka Mmekọrịta Uche (nyocha ROI — Agba 9 Ebili 3) +## Ndepụta Ọrụ Nchịkọta Echiche (nyocha ROI — Agba 9 Ebili Mmiri 3) -E jiri `ci.yml` tụnyere ma dozie ndepụta a na 2026-06-17 (ụdị nke gara aga hapụrụ +E mere ka ndepụta a kwekọọ na `ci.yml` na 2026-06-17 (ụdị gara aga ewepụghị `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Nyocha ROI e mere na nchịkọta ahụ e doziri +`check:codeql-ratchet`, `check:pr-evidence`). Nyocha ROI nke usoro ahụ e mere ka o kwekọọ chọpụtara ndị a dị ka ndị a ga-atụle maka ime ka usoro dị mfe. **Njikọ ndị ahụ bụ mgbanwe CI -nke usoro ọrụ; ịgbanwe/ịhapụ ha bụ mkpebi iwu e debeere onye na-ahụ maka usoro ahụ.** Ọ dịghị ihe dị n'okpuru -etinyegoro n'ọrụ. +a na-eme n'ụzọ akpaaka; ntụgharị/nhichapụ ndị ahụ bụ mkpebi iwu ọrụ edobere maka onye na-ahụ maka ya.** Ọ dịghị ihe dị n'okpuru ebe a +etinyela n'ọrụ ugbu a. **Ihe ọzọ a na-edeghị n'elu** (ndụmọdụ, mgbaàmà dị ala): ọrụ `docs-lint` -(markdownlint + Vale, ọrụ ahụ dum nwere `continue-on-error`) na usoro ọrụ nyocha kwụụrụ onwe ha +(markdownlint + Vale, ọrụ ahụ dum bụ `continue-on-error`) na usoro ọrụ nyocha kwụụrụ onwe ha `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` dị na -`quality-baseline.json` mana ejikọtaghị ya na ratchet na-egbochi ihe na `ci.yml` — metrik ahụ +`quality-baseline.json` mana ejikọghị ya na ratchet na-egbochi ihe na `ci.yml` — metrik ahụ enweghịzi ihe jikọrọ ya ugbu a. -### Jikọta / wepụ oyiri (usoro ọrụ nkịtị, ihe ize ndụ dị ala) +### Jikọta / wepụ nkwugharị (nke akpaaka, ihe ize ndụ dị ala) -A kwadoro onye ọ bụla a họpụtara site n'iji ọnọdụ gate dị ndụ na 2026-06-17 (tụkwasị obi-ma-nyochaa); -ọtụtụ njikọ ndị yiri ka ha “doro anya” mechara bụrụ ndị na-ezo ụgwọ ọrụ, ya mere ha **abụghị** ihe a ga-etinye ozugbo n'enweghị nsogbu. +A nyochara onye ọ bụla a tụpụtara megide ọnọdụ gate dị ndụ na 2026-06-17 (tụkwasị obi mana nyochaa); +ọtụtụ njikọ ndị yiri ihe "doro anya" mechara bụrụ na ha na-ezo ụgwọ teknụzụ ma ha **abụghị** ihe enwere ike dochie ozugbo n'enweghị nsogbu. -- **`check:docs-sync` na-agba ugboro abụọ** — ọ na-agba naanị ya n'ọrụ `lint`, ọzọkwa n'ime `check:docs-all` (`docs-sync-strict`) nakwa na husky pre-commit hook. ✅ **EMECHALA** — ewepụla ịkpọ ya naanị ya na `lint`. -- **Nnyocha CVE** — ❌ **Ọ BỤGHỊ njikọ dị ọcha.** `audit:deps` na-akwụsị ozugbo ma ọ bụrụ na e nwere CVE ọ bụla dị elu/dị oke egwu; `check:vuln-ratchet` (osv) na-akwụsị naanị mgbe e nwere _nlaghachi azụ_ ma e jiri ya tụnyere baseline (ugbu a 1 MODERATE). Ihe ha pụtara dị iche — iwepụ `audit:deps` ga-eme ka gate zuru oke maka ihe dị elu/dị oke egwu funahụ. Debe ha abụọ. -- **Nchọpụta cycle** — ❌ **Ọ BỤGHỊ njikọ dị ọcha.** `check:circular-deps` (dpdm) na-akọ **cycle 91** (ọ bụ ya mere o ji bụrụ naanị ndụmọdụ); enweghị ike ime ka ọ bụrụ ihe na-egbochi ruo mgbe e buru ụzọ dozie ha, ọ na-ekpuchikwa akụkụ sara mbara karịa `check:cycles` ahọpụtara nke ọma ma na-aga nke ọma. Debe `check:cycles` ka ọ bụrụ ihe na-egbochi; idozi cycle dpdm 91 ahụ bụ backlog nke ya. -- **Mgbagwoju anya** — ✅ **EMECHALA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): otu ngafe ESLint, na-agụ site na ruleId ka baseline cyclomatic+max-lines na cognitive wee nọgide na-anọrọ onwe ha; `check:complexity` / `check:cognitive-complexity` nke ọ bụla ka dị maka `--update` mpaghara. -- **Mgbochi echiche ụgha nke `/api`** — ✅ **EMECHALA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): otu ndepụta FS nke `src/app/api`, openapi-routes + docs-symbols ka na-enye akụkọ nke ha n'onwe ha; nke ọ bụla ka dị maka ịgba ọsọ mpaghara. -- **`check:node-runtime` na-agba n'ọrụ 11** — ⚠️ **ROI dị ala.** Nke ọ bụla bụ runner dị iche, nyocha ahụ na-ewekwa <1s; mkpokọta oge a ga-echekwa bụ ~10s, ma e jiri ya tụnyere ịtụfu nchebe dị ọnụ ala maka ọrụ ọ bụla. O kwesịghị ọgba aghara mgbanwe ahụ. -- **`typecheck:noimplicit:core` na CI lint** — ✅ **ewepụla ya n'ọrụ lint** (ọ bụbu ndụmọdụ nwere `continue-on-error`); elu type na-egbochi bụ `typecheck:core` + `check:type-coverage`. E debere script mpaghara. +- **`check:docs-sync` na-agba ugboro abụọ** — naanị ya na ọrụ `lint`, ma ọzọkwa n'ime `check:docs-all` (`docs-sync-strict`) na husky pre-commit hook. ✅ **EMECHAA** — ewepụla ọkpụkpọ ya kwụụrụ onwe ya na `lint`. +- **Nyocha CVE** — ❌ **Ọ bụghị njikọ dị ọcha.** `audit:deps` na-ada ozugbo ma ọ bụrụ na e nwere CVE ọ bụla dị elu/dị oke egwu; `check:vuln-ratchet` (osv) na-ada naanị mgbe e nwere _nlaghachi azụ_ ma e jiri ya tụnyere baseline (ugbu a 1 MODERATE). Ihe ha pụtara dị iche — iwepụ `audit:deps` ga-eme ka gate zuru oke maka ihe dị elu/dị oke egwu funahụ. Debe ha abụọ. +- **Nchọpụta okirikiri** — ✅ **EMECHAA** (#15159 G-01/G-02). Ederede ochie ebe a kpọrọ `check:cycles` gate "na-acha akwụkwọ ndụ, ahọpụtara nke ọma" ma kwado ka ọ nọgide na-egbochi n'ihi na `check:circular-deps` (dpdm) gosipụtara okirikiri 91. Agba akwụkwọ ndụ ahụ bụ **agba akwụkwọ ndụ ụgha**: `check:cycles` nyochara subdirectory 5 (faịlụ 450), dakọtara naanị static `import|export … from`, ma wepụ specifier `@/` na `@omniroute/open-sse/` niile, ya mere ọ pụghị ịhụ okirikiri dynamic-import + alias ndị jupụtara na repo ahụ. Edozila ya: gate ahụ na-agafe ugbu a na `src` + `open-sse` (faịlụ 5023), na-anakọta specifier site na TypeScript AST (ya mere `import("…")` na-agụta mana `typeof import("…")` nọ n'ọnọdụ type anaghị agụta), ma na-edozi tsconfig `paths`. Ọ na-achọta okirikiri **14**, ọ bụghị 0. Ebe ọ bụ na enweghị ike idozi okirikiri 14 dịbu adị n'ime gate PR, `check:cycles` abụrụla **ratchet** ugbu a (`--ratchet`, oke elu `metrics.cycles.value = 14` na `quality-baseline.json`, `direction: down`) — ọ na-egbochi _nlaghachi azụ_ ọ bụla, ọnụ ọgụgụ ahụ nwekwara ike naanị ibelata. CI na-agba `npm run check:cycles:ratchet`. Mbelata ya ga-eso **A-01** gaa n'ihu. `check:circular-deps` (dpdm) na-anọgide dịka ndụmọdụ nke na-enye echiche nke abụọ sara mbara. +- **Mgbagwoju anya** — ✅ **EMECHAA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): otu ngafe ESLint, na-agụta dịka ruleId ka baseline cyclomatic+max-lines na cognitive wee nọgide na-anọpụ iche; `check:complexity` / `check:cognitive-complexity` nke ọ bụla ka dị maka `--update` mpaghara. +- **Mgbochi echiche ụgha nke `/api`** — ✅ **EMECHAA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): otu ndepụta FS nke `src/app/api`; openapi-routes + docs-symbols ka na-enye akụkọ iche iche; nke ọ bụla ka dị maka ịgba ọsọ mpaghara. +- **`check:node-runtime` na-agba n'ọrụ 11** — ⚠️ **ROI dị ala.** Nke ọ bụla bụ runner dị iche, nyocha ahụ erughị 1s; mkpokọta oge echekwara bụ ihe dịka ~10s, mana nke ahụ ga-efu nchebe dị ọnụ ala n'ọrụ ọ bụla. O kwesịghị ọgba aghara mgbanwe ahụ. +- **`typecheck:noimplicit:core` na CI lint** — ✅ **ewepụla ya na ọrụ lint** (ọ bụbu ndụmọdụ `continue-on-error`); mpaghara type na-egbochi bụ `typecheck:core` + `check:type-coverage`. E debere script mpaghara. -### Gbanwee / kpebie (iwu onye na-ahụ maka usoro) +### Tụgharịa / kpebie (iwu ọrụ onye na-ahụ maka ya) -- `check:openapi-security-tiers` (ndụmọdụ) — ❌ **A PỤGHỊ ịgbanwe ya ozugbo n'enweghị nsogbu.** Ọ na-eji 0 pụọ mana ọ na-adọ aka ná ntị na ọtụtụ route `traffic-inspector` dị n'okpuru `LOCAL_ONLY_API_PREFIXES` enweghị nkọwa `x-loopback-only: true`. Ime ka ọ bụrụ iwu chọrọ ka e buru ụzọ tinye nkọwa ndị ahụ na `openapi.yaml`. -- `typecheck:noimplicit:core` (ndụmọdụ) — ratchet `check:type-coverage` na-egbochi ekpuchilarị ọtụtụ ọrụ ya. Gbanwee ya ka ọ bụrụ ratchet ma ọ bụ wepụ ngafe `tsc` nke abụọ nke na-eme otu ọrụ ahụ. -- `test:vitest:ui` (ugbu a ọ bụ **ihe na-egbochi**) — ewepụla ọdịda ndị dịbu adị kpọmkwem na `vitest.config.ts` site na nkọwa nsuso `// #8618`; ọdịda ọhụrụ ga-eme ka ọrụ ahụ daa. -- `check:secrets` (gitleaks, ratchet na-egbochi nke a kpọchiri na false-positive 3 edekọtara) — tinye 3 ahụ na allowlist iji ruo 0, ma ọ bụ wedata ya ka ọ bụrụ ndụmọdụ. Ọ na-ekpuchi ụfọdụ otu ebe GitHub native secret-scanning + `check:public-creds` na-ekpuchi. -- `check:pr-evidence` (na-egbochi, na-eji grep enyocha prose dị na PR-body) — ihe ize ndụ false-positive dị elu; iwepụ ya ga-eme ka mmanye Hard Rule #18 ghara isi ike, ya mere nke a bụ ezigbo mkpebi iwu. -- `semgrep` (ndụmọdụ kwụụrụ onwe ya) — ya na CodeQL na-ekpuchi otu ezinụlọ OWASP ụfọdụ; jikọta baseline ya na ratchet ma ọ bụ wepụ ya. +- `check:openapi-security-tiers` (ndụmọdụ) — ❌ **Enweghị ike ịtụgharị ya n'ụzọ dị ọcha.** Ọ na-eji 0 pụọ mana na-adọ aka ná ntị na ọtụtụ route `traffic-inspector` dị n'okpuru `LOCAL_ONLY_API_PREFIXES` enweghị annotation `x-loopback-only: true`. Ịmanye ya chọrọ ibu ụzọ tinye annotation ndị ahụ na `openapi.yaml`. +- `typecheck:noimplicit:core` (ndụmọdụ) — ratchet `check:type-coverage` na-egbochi ihe anọchiwo ọtụtụ ọrụ ya. Tụgharịa ya ka ọ bụrụ ratchet ma ọ bụ wepụ ngafe `tsc` nke abụọ na-eme otu ọrụ ọzọ. +- `test:vitest:ui` (ugbu a **na-egbochi**) — ewepụla ọdịda ndị dịbu adị kpọmkwem na `vitest.config.ts` site na comment nsuso `// #8618`; ọdịda ọhụrụ ga-eme ka ọrụ ahụ daa. +- `check:secrets` (gitleaks, ratchet na-egbochi nke akpọchiri na false-positive 3 edere n'akwụkwọ) — tinye atọ ahụ na allowlist ka ọ ruo 0, ma ọ bụ wedata ya ka ọ bụrụ ndụmọdụ. Ọ na-ekpuchi ụfọdụ ọrụ GitHub native secret-scanning + `check:public-creds` na-arụ. +- `check:pr-evidence` (na-egbochi, na-eji grep chọọ prose dị na PR-body) — ihe ize ndụ false-positive dị elu; iwepụ ya ga-eme ka mmanye Hard Rule #18 ghara ịdị ike, ya mere nke a bụ ezigbo mkpebi iwu ọrụ. +- `semgrep` (ndụmọdụ kwụụrụ onwe ya) — ya na CodeQL na-ekpuchi ụfọdụ otu OWASP; jikọta baseline ya na ratchet ma ọ bụ wepụ ya. --- diff --git a/docs/i18n/it/CONTRIBUTING.md b/docs/i18n/it/CONTRIBUTING.md index 2fa45424464..62ff673dc55 100644 --- a/docs/i18n/it/CONTRIBUTING.md +++ b/docs/i18n/it/CONTRIBUTING.md @@ -388,22 +388,22 @@ Scrivere test unitari in `tests/unit/` che coprano almeno: --- -## Checklist della Pull Request +## Checklist della pull request - [ ] I test vengono superati (`npm test`) - [ ] Il linting viene superato (`npm run lint`) -- [ ] La build viene completata correttamente (`npm run build`) +- [ ] La build viene completata con successo (`npm run build`) - [ ] Sono stati aggiunti i tipi TypeScript per le nuove funzioni e interfacce pubbliche - [ ] Nessun segreto o valore di fallback codificato direttamente -- [ ] Le credenziali upstream pubbliche sono incorporate tramite `resolvePublicCred()` (vedere [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), mai come valori letterali -- [ ] Le risposte di errore passano attraverso `buildErrorBody()` / `sanitizeErrorMessage()` — nessuna traccia dello stack non elaborata nei corpi delle risposte (vedere [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] I comandi shell (`exec` / `spawn`) passano i valori di runtime tramite `env`, non mediante interpolazione di stringhe -- [ ] Tutti gli input sono convalidati con schemi Zod +- [ ] Le credenziali pubbliche upstream sono incorporate tramite `resolvePublicCred()` (vedere [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), mai come valori letterali +- [ ] Le risposte di errore vengono gestite tramite `buildErrorBody()` / `sanitizeErrorMessage()` — nessuna traccia dello stack non elaborata nei corpi delle risposte (vedere [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] I comandi shell (`exec` / `spawn`) passano i valori di runtime tramite `env`, non tramite interpolazione di stringhe +- [ ] Tutti gli input vengono convalidati con schemi Zod - [ ] È stato aggiunto un **frammento** del changelog in `changelog.d/{features|fixes|maintenance}/-.md` per le modifiche visibili agli utenti (vedere [`changelog.d/README.md`](./changelog.d/README.md)) — **non** modificare direttamente `CHANGELOG.md`; i frammenti vengono aggregati al momento del rilascio e non generano mai conflitti tra le PR - [ ] La documentazione è stata aggiornata (se applicabile) -- [ ] Nessun nuovo avviso CodeQL / Secret-Scanning aperto, oppure ciascun avviso è stato ignorato con una giustificazione tecnica che fa riferimento al documento pertinente in `docs/security/` -- [ ] Le route che generano processi figli (`/api/mcp/`, `/api/cli-tools/runtime/`) sono classificate come `isLocalOnlyPath()` in `src/server/authz/routeGuard.ts` — vedere [Regola inderogabile n. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Nessun trailer `Co-Authored-By` nei messaggi di commit — i commit devono risultare esclusivamente associati all'identità Git del proprietario del repository (Regola inderogabile n. 16) +- [ ] Non sono stati generati nuovi avvisi CodeQL / Secret-Scanning oppure ciascuno è stato ignorato con una giustificazione tecnica che fa riferimento al documento pertinente in `docs/security/` +- [ ] Le route che generano processi figlio (`/api/mcp/`, `/api/cli-tools/runtime/`) sono classificate come `isLocalOnlyPath()` in `src/server/authz/routeGuard.ts` — vedere la [Regola tassativa n. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Nessun trailer `Co-authored-by` relativo ad AI/bot nei messaggi di commit (Regola tassativa n. 16) — i collaboratori umani il cui lavoro viene riutilizzato sono accreditati con trailer standard `Co-authored-by: Name ` --- diff --git a/docs/i18n/it/docs/architecture/QUALITY_GATES.md b/docs/i18n/it/docs/architecture/QUALITY_GATES.md index 1b7dacc0c20..77076db4f2c 100644 --- a/docs/i18n/it/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/it/docs/architecture/QUALITY_GATES.md @@ -19,215 +19,217 @@ replicazione indipendente dagli strumenti dello stesso sistema, consulta il ### Ammissione dei candidati -I workflow CI e Quality Gates emettono ciascuno un verdetto stabile: `Gate / CI` e -`Gate / Quality`. La rispettiva policy di ammissione versionata elenca ogni job upstream -come obbligatorio o consultivo. Un job obbligatorio applicabile deve avere esito positivo: +I workflow CI e Quality Gates producono ciascuno un verdetto stabile: `Gate / CI` e +`Gate / Quality`. La relativa politica di ammissione versionata classifica ogni job +a monte come obbligatorio o consultivo. Un job obbligatorio applicabile deve riuscire: risultati mancanti, annullati, ignorati, in sospeso e sconosciuti non possono determinare -un esito PASS. Una classificazione valida come solo documentazione o solo catalogo può -rendere non applicabile una lane di codice; una PR in bozza non è un candidato accettato. -Un'etichetta `hotfix` non esonera dalla presentazione delle evidenze. +un esito PASS. Una classificazione valida come docs-only o catalog-only può rendere +non applicabile una lane di codice; una PR in bozza non è un candidato accettato. +Un'etichetta `hotfix` non esenta dall'obbligo di fornire evidenze. -Entrambi i workflow coprono le PR e i push sui branch main/release, l'avvio manuale e -gli eventi merge-group. Push, avvio manuale e merge-group eseguono la selezione completa. +Entrambi i workflow coprono le PR e i push verso i branch main/release, l'avvio manuale +e gli eventi merge-group. Push, avvio manuale e merge-group eseguono la selezione completa. I fork e i merge group utilizzano runner ospitati per i job che altrimenti selezionerebbero runner self-hosted; prima del rollout deve essere verificata una capacità ospitata sufficiente. Ogni ricevuta JSON identifica lo SHA sottoposto a checkout, l'esecuzione del workflow e il tentativo. -La CLI rifiuta una mancata corrispondenza tra lo SHA del checkout e quello dell'evento. I test del -workflow associano l'appartenenza alla policy all'elenco `needs` del job di verdetto, affinché una -lane nuova o rimossa non possa scomparire senza essere rilevata. Le ricevute coprono il workflow -di appartenenza, non la pubblicazione, il deployment o i meccanismi interni di uno scanner -consultivo esistente. L'attivazione di entrambi i nomi dei check nelle regole del branch è una -modifica amministrativa separata; l'aggiunta di questi job non protegge di per sé un branch. +La CLI rifiuta una mancata corrispondenza tra lo SHA del checkout e quello dell'evento. I test del workflow +vincolano l'appartenenza alla politica all'elenco `needs` del job del verdetto, in modo che una lane nuova +o rimossa non possa scomparire silenziosamente. Le ricevute coprono il workflow a cui appartengono, +non la pubblicazione, il deployment o il funzionamento interno di uno scanner consultivo esistente. +L'attivazione di entrambi i nomi dei check nelle regole dei branch è una modifica amministrativa +separata; l'aggiunta di questi job non protegge di per sé un branch. -### Inventario delle scansioni statiche +### Inventario della scansione statica L'inventario versionato degli alias npm e l'appartenenza alla scansione statica si trovano in -`config/quality/gate-manifest.json`. Eseguire `npm run check:gate-manifest` per convalidare +`config/quality/gate-manifest.json`. Esegui `npm run check:gate-manifest` per convalidare i nomi degli script e i comandi esatti rispetto a `package.json`; aggiunte, rimozioni e -variazioni dei comandi fanno fallire sia l'hook locale sia i job di classificazione delle -modifiche in CI. Un alias non è un job del workflow, un'istanza della matrice o un caso di test: -questi conteggi non devono essere presentati come intercambiabili. +variazioni dei comandi causano il fallimento sia dell'hook locale sia dei job di classificazione +delle modifiche nella CI. Un alias non è un job del workflow, un'istanza della matrice o un caso +di test: questi conteggi non devono essere presentati come intercambiabili. -Usare `npm run quality:scan -- --list` o `npm run quality:scan:fast -- --list` +Usa `npm run quality:scan -- --list` o `npm run quality:scan:fast -- --list` per esaminare gli alias selezionati senza eseguirli. Il runner richiama l'entrypoint -npm, preservandone quindi il runtime, incluso Bun dove configurato. +npm, preservandone così il runtime (incluso Bun, ove configurato). Il manifest registra gli alias esterni a tali profili come richiamati separatamente e -i comandi di manutenzione sono vietati nei profili di scansione di sola lettura. +i comandi di manutenzione sono vietati nei profili di scansione in sola lettura. -Questi profili coprono esclusivamente la scansione statica. Non certificano i test del prodotto, +Questi profili coprono soltanto la scansione statica. Non certificano i test del prodotto, la copertura, il packaging, i check esterni o l'accettazione completa di un candidato per il rilascio. -L'ammissione del workflow usa i file collegati `config/quality/admission-policy.json` e +L'ammissione del workflow utilizza i file collegati `config/quality/admission-policy.json` e `scripts/quality/admission-verdict.mjs`. I profili release-observer rimangono separati; -esaminare indipendentemente i relativi check e le ricevute applicabili. L'inventario -testuale riportato di seguito è un riferimento, non una prova dell'effettiva esecuzione di un gate. +esamina in modo indipendente i check e le ricevute applicabili. L'inventario +descrittivo riportato di seguito è un riferimento, non una prova dell'effettiva esecuzione di un gate. -Gli script si trovano in `scripts/check/` (gate di policy) e `scripts/quality/` (motore ratchet). -La fonte autorevole per la CI è `.github/workflows/ci.yml`. +Gli script si trovano in `scripts/check/` (gate delle politiche) e `scripts/quality/` (motore ratchet). +La fonte autorevole della CI è `.github/workflows/ci.yml`. ### Percorso rapido per le PR di rilascio (`quality.yml`) -`.github/workflows/quality.yml` integra la CI per le PR main/release, i push sui branch protetti, -l'avvio manuale e i merge group. Le PR utilizzano check rapidi filtrati in base ai percorsi. La build -duplicata, permanentemente disabilitata, è stata rimossa; i veri check di build/package/avvio -rimangono nella CI. - -| Job | Ambito | Bloccante | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `Docs Gates (fast-path)` | PR di documentazione/codice; riferimenti alla documentazione API e tutta la documentazione | Sì | -| `Fast Quality Gates` | PR di codice; check statici, typecheck, typecheck della dashboard, test unitari interessati | Sì | -| `Forgotten sibling tests` | PR di codice; moduli modificati tracciati fino ai consumer statici e ai test sibling candidati; i percorsi tramite barrel e import dinamici sono segnalati come diagnostica consultiva, con le eccezioni dell'allowlist di riferimento | **Consultivo** | -| `Vitest (fast-path)` | PR di codice; suite vitest rapida | Sì | -| `Unit Tests fast-path` | PR di codice; suite unitaria suddivisa in 4 shard | Sì | -| `No new ESLint warnings` | PR di codice; protezione lint consapevole delle soppressioni | Sì, inclusi i fork | -| `Merge integrity (changelog + generated skills)` | PR non in bozza; sincronizzazione del changelog e delle skill generate | Sì, inclusi i fork | +`.github/workflows/quality.yml` integra la CI per le PR main/release, i push verso branch +protetti, l'avvio manuale e i merge group. Le PR utilizzano controlli rapidi filtrati in base ai percorsi. +La build duplicata, disabilitata in modo permanente, è stata rimossa; i controlli effettivi di +build/package/avvio rimangono nella CI. + +| Job | Ambito | Bloccante | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `Docs Gates (fast-path)` | PR di documentazione/codice; riferimenti alla documentazione API e docs-all | Sì | +| `Fast Quality Gates` | PR di codice; controlli statici, typecheck, typecheck della dashboard, unit test interessati | Sì | +| `Forgotten sibling tests` | PR di codice; moduli modificati ricondotti ai consumer statici e ai test sibling candidati; i percorsi barrel e dynamic-import sono segnalati come diagnostica consultiva, con le eccezioni dell'allowlist indicate | **Consultivo** | +| `Vitest (fast-path)` | PR di codice; suite Vitest rapida | Sì | +| `Unit Tests fast-path` | PR di codice; suite di unit test suddivisa in 4 shard | Sì | +| `No new ESLint warnings` | PR di codice; protezione lint consapevole delle soppressioni | Sì, inclusi i fork | +| `Merge integrity (changelog + generated skills)` | PR non in bozza; sincronizzazione del changelog e delle skill generate | Sì, inclusi i fork | #### Report sui test sibling dimenticati -`npm run check:forgotten-sibling-tests` riutilizza il risolutore degli import alla base della mappa -dell'impatto dei test. Per ogni modulo di produzione modificato, segnala catene deterministiche -`changed module/symbol -> static consumer -> candidate sibling test` quando il test candidato -è assente dal diff della pull request. Il riepilogo Markdown e il risultato JSON vengono conservati -come artefatto del workflow `forgotten-sibling-tests` per la calibrazione prima di qualsiasi rollout -bloccante. +`npm run check:forgotten-sibling-tests` riutilizza il resolver delle importazioni alla base della mappa dell'impatto dei test. +Per ogni modulo di produzione modificato, segnala catene deterministiche +`modulo/simbolo modificato -> consumer statico -> test sibling candidato` quando il test candidato +non è presente nel diff della pull request. Il riepilogo Markdown e il risultato JSON vengono conservati come +artefatto del workflow `forgotten-sibling-tests` per la calibrazione prima di qualsiasi rollout bloccante. -Le riesportazioni barrel e le importazioni dinamiche sono esclusivamente diagnostiche di risoluzione; non generano mai un rilievo bloccante. Le eccezioni revisionate si trovano in +Le riesportazioni tramite barrel e le importazioni dinamiche sono solo diagnostiche di risoluzione; non generano mai un +rilievo bloccante. Le eccezioni esaminate si trovano in `config/quality/forgotten-sibling-allowlist.json`. Ogni voce deve indicare il consumer e il test candidato, fornire una motivazione specifica e includere un link a una issue o pull request di GitHub. Le voci non valide causano -il fallimento in modalità chiusa. Le eccezioni non possono ignorare un test candidato eliminato o una diff che aggiunge `.skip`/`.todo`; -l'indebolimento delle asserzioni e altre forme di mascheramento restano sotto la responsabilità del gate bloccante indipendente +un errore in modalità fail-closed. Le eccezioni non possono ignorare un test candidato eliminato o una diff che aggiunge `.skip`/`.todo`; +l'indebolimento delle asserzioni e altri meccanismi di mascheramento restano sotto la responsabilità del gate bloccante indipendente `check:test-masking`. ### Job: `lint` -Viene eseguito su ogni PR verso `main`. In caso di fallimento, blocca il merge. - -| Script (`npm run ...`) | Verifica | Bloccante | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | La versione di Node.js rientra nell'intervallo supportato | Sì | -| `check:cycles` | Importazioni circolari — tutti i moduli in `src/` + `open-sse/` | Sì | -| `check:route-validation:t06` | Presenza degli schemi Zod su tutte le route (policy Tier 6) | Sì | -| `check:any-budget:t11` | Il numero di `@ts-expect-error // any` non supera il budget (catraca Tier 11) | Sì | -| `check:provider-consistency` | Ogni provider in `providers.ts` ha una voce corrispondente in `providerRegistry.ts` (e viceversa, entro i limiti dell'allowlist) | Sì | -| `check:model-lifecycle` | Le tre tabelle di routing gestite manualmente rimangono coerenti con lo snapshot del ciclo di vita incluso nel repository (#11503): `FITNESS_TABLE` (`taskFitness.ts`) non assegna un punteggio ad alcun id ritirato che `REGISTRY` possa instradare; ogni destinazione di `BUILT_IN_ALIASES` è presente in `REGISTRY` e assente dallo snapshot degli id ritirati; ogni id ritirato ancora presente in `REGISTRY` viene inoltrato o elencato in `allowedRetiredInCatalog`; inoltre, nessuna origine o destinazione di `DEFAULT_DEGRADATION_MAP` risulta ritirata in tale snapshot. Questo non dimostra che un modello sia attualmente servito da un upstream attivo. Offline — esegue il confronto con `config/quality/model-lifecycle.json`, aggiornato manualmente tramite `npm run quality:refresh-model-lifecycle` (richiede la rete; non integrato nella CI). `allowedRetiredInCatalog` è un meccanismo progressivo di riduzione: aggiungere una voce solo se associata a un issue di tracciamento. | Sì | -| `check:fetch-targets` | Ogni `fetch("/api/...")` nel codice lato client in `src/` viene risolto in un `route.ts` reale | Sì | -| `check:deps` | Tutte le dipendenze installabili tramite `npm install` in ogni `package.json` del repository sono incluse in `dependency-allowlist.json`; i nuovi pacchetti senza versione fissata o vittime di slopsquatting vengono segnalati | Sì | -| `audit:deps` | `npm audit` (root + electron) — nessun avviso di gravità alta/critica (si sovrappone a osv `check:vuln-ratchet`; vedere il backlog di razionalizzazione) | Sì | -| `check:lockfile` | Integrità di `package-lock.json` — registro https, hash di integrità, nessuna sostituzione dell'host | Sì | -| `check:licenses` | Elenco consentito di licenze SPDX per le dipendenze di produzione | Sì | -| `check:tracked-artifacts` | Nessun artefatto di build / collegamento simbolico `node_modules` sottoposto a commit (eseguito anche nel pre-commit di husky; il pre-push è intenzionalmente leggero — #6716) | Sì | -| `check:ai-attribution` | Nessun trailer `Co-Authored-By` di IA/bot né piè di pagina relativo alla generazione tramite IA nei commit, nel titolo o nel corpo delle PR — Regola inderogabile #16 (nel ciclo di controlli rapidi di `quality.yml` per PR→`release/**` — legge il payload dell'evento e non esegue alcuna operazione al di fuori delle PR — e in un passaggio riservato alle PR nel lint di `ci.yml` per PR→`main`; inoltre nell'hook `commit-msg` di husky; coautori umani consentiti; #14436) | -| `check:vitest-exclusions` | Ogni esclusione di Vitest indica un issue di tracciamento ed è presente in `config/quality/vitest-exclusions.json` (#13204) | Sì | -| `check:file-size` | Nessun file sorgente supera il limite previsto per la relativa estensione (ratchet: file di grandi dimensioni bloccati nell'elenco `frozen`) | Sì | -| `check:error-helper` | Le risposte di errore negli esecutori/handler utilizzano `buildErrorBody()` / `sanitizeErrorMessage()` (Regola inderogabile #12) | Sì | -| `check:migration-numbering` | I file SQL di migrazione sono numerati in sequenza, senza lacune o duplicati | Sì | -| `check:public-creds` | Nessun valore letterale OAuth `client_id`/`client_secret` o chiave Firebase Web al di fuori di `publicCreds.ts` (Regola rigida n. 11) | Sì | -| `check:db-rules` | Nessun SQL grezzo al di fuori dei moduli `src/lib/db/`; nessuna importazione barrel da `localDb.ts` (Regole rigide n. 2/n. 5) | Sì | -| `check:known-symbols` | Gli esecutori dei provider, le strategie di routing e i traduttori registrati nelle rispettive tabelle di dispatch corrispondono ai file su disco, senza simboli orfani o non dichiarati | Sì | -| `check:route-guard-membership` | Ogni route che genera un processo figlio è classificata da `isLocalOnlyPath()` (Regole rigide n. 15/n. 17) | Sì | -| `check:test-discovery` | Ogni file `*.test.ts` / `*.spec.ts` nel repository viene raccolto da almeno un test runner (ratchet: l'elenco dei file orfani in `test-discovery-baseline.json` può solo ridursi) | Sì | -| `check:agent-skills-sync` | Gli artefatti agent-skills generati corrispondono al relativo catalogo sorgente (nessuna divergenza) | -| `check:provider-asset-provenance` | I loghi/gli asset dei provider dispongono di una voce di provenienza registrata | -| `lint:json` | I file di configurazione JSON vengono analizzati correttamente e soddisfano le regole di lint del repository | -| `typecheck:core` | Compilazione TypeScript senza errori (solo avvisi consultivi) | Sì | -| `typecheck:noimplicit:core` | `noImplicitAny` rigoroso — orientato al futuro; molti call site preesistenti richiedono ancora annotazioni | **Consultivo** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limitato a `src/app/(dashboard)/**` (#7033) — l'allowlist selezionata di 27 file di `typecheck:core` non include alcun TSX della dashboard e nemmeno `next build` ne esegue il controllo dei tipi (`next.config.mjs` imposta `ignoreBuildErrors: true`), quindi le regressioni relative a identificatori orfani presenti in tale area (#6625/#6909) non erano visibili alla CI. Esegue il confronto con una baseline bloccata del conteggio per file/per codice TS (`config/quality/dashboard-typecheck-baseline.json`, seguendo lo stesso schema di controllo delle voci obsolete di `check:known-symbols`) — solo i NUOVI errori oltre il conteggio della baseline fanno fallire il controllo; ridurre progressivamente la baseline con `--update` quando viene corretto un errore preesistente. | Sì | +Viene eseguito su ogni PR verso `main`. In caso di errore, blocca il merge. + +| Script (`npm run ...`) | Verifica | Bloccante | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | +| `check:node-runtime` | La versione di Node.js rientra nell'intervallo supportato | Sì | +| `check:cycles` | Importazioni circolari nell'intero ambito di `src/` + `open-sse/` (basato su AST, con risoluzione dei `paths` di tsconfig). L'esecuzione semplice è consultiva ed elenca i cicli. `check:cycles:ratchet` (quello eseguito dalla CI) blocca quando il conteggio supera il limite massimo `metrics.cycles` in `quality-baseline.json` — attualmente 14, `direction: down`, quindi può solo diminuire (#15159 G-01/G-02) | Sì (ratchet) | +| `check:route-validation:t06` | Presenza degli schemi Zod su tutte le route (policy di livello 6) | Sì | +| `check:any-budget:t11` | Il conteggio di `@ts-expect-error // any` non supera il budget (ratchet di livello 11) | Sì | +| `check:provider-consistency` | Ogni provider in `providers.ts` ha una voce corrispondente in `providerRegistry.ts` (e viceversa, nei limiti dell'allowlist) | Sì | +| `check:model-lifecycle` | Le tre tabelle di routing gestite manualmente rimangono coerenti con lo snapshot del ciclo di vita incluso nel repository (#11503): `FITNESS_TABLE` (`taskFitness.ts`) non assegna un punteggio ad alcun id ritirato che `REGISTRY` possa instradare; ogni destinazione di `BUILT_IN_ALIASES` è presente in `REGISTRY` e assente dallo snapshot degli id ritirati; ogni id ritirato ancora presente in `REGISTRY` viene inoltrato oppure elencato in `allowedRetiredInCatalog`; inoltre, nessuna origine o destinazione di `DEFAULT_DEGRADATION_MAP` risulta ritirata in tale snapshot. Ciò non dimostra che un modello sia attualmente erogato da un upstream attivo. Offline — esegue il confronto con `config/quality/model-lifecycle.json`, aggiornato manualmente con `npm run quality:refresh-model-lifecycle` (rete; non integrato nella CI). `allowedRetiredInCatalog` è un meccanismo di riduzione progressiva: aggiungere una voce solo in presenza di un issue di tracciamento. | Sì | +| `check:fetch-targets` | Ogni `fetch("/api/...")` nel codice lato client in `src/` si risolve in un file `route.ts` reale | Sì | +| `check:deps` | Tutte le dipendenze installabili con `npm install` in ogni `package.json` del repository sono presenti in `dependency-allowlist.json`; i nuovi pacchetti senza versione bloccata o soggetti a slopsquatting vengono segnalati | Sì | +| `audit:deps` | `npm audit` (root + electron) — nessun avviso di gravità alta/critica (si sovrappone al controllo OSV `check:vuln-ratchet`; vedere il backlog di razionalizzazione) | Sì | +| `check:lockfile` | Integrità di `package-lock.json` — registro https, hash di integrità, nessuna sostituzione degli host | Sì | +| `check:licenses` | Elenco consentito di licenze SPDX per le dipendenze di produzione | Sì | +| `check:tracked-artifacts` | Nessun artefatto di build / link simbolico `node_modules` registrato nel repository (viene eseguito anche nel pre-commit di husky; il pre-push è intenzionalmente leggero — #6716) | Sì | +| `check:ai-attribution` | Nessun trailer `Co-Authored-By` di IA/bot o piè di pagina relativo alla generazione tramite IA nei commit, nel titolo o nel corpo delle PR — Regola inderogabile #16 (nel ciclo fast-gates di `quality.yml` per PR→`release/**` — legge il payload dell'evento, non esegue alcuna operazione al di fuori delle PR — e in un passaggio riservato alle PR nel lint di `ci.yml` per PR→`main`; anche nell'hook `commit-msg` di husky; sono consentiti i coautori umani; #14436) | +| `check:vitest-exclusions` | Ogni esclusione di Vitest indica un issue di tracciamento ed è presente in `config/quality/vitest-exclusions.json` (#13204) | Sì | +| `check:file-size` | Nessun file sorgente supera il limite previsto per la relativa estensione (ratchet: file di grandi dimensioni bloccati nell'elenco `frozen`) | Sì | +| `check:error-helper` | Le risposte di errore negli executor/handler utilizzano `buildErrorBody()` / `sanitizeErrorMessage()` (Regola inderogabile #12) | Sì | +| `check:migration-numbering` | I file SQL di migrazione sono numerati in sequenza, senza interruzioni o duplicati | Sì | +| `check:public-creds` | Nessun valore letterale OAuth `client_id`/`client_secret` o chiave Web Firebase al di fuori di `publicCreds.ts` (Regola rigida n. 11) | Sì | +| `check:db-rules` | Nessun SQL non elaborato al di fuori dei moduli `src/lib/db/`; nessuna importazione barrel da `localDb.ts` (Regole rigide n. 2/n. 5) | Sì | +| `check:known-symbols` | Gli esecutori dei provider, le strategie di routing e i traduttori registrati nelle rispettive tabelle di dispatch corrispondono ai file su disco, senza simboli orfani o non dichiarati | Sì | +| `check:route-guard-membership` | Ogni route che genera un processo figlio è classificata da `isLocalOnlyPath()` (Regole rigide n. 15/n. 17) | Sì | +| `check:test-discovery` | Ogni file `*.test.ts` / `*.spec.ts` nel repository viene rilevato da almeno un test runner (vincolo progressivo: l'elenco degli orfani in `test-discovery-baseline.json` può solo ridursi) | Sì | +| `check:agent-skills-sync` | Gli artefatti agent-skills generati corrispondono al relativo catalogo sorgente (nessuna divergenza) | +| `check:provider-asset-provenance` | I loghi/gli asset dei provider dispongono di una voce di provenienza registrata | +| `lint:json` | I file di configurazione JSON vengono analizzati correttamente e soddisfano le regole di lint del repository | +| `typecheck:core` | Compilazione TypeScript senza errori (solo avvisi consultivi) | Sì | +| `typecheck:noimplicit:core` | `noImplicitAny` rigoroso — orientato al futuro; molti siti di chiamata preesistenti richiedono ancora annotazioni | **Consultivo** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` limitato a `src/app/(dashboard)/**` (#7033) — l’elenco consentito selezionato di 27 file di `typecheck:core` non include alcun TSX della dashboard e nemmeno `next build` ne esegue il controllo dei tipi (`next.config.mjs` imposta `ignoreBuildErrors: true`), quindi le regressioni relative a identificatori orfani presenti lì (#6625/#6909) erano invisibili alla CI. Confronta i risultati con una baseline bloccata dei conteggi per file/per codice TS (`config/quality/dashboard-typecheck-baseline.json`, lo stesso schema di controllo dell’obsolescenza usato da `check:known-symbols`) — solo i NUOVI errori oltre il conteggio della baseline fanno fallire il gate; ridurre progressivamente la baseline con `--update` quando viene corretto un errore preesistente. | Sì | ### Job: `quality-gate` -Viene eseguito dopo `test-coverage`. Impedisce il merge in caso di errore. +Viene eseguito dopo `test-coverage`. Blocca il merge in caso di errore. -| Script | Verifica | Bloccante | -| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | Genera `quality-metrics.json` (numero di avvisi ESLint, copertura dal report combinato degli shard) | Sì (a monte del ratchet) | -| `quality:ratchet` | Nessuna metrica in `quality-baseline.json` è peggiorata (avvisi ESLint ≤ baseline; copertura ≥ baseline) | Sì | -| `check:duplication` | La duplicazione del codice (jscpd@4) non supera la baseline in `quality-baseline.json` | Sì | -| `check:complexity` | La complessità ciclomatica a livello di file non supera il limite (regole ESLint di base `complexity` + `max-lines-per-function`) | Sì | -| `check:cognitive-complexity` | Ratchet della complessità cognitiva (`eslint-plugin-sonarjs`) — passaggio ESLint separato; la CI esegue entrambi insieme nel singolo passaggio `check:complexity-ratchets` | Sì | -| `check:dead-code` | Il ratchet di esportazioni/file inutilizzati (knip) non peggiora rispetto alla baseline | Sì | -| `check:compression-budget` | Budget del benchmark di compressione — le soglie minime di risparmio di token per motore non devono peggiorare | Sì | -| `check:type-coverage` | Il ratchet della percentuale di codice tipizzato (`type-coverage`) non peggiora; sostituisce in gran parte `typecheck:noimplicit:core` | Sì | -| `check:codeql-ratchet` | Il numero di avvisi CodeQL aperti non peggiora (lettura tramite `gh api`; esclusione controllata senza token) — per la frequenza di aggiornamento e l'attivazione manuale, vedere "Ratchet CodeQL" sotto | Sì | +| Script | Verifica | Bloccante | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | Genera `quality-metrics.json` (numero di avvisi ESLint, copertura dal report aggregato degli shard) | Sì (a monte del ratchet) | +| `quality:ratchet` | Nessuna metrica in `quality-baseline.json` è peggiorata (avvisi ESLint ≤ baseline; copertura ≥ baseline) | Sì | +| `check:duplication` | La duplicazione del codice (jscpd@4) non supera la baseline in `quality-baseline.json` | Sì | +| `check:complexity` | La complessità ciclomatica a livello di file non supera il limite (`complexity` di ESLint core + `max-lines-per-function`) | Sì | +| `check:cognitive-complexity` | Ratchet della complessità cognitiva (`eslint-plugin-sonarjs`) — passaggio ESLint separato; la CI esegue entrambi accorpandoli nell'unico passaggio `check:complexity-ratchets` | Sì | +| `check:dead-code` | Il ratchet di esportazioni/file inutilizzati (knip) non peggiora rispetto alla baseline | Sì | +| `check:compression-budget` | Budget del benchmark di compressione — le soglie minime di risparmio dei token per motore non devono peggiorare | Sì | +| `check:type-coverage` | Il ratchet della percentuale di codice tipizzato (`type-coverage`) non peggiora; sostituisce in gran parte `typecheck:noimplicit:core` | Sì | +| `check:codeql-ratchet` | Il numero di avvisi CodeQL aperti non peggiora (lettura tramite `gh api`; ignorato senza errori in assenza di token) — per la frequenza di aggiornamento e l'attivazione manuale, vedere "Ratchet CodeQL" di seguito | Sì | ### Job: `quality-extended` L'intero job è consultivo (`continue-on-error: true`). I ratchet basati su npm vengono -eseguiti effettivamente; gli scanner esterni vengono installati tramite `gh release download` e si escludono automaticamente (exit 0) -quando un binario è ancora assente. - -| Script | Verifica | Bloccante | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | -| `check:circular-deps` | Nessuna dipendenza circolare (dpdm) | **Consultivo** | -| `check:bundle-size` | La dimensione del bundle non supera il limite | **Consultivo** | -| `check:secrets` | Scansione dei segreti (gitleaks) — viene ignorata se il binario è assente | **Consultivo** | -| `check:vuln-ratchet` | Le vulnerabilità delle dipendenze (osv-scanner) non peggiorano — viene ignorato se il binario è assente | **Consultivo** | -| `check:workflows` | Analisi dei workflow (actionlint + zizmor); scanner mancanti/non funzionanti, report non validi o baseline del ratchet mancante causano un errore INCOMPLETE. I risultati validi seguono la policy selezionata: rigorosa/consultiva/ratchet | Esecuzione obbligatoria; ratchet zizmor bloccante nella CI | -| `check:openapi-breaking` | Modifiche incompatibili al contratto dell'API pubblica (`openapi.yaml`) rispetto al branch di base (oasdiff) — genera `openapiBreaking=N`; viene ignorato se oasdiff è assente o la specifica di base non è risolvibile | **Consultivo** | +eseguiti effettivamente; gli scanner esterni vengono installati tramite `gh release download` +e si ignorano automaticamente (exit 0) se un eseguibile risulta ancora assente. + +| Script | Verifica | Bloccante | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| `check:circular-deps` | Nessuna dipendenza circolare (dpdm) | **Consultivo** | +| `check:bundle-size` | La dimensione del bundle non supera il limite | **Consultivo** | +| `check:secrets` | Scansione dei segreti (gitleaks) — ignorata se l'eseguibile è assente | **Consultivo** | +| `check:vuln-ratchet` | Le vulnerabilità delle dipendenze (osv-scanner) non peggiorano — ignorato se l'eseguibile è assente | **Consultivo** | +| `check:workflows` | Lint dei workflow (actionlint + zizmor); scanner mancanti/non funzionanti, report non validi o baseline del ratchet mancante causano un errore INCOMPLETE. I risultati validi seguono la policy rigorosa/consultiva/ratchet selezionata | Esecuzione obbligatoria; ratchet zizmor bloccante nella CI | +| `check:openapi-breaking` | Modifiche incompatibili al contratto dell'API pubblica (`openapi.yaml`) rispetto al branch di base (oasdiff) — genera `openapiBreaking=N`; ignorato se oasdiff è assente o se la specifica di base non può essere risolta | **Consultivo** | ### Job: `docs-sync-strict` Viene eseguito su ogni PR verso `main`. Blocca il merge in caso di errore. -| Script | Verifica | Bloccante | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `check:docs-all` | Meta-gate che esegue sequenzialmente i 6 sotto-gate riportati di seguito | Sì | -| ↳ `check:docs-sync` | Coerenza delle versioni tra CHANGELOG / OpenAPI / llm.txt | Sì | -| ↳ `check:docs-counts` | I conteggi nel testo (numero di provider, numero di migrazioni, ecc.) rientrano nella finestra ratchet dei conteggi reali | Sì | -| ↳ `check:env-doc-sync` | Ogni variabile di ambiente in `.env.example` è documentata in una tabella della documentazione e viceversa | Sì | -| ↳ `check:deprecated-versions` | Nessuna stringa di versione deprecata nella documentazione | Sì | -| ↳ `check:doc-links` | I link markdown interni nella documentazione rimandano a file reali (formato `[testo]`/`(percorso)`) | Sì | -| ↳ `check:fabricated-docs` | Le route, le variabili di ambiente, i comandi CLI, i nomi degli hook e i percorsi dei file citati nella documentazione esistono nel codebase. Gate rigido tramite `--strict`; errore non bloccante senza il flag. | Sì (tramite `--strict` nella CI) | -| `check:cli-i18n` | Le stringhe dei comandi CLI sono presenti in tutti i file delle impostazioni locali i18n | Sì | -| `check:openapi-coverage` | La specifica OpenAPI copre almeno una soglia minima soggetta a ratchet delle route reali | Sì | -| `check:openapi-security-tiers` | Le annotazioni dei livelli di sicurezza in `openapi.yaml` sono coerenti con le classificazioni di `routeGuard.ts` | **Consultivo** | -| `check:openapi-routes` | Ogni percorso in `openapi.yaml` corrisponde a un file `route.ts` reale (anti-allucinazione) | Sì | -| `check:docs-symbols` | Ogni riferimento `/api/...` in `docs/**/*.md` corrisponde a un file `route.ts` reale (anti-allucinazione) | Sì | -| `i18n translation drift` | Chiavi non tradotte nei file delle impostazioni locali i18n — solo avviso | **Consultivo** | +| Script | Verifica | Bloccante | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `check:docs-all` | Meta-gate che esegue in sequenza i 6 sotto-gate riportati di seguito | Sì | +| ↳ `check:docs-sync` | Coerenza delle versioni tra CHANGELOG / OpenAPI / llm.txt | Sì | +| ↳ `check:docs-counts` | I conteggi nel testo (numero di provider, numero di migrazioni, ecc.) rientrano nella finestra di ratchet dei conteggi reali | Sì | +| ↳ `check:env-doc-sync` | Ogni variabile d'ambiente in `.env.example` è documentata in una tabella della documentazione e viceversa | Sì | +| ↳ `check:deprecated-versions` | Nessuna stringa di versione deprecata nella documentazione | Sì | +| ↳ `check:doc-links` | I link Markdown interni nella documentazione si risolvono in file reali (formato `[testo]`/`(percorso)`) | Sì | +| ↳ `check:fabricated-docs` | Route, variabili d'ambiente, comandi CLI, nomi degli hook e percorsi di file citati nella documentazione esistono nel codebase. Gate rigido tramite `--strict`; errore non bloccante senza il flag. | Sì (tramite `--strict` nella CI) | +| `check:cli-i18n` | Le stringhe dei comandi CLI sono presenti in tutti i file delle impostazioni locali i18n | Sì | +| `check:openapi-coverage` | La specifica OpenAPI copre almeno una soglia minima, definita tramite ratchet, delle route reali | Sì | +| `check:openapi-security-tiers` | Le annotazioni dei livelli di sicurezza in `openapi.yaml` sono coerenti con le classificazioni di `routeGuard.ts` | **Consultivo** | +| `check:openapi-routes` | Ogni percorso in `openapi.yaml` si risolve in un `route.ts` reale (anti-allucinazione) | Sì | +| `check:docs-symbols` | Ogni riferimento `/api/...` in `docs/**/*.md` si risolve in un `route.ts` reale (anti-allucinazione) | Sì | +| `i18n translation drift` | Chiavi non tradotte nei file delle impostazioni locali i18n — solo avviso | **Consultivo** | ### Job: `i18n-ui-coverage` -| Script | Verifica | Bloccante | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (inline) | La copertura delle chiavi i18n dell'interfaccia utente è ≥ 65% | Sì | -| `check-ui-value-drift` (inline) | La riscrittura di un **valore** inglese non lascia traduzioni obsolete | Sì | -| `check-new-key-coverage` (inline) | Una **nuova** chiave inglese è tradotta in ogni impostazione locale — un marcatore `__MISSING__:` viene rifiutato | Sì | -| `check-translation-ratio` | Il rapporto di traduzioni reali per impostazione locale (valori identici all'inglese / segnaposto / elementi mancanti non inclusi nell'allowlist) non deve superare `config/quality/i18n-translation-baseline.json` + margine | **Consultivo** | +| Script | Verifica | Bloccante | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (inline) | La copertura delle chiavi i18n dell'interfaccia utente è ≥ 65% | Sì | +| `check-ui-value-drift` (inline) | La riscrittura di un **valore** inglese non lascia alcuna traduzione obsoleta | Sì | +| `check-new-key-coverage` (inline) | Una **nuova** chiave inglese è tradotta in ogni impostazione locale — un marcatore `__MISSING__:` viene rifiutato | Sì | +| `check-translation-ratio` | Il rapporto di traduzioni reali per impostazione locale (valori identici all'inglese / segnaposto / elementi mancanti non inclusi nell'elenco consentito) non deve superare `config/quality/i18n-translation-baseline.json` + margine | **Consultivo** | -Richiede `fetch-depth: 0` — il gate value-drift confronta `en.json` con la merge base. +Richiede `fetch-depth: 0` — il gate value-drift confronta `en.json` con la base di merge. #### `check-ui-value-drift` — gate per le traduzioni obsolete -Intercetta l'unica regressione i18n che gli altri gate non possono rilevare strutturalmente: un valore inglese +Rileva l'unica regressione i18n che gli altri gate non possono individuare strutturalmente: un valore inglese viene riscritto e le traduzioni derivate dall'inglese _precedente_ rimangono invariate, quindi -gli utenti non anglofoni continuano a leggere testi formulati in modo autorevole, ma ora errati. +gli utenti non anglofoni continuano a leggere un testo formulato con sicurezza, ma ormai errato. -Questo problema è stato effettivamente distribuito. `oauthModal.googleOAuthWarning` è stato riscritto quando è stato -introdotto l'helper di accesso Antigravity (#5203); **39 impostazioni locali su 43** hanno mantenuto il testo che indicava agli operatori di «copiare +È successo davvero in produzione. `oauthModal.googleOAuthWarning` è stato riscritto quando è stato +introdotto l'helper di accesso Antigravity (#5203); **39 delle 43 impostazioni locali** hanno mantenuto il testo che indicava agli operatori di «copiare l'URL completo e incollarlo qui sotto» — un flusso che non può essere completato per quel provider. Il problema è passato inosservato fino alla #8463 perché: -- `sync-ui-keys` aggiunge solo le chiavi **assenti**, mai quelle **obsolete**; -- `check-ui-keys-coverage` conteggia la _presenza_ delle chiavi, quindi una traduzione obsoleta viene considerata coperta; -- `check-translation-drift` tiene traccia delle copie speculari della documentazione `docs/i18n//**.md` — +- `sync-ui-keys` completa solo le chiavi **assenti**, mai quelle **obsolete**; +- `check-ui-keys-coverage` conta la _presenza_ delle chiavi, quindi una traduzione obsoleta viene considerata coperta; +- `check-translation-drift` monitora le copie speculari della documentazione in `docs/i18n//**.md` — non legge mai `src/i18n/messages/*.json`. Bloccante nel job `docs-sync-strict` dalla - risincronizzazione 2026-09: modifica un documento principale → `npm run i18n:run -- --files=` (a livello di sezione, economico). + risincronizzazione 2026-09: modifica un documento principale → `npm run i18n:run -- --files=` (a livello di sezione, poco costoso). -**Consapevole delle differenze, non basato su una baseline.** Confronta `en.json` alla base di merge con +**Basato sulle differenze, non su una baseline.** Confronta `en.json` alla base di merge con l'albero di lavoro; per ogni chiave il cui valore inglese è cambiato, qualsiasi lingua che -mantenga ancora una traduzione invariata è obsoleta. Questo deliberatamente **congela il debito preesistente**: -una differenza non può rivelare da quale vecchio testo inglese derivi una traduzione presente da tempo, -quindi il controllo valuta solo ciò che viene modificato dalla modifica corrente. L'alternativa (una baseline -di hash per chiave) richiederebbe un file generato di circa 600 KB, 3 volte più grande della maggiore -baseline esistente, modificato a ogni PR di i18n. +contenga ancora una traduzione non modificata è obsoleta. Questo deliberatamente **congela +il debito preesistente**: una differenza non può rivelare da quale vecchio testo inglese +derivi una traduzione esistente da tempo, quindi il controllo valuta solo ciò che viene +toccato dalla modifica corrente. L'alternativa (una baseline con hash per ogni chiave) +richiederebbe un file generato di ~600 KB, 3 volte più grande della maggiore baseline +esistente, con modifiche a ogni PR di internazionalizzazione. -Esistono due modi per soddisfare il controllo: +Due modi per soddisfare il controllo: 1. aggiornare le traduzioni interessate, oppure -2. impostarle su `__MISSING__:` — il runtime fornisce quindi il testo inglese corretto - (`src/i18n/request.ts::deepMergeFallback`, #7258) e la chiave viene accodata per la traduzione. +2. impostarle su `__MISSING__:` — il runtime fornirà quindi il testo inglese + corretto (`src/i18n/request.ts::deepMergeFallback`, #7258) e la chiave verrà accodata + per la traduzione. -Se è cambiato il **significato** della stringa, è preferibile **rinominare la chiave**: una nuova chiave -non può ereditare una traduzione obsoleta. Questo è il modello usato dalla #8463. +Se è cambiato il **significato** della stringa, è preferibile **rinominare la chiave**: una +nuova chiave non può ereditare una traduzione obsoleta. È il modello usato dalla #8463. ```bash npm run i18n:check-value-drift # rigoroso (quello eseguito dalla CI) @@ -235,47 +237,50 @@ npm run i18n:check-value-drift:warn # solo segnalazione BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Termina con codice 0 e `SKIP reason=base-unresolved` quando il catalogo di base non può essere letto -(clone superficiale senza il riferimento di base), analogamente a `check-openapi-breaking`. +Termina con codice 0 e `SKIP reason=base-unresolved` quando il catalogo di base non può +essere letto (clone superficiale senza il riferimento di base), analogamente a +`check-openapi-breaking`. -### Job: `i18n` +### Processo: `i18n` -Matrice completa di convalida i18n (un job per lingua). L'intero job è consultivo. +Matrice completa di convalida dell'internazionalizzazione (un processo per lingua). +L'intero processo è consultivo. -| Script | Convalida | Bloccante | -| ------------------------------- | --------------------------------------- | ---------------------------------------------------------- | -| `validate_translation.py quick` | Completezza della traduzione per lingua | **Consultivo** (`continue-on-error: true` sull'intero job) | +| Script | Convalida | Bloccante | +| ------------------------------- | --------------------------------------- | --------------------------------------------------------------- | +| `validate_translation.py quick` | Completezza della traduzione per lingua | **Consultivo** (`continue-on-error: true` sull'intero processo) | -### Job: `pr-test-policy` +### Processo: `pr-test-policy` Viene eseguito solo sulle pull request. | Script | Convalida | Bloccante | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | Le PR che modificano il codice di produzione in `src/`, `open-sse/`, `electron/` o `bin/` devono includere o aggiornare i test (Regola rigida #8) | Sì | +| `check:pr-test-policy` | Le PR che modificano il codice di produzione in `src/`, `open-sse/`, `electron/` o `bin/` devono includere o aggiornare i test (Regola rigida n. 8) | Sì | | `check:test-masking` | I file di test modificati non riducono il numero netto di asserzioni né aggiungono tautologie `assert.ok(true)` | Sì | -| `check:pr-evidence` | Il corpo della PR cita prove di test/VPS relative alla modifica (automatizza la Regola rigida #18 cercando nel testo della PR — fragile, vedere Arretrati) | Sì | +| `check:pr-evidence` | Il corpo della PR cita prove da test/VPS relative alla modifica (automatizza la Regola rigida n. 18 cercando nel testo della PR — fragile, vedere Backlog) | Sì | -### Job: `test-vitest` +### Processo: `test-vitest` -Viene eseguito dopo `build`. Blocca il merge in caso di errore. +Viene eseguito dopo `build`. In caso di errore, blocca il merge. -| Suite | Convalida | Bloccante | -| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | Server MCP (110 strumenti), autoCombo, cache — runner vitest | Sì | -| `test:vitest:ui` | Test dei componenti dell'interfaccia — runner vitest | **Bloccante** — gli errori preesistenti sono esplicitamente esclusi in `vitest.config.ts`; i nuovi errori fanno fallire il job | +| Suite | Convalida | Bloccante | +| ---------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Server MCP (110 strumenti), autoCombo, cache — runner vitest | Sì | +| `test:vitest:ui` | Test dei componenti UI — runner vitest | **Bloccante** — gli errori preesistenti sono esplicitamente esclusi in `vitest.config.ts`; i nuovi errori fanno fallire il processo | ### Workflow notturni (pianificati, consultivi) -Vengono eseguiti secondo una pianificazione cron (e tramite `workflow_dispatch`), mai sulle PR. Sono tutti consultivi. +Vengono eseguiti secondo una pianificazione cron (e tramite `workflow_dispatch`), mai +sulle PR. Sono tutti consultivi. | Workflow | Convalida | Bloccante | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | Test basati sulle proprietà con fast-check, un seed casuale e un numero elevato di esecuzioni | **Consultivo** | -| `nightly-resilience` | Controllo della crescita dell'heap, iniezione caotica di guasti, test di carico/soak con k6 | **Consultivo** | -| `nightly-llm-security` | Protezione dalle injection di promptfoo (modalità di blocco) + sonde garak (ignorate senza il segreto di un provider) | **Consultivo** | +| `nightly-property` | Test basati sulle proprietà con fast-check, con un seed casuale e un numero elevato di esecuzioni | **Consultivo** | +| `nightly-resilience` | Controllo della crescita dell'heap, iniezione caotica di errori, test di carico/prolungati con k6 | **Consultivo** | +| `nightly-llm-security` | Protezione dalle iniezioni con promptfoo (modalità blocco) + sonde garak (ignorate senza il segreto di un provider) | **Consultivo** | | `nightly-schemathesis` | Fuzzing del contratto OpenAPI (schemathesis) su un'istanza OmniRoute attiva usando `docs/openapi.yaml` — evidenzia violazioni della specifica/errori 500 non gestiti (Fase 8 B.4) | **Consultivo** | -| `nightly-mutation` | Punteggio dei test di mutazione Stryker sulla corsia rapida dei test unitari — i mutanti sopravvissuti evidenziano asserzioni deboli | **Consultivo** | +| `nightly-mutation` | Punteggio dei test di mutazione Stryker sulla corsia veloce dei test unitari — i mutanti sopravvissuti evidenziano asserzioni deboli | **Consultivo** | | `nightly-compat` | Matrice di compatibilità del motore Node per gli intervalli `engines.node` supportati | **Consultivo** | --- @@ -553,39 +558,39 @@ errore di connessione e non interrompe mai le sessioni. Questo inventario è stato riconciliato con `ci.yml` il 2026-06-17 (la versione precedente ometteva `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Una revisione del ROI dell'insieme riconciliato -ha identificato i seguenti candidati alla razionalizzazione. **Gli accorpamenti sono modifiche -meccaniche alla CI; le attivazioni/disattivazioni e le rimozioni sono decisioni di policy riservate -all'operatore.** Nulla di quanto segue è stato ancora applicato. +`check:codeql-ratchet`, `check:pr-evidence`). Una revisione ROI dell'insieme riconciliato +ha individuato i seguenti candidati alla razionalizzazione. **Le unificazioni sono modifiche +meccaniche alla CI; le conversioni/rimozioni sono decisioni di policy riservate all'operatore.** +Nulla di quanto segue è stato ancora applicato. -**Non documentati anche sopra** (consultivi, segnale debole): il job `docs-lint` -(markdownlint + Vale, intero job con `continue-on-error`) e i workflow autonomi degli scanner +**Inoltre non documentati sopra** (consultivi, segnale debole): il job `docs-lint` +(markdownlint + Vale, intero job con `continue-on-error`) e i workflow di scansione autonomi `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` è presente in `quality-baseline.json`, ma non è collegato a un ratchet bloccante in `ci.yml`: la metrica è attualmente orfana. -### Accorpamento / deduplicazione (meccanici, rischio inferiore) +### Unificazione / deduplicazione (meccanica, rischio inferiore) -Ogni candidato è stato convalidato rispetto allo stato effettivo dei gate il 2026-06-17 (fidarsi, -ma verificare); diversi accorpamenti "ovvi" si sono rivelati celare debito e **non** sono -sostituzioni dirette senza rischi. +Ogni candidato è stato validato rispetto allo stato effettivo dei gate il 2026-06-17 +(fidarsi, ma verificare); diverse unificazioni "ovvie" si sono rivelate nascondere debito +e **non** sono sostituzioni dirette prive di rischi. -- **`check:docs-sync` viene eseguito due volte** — autonomamente nel job `lint` e nuovamente all'interno di `check:docs-all` (`docs-sync-strict`) e dell'hook pre-commit di husky. ✅ **FATTO** — rimossa l'esecuzione autonoma da `lint`. -- **Scansione delle CVE** — ❌ **NON è un accorpamento diretto senza rischi.** `audit:deps` genera un errore bloccante per qualsiasi CVE di gravità alta/critica; `check:vuln-ratchet` (osv) fallisce soltanto in caso di _regressione_ rispetto alla baseline (attualmente 1 MODERATE). Semantiche diverse: rimuovere `audit:deps` eliminerebbe il gate assoluto per le vulnerabilità di gravità alta/critica. Mantenerli entrambi. -- **Rilevamento dei cicli** — ❌ **NON è un accorpamento diretto senza rischi.** `check:circular-deps` (dpdm) segnala **91 cicli** (per questo è consultivo); non può essere promosso a bloccante senza prima risolverli e ha un ambito più ampio rispetto a `check:cycles`, che è verde e mirato. Mantenere `check:cycles` come bloccante; la risoluzione dei 91 cicli dpdm costituisce un backlog separato. -- **Complessità** — ✅ **FATTO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): un'unica scansione ESLint, con conteggi per ruleId, in modo che le baseline di complessità ciclomatica+numero massimo di righe e di complessità cognitiva rimangano indipendenti; i singoli `check:complexity` / `check:cognitive-complexity` restano disponibili per l'uso locale con `--update`. -- **Anti-allucinazione di `/api`** — ✅ **FATTO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): un unico inventario del filesystem di `src/app/api`; openapi-routes + docs-symbols continuano a generare report indipendenti; i singoli controlli restano disponibili per le esecuzioni locali. -- **`check:node-runtime` viene eseguito in 11 job** — ⚠️ **ROI basso.** Ciascuno usa un runner separato e il controllo richiede <1s; risparmio totale di ~10s, a fronte della perdita di una protezione economica per ciascun job. Non vale la complessità della modifica. -- **`typecheck:noimplicit:core` nel lint della CI** — ✅ **rimosso dal job lint** (era consultivo con `continue-on-error`); la superficie dei tipi bloccante è `typecheck:core` + `check:type-coverage`. Script locale mantenuto. +- **`check:docs-sync` viene eseguito due volte** — autonomamente nel job `lint` e nuovamente all'interno di `check:docs-all` (`docs-sync-strict`) e dell'hook pre-commit di husky. ✅ **FATTO** — l'invocazione autonoma in `lint` è stata rimossa. +- **Scansione delle CVE** — ❌ **NON è un'unificazione pulita.** `audit:deps` fallisce in modo bloccante per qualsiasi CVE alta/critica; `check:vuln-ratchet` (osv) fallisce solo in caso di _regressione_ rispetto alla baseline (attualmente 1 MODERATE). Semantiche diverse: la rimozione di `audit:deps` eliminerebbe il gate assoluto per le vulnerabilità alte/critiche. Mantenerli entrambi. +- **Rilevamento dei cicli** — ✅ **FATTO** (#15159 G-01/G-02). Il testo precedente definiva `check:cycles` il gate "verde e curato" e giustificava il suo mantenimento come bloccante perché `check:circular-deps` (dpdm) segnalava 91 cicli. Quel verde era un **falso verde**: `check:cycles` analizzava 5 sottodirectory (450 file), rilevava solo `import|export … from` statici e scartava ogni specificatore `@/` e `@omniroute/open-sse/`, quindi non poteva rilevare i cicli con import dinamici + alias che dominavano il repository. Corretto: ora il gate percorre `src` + `open-sse` (5023 file), raccoglie gli specificatori dall'AST TypeScript (quindi `import("…")` conta, mentre `typeof import("…")` in posizione di tipo no) e risolve i `paths` di tsconfig. Trova **14** cicli, non 0. Poiché 14 cicli preesistenti non possono essere corretti in una PR dedicata al gate, `check:cycles` è ora un **ratchet** (`--ratchet`, soglia massima `metrics.cycles.value = 14` in `quality-baseline.json`, `direction: down`): blocca qualsiasi _regressione_ e il conteggio può solo diminuire. La CI esegue `npm run check:cycles:ratchet`. La riduzione progressiva procede insieme ad **A-01**. `check:circular-deps` (dpdm) rimane consultivo come seconda valutazione più ampia. +- **Complessità** — ✅ **FATTO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): un'unica scansione ESLint, con conteggi per ruleId affinché le baseline di complessità ciclomatica+max-lines e cognitiva restino indipendenti; i singoli `check:complexity` / `check:cognitive-complexity` rimangono disponibili per l'uso locale con `--update`. +- **Anti-allucinazione di `/api`** — ✅ **FATTO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): un unico inventario del file system per `src/app/api`; openapi-routes + docs-symbols continuano a produrre report indipendenti; i controlli individuali rimangono disponibili per le esecuzioni locali. +- **`check:node-runtime` viene eseguito in 11 job** — ⚠️ **ROI basso.** Ognuno è un runner separato e il controllo richiede <1s; il risparmio totale è di ~10s, a fronte della perdita di una protezione economica per ogni job. Non vale la pena affrontare le modifiche necessarie. +- **`typecheck:noimplicit:core` nel lint della CI** — ✅ **rimosso dal job lint** (era consultivo con `continue-on-error`); la superficie di tipi bloccante è `typecheck:core` + `check:type-coverage`. Script locale mantenuto. -### Attivare/disattivare / decidere (policy dell'operatore) +### Conversione / decisione (policy dell'operatore) -- `check:openapi-security-tiers` (consultivo) — ❌ **NON può essere reso bloccante senza interventi preliminari.** Termina con codice 0, ma avverte che diverse route di `traffic-inspector` sotto `LOCAL_ONLY_API_PREFIXES` non includono l'annotazione `x-loopback-only: true`. Per renderlo bloccante è necessario aggiungere prima tali annotazioni a `openapi.yaml`. -- `typecheck:noimplicit:core` (consultivo) — ampiamente sostituito dal ratchet bloccante `check:type-coverage`. Convertirlo in un ratchet oppure rimuovere il secondo passaggio `tsc` ridondante. -- `test:vitest:ui` (ora **bloccante**) — gli errori preesistenti sono esplicitamente esclusi in `vitest.config.ts` con commenti di tracciamento `// #8618`; i nuovi errori fanno fallire il job. -- `check:secrets` (gitleaks, ratchet bloccante congelato su 3 falsi positivi documentati) — aggiungere i 3 elementi all'allowlist per raggiungere 0, oppure declassarlo a consultivo. Si sovrappone alla scansione nativa dei segreti di GitHub + `check:public-creds`. -- `check:pr-evidence` (bloccante, esegue grep sul testo del corpo della PR) — alto rischio di falsi positivi; la rimozione indebolirebbe l'applicazione della Regola Rigida n. 18, quindi si tratta di un'autentica decisione di policy. -- `semgrep` (workflow autonomo consultivo) — si sovrappone a CodeQL per le categorie OWASP; collegare la sua baseline a un ratchet oppure rimuoverlo. +- `check:openapi-security-tiers` (consultivo) — ❌ **NON convertibile in modo pulito.** Termina con codice 0, ma avverte che diverse route `traffic-inspector` sotto `LOCAL_ONLY_API_PREFIXES` non hanno l'annotazione `x-loopback-only: true`. Per renderlo bloccante è necessario aggiungere prima tali annotazioni a `openapi.yaml`. +- `typecheck:noimplicit:core` (consultivo) — in gran parte sostituito dal ratchet bloccante `check:type-coverage`. Convertirlo in ratchet oppure rimuovere il secondo passaggio `tsc` ridondante. +- `test:vitest:ui` (ora **bloccante**) — gli errori preesistenti sono esclusi esplicitamente in `vitest.config.ts` con commenti di tracciamento `// #8618`; i nuovi errori fanno fallire il job. +- `check:secrets` (gitleaks, ratchet bloccante fissato a 3 falsi positivi documentati) — aggiungere i 3 alla allowlist per arrivare a 0, oppure declassarlo a consultivo. Si sovrappone alla scansione nativa dei segreti di GitHub + `check:public-creds`. +- `check:pr-evidence` (bloccante, esegue grep sul testo descrittivo del corpo della PR) — elevato rischio di falsi positivi; rimuoverlo indebolisce l'applicazione della Hard Rule #18, quindi si tratta di una vera decisione di policy. +- `semgrep` (autonomo consultivo) — si sovrappone a CodeQL per le famiglie OWASP; collegare la sua baseline a un ratchet oppure rimuoverlo. --- diff --git a/docs/i18n/ja/CONTRIBUTING.md b/docs/i18n/ja/CONTRIBUTING.md index f3f0d3f26a4..5bdc8aec974 100644 --- a/docs/i18n/ja/CONTRIBUTING.md +++ b/docs/i18n/ja/CONTRIBUTING.md @@ -386,22 +386,22 @@ OAuth 認証情報を `src/lib/oauth/constants/oauth.ts` に、サービスを ` --- -## プルリクエストチェックリスト +## Pull Request チェックリスト - [ ] テストが成功する(`npm test`) - [ ] Lint が成功する(`npm run lint`) - [ ] ビルドが成功する(`npm run build`) - [ ] 新しい公開関数およびインターフェースに TypeScript の型が追加されている - [ ] ハードコードされたシークレットやフォールバック値がない -- [ ] 公開アップストリーム認証情報は、リテラルではなく `resolvePublicCred()` を介して埋め込まれている([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) を参照) -- [ ] エラーレスポンスは `buildErrorBody()` / `sanitizeErrorMessage()` を経由している — レスポンス本文に未加工のスタックトレースを含めない([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) を参照) -- [ ] シェルコマンド(`exec` / `spawn`)では、実行時の値を文字列補間ではなく `env` 経由で渡している +- [ ] 公開アップストリーム認証情報はリテラルではなく `resolvePublicCred()` を使用して埋め込まれている([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) を参照) +- [ ] エラーレスポンスは `buildErrorBody()` / `sanitizeErrorMessage()` を経由している — レスポンス本文に未加工のスタックトレースが含まれていない([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) を参照) +- [ ] シェルコマンド(`exec` / `spawn`)には、文字列補間ではなく `env` を介してランタイム値を渡している - [ ] すべての入力が Zod スキーマで検証されている -- [ ] ユーザー向けの変更について、`changelog.d/{features|fixes|maintenance}/-.md` 以下に変更履歴の**フラグメント**が追加されている([`changelog.d/README.md`](./changelog.d/README.md) を参照)— `CHANGELOG.md` を直接編集しては**ならない**。フラグメントはリリース時に集約され、PR 間で競合することはない +- [ ] ユーザー向けの変更について、`changelog.d/{features|fixes|maintenance}/-.md` 配下に Changelog の**フラグメント**が追加されている([`changelog.d/README.md`](./changelog.d/README.md) を参照)— `CHANGELOG.md` を直接編集してはならない。フラグメントはリリース時に集約され、PR 間で競合することはない - [ ] ドキュメントが更新されている(該当する場合) -- [ ] 新しい CodeQL / Secret-Scanning アラートが発生していない。または、各アラートが関連する `docs/security/` ドキュメントを参照した技術的根拠とともに却下されている -- [ ] 子プロセスを起動するルート(`/api/mcp/`、`/api/cli-tools/runtime/`)が `src/server/authz/routeGuard.ts` で `isLocalOnlyPath()` として分類されている — [ハードルール #15](docs/security/ROUTE_GUARD_TIERS.md) を参照 -- [ ] コミットメッセージに `Co-Authored-By` トレーラーがない — コミットはリポジトリ所有者の Git ID のみで作成されたものとして表示されなければならない(ハードルール #16) +- [ ] 新しい CodeQL / Secret-Scanning アラートが発生していない、または各アラートが関連する `docs/security/` ドキュメントを参照した技術的根拠とともに却下されている +- [ ] 子プロセスを起動するルート(`/api/mcp/`、`/api/cli-tools/runtime/`)が `src/server/authz/routeGuard.ts` 内で `isLocalOnlyPath()` として分類されている — [厳守ルール #15](docs/security/ROUTE_GUARD_TIERS.md) を参照 +- [ ] コミットメッセージに AI/bot の `Co-authored-by` トレーラーが含まれていない(厳守ルール #16)— 再利用した作業を行った人間の共同作業者は、標準の `Co-authored-by: Name ` トレーラーでクレジットされている --- diff --git a/docs/i18n/ja/docs/architecture/QUALITY_GATES.md b/docs/i18n/ja/docs/architecture/QUALITY_GATES.md index 685d2fde012..9657b6c55cc 100644 --- a/docs/i18n/ja/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ja/docs/architecture/QUALITY_GATES.md @@ -19,119 +19,123 @@ ### 候補の受け入れ -CI および Quality Gates ワークフローは、それぞれ安定した判定結果 `Gate / CI` と +CI ワークフローと Quality Gates ワークフローは、それぞれ安定した判定結果 `Gate / CI` および `Gate / Quality` を出力します。バージョン管理された受け入れポリシーでは、すべての上流ジョブを -必須またはアドバイザリーとして列挙します。適用対象の必須ジョブは成功しなければなりません。 -欠落、キャンセル、スキップ、保留中、不明の結果では PASS を確定できません。有効な -ドキュメントのみ、またはカタログのみという分類により、コードレーンを適用対象外にできますが、 -ドラフト PR は受け入れ可能な候補ではありません。`hotfix` ラベルによって証跡が免除されることはありません。 - -両方のワークフローは、PR、main/release ブランチへのプッシュ、手動ディスパッチ、 -およびマージグループイベントを対象とします。プッシュ、ディスパッチ、マージグループでは、 -すべての選択項目が実行されます。フォークおよびマージグループでは、通常であればセルフホステッド -ランナーを選択するジョブにもホステッドランナーを使用します。ロールアウト前に、十分な -ホステッド容量があることを確認する必要があります。 - -各 JSON レシートは、チェックアウトされた SHA、ワークフロー実行、および試行を識別します。 -CLI は、チェックアウト SHA とイベント SHA の不一致を拒否します。ワークフローテストでは、 -ポリシーのメンバーシップを判定ジョブの `needs` リストに紐付けるため、新規または削除された -レーンが気付かれないまま消えることはありません。レシートが対象とするのは自身のワークフローであり、 -公開、デプロイ、または既存のアドバイザリースキャナーの内部処理ではありません。ブランチルールで -両方のチェック名を有効化することは、別途必要な管理上の変更です。これらのジョブを追加するだけでは、 -ブランチは保護されません。 +必須またはアドバイザリとして列挙します。適用対象となる必須ジョブは成功しなければなりません。 +結果が欠落、キャンセル、スキップ、保留中、不明の場合、PASS を確定できません。有効な +docs-only または catalog-only 分類によりコードレーンが適用対象外になることはありますが、 +ドラフト PR は受け入れ対象の候補ではありません。`hotfix` ラベルによってエビデンス要件が +免除されることもありません。 + +両方のワークフローは、PR、main/release ブランチへの push、手動 dispatch、および +merge-group イベントを対象とします。push、dispatch、merge-group では完全な選択セットが +実行されます。fork と merge group では、本来 self-hosted runner を選択するジョブに +hosted runner を使用します。ロールアウト前に、十分な hosted capacity があることを +確認する必要があります。 + +各 JSON レシートは、checkout された SHA、workflow run、および attempt を識別します。 +CLI は checkout/event の SHA 不一致を拒否します。ワークフローテストでは、ポリシーの +メンバーシップを判定ジョブの `needs` リストに関連付けるため、新規または削除されたレーンが +暗黙のうちに消えることはありません。レシートが対象とするのは、それ自身のワークフローであり、 +publication、deployment、または既存のアドバイザリスキャナーの内部処理ではありません。 +ブランチルールで両方のチェック名を有効にすることは、別途必要な管理上の変更です。これらの +ジョブを追加するだけでは、ブランチは保護されません。 ### 静的スキャン一覧 バージョン管理された npm エイリアス一覧と静的スキャンのメンバーシップは、 `config/quality/gate-manifest.json` にあります。`package.json` に対してスクリプト名と -正確なコマンドを検証するには、`npm run check:gate-manifest` を実行してください。追加、削除、 -およびコマンドの乖離があると、ローカルフックと CI の変更分類ジョブの両方が失敗します。 +完全一致するコマンドを検証するには、`npm run check:gate-manifest` を実行します。 +追加、削除、コマンドの差異があると、ローカルフックと CI の変更分類ジョブの両方が失敗します。 エイリアスは、ワークフロージョブ、マトリックスインスタンス、テストケースのいずれでもありません。 -これらの件数を相互に置き換え可能なものとして提示してはなりません。 - -選択されたエイリアスを実行せずに確認するには、`npm run quality:scan -- --list` または -`npm run quality:scan:fast -- --list` を使用してください。ランナーは npm エントリポイントを -呼び出すため、設定されている場合の Bun を含め、そのランタイムが維持されます。マニフェストでは、 -これらのプロファイル外のエイリアスを個別実行として記録し、読み取り専用のスキャンプロファイルでは -メンテナンスコマンドを禁止しています。 - -これらのプロファイルが対象とするのは静的スキャンのみです。プロダクトテスト、カバレッジ、 -パッケージング、外部チェック、または候補のリリース受け入れ全体を保証するものではありません。 -ワークフローの受け入れでは、関連付けられた `config/quality/admission-policy.json` と -`scripts/quality/admission-verdict.mjs` を使用します。リリースオブザーバーのプロファイルは -引き続き別個のものです。適用対象のチェックとレシートは、それぞれ個別に確認してください。 -以下の文章による一覧は参考情報であり、ゲートが実際に実行されたことの証明ではありません。 - -スクリプトは `scripts/check/`(ポリシーゲート)と `scripts/quality/`(ラチェットエンジン)以下にあります。 +これらの件数を相互に置き換え可能なものとして示してはなりません。 + +選択されたエイリアスを実行せずに確認するには、 +`npm run quality:scan -- --list` または `npm run quality:scan:fast -- --list` を使用します。 +runner は npm entrypoint を呼び出すため、設定されている場合の Bun を含め、そのランタイムが +維持されます。manifest では、これらのプロファイル外のエイリアスを個別に呼び出されるものとして +記録します。また、読み取り専用のスキャンプロファイルでは、メンテナンスコマンドは禁止されます。 + +これらのプロファイルが対象とするのは静的スキャンのみです。product tests、coverage、 +packaging、external checks、または候補の完全な release acceptance を認定するものでは +ありません。ワークフローの受け入れでは、リンクされた +`config/quality/admission-policy.json` と +`scripts/quality/admission-verdict.mjs` を使用します。release-observer プロファイルは +引き続き分離されています。適用対象のチェックとレシートは個別に確認してください。以下の +文章による一覧は参照情報であり、ゲートが実際に実行されたことの証明ではありません。 + +スクリプトは `scripts/check/`(ポリシーゲート)と +`scripts/quality/`(ratchet engine)にあります。 CI の信頼できる唯一の情報源は `.github/workflows/ci.yml` です。 -### リリース PR の高速パス(`quality.yml`) - -`.github/workflows/quality.yml` は、main/release PR、保護対象ブランチへのプッシュ、 -ディスパッチ、マージグループにおいて CI を補完します。PR では、パスでフィルタリングされた -高速チェックを使用します。恒久的に無効化されていた重複ビルドは削除されました。 -実際のビルド、パッケージ、起動チェックは引き続き CI にあります。 - -| ジョブ | スコープ | ブロッキング | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `Docs Gates (fast-path)` | ドキュメント/コード PR。API ドキュメント参照とドキュメント全体 | はい | -| `Fast Quality Gates` | コード PR。静的チェック、型チェック、ダッシュボードの型チェック、影響を受けるユニットテスト | はい | -| `Forgotten sibling tests` | コード PR。変更されたモジュールから静的コンシューマーと候補となる兄弟テストを追跡。バレルおよび動的インポートのパスは、参照された許可リストの例外とともにアドバイザリー診断として報告されます | **アドバイザリー** | -| `Vitest (fast-path)` | コード PR。高速 Vitest スイート | はい | -| `Unit Tests fast-path` | コード PR。4 シャードのユニットスイート | はい | -| `No new ESLint warnings` | コード PR。抑制を考慮した lint ガード | はい(フォークを含む) | -| `Merge integrity (changelog + generated skills)` | ドラフトではない PR。変更履歴と生成されたスキルの同期 | はい(フォークを含む) | - -#### 取りこぼされた兄弟テストのレポート - -`npm run check:forgotten-sibling-tests` は、テスト影響マップの基盤となるインポートリゾルバーを再利用します。 -変更された各本番モジュールについて、候補テストがプルリクエストの差分に含まれていない場合に、 -決定論的な `changed module/symbol -> static consumer -> candidate sibling test` チェーンを報告します。 -Markdown サマリーと JSON 結果は、ブロッキングとしてロールアウトする前の調整用に、 -`forgotten-sibling-tests` ワークフローアーティファクトとして保持されます。 - -バレル再エクスポートと動的インポートは、解決診断のみを目的としており、 -ブロッキング対象の検出結果を生成することはありません。レビュー済みの例外は -`config/quality/forgotten-sibling-allowlist.json` で管理されます。各エントリには、コンシューマーと候補 -テストを明記し、具体的な理由を示したうえで、GitHub issue または pull request へのリンクを含める必要があります。不正な形式のエントリは -安全側に倒して拒否されます。例外によって、削除された候補テストや、`.skip`/`.todo` を追加する差分を抑制することはできません。 -アサーションの弱体化やその他のマスキングについては、独立してブロッキングする +### Release PR fast-path(`quality.yml`) + +`.github/workflows/quality.yml` は、main/release PR、保護されたブランチへの +push、dispatch、merge group において CI を補完します。PR では、パスでフィルタリングされた +高速チェックを使用します。恒久的に無効化されていた重複 build は削除されました。 +実際の build/package/boot チェックは引き続き CI に残ります。 + +| ジョブ | スコープ | ブロッキング | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `Docs Gates (fast-path)` | Docs/code PR、API docs refs、および docs-all | はい | +| `Fast Quality Gates` | Code PR、静的チェック、typecheck、dashboard typecheck、影響を受ける unit tests | はい | +| `Forgotten sibling tests` | Code PR、変更されたモジュールを static consumers と candidate sibling tests まで追跡。barrel と dynamic-import のパスは、参照された allowlist の例外とともにアドバイザリ診断として報告されます | **アドバイザリ** | +| `Vitest (fast-path)` | Code PR、高速 vitest suite | はい | +| `Unit Tests fast-path` | Code PR、4-shard unit suite | はい | +| `No new ESLint warnings` | Code PR、suppressions-aware lint guard | はい(fork を含む) | +| `Merge integrity (changelog + generated skills)` | ドラフトではない PR、changelog と generated skill の同期 | はい(fork を含む) | + +#### Forgotten sibling tests レポート + +`npm run check:forgotten-sibling-tests` は、test-impact map の基盤となる import resolver を +再利用します。変更された各 production module について、候補テストが pull-request diff に +含まれていない場合、決定論的な +`changed module/symbol -> static consumer -> candidate sibling test` チェーンを報告します。 +Markdown summary と JSON result は、ブロッキング方式でのロールアウト前にキャリブレーションを +行うため、`forgotten-sibling-tests` workflow artifact として保持されます。 + +バレル再エクスポートと動的インポートは、解決に関する診断のみを目的としており、 +ブロッキング判定を生成することはありません。レビュー済みの例外は +`config/quality/forgotten-sibling-allowlist.json` にあります。各エントリでは、コンシューマーと候補 +テストを指定し、具体的な根拠を示し、GitHub issue または pull request へのリンクを記載する必要があります。不正な形式のエントリは +安全側に倒して失敗します。例外によって、削除された候補テストや、`.skip`/`.todo` を追加する差分を抑制することはできません。 +アサーションの弱体化やその他のマスキングについては、独立してブロッキングを行う `check:test-masking` ゲートが引き続き担当します。 ### ジョブ: `lint` `main` に対するすべての PR で実行されます。失敗した場合はマージをブロックします。 -| スクリプト (`npm run ...`) | 検証内容 | ブロッキング | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| `check:node-runtime` | Node.js のバージョンがサポート対象範囲内であること | はい | -| `check:cycles` | 循環インポート — すべての `src/` + `open-sse/` モジュール | はい | -| `check:route-validation:t06` | すべてのルートに Zod スキーマが存在すること(Tier 6 ポリシー) | はい | -| `check:any-budget:t11` | `@ts-expect-error // any` の数が上限を超えていないこと(Tier 11 ゲート) | はい | -| `check:provider-consistency` | `providers.ts` 内のすべてのプロバイダーに、`providerRegistry.ts` 内の対応するエントリが存在する(逆方向も同様。ただし許可リスト内に限る) | はい | -| `check:model-lifecycle` | 手動で保守されている3つのルーティングテーブルが、チェックイン済みのライフサイクルスナップショット(#11503)と整合していることを確認する:`FITNESS_TABLE`(`taskFitness.ts`)では、`REGISTRY` がルーティング可能な廃止済み id にスコアを付けないこと、すべての `BUILT_IN_ALIASES` のターゲットが `REGISTRY` に存在し、廃止済み id のスナップショットには存在しないこと、`REGISTRY` に残っているすべての廃止済み id が転送されるか `allowedRetiredInCatalog` に記載されていること、さらに `DEFAULT_DEGRADATION_MAP` のソースまたはターゲットがそのスナップショット内で廃止済みになっていないこと。これは、モデルが現在稼働中のアップストリームによって提供されていることを証明するものではない。オフライン — `config/quality/model-lifecycle.json` と比較する。このファイルは `npm run quality:refresh-model-lifecycle` を使用して手動で更新する(ネットワークを使用し、CI には組み込まれていない)。`allowedRetiredInCatalog` は段階的削減のためのラチェットであり、エントリを追加するのは追跡 issue がある場合に限る。 | はい | -| `check:fetch-targets` | クライアント側の `src/` にあるすべての `fetch("/api/...")` が、実在する `route.ts` に解決される | はい | -| `check:deps` | リポジトリ内のすべての `package.json` に含まれる、`npm install` でインストール可能な依存関係がすべて `dependency-allowlist.json` に登録されていることを確認し、新たなバージョン未固定パッケージやスロップスクワッティングされたパッケージを検出する | はい | -| `audit:deps` | `npm audit`(ルート + electron)— high/critical のアドバイザリがないこと(osv の `check:vuln-ratchet` と重複。Rationalization Backlog を参照) | はい | -| `check:lockfile` | `package-lock.json` の完全性 — https レジストリ、完全性ハッシュ、ホストのオーバーライドなし | はい | -| `check:licenses` | 本番依存関係の SPDX ライセンス許可リスト | はい | -| `check:tracked-artifacts` | ビルド成果物およびコミットされた `node_modules` シンボリックリンクがないこと(husky の pre-commit でも実行。pre-push は意図的に軽量化 — #6716) | はい | -| `check:ai-attribution` | PR のコミット、タイトル、本文に、AI/ボットによる `Co-Authored-By` トレーラーまたは AI 生成フッターがないこと — 厳格ルール #16(PR→`release/**` 向けの `quality.yml` 高速ゲートループ内。イベントペイロードを読み取り、PR 以外では何も行わない。また、PR→`main` 向けの `ci.yml` lint にある PR 専用ステップ、および husky の `commit-msg` フックでも実行。人間の共同作成者は許可。#14436) | -| `check:vitest-exclusions` | すべての Vitest 除外に追跡用 Issue が指定され、`config/quality/vitest-exclusions.json` に記載されていること(#13204) | はい | -| `check:file-size` | ソースファイルが拡張子ごとの上限を超えていないこと(ラチェット方式:サイズの大きい固定対象ファイルは `frozen` リストに記載) | はい | -| `check:error-helper` | executor/handler のエラーレスポンスで `buildErrorBody()` / `sanitizeErrorMessage()` を使用すること(厳格ルール #12) | はい | -| `check:migration-numbering` | Migration SQL ファイルは欠番や重複がなく、連番になっている | はい | -| `check:public-creds` | `publicCreds.ts` の外部に、OAuth の `client_id`/`client_secret` または Firebase Web キーのリテラルが存在しない(ハードルール #11) | はい | -| `check:db-rules` | `src/lib/db/` モジュールの外部に生の SQL が存在せず、`localDb.ts` からのバレルインポートもない(ハードルール #2/#5) | はい | -| `check:known-symbols` | ディスパッチテーブルに登録されたプロバイダーエグゼキューター、ルーティング戦略、トランスレーターがディスク上のファイルと一致しており、孤立したシンボルや未宣言のシンボルがない | はい | -| `check:route-guard-membership` | 子プロセスを生成するすべてのルートが `isLocalOnlyPath()` によって分類されている(ハードルール #15/#17) | はい | -| `check:test-discovery` | リポジトリ内のすべての `*.test.ts` / `*.spec.ts` ファイルが、少なくとも 1 つのテストランナーによって収集される(ラチェット:`test-discovery-baseline.json` 内の孤立ファイルリストは縮小のみ可能) | はい | -| `check:agent-skills-sync` | 生成された agent-skills アーティファクトがソースカタログと一致している(差分なし) | -| `check:provider-asset-provenance` | プロバイダーのロゴ/アセットに記録済みの出所エントリが付与されている | -| `lint:json` | JSON 設定ファイルが解析可能で、リポジトリの lint ルールを満たしている | -| `typecheck:core` | エラーなしで TypeScript をコンパイルする(警告のみ) | はい | -| `typecheck:noimplicit:core` | 厳格な `noImplicitAny` — 将来を見据えたチェック。既存の多数の呼び出し箇所には、依然として注釈が必要 | **勧告**(`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` を対象とする `tsc`(#7033)— `typecheck:core` で厳選された27ファイルの許可リストにはダッシュボードの TSX が一切含まれておらず、`next build` でも型チェックされません(`next.config.mjs` で `ignoreBuildErrors: true` が設定されているため)。そのため、そこで発生した未解決識別子のリグレッション(#6625/#6909)は CI で検出できませんでした。ファイルごと/TS コードごとの件数を固定したベースライン(`config/quality/dashboard-typecheck-baseline.json`、`check:known-symbols` と同じ陳腐化チェックパターン)と比較し、ベースラインの件数を超える新規エラーのみがゲートを失敗させます。既存エラーを修正した場合は、`--update` を使用してベースラインを段階的に引き下げます。 | はい | +| スクリプト (`npm run ...`) | 検証内容 | ブロッキング | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Node.js のバージョンがサポート対象範囲内であること | はい | +| `check:cycles` | `src/` + `open-sse/` 全体の循環インポート(AST ベース、tsconfig の `paths` を解決)。単独実行時は勧告のみで、循環を一覧表示します。`check:cycles:ratchet`(CI で実行されるもの)は、循環数が `quality-baseline.json` の `metrics.cycles` 上限を超えた場合にブロックします。現在は 14、`direction: down` であるため、減少のみが許可されます(#15159 G-01/G-02) | はい(ラチェット) | +| `check:route-validation:t06` | すべてのルートに Zod スキーマが存在すること(Tier 6 ポリシー) | はい | +| `check:any-budget:t11` | `@ts-expect-error // any` の件数が予算を超えていないこと(Tier 11 catraca) | はい | +| `check:provider-consistency` | `providers.ts` 内のすべてのプロバイダーに、`providerRegistry.ts` 内の対応するエントリが存在する(その逆も同様。ただし許可リスト内に限る) | はい | +| `check:model-lifecycle` | 手動で管理される3つのルーティングテーブルが、チェックイン済みのライフサイクルスナップショット(#11503)と整合していることを確認する:`FITNESS_TABLE`(`taskFitness.ts`)では、`REGISTRY` がルーティング可能な廃止済み id にスコアを付けないこと、すべての `BUILT_IN_ALIASES` のターゲットが `REGISTRY` に存在し、かつ廃止済み id のスナップショットに存在しないこと、`REGISTRY` に残っているすべての廃止済み id が転送されるか `allowedRetiredInCatalog` に記載されていること、さらに `DEFAULT_DEGRADATION_MAP` のソースまたはターゲットがそのスナップショットで廃止済みになっていないこと。これは、モデルが現在稼働中のアップストリームから提供されていることを証明するものではない。オフライン — `config/quality/model-lifecycle.json` と比較する。このファイルは `npm run quality:refresh-model-lifecycle`(ネットワークを使用。CI には組み込まれていない)で手動更新する。`allowedRetiredInCatalog` は段階的削減のためのラチェットであり、エントリは追跡用 issue がある場合にのみ追加する。 | はい | +| `check:fetch-targets` | クライアント側の `src/` 内にあるすべての `fetch("/api/...")` が、実在する `route.ts` に解決される | はい | +| `check:deps` | リポジトリ内のすべての `package.json` に含まれる、`npm install` でインストール可能な依存関係が `dependency-allowlist.json` に登録されていること。新規のバージョン未固定パッケージやスロップスクワッティングされたパッケージはフラグ付けされる | はい | +| `audit:deps` | `npm audit`(ルート + electron)— high/critical のアドバイザリがないこと(osv の `check:vuln-ratchet` と重複。Rationalization Backlog を参照) | はい | +| `check:lockfile` | `package-lock.json` の整合性 — https レジストリ、整合性ハッシュ、ホストのオーバーライドなし | はい | +| `check:licenses` | 本番環境の依存関係に対する SPDX ライセンス許可リスト | はい | +| `check:tracked-artifacts` | ビルド成果物およびコミットされた `node_modules` シンボリックリンクが存在しないこと(husky の pre-commit でも実行。pre-push は意図的に軽量化 — #6716) | はい | +| `check:ai-attribution` | PR のコミット、タイトル、本文に、AI/ボットによる `Co-Authored-By` トレーラーまたは AI 生成フッターが存在しないこと — 厳格ルール #16(PR→`release/**` 向けの `quality.yml` 高速ゲートループ内でイベントペイロードを読み取り、PR 以外では何も実行しない。また、PR→`main` 向けの `ci.yml` lint にある PR 専用ステップ、および husky の `commit-msg` フックでも実行。人間の共同作成者は許可。#14436) | +| `check:vitest-exclusions` | すべての Vitest 除外項目に追跡用 issue が記載され、`config/quality/vitest-exclusions.json` に含まれていること(#13204) | はい | +| `check:file-size` | ソースファイルが拡張子ごとの上限を超えていないこと(ラチェット方式:大容量ファイルは `frozen` リストで固定) | はい | +| `check:error-helper` | executor/handler のエラーレスポンスで `buildErrorBody()` / `sanitizeErrorMessage()` を使用していること(厳格ルール #12) | はい | +| `check:migration-numbering` | Migration SQL ファイルには欠番や重複がなく、連番になっている | はい | +| `check:public-creds` | `publicCreds.ts` 以外に、OAuth の `client_id`/`client_secret` または Firebase Web キーのリテラルが存在しない(厳格なルール #11) | はい | +| `check:db-rules` | `src/lib/db/` モジュール以外に生の SQL が存在せず、`localDb.ts` からのバレルインポートも存在しない(厳格なルール #2/#5) | はい | +| `check:known-symbols` | ディスパッチテーブルに登録されているプロバイダーエグゼキューター、ルーティング戦略、トランスレーターがディスク上のファイルと一致しており、孤立したシンボルや未宣言のシンボルが存在しない | はい | +| `check:route-guard-membership` | 子プロセスを起動するすべてのルートが `isLocalOnlyPath()` によって分類されている(厳格なルール #15/#17) | はい | +| `check:test-discovery` | リポジトリ内のすべての `*.test.ts` / `*.spec.ts` ファイルが、少なくとも 1 つのテストランナーによって収集される(ラチェット方式:`test-discovery-baseline.json` 内の孤立ファイル一覧は減少のみ許可) | はい | +| `check:agent-skills-sync` | 生成された agent-skills アーティファクトがソースカタログと一致している(ドリフトなし) | +| `check:provider-asset-provenance` | プロバイダーのロゴ/アセットに由来情報の記録が付与されている | +| `lint:json` | JSON 設定ファイルが正常に解析され、リポジトリの lint ルールを満たしている | +| `typecheck:core` | エラーなしで TypeScript をコンパイルできる(勧告的な警告のみ) | はい | +| `typecheck:noimplicit:core` | 厳格な `noImplicitAny` — 将来を見据えたチェック。既存の多くの呼び出し箇所には、まだ型注釈が必要 | **勧告的**(`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` を対象とする `tsc`(#7033)— `typecheck:core` で厳選された27ファイルの許可リストにはダッシュボードの TSX が一切含まれておらず、`next build` でも型チェックされません(`next.config.mjs` で `ignoreBuildErrors: true` が設定されているため)。そのため、そこで発生した孤立識別子のリグレッション(#6625/#6909)は CI で検出できませんでした。ファイルごと/TS コードごとの件数を固定したベースライン(`config/quality/dashboard-typecheck-baseline.json`、`check:known-symbols` と同じ古さを強制するパターン)との差分を比較します。ベースライン化された件数を超える新しいエラーのみがゲートを失敗させます。既存のエラーを修正した場合は、`--update` でベースラインを段階的に引き下げます。 | はい | ### ジョブ:`quality-gate` @@ -139,147 +143,136 @@ Markdown サマリーと JSON 結果は、ブロッキングとしてロール | スクリプト | 検証内容 | ブロッキング | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | `quality-metrics.json` を出力(ESLint の警告数、統合されたシャードレポートからのカバレッジ) | はい(ラチェットの前段) | +| `quality:collect` | `quality-metrics.json` を出力する(ESLint の警告数、マージされたシャードレポートからのカバレッジ) | はい(ラチェットの前段) | | `quality:ratchet` | `quality-baseline.json` 内の各メトリクスが悪化していないこと(ESLint の警告数 ≤ ベースライン、カバレッジ ≥ ベースライン) | はい | -| `check:duplication` | コード重複(jscpd@4)が `quality-baseline.json` 内のベースラインを超えていないこと | はい | +| `check:duplication` | コードの重複(jscpd@4)が `quality-baseline.json` のベースラインを超えていないこと | はい | | `check:complexity` | ファイル単位の循環的複雑度が上限を超えていないこと(コア ESLint の `complexity` + `max-lines-per-function`) | はい | -| `check:cognitive-complexity` | 認知的複雑度のラチェット(`eslint-plugin-sonarjs`)— 個別の ESLint パス。CI では両方を統合し、単一の `check:complexity-ratchets` ステップとして実行 | はい | -| `check:dead-code` | 未使用のエクスポート/ファイルのラチェット(knip)がベースラインと比較して悪化していないこと | はい | +| `check:cognitive-complexity` | 認知的複雑度のラチェット(`eslint-plugin-sonarjs`)— 個別の ESLint パス。CI では両方を統合し、単一の `check:complexity-ratchets` ステップとして実行する | はい | +| `check:dead-code` | 未使用のエクスポート/ファイルのラチェット(knip)がベースラインから悪化していないこと | はい | | `check:compression-budget` | 圧縮ベンチマークの予算 — エンジンごとのトークン削減率の下限が悪化してはならないこと | はい | -| `check:type-coverage` | 型付け率のラチェット(`type-coverage`)が悪化していないこと。`typecheck:noimplicit:core` をほぼ包含 | はい | +| `check:type-coverage` | 型付け率のラチェット(`type-coverage`)が悪化していないこと。`typecheck:noimplicit:core` をほぼ包含する | はい | | `check:codeql-ratchet` | 未解決の CodeQL アラート数が悪化していないこと(`gh api` 経由で読み取り。トークンがない場合は正常にスキップ)— 更新頻度と手動トリガーについては、以下の「CodeQL ラチェット」を参照 | はい | ### ジョブ: `quality-extended` -ジョブ全体は参考情報扱いです(`continue-on-error: true`)。npm ベースのラチェットは -実際に実行されます。外部スキャナーは `gh release download` を介してインストールされ、バイナリが -まだ存在しない場合は自動的にスキップします(終了コード 0)。 +ジョブ全体が参考情報扱いです(`continue-on-error: true`)。npm ベースのラチェットは +実際に実行されます。外部スキャナーは `gh release download` 経由でインストールされ、バイナリが +依然として存在しない場合は自動的にスキップします(終了コード 0)。 -| スクリプト | 検証内容 | ブロッキング | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | -| `check:circular-deps` | 循環依存がないこと(dpdm) | **参考情報** | -| `check:bundle-size` | バンドルサイズが上限を超えていないこと | **参考情報** | -| `check:secrets` | シークレットスキャン(gitleaks)— バイナリが存在しない場合はスキップ | **参考情報** | -| `check:vuln-ratchet` | 依存関係の脆弱性(osv-scanner)が悪化していないこと — バイナリが存在しない場合はスキップ | **参考情報** | -| `check:workflows` | ワークフローのリント(actionlint + zizmor)。スキャナーの欠落/破損、無効なレポート、またはラチェットのベースライン欠落は INCOMPLETE として失敗。妥当な検出結果には、選択した厳格/参考情報/ラチェットポリシーを適用 | 実行必須。CI では zizmor ラチェットがブロッキング | -| `check:openapi-breaking` | ベースブランチと比較した公開 API コントラクト(`openapi.yaml`)の破壊的変更(oasdiff)— `openapiBreaking=N` を出力。oasdiff が存在しないか、ベース仕様を解決できない場合はスキップ | **参考情報** | +| スクリプト | 検証内容 | ブロッキング | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| `check:circular-deps` | 循環依存がないこと(dpdm) | **参考情報** | +| `check:bundle-size` | バンドルサイズが上限を超えていないこと | **参考情報** | +| `check:secrets` | シークレットスキャン(gitleaks)— バイナリが存在しない場合はスキップ | **参考情報** | +| `check:vuln-ratchet` | 依存関係の脆弱性(osv-scanner)が悪化していないこと — バイナリが存在しない場合はスキップ | **参考情報** | +| `check:workflows` | ワークフローの lint(actionlint + zizmor)。スキャナーの欠落/破損、無効なレポート、またはラチェットのベースライン欠落は INCOMPLETE として失敗する。有効な検出結果には、選択された厳格/参考情報/ラチェットポリシーが適用される | 実行必須。CI では zizmor ラチェットがブロッキング | +| `check:openapi-breaking` | ベースブランチと比較した公開 API コントラクト(`openapi.yaml`)の破壊的変更(oasdiff)— `openapiBreaking=N` を出力する。oasdiff が存在しないか、ベース仕様を解決できない場合はスキップ | **参考情報** | ### ジョブ: `docs-sync-strict` `main` へのすべての PR で実行されます。失敗した場合はマージをブロックします。 -| スクリプト | 検証内容 | ブロッキング | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -| `check:docs-all` | 以下の6つのサブゲートを順番に実行するメタゲート | はい | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt のバージョン整合性 | はい | -| ↳ `check:docs-counts` | 本文中の件数(プロバイダー数、マイグレーション数など)が、実際の件数に対するラチェット範囲内に収まっていること | はい | -| ↳ `check:env-doc-sync` | `.env.example` 内のすべての環境変数がドキュメントの表に記載され、その逆も成立すること | はい | -| ↳ `check:deprecated-versions` | ドキュメント内に非推奨のバージョン文字列が存在しないこと | はい | -| ↳ `check:doc-links` | ドキュメント内の内部 Markdown リンクが実在するファイルに解決されること(`[text]`/`(path)` 形式) | はい | -| ↳ `check:fabricated-docs` | ドキュメントに記載されたルート、環境変数、CLI コマンド、フック名、ファイルパスがコードベース内に存在すること。`--strict` ではハードゲート、フラグなしではソフトフェイル。 | はい(CI では `--strict` を使用) | -| `check:cli-i18n` | CLI コマンド文字列がすべての i18n ロケールファイルに存在すること | はい | -| `check:openapi-coverage` | OpenAPI 仕様が、実在するルート数に対してラチェットされた最低基準以上をカバーしていること | はい | -| `check:openapi-security-tiers` | `openapi.yaml` のセキュリティ階層アノテーションが `routeGuard.ts` の分類と一致すること | **参考情報** | -| `check:openapi-routes` | `openapi.yaml` 内のすべてのパスが実在する `route.ts` に解決されること(ハルシネーション防止) | はい | -| `check:docs-symbols` | `docs/**/*.md` 内のすべての `/api/...` 参照が実在する `route.ts` に解決されること(ハルシネーション防止) | はい | -| `i18n translation drift` | i18n ロケールファイル内の未翻訳キー — 警告のみ | **参考情報** | - -### ジョブ:`i18n-ui-coverage` - -| スクリプト | 検証内容 | ブロッキング | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `check-ui-keys-coverage` (inline) | UI i18n キーのカバレッジが 65% 以上であること | はい | -| `check-ui-value-drift` (inline) | 書き換えられた英語の**値**に対して、古い翻訳が残っていないこと | はい | -| `check-new-key-coverage` (inline) | **新しい**英語キーがすべてのロケールで翻訳されていること — `__MISSING__:` マーカーは拒否される | はい | -| `check-translation-ratio` | ロケールごとの実翻訳率(許可リスト外で英語と同一/プレースホルダー/未翻訳の項目)が `config/quality/i18n-translation-baseline.json` + 許容幅を超えないこと | **参考情報** | - -`fetch-depth: 0` が必要です — 値ドリフトゲートは、マージベースに対して `en.json` の差分を取得します。 +| スクリプト | 検証内容 | ブロッキング | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | +| `check:docs-all` | 以下の6つのサブゲートを順番に実行するメタゲート | はい | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt のバージョン整合性 | はい | +| ↳ `check:docs-counts` | 本文中の件数(プロバイダー数、マイグレーション数など)が、実際の件数に対するラチェット範囲内にあること | はい | +| ↳ `check:env-doc-sync` | `.env.example` 内のすべての環境変数がドキュメントの表に記載されており、その逆も満たされていること | はい | +| ↳ `check:deprecated-versions` | ドキュメントに非推奨のバージョン文字列が存在しないこと | はい | +| ↳ `check:doc-links` | ドキュメント内のMarkdown内部リンクが実在するファイルを参照していること(`[text]`/`(path)` 形式) | はい | +| ↳ `check:fabricated-docs` | ドキュメントに記載されたルート、環境変数、CLIコマンド、フック名、ファイルパスがコードベース内に存在すること。`--strict` ではハードゲート、フラグなしではソフトフェイル。 | はい(CIでは `--strict` を使用) | +| `check:cli-i18n` | CLIコマンド文字列がすべてのi18nロケールファイルに存在すること | はい | +| `check:openapi-coverage` | OpenAPI仕様が、実在するルート数について少なくともラチェット設定された下限以上をカバーしていること | はい | +| `check:openapi-security-tiers` | `openapi.yaml` のセキュリティ階層アノテーションが `routeGuard.ts` の分類と一致していること | **参考情報** | +| `check:openapi-routes` | `openapi.yaml` 内のすべてのパスが実在する `route.ts` に解決されること(ハルシネーション防止) | はい | +| `check:docs-symbols` | `docs/**/*.md` 内のすべての `/api/...` 参照が実在する `route.ts` に解決されること(ハルシネーション防止) | はい | +| `i18n translation drift` | i18nロケールファイル内の未翻訳キー — 警告のみ | **参考情報** | + +### ジョブ: `i18n-ui-coverage` + +| スクリプト | 検証内容 | ブロッキング | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `check-ui-keys-coverage` (inline) | UIのi18nキーのカバレッジが65%以上であること | はい | +| `check-ui-value-drift` (inline) | 書き換えられた英語の**値**に対して、古い翻訳が残っていないこと | はい | +| `check-new-key-coverage` (inline) | **新しい**英語キーがすべてのロケールで翻訳されていること — `__MISSING__:` マーカーは拒否される | はい | +| `check-translation-ratio` | ロケールごとの実翻訳率(許可リスト外で英語と同一/プレースホルダー/欠落しているリーフ)が `config/quality/i18n-translation-baseline.json` + 許容幅を超えてはならないこと | **参考情報** | + +`fetch-depth: 0` が必要です — 値ドリフトゲートは、マージベースとの差分として `en.json` を比較します。 #### `check-ui-value-drift` — 古い翻訳を検出するゲート -他のゲートでは構造上検出できない、ある種の i18n リグレッションを検出します。英語の値が -書き換えられたにもかかわらず、_以前の_英語を基にした翻訳が残り続け、その結果、 -英語以外のユーザーが、自信ありげに書かれた、現在では誤っている文言を読み続ける問題です。 +ほかのゲートでは構造上検出できない、ある種のi18nリグレッションを検出します。英語の値が +書き換えられたにもかかわらず、_以前の_英語から作られた翻訳が残り、 +英語以外のユーザーが、自信に満ちた表現で書かれた、現在では誤っている文言を読み続けてしまう問題です。 -これは実際にリリースされました。Antigravity ログインヘルパーが導入された際(#5203)に +これは実際にリリースされました。Antigravityログインヘルパーが導入された際(#5203)に `oauthModal.googleOAuthWarning` が書き換えられましたが、**43ロケール中39ロケール**では、 -運用者に「完全な URL をコピーして下に貼り付ける」よう案内する文言が残っていました。 -このプロバイダーでは、そのフローを完了できません。この問題は #8463 まで見過ごされていました。 -理由は次のとおりです。 - -- `sync-ui-keys` は**存在しない**キーのみを補完し、**古い**キーは更新しません。 -- `check-ui-keys-coverage` はキーの_存在_を数えるため、古い翻訳もカバー済みとして扱われます。 -- `check-translation-drift` は `docs/i18n//**.md` のドキュメントミラーを追跡します — - `src/i18n/messages/*.json` は一切読み込みません。2026-09 の再同期以降、ジョブ - `docs-sync-strict` でブロッキングされています。コアドキュメントを編集した場合は、 - `npm run i18n:run -- --files=` を実行してください(セクション単位で低コスト)。 - -**差分を認識し、ベースラインには依存しません。** マージベースの `en.json` と -作業ツリーを比較し、英語の値が変更された各キーについて、未変更の翻訳が残っている -ロケールを古いものと判定します。これは意図的に**既存の負債を固定**します。差分からは、 -長期間残っている翻訳がどの古い英語に由来するのか判別できないため、このゲートは -現在の変更が触れた箇所のみを判定します。代替案(キーごとのハッシュベースライン)では、 -既存で最大のベースラインの3倍にあたる、約600 KBの生成ファイルが必要になり、 -i18n関連のPRのたびに変更が発生します。 +オペレーターに「完全なURLをコピーして下に貼り付ける」よう案内するテキストが残っていました — +そのプロバイダーでは完了できないフローです。この問題は#8463まで見過ごされていました。その理由は次のとおりです。 + +- `sync-ui-keys` は**存在しない**キーのみを補完し、**古い**キーは決して補完しないため。 +- `check-ui-keys-coverage` はキーの_存在_を数えるため、古い翻訳もカバー済みとして計上されるため。 +- `check-translation-drift` は `docs/i18n//**.md` のドキュメントミラーを追跡し、 + `src/i18n/messages/*.json` は一切読み込まないため。2026-09の再同期以降、ジョブ `docs-sync-strict` でブロッキングされます。 + コアドキュメントを編集した場合は、`npm run i18n:run -- --files=` を実行してください(セクション単位で低コスト)。 + +**差分認識型であり、ベースライン依存ではありません。** マージベース時点の `en.json` と作業ツリーを比較し、英語の値が変更された各キーについて、未変更の翻訳が残っているロケールを古いものと判定します。これは意図的に**既存の負債を固定**します。差分からは、長期間存在する翻訳がどの古い英語に基づいているか判断できないため、このゲートでは現在の変更が触れた箇所のみを判定します。代替案(キーごとのハッシュベースライン)では、既存の最大ベースラインの3倍に相当する約600 KBの生成ファイルが必要となり、i18nのPRごとに変更が発生します。 これを満たす方法は2つあります。 1. 影響を受ける翻訳を更新する、または -2. `__MISSING__:` に設定する — その場合、ランタイムは修正済みの英語を返し - (`src/i18n/request.ts::deepMergeFallback`、#7258)、そのキーを翻訳待ちキューに追加します。 +2. `__MISSING__:` に設定する — するとランタイムは修正済みの英語を返し + (`src/i18n/request.ts::deepMergeFallback`、#7258)、そのキーは翻訳待ちキューに追加されます。 -文字列の**意味**が変わった場合は、**キー名の変更**を優先してください。新しいキーが -古い翻訳を継承することはありません。#8463ではこのパターンが使用されています。 +文字列の**意味**が変わった場合は、**キーの名前変更**を推奨します。新しいキーが古い翻訳を引き継ぐことはありません。#8463ではこのパターンが使用されています。 ```bash -npm run i18n:check-value-drift # 厳格モード(CIで実行されるもの) +npm run i18n:check-value-drift # 厳格(CIで実行されるもの) npm run i18n:check-value-drift:warn # レポートのみ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -ベースカタログを読み取れない場合(ベースrefのないシャロークローン)は、 -`check-openapi-breaking` と同様に、`SKIP reason=base-unresolved` を表示して終了コード0で -終了します。 +ベースカタログを読み取れない場合(ベースrefを含まないshallow clone)は、`check-openapi-breaking`と同様に、`SKIP reason=base-unresolved`を表示して終了コード0で終了します。 -### ジョブ: `i18n` +### ジョブ:`i18n` -完全なi18n検証マトリクス(ロケールごとに1ジョブ)。ジョブ全体が参考情報扱いです。 +完全なi18n検証マトリックス(ロケールごとに1ジョブ)。ジョブ全体がアドバイザリです。 -| スクリプト | 検証内容 | ブロッキング | -| ------------------------------- | -------------------------- | ----------------------------------------------------- | -| `validate_translation.py quick` | ロケールごとの翻訳の完全性 | **参考情報**(ジョブ全体で`continue-on-error: true`) | +| スクリプト | 検証内容 | ブロッキング | +| ------------------------------- | -------------------------- | --------------------------------------------------------- | +| `validate_translation.py quick` | ロケールごとの翻訳の完全性 | **アドバイザリ**(ジョブ全体に`continue-on-error: true`) | -### ジョブ: `pr-test-policy` +### ジョブ:`pr-test-policy` プルリクエストでのみ実行されます。 -| スクリプト | 検証内容 | ブロッキング | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `check:pr-test-policy` | `src/`、`open-sse/`、`electron/`、または`bin/`の本番コードを変更するPRには、テストの追加または更新が必要(ハードルール#8) | はい | -| `check:test-masking` | 変更されたテストファイルで、アサートの純数が減少しておらず、`assert.ok(true)`のような恒真式が追加されていないこと | はい | -| `check:pr-evidence` | PR本文に変更に関するテスト/VPSの証跡が記載されていること(PRの文章をgrepしてハードルール#18を機械化 — 壊れやすいためBacklogを参照) | はい | +| スクリプト | 検証内容 | ブロッキング | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `check:pr-test-policy` | `src/`、`open-sse/`、`electron/`、または`bin/`内の本番コードを変更するPRには、テストの追加または更新が必要(ハードルール#8) | はい | +| `check:test-masking` | 変更されたテストファイルで、アサーションの正味数が減少しておらず、`assert.ok(true)`のような恒真式が追加されていないこと | はい | +| `check:pr-evidence` | PR本文に変更に関するテスト/VPSの証拠が記載されていること(PR本文をgrepしてハードルール#18を自動化 — 脆弱。Backlogを参照) | はい | -### ジョブ: `test-vitest` +### ジョブ:`test-vitest` -`build`後に実行されます。失敗した場合はマージをブロックします。 +`build`の後に実行されます。失敗した場合はマージをブロックします。 -| スイート | 検証内容 | ブロッキング | -| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCPサーバー(110ツール)、autoCombo、キャッシュ — vitestランナー | はい | -| `test:vitest:ui` | UIコンポーネントテスト — vitestランナー | **ブロッキング** — 既存の失敗は`vitest.config.ts`で明示的に除外されており、新たな失敗が発生するとジョブが失敗します | +| スイート | 検証内容 | ブロッキング | +| ---------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCPサーバー(110ツール)、autoCombo、キャッシュ — vitestランナー | はい | +| `test:vitest:ui` | UIコンポーネントテスト — vitestランナー | **ブロッキング** — 既存の失敗は`vitest.config.ts`で明示的に除外されており、新しい失敗はジョブを失敗させます | -### 夜間ワークフロー(スケジュール実行、参考情報) +### ナイトリーワークフロー(スケジュール実行、アドバイザリ) -これらはcronスケジュール(および`workflow_dispatch`)で実行され、PRでは実行されません。すべて参考情報扱いです。 +これらはcronスケジュール(および`workflow_dispatch`)で実行され、PRでは実行されません。すべてアドバイザリです。 -| ワークフロー | 検証内容 | ブロッキング | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `nightly-property` | ランダムシードと多い実行回数を使用したfast-checkプロパティテスト | **参考情報** | -| `nightly-resilience` | ヒープ増加ゲート、カオスフォールトインジェクション、k6負荷/ソークテスト | **参考情報** | -| `nightly-llm-security` | promptfooインジェクションガード(ブロックモード)+ garakプローブ(プロバイダーシークレットがない場合はスキップ) | **参考情報** | -| `nightly-schemathesis` | `docs/openapi.yaml`を使用し、稼働中のOmniRouteに対してOpenAPIコントラクトファジング(schemathesis)を実行 — 仕様違反/未処理の500を明らかにする(フェーズ8 B.4) | **参考情報** | -| `nightly-mutation` | 高速ユニットレーンに対するStrykerミューテーションテストのスコア — 生き残ったミュータントにより弱いアサートを明らかにする | **参考情報** | -| `nightly-compat` | サポート対象の`engines.node`範囲全体にわたるNodeエンジン互換性マトリクス | **参考情報** | +| ワークフロー | 検証内容 | ブロッキング | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `nightly-property` | ランダムシードと高い実行回数を使用するfast-checkプロパティテスト | **アドバイザリ** | +| `nightly-resilience` | ヒープ増加ゲート、カオス障害注入、k6負荷/ソークテスト | **アドバイザリ** | +| `nightly-llm-security` | promptfooインジェクションガード(ブロックモード)+ garakプローブ(プロバイダーシークレットがない場合はスキップ) | **アドバイザリ** | +| `nightly-schemathesis` | `docs/openapi.yaml`を使用して稼働中のOmniRouteに対して行うOpenAPIコントラクトファジング(schemathesis)— 仕様違反/未処理の500を顕在化(フェーズ8 B.4) | **アドバイザリ** | +| `nightly-mutation` | 高速ユニットレーンに対するStrykerミューテーションテストのスコア — 生き残ったミュータントによって弱いアサーションを顕在化 | **アドバイザリ** | +| `nightly-compat` | サポート対象の`engines.node`範囲全体にわたるNodeエンジン互換性マトリックス | **アドバイザリ** | --- @@ -536,41 +529,41 @@ CI ゲートに加えて、OmniRoute には**オプトイン**の `agent-lsp` ## 合理化バックログ(ROI レビュー — フェーズ 9 ウェーブ 3) -このインベントリは 2026-06-17 に `ci.yml` と照合済みです(以前のバージョンでは +このインベントリは 2026-06-17 に `ci.yml` と照合されました(以前のバージョンでは `audit:deps`、`check:tracked-artifacts`、`check:lockfile`、`check:licenses`、 `check:dead-code`、`check:cognitive-complexity`、`check:type-coverage`、 -`check:codeql-ratchet`、`check:pr-evidence` が抜けていました)。照合済みセットの ROI レビューにより、 -以下の合理化候補が特定されました。**マージは機械的な CI -変更です。切り替え/削除はオペレーターに委ねられたポリシー上の判断です。** 以下の内容は +`check:codeql-ratchet`、`check:pr-evidence` が欠落していました)。照合済みのセットに対する ROI レビューにより、 +以下の合理化候補が特定されました。**統合は機械的な CI +変更です。切り替え/削除はオペレーターに委ねられたポリシー判断です。** 以下の項目は まだ何も適用されていません。 -**上記に加えて未文書化の項目**(アドバイザリー、シグナルが弱い)として、`docs-lint` ジョブ -(markdownlint + Vale、ジョブ全体が `continue-on-error`)およびスタンドアロンのスキャナーワークフロー -`semgrep.yml` / `codeql.yml` / `scorecard.yml` があります。`semgrepFindings: 0` は -`quality-baseline.json` にありますが、`ci.yml` のブロッキング・ラチェットには接続されていません。このメトリクスは +**上記に記載されていないもの**(アドバイザリー、シグナルが弱い):`docs-lint` ジョブ +(markdownlint + Vale、ジョブ全体が `continue-on-error`)および独立したスキャナーワークフロー +`semgrep.yml` / `codeql.yml` / `scorecard.yml`。`semgrepFindings: 0` は +`quality-baseline.json` にありますが、`ci.yml` のブロッキングラチェットには接続されていません。このメトリクスは 現在孤立しています。 -### マージ/重複排除(機械的、低リスク) +### 統合/重複排除(機械的、低リスク) -各候補は 2026-06-17 時点の実際のゲート状態に対して検証済みです(信頼しつつ検証)。 -一見「明らか」なマージのいくつかは、実際には負債を隠していることが判明し、**そのまま置き換え可能ではありません**。 +各候補は 2026-06-17 時点の実際のゲート状態と照合して検証されました(信頼しつつ検証)。 +「明らか」に見えた複数の統合が、実際には負債を隠しており、**そのまま置き換えられるものではない**ことが判明しました。 -- **`check:docs-sync` が 2 回実行される** — `lint` ジョブ内で単独実行され、さらに `check:docs-all`(`docs-sync-strict`)内および husky の pre-commit フックでも実行されます。✅ **完了** — `lint` での単独呼び出しを削除しました。 -- **CVE スキャン** — ❌ **そのままマージ不可。** `audit:deps` は high/critical の CVE が 1 件でもあるとハードフェイルします。一方、`check:vuln-ratchet`(osv)はベースライン(現在は MODERATE が 1 件)に対する_リグレッション_がある場合にのみ失敗します。セマンティクスが異なるため、`audit:deps` を削除すると high/critical に対する絶対的なゲートが失われます。両方を維持してください。 -- **循環依存の検出** — ❌ **そのままマージ不可。** `check:circular-deps`(dpdm)は **91 件の循環**を報告します(そのためアドバイザリーになっています)。まずそれらを解消しない限りブロッキングに昇格できず、正常なキュレーション済み `check:cycles` よりも対象範囲が広くなっています。`check:cycles` はブロッキングのまま維持してください。91 件の dpdm 循環の解消は、独立したバックログ項目です。 -- **複雑度** — ✅ **完了**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`):ESLint の走査を 1 回に統合し、ruleId ごとにカウントすることで、循環的複雑度+最大行数と認知的複雑度のベースラインを独立させたままにしています。個別の `check:complexity` / `check:cognitive-complexity` は、ローカルでの `--update` 用に残しています。 -- **`/api` のハルシネーション防止** — ✅ **完了**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`):`src/app/api` の FS インベントリを 1 回に統合し、openapi-routes と docs-symbols は引き続き個別にレポートします。個別コマンドはローカル実行用に残しています。 -- **`check:node-runtime` が 11 個のジョブで実行される** — ⚠️ **ROI が低いです。** 各ジョブは別々のランナーで実行され、このチェックは 1 秒未満です。合計削減時間は約 10 秒ですが、安価なジョブ単位のガードを失うことになります。変更コストに見合いません。 -- **CI lint 上の `typecheck:noimplicit:core`** — ✅ **lint ジョブから削除済み**(以前はアドバイザリーの `continue-on-error`)。ブロッキングの型サーフェスは `typecheck:core` + `check:type-coverage` です。ローカルスクリプトは維持しています。 +- **`check:docs-sync` が 2 回実行される** — `lint` ジョブで単独実行され、さらに `check:docs-all`(`docs-sync-strict`)内と husky の pre-commit フックでも実行されます。✅ **完了** — 単独の `lint` 呼び出しを削除しました。 +- **CVE スキャン** — ❌ **そのまま統合可能ではありません。** `audit:deps` は high/critical の CVE が 1 件でもあればハードフェイルします。`check:vuln-ratchet`(osv)はベースライン(現在 1 MODERATE)に対する_悪化_の場合にのみ失敗します。セマンティクスが異なるため、`audit:deps` を削除すると high/critical に対する絶対的なゲートが失われます。両方を維持します。 +- **循環検出** — ✅ **完了**(#15159 G-01/G-02)。以前の記述では `check:cycles` を「グリーンで、厳選された」ゲートと呼び、`check:circular-deps`(dpdm)が 91 件の循環を報告していたことを理由に、ブロッキングのまま維持することを正当化していました。そのグリーンは**偽のグリーン**でした。`check:cycles` は 5 個のサブディレクトリ(450 ファイル)をスキャンし、静的な `import|export … from` のみにマッチし、すべての `@/` および `@omniroute/open-sse/` 指定子を除外していたため、リポジトリ内の大半を占める動的 import + エイリアスの循環を検出できませんでした。修正済みです。現在のゲートは `src` + `open-sse`(5023 ファイル)を走査し、TypeScript AST から指定子を収集し(そのため `import("…")` はカウントされ、型位置の `typeof import("…")` はカウントされません)、tsconfig の `paths` を解決します。検出される循環は 0 件ではなく **14** 件です。既存の 14 件の循環はゲート PR では修正できないため、`check:cycles` は現在**ラチェット**になっています(`--ratchet`、`quality-baseline.json` 内の上限は `metrics.cycles.value = 14`、`direction: down`)。あらゆる_悪化_をブロックし、件数は減少することしか許されません。CI は `npm run check:cycles:ratchet` を実行します。段階的な解消は **A-01** と併せて進めます。`check:circular-deps`(dpdm)は、より広範なセカンドオピニオンとしてアドバイザリーのまま維持します。 +- **複雑度** — ✅ **完了**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`):1 回の ESLint 走査で、ruleId ごとにカウントするため、循環的複雑度 + 最大行数と認知的複雑度のベースラインは独立したままです。個別の `check:complexity` / `check:cognitive-complexity` は、ローカルでの `--update` 用に維持します。 +- **`/api` の幻覚防止** — ✅ **完了**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`):`src/app/api` に対する 1 回の FS インベントリで、openapi-routes + docs-symbols は引き続き個別に報告します。個別のチェックはローカル実行用に維持します。 +- **`check:node-runtime` が 11 ジョブで実行される** — ⚠️ **ROI が低いです。** それぞれが別のランナーであり、チェックは 1 秒未満です。節約できる合計時間は約 10 秒ですが、その代わりに安価なジョブ単位のガードを失います。変更に伴う手間に見合いません。 +- **CI lint での `typecheck:noimplicit:core`** — ✅ **lint ジョブから削除済み**(以前はアドバイザリーの `continue-on-error`)。ブロッキング対象の型サーフェスは `typecheck:core` + `check:type-coverage` です。ローカルスクリプトは維持しています。 -### 切り替え/判断(オペレーターのポリシー) +### 切り替え/判断(オペレーターポリシー) -- `check:openapi-security-tiers`(アドバイザリー)— ❌ **そのまま切り替え不可。** 終了コードは 0 ですが、`LOCAL_ONLY_API_PREFIXES` 配下の複数の `traffic-inspector` ルートに `x-loopback-only: true` アノテーションがないと警告します。強制するには、まずそれらのアノテーションを `openapi.yaml` に追加する必要があります。 -- `typecheck:noimplicit:core`(アドバイザリー)— ブロッキングの `check:type-coverage` ラチェットによって大部分が包含されています。ラチェットに切り替えるか、重複する 2 回目の `tsc` パスを削除してください。 -- `test:vitest:ui`(現在は**ブロッキング**)— 既存の失敗は、`// #8618` の追跡コメント付きで `vitest.config.ts` から明示的に除外されています。新たな失敗が発生するとジョブは失敗します。 -- `check:secrets`(gitleaks、文書化済みの誤検知 3 件で固定されたブロッキング・ラチェット)— 3 件を許可リストに入れて 0 にするか、アドバイザリーに降格してください。GitHub ネイティブのシークレットスキャンおよび `check:public-creds` と重複しています。 -- `check:pr-evidence`(ブロッキング、PR 本文の文章を grep)— 誤検知のリスクが高い一方、削除するとハードルール #18 の強制力が弱まるため、これは純粋にポリシー上の判断です。 -- `semgrep`(アドバイザリーのスタンドアロン)— OWASP 系の検出で CodeQL と重複しています。ベースラインをラチェットに接続するか、削除してください。 +- `check:openapi-security-tiers`(アドバイザリー)— ❌ **そのまま切り替えることはできません。** 終了コードは 0 ですが、`LOCAL_ONLY_API_PREFIXES` 配下の複数の `traffic-inspector` ルートに `x-loopback-only: true` アノテーションがないことを警告します。強制するには、まずそれらのアノテーションを `openapi.yaml` に追加する必要があります。 +- `typecheck:noimplicit:core`(アドバイザリー)— 大部分がブロッキングの `check:type-coverage` ラチェットに包含されています。ラチェットに切り替えるか、重複する 2 回目の `tsc` パスを削除します。 +- `test:vitest:ui`(現在は**ブロッキング**)— 既存の失敗は、`// #8618` 追跡コメント付きで `vitest.config.ts` から明示的に除外されています。新たな失敗が発生するとジョブは失敗します。 +- `check:secrets`(gitleaks、文書化された 3 件の誤検知で固定されたブロッキングラチェット)— 3 件を許可リストに追加して 0 件にするか、アドバイザリーへ降格します。GitHub ネイティブの secret-scanning + `check:public-creds` と重複します。 +- `check:pr-evidence`(ブロッキング、PR 本文の文章を grep)— 誤検知のリスクが高いです。削除するとハードルール #18 の強制力が弱まるため、これは実質的なポリシー判断です。 +- `semgrep`(独立したアドバイザリー)— OWASP 系統について CodeQL と重複します。ベースラインをラチェットに接続するか、削除します。 --- diff --git a/docs/i18n/ka/CONTRIBUTING.md b/docs/i18n/ka/CONTRIBUTING.md index 953774c54f0..7db424d06dd 100644 --- a/docs/i18n/ka/CONTRIBUTING.md +++ b/docs/i18n/ka/CONTRIBUTING.md @@ -398,17 +398,17 @@ docs/ - [ ] ტესტები წარმატებით სრულდება (`npm test`) - [ ] ლინტინგი წარმატებით სრულდება (`npm run lint`) - [ ] აგება წარმატებით სრულდება (`npm run build`) -- [ ] ახალი საჯარო ფუნქციებისა და ინტერფეისებისთვის დამატებულია TypeScript-ის ტიპები -- [ ] არ არის მყარად გაწერილი საიდუმლოები ან სარეზერვო მნიშვნელობები -- [ ] ზედა დონის საჯარო ავტორიზაციის მონაცემები ჩაშენებულია `resolvePublicCred()`-ის მეშვეობით (იხილეთ [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) და არასოდეს — ლიტერალების სახით -- [ ] შეცდომის პასუხები მუშავდება `buildErrorBody()` / `sanitizeErrorMessage()`-ის მეშვეობით — პასუხის სხეულებში არ არის დაუმუშავებელი სტეკის კვალები (იხილეთ [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] ახალ საჯარო ფუნქციებსა და ინტერფეისებს დამატებული აქვს TypeScript-ის ტიპები +- [ ] არ არის მყარად გაწერილი საიდუმლო მონაცემები ან სარეზერვო მნიშვნელობები +- [ ] საჯარო upstream ავტორიზაციის მონაცემები ჩაშენებულია `resolvePublicCred()`-ის მეშვეობით (იხილეთ [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) და არასდროს — პირდაპირი ლიტერალების სახით +- [ ] შეცდომის პასუხები მუშავდება `buildErrorBody()` / `sanitizeErrorMessage()`-ის მეშვეობით — პასუხის სხეულებში არ არის დაუმუშავებელი stack trace-ები (იხილეთ [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] გარსის ბრძანებები (`exec` / `spawn`) შესრულების დროის მნიშვნელობებს გადასცემს `env`-ის მეშვეობით და არა სტრიქონული ინტერპოლაციით -- [ ] ყველა შეყვანილი მონაცემი შემოწმებულია Zod-ის სქემებით -- [ ] მომხმარებლისთვის ხილული ცვლილებებისთვის ცვლილებების ჟურნალის **ფრაგმენტი** დამატებულია `changelog.d/{features|fixes|maintenance}/-.md`-ში (იხილეთ [`changelog.d/README.md`](./changelog.d/README.md)) — **არ** დაარედაქტიროთ `CHANGELOG.md` პირდაპირ; ფრაგმენტები გაერთიანდება გამოშვებისას და Pull Request-ებს შორის კონფლიქტს არასოდეს წარმოქმნის +- [ ] ყველა შეყვანილი მონაცემი ვალიდირებულია Zod-ის სქემებით +- [ ] მომხმარებლისთვის ხილული ცვლილებებისთვის `changelog.d/{features|fixes|maintenance}/-.md`-ში დამატებულია ცვლილებების ჟურნალის **ფრაგმენტი** (იხილეთ [`changelog.d/README.md`](./changelog.d/README.md)) — **არ** დაარედაქტიროთ `CHANGELOG.md` პირდაპირ; ფრაგმენტები ერთიანდება რელიზის დროს და Pull Request-ებს შორის კონფლიქტს არასდროს იწვევს - [ ] დოკუმენტაცია განახლებულია (თუ საჭიროა) -- [ ] არ არის გახსნილი CodeQL-ის / Secret-Scanning-ის ახალი გაფრთხილებები, ან თითოეული მათგანი უარყოფილია ტექნიკური დასაბუთებით, რომელიც შესაბამის `docs/security/` დოკუმენტს მიუთითებს +- [ ] არ გახსნილა CodeQL-ის / Secret-Scanning-ის ახალი გაფრთხილებები, ან თითოეული მათგანი უარყოფილია ტექნიკური დასაბუთებით, შესაბამის `docs/security/` დოკუმენტზე მითითებით - [ ] მარშრუტები, რომლებიც შვილობილ პროცესებს უშვებს (`/api/mcp/`, `/api/cli-tools/runtime/`), კლასიფიცირებულია როგორც `isLocalOnlyPath()` ფაილში `src/server/authz/routeGuard.ts` — იხილეთ [მკაცრი წესი #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] commit-ის შეტყობინებებში არ არის `Co-Authored-By` ტრეილერები — commit-ები მხოლოდ რეპოზიტორიის მფლობელის Git-ის იდენტობის ქვეშ უნდა გამოჩნდეს (მკაცრი წესი #16) +- [ ] commit-ის შეტყობინებებში არ არის AI/bot-ის `Co-authored-by` ტრეილერები (მკაცრი წესი #16) — ადამიან თანამშრომლებს, რომელთა ნამუშევარიც ხელახლა გამოიყენება, მიეთითებათ ავტორობა სტანდარტული `Co-authored-by: Name ` ტრეილერებით --- diff --git a/docs/i18n/ka/docs/architecture/QUALITY_GATES.md b/docs/i18n/ka/docs/architecture/QUALITY_GATES.md index 50cea369a9d..574f289c6d9 100644 --- a/docs/i18n/ka/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ka/docs/architecture/QUALITY_GATES.md @@ -19,259 +19,251 @@ ### კანდიდატის დაშვება -CI და Quality Gates სამუშაო პროცესები თითოეული გასცემს სტაბილურ ვერდიქტს: `Gate / CI` და -`Gate / Quality`. მათი ვერსირებული დაშვების პოლიტიკა თითოეულ ზედა დონის დავალებას -სავალდებულოდ ან სარეკომენდაციოდ განსაზღვრავს. შესაბამისი სავალდებულო დავალება წარმატებით უნდა დასრულდეს: -არარსებული, გაუქმებული, გამოტოვებული, მოლოდინის რეჟიმში მყოფი და უცნობი შედეგები PASS სტატუსს ვერ ადასტურებს. მხოლოდ -დოკუმენტაციასთან ან მხოლოდ კატალოგთან დაკავშირებულმა მართებულმა კლასიფიკაციამ შესაძლოა კოდის ნაკადი შეუსაბამოდ აქციოს; -შავი PR მიღებულ კანდიდატად არ ითვლება. `hotfix` ჭდე მტკიცებულების მოთხოვნას არ აუქმებს. - -ორივე სამუშაო პროცესი მოიცავს PR-ებსა და main/release განშტოებებში გაგზავნილ ცვლილებებს, ხელით გაშვებასა და -merge-group მოვლენებს. Push, dispatch და merge-group სრულ შერჩევას უშვებს. ფორკები -და merge-group-ები ჰოსტირებულ რანერებს იყენებს იმ დავალებებისთვის, რომლებიც სხვა შემთხვევაში თვითჰოსტირებულ -რანერებს აირჩევდა; დანერგვამდე უნდა შემოწმდეს ჰოსტირებული სიმძლავრის საკმარისობა. - -თითოეული JSON ქვითარი განსაზღვრავს ამოღებულ SHA-ს, სამუშაო პროცესის გაშვებასა და მცდელობას. -CLI უარყოფს checkout/event SHA შეუსაბამობას. სამუშაო პროცესის ტესტები პოლიტიკის წევრობას -ვერდიქტის დავალების `needs` სიას უკავშირებს, რათა ახალი ან წაშლილი ნაკადი შეუმჩნევლად არ გაქრეს. -ქვითრები მოიცავს საკუთარ სამუშაო პროცესს და არა გამოქვეყნებას, განთავსებას ან არსებული -სარეკომენდაციო სკანერის შიდა მუშაობას. განშტოების წესებში ორივე შემოწმების სახელის გააქტიურება -ცალკე ადმინისტრაციული ცვლილებაა; ამ დავალებების დამატება თავისთავად არ იცავს განშტოებას. +CI-ისა და Quality Gates-ის სამუშაო პროცესები თითოეული გამოსცემს სტაბილურ ვერდიქტს: `Gate / CI` და +`Gate / Quality`. მათი ვერსირებული დაშვების პოლიტიკა ყველა ზედა დონის დავალებას +სავალდებულოდ ან სარეკომენდაციოდ განსაზღვრავს. შესაბამისი სავალდებულო დავალება წარმატებით უნდა დასრულდეს: არარსებული, +გაუქმებული, გამოტოვებული, მოლოდინის რეჟიმში მყოფი და უცნობი შედეგები PASS-ს ვერ დაადასტურებს. მხოლოდ +დოკუმენტაციად ან მხოლოდ კატალოგად მართებულმა კლასიფიკაციამ შესაძლოა კოდის შესრულების ზოლი შეუსაბამოდ აქციოს; +შავი PR მიღებულ კანდიდატად არ ითვლება. `hotfix` იარლიყი მტკიცებულების მოთხოვნას არ აუქმებს. + +ორივე სამუშაო პროცესი მოიცავს PR-ებსა და push-ებს main/release განშტოებებში, ხელით გაშვებასა და +merge-group მოვლენებს. Push, dispatch და merge-group სრულ არჩევანს ასრულებს. Fork-ები +და merge group-ები ჰოსტირებულ runner-ებს იყენებს იმ დავალებებისთვის, რომლებიც სხვა შემთხვევაში self-hosted +runner-ებს აირჩევდა; გაშლამდე საკმარისი ჰოსტირებული სიმძლავრე უნდა შემოწმდეს. + +თითოეული JSON ქვითარი განსაზღვრავს checkout-ით მიღებულ SHA-ს, სამუშაო პროცესის გაშვებასა და მცდელობას. +CLI უარყოფს checkout/event SHA-ს შეუსაბამობას. სამუშაო პროცესის ტესტები პოლიტიკის წევრობას +ვერდიქტის დავალების `needs` სიასთან აკავშირებს, რათა ახალი ან წაშლილი ზოლი შეუმჩნევლად არ გაქრეს. +ქვითრები მოიცავს საკუთარ სამუშაო პროცესს და არა გამოქვეყნებას, გაშლას ან არსებული +სარეკომენდაციო სკანერის შიდა ლოგიკას. განშტოების წესებში ორივე შემოწმების სახელის გააქტიურება +ცალკე ადმინისტრაციული ცვლილებაა; ამ დავალებების დამატება თავისთავად განშტოებას არ იცავს. ### სტატიკური სკანირების ინვენტარი ვერსირებული npm-ფსევდონიმების ინვენტარი და სტატიკური სკანირების წევრობა განთავსებულია -`config/quality/gate-manifest.json`-ში. სკრიპტების სახელებისა და ზუსტი ბრძანებების -`package.json`-თან შესადარებლად გაუშვით `npm run check:gate-manifest`; დამატებები, წაშლები და -ბრძანებების გადახრა წარუმატებელს ხდის როგორც ლოკალურ ჰუკს, ისე CI-ში ცვლილებების კლასიფიკაციის დავალებებს. +`config/quality/gate-manifest.json`-ში. გაუშვით `npm run check:gate-manifest`, რათა +სკრიპტების სახელები და ზუსტი ბრძანებები `package.json`-თან მიმართებით შეამოწმოთ; დამატებები, წაშლები და +ბრძანებების აცდენა ჩავარდნას იწვევს როგორც ლოკალურ hook-ში, ისე CI-ის ცვლილებების კლასიფიკაციის დავალებებში. ფსევდონიმი არ არის სამუშაო პროცესის დავალება, მატრიცის ეგზემპლარი ან სატესტო შემთხვევა: ეს რაოდენობები ურთიერთჩანაცვლებადად არ უნდა იყოს წარმოდგენილი. -არჩეული ფსევდონიმების შესრულების გარეშე შესამოწმებლად გამოიყენეთ `npm run quality:scan -- --list` ან `npm run quality:scan:fast -- --list`. -რანერი npm-ის შესვლის წერტილს იძახებს, ამიტომ მისი შესრულების გარემო (მათ შორის Bun, სადაც კონფიგურირებულია) შენარჩუნებულია. -მანიფესტი ამ პროფილების მიღმა არსებულ ფსევდონიმებს ცალკე გამოძახებულად აღრიცხავს, ხოლო +არჩეული ფსევდონიმების შესრულების გარეშე სანახავად გამოიყენეთ `npm run quality:scan -- --list` ან `npm run quality:scan:fast -- --list`. +runner-ი npm-ის შესვლის წერტილს იძახებს, ამიტომ მისი შესრულების გარემო (მათ შორის, სადაც კონფიგურირებულია, Bun) შენარჩუნებულია. +მანიფესტი ამ პროფილების გარეთ არსებულ ფსევდონიმებს ცალკე გამოძახებულად აღრიცხავს, ხოლო მომსახურების ბრძანებები მხოლოდ-წაკითხვის სკანირების პროფილებში აკრძალულია. ეს პროფილები მხოლოდ სტატიკურ სკანირებას მოიცავს. ისინი არ ადასტურებს პროდუქტის ტესტებს, -დაფარვას, პაკეტირებას, გარე შემოწმებებს ან კანდიდატის რელიზისთვის სრულ დაშვებას. +დაფარვას, შეფუთვას, გარე შემოწმებებს ან კანდიდატის სრულ შესაბამისობას რელიზის მოთხოვნებთან. სამუშაო პროცესში დაშვება იყენებს დაკავშირებულ `config/quality/admission-policy.json`-სა და -`scripts/quality/admission-verdict.mjs`-ს. Release-observer პროფილები განცალკევებული რჩება; +`scripts/quality/admission-verdict.mjs`-ს. Release-observer-ის პროფილები განცალკევებული რჩება; მათი შესაბამისი შემოწმებები და ქვითრები დამოუკიდებლად შეამოწმეთ. ქვემოთ მოცემული ტექსტური ინვენტარი საცნობაროა და არა იმის მტკიცებულება, რომ გეითი რეალურად გაეშვა. -სკრიპტები განთავსებულია `scripts/check/`-ში (პოლიტიკის გეითები) და `scripts/quality/`-ში (ratchet ძრავა). +სკრიპტები განთავსებულია `scripts/check/`-ში (პოლიტიკის გეითები) და `scripts/quality/`-ში (ratchet-ის ძრავა). CI-ის ჭეშმარიტების წყაროა `.github/workflows/ci.yml`. ### Release PR-ის სწრაფი გზა (`quality.yml`) -`.github/workflows/quality.yml` ავსებს CI-ს main/release PR-ებზე, დაცულ განშტოებებში -გაგზავნილ ცვლილებებზე, dispatch-სა და merge-group-ებზე. PR-ები იყენებს ბილიკებით გაფილტრულ სწრაფ შემოწმებებს. მუდმივად -გამორთული დუბლირებული აგება წაიშალა; რეალური აგების/პაკეტირების/ჩატვირთვის შემოწმებები CI-ში რჩება. +`.github/workflows/quality.yml` ავსებს CI-ს main/release PR-ებისთვის, დაცულ განშტოებებში +push-ებისთვის, dispatch-ისა და merge group-ებისთვის. PR-ები გზების მიხედვით გაფილტრულ სწრაფ შემოწმებებს იყენებს. მუდმივად +გამორთული დუბლირებული build წაიშალა; რეალური build/package/boot შემოწმებები CI-ში რჩება. -| დავალება | ფარგლები | ბლოკირებადი | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | -| `Docs Gates (fast-path)` | დოკუმენტაციის/კოდის PR-ები; API დოკუმენტაციის ბმულები და სრულად დოკუმენტაცია | დიახ | -| `Fast Quality Gates` | კოდის PR-ები; სტატიკური შემოწმებები, ტიპების შემოწმება, დაფის ტიპების შემოწმება, ზემოქმედებული მოდულური ტესტები | დიახ | -| `Forgotten sibling tests` | კოდის PR-ები; შეცვლილი მოდულების მიკვლევა სტატიკურ მომხმარებლებსა და შესაძლო მონათესავე ტესტებამდე; barrel და dynamic-import ბილიკები წარმოდგენილია სარეკომენდაციო დიაგნოსტიკის სახით, მითითებული დაშვების სიის გამონაკლისებით | **სარეკომენდაციო** | -| `Vitest (fast-path)` | კოდის PR-ები; სწრაფი vitest ნაკრები | დიახ | -| `Unit Tests fast-path` | კოდის PR-ები; 4-შარდიანი მოდულური ტესტების ნაკრები | დიახ | -| `No new ESLint warnings` | კოდის PR-ები; გამონაკლისების გათვალისწინების მქონე lint დამცავი | დიახ, ფორკების ჩათვლით | -| `Merge integrity (changelog + generated skills)` | არაშავი PR-ები; ცვლილებების ჟურნალისა და გენერირებული უნარების სინქრონიზაცია | დიახ, ფორკების ჩათვლით | +| დავალება | მოქმედების არეალი | დამბლოკავი | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `Docs Gates (fast-path)` | დოკუმენტაციის/კოდის PR-ები; API დოკუმენტაციის მითითებები და სრული დოკუმენტაცია | დიახ | +| `Fast Quality Gates` | კოდის PR-ები; სტატიკური შემოწმებები, ტიპების შემოწმება, dashboard-ის ტიპების შემოწმება, ზემოქმედების ქვეშ მყოფი მოდულური ტესტები | დიახ | +| `Forgotten sibling tests` | კოდის PR-ები; შეცვლილი მოდულების კვალის მიდევნება სტატიკურ მომხმარებლებსა და კანდიდატ მონათესავე ტესტებამდე; barrel-ისა და dynamic-import-ის გზები სარეკომენდაციო დიაგნოსტიკად ანგარიშდება, შესაბამისი allowlist გამონაკლისებით | **სარეკომენდაციო** | +| `Vitest (fast-path)` | კოდის PR-ები; სწრაფი vitest კომპლექტი | დიახ | +| `Unit Tests fast-path` | კოდის PR-ები; მოდულური ტესტების 4-shard-იანი კომპლექტი | დიახ | +| `No new ESLint warnings` | კოდის PR-ები; ჩახშობების გათვალისწინებით მოქმედი lint-ის დამცავი | დიახ, fork-ების ჩათვლით | +| `Merge integrity (changelog + generated skills)` | არაშავი PR-ები; changelog-ისა და გენერირებული უნარების სინქრონიზაცია | დიახ, fork-ების ჩათვლით | #### დავიწყებული მონათესავე ტესტების ანგარიში -`npm run check:forgotten-sibling-tests` ხელახლა იყენებს ტესტებზე ზემოქმედების რუკის საფუძვლად არსებულ იმპორტების გადამჭრელს. -თითოეული შეცვლილი საწარმოო მოდულისთვის ის დეტერმინისტულ -`changed module/symbol -> static consumer -> candidate sibling test` ჯაჭვებს აჩვენებს, როდესაც კანდიდატი -ტესტი pull-request-ის სხვაობაში არ არის. Markdown შეჯამება და JSON შედეგი ინახება, როგორც -`forgotten-sibling-tests` სამუშაო პროცესის არტეფაქტი, ნებისმიერი ბლოკირებადი დანერგვის წინ კალიბრაციისთვის. +`npm run check:forgotten-sibling-tests` ხელახლა იყენებს ტესტებზე ზემოქმედების რუკის საფუძვლად არსებულ import-ის resolver-ს. +ყოველი შეცვლილი საწარმოო მოდულისთვის ის დეტერმინისტულ +`changed module/symbol -> static consumer -> candidate sibling test` ჯაჭვებს აჩვენებს, როცა კანდიდატი +ტესტი pull-request-ის diff-ში არ არის. Markdown-ის შეჯამება და JSON შედეგი ინახება როგორც +`forgotten-sibling-tests` სამუშაო პროცესის არტეფაქტი, ნებისმიერი დამბლოკავი დანერგვის წინ კალიბრაციისთვის. -Barrel re-export-ები და დინამიკური import-ები მხოლოდ resolution-ის დიაგნოსტიკისთვის გამოიყენება; ისინი არასოდეს ქმნიან -დამბლოკავ დარღვევას. განხილული გამონაკლისები ინახება -`config/quality/forgotten-sibling-allowlist.json`-ში. თითოეულ ჩანაწერში მითითებული უნდა იყოს consumer და candidate -ტესტები, წარმოდგენილი უნდა იყოს კონკრეტული დასაბუთება და GitHub issue-ის ან pull request-ის ბმული. არასწორად ფორმირებული ჩანაწერები -უარყოფის პრინციპით მუშავდება. გამონაკლისები ვერ დაფარავს წაშლილ candidate ტესტს ან diff-ს, რომელიც ამატებს `.skip`/`.todo`-ს; -assertion-ის შესუსტება და სხვა სახის დაფარვა კვლავ დამოუკიდებლად დამბლოკავი -`check:test-masking` gate-ის პასუხისმგებლობაში რჩება. +Barrel-რეექსპორტები და დინამიკური იმპორტები მხოლოდ გარჩევადობის დიაგნოსტიკას ემსახურება; ისინი არასოდეს წარმოქმნის +დამბლოკავ მიგნებას. განხილული გამონაკლისები ინახება +`config/quality/forgotten-sibling-allowlist.json`-ში. თითოეულ ჩანაწერში მითითებული უნდა იყოს მომხმარებელი და კანდიდატი +ტესტი, მოცემული უნდა იყოს კონკრეტული დასაბუთება და GitHub-ის issue-ის ან pull request-ის ბმული. არასწორად შედგენილი ჩანაწერები +ნაგულისხმევად უარყოფილია. გამონაკლისები ვერ დაფარავს წაშლილ კანდიდატ ტესტს ან diff-ს, რომელიც ამატებს `.skip`/`.todo`-ს; +assertion-ის შესუსტება და სხვა სახის შენიღბვა კვლავ დამოუკიდებლად დამბლოკავი +`check:test-masking` კარიბჭის პასუხისმგებლობაში რჩება. ### დავალება: `lint` -ეშვება `main`-ზე მიმართულ ყოველ PR-ზე. წარუმატებლობის შემთხვევაში merge-ს ბლოკავს. - -| სკრიპტი (`npm run ...`) | რას ამოწმებს | დამბლოკავი | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| `check:node-runtime` | Node.js-ის ვერსია მხარდაჭერილ დიაპაზონშია | დიახ | -| `check:cycles` | ციკლური import-ები — ყველა `src/` + `open-sse/` მოდული | დიახ | -| `check:route-validation:t06` | Zod-ის სქემები წარმოდგენილია ყველა route-ზე (Tier 6-ის პოლიტიკა) | დიახ | -| `check:any-budget:t11` | `@ts-expect-error // any`-ის რაოდენობა არ აღემატება ბიუჯეტს (Tier 11 catraca) | დიახ | -| `check:provider-consistency` | `providers.ts`-ში თითოეულ პროვაიდერს აქვს შესაბამისი ჩანაწერი `providerRegistry.ts`-ში (და პირიქით, დაშვებული სიის ფარგლებში) | დიახ | -| `check:model-lifecycle` | ხელით მართული სამი მარშრუტიზაციის ცხრილი შესაბამისობაში რჩება რეპოზიტორიაში შენახულ სასიცოცხლო ციკლის სურათთან (#11503): `FITNESS_TABLE` (`taskFitness.ts`) არ ანიჭებს ქულას არცერთ გაუქმებულ id-ს, რომლის მარშრუტიზაციაც `REGISTRY`-ს შეუძლია; `BUILT_IN_ALIASES`-ის თითოეული სამიზნე წარმოდგენილია `REGISTRY`-ში და არ არის გაუქმებული id-ების სურათში; `REGISTRY`-ში ჯერ კიდევ არსებული თითოეული გაუქმებული id გადამისამართებულია ან ჩამოთვლილია `allowedRetiredInCatalog`-ში; და `DEFAULT_DEGRADATION_MAP`-ის არცერთი წყარო ან სამიზნე ამ სურათში გაუქმებულად არ არის მონიშნული. ეს არ ადასტურებს, რომ მოდელს ამჟამად მოქმედი ზედა დონის სერვისი ემსახურება. ოფლაინ რეჟიმში — ადარებს `config/quality/model-lifecycle.json`-ს, რომელიც ხელით ახლდება `npm run quality:refresh-model-lifecycle`-ის მეშვეობით (საჭიროებს ქსელს; CI-ში არ არის ჩართული). `allowedRetiredInCatalog` არის თანდათანობითი შემცირების მექანიზმი: ჩანაწერი დაამატეთ მხოლოდ თვალთვალის საკითხთან ერთად. | დიახ | -| `check:fetch-targets` | კლიენტის მხარის `src/`-ში არსებული თითოეული `fetch("/api/...")` რეალურ `route.ts`-ზე მიუთითებს | დიახ | -| `check:deps` | რეპოზიტორიის თითოეულ `package.json`-ში არსებული ყველა `npm install`-ით ინსტალირებადი დამოკიდებულება შეტანილია `dependency-allowlist.json`-ში; ახალი არაფიქსირებული ვერსიის ან slopsquatting-ის შედეგად წარმოქმნილი პაკეტები მოინიშნება | დიახ | -| `audit:deps` | `npm audit` (ძირითადი პროექტი + electron) — მაღალი/კრიტიკული დონის არცერთი გაფრთხილება (ნაწილობრივ ემთხვევა osv-ის `check:vuln-ratchet`-ს; იხილეთ რაციონალიზაციის ბექლოგი) | დიახ | -| `check:lockfile` | `package-lock.json`-ის მთლიანობა — https რეესტრი, მთლიანობის ჰეშები, ჰოსტის გადაფარვების გარეშე | დიახ | -| `check:licenses` | SPDX ლიცენზიების ნებადართული სია production dependencies-ისთვის | დიახ | -| `check:tracked-artifacts` | build artifacts / commit-ში დამატებული `node_modules` symlinks არ არის (ასევე ეშვება husky pre-commit-ში; pre-push განზრახ მსუბუქია — #6716) | დიახ | -| `check:ai-attribution` | PR commit-ებში, სათაურში ან ტექსტში არ არის AI/ბოტის `Co-Authored-By` trailer ან AI-ის მიერ გენერირების footer — მკაცრი წესი #16 (`quality.yml`-ის fast-gates ციკლში PR→`release/**`-ისთვის — კითხულობს event payload-ს, PR-ების გარეთ არაფერს აკეთებს — და მხოლოდ PR-ისთვის განკუთვნილი ნაბიჯი `ci.yml` lint-ში PR→`main`-ისთვის; ასევე husky `commit-msg` hook; ადამიანის თანაავტორები დაშვებულია; #14436) | -| `check:vitest-exclusions` | Vitest-ის თითოეული გამონაკლისი მიუთითებს tracking issue-ს და წარმოდგენილია `config/quality/vitest-exclusions.json`-ში (#13204) | დიახ | -| `check:file-size` | არცერთი source file არ აჭარბებს შესაბამისი გაფართოებისთვის დაწესებულ ზღვარს (ratchet: გაყინული დიდი ფაილები `frozen` სიაში) | დიახ | -| `check:error-helper` | executors/handlers-ში შეცდომის პასუხები იყენებს `buildErrorBody()` / `sanitizeErrorMessage()`-ს (მკაცრი წესი #12) | დიახ | -| `check:migration-numbering` | მიგრაციის SQL ფაილები დანომრილია თანმიმდევრულად, გამოტოვებებისა და დუბლიკატების გარეშე | დიახ | -| `check:public-creds` | `publicCreds.ts`-ის გარეთ არ არის OAuth-ის ლიტერალური `client_id`/`client_secret` ან Firebase Web გასაღებები (მკაცრი წესი #11) | დიახ | -| `check:db-rules` | `src/lib/db/` მოდულების გარეთ არ არის დაუმუშავებელი SQL; `localDb.ts`-იდან არ არის barrel-იმპორტები (მკაცრი წესები #2/#5) | დიახ | -| `check:known-symbols` | პროვაიდერის შემსრულებლები, მარშრუტიზაციის სტრატეგიები და მთარგმნელები, რომლებიც რეგისტრირებულია შესაბამის დისპეტჩერიზაციის ცხრილებში, ემთხვევა დისკზე არსებულ ფაილებს — არ არის ობოლი ან გამოუცხადებელი სიმბოლოები | დიახ | -| `check:route-guard-membership` | ყველა მარშრუტი, რომელიც შვილობილ პროცესს უშვებს, კლასიფიცირებულია `isLocalOnlyPath()`-ის მიერ (მკაცრი წესები #15/#17) | დიახ | -| `check:test-discovery` | რეპოზიტორიაში არსებული ყველა `*.test.ts` / `*.spec.ts` ფაილი შეგროვებულია სულ მცირე ერთი ტესტების გამშვების მიერ (ratchet: `test-discovery-baseline.json`-ში ობოლი ფაილების სია მხოლოდ შეიძლება შემცირდეს) | დიახ | -| `check:agent-skills-sync` | გენერირებული agent-skills არტეფაქტები ემთხვევა მათ წყარო კატალოგს (გადახრის გარეშე) | -| `check:provider-asset-provenance` | პროვაიდერის ლოგოებს/აქტივებს ახლავს წარმომავლობის რეგისტრირებული ჩანაწერი | -| `lint:json` | JSON კონფიგურაციის ფაილები იშლება შეცდომების გარეშე და აკმაყოფილებს რეპოზიტორიის ლინტინგის წესებს | -| `typecheck:core` | TypeScript-ის კომპილაცია შეცდომების გარეშე (მხოლოდ სარეკომენდაციო გაფრთხილებები) | დიახ | -| `typecheck:noimplicit:core` | მკაცრი `noImplicitAny` — სამომავლო მოთხოვნა; ბევრ მანამდე არსებულ გამოძახების ადგილს ჯერ კიდევ სჭირდება ანოტაციები | **სარეკომენდაციო** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, რომელიც შემოიფარგლება `src/app/(dashboard)/**`-ით (#7033) — `typecheck:core`-ის 27 ფაილისგან შემდგარი შერჩევითი დაშვების სია არ შეიცავს dashboard-ის არცერთ TSX ფაილს, ხოლო `next build` მას საერთოდ არ უტარებს ტიპების შემოწმებას (`next.config.mjs`-ში დაყენებულია `ignoreBuildErrors: true`), ამიტომ იქ არსებული უპატრონო იდენტიფიკატორების რეგრესიები (#6625/#6909) CI-სთვის შეუმჩნეველი იყო. განსხვავებები მოწმდება თითოეულ ფაილსა და TS კოდზე შეცდომების რაოდენობის გაყინულ საბაზისო მაჩვენებელთან (`config/quality/dashboard-typecheck-baseline.json`, მოძველების კონტროლის იგივე სქემით, რომელსაც `check:known-symbols` იყენებს) — შემოწმება ჩავარდება მხოლოდ მაშინ, როდესაც შეცდომების რაოდენობა საბაზისო მაჩვენებელს გადააჭარბებს; მანამდე არსებული შეცდომის გამოსწორებისას ზღვარი შეამცირეთ `--update`-ით. | დიახ | +ეშვება `main`-ში მიმართული ყოველი PR-ისთვის. წარუმატებლობის შემთხვევაში merge-ს ბლოკავს. + +| სკრიპტი (`npm run ...`) | რას ამოწმებს | დამბლოკავი | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:node-runtime` | Node.js-ის ვერსია მხარდაჭერილ დიაპაზონშია | დიახ | +| `check:cycles` | ციკლური იმპორტები მთლიან `src/` + `open-sse/`-ში (AST-ზე დაფუძნებული, tsconfig-ის `paths` გათვალისწინებულია). ცალკე გაშვება მხოლოდ სარეკომენდაციოა და ციკლებს ჩამოთვლის. `check:cycles:ratchet` (რომელსაც CI უშვებს) ბლოკავს, როდესაც რაოდენობა `quality-baseline.json`-ში განსაზღვრულ `metrics.cycles` ზღვარს აჭარბებს — ამჟამად 14, `direction: down`, ამიტომ ის მხოლოდ შეიძლება შემცირდეს (#15159 G-01/G-02) | დიახ (ratchet) | +| `check:route-validation:t06` | Zod-ის სქემები წარმოდგენილია ყველა route-ზე (Tier 6 პოლიტიკა) | დიახ | +| `check:any-budget:t11` | `@ts-expect-error // any`-ის რაოდენობა ბიუჯეტს არ აღემატება (Tier 11 catraca) | დიახ | +| `check:provider-consistency` | `providers.ts`-ში თითოეულ პროვაიდერს აქვს შესაბამისი ჩანაწერი `providerRegistry.ts`-ში (და პირიქით, დაშვებული სიის ფარგლებში) | დიახ | +| `check:model-lifecycle` | ხელით შენარჩუნებული მარშრუტიზაციის სამი ცხრილი შესაბამისობაში რჩება რეპოზიტორიაში დაფიქსირებულ სასიცოცხლო ციკლის სნეპშოტთან (#11503): `FITNESS_TABLE` (`taskFitness.ts`) არ ანიჭებს ქულას არცერთ გაუქმებულ id-ს, რომლის მარშრუტიზაციაც `REGISTRY`-ს შეუძლია; `BUILT_IN_ALIASES`-ის თითოეული სამიზნე წარმოდგენილია `REGISTRY`-ში და არ არის გაუქმებული id-ების სნეპშოტში; `REGISTRY`-ში ჯერ კიდევ არსებული თითოეული გაუქმებული id გადამისამართებულია ან შეტანილია `allowedRetiredInCatalog`-ში; და `DEFAULT_DEGRADATION_MAP`-ის არცერთი წყარო ან სამიზნე ამ სნეპშოტში გაუქმებულად არ არის მონიშნული. ეს არ ამტკიცებს, რომ მოდელს ამჟამად ცოცხალი ზედა დონის სერვისი ემსახურება. ოფლაინ — შედარება ხდება `config/quality/model-lifecycle.json`-თან, რომელიც ხელით ახლდება `npm run quality:refresh-model-lifecycle`-ის გამოყენებით (საჭიროებს ქსელს; CI-ში ინტეგრირებული არ არის). `allowedRetiredInCatalog` არის ეტაპობრივი შემცირების მექანიზმი: ჩანაწერი დაამატეთ მხოლოდ თვალყურის სადევნებელ საკითხთან ერთად. | დიახ | +| `check:fetch-targets` | კლიენტის მხარის `src/`-ში თითოეული `fetch("/api/...")` რეალურ `route.ts`-ზე მიუთითებს | დიახ | +| `check:deps` | რეპოზიტორიაში არსებულ თითოეულ `package.json`-ში ყველა `npm install`-ით დასაყენებელი დამოკიდებულება შეტანილია `dependency-allowlist.json`-ში; ახალი დაუფიქსირებელი ვერსიის ან slopsquatting-ის ნიშნების მქონე პაკეტები მონიშნულია | დიახ | +| `audit:deps` | `npm audit` (ძირეული პროექტი + electron) — მაღალი/კრიტიკული დონის არცერთი გაფრთხილება (ნაწილობრივ ფარავს osv-ის `check:vuln-ratchet`-ს; იხილეთ რაციონალიზაციის დაგროვილი სია) | დიახ | +| `check:lockfile` | `package-lock.json`-ის მთლიანობა — https რეესტრი, მთლიანობის ჰეშები, ჰოსტის ჩამნაცვლებლების გარეშე | დიახ | +| `check:licenses` | საწარმოო დამოკიდებულებებისთვის დაშვებული SPDX ლიცენზიების სია | დიახ | +| `check:tracked-artifacts` | არ არის აგების არტეფაქტები / რეპოზიტორიაში დაფიქსირებული `node_modules` სიმბოლური ბმულები (ასევე სრულდება husky-ის pre-commit ჰუკში; pre-push განზრახ მსუბუქია — #6716) | დიახ | +| `check:ai-attribution` | PR-ის კომიტებში, სათაურში ან აღწერაში არ არის AI/ბოტის `Co-Authored-By` ტრეილერი ან AI-გენერაციის ქვედა კოლონტიტული — მკაცრი წესი #16 (`quality.yml`-ის სწრაფი შემოწმებების ციკლში PR→`release/**`-ისთვის — კითხულობს მოვლენის მონაცემებს, ხოლო PR-ების გარეთ არაფერს აკეთებს — და მხოლოდ PR-ისთვის განკუთვნილ ნაბიჯში `ci.yml`-ის lint შემოწმებაში PR→`main`-ისთვის; ასევე husky-ის `commit-msg` ჰუკში; ადამიან თანაავტორები დაშვებულია; #14436) | +| `check:vitest-exclusions` | Vitest-ის თითოეული გამონაკლისი მიუთითებს თვალყურის სადევნებელ issue-ზე და მოცემულია `config/quality/vitest-exclusions.json`-ში (#13204) | დიახ | +| `check:file-size` | არცერთი საწყისი ფაილი არ აჭარბებს გაფართოების მიხედვით განსაზღვრულ ზღვარს (რეჩეტი: დიდი გაყინული ფაილები `frozen` სიაშია) | დიახ | +| `check:error-helper` | executors/handlers-ში შეცდომის პასუხები იყენებს `buildErrorBody()` / `sanitizeErrorMessage()`-ს (მკაცრი წესი #12) | დიახ | +| `check:migration-numbering` | მიგრაციის SQL ფაილები დანომრილია თანმიმდევრულად, გამოტოვებებისა და დუბლიკატების გარეშე | დიახ | +| `check:public-creds` | `publicCreds.ts`-ის გარეთ არ არის OAuth-ის პირდაპირ მითითებული `client_id`/`client_secret` ან Firebase Web-ის გასაღებები (მკაცრი წესი #11) | დიახ | +| `check:db-rules` | `src/lib/db/` მოდულების გარეთ არ არის დაუმუშავებელი SQL; `localDb.ts`-დან არ გამოიყენება barrel-იმპორტები (მკაცრი წესები #2/#5) | დიახ | +| `check:known-symbols` | პროვაიდერის შემსრულებლები, მარშრუტიზაციის სტრატეგიები და მთარგმნელები, რომლებიც რეგისტრირებულია შესაბამის დისპეტჩერიზაციის ცხრილებში, ემთხვევა დისკზე არსებულ ფაილებს — არ არის უპატრონო ან გამოუცხადებელი სიმბოლოები | დიახ | +| `check:route-guard-membership` | ყველა მარშრუტი, რომელიც შვილობილ პროცესს ქმნის, კლასიფიცირებულია `isLocalOnlyPath()`-ის მიერ (მკაცრი წესები #15/#17) | დიახ | +| `check:test-discovery` | რეპოზიტორიაში არსებული ყველა `*.test.ts` / `*.spec.ts` ფაილი გროვდება სულ მცირე ერთი ტესტების გამშვების მიერ (ratchet: `test-discovery-baseline.json`-ში არსებული უპატრონო ფაილების სია შეიძლება მხოლოდ შემცირდეს) | დიახ | +| `check:agent-skills-sync` | გენერირებული agent-skills არტეფაქტები შეესაბამება მათ საწყის კატალოგს (განსხვავებების გარეშე) | +| `check:provider-asset-provenance` | პროვაიდერის ლოგოებს/რესურსებს ახლავს ჩაწერილი წარმომავლობის ჩანაწერი | +| `lint:json` | JSON კონფიგურაციის ფაილები იშლება შეცდომის გარეშე და აკმაყოფილებს რეპოზიტორიის ლინტინგის წესებს | +| `typecheck:core` | TypeScript-ის კომპილაცია შეცდომების გარეშე (მხოლოდ სარეკომენდაციო გაფრთხილებები) | დიახ | +| `typecheck:noimplicit:core` | მკაცრი `noImplicitAny` — სამომავლო მოთხოვნა; ბევრ უკვე არსებულ გამოძახების ადგილს კვლავ სჭირდება ანოტაციები | **სარეკომენდაციო** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, რომლის არე შემოიფარგლება `src/app/(dashboard)/**`-ით (#7033) — `typecheck:core`-ის საგანგებოდ შერჩეული 27-ფაილიანი დასაშვები სია არ შეიცავს dashboard-ის არცერთ TSX ფაილს, ხოლო `next build` ასევე არასოდეს ახორციელებს მის ტიპების შემოწმებას (`next.config.mjs`-ში დაყენებულია `ignoreBuildErrors: true`), ამიტომ იქ არსებული მიუწვდომელი იდენტიფიკატორების რეგრესიები (#6625/#6909) CI-სთვის შეუმჩნეველი იყო. განსხვავებები მოწმდება თითოეული ფაილისა და თითოეული TS-კოდის რაოდენობის გაყინულ საბაზისო მაჩვენებელთან (`config/quality/dashboard-typecheck-baseline.json`, მოძველების კონტროლის იგივე სქემა, რაც `check:known-symbols`-ში) — ბარიერს ვერ გადალახავს მხოლოდ საბაზისო რაოდენობას ზემოთ არსებული ახალი შეცდომები; როდესაც უკვე არსებული შეცდომა გამოსწორდება, საბაზისო მაჩვენებელი შეამცირეთ `--update`-ით. | დიახ | ### დავალება: `quality-gate` -ეშვება `test-coverage`-ის შემდეგ. წარუმატებლობის შემთხვევაში ბლოკავს შერწყმას. +ეშვება `test-coverage`-ის შემდეგ. წარუმატებლობის შემთხვევაში შერწყმას ბლოკავს. | სკრიპტი | რას ამოწმებს | ბლოკირებადი | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `quality:collect` | ქმნის `quality-metrics.json`-ს (ESLint-ის გაფრთხილებების რაოდენობა, დაფარვა გაერთიანებული shard-ანგარიშიდან) | დიახ (ratchet-მდე) | -| `quality:ratchet` | `quality-baseline.json`-ში თითოეული მეტრიკა არ გაუარესებულა (ESLint-ის გაფრთხილებები ≤ baseline; დაფარვა ≥ baseline) | დიახ | -| `check:duplication` | კოდის დუბლირება (jscpd@4) არ აღემატება `quality-baseline.json`-ში მითითებულ baseline-ს | დიახ | -| `check:complexity` | ფაილის დონის ციკლომატური სირთულე არ აღემატება ზღვარს (ძირითადი ESLint `complexity` + `max-lines-per-function`) | დიახ | -| `check:cognitive-complexity` | კოგნიტიური სირთულის ratchet (`eslint-plugin-sonarjs`) — ESLint-ის ცალკე გაშვება; CI ორივეს აერთიანებს ერთ `check:complexity-ratchets` ნაბიჯად | დიახ | -| `check:dead-code` | გამოუყენებელი ექსპორტების / ფაილების ratchet (knip) baseline-თან შედარებით არ უარესდება | დიახ | -| `check:compression-budget` | შეკუმშვის საორიენტაციო ტესტის ბიუჯეტი — თითოეული ძრავისთვის ტოკენების დაზოგვის მინიმალური ზღვრები არ უნდა გაუარესდეს | დიახ | -| `check:type-coverage` | ტიპიზაციის პროცენტული მაჩვენებლის ratchet (`type-coverage`) არ უარესდება; დიდწილად მოიცავს `typecheck:noimplicit:core`-ს | დიახ | -| `check:codeql-ratchet` | ღია CodeQL გაფრთხილებების რაოდენობა არ უარესდება (კითხულობს `gh api`-ის მეშვეობით; ტოკენის გარეშე კორექტულად გამოტოვებს) — განახლების სიხშირე და ხელით გაშვება: იხილეთ „CodeQL ratchet“ ქვემოთ | დიახ | +| `quality:collect` | ქმნის `quality-metrics.json`-ს (ESLint-ის გაფრთხილებების რაოდენობა, გაერთიანებული შარდების ანგარიშიდან მიღებული დაფარვა) | დიახ (ratchet-მდე) | +| `quality:ratchet` | `quality-baseline.json`-ში თითოეული მეტრიკა არ გაუარესებულა (ESLint-ის გაფრთხილებები ≤ საბაზისო მაჩვენებელი; დაფარვა ≥ საბაზისო მაჩვენებელი) | დიახ | +| `check:duplication` | კოდის დუბლირება (jscpd@4) არ აჭარბებს `quality-baseline.json`-ში განსაზღვრულ საბაზისო მაჩვენებელს | დიახ | +| `check:complexity` | ფაილის დონის ციკლომატური სირთულე არ აჭარბებს ზღვარს (ძირითადი ESLint-ის `complexity` + `max-lines-per-function`) | დიახ | +| `check:cognitive-complexity` | კოგნიტიური სირთულის ratchet (`eslint-plugin-sonarjs`) — ESLint-ის ცალკე გაშვება; CI ორივეს აერთიანებს ერთ `check:complexity-ratchets` ეტაპად | დიახ | +| `check:dead-code` | გამოუყენებელი ექსპორტების / ფაილების ratchet (knip) არ უარესდება საბაზისო მაჩვენებელთან შედარებით | დიახ | +| `check:compression-budget` | შეკუმშვის საორიენტაციო ტესტის ბიუჯეტი — თითოეული ძრავისთვის ტოკენების დაზოგვის მინიმალური ზღვარი არ უნდა გაუარესდეს | დიახ | +| `check:type-coverage` | ტიპიზაციის პროცენტული მაჩვენებლის ratchet (`type-coverage`) არ უარესდება; მეტწილად მოიცავს `typecheck:noimplicit:core`-ს | დიახ | +| `check:codeql-ratchet` | ღია CodeQL გაფრთხილებების რაოდენობა არ უარესდება (იკითხება `gh api`-ის მეშვეობით; ტოკენის გარეშე კორექტულად გამოტოვდება) — განახლების სიხშირე და ხელით გაშვება: იხილეთ ქვემოთ „CodeQL ratchet“ | დიახ | ### დავალება: `quality-extended` -მთელი დავალება სარეკომენდაციო ხასიათისაა (`continue-on-error: true`). npm-ზე დაფუძნებული ratchet-ები -რეალურად სრულდება; გარე სკანერები ინსტალირდება `gh release download`-ის მეშვეობით და თავად გამოტოვებენ შემოწმებას (exit 0), -თუ ბინარული ფაილი კვლავ არ არის ხელმისაწვდომი. +მთელი დავალება სარეკომენდაციოა (`continue-on-error: true`). npm-ზე დაფუძნებული ratchet-ები +რეალურად სრულდება; გარე სკანერები ინსტალირდება `gh release download`-ის მეშვეობით და +თავად გამოტოვებენ შემოწმებას (exit 0), თუ ბინარული ფაილი კვლავ არ არსებობს. -| სკრიპტი | რას ამოწმებს | ბლოკირებადი | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `check:circular-deps` | ციკლური დამოკიდებულებები არ არსებობს (dpdm) | **სარეკომენდაციო** | -| `check:bundle-size` | bundle-ის ზომა არ აღემატება ზღვარს | **სარეკომენდაციო** | -| `check:secrets` | საიდუმლო მონაცემების სკანირება (gitleaks) — გამოტოვებს, თუ ბინარული ფაილი არ არის ხელმისაწვდომი | **სარეკომენდაციო** | -| `check:vuln-ratchet` | დამოკიდებულებების მოწყვლადობები (osv-scanner) არ უარესდება — გამოტოვებს, თუ ბინარული ფაილი არ არის ხელმისაწვდომი | **სარეკომენდაციო** | -| `check:workflows` | workflow-ების lint-შემოწმება (actionlint + zizmor); არარსებული/გაუმართავი სკანერები, არასწორი ანგარიშები ან არარსებული ratchet baseline იწვევს INCOMPLETE სტატუსით ჩავარდნას. ვალიდური მიგნებები ემორჩილება არჩეულ მკაცრ/სარეკომენდაციო/ratchet პოლიტიკას | შესრულება სავალდებულოა; zizmor ratchet ბლოკირებადია CI-ში | -| `check:openapi-breaking` | საჯარო API კონტრაქტში (`openapi.yaml`) base branch-თან შედარებით შეუთავსებელი ცვლილებები (oasdiff) — ქმნის `openapiBreaking=N`-ს; გამოტოვებს, თუ oasdiff არ არის ხელმისაწვდომი ან საბაზისო სპეციფიკაციის დამუშავება შეუძლებელია | **სარეკომენდაციო** | +| სკრიპტი | რას ამოწმებს | ბლოკირებადი | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| `check:circular-deps` | ციკლური დამოკიდებულებები არ არსებობს (dpdm) | **სარეკომენდაციო** | +| `check:bundle-size` | პაკეტის ზომა არ აჭარბებს ზღვარს | **სარეკომენდაციო** | +| `check:secrets` | საიდუმლო მონაცემების სკანირება (gitleaks) — გამოტოვდება, თუ ბინარული ფაილი არ არსებობს | **სარეკომენდაციო** | +| `check:vuln-ratchet` | დამოკიდებულებების მოწყვლადობები (osv-scanner) არ უარესდება — გამოტოვდება, თუ ბინარული ფაილი არ არსებობს | **სარეკომენდაციო** | +| `check:workflows` | სამუშაო პროცესების ლინტინგი (actionlint + zizmor); არარსებული/გაუმართავი სკანერები, არასწორი ანგარიშები ან ratchet-ის არარსებული საბაზისო მაჩვენებელი იწვევს INCOMPLETE სტატუსით ჩავარდნას. ვალიდური მიგნებები მიჰყვება არჩეულ მკაცრ/სარეკომენდაციო/ratchet პოლიტიკას | შესრულება სავალდებულოა; zizmor-ის ratchet ბლოკირებადია CI-ში | +| `check:openapi-breaking` | საჯარო API კონტრაქტში (`openapi.yaml`) საბაზისო განშტოებასთან შედარებით შეუთავსებელი ცვლილებები (oasdiff) — ქმნის `openapiBreaking=N`-ს; გამოტოვდება, თუ oasdiff არ არსებობს ან საბაზისო სპეციფიკაციის დამუშავება შეუძლებელია | **სარეკომენდაციო** | ### დავალება: `docs-sync-strict` -სრულდება `main`-ისკენ მიმართულ ყველა PR-ზე. წარუმატებლობის შემთხვევაში merge-ს ბლოკავს. - -| სკრიპტი | რას ამოწმებს | ბლოკირებადი | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | მეტა-ბარიერი, რომელიც ქვემოთ მოცემულ 6 ქვე-ბარიერს თანმიმდევრულად უშვებს | დიახ | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ვერსიების თანხვედრას | დიახ | -| ↳ `check:docs-counts` | პროზაულ ტექსტში მოცემული რაოდენობები (პროვაიდერების რაოდენობა, მიგრაციების რაოდენობა და ა.შ.) რეალური რაოდენობების მკაცრ დიაპაზონშია | დიახ | -| ↳ `check:env-doc-sync` | `.env.example`-ში არსებული ყოველი გარემოს ცვლადი დოკუმენტაციის ცხრილშია აღწერილი და პირიქით | დიახ | -| ↳ `check:deprecated-versions` | დოკუმენტაციაში მოძველებული ვერსიების აღმნიშვნელი სტრიქონები არ არის | დიახ | -| ↳ `check:doc-links` | დოკუმენტაციაში არსებული შიდა markdown-ბმულები რეალურ ფაილებზე მიუთითებს (`[text]`/`(path)` ფორმა) | დიახ | -| ↳ `check:fabricated-docs` | დოკუმენტაციაში ნახსენები მარშრუტები, გარემოს ცვლადები, CLI ბრძანებები, ჰუკების სახელები და ფაილების ბილიკები კოდურ ბაზაში არსებობს. მკაცრი ბარიერი `--strict`-ის გამოყენებით; ამ ალმის გარეშე შეცდომა მხოლოდ გაფრთხილებაა. | დიახ (`--strict`-ით CI-ში) | -| `check:cli-i18n` | CLI ბრძანებების სტრიქონები ყველა i18n ლოკალის ფაილშია წარმოდგენილი | დიახ | -| `check:openapi-coverage` | OpenAPI სპეციფიკაცია რეალური მარშრუტების რაოდენობის სულ მცირე მკაცრად განსაზღვრულ ქვედა ზღვარს ფარავს | დიახ | -| `check:openapi-security-tiers` | `openapi.yaml`-ში უსაფრთხოების დონის ანოტაციები `routeGuard.ts`-ის კლასიფიკაციებთან თანხვედრაშია | **სარეკომენდაციო** | -| `check:openapi-routes` | `openapi.yaml`-ში მოცემული ყოველი ბილიკი რეალურ `route.ts`-ს შეესაბამება (ჰალუცინაციების საწინააღმდეგოდ) | დიახ | -| `check:docs-symbols` | `docs/**/*.md`-ში არსებული ყოველი `/api/...` მითითება რეალურ `route.ts`-ს შეესაბამება (ჰალუცინაციების საწინააღმდეგოდ) | დიახ | -| `i18n translation drift` | უთარგმნელი გასაღებები i18n ლოკალის ფაილებში — მხოლოდ გაფრთხილება | **სარეკომენდაციო** | +სრულდება `main`-ზე მიმართულ ყოველ PR-ზე. წარუმატებლობის შემთხვევაში შერწყმას ბლოკავს. + +| სკრიპტი | რას ამოწმებს | ბლოკირებადი | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- | +| `check:docs-all` | მეტა-ბარიერი, რომელიც ქვემოთ მოცემულ 6 ქვებარიერს თანმიმდევრულად უშვებს | დიახ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ვერსიების თანხვედრა | დიახ | +| ↳ `check:docs-counts` | პროზაულ ტექსტში მოცემული რაოდენობები (პროვაიდერების რაოდენობა, მიგრაციების რაოდენობა და ა.შ.) რეალური რაოდენობების ratchet-ფანჯრის ფარგლებშია | დიახ | +| ↳ `check:env-doc-sync` | `.env.example`-ში არსებული ყველა გარემოს ცვლადი დოკუმენტაციის ცხრილშია აღწერილი და პირიქით | დიახ | +| ↳ `check:deprecated-versions` | დოკუმენტაციაში მოძველებული ვერსიების სტრიქონები არ არის | დიახ | +| ↳ `check:doc-links` | დოკუმენტაციაში არსებული შიდა markdown-ბმულები რეალურ ფაილებზე მიუთითებს (`[text]`/`(path)` ფორმა) | დიახ | +| ↳ `check:fabricated-docs` | დოკუმენტაციაში მითითებული მარშრუტები, გარემოს ცვლადები, CLI ბრძანებები, hook-ების სახელები და ფაილის გზები კოდურ ბაზაში არსებობს. მკაცრი ბარიერი `--strict`-ით; ამ ალმის გარეშე შეცდომა მხოლოდ რბილია. | დიახ (CI-ში `--strict`-ით) | +| `check:cli-i18n` | CLI ბრძანებების სტრიქონები ყველა i18n ლოკალის ფაილშია წარმოდგენილი | დიახ | +| `check:openapi-coverage` | OpenAPI სპეციფიკაცია მოიცავს რეალური მარშრუტების მინიმუმ ratchet-ით განსაზღვრულ ქვედა ზღვარს | დიახ | +| `check:openapi-security-tiers` | `openapi.yaml`-ში უსაფრთხოების დონის ანოტაციები შეესაბამება `routeGuard.ts`-ის კლასიფიკაციებს | **სარეკომენდაციო** | +| `check:openapi-routes` | `openapi.yaml`-ში არსებული ყველა გზა რეალურ `route.ts`-ს შეესაბამება (ჰალუცინაციის საწინააღმდეგო შემოწმება) | დიახ | +| `check:docs-symbols` | `docs/**/*.md`-ში არსებული ყველა `/api/...` მითითება რეალურ `route.ts`-ს შეესაბამება (ჰალუცინაციის საწინააღმდეგო შემოწმება) | დიახ | +| `i18n translation drift` | უთარგმნელი გასაღებები i18n ლოკალის ფაილებში — მხოლოდ გაფრთხილება | **სარეკომენდაციო** | ### დავალება: `i18n-ui-coverage` -| სკრიპტი | რას ამოწმებს | ბლოკირებადი | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `check-ui-keys-coverage` (inline) | UI-ის i18n გასაღებების დაფარვა ≥ 65%-ია | დიახ | -| `check-ui-value-drift` (inline) | ხელახლა დაწერილი ინგლისური **მნიშვნელობა** მოძველებულ თარგმანს არ ტოვებს | დიახ | -| `check-new-key-coverage` (inline) | **ახალი** ინგლისური გასაღები ყველა ლოკალში თარგმნილია — `__MISSING__:` მარკერი უარყოფილია | დიახ | -| `check-translation-ratio` | რეალური თარგმანების თანაფარდობა თითოეული ლოკალისთვის (ინგლისურის იდენტური / ჩანაცვლების ტექსტი / ნებადართული სიის მიღმა დაკარგული ფოთლები) არ უნდა აღემატებოდეს `config/quality/i18n-translation-baseline.json` + დასაშვებ გადახრას | **სარეკომენდაციო** | +| სკრიპტი | რას ამოწმებს | ბლოკირებადი | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `check-ui-keys-coverage` (inline) | UI i18n გასაღებების დაფარვა ≥ 65%-ია | დიახ | +| `check-ui-value-drift` (inline) | გადაწერილი ინგლისური **მნიშვნელობის** შემდეგ მოძველებული თარგმანი არ რჩება | დიახ | +| `check-new-key-coverage` (inline) | **ახალი** ინგლისური გასაღები ყველა ლოკალზეა თარგმნილი — `__MISSING__:` მარკერი უარყოფილია | დიახ | +| `check-translation-ratio` | თითოეული ლოკალის რეალური თარგმანის თანაფარდობა (ინგლისურის იდენტური / placeholder / გამოტოვებული ფოთლები დაშვებული სიის მიღმა) არ უნდა აღემატებოდეს `config/quality/i18n-translation-baseline.json`-ს + დასაშვებ გადახრას | **სარეკომენდაციო** | საჭიროა `fetch-depth: 0` — მნიშვნელობის აცდენის ბარიერი `en.json`-ს შერწყმის ბაზასთან ადარებს. #### `check-ui-value-drift` — მოძველებული თარგმანის ბარიერი -აღმოაჩენს იმ ერთ i18n რეგრესიას, რომლის დანახვაც სხვა ბარიერებს სტრუქტურულად არ შეუძლიათ: ინგლისური მნიშვნელობა -ხელახლა იწერება, ხოლო _წინა_ ინგლისური ტექსტიდან მიღებული თარგმანები უცვლელი რჩება, რის გამოც -არაინგლისურენოვანი მომხმარებლები კვლავ თავდაჯერებული ტონით დაწერილ, თუმცა უკვე მცდარ ტექსტს კითხულობენ. +აფიქსირებს იმ ერთადერთ i18n რეგრესიას, რომლის სტრუქტურულად დანახვაც სხვა ბარიერებს არ შეუძლიათ: ინგლისური მნიშვნელობა +გადაიწერება, ხოლო _წინა_ ინგლისურიდან მიღებული თარგმანები უცვლელი რჩება, რის გამოც +არაინგლისურენოვანი მომხმარებლები კვლავ დამაჯერებლად ფორმულირებულ, თუმცა უკვე არასწორ ტექსტს კითხულობენ. -ეს რეალურად გამოქვეყნებულ ვერსიაში მოხვდა. `oauthModal.googleOAuthWarning` ხელახლა დაიწერა, როდესაც Antigravity-ის +ეს რეალურ რელიზში მოხვდა. `oauthModal.googleOAuthWarning` გადაიწერა, როდესაც Antigravity-ის შესვლის დამხმარე დაემატა (#5203); **43 ლოკალიდან 39-ში** დარჩა ტექსტი, რომელიც ოპერატორებს ეუბნებოდა, რომ „სრული -URL დაეკოპირებინათ და ქვემოთ ჩაესვათ“ — პროცესი, რომელიც ამ პროვაიდერისთვის ვერ დასრულდება. ეს +URL დაეკოპირებინათ და ქვემოთ ჩაესვათ“ — პროცესი, რომლის დასრულებაც ამ პროვაიდერისთვის შეუძლებელია. პრობლემა #8463-მდე შეუმჩნეველი დარჩა, რადგან: -- `sync-ui-keys` მხოლოდ **არარსებულ** გასაღებებს ამატებს და არასოდეს ანახლებს **მოძველებულებს**; -- `check-ui-keys-coverage` გასაღების _არსებობას_ ითვლის, ამიტომ მოძველებული თარგმანი დაფარულად ითვლება; -- `check-translation-drift` თვალს ადევნებს `docs/i18n//**.md` დოკუმენტაციის ასლებს — - ის არასოდეს კითხულობს `src/i18n/messages/*.json`-ს. ბლოკირებადია დავალებაში `docs-sync-strict` 2026-09-ის - ხელახალი სინქრონიზაციიდან: შეცვალეთ ძირითადი დოკუმენტი → `npm run i18n:run -- --files=` (სექციის დონეზე, სწრაფი). +- `sync-ui-keys` მხოლოდ **არარსებულ** გასაღებებს ამატებს და არასოდეს აახლებს **მოძველებულებს**; +- `check-ui-keys-coverage` გასაღების _არსებობას_ ითვლის, ამიტომ მოძველებული თარგმანი დაფარულად მიიჩნევა; +- `check-translation-drift` აკვირდება `docs/i18n//**.md` დოკუმენტაციის სარკეებს — + ის არასოდეს კითხულობს `src/i18n/messages/*.json`-ს. 2026-09-ის ხელახალი სინქრონიზაციის შემდეგ ბლოკირებადია დავალებაში `docs-sync-strict`: ძირითადი დოკუმენტის რედაქტირება → `npm run i18n:run -- --files=` (სექციის დონეზე, იაფი). -**ცვლილებების სხვაობაზე ორიენტირებული და არა საბაზისო მონაცემებზე დაყრდნობილი.** ის შერწყმის საბაზისო წერტილში არსებულ `en.json`-ს -სამუშაო ხეს ადარებს; ყველა გასაღებისთვის, რომლის ინგლისური მნიშვნელობაც შეიცვალა, მოძველებულია ნებისმიერი ლოკალი, რომელიც ჯერ კიდევ -უცვლელ თარგმანს შეიცავს. ეს განზრახ **აფიქსირებს უკვე არსებულ დავალიანებას** — სხვაობა -ვერ გამოავლენს, თუ ძველი ინგლისური ტექსტის რომელი ვერსიიდან მომდინარეობს დიდი ხნის წინანდელი თარგმანი, ამიტომ შემოწმება აფასებს -მხოლოდ იმას, რასაც მიმდინარე ცვლილება ეხება. ალტერნატივა (თითოეული გასაღებისთვის ჰეშების საბაზისო ფაილი) მოითხოვდა -დაახლოებით 600 KB-იან გენერირებულ ფაილს, რაც უდიდეს არსებულ საბაზისო ფაილზე 3-ჯერ დიდია და ყოველ i18n PR-ზე შეიცვლებოდა. +**ითვალისწინებს diff-ს და არ ეყრდნობა საბაზისო ფაილს.** ის merge base-ში არსებულ `en.json`-ს სამუშაო ხეს ადარებს; თითოეული გასაღებისთვის, რომლის ინგლისური მნიშვნელობაც შეიცვალა, ნებისმიერი ლოკალი, რომელიც კვლავ უცვლელ თარგმანს შეიცავს, მოძველებულია. ეს განზრახ **აფიქსირებს უკვე არსებულ დავალიანებას** — diff ვერ გამოავლენს, თუ ძველი ინგლისური ტექსტის რომელი ვერსიიდან მომდინარეობს დიდი ხნის წინანდელი თარგმანი, ამიტომ შემოწმება აფასებს მხოლოდ იმას, რასაც მიმდინარე ცვლილება ეხება. ალტერნატივა (თითოეულ გასაღებზე hash-ის შემცველი საბაზისო ფაილი) მოითხოვდა დაახლოებით 600 KB-იან გენერირებულ ფაილს, რაც უდიდეს არსებულ საბაზისო ფაილზე 3-ჯერ დიდია და ყოველ i18n PR-ზე შეიცვლებოდა. -მისი დაკმაყოფილების ორი გზა არსებობს: +მის დასაკმაყოფილებლად ორი გზა არსებობს: 1. განაახლეთ შესაბამისი თარგმანები, ან -2. მიანიჭეთ მათ `__MISSING__:` — შესრულების გარემო შემდეგ გასცემს შესწორებულ ინგლისურ ტექსტს - (`src/i18n/request.ts::deepMergeFallback`, #7258), ხოლო გასაღები თარგმნის რიგში დაემატება. +2. მიანიჭეთ მათ `__MISSING__:` — ამის შემდეგ runtime გასცემს გასწორებულ ინგლისურ ტექსტს + (`src/i18n/request.ts::deepMergeFallback`, #7258), ხოლო გასაღები თარგმნის რიგში ჩადგება. -თუ სტრიქონის **მნიშვნელობა** შეიცვალა, უმჯობესია **გასაღებს სახელი შეუცვალოთ**: ახალი გასაღები -მოძველებულ თარგმანს ვერ დაიმკვიდრებს. ეს არის მიდგომა, რომელიც #8463-ში გამოიყენეს. +თუ სტრიქონის **მნიშვნელობა** შეიცვალა, უმჯობესია **გასაღებს სახელი შეუცვალოთ**: ახალი გასაღები მოძველებულ თარგმანს ვერ დაიმკვიდრებს. სწორედ ეს მიდგომა გამოიყენა #8463-მა. ```bash npm run i18n:check-value-drift # მკაცრი (რასაც CI უშვებს) -npm run i18n:check-value-drift:warn # მხოლოდ ანგარიშის მომზადება +npm run i18n:check-value-drift:warn # მხოლოდ ანგარიშის წარდგენა BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -ასრულებს მუშაობას 0 კოდით და `SKIP reason=base-unresolved` შეტყობინებით, როდესაც საბაზისო კატალოგის წაკითხვა შეუძლებელია (ზედაპირული -კლონი საბაზისო ref-ის გარეშე), `check-openapi-breaking`-ის ანალოგიურად. +ასრულებს მუშაობას 0 კოდით და `SKIP reason=base-unresolved` შეტყობინებით, როდესაც საბაზისო კატალოგის წაკითხვა შეუძლებელია (shallow clone საბაზისო ref-ის გარეშე), `check-openapi-breaking`-ის ანალოგიურად. ### დავალება: `i18n` i18n-ის სრული ვალიდაციის მატრიცა (თითო დავალება თითო ლოკალზე). მთელი დავალება სარეკომენდაციო ხასიათისაა. -| სკრიპტი | რას ამოწმებს | ბლოკირებადობა | -| ------------------------------- | -------------------------------------- | -------------------------------------------------------------- | -| `validate_translation.py quick` | თარგმანის სისრულე თითოეული ლოკალისთვის | **სარეკომენდაციო** (`continue-on-error: true` მთელ დავალებაზე) | +| სკრიპტი | რას ამოწმებს | ბლოკავს | +| ------------------------------- | --------------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | თარგმანის სისრულეს თითოეული ლოკალისთვის | **სარეკომენდაციო** (`continue-on-error: true` მთელ დავალებაზე) | ### დავალება: `pr-test-policy` ეშვება მხოლოდ pull request-ებზე. -| სკრიპტი | რას ამოწმებს | ბლოკირებადობა | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `check:pr-test-policy` | PR-ები, რომლებიც ცვლიან საწარმოო კოდს `src/`, `open-sse/`, `electron/` ან `bin/`-ში, უნდა შეიცავდეს ან აახლებდეს ტესტებს (მკაცრი წესი #8) | დიახ | -| `check:test-masking` | შეცვლილი სატესტო ფაილები არ ამცირებს ასერტების წმინდა რაოდენობას და არ ამატებს `assert.ok(true)` ტავტოლოგიებს | დიახ | -| `check:pr-evidence` | PR-ის აღწერაში მითითებულია ცვლილების ტესტირების/VPS-ის მტკიცებულებები (მკაცრი წესის #18 ავტომატიზაცია PR-ის ტექსტში ძიებით — არასაიმედოა, იხილეთ Backlog) | დიახ | +| სკრიპტი | რას ამოწმებს | ბლოკავს | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `check:pr-test-policy` | PR-ები, რომლებიც ცვლიან საწარმოო კოდს `src/`, `open-sse/`, `electron/` ან `bin/`-ში, უნდა შეიცავდნენ ან აახლებდნენ ტესტებს (მკაცრი წესი #8) | დიახ | +| `check:test-masking` | შეცვლილი სატესტო ფაილები არ ამცირებენ assert-ების წმინდა რაოდენობას და არ ამატებენ `assert.ok(true)` ტავტოლოგიებს | დიახ | +| `check:pr-evidence` | PR-ის აღწერა მიუთითებს ცვლილების ტესტირების/VPS-ის მტკიცებულებაზე (მკაცრი წესის #18 ავტომატიზაცია PR-ის ტექსტში ძიებით — არასაიმედოა, იხილეთ Backlog) | დიახ | ### დავალება: `test-vitest` -ეშვება `build`-ის შემდეგ. წარუმატებლობის შემთხვევაში ბლოკავს შერწყმას. +ეშვება `build`-ის შემდეგ. წარუმატებლობის შემთხვევაში merge-ს ბლოკავს. -| ნაკრები | რას ამოწმებს | ბლოკირებადობა | -| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | MCP სერვერი (110 ხელსაწყო), autoCombo, ქეში — vitest-ის გამშვები | დიახ | -| `test:vitest:ui` | UI კომპონენტების ტესტები — vitest-ის გამშვები | **ბლოკირებადი** — უკვე არსებული წარუმატებლობები აშკარად გამორიცხულია `vitest.config.ts`-ში; ახალი წარუმატებლობები დავალებას ჩააგდებს | +| ნაკრები | რას ამოწმებს | ბლოკავს | +| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP სერვერს (110 ხელსაწყო), autoCombo-ს, cache-ს — vitest runner | დიახ | +| `test:vitest:ui` | UI კომპონენტების ტესტებს — vitest runner | **ბლოკავს** — უკვე არსებული წარუმატებელი ტესტები აშკარად გამორიცხულია `vitest.config.ts`-ში; ახალი წარუმატებლობები დავალებას ჩააგდებს | -### ღამის სამუშაო პროცესები (დაგეგმილი, სარეკომენდაციო) +### ღამის workflow-ები (განრიგით, სარეკომენდაციო) -ისინი ეშვება cron განრიგით (და `workflow_dispatch`-ით), მაგრამ არასდროს PR-ებზე. ყველა მათგანი სარეკომენდაციო ხასიათისაა. +ისინი cron-განრიგით (და `workflow_dispatch`-ით) ეშვება, PR-ებზე კი არასდროს. ყველა მათგანი სარეკომენდაციო ხასიათისაა. -| სამუშაო პროცესი | რას ამოწმებს | ბლოკირებადობა | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `nightly-property` | fast-check-ის თვისებებზე დაფუძნებული ტესტები შემთხვევითი საწყისი მნიშვნელობითა და გაშვებების დიდი რაოდენობით | **სარეკომენდაციო** | -| `nightly-resilience` | heap-ის ზრდის შემოწმება, ქაოსური გაუმართაობების ინექცია, k6 დატვირთვის/ხანგრძლივი დატვირთვის ტესტირება | **სარეკომენდაციო** | -| `nightly-llm-security` | promptfoo-ს ინექციისგან დაცვა (ბლოკირების რეჟიმი) + garak-ის შემოწმებები (გამოტოვებულია პროვაიდერის საიდუმლოს გარეშე) | **სარეკომენდაციო** | -| `nightly-schemathesis` | OpenAPI კონტრაქტის ფაზინგი (schemathesis) გაშვებულ OmniRoute-ზე `docs/openapi.yaml`-ის გამოყენებით — გამოავლენს სპეციფიკაციის დარღვევებს / დაუმუშავებელ 500-იან პასუხებს (ფაზა 8 B.4) | **სარეკომენდაციო** | -| `nightly-mutation` | Stryker-ის მუტაციური ტესტირების ქულა სწრაფი მოდულური ტესტების ნაკრებისთვის — გადარჩენილი მუტანტები სუსტ ასერტებს გამოავლენს | **სარეკომენდაციო** | -| `nightly-compat` | Node ძრავის თავსებადობის მატრიცა მხარდაჭერილი `engines.node` დიაპაზონებისთვის | **სარეკომენდაციო** | +| Workflow | რას ამოწმებს | ბლოკავს | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `nightly-property` | fast-check property ტესტებს შემთხვევითი seed-ითა და გაშვებების დიდი რაოდენობით | **სარეკომენდაციო** | +| `nightly-resilience` | heap-ის ზრდის შემოწმებას, chaos fault-injection-ს, k6 load/soak ტესტებს | **სარეკომენდაციო** | +| `nightly-llm-security` | promptfoo injection guard-ს (block რეჟიმი) + garak probes-ს (გამოტოვებულია provider-ის secret-ის გარეშე) | **სარეკომენდაციო** | +| `nightly-schemathesis` | OpenAPI კონტრაქტის fuzzing-ს (schemathesis) გაშვებული OmniRoute-ის წინააღმდეგ, `docs/openapi.yaml`-ის გამოყენებით — ავლენს სპეციფიკაციის დარღვევებს / დაუმუშავებელ 500-ებს (Fase 8 B.4) | **სარეკომენდაციო** | +| `nightly-mutation` | Stryker mutation-testing-ის ქულას სწრაფ unit lane-ზე — გადარჩენილი mutants სუსტ assert-ებს ავლენს | **სარეკომენდაციო** | +| `nightly-compat` | Node engine-ის თავსებადობის მატრიცას მხარდაჭერილ `engines.node` დიაპაზონებში | **სარეკომენდაციო** | --- @@ -534,43 +526,43 @@ CI-ის შემოწმებების გარდა, OmniRoute-ს --- -## რაციონალიზაციის ბექლოგი (ROI მიმოხილვა — ფაზა 9, ტალღა 3) +## რაციონალიზაციის ბექლოგი (ROI-ის მიმოხილვა — ფაზა 9, ტალღა 3) -ეს ინვენტარი 2026-06-17-ს შეჯერდა `ci.yml`-თან (წინა ვერსიაში გამოტოვებული იყო +ეს ინვენტარი შეჯერებულია `ci.yml`-თან 2026-06-17-ს (წინა ვერსიაში გამოტოვებული იყო `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). შეჯერებული ნაკრების ROI მიმოხილვამ +`check:codeql-ratchet`, `check:pr-evidence`). შეჯერებული ნაკრების ROI-ის მიმოხილვამ გამოავლინა რაციონალიზაციის შემდეგი კანდიდატები. **გაერთიანებები CI-ის მექანიკური -ცვლილებებია; გადართვა/ამოღება კი ოპერატორისთვის განკუთვნილი პოლიტიკის გადაწყვეტილებებია.** ქვემოთ -ჩამოთვლილიდან ჯერ არაფერი განხორციელებულა. +ცვლილებებია; გადართვა/ამოღება კი პოლიტიკის გადაწყვეტილებებია, რომლებიც ოპერატორს ეკუთვნის.** ქვემოთ +ჩამოთვლილთაგან ჯერ არაფერი გამოყენებულა. -**ზემოთ ასევე არ არის დოკუმენტირებული** (სარეკომენდაციო, დაბალი სიგნალი): `docs-lint` დავალება +**ზემოთ ასევე არ არის დოკუმენტირებული** (სარეკომენდაციო, დაბალი სიგნალის მქონე): `docs-lint` დავალება (markdownlint + Vale, მთელ დავალებაზე `continue-on-error`) და დამოუკიდებელი სკანერის სამუშაო პროცესები `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` არის -`quality-baseline.json`-ში, თუმცა `ci.yml`-ში ბლოკირების ტრეშოლდთან მიბმული არ არის — მეტრიკა +`quality-baseline.json`-ში, თუმცა `ci.yml`-ში ბლოკირების მექანიზმის მქონე რეჩეტთან დაკავშირებული არ არის — მეტრიკა ამჟამად ობლადაა დარჩენილი. ### გაერთიანება / დუბლირების მოცილება (მექანიკური, ნაკლები რისკი) -თითოეული კანდიდატი 2026-06-17-ს მოქმედი გეიტების მდგომარეობასთან მიმართებით გადამოწმდა (ენდე, მაგრამ გადაამოწმე); -რამდენიმე „აშკარა“ გაერთიანება, როგორც აღმოჩნდა, დაფარულ დავალიანებას შეიცავდა და **არ არის** პირდაპირი, უპრობლემო ჩანაცვლება. - -- **`check:docs-sync` ორჯერ სრულდება** — დამოუკიდებლად `lint` დავალებაში და ხელახლა `check:docs-all`-ის (`docs-sync-strict`) შიგნით, ასევე husky-ის pre-commit ჰუკში. ✅ **შესრულებულია** — დამოუკიდებელი `lint` გამოძახება ამოღებულია. -- **CVE სკანირება** — ❌ **სუფთა გაერთიანება არ არის.** `audit:deps` ნებისმიერ მაღალი/კრიტიკული სიმძიმის CVE-ზე მკაცრად მარცხდება; `check:vuln-ratchet` (osv) კი მხოლოდ საბაზისო მაჩვენებელთან შედარებით _გაუარესების_ შემთხვევაში მარცხდება (ამჟამად 1 MODERATE). სემანტიკა განსხვავებულია — `audit:deps`-ის ამოღებით მაღალი/კრიტიკული სიმძიმის აბსოლუტური გეიტი დაიკარგებოდა. ორივე დატოვეთ. -- **ციკლების აღმოჩენა** — ❌ **სუფთა გაერთიანება არ არის.** `check:circular-deps` (dpdm) აჩვენებს **91 ციკლს** (სწორედ ამიტომ არის სარეკომენდაციო); მათი წინასწარ აღმოფხვრის გარეშე მისი ბლოკირების რეჟიმში გადაყვანა შეუძლებელია და მას უფრო ფართო არეალი აქვს, ვიდრე წარმატებულ, კურირებულ `check:cycles`-ს. `check:cycles` დატოვეთ ბლოკირების რეჟიმში; dpdm-ის 91 ციკლის აღმოფხვრა ცალკე ბექლოგია. -- **სირთულე** — ✅ **შესრულებულია** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ESLint-ის ერთი გავლა, დათვლა ruleId-ის მიხედვით, რათა ციკლომატური სირთულისა და max-lines-ის საბაზისო მაჩვენებლები კოგნიტიური სირთულის საბაზისო მაჩვენებლებისგან დამოუკიდებელი დარჩეს; ცალკეული `check:complexity` / `check:cognitive-complexity` ლოკალური `--update`-ისთვის შენარჩუნებულია. -- **`/api`-ს ანტიჰალუცინაციური შემოწმება** — ✅ **შესრულებულია** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-ის FS ინვენტარიზაცია ერთხელ სრულდება, openapi-routes + docs-symbols კვლავ დამოუკიდებლად აგენერირებს ანგარიშებს; ცალკეული შემოწმებები ლოკალური გაშვებებისთვის შენარჩუნებულია. -- **`check:node-runtime` 11 დავალებაში სრულდება** — ⚠️ **დაბალი ROI.** თითოეული ცალკე რანერია და შემოწმებას <1წმ სჭირდება; ჯამური ეკონომია ~10წმ-ია, იაფი თითო-დავალებიანი დაცვის დაკარგვის ფასად. ცვლილებებით გამოწვეულ აურზაურად არ ღირს. -- **`typecheck:noimplicit:core` CI lint-ში** — ✅ **ამოღებულია lint დავალებიდან** (იყო სარეკომენდაციო `continue-on-error`); ტიპების ზედაპირის ბლოკირებას უზრუნველყოფს `typecheck:core` + `check:type-coverage`. ლოკალური სკრიპტი შენარჩუნებულია. - -### გადართვა / გადაწყვეტილება (ოპერატორის პოლიტიკა) - -- `check:openapi-security-tiers` (სარეკომენდაციო) — ❌ **პირდაპირ ვერ გადაირთვება.** ის 0 კოდით სრულდება, თუმცა აფრთხილებს, რომ `LOCAL_ONLY_API_PREFIXES`-ის ქვეშ მდებარე `traffic-inspector`-ის რამდენიმე მარშრუტს `x-loopback-only: true` ანოტაცია აკლია. მის სავალდებულოდ ქცევამდე ეს ანოტაციები ჯერ `openapi.yaml`-ს უნდა დაემატოს. -- `typecheck:noimplicit:core` (სარეკომენდაციო) — ძირითადად მოცულია ბლოკირების რეჟიმში მოქმედი `check:type-coverage` ტრეშოლდით. გადაიყვანეთ ტრეშოლდზე ან ამოიღეთ ზედმეტი მეორე `tsc` გავლა. -- `test:vitest:ui` (ახლა **ბლოკირების რეჟიმშია**) — წინასწარ არსებული ჩავარდნები ცალსახად გამორიცხულია `vitest.config.ts`-ში `// #8618` თვალთვალის კომენტარებით; ახალი ჩავარდნები დავალებას წარუმატებლად ასრულებს. -- `check:secrets` (gitleaks, ბლოკირების ტრეშოლდი, დაფიქსირებული 3 დოკუმენტირებული ცრუ დადებითი შედეგით) — დაამატეთ სამივე დაშვებულთა სიაში, რათა მაჩვენებელი 0 გახდეს, ან გადაიყვანეთ სარეკომენდაციო რეჟიმში. ნაწილობრივ ემთხვევა GitHub-ის ჩაშენებულ საიდუმლოებების სკანირებას + `check:public-creds`. -- `check:pr-evidence` (ბლოკირების რეჟიმში, grep-ით ამოწმებს PR-ის ტექსტურ აღწერას) — ცრუ დადებითი შედეგების მაღალი რისკი; ამოღების შემთხვევაში Hard Rule #18-ის აღსრულება სუსტდება, ამიტომ ეს ნამდვილად პოლიტიკის საკითხია. -- `semgrep` (დამოუკიდებელი, სარეკომენდაციო) — OWASP-ის კატეგორიებისთვის CodeQL-ს ნაწილობრივ ემთხვევა; მიაბით მისი საბაზისო მაჩვენებელი ტრეშოლდს ან ამოიღეთ. +თითოეული კანდიდატი შემოწმდა აქტიური გეიტების მდგომარეობასთან 2026-06-17-ს (ენდე, მაგრამ გადაამოწმე); +რამდენიმე „აშკარა“ გაერთიანება რეალურად დამალულ ტექნიკურ ვალს შეიცავდა და **არ არის** პირდაპირი უსაფრთხო ჩანაცვლება. + +- **`check:docs-sync` ორჯერ ეშვება** — ცალკე `lint` დავალებაში და კვლავ `check:docs-all`-ის (`docs-sync-strict`) შიგნით და husky-ის pre-commit ჰუკში. ✅ **შესრულებულია** — ცალკეული `lint` გამოძახება ამოღებულია. +- **CVE სკანირება** — ❌ **არ არის სუფთა გაერთიანება.** `audit:deps` იწვევს მკაცრ ჩავარდნას ნებისმიერ მაღალი/კრიტიკული სიმძიმის CVE-ზე; `check:vuln-ratchet` (osv) კი მხოლოდ საბაზისო დონესთან შედარებით _გაუარესების_ შემთხვევაში ვარდება (ამჟამად 1 MODERATE). სემანტიკა განსხვავებულია — `audit:deps`-ის ამოღებით დაიკარგებოდა მაღალი/კრიტიკული სიმძიმის აბსოლუტური გეიტი. ორივე უნდა დარჩეს. +- **ციკლების აღმოჩენა** — ✅ **შესრულებულია** (#15159 G-01/G-02). ძველ ტექსტში `check:cycles` აღწერილი იყო, როგორც „მწვანე, კურირებული“ გეიტი და მისი ბლოკირებად დატოვება იმით იყო გამართლებული, რომ `check:circular-deps` (dpdm) 91 ციკლს აფიქსირებდა. ეს მწვანე სტატუსი **ცრუ დადებითი შედეგი** იყო: `check:cycles` ასკანირებდა 5 ქვედირექტორიას (450 ფაილს), ამთხვევდა მხოლოდ სტატიკურ `import|export … from` კონსტრუქციებს და უგულებელყოფდა ყველა `@/` და `@omniroute/open-sse/` სპეციფიკატორს, ამიტომ ვერ ხედავდა დინამიკური იმპორტისა და ფსევდონიმების ციკლებს, რომლებიც რეპოზიტორიაში ჭარბობდა. გასწორებულია: ახლა გეიტი სრულად გადის `src` + `open-sse`-ზე (5023 ფაილი), სპეციფიკატორებს TypeScript AST-იდან აგროვებს (ამიტომ `import("…")` ითვლება, ხოლო ტიპის პოზიციაში არსებული `typeof import("…")` — არა) და ხსნის tsconfig-ის `paths`-ს. ის პოულობს **14** ციკლს და არა 0-ს. რადგან მანამდე არსებული 14 ციკლის გასწორება გეიტის PR-ში შეუძლებელია, `check:cycles` ახლა **რეჩეტია** (`--ratchet`, ზედა ზღვარი `metrics.cycles.value = 14` ფაილში `quality-baseline.json`, `direction: down`) — ის ბლოკავს ნებისმიერ _გაუარესებას_ და რაოდენობა მხოლოდ შემცირდება. CI უშვებს `npm run check:cycles:ratchet`-ს. ეტაპობრივი შემცირება მიმდინარეობს **A-01**-თან ერთად. `check:circular-deps` (dpdm) რჩება სარეკომენდაციო რეჟიმში, როგორც უფრო ფართო მეორე შეფასება. +- **სირთულე** — ✅ **შესრულებულია** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ESLint-ის ერთი გავლა, დათვლა ruleId-ის მიხედვით, რათა ციკლომატური სირთულის+max-lines-ისა და კოგნიტიური სირთულის საბაზისო მნიშვნელობები დამოუკიდებელი დარჩეს; ცალკეული `check:complexity` / `check:cognitive-complexity` შენარჩუნებულია ლოკალური `--update`-ისთვის. +- **`/api`-ის ანტიჰალუცინაციური შემოწმება** — ✅ **შესრულებულია** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-ის ფაილური სისტემის ერთი ინვენტარიზაცია, openapi-routes + docs-symbols კვლავ დამოუკიდებლად ქმნის ანგარიშებს; ცალკეული შემოწმებები შენარჩუნებულია ლოკალური გაშვებებისთვის. +- **`check:node-runtime` 11 დავალებაში ეშვება** — ⚠️ **დაბალი ROI.** თითოეული მათგანი ცალკე რანერია, ხოლო შემოწმებას <1 წმ სჭირდება; ჯამური დანაზოგი დაახლოებით 10 წმ-ია, სანაცვლოდ კი იკარგება იაფი, თითოეულ დავალებაზე მოქმედი დამცავი შემოწმება. ცვლილებით გამოწვეულ აურზაურად არ ღირს. +- **`typecheck:noimplicit:core` CI-ის lint-ზე** — ✅ **ამოღებულია lint დავალებიდან** (იყო სარეკომენდაციო `continue-on-error`); ტიპების ზედაპირის ბლოკირებადი შემოწმებაა `typecheck:core` + `check:type-coverage`. ლოკალური სკრიპტი შენარჩუნებულია. + +### გადართვა / გადაწყვეტილების მიღება (ოპერატორის პოლიტიკა) + +- `check:openapi-security-tiers` (სარეკომენდაციო) — ❌ **პირდაპირ გადართვა შეუძლებელია.** ის აბრუნებს 0-ს, თუმცა აფრთხილებს, რომ `LOCAL_ONLY_API_PREFIXES`-ის ქვეშ არსებული რამდენიმე `traffic-inspector` მარშრუტი არ შეიცავს `x-loopback-only: true` ანოტაციას. მის სავალდებულოდ ქცევამდე ეს ანოტაციები ჯერ `openapi.yaml`-ს უნდა დაემატოს. +- `typecheck:noimplicit:core` (სარეკომენდაციო) — ძირითადად ჩანაცვლებულია ბლოკირებადი `check:type-coverage` რეჩეტით. გადართეთ რეჩეტზე ან ამოიღეთ ზედმეტი მეორე `tsc` გავლა. +- `test:vitest:ui` (ახლა **ბლოკირებადია**) — მანამდე არსებული ჩავარდნები პირდაპირაა გამორიცხული `vitest.config.ts`-ში `// #8618` თვალთვალის კომენტარებით; ახალი ჩავარდნები დავალებას ჩააგდებს. +- `check:secrets` (gitleaks, ბლოკირებადი რეჩეტი, გაყინული 3 დოკუმენტირებულ ცრუ დადებით შედეგზე) — დაამატეთ ეს 3 დაშვებულთა სიაში, რათა მაჩვენებელი 0-მდე ჩამოვიდეს, ან გადაიყვანეთ სარეკომენდაციო რეჟიმში. ნაწილობრივ ემთხვევა GitHub-ის ჩაშენებულ საიდუმლოების სკანირებასა და `check:public-creds`-ს. +- `check:pr-evidence` (ბლოკირებადი, PR-ის ტექსტურ აღწერაში grep-ით ეძებს) — ცრუ დადებითი შედეგების მაღალი რისკი; მისი ამოღება ასუსტებს მკაცრი წესის #18 აღსრულებას, ამიტომ ეს ნამდვილად პოლიტიკის საკითხია. +- `semgrep` (სარეკომენდაციო დამოუკიდებელი შემოწმება) — OWASP-ის კატეგორიებისთვის ნაწილობრივ ემთხვევა CodeQL-ს; დაუკავშირეთ მისი საბაზისო მნიშვნელობა რეჩეტს ან ამოიღეთ. --- diff --git a/docs/i18n/km/CONTRIBUTING.md b/docs/i18n/km/CONTRIBUTING.md index d499139b3f5..21d81ee9f9e 100644 --- a/docs/i18n/km/CONTRIBUTING.md +++ b/docs/i18n/km/CONTRIBUTING.md @@ -401,20 +401,20 @@ docs/ ## បញ្ជីត្រួតពិនិត្យ Pull Request -- [ ] តេស្តឆ្លងកាត់ (`npm test`) -- [ ] ការត្រួតពិនិត្យ Lint ឆ្លងកាត់ (`npm run lint`) -- [ ] ការ build ជោគជ័យ (`npm run build`) -- [ ] បានបន្ថែម TypeScript types សម្រាប់ functions និង interfaces សាធារណៈថ្មី -- [ ] គ្មានព័ត៌មានសម្ងាត់ ឬតម្លៃ fallback ដែលបាន hardcode -- [ ] ព័ត៌មានសម្ងាត់សាធារណៈពីប្រភពខាងដើមត្រូវបានបង្កប់តាមរយៈ `resolvePublicCred()` (សូមមើល [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) មិនត្រូវបង្កប់ជា literals ឡើយ -- [ ] Error responses ឆ្លងកាត់ `buildErrorBody()` / `sanitizeErrorMessage()` — គ្មាន stack traces ដើមនៅក្នុង response bodies (សូមមើល [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell commands (`exec` / `spawn`) បញ្ជូនតម្លៃ runtime តាមរយៈ `env` មិនមែនតាមរយៈ string interpolation -- [ ] Inputs ទាំងអស់ត្រូវបានផ្ទៀងផ្ទាត់ដោយប្រើ Zod schemas -- [ ] បានបន្ថែម **fragment** នៃ changelog នៅក្រោម `changelog.d/{features|fixes|maintenance}/-.md` សម្រាប់ការផ្លាស់ប្តូរដែលអ្នកប្រើប្រាស់អាចមើលឃើញ (សូមមើល [`changelog.d/README.md`](./changelog.d/README.md)) — **កុំ** កែសម្រួល `CHANGELOG.md` ដោយផ្ទាល់; fragments ត្រូវបានប្រមូលបញ្ចូលគ្នានៅពេលចេញ release ហើយមិនដែលប៉ះទង្គិចគ្នារវាង PRs ឡើយ -- [ ] ឯកសារត្រូវបានធ្វើបច្ចុប្បន្នភាព (ប្រសិនបើអាចអនុវត្តបាន) -- [ ] មិនមាន CodeQL / Secret-Scanning alerts ថ្មីត្រូវបានបើក ឬ alerts នីមួយៗត្រូវបានបដិសេធដោយមានយុត្តិកម្មបច្ចេកទេសយោងទៅឯកសារ `docs/security/` ដែលពាក់ព័ន្ធ +- [ ] ការធ្វើតេស្តជោគជ័យ (`npm test`) +- [ ] ការត្រួតពិនិត្យ Lint ជោគជ័យ (`npm run lint`) +- [ ] ការ Build ជោគជ័យ (`npm run build`) +- [ ] បានបន្ថែម TypeScript types សម្រាប់ public functions និង interfaces ថ្មី +- [ ] មិនមាន secrets ឬ fallback values ដែលសរសេរបង្កប់ដោយផ្ទាល់ +- [ ] បានបង្កប់ public upstream credentials តាមរយៈ `resolvePublicCred()` (សូមមើល [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) ដោយមិនប្រើ literals ជាដាច់ខាត +- [ ] Error responses ត្រូវបានបញ្ជូនតាមរយៈ `buildErrorBody()` / `sanitizeErrorMessage()` — មិនមាន raw stack traces នៅក្នុង response bodies ទេ (សូមមើល [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell commands (`exec` / `spawn`) បញ្ជូន runtime values តាមរយៈ `env` មិនមែនតាមរយៈ string interpolation ទេ +- [ ] inputs ទាំងអស់ត្រូវបានផ្ទៀងផ្ទាត់ដោយប្រើ Zod schemas +- [ ] បានបន្ថែម **fragment** នៃ Changelog នៅក្រោម `changelog.d/{features|fixes|maintenance}/-.md` សម្រាប់ការផ្លាស់ប្តូរដែលប៉ះពាល់ដល់អ្នកប្រើប្រាស់ (សូមមើល [`changelog.d/README.md`](./changelog.d/README.md)) — **កុំ**កែសម្រួល `CHANGELOG.md` ដោយផ្ទាល់; fragments ត្រូវបានបូកបញ្ចូលគ្នានៅពេលចេញផ្សាយ ហើយមិនបង្កឱ្យមាន conflicts រវាង PRs ទេ +- [ ] បានធ្វើបច្ចុប្បន្នភាពឯកសារ (ប្រសិនបើអាចអនុវត្តបាន) +- [ ] មិនបានបង្កើត CodeQL / Secret-Scanning alerts ថ្មី ឬ alert នីមួយៗត្រូវបានបដិសេធដោយមានហេតុផលបច្ចេកទេសយោងទៅឯកសារ `docs/security/` ដែលពាក់ព័ន្ធ - [ ] Routes ដែលបង្កើត child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) ត្រូវបានចាត់ថ្នាក់ជា `isLocalOnlyPath()` នៅក្នុង `src/server/authz/routeGuard.ts` — សូមមើល [ច្បាប់តឹងរ៉ឹង #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] គ្មាន trailers `Co-Authored-By` នៅក្នុង commit messages — commits ត្រូវតែបង្ហាញតែក្រោម Git identity របស់ម្ចាស់ repository ប៉ុណ្ណោះ (ច្បាប់តឹងរ៉ឹង #16) +- [ ] មិនមាន AI/bot `Co-authored-by` trailers នៅក្នុង commit messages ទេ (ច្បាប់តឹងរ៉ឹង #16) — human collaborators ដែលស្នាដៃរបស់ពួកគេត្រូវបានប្រើឡើងវិញ ត្រូវបានផ្តល់កិត្តិយសដោយប្រើ trailers ស្តង់ដារ `Co-authored-by: Name ` --- diff --git a/docs/i18n/km/docs/architecture/QUALITY_GATES.md b/docs/i18n/km/docs/architecture/QUALITY_GATES.md index a7e1376b010..a25089e669b 100644 --- a/docs/i18n/km/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/km/docs/architecture/QUALITY_GATES.md @@ -15,215 +15,215 @@ --- -## បញ្ជីសារពើភណ្ឌ Gate និងប្រូហ្វាល់ប្រតិបត្តិការ +## បញ្ជីសារពើភណ្ឌ Gate និងប្រូហ្វាល់ការប្រតិបត្តិ -### ការអនុញ្ញាតបេក្ខភាព +### ការទទួលយកបេក្ខភាព -Workflow របស់ CI និង Quality Gates នីមួយៗបញ្ចេញលទ្ធផលវិនិច្ឆ័យដែលមានស្ថិរភាព៖ `Gate / CI` និង -`Gate / Quality`។ គោលការណ៍អនុញ្ញាតដែលមានកំណែរបស់វារាយបញ្ជីគ្រប់ job ខ្សែខាងលើ -ថាតម្រូវ ឬជាការណែនាំ។ job តម្រូវដែលអាចអនុវត្តបានត្រូវតែជោគជ័យ៖ លទ្ធផលដែល -បាត់ លុបចោល រំលង កំពុងរង់ចាំ និងមិនស្គាល់ មិនអាចបញ្ជាក់ PASS បានទេ។ ការចាត់ថ្នាក់ -docs-only ឬ catalog-only ដែលត្រឹមត្រូវ អាចធ្វើឱ្យ lane កូដមិនអាចអនុវត្តបាន; -draft PR មិនមែនជាបេក្ខភាពដែលត្រូវបានទទួលយកទេ។ label `hotfix` មិនលើកលែងភស្តុតាងឡើយ។ +Workflow CI និង Quality Gates នីមួយៗបញ្ចេញសេចក្តីសម្រេចដែលមានឈ្មោះថេរ៖ `Gate / CI` និង +`Gate / Quality`។ គោលការណ៍ទទួលយកដែលមានកំណែរបស់វារាយបញ្ជី job ខ្សែខាងលើនីមួយៗ +ថាជា job ចាំបាច់ ឬជាប្រឹក្សា។ job ចាំបាច់ដែលអនុវត្តបានត្រូវតែជោគជ័យ៖ លទ្ធផលដែលបាត់, +ត្រូវបានបោះបង់, ត្រូវបានរំលង, កំពុងរង់ចាំ និងមិនស្គាល់ មិនអាចបញ្ជាក់ PASS បានទេ។ ចំណាត់ថ្នាក់ +docs-only ឬ catalog-only ដែលត្រឹមត្រូវអាចធ្វើឱ្យ lane កូដមួយមិនអាចអនុវត្តបាន; +draft PR មិនមែនជាបេក្ខភាពដែលត្រូវបានទទួលយកទេ។ ស្លាក `hotfix` មិនលើកលែងតម្រូវការភស្តុតាងឡើយ។ -Workflow ទាំងពីរគ្របដណ្តប់ PR និង push ទៅកាន់ branch main/release, ការបញ្ជាដំណើរការដោយដៃ និង +Workflow ទាំងពីរគ្របដណ្ដប់លើ PR និង push ទៅកាន់ branch main/release, ការបញ្ជាដំណើរការដោយដៃ និង ព្រឹត្តិការណ៍ merge-group។ Push, dispatch និង merge-group ដំណើរការជម្រើសពេញលេញ។ Fork -និង merge group ប្រើ hosted runner សម្រាប់ job ដែលតាមធម្មតាជ្រើសរើស self-hosted -runner; ត្រូវតែផ្ទៀងផ្ទាត់ថាមានសមត្ថភាព hosted គ្រប់គ្រាន់មុនពេលដាក់ឱ្យប្រើប្រាស់។ +និង merge group ប្រើ hosted runner សម្រាប់ job ដែលបើមិនដូច្នោះទេនឹងជ្រើស self-hosted +runner; ត្រូវតែផ្ទៀងផ្ទាត់ថាមានសមត្ថភាព hosted គ្រប់គ្រាន់ មុនពេលដាក់ឱ្យប្រើប្រាស់។ -បង្កាន់ដៃ JSON នីមួយៗកំណត់អត្តសញ្ញាណ SHA ដែលបាន check out, workflow run និង attempt។ -CLI បដិសេធភាពមិនត្រូវគ្នារវាង checkout/event SHA។ ការធ្វើតេស្ត Workflow ភ្ជាប់សមាជិកភាពគោលការណ៍ -ទៅនឹងបញ្ជី `needs` របស់ verdict job ដើម្បីកុំឱ្យ lane ថ្មី ឬដែលបានដកចេញ បាត់ទៅដោយស្ងៀមស្ងាត់។ -បង្កាន់ដៃទាំងនេះគ្របដណ្តប់តែ workflow របស់វាផ្ទាល់ប៉ុណ្ណោះ មិនមែនការបោះពុម្ពផ្សាយ ការដាក់ឱ្យប្រើប្រាស់ ឬដំណើរការខាងក្នុង -របស់ advisory scanner ដែលមានស្រាប់ទេ។ ការធ្វើឱ្យ check name ទាំងពីរសកម្មនៅក្នុង branch rule គឺជា -ការផ្លាស់ប្តូរផ្នែករដ្ឋបាលដាច់ដោយឡែក; ការបន្ថែម job ទាំងនេះមិនការពារ branch ដោយខ្លួនវាឡើយ។ +បង្កាន់ដៃ JSON នីមួយៗកំណត់អត្តសញ្ញាណ SHA ដែលបាន check out, ការដំណើរការ workflow និង attempt។ +CLI បដិសេធភាពមិនត្រូវគ្នារវាង checkout/event SHA។ ការធ្វើតេស្ត workflow ភ្ជាប់សមាជិកភាពគោលការណ៍ +ទៅនឹងបញ្ជី `needs` របស់ verdict job ដើម្បីកុំឱ្យ lane ថ្មី ឬ lane ដែលបានដកចេញ បាត់ទៅដោយស្ងៀមស្ងាត់។ +បង្កាន់ដៃទាំងនេះគ្របដណ្ដប់លើ workflow របស់ខ្លួន មិនមែនលើការបោះពុម្ពផ្សាយ, ការដាក់ឱ្យប្រើប្រាស់ ឬផ្នែកខាងក្នុង +នៃ advisory scanner ដែលមានស្រាប់ទេ។ ការធ្វើឱ្យឈ្មោះ check ទាំងពីរសកម្មក្នុងច្បាប់ branch គឺជា +ការផ្លាស់ប្ដូរផ្នែករដ្ឋបាលដោយឡែកមួយ; ការបន្ថែម job ទាំងនេះមិនការពារ branch ដោយខ្លួនឯងទេ។ -### បញ្ជីសារពើភណ្ឌ static scan +### បញ្ជីសារពើភណ្ឌការស្កេនស្ថិតិ បញ្ជីសារពើភណ្ឌ npm-alias ដែលមានកំណែ និងសមាជិកភាព static-scan ស្ថិតនៅក្នុង `config/quality/gate-manifest.json`។ ដំណើរការ `npm run check:gate-manifest` ដើម្បីផ្ទៀងផ្ទាត់ -ឈ្មោះ script និង command ជាក់លាក់ទល់នឹង `package.json`; ការបន្ថែម ការដកចេញ និង -ការប្រែប្រួល command នឹងធ្វើឱ្យទាំង local hook និង job ចាត់ថ្នាក់ការផ្លាស់ប្តូរក្នុង CI បរាជ័យ។ -alias មិនមែនជា workflow job, matrix instance ឬ test case ទេ៖ មិនត្រូវបង្ហាញចំនួនទាំងនេះ +ឈ្មោះ script និង command ពិតប្រាកដធៀបនឹង `package.json`; ការបន្ថែម, ការដកចេញ និង +ការប្រែប្រួល command នឹងធ្វើឱ្យទាំង local hook និង job ចំណាត់ថ្នាក់ការផ្លាស់ប្ដូរក្នុង CI បរាជ័យ។ +alias មួយមិនមែនជា workflow job, matrix instance ឬ test case ទេ៖ មិនត្រូវបង្ហាញចំនួនទាំងនេះ ថាអាចប្រើជំនួសគ្នាបានឡើយ។ ប្រើ `npm run quality:scan -- --list` ឬ `npm run quality:scan:fast -- --list` -ដើម្បីពិនិត្យមើល alias ដែលបានជ្រើសរើសដោយមិនប្រតិបត្តិវា។ runner ហៅ -npm entrypoint ដូច្នេះ runtime របស់វា (រួមទាំង Bun នៅកន្លែងដែលបានកំណត់រចនាសម្ព័ន្ធ) ត្រូវបានរក្សាទុក។ -manifest កត់ត្រា alias ដែលនៅក្រៅប្រូហ្វាល់ទាំងនោះថាត្រូវបានហៅដោយឡែក ហើយ -command ថែទាំត្រូវបានហាមឃាត់ក្នុងប្រូហ្វាល់ scan ដែលបានតែអាន។ - -ប្រូហ្វាល់ទាំងនេះគ្របដណ្តប់តែ static scan ប៉ុណ្ណោះ។ វាមិនបញ្ជាក់ product test, -coverage, packaging, external check ឬការទទួលយកបេក្ខភាពពេញលេញសម្រាប់ release ឡើយ។ -ការអនុញ្ញាតរបស់ Workflow ប្រើ `config/quality/admission-policy.json` ដែលបានភ្ជាប់ និង +ដើម្បីត្រួតពិនិត្យ alias ដែលបានជ្រើស ដោយមិនប្រតិបត្តិពួកវា។ runner ហៅ npm entrypoint +ដូច្នេះ runtime របស់វា (រួមទាំង Bun នៅកន្លែងដែលបានកំណត់រចនាសម្ព័ន្ធ) ត្រូវបានរក្សាទុក។ +manifest កត់ត្រា alias នៅក្រៅប្រូហ្វាល់ទាំងនោះថាត្រូវបានហៅដោយឡែក ហើយ +maintenance command ត្រូវបានហាមឃាត់ក្នុងប្រូហ្វាល់ស្កេន read-only។ + +ប្រូហ្វាល់ទាំងនេះគ្របដណ្ដប់តែ static scan ប៉ុណ្ណោះ។ ពួកវាមិនបញ្ជាក់ជាផ្លូវការលើ product test, +coverage, packaging, external check ឬការទទួលយក release ពេញលេញរបស់បេក្ខភាពឡើយ។ +ការទទួលយក workflow ប្រើ `config/quality/admission-policy.json` ដែលបានភ្ជាប់ និង `scripts/quality/admission-verdict.mjs`។ ប្រូហ្វាល់ release-observer នៅតែដាច់ដោយឡែក; -ពិនិត្យ check និងបង្កាន់ដៃដែលអាចអនុវត្តបានរបស់វាដោយឡែក។ បញ្ជីសារពើភណ្ឌជាអត្ថបទ -ខាងក្រោមគឺជាឯកសារយោង មិនមែនជាភស្តុតាងថា gate បានដំណើរការពិតប្រាកដទេ។ +ត្រូវត្រួតពិនិត្យ check និងបង្កាន់ដៃដែលអនុវត្តបានរបស់ពួកវាដោយឯករាជ្យ។ បញ្ជីសារពើភណ្ឌជា +អត្ថបទខាងក្រោមគឺជាឯកសារយោង មិនមែនជាភស្តុតាងថា gate ពិតជាបានដំណើរការឡើយ។ Script ស្ថិតនៅក្រោម `scripts/check/` (policy gate) និង `scripts/quality/` (ratchet engine)។ -ប្រភពការពិតរបស់ CI គឺ `.github/workflows/ci.yml`។ +ប្រភពសេចក្តីពិតរបស់ CI គឺ `.github/workflows/ci.yml`។ -### Fast-path របស់ Release PR (`quality.yml`) +### ផ្លូវលឿនសម្រាប់ Release PR (`quality.yml`) -`.github/workflows/quality.yml` បំពេញបន្ថែម CI សម្រាប់ PR របស់ main/release, push ទៅ -protected branch, dispatch និង merge group។ PR ប្រើ fast check ដែលត្រងតាម path។ duplicate build -ដែលបានបិទជាអចិន្ត្រៃយ៍ត្រូវបានដកចេញ; check build/package/boot ពិតប្រាកដនៅតែមានក្នុង CI។ +`.github/workflows/quality.yml` បំពេញបន្ថែម CI លើ main/release PR, push ទៅកាន់ protected branch, +dispatch និង merge group។ PR ប្រើ fast check ដែលបានច្រោះតាម path។ duplicate build ដែលបាន +បិទជាអចិន្ត្រៃយ៍ត្រូវបានដកចេញ; build/package/boot check ពិតប្រាកដនៅតែមានក្នុង CI។ -| Job | វិសាលភាព | ការទប់ស្កាត់ | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `Docs Gates (fast-path)` | PR ឯកសារ/កូដ; API docs refs និង docs-all | បាទ/ចាស | -| `Fast Quality Gates` | PR កូដ; static check, typecheck, dashboard typecheck, impacted unit test | បាទ/ចាស | -| `Forgotten sibling tests` | PR កូដ; module ដែលបានផ្លាស់ប្តូរត្រូវបានតាមដានទៅ static consumer និង candidate sibling test; path របស់ barrel និង dynamic-import ត្រូវបានរាយការណ៍ជាការវិនិច្ឆ័យណែនាំ ជាមួយ exception ក្នុង allowlist ដែលយោងដល់ | **ការណែនាំ** | -| `Vitest (fast-path)` | PR កូដ; fast vitest suite | បាទ/ចាស | -| `Unit Tests fast-path` | PR កូដ; unit suite ចំនួន 4 shard | បាទ/ចាស | -| `No new ESLint warnings` | PR កូដ; lint guard ដែលគិតគូរពី suppression | បាទ/ចាស រួមទាំង fork | -| `Merge integrity (changelog + generated skills)` | PR ដែលមិនមែនជា draft; ការធ្វើសមកាលកម្ម changelog និង generated skill | បាទ/ចាស រួមទាំង fork | +| Job | វិសាលភាព | ការរារាំង | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | Docs/code PR; API docs refs និង docs-all | បាទ/ចាស | +| `Fast Quality Gates` | Code PR; static check, typecheck, dashboard typecheck, impacted unit test | បាទ/ចាស | +| `Forgotten sibling tests` | Code PR; module ដែលបានផ្លាស់ប្ដូរត្រូវបានតាមដានទៅកាន់ static consumer និង candidate sibling test; barrel និង dynamic-import path ត្រូវបានរាយការណ៍ជាការវិនិច្ឆ័យបែបប្រឹក្សា ដោយមានករណីលើកលែង allowlist ដែលបានយោង | **ប្រឹក្សា** | +| `Vitest (fast-path)` | Code PR; fast vitest suite | បាទ/ចាស | +| `Unit Tests fast-path` | Code PR; unit suite ចំនួន 4 shard | បាទ/ចាស | +| `No new ESLint warnings` | Code PR; lint guard ដែលគិតគូរពី suppression | បាទ/ចាស រួមទាំង fork | +| `Merge integrity (changelog + generated skills)` | Non-draft PR; changelog និង generated skill sync | បាទ/ចាស រួមទាំង fork | #### របាយការណ៍ Forgotten sibling tests `npm run check:forgotten-sibling-tests` ប្រើ import resolver ដែលនៅពីក្រោយ test-impact map ឡើងវិញ។ -សម្រាប់ production module នីមួយៗដែលបានផ្លាស់ប្តូរ វារាយការណ៍ខ្សែសង្វាក់កំណត់បានដដែល -`changed module/symbol -> static consumer -> candidate sibling test` នៅពេល candidate -test មិនមានក្នុង diff របស់ pull request។ សេចក្តីសង្ខេប Markdown និងលទ្ធផល JSON ត្រូវបានរក្សាទុកជា -workflow artifact `forgotten-sibling-tests` សម្រាប់ការក្រិតតម្រូវ មុនពេលដាក់ឱ្យប្រើប្រាស់ជាការទប់ស្កាត់ណាមួយ។ - -ការនាំចេញបន្តបែប Barrel និងការនាំចូលបែបថាមវន្ត គ្រាន់តែជាការវិនិច្ឆ័យអំពីការដោះស្រាយប៉ុណ្ណោះ; វាមិនដែលបង្កើត -លទ្ធផលរកឃើញដែលរារាំងឡើយ។ ករណីលើកលែងដែលបានពិនិត្យរួចមាននៅក្នុង -`config/quality/forgotten-sibling-allowlist.json`។ ធាតុនីមួយៗត្រូវតែបញ្ជាក់ឈ្មោះតេស្តប្រើប្រាស់ និងតេស្តបេក្ខជន -ផ្តល់ហេតុផលជាក់លាក់ និងភ្ជាប់ទៅកាន់ GitHub issue ឬ pull request។ ធាតុដែលមានទម្រង់មិនត្រឹមត្រូវនឹងបរាជ័យ -ក្នុងស្ថានភាពបិទ។ ករណីលើកលែងមិនអាចលាក់បាំងតេស្តបេក្ខជនដែលត្រូវបានលុប ឬ diff ដែលបន្ថែម `.skip`/`.todo` បានទេ; -ការធ្វើឱ្យ assertion ខ្សោយ និងការលាក់បាំងផ្សេងទៀត នៅតែស្ថិតក្រោមការគ្រប់គ្រងរបស់ច្រករារាំងឯករាជ្យ +សម្រាប់ production module នីមួយៗដែលបានផ្លាស់ប្ដូរ វារាយការណ៍ខ្សែសង្វាក់ +`changed module/symbol -> static consumer -> candidate sibling test` ដែលមានលក្ខណៈកំណត់បានជានិច្ច នៅពេល candidate +test មិនមានក្នុង diff របស់ pull-request។ សេចក្តីសង្ខេប Markdown និងលទ្ធផល JSON ត្រូវបានរក្សាទុកជា +workflow artifact `forgotten-sibling-tests` សម្រាប់ការក្រិតតម្រូវ មុនពេលដាក់ឱ្យប្រើប្រាស់ជាការរារាំងណាមួយ។ + +ការនាំចេញបន្តតាម barrel និងការនាំចូលបែបថាមវន្ត គ្រាន់តែជាការវិនិច្ឆ័យអំពីការដោះស្រាយប៉ុណ្ណោះ ពួកវាមិនដែលបង្កើត +ការរកឃើញដែលរារាំងឡើយ។ ករណីលើកលែងដែលបានពិនិត្យរួចមាននៅក្នុង +`config/quality/forgotten-sibling-allowlist.json`។ ធាតុនីមួយៗត្រូវតែបញ្ជាក់ឈ្មោះ consumer និង candidate +test ផ្តល់ហេតុផលជាក់លាក់ និងភ្ជាប់ទៅកាន់ GitHub issue ឬ pull request។ ធាតុដែលមានទម្រង់មិនត្រឹមត្រូវនឹងបរាជ័យ +តាមលំនាំសុវត្ថិភាព។ ករណីលើកលែងមិនអាចរារាំង candidate test ដែលបានលុប ឬ diff ដែលបន្ថែម `.skip`/`.todo` បានទេ; +ការធ្វើឱ្យ assertion ខ្សោយ និងការបិទបាំងផ្សេងទៀត នៅតែជាកម្មសិទ្ធិរបស់ច្រកត្រួតពិនិត្យដែលរារាំងដោយឯករាជ្យ `check:test-masking`។ -### កិច្ចការ: `lint` - -ដំណើរការលើរាល់ PR ទៅកាន់ `main`។ រារាំងការបញ្ចូលចូលគ្នា ប្រសិនបើបរាជ័យ។ - -| ស្គ្រីប (`npm run ...`) | ផ្ទៀងផ្ទាត់ | រារាំង | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| `check:node-runtime` | កំណែ Node.js ស្ថិតនៅក្នុងចន្លោះដែលបានគាំទ្រ | បាទ/ចាស | -| `check:cycles` | ការនាំចូលជារង្វង់ — ម៉ូឌុល `src/` + `open-sse/` ទាំងអស់ | បាទ/ចាស | -| `check:route-validation:t06` | មាន Zod schemas នៅលើ routes ទាំងអស់ (គោលការណ៍ Tier 6) | បាទ/ចាស | -| `check:any-budget:t11` | ចំនួន `@ts-expect-error // any` មិនលើសថវិកាកំណត់ (Tier 11 catraca) | បាទ/ចាស | -| `check:provider-consistency` | រាល់ provider នៅក្នុង `providers.ts` មានធាតុដែលត្រូវគ្នានៅក្នុង `providerRegistry.ts` (និងផ្ទុយមកវិញ សម្រាប់តែធាតុក្នុង allowlist) | បាទ/ចាស | -| `check:model-lifecycle` | តារាងកំណត់ផ្លូវដែលថែទាំដោយដៃទាំងបីនៅតែស្របគ្នាជាមួយ lifecycle snapshot ដែលបាន commit (#11503)៖ `FITNESS_TABLE` (`taskFitness.ts`) មិនដាក់ពិន្ទុឱ្យ id ដែលបានចូលនិវត្តន៍ណាមួយដែល `REGISTRY` អាចកំណត់ផ្លូវទៅកាន់បានទេ; រាល់គោលដៅរបស់ `BUILT_IN_ALIASES` មាននៅក្នុង `REGISTRY` និងមិនមាននៅក្នុង snapshot នៃ id ដែលបានចូលនិវត្តន៍; រាល់ id ដែលបានចូលនិវត្តន៍ ហើយនៅតែមានក្នុង `REGISTRY` ត្រូវបានបញ្ជូនបន្ត ឬរាយក្នុង `allowedRetiredInCatalog`; ហើយគ្មានប្រភព ឬគោលដៅណាមួយរបស់ `DEFAULT_DEGRADATION_MAP` ត្រូវបានសម្គាល់ថាបានចូលនិវត្តន៍នៅក្នុង snapshot នោះទេ។ វាមិនបញ្ជាក់ថា model មួយកំពុងត្រូវបានផ្តល់សេវាដោយ upstream ដែលកំពុងដំណើរការនោះទេ។ ដំណើរការក្រៅបណ្ដាញ — ប្រៀបធៀបជាមួយ `config/quality/model-lifecycle.json` ដែលធ្វើបច្ចុប្បន្នភាពដោយដៃតាមរយៈ `npm run quality:refresh-model-lifecycle` (ត្រូវការបណ្ដាញ; មិនបានភ្ជាប់ទៅក្នុង CI)។ `allowedRetiredInCatalog` គឺជាយន្តការរឹតបន្តឹងជាលំដាប់៖ បន្ថែមធាតុមួយបាន លុះត្រាតែមាន issue សម្រាប់តាមដាន។ | បាទ/ចាស | -| `check:fetch-targets` | រាល់ `fetch("/api/...")` នៅក្នុង `src/` ផ្នែក client អាចដោះស្រាយទៅកាន់ `route.ts` ដែលមានពិតប្រាកដ | បាទ/ចាស | -| `check:deps` | deps ទាំងអស់ដែលអាចដំឡើងដោយ `npm install` នៅទូទាំងរាល់ `package.json` ក្នុង repo មាននៅក្នុង `dependency-allowlist.json`; package ថ្មីដែលមិនបានចាក់សោ version ឬមានឈ្មោះស្រដៀងដើម្បីបោកបញ្ឆោត នឹងត្រូវបានសម្គាល់ | បាទ/ចាស | -| `audit:deps` | `npm audit` (root + electron) — គ្មានការជូនដំណឹងកម្រិតខ្ពស់/ធ្ងន់ធ្ងរ (ត្រួតគ្នាជាមួយ osv `check:vuln-ratchet`; សូមមើលបញ្ជីការងារ Rationalization Backlog) | បាទ/ចាស | -| `check:lockfile` | សុចរិតភាពរបស់ `package-lock.json` — https registry, integrity hashes និងគ្មានការកំណត់ host ជំនួស | បាទ/ចាស | -| `check:licenses` | បញ្ជីអនុញ្ញាតអាជ្ញាបណ្ណ SPDX សម្រាប់ dependency ក្នុង production | បាទ/ចាស | -| `check:tracked-artifacts` | មិនមាន artifact ពីការ build / symlink របស់ `node_modules` ដែលបាន commit ទេ (ដំណើរការផងដែរនៅក្នុង husky pre-commit; pre-push ត្រូវបានកំណត់ឱ្យស្រាលដោយចេតនា — #6716) | បាទ/ចាស | -| `check:ai-attribution` | មិនអនុញ្ញាត trailer `Co-Authored-By` របស់ AI/bot ឬ footer បញ្ជាក់ពីការបង្កើតដោយ AI នៅក្នុង commit ចំណងជើង ឬតួអត្ថបទរបស់ PR ទេ — ច្បាប់តឹងរ៉ឹង #16 (នៅក្នុងរង្វិលជុំ fast-gates របស់ `quality.yml` សម្រាប់ PR→`release/**` — អាន event payload និងមិនធ្វើអ្វីនៅក្រៅ PR — ព្រមទាំងជំហានសម្រាប់តែ PR នៅក្នុង lint របស់ `ci.yml` សម្រាប់ PR→`main`; ក៏មាន hook husky `commit-msg` ផងដែរ; អនុញ្ញាតសហអ្នកនិពន្ធជាមនុស្ស; #14436) | -| `check:vitest-exclusions` | ការដកចេញរបស់ Vitest នីមួយៗត្រូវបញ្ជាក់ tracking issue និងមាននៅក្នុង `config/quality/vitest-exclusions.json` (#13204) | បាទ/ចាស | -| `check:file-size` | គ្មានឯកសារ source ណាមួយលើសពីកម្រិតកំណត់តាម extension ទេ (ratchet៖ ឯកសារធំដែលត្រូវបានបង្កកនៅក្នុងបញ្ជី `frozen`) | បាទ/ចាស | -| `check:error-helper` | response កំហុសនៅក្នុង executor/handler ប្រើ `buildErrorBody()` / `sanitizeErrorMessage()` (ច្បាប់តឹងរ៉ឹង #12) | បាទ/ចាស | -| `check:migration-numbering` | ឯកសារ Migration SQL ត្រូវបានដាក់លេខតាមលំដាប់ ដោយគ្មានលេខរំលង ឬលេខស្ទួន | បាទ/ចាស | -| `check:public-creds` | មិនមានតម្លៃជាក់លាក់ OAuth `client_id`/`client_secret` ឬ Firebase Web keys នៅក្រៅ `publicCreds.ts` ទេ (វិធានតឹងរ៉ឹង #11) | បាទ/ចាស | -| `check:db-rules` | មិនមាន SQL ដើមនៅក្រៅម៉ូឌុល `src/lib/db/` ទេ; មិនមាន barrel-imports ពី `localDb.ts` ទេ (វិធានតឹងរ៉ឹង #2/#5) | បាទ/ចាស | -| `check:known-symbols` | Provider executors, routing strategies និង translators ដែលបានចុះឈ្មោះក្នុង dispatch tables របស់ពួកវា ត្រូវតែផ្គូផ្គងនឹងឯកសារនៅលើឌីស — មិនមាន symbols ដែលកំព្រា ឬមិនបានប្រកាសទេ | បាទ/ចាស | -| `check:route-guard-membership` | គ្រប់ route ដែលបង្កើត child process ត្រូវបានចាត់ថ្នាក់ដោយ `isLocalOnlyPath()` (វិធានតឹងរ៉ឹង #15/#17) | បាទ/ចាស | -| `check:test-discovery` | គ្រប់ឯកសារ `*.test.ts` / `*.spec.ts` ក្នុង repo ត្រូវបានប្រមូលដោយ test runner យ៉ាងហោចណាស់មួយ (ratchet៖ បញ្ជីឯកសារកំព្រាក្នុង `test-discovery-baseline.json` អាចតែថយចុះប៉ុណ្ណោះ) | បាទ/ចាស | -| `check:agent-skills-sync` | ផ្ទៀងផ្ទាត់ថា artifact ដែលបានបង្កើតសម្រាប់ agent-skills ត្រូវគ្នានឹងកាតាឡុកប្រភពរបស់វា (គ្មានភាពខុសគ្នា) | -| `check:provider-asset-provenance` | ឡូហ្គោ/asset របស់ provider មានធាតុកំណត់ត្រាប្រភពដើម | -| `lint:json` | ឯកសារកំណត់រចនាសម្ព័ន្ធ JSON អាច parse បាន និងអនុលោមតាមច្បាប់ lint របស់ repo | -| `typecheck:core` | ចងក្រង TypeScript ដោយគ្មានកំហុស (មានតែការព្រមានជាព័ត៌មានណែនាំប៉ុណ្ណោះ) | បាទ/ចាស | -| `typecheck:noimplicit:core` | `noImplicitAny` តឹងរ៉ឹង — សម្រាប់អនាគត; ទីតាំងហៅដែលមានស្រាប់ជាច្រើននៅតែត្រូវការការកំណត់ annotation | **ជាព័ត៌មានណែនាំ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ដែលកំណត់វិសាលភាពត្រឹម `src/app/(dashboard)/**` (#7033) — បញ្ជីអនុញ្ញាត 27 ឯកសារដែលបានជ្រើសរើសរបស់ `typecheck:core` មិនរួមបញ្ចូល dashboard TSX ណាមួយទេ ហើយ `next build` ក៏មិនដែលពិនិត្យ type របស់វាដែរ (`next.config.mjs` កំណត់ `ignoreBuildErrors: true`) ដូច្នេះ regression នៃ identifier ដែលគ្មានប្រភពយោងនៅទីនោះ (#6625/#6909) មិនអាចត្រូវបាន CI រកឃើញ។ វាប្រៀបធៀបភាពខុសគ្នាជាមួយ baseline ចំនួនថេរតាមឯកសារ/កូដ TS (`config/quality/dashboard-typecheck-baseline.json`, ប្រើលំនាំអនុវត្តចំពោះភាពហួសសម័យដូចគ្នានឹង `check:known-symbols`) — មានតែកំហុសថ្មីលើសពីចំនួនក្នុង baseline ប៉ុណ្ណោះដែលធ្វើឱ្យ gate បរាជ័យ; បន្ថយ baseline ជាបន្តបន្ទាប់ដោយប្រើ `--update` នៅពេលកំហុសដែលមានស្រាប់ត្រូវបានកែ។ | បាទ/ចាស | - -### Job៖ `quality-gate` - -ដំណើរការបន្ទាប់ពី `test-coverage`។ រារាំងការបញ្ចូល merge នៅពេលបរាជ័យ។ - -| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `quality:collect` | បង្កើត `quality-metrics.json` (ចំនួនការព្រមាន ESLint និង coverage ពីរបាយការណ៍ shard ដែលបានបញ្ចូលគ្នា) | បាទ/ចាស (នៅមុន ratchet) | -| `quality:ratchet` | ម៉ែត្រនីមួយៗក្នុង `quality-baseline.json` មិនបានថយចុះ (ការព្រមាន ESLint ≤ baseline; coverage ≥ baseline) | បាទ/ចាស | -| `check:duplication` | ការស្ទួនកូដ (jscpd@4) មិនលើស baseline ក្នុង `quality-baseline.json` | បាទ/ចាស | -| `check:complexity` | ភាពស្មុគស្មាញ cyclomatic កម្រិតឯកសារមិនលើសដែនកំណត់ (ESLint `complexity` ស្នូល + `max-lines-per-function`) | បាទ/ចាស | -| `check:cognitive-complexity` | Ratchet នៃភាពស្មុគស្មាញផ្នែកការគិត (`eslint-plugin-sonarjs`) — ដំណើរការ ESLint ដាច់ដោយឡែក; CI ដំណើរការទាំងពីរដោយបញ្ចូលជាជំហាន `check:complexity-ratchets` តែមួយ | បាទ/ចាស | -| `check:dead-code` | Ratchet សម្រាប់ exports / ឯកសារដែលមិនបានប្រើ (knip) មិនថយចុះធៀបនឹង baseline | បាទ/ចាស | -| `check:compression-budget` | ថវិកា benchmark សម្រាប់ compression — កម្រិតអប្បបរមានៃការសន្សំ token តាម engine នីមួយៗមិនត្រូវថយចុះ | បាទ/ចាស | -| `check:type-coverage` | Ratchet ភាគរយដែលបានកំណត់ type (`type-coverage`) មិនថយចុះ; ជាទូទៅគ្របដណ្តប់ជំនួស `typecheck:noimplicit:core` | បាទ/ចាស | -| `check:codeql-ratchet` | ចំនួនការជូនដំណឹង CodeQL ដែលបើកមិនថយចុះ (អានតាមរយៈ `gh api`; រំលងដោយសុវត្ថិភាពនៅពេលគ្មាន token) — សម្រាប់វដ្ត refresh និងការបង្កឱ្យដំណើរការដោយដៃ៖ សូមមើល "CodeQL ratchet" ខាងក្រោម | បាទ/ចាស | - -### Job៖ `quality-extended` - -Job ទាំងមូលគឺសម្រាប់ផ្តល់យោបល់ (`continue-on-error: true`)។ Ratchet ដែលផ្អែកលើ npm ដំណើរការ -ជាក់ស្តែង; scanner ខាងក្រៅត្រូវបានដំឡើងតាមរយៈ `gh release download` ហើយរំលងដោយខ្លួនឯង (exit 0) -នៅពេល binary នៅតែមិនមាន។ - -| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -| `check:circular-deps` | មិនមាន dependency ជារង្វិល (dpdm) | **សម្រាប់ផ្តល់យោបល់** | -| `check:bundle-size` | ទំហំ bundle មិនលើសដែនកំណត់ | **សម្រាប់ផ្តល់យោបល់** | -| `check:secrets` | ការស្កេន secret (gitleaks) — រំលងប្រសិនបើគ្មាន binary | **សម្រាប់ផ្តល់យោបល់** | -| `check:vuln-ratchet` | ភាពងាយរងគ្រោះរបស់ dependency (osv-scanner) មិនថយចុះ — រំលងប្រសិនបើគ្មាន binary | **សម្រាប់ផ្តល់យោបល់** | -| `check:workflows` | ការត្រួតពិនិត្យ workflow (actionlint + zizmor); scanner ដែលបាត់/ខូច របាយការណ៍មិនត្រឹមត្រូវ ឬគ្មាន ratchet baseline នឹងបរាជ័យជា INCOMPLETE។ លទ្ធផលរកឃើញដែលមានសុពលភាពអនុវត្តតាមគោលការណ៍ strict/advisory/ratchet ដែលបានជ្រើសរើស | តម្រូវឱ្យដំណើរការ; zizmor ratchet រារាំងក្នុង CI | -| `check:openapi-breaking` | ការផ្លាស់ប្តូរដែលបំបែកភាពឆបគ្នានៃកិច្ចសន្យា API សាធារណៈ (`openapi.yaml`) ធៀបនឹង branch មូលដ្ឋាន (oasdiff) — បង្កើត `openapiBreaking=N`; រំលងប្រសិនបើគ្មាន oasdiff ឬមិនអាចដោះស្រាយ spec មូលដ្ឋានបាន | **សម្រាប់ផ្តល់យោបល់** | - -### Job៖ `docs-sync-strict` - -ដំណើរការលើរាល់ PR ទៅកាន់ `main`។ រារាំងការបញ្ចូលគ្នានៅពេលបរាជ័យ។ - -| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `check:docs-all` | ច្រកត្រួតពិនិត្យមេតាដែលដំណើរការច្រកត្រួតពិនិត្យរងទាំង 6 ខាងក្រោមតាមលំដាប់ | បាទ/ចាស | -| ↳ `check:docs-sync` | ភាពស៊ីសង្វាក់គ្នានៃកំណែ CHANGELOG / OpenAPI / llm.txt | បាទ/ចាស | -| ↳ `check:docs-counts` | ចំនួនដែលរៀបរាប់ក្នុងអត្ថបទ (ចំនួនអ្នកផ្តល់សេវា ចំនួនការធ្វើចំណាកស្រុក ជាដើម) ស្ថិតនៅក្នុងចន្លោះ ratchet នៃចំនួនពិត | បាទ/ចាស | -| ↳ `check:env-doc-sync` | អថេរបរិស្ថានទាំងអស់ក្នុង `.env.example` ត្រូវបានចងក្រងជាឯកសារក្នុងតារាងឯកសារណាមួយ ហើយផ្ទុយមកវិញ | បាទ/ចាស | -| ↳ `check:deprecated-versions` | មិនមានខ្សែអក្សរកំណែដែលលែងប្រើនៅក្នុងឯកសារ | បាទ/ចាស | -| ↳ `check:doc-links` | តំណ markdown ខាងក្នុងឯកសារអាចចូលទៅកាន់ឯកសារពិតបាន (ទម្រង់ `[text]`/`(path)`) | បាទ/ចាស | -| ↳ `check:fabricated-docs` | Route អថេរបរិស្ថាន ពាក្យបញ្ជា CLI ឈ្មោះ hook និងផ្លូវឯកសារដែលយោងក្នុងឯកសារ មាននៅក្នុងមូលដ្ឋានកូដ។ ជាច្រកត្រួតពិនិត្យរឹងតាមរយៈ `--strict`; បរាជ័យបែបទន់ដោយគ្មាន flag។ | បាទ/ចាស (តាមរយៈ `--strict` ក្នុង CI) | -| `check:cli-i18n` | ខ្សែអក្សរពាក្យបញ្ជា CLI មាននៅក្នុងឯកសារ locale i18n ទាំងអស់ | បាទ/ចាស | -| `check:openapi-coverage` | សេចក្តីបញ្ជាក់ OpenAPI គ្របដណ្តប់យ៉ាងហោចណាស់ដល់កម្រិតអប្បបរមាបែប ratchet នៃ route ពិត | បាទ/ចាស | -| `check:openapi-security-tiers` | ចំណារពន្យល់កម្រិតសុវត្ថិភាពក្នុង `openapi.yaml` ស្របគ្នាជាមួយចំណាត់ថ្នាក់ក្នុង `routeGuard.ts` | **ជាការណែនាំ** | -| `check:openapi-routes` | Path នីមួយៗក្នុង `openapi.yaml` អាចចូលទៅកាន់ `route.ts` ពិតបាន (ការពារការប្រឌិតព័ត៌មាន) | បាទ/ចាស | -| `check:docs-symbols` | រាល់ឯកសារយោង `/api/...` ក្នុង `docs/**/*.md` អាចចូលទៅកាន់ `route.ts` ពិតបាន (ការពារការប្រឌិតព័ត៌មាន) | បាទ/ចាស | -| `i18n translation drift` | Key ដែលមិនបានបកប្រែក្នុងឯកសារ locale i18n — គ្រាន់តែព្រមានប៉ុណ្ណោះ | **ជាការណែនាំ** | +### កិច្ចការ៖ `lint` + +ដំណើរការលើគ្រប់ PR ទៅកាន់ `main`។ រារាំងការបញ្ចូលចូលគ្នា ប្រសិនបើបរាជ័យ។ + +| ស្គ្រីប (`npm run ...`) | អ្វីដែលត្រូវផ្ទៀងផ្ទាត់ | ការរារាំង | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:node-runtime` | កំណែ Node.js ស្ថិតនៅក្នុងជួរដែលបានគាំទ្រ | បាទ/ចាស | +| `check:cycles` | ការនាំចូលជារង្វង់នៅទូទាំង `src/` + `open-sse/` (ផ្អែកលើ AST ហើយ `paths` របស់ tsconfig ត្រូវបានដោះស្រាយ)។ ការដំណើរការធម្មតា = ជាការណែនាំ និងបង្ហាញបញ្ជីរង្វង់។ `check:cycles:ratchet` (ដែល CI ដំណើរការ) នឹងរារាំង នៅពេលចំនួនលើសពីកម្រិតអតិបរមា `metrics.cycles` ក្នុង `quality-baseline.json` — បច្ចុប្បន្នគឺ 14, `direction: down` ដូច្នេះវាអាចតែថយចុះប៉ុណ្ណោះ (#15159 G-01/G-02) | បាទ/ចាស (ratchet) | +| `check:route-validation:t06` | មាន Zod schemas នៅលើ routes ទាំងអស់ (គោលការណ៍ Tier 6) | បាទ/ចាស | +| `check:any-budget:t11` | ចំនួន `@ts-expect-error // any` មិនលើសពីកម្រិតដែលបានកំណត់ (Tier 11 catraca) | បាទ/ចាស | +| `check:provider-consistency` | រាល់ provider នៅក្នុង `providers.ts` មាន entry ដែលត្រូវគ្នានៅក្នុង `providerRegistry.ts` (និងផ្ទុយមកវិញ សម្រាប់អ្វីដែលស្ថិតក្នុង allowlist) | បាទ | +| `check:model-lifecycle` | តារាង routing ចំនួនបីដែលថែទាំដោយដៃ នៅតែមានភាពស៊ីសង្វាក់គ្នាជាមួយ lifecycle snapshot ដែលបាន commit (#11503)៖ `FITNESS_TABLE` (`taskFitness.ts`) មិនដាក់ពិន្ទុឱ្យ retired id ណាមួយដែល `REGISTRY` អាច route បានទេ; រាល់ target របស់ `BUILT_IN_ALIASES` មាននៅក្នុង `REGISTRY` និងមិនមាននៅក្នុង retired-id snapshot; រាល់ retired id ដែលនៅតែមានក្នុង `REGISTRY` ត្រូវបាន forward ឬរាយក្នុង `allowedRetiredInCatalog`; ហើយគ្មាន source ឬ target របស់ `DEFAULT_DEGRADATION_MAP` ណាមួយបង្ហាញថា retired ក្នុង snapshot នោះទេ។ វាមិនបញ្ជាក់ថា model មួយបច្ចុប្បន្នត្រូវបានផ្តល់សេវាដោយ live upstream នោះទេ។ Offline — ប្រៀបធៀបជាមួយ `config/quality/model-lifecycle.json` ដែល refresh ដោយដៃតាមរយៈ `npm run quality:refresh-model-lifecycle` (ត្រូវការ network; មិនបានភ្ជាប់ទៅក្នុង CI)។ `allowedRetiredInCatalog` គឺជា burn-down ratchet៖ បន្ថែម entry តែជាមួយ tracking issue ប៉ុណ្ណោះ។ | បាទ | +| `check:fetch-targets` | រាល់ `fetch("/api/...")` នៅក្នុង `src/` ផ្នែក client-side resolve ទៅកាន់ `route.ts` ដែលមានពិតប្រាកដ | បាទ | +| `check:deps` | deps ទាំងអស់ដែលអាច `npm install` បាន នៅទូទាំងរាល់ `package.json` ក្នុង repo សុទ្ធតែមានក្នុង `dependency-allowlist.json`; package ថ្មីដែលមិនបាន pin ឬត្រូវបាន slopsquat នឹងត្រូវបានដាក់សញ្ញាសម្គាល់ | បាទ | +| `audit:deps` | `npm audit` (root + electron) — គ្មានការណែនាំសុវត្ថិភាពកម្រិត high/critical (ជាន់គ្នាជាមួយ osv `check:vuln-ratchet`; សូមមើល Rationalization Backlog) | បាទ | +| `check:lockfile` | integrity របស់ `package-lock.json` — https registry, integrity hashes, គ្មាន host overrides | បាទ | +| `check:licenses` | បញ្ជីអាជ្ញាបណ្ណ SPDX ដែលអនុញ្ញាតសម្រាប់ production dependencies | បាទ | +| `check:tracked-artifacts` | គ្មាន build artifacts / symlinks របស់ `node_modules` ដែលបាន commit (ក៏ដំណើរការនៅក្នុង husky pre-commit ផងដែរ; pre-push ត្រូវបានកំណត់ឱ្យស្រាលដោយចេតនា — #6716) | បាទ | +| `check:ai-attribution` | គ្មាន trailer `Co-Authored-By` របស់ AI/bot ឬ footer នៃការបង្កើតដោយ AI នៅក្នុង commits, ចំណងជើង ឬខ្លឹមសារ PR — ច្បាប់តឹងរ៉ឹង #16 (នៅក្នុង fast-gates loop របស់ `quality.yml` សម្រាប់ PR→`release/**` — អាន event payload, មិនធ្វើអ្វីទេនៅក្រៅ PR — និងជំហានសម្រាប់តែ PR នៅក្នុង lint របស់ `ci.yml` សម្រាប់ PR→`main`; ព្រមទាំង hook `commit-msg` របស់ husky ផងដែរ; អនុញ្ញាតឱ្យមានសហអ្នកនិពន្ធជាមនុស្ស; #14436) | +| `check:vitest-exclusions` | រាល់ការដកចេញពី Vitest ត្រូវបញ្ជាក់ tracking issue និងមាននៅក្នុង `config/quality/vitest-exclusions.json` (#13204) | បាទ | +| `check:file-size` | គ្មានឯកសារ source ណាមួយលើសពីកម្រិតអតិបរមាតាម extension (ratchet: ឯកសារធំដែលបានបង្កកនៅក្នុងបញ្ជី `frozen`) | បាទ | +| `check:error-helper` | Error responses នៅក្នុង executors/handlers ប្រើ `buildErrorBody()` / `sanitizeErrorMessage()` (ច្បាប់តឹងរ៉ឹង #12) | បាទ | +| `check:migration-numbering` | ឯកសារ Migration SQL ត្រូវបានដាក់លេខរៀងបន្តបន្ទាប់ ដោយគ្មានលេខខ្វះ ឬលេខស្ទួន | បាទ/ចាស | +| `check:public-creds` | មិនមានតម្លៃ OAuth `client_id`/`client_secret` ឬ Firebase Web keys ដែលសរសេរផ្ទាល់នៅខាងក្រៅ `publicCreds.ts` ទេ (វិធានតឹងរ៉ឹង #11) | បាទ/ចាស | +| `check:db-rules` | មិនមាន SQL ដើមនៅខាងក្រៅម៉ូឌុល `src/lib/db/` ទេ; មិនមាន barrel-imports ពី `localDb.ts` ទេ (វិធានតឹងរ៉ឹង #2/#5) | បាទ/ចាស | +| `check:known-symbols` | កម្មវិធីប្រតិបត្តិរបស់ Provider យុទ្ធសាស្ត្រកំណត់ផ្លូវ និងកម្មវិធីបកប្រែដែលបានចុះបញ្ជីក្នុងតារាង dispatch របស់ពួកវា ត្រូវគ្នានឹងឯកសារនៅលើថាស — មិនមាននិមិត្តសញ្ញាដែលគ្មានម្ចាស់ ឬមិនបានប្រកាសទេ | បាទ/ចាស | +| `check:route-guard-membership` | គ្រប់ route ដែលបង្កើត child process ត្រូវបានចាត់ថ្នាក់ដោយ `isLocalOnlyPath()` (វិធានតឹងរ៉ឹង #15/#17) | បាទ/ចាស | +| `check:test-discovery` | គ្រប់ឯកសារ `*.test.ts` / `*.spec.ts` ក្នុង repo ត្រូវបានប្រមូលដោយ test runner យ៉ាងហោចណាស់មួយ (ratchet៖ បញ្ជីឯកសារគ្មានម្ចាស់ក្នុង `test-discovery-baseline.json` អាចតែថយចុះប៉ុណ្ណោះ) | បាទ/ចាស | +| `check:agent-skills-sync` | វត្ថុសិប្បនិម្មិត agent-skills ដែលបានបង្កើតត្រូវគ្នានឹងកាតាឡុកប្រភពរបស់វា (គ្មានភាពខុសគ្នា) | +| `check:provider-asset-provenance` | ឡូហ្គោ/ទ្រព្យសកម្មរបស់អ្នកផ្តល់សេវាមានកំណត់ត្រាប្រភពដើម | +| `lint:json` | ឯកសារកំណត់រចនាសម្ព័ន្ធ JSON អាចញែកបាន និងអនុលោមតាមច្បាប់ lint របស់ repo | +| `typecheck:core` | ការចងក្រង TypeScript ដោយគ្មានកំហុស (មានតែការព្រមានជាលក្ខណៈណែនាំប៉ុណ្ណោះ) | បាទ/ចាស | +| `typecheck:noimplicit:core` | `noImplicitAny` ដ៏តឹងរ៉ឹង — ផ្តោតទៅអនាគត; ទីតាំងហៅដែលមានស្រាប់ជាច្រើននៅតែត្រូវការចំណារពន្យល់ប្រភេទ | **ជាលក្ខណៈណែនាំ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ដែលកំណត់វិសាលភាពត្រឹម `src/app/(dashboard)/**` (#7033) — បញ្ជីអនុញ្ញាត 27 ឯកសារដែលបានជ្រើសរើសរបស់ `typecheck:core` មិនរួមបញ្ចូល dashboard TSX ណាមួយទេ ហើយ `next build` ក៏មិនដែលពិនិត្យប្រភេទរបស់វាដែរ (`next.config.mjs` កំណត់ `ignoreBuildErrors: true`) ដូច្នេះ ការថយចុះគុណភាពពាក់ព័ន្ធនឹង identifier ដែលកំព្រានៅទីនោះ (#6625/#6909) មិនអាចមើលឃើញដោយ CI បានទេ។ ប្រៀបធៀបភាពខុសគ្នាជាមួយ baseline ចំនួនកូដ TS ក្នុងមួយឯកសារដែលបានបង្កក (`config/quality/dashboard-typecheck-baseline.json`, លំនាំអនុវត្តភាពហួសសម័យដូចគ្នានឹង `check:known-symbols`) — មានតែកំហុសថ្មីដែលលើសពីចំនួនក្នុង baseline ប៉ុណ្ណោះដែលធ្វើឱ្យ gate បរាជ័យ; កាត់បន្ថយជាបន្តបន្ទាប់ដោយប្រើ `--update` នៅពេលកំហុសដែលមានស្រាប់ត្រូវបានជួសជុល។ | បាទ/ចាស | + +### កិច្ចការ៖ `quality-gate` + +ដំណើរការបន្ទាប់ពី `test-coverage`។ ទប់ស្កាត់ការបញ្ចូលបញ្ចូលគ្នា នៅពេលបរាជ័យ។ + +| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `quality:collect` | បង្កើត `quality-metrics.json` (ចំនួនការព្រមាន ESLint និង coverage ពីរបាយការណ៍ shard ដែលបានបញ្ចូលគ្នា) | បាទ/ចាស (ដំណើរការមុន ratchet) | +| `quality:ratchet` | ម៉ែត្រនីមួយៗក្នុង `quality-baseline.json` មិនបានថយចុះ (ការព្រមាន ESLint ≤ baseline; coverage ≥ baseline) | បាទ/ចាស | +| `check:duplication` | ការស្ទួនកូដ (jscpd@4) មិនលើស baseline ក្នុង `quality-baseline.json` | បាទ/ចាស | +| `check:complexity` | ភាពស្មុគស្មាញ cyclomatic កម្រិតឯកសារមិនលើសកម្រិតកំណត់ (ESLint `complexity` ស្នូល + `max-lines-per-function`) | បាទ/ចាស | +| `check:cognitive-complexity` | ratchet ភាពស្មុគស្មាញផ្នែកការគិត (`eslint-plugin-sonarjs`) — ការដំណើរការ ESLint ដាច់ដោយឡែក; CI ដំណើរការទាំងពីរដោយបញ្ចូលគ្នាជាជំហាន `check:complexity-ratchets` តែមួយ | បាទ/ចាស | +| `check:dead-code` | ratchet សម្រាប់ export / ឯកសារដែលមិនបានប្រើ (knip) មិនថយចុះធៀបនឹង baseline | បាទ/ចាស | +| `check:compression-budget` | ថវិកា benchmark នៃការបង្ហាប់ — កម្រិតអប្បបរមានៃការសន្សំ token សម្រាប់ engine នីមួយៗមិនត្រូវថយចុះ | បាទ/ចាស | +| `check:type-coverage` | ratchet ភាគរយដែលបានកំណត់ type (`type-coverage`) មិនថយចុះ; ជាទូទៅគ្របដណ្ដប់លើ `typecheck:noimplicit:core` | បាទ/ចាស | +| `check:codeql-ratchet` | ចំនួនការជូនដំណឹង CodeQL ដែលនៅបើកមិនថយក្រោយ (អានតាម `gh api`; រំលងដោយសុវត្ថិភាពពេលគ្មាន token) — សម្រាប់ចន្លោះពេល refresh និងការចាប់ផ្ដើមដោយដៃ៖ សូមមើល "CodeQL ratchet" ខាងក្រោម | បាទ/ចាស | + +### Job: `quality-extended` + +Job ទាំងមូលមានលក្ខណៈផ្ដល់យោបល់ (`continue-on-error: true`)។ ratchet ដែលផ្អែកលើ npm ដំណើរការ +ជាក់ស្ដែង; scanner ខាងក្រៅត្រូវបានដំឡើងតាម `gh release download` ហើយរំលងខ្លួនឯង (exit 0) +នៅពេលនៅតែគ្មាន binary។ + +| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| `check:circular-deps` | មិនមាន dependency ជារង្វង់ (dpdm) | **ផ្ដល់យោបល់** | +| `check:bundle-size` | ទំហំ bundle មិនលើសកម្រិតកំណត់ | **ផ្ដល់យោបល់** | +| `check:secrets` | ស្កេនរក secret (gitleaks) — រំលងប្រសិនបើគ្មាន binary | **ផ្ដល់យោបល់** | +| `check:vuln-ratchet` | ភាពងាយរងគ្រោះនៃ dependency (osv-scanner) មិនថយក្រោយ — រំលងប្រសិនបើគ្មាន binary | **ផ្ដល់យោបល់** | +| `check:workflows` | ពិនិត្យ workflow (actionlint + zizmor); scanner ដែលបាត់/ខូច របាយការណ៍មិនត្រឹមត្រូវ ឬគ្មាន ratchet baseline នឹងបរាជ័យជា INCOMPLETE។ បញ្ហាដែលរកឃើញត្រឹមត្រូវអនុវត្តតាមគោលការណ៍ strict/advisory/ratchet ដែលបានជ្រើសរើស | តម្រូវឱ្យប្រតិបត្តិ; zizmor ratchet រារាំងក្នុង CI | +| `check:openapi-breaking` | ការផ្លាស់ប្ដូរដែលធ្វើឱ្យខូចភាពឆបគ្នានៃកិច្ចសន្យា API សាធារណៈ (`openapi.yaml`) ធៀបនឹង branch មូលដ្ឋាន (oasdiff) — បង្កើត `openapiBreaking=N`; រំលងប្រសិនបើគ្មាន oasdiff ឬមិនអាចដោះស្រាយ spec មូលដ្ឋានបាន | **ផ្ដល់យោបល់** | + +### Job: `docs-sync-strict` + +ដំណើរការលើរាល់ PR ទៅ `main`។ រារាំងការបញ្ចូលចូលគ្នាប្រសិនបើបរាជ័យ។ + +| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| `check:docs-all` | ច្រកមេតាដែលដំណើរការច្រករងទាំង 6 ខាងក្រោមតាមលំដាប់ | បាទ/ចាស | +| ↳ `check:docs-sync` | ភាពស៊ីសង្វាក់គ្នានៃកំណែ CHANGELOG / OpenAPI / llm.txt | បាទ/ចាស | +| ↳ `check:docs-counts` | ចំនួននៅក្នុងអត្ថបទ (ចំនួនអ្នកផ្តល់សេវា ចំនួនការធ្វើ migration ជាដើម) ស្ថិតនៅក្នុងចន្លោះ ratchet នៃចំនួនពិត | បាទ/ចាស | +| ↳ `check:env-doc-sync` | អថេរបរិស្ថាននីមួយៗក្នុង `.env.example` ត្រូវបានចងក្រងជាឯកសារនៅក្នុងតារាងឯកសារ ហើយផ្ទុយមកវិញ | បាទ/ចាស | +| ↳ `check:deprecated-versions` | មិនមានខ្សែអក្សរកំណែដែលបានឈប់គាំទ្រនៅក្នុងឯកសារ | បាទ/ចាស | +| ↳ `check:doc-links` | តំណ markdown ខាងក្នុងនៅក្នុងឯកសារអាចនាំទៅកាន់ឯកសារពិត (`[text]`/`(path)` form) | បាទ/ចាស | +| ↳ `check:fabricated-docs` | Routes អថេរបរិស្ថាន ពាក្យបញ្ជា CLI ឈ្មោះ hook និងផ្លូវឯកសារដែលបានយោងក្នុងឯកសារ មានពិតនៅក្នុង codebase។ ជាច្រកតឹងរ៉ឹងតាមរយៈ `--strict`; បរាជ័យបែបទន់បើគ្មាន flag។ | បាទ/ចាស (តាមរយៈ `--strict` ក្នុង CI) | +| `check:cli-i18n` | ខ្សែអក្សរពាក្យបញ្ជា CLI មាននៅក្នុងឯកសារ locale i18n ទាំងអស់ | បាទ/ចាស | +| `check:openapi-coverage` | សេចក្តីបញ្ជាក់ OpenAPI គ្របដណ្តប់យ៉ាងហោចណាស់ដល់កម្រិតអប្បបរមាបែប ratchet នៃ routes ពិត | បាទ/ចាស | +| `check:openapi-security-tiers` | សេចក្តីសម្គាល់កម្រិតសុវត្ថិភាពនៅក្នុង `openapi.yaml` ស៊ីសង្វាក់គ្នាជាមួយចំណាត់ថ្នាក់ក្នុង `routeGuard.ts` | **ជាការណែនាំ** | +| `check:openapi-routes` | គ្រប់ path នៅក្នុង `openapi.yaml` អាចនាំទៅកាន់ `route.ts` ពិត (ការពារការប្រឌិតព័ត៌មាន) | បាទ/ចាស | +| `check:docs-symbols` | គ្រប់ឯកសារយោង `/api/...` នៅក្នុង `docs/**/*.md` អាចនាំទៅកាន់ `route.ts` ពិត (ការពារការប្រឌិតព័ត៌មាន) | បាទ/ចាស | +| `i18n translation drift` | key ដែលមិនបានបកប្រែនៅក្នុងឯកសារ locale i18n — គ្រាន់តែព្រមានប៉ុណ្ណោះ | **ជាការណែនាំ** | ### កិច្ចការ៖ `i18n-ui-coverage` -| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | -| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (ក្នុងបន្ទាត់) | អត្រាគ្របដណ្តប់ key i18n របស់ UI គឺ ≥ 65% | បាទ/ចាស | -| `check-ui-value-drift` (ក្នុងបន្ទាត់) | **តម្លៃ**ជាភាសាអង់គ្លេសដែលត្រូវបានសរសេរឡើងវិញ មិនបន្សល់ទុកការបកប្រែចាស់ណាមួយទេ | បាទ/ចាស | -| `check-new-key-coverage` (ក្នុងបន្ទាត់) | Key ភាសាអង់គ្លេស**ថ្មី**ត្រូវបានបកប្រែក្នុងគ្រប់ locale — សញ្ញាសម្គាល់ `__MISSING__:` ត្រូវបានបដិសេធ | បាទ/ចាស | -| `check-translation-ratio` | អនុបាតការបកប្រែពិតក្នុង locale នីមួយៗ (តម្លៃដូចគ្នានឹងភាសាអង់គ្លេស / placeholder / ធាតុដែលបាត់នៅក្រៅបញ្ជីអនុញ្ញាត) មិនត្រូវលើសពី `config/quality/i18n-translation-baseline.json` + កម្រិតបន្ធូរបន្ថយឡើយ | **ជាការណែនាំ** | +| ស្គ្រីប | ផ្ទៀងផ្ទាត់ | រារាំង | +| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (ក្នុងបន្ទាត់) | ការគ្របដណ្តប់ key i18n របស់ UI គឺ ≥ 65% | បាទ/ចាស | +| `check-ui-value-drift` (ក្នុងបន្ទាត់) | **តម្លៃ** ភាសាអង់គ្លេសដែលបានសរសេរឡើងវិញ មិនបន្សល់ទុកការបកប្រែហួសសម័យឡើយ | បាទ/ចាស | +| `check-new-key-coverage` (ក្នុងបន្ទាត់) | key ភាសាអង់គ្លេស **ថ្មី** ត្រូវបានបកប្រែក្នុងគ្រប់ locale — marker `__MISSING__:` នឹងត្រូវបានបដិសេធ | បាទ/ចាស | +| `check-translation-ratio` | អនុបាតការបកប្រែពិតក្នុងមួយ locale (ស្លឹកដែលដូចគ្នានឹងភាសាអង់គ្លេស / placeholder / បាត់ នៅក្រៅ allowlist) មិនត្រូវលើសពី `config/quality/i18n-translation-baseline.json` + កម្រិតបន្ធូរ | **ជាការណែនាំ** | -តម្រូវឱ្យមាន `fetch-depth: 0` — ច្រកត្រួតពិនិត្យ value-drift ធ្វើ diff លើ `en.json` ធៀបនឹង merge base។ +ត្រូវការ `fetch-depth: 0` — ច្រក value-drift ធ្វើ diff លើ `en.json` ធៀបនឹង merge base។ -#### `check-ui-value-drift` — ច្រកត្រួតពិនិត្យការបកប្រែចាស់ +#### `check-ui-value-drift` — ច្រកការបកប្រែហួសសម័យ -ចាប់បាន regression i18n មួយប្រភេទដែលច្រកត្រួតពិនិត្យផ្សេងទៀតមិនអាចមើលឃើញតាមរចនាសម្ព័ន្ធបាន៖ តម្លៃជាភាសាអង់គ្លេស -ត្រូវបានសរសេរឡើងវិញ ខណៈការបកប្រែដែលផ្អែកលើភាសាអង់គ្លេស_ពីមុន_នៅតែមាន ដូច្នេះ -អ្នកប្រើប្រាស់ដែលមិនប្រើភាសាអង់គ្លេសនៅតែអានអត្ថបទដែលសរសេរយ៉ាងច្បាស់លាស់ ប៉ុន្តែឥឡូវនេះខុស។ +ចាប់បាន regression i18n មួយប្រភេទដែលច្រកផ្សេងៗមិនអាចមើលឃើញតាមរចនាសម្ព័ន្ធ៖ តម្លៃភាសាអង់គ្លេស +ត្រូវបានសរសេរឡើងវិញ ខណៈការបកប្រែដែលបានបង្កើតពីភាសាអង់គ្លេស _មុន_ នៅតែមាន ដូច្នេះ +អ្នកប្រើប្រាស់ដែលមិនប្រើភាសាអង់គ្លេសនៅតែអានអត្ថបទដែលមានទម្រង់ជឿជាក់ ប៉ុន្តែឥឡូវនេះខុស។ -បញ្ហានេះពិតជាត្រូវបានចេញផ្សាយមែន។ `oauthModal.googleOAuthWarning` ត្រូវបានសរសេរឡើងវិញ នៅពេលកម្មវិធីជំនួយចូលប្រើ Antigravity -ត្រូវបានដាក់ឱ្យប្រើ (#5203); **39 ក្នុងចំណោម 43 locale** នៅតែរក្សាអត្ថបទដែលប្រាប់អ្នកប្រតិបត្តិការឱ្យ "ចម្លង -URL ពេញលេញ ហើយបិទភ្ជាប់វានៅខាងក្រោម" — ជាលំហូរដែលមិនអាចបញ្ចប់បានសម្រាប់អ្នកផ្តល់សេវានោះ។ វា -មិនត្រូវបានរកឃើញរហូតដល់ #8463 ពីព្រោះ៖ +បញ្ហានេះពិតជាបានចេញផ្សាយទៅអ្នកប្រើប្រាស់។ `oauthModal.googleOAuthWarning` ត្រូវបានសរសេរឡើងវិញ នៅពេលកម្មវិធីជំនួយចូលប្រើ Antigravity +ត្រូវបានដាក់បញ្ចូល (#5203); **39 ក្នុងចំណោម 43 locales** នៅតែរក្សាអត្ថបទដែលប្រាប់អ្នកប្រតិបត្តិឱ្យ "ចម្លង +URL ពេញលេញ ហើយបិទភ្ជាប់វាខាងក្រោម" — ជាលំហូរដែលមិនអាចបញ្ចប់បានសម្រាប់អ្នកផ្តល់សេវានោះ។ វា +មិនត្រូវបានកត់សម្គាល់រហូតដល់ #8463 ដោយសារតែ៖ -- `sync-ui-keys` បំពេញបន្ថែមតែ key ដែល**មិនមាន**ប៉ុណ្ណោះ មិនមែន key ដែល**ចាស់**ទេ; -- `check-ui-keys-coverage` រាប់_វត្តមាន_របស់ key ដូច្នេះការបកប្រែចាស់ត្រូវបានចាត់ទុកថាបានគ្របដណ្តប់; -- `check-translation-drift` តាមដានឯកសារឆ្លុះបញ្ចាំងនៃឯកសារ `docs/i18n//**.md` — - វាមិនដែលអាន `src/i18n/messages/*.json` ទេ។ ជាការរារាំងក្នុងកិច្ចការ `docs-sync-strict` ចាប់តាំងពី - ការធ្វើសមកាលកម្មឡើងវិញ 2026-09៖ កែសម្រួលឯកសារស្នូល → `npm run i18n:run -- --files=` (តាមកម្រិតផ្នែក ចំណាយធនធានតិច)។ +- `sync-ui-keys` បំពេញតែ key ដែល **អវត្តមាន** ប៉ុណ្ណោះ មិនដែលបំពេញ key ដែល **ហួសសម័យ** ឡើយ; +- `check-ui-keys-coverage` រាប់ _វត្តមាន_ របស់ key ដូច្នេះការបកប្រែហួសសម័យត្រូវបានរាប់ថាបានគ្របដណ្តប់; +- `check-translation-drift` តាមដានឯកសារចម្លងនៃ documentation ក្នុង `docs/i18n//**.md` — + វាមិនដែលអាន `src/i18n/messages/*.json` ទេ។ បានរារាំងក្នុងកិច្ចការ `docs-sync-strict` ចាប់តាំងពី + ការធ្វើ re-sync ឆ្នាំ 2026-09៖ កែសម្រួលឯកសារស្នូល → `npm run i18n:run -- --files=` (កម្រិត section ចំណាយតិច)។ **យល់ដឹងអំពី diff មិនមែនផ្អែកលើ baseline ទេ។** វាប្រៀបធៀប `en.json` នៅ merge base ជាមួយនឹង -working tree; សម្រាប់ key នីមួយៗដែលតម្លៃភាសាអង់គ្លេសបានផ្លាស់ប្តូរ locale ណាមួយដែលនៅតែមាន -ការបកប្រែមិនទាន់បានកែប្រែ ត្រូវបានចាត់ទុកថាហួសសម័យ។ វាចេតនា **បង្កកបំណុលដែលមានស្រាប់** — diff -មិនអាចបង្ហាញថាការបកប្រែដែលមានជាយូរមកហើយនោះបានមកពីអត្ថបទភាសាអង់គ្លេសចាស់មួយណាទេ ដូច្នេះ gate វាយតម្លៃ +working tree; សម្រាប់ key នីមួយៗដែលតម្លៃជាភាសាអង់គ្លេសបានផ្លាស់ប្តូរ locale ណាមួយដែលនៅតែមាន +ការបកប្រែមិនបានកែប្រែ នឹងត្រូវចាត់ទុកថាហួសសុពលភាព។ វាមានចេតនា **បង្កកបំណុលដែលមានស្រាប់** — diff +មិនអាចបង្ហាញថាការបកប្រែដែលមានជាយូរមកហើយបានមកពីអត្ថបទភាសាអង់គ្លេសចាស់មួយណាទេ ដូច្នេះ gate វាយតម្លៃ តែអ្វីដែលការផ្លាស់ប្តូរបច្ចុប្បន្នប៉ះពាល់ប៉ុណ្ណោះ។ ជម្រើសផ្សេងទៀត (baseline hash សម្រាប់ key នីមួយៗ) នឹងត្រូវការ -ឯកសារដែលបានបង្កើតទំហំប្រហែល ~600 KB ដែលធំជាង baseline ដែលមានស្រាប់ធំបំផុត 3× ហើយប្រែប្រួលនៅរាល់ i18n PR។ +ឯកសារដែលបានបង្កើតទំហំប្រហែល 600 KB ដែលមានទំហំធំជាង baseline ធំបំផុតបច្ចុប្បន្ន 3 ដង ហើយផ្លាស់ប្តូររាល់ i18n PR។ មានពីរវិធីដើម្បីបំពេញលក្ខខណ្ឌនេះ៖ 1. ធ្វើបច្ចុប្បន្នភាពការបកប្រែដែលរងផលប៉ះពាល់ ឬ -2. កំណត់ពួកវាទៅជា `__MISSING__:` — បន្ទាប់មក runtime នឹងបង្ហាញអត្ថបទភាសាអង់គ្លេសដែលបានកែតម្រូវ - (`src/i18n/request.ts::deepMergeFallback`, #7258) ហើយដាក់ key ចូលជួររង់ចាំសម្រាប់ការបកប្រែ។ +2. កំណត់តម្លៃពួកវាទៅជា `__MISSING__:` — បន្ទាប់មក runtime នឹងផ្តល់អត្ថបទភាសាអង់គ្លេសដែលបានកែត្រឹមត្រូវ + (`src/i18n/request.ts::deepMergeFallback`, #7258) ហើយ key នោះនឹងចូលជួររង់ចាំសម្រាប់ការបកប្រែ។ ប្រសិនបើ **អត្ថន័យ** របស់ string បានផ្លាស់ប្តូរ គួរតែជ្រើសរើស **ប្តូរឈ្មោះ key**៖ key ថ្មីមិនអាចទទួលបន្ត -ការបកប្រែហួសសម័យបានទេ។ នេះជាគំរូដែល #8463 បានប្រើ។ +ការបកប្រែដែលហួសសុពលភាពបានទេ។ នេះជាគំរូដែល #8463 បានប្រើ។ ```bash npm run i18n:check-value-drift # តឹងរ៉ឹង (អ្វីដែល CI ដំណើរការ) @@ -231,48 +231,48 @@ npm run i18n:check-value-drift:warn # រាយការណ៍តែប៉ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -បញ្ចប់ដោយលេខកូដ 0 ជាមួយ `SKIP reason=base-unresolved` នៅពេលមិនអាចអាន catalog មូលដ្ឋានបាន (shallow -clone ដែលគ្មាន base ref) ដោយធ្វើតាមឥរិយាបថរបស់ `check-openapi-breaking`។ +ចាកចេញដោយលេខកូដ 0 ជាមួយ `SKIP reason=base-unresolved` នៅពេលមិនអាចអាន catalog មូលដ្ឋានបាន (shallow +clone ដែលគ្មាន base ref) ដោយឆ្លុះបញ្ចាំងឥរិយាបថរបស់ `check-openapi-breaking`។ ### Job៖ `i18n` -ម៉ាទ្រីសផ្ទៀងផ្ទាត់ i18n ពេញលេញ (មួយ job ក្នុងមួយ locale)។ job ទាំងមូលគ្រាន់តែជាការណែនាំ។ +ម៉ាទ្រីសត្រួតពិនិត្យ i18n ពេញលេញ (មួយ job សម្រាប់ locale នីមួយៗ)។ job ទាំងមូលគឺជាការណែនាំ។ -| Script | ផ្ទៀងផ្ទាត់ | ការរារាំង | -| ------------------------------- | --------------------------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | ភាពពេញលេញនៃការបកប្រែក្នុង locale នីមួយៗ | **ជាការណែនាំ** (`continue-on-error: true` លើ job ទាំងមូល) | +| Script | ផ្ទៀងផ្ទាត់ | ការរារាំង | +| ------------------------------- | ----------------------------------------- | --------------------------------------------------------- | +| `validate_translation.py quick` | ភាពពេញលេញនៃការបកប្រែសម្រាប់ locale នីមួយៗ | **ជាការណែនាំ** (`continue-on-error: true` លើ job ទាំងមូល) | ### Job៖ `pr-test-policy` ដំណើរការតែលើ pull request ប៉ុណ្ណោះ។ -| Script | ផ្ទៀងផ្ទាត់ | ការរារាំង | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | PR ដែលផ្លាស់ប្តូរ production code ក្នុង `src/`, `open-sse/`, `electron/`, ឬ `bin/` ត្រូវតែរួមបញ្ចូល ឬធ្វើបច្ចុប្បន្នភាព test (វិធានតឹងរ៉ឹង #8) | បាទ/ចាស | -| `check:test-masking` | ឯកសារ test ដែលបានផ្លាស់ប្តូរមិនកាត់បន្ថយចំនួន assert សរុបសុទ្ធ ឬបន្ថែម tautology `assert.ok(true)` ទេ | បាទ/ចាស | -| `check:pr-evidence` | ខ្លឹមសារ PR យោងភស្តុតាង test/VPS សម្រាប់ការផ្លាស់ប្តូរ (អនុវត្តវិធានតឹងរ៉ឹង #18 ដោយ grep អត្ថបទ PR — ងាយខូច សូមមើល Backlog) | បាទ/ចាស | +| Script | ផ្ទៀងផ្ទាត់ | ការរារាំង | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------- | +| `check:pr-test-policy` | PR ដែលផ្លាស់ប្តូរ production code ក្នុង `src/`, `open-sse/`, `electron/` ឬ `bin/` ត្រូវតែបញ្ចូល ឬធ្វើបច្ចុប្បន្នភាព test (Hard Rule #8) | បាទ/ចាស | +| `check:test-masking` | ឯកសារ test ដែលបានផ្លាស់ប្តូរមិនបន្ថយចំនួន assert សុទ្ធ ឬបន្ថែម tautology `assert.ok(true)` ទេ | បាទ/ចាស | +| `check:pr-evidence` | ខ្លឹមសារ PR យោងភស្តុតាង test/VPS សម្រាប់ការផ្លាស់ប្តូរ (ធ្វើឱ្យ Hard Rule #18 ដំណើរការដោយ grep លើអត្ថបទ PR — ងាយខូច សូមមើល Backlog) | បាទ/ចាស | ### Job៖ `test-vitest` -ដំណើរការបន្ទាប់ពី `build`។ រារាំងការបញ្ចូល merge នៅពេលបរាជ័យ។ +ដំណើរការបន្ទាប់ពី `build`។ រារាំងការ merge នៅពេលបរាជ័យ។ -| Suite | ផ្ទៀងផ្ទាត់ | ការរារាំង | -| ---------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (ឧបករណ៍ 110), autoCombo, cache — vitest runner | បាទ/ចាស | -| `test:vitest:ui` | test សមាសភាគ UI — vitest runner | **រារាំង** — failure ដែលមានស្រាប់ត្រូវបានដកចេញយ៉ាងច្បាស់ក្នុង `vitest.config.ts`; failure ថ្មីធ្វើឱ្យ job បរាជ័យ | +| Suite | ផ្ទៀងផ្ទាត់ | ការរារាំង | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | បាទ/ចាស | +| `test:vitest:ui` | test សមាសភាគ UI — vitest runner | **រារាំង** — failure ដែលមានស្រាប់ត្រូវបានដកចេញយ៉ាងច្បាស់ក្នុង `vitest.config.ts`; failure ថ្មីនឹងធ្វើឱ្យ job បរាជ័យ | -### Workflow ប្រចាំយប់ (កំណត់ពេល និងជាការណែនាំ) +### Workflow ប្រចាំយប់ (បានកំណត់ពេល ជាការណែនាំ) -Workflow ទាំងនេះដំណើរការតាមកាលវិភាគ cron (និង `workflow_dispatch`) មិនដែលដំណើរការលើ PR ទេ។ ទាំងអស់គ្រាន់តែជាការណែនាំ។ +ទាំងនេះដំណើរការតាមកាលវិភាគ cron (និង `workflow_dispatch`) ហើយមិនដំណើរការលើ PR ទេ។ ទាំងអស់គឺជាការណែនាំ។ -| Workflow | ផ្ទៀងផ្ទាត់ | ការរារាំង | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | property test របស់ fast-check ជាមួយ random seed + ចំនួនដងដំណើរការខ្ពស់ | **ជាការណែនាំ** | -| `nightly-resilience` | gate សម្រាប់ការកើនឡើងនៃ heap, ការបញ្ចូល fault បែប chaos, load/soak របស់ k6 | **ជាការណែនាំ** | -| `nightly-llm-security` | ការការពារ injection របស់ promptfoo (block mode) + probe របស់ garak (រំលងប្រសិនបើគ្មាន provider secret) | **ជាការណែនាំ** | -| `nightly-schemathesis` | ការធ្វើ fuzzing លើ contract OpenAPI (schemathesis) ទល់នឹង OmniRoute ដែលកំពុងដំណើរការ ដោយប្រើ `docs/openapi.yaml` — បង្ហាញការបំពាន spec / 500 ដែលមិនបានដោះស្រាយ (ដំណាក់កាល 8 B.4) | **ជាការណែនាំ** | -| `nightly-mutation` | ពិន្ទុ mutation-testing របស់ Stryker លើ lane unit រហ័ស — mutant ដែលរស់រានបង្ហាញពី assert ខ្សោយ | **ជាការណែនាំ** | -| `nightly-compat` | ម៉ាទ្រីសភាពឆបគ្នារបស់ Node engine នៅទូទាំងចន្លោះ `engines.node` ដែលបានគាំទ្រ | **ជាការណែនាំ** | +| Workflow | ផ្ទៀងផ្ទាត់ | ការរារាំង | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | property test របស់ fast-check ជាមួយ random seed + ចំនួនដំណើរការខ្ពស់ | **ជាការណែនាំ** | +| `nightly-resilience` | gate កំណើន heap, ការបញ្ចូល fault បែប chaos, load/soak របស់ k6 | **ជាការណែនាំ** | +| `nightly-llm-security` | ឧបករណ៍ការពារ injection របស់ promptfoo (block mode) + probe របស់ garak (រំលងបើគ្មាន provider secret) | **ជាការណែនាំ** | +| `nightly-schemathesis` | ការ fuzz contract OpenAPI (schemathesis) ប្រឆាំងនឹង OmniRoute ដែលកំពុងដំណើរការ ដោយប្រើ `docs/openapi.yaml` — បង្ហាញការបំពាន spec / error 500 ដែលមិនបានដោះស្រាយ (Fase 8 B.4) | **ជាការណែនាំ** | +| `nightly-mutation` | ពិន្ទុ mutation testing របស់ Stryker លើ lane unit test លឿន — mutant ដែលនៅរស់បង្ហាញពី assert ខ្សោយ | **ជាការណែនាំ** | +| `nightly-compat` | ម៉ាទ្រីសភាពឆបគ្នារបស់ Node engine នៅទូទាំងចន្លោះ `engines.node` ដែលបានគាំទ្រ | **ជាការណែនាំ** | --- @@ -536,43 +536,43 @@ Job នេះមិនដែល push ទៅ `release/*` ទេ — មនុស --- -## បញ្ជីការងាររង់ចាំសម្រាប់ការរៀបចំសមហេតុផល (ការពិនិត្យ ROI — ដំណាក់កាល 9 រលក 3) +## បញ្ជីការងាររង់ចាំសម្រាប់ការរៀបចំឱ្យសមហេតុផល (ការពិនិត្យ ROI — ដំណាក់កាលទី 9 រលកទី 3) បញ្ជីសារពើភណ្ឌនេះត្រូវបានផ្ទៀងផ្ទាត់ជាមួយ `ci.yml` នៅថ្ងៃទី 2026-06-17 (កំណែមុនបានរំលង `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`)។ ការពិនិត្យ ROI លើសំណុំដែលបានផ្ទៀងផ្ទាត់ -បានកំណត់ឃើញបេក្ខភាពសម្រាប់ការរៀបចំសមហេតុផលដូចខាងក្រោម។ **ការបញ្ចូលគ្នាទាំងនេះគឺជា -ការផ្លាស់ប្តូរ CI បែបមេកានិច ចំណែកការប្តូរ/លុបចោលគឺជាការសម្រេចចិត្តផ្នែកគោលនយោបាយ -ដែលទុកជូនអ្នកប្រតិបត្តិ។** មិនទាន់មានអ្វីខាងក្រោមត្រូវបានអនុវត្តនៅឡើយទេ។ +បានកំណត់ឃើញបេក្ខភាពខាងក្រោមសម្រាប់ការរៀបចំឱ្យសមហេតុផល។ **ការបញ្ចូលគ្នាគឺជាការផ្លាស់ប្តូរ CI +បែបមេកានិច ចំណែកការប្តូរ/លុបគឺជាការសម្រេចចិត្តផ្នែកគោលនយោបាយដែលទុកឱ្យប្រតិបត្តិករ។** មិនទាន់មានអ្វី +ខាងក្រោមត្រូវបានអនុវត្តនៅឡើយទេ។ -**អ្វីដែលមិនបានចងក្រងជាឯកសារនៅខាងលើផងដែរ** (ជាការណែនាំ សញ្ញាខ្សោយ)៖ ការងារ `docs-lint` -(markdownlint + Vale ដោយការងារទាំងមូលប្រើ `continue-on-error`) និង workflow ស្កេនដាច់ដោយឡែក +**អ្វីដែលមិនបានចងក្រងជាឯកសារនៅខាងលើផងដែរ** (ជាការណែនាំ សញ្ញាខ្សោយ)៖ job `docs-lint` +(markdownlint + Vale, job ទាំងមូលប្រើ `continue-on-error`) និង workflow ស្កេនដាច់ដោយឡែក `semgrep.yml` / `codeql.yml` / `scorecard.yml`។ `semgrepFindings: 0` មាននៅក្នុង -`quality-baseline.json` ប៉ុន្តែមិនត្រូវបានភ្ជាប់ទៅនឹង ratchet ដែលទប់ស្កាត់នៅក្នុង `ci.yml` ទេ — ម៉ែត្រនេះ -បច្ចុប្បន្នគ្មានការតភ្ជាប់។ +`quality-baseline.json` ប៉ុន្តែមិនត្រូវបានភ្ជាប់ទៅ ratchet ដែលរារាំងនៅក្នុង `ci.yml` ទេ — metric នេះ +បច្ចុប្បន្ននៅឯកោ។ ### បញ្ចូលគ្នា / លុបភាពស្ទួន (បែបមេកានិច ហានិភ័យទាបជាង) -បេក្ខភាពនីមួយៗត្រូវបានផ្ទៀងផ្ទាត់ជាមួយស្ថានភាព gate ជាក់ស្តែងនៅថ្ងៃទី 2026-06-17 (ជឿ ប៉ុន្តែត្រូវផ្ទៀងផ្ទាត់); -ការបញ្ចូលគ្នាមួយចំនួនដែលមើលទៅ «ច្បាស់លាស់» បែរជាលាក់បំណុល ហើយ **មិនមែន** ជាជម្រើសជំនួសដោយផ្ទាល់ដែលស្អាតនោះទេ។ - -- **`check:docs-sync` ដំណើរការពីរដង** — ដាច់ដោយឡែកនៅក្នុងការងារ `lint` ហើយម្តងទៀតនៅខាងក្នុង `check:docs-all` (`docs-sync-strict`) និង husky pre-commit hook។ ✅ **រួចរាល់** — បានដកការហៅដំណើរការ `lint` ដាច់ដោយឡែកចេញ។ -- **ការស្កេន CVE** — ❌ **មិនមែនជាការបញ្ចូលគ្នាដែលស្អាតទេ។** `audit:deps` បរាជ័យភ្លាមៗនៅពេលមាន CVE កម្រិតខ្ពស់/ធ្ងន់ធ្ងរណាមួយ; `check:vuln-ratchet` (osv) បរាជ័យតែលើ _ការថយចុះ_ ធៀបនឹង baseline ប៉ុណ្ណោះ (បច្ចុប្បន្នមាន 1 MODERATE)។ អត្ថន័យខុសគ្នា — ការលុប `audit:deps` នឹងធ្វើឱ្យបាត់ gate ដាច់ខាតសម្រាប់កម្រិតខ្ពស់/ធ្ងន់ធ្ងរ។ រក្សាទុកទាំងពីរ។ -- **ការរកឃើញវដ្ត** — ❌ **មិនមែនជាការបញ្ចូលគ្នាដែលស្អាតទេ។** `check:circular-deps` (dpdm) រាយការណ៍ **91 វដ្ត** (នេះហើយជាមូលហេតុដែលវាគ្រាន់តែជាការណែនាំ); វាមិនអាចត្រូវបានដំឡើងទៅជាការទប់ស្កាត់បានទេ ដោយមិនដោះស្រាយវដ្តទាំងនោះជាមុន ហើយវាមានវិសាលភាពទូលំទូលាយជាង `check:cycles` ដែលបានជ្រើសរើសយ៉ាងច្បាស់លាស់ និងមានស្ថានភាពបៃតង។ រក្សា `check:cycles` ជាការទប់ស្កាត់; ការដោះស្រាយវដ្ត dpdm ទាំង 91 គឺជាបញ្ជីការងាររង់ចាំដាច់ដោយឡែក។ -- **ភាពស្មុគស្មាញ** — ✅ **រួចរាល់** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)៖ ការស្កេន ESLint មួយដង រាប់តាម ruleId ដូច្នេះ baseline សម្រាប់ cyclomatic+max-lines និង cognitive នៅតែឯករាជ្យពីគ្នា; `check:complexity` / `check:cognitive-complexity` នីមួយៗនៅតែរក្សាទុកសម្រាប់ `--update` ក្នុងមូលដ្ឋាន។ -- **ការប្រឆាំងការប្រឌិតព័ត៌មានសម្រាប់ `/api`** — ✅ **រួចរាល់** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)៖ បញ្ជីសារពើភណ្ឌ FS មួយនៃ `src/app/api` ខណៈ openapi-routes + docs-symbols នៅតែរាយការណ៍ដោយឯករាជ្យ; ការត្រួតពិនិត្យនីមួយៗនៅតែរក្សាទុកសម្រាប់ការដំណើរការក្នុងមូលដ្ឋាន។ -- **`check:node-runtime` ដំណើរការក្នុងការងារ 11** — ⚠️ **ROI ទាប។** ការងារនីមួយៗមាន runner ដាច់ដោយឡែក ហើយការត្រួតពិនិត្យចំណាយពេល <1s; ការសន្សំសរុបប្រហែល ~10s បើធៀបនឹងការបាត់បង់របាំងការពារថោកមួយសម្រាប់ការងារនីមួយៗ។ មិនសមនឹងការរំខានពីការផ្លាស់ប្តូរទេ។ -- **`typecheck:noimplicit:core` នៅលើ CI lint** — ✅ **បានដកចេញពីការងារ lint** (ពីមុនជាការណែនាំដោយប្រើ `continue-on-error`); ផ្ទៃប្រភេទដែលទប់ស្កាត់គឺ `typecheck:core` + `check:type-coverage`។ ស្គ្រីបក្នុងមូលដ្ឋានត្រូវបានរក្សាទុក។ - -### ប្តូរ / សម្រេចចិត្ត (គោលនយោបាយរបស់អ្នកប្រតិបត្តិ) - -- `check:openapi-security-tiers` (ជាការណែនាំ) — ❌ **មិនអាចប្តូរបានដោយស្អាតទេ។** វាបញ្ចប់ដោយលេខកូដ 0 ប៉ុន្តែព្រមានថា route `traffic-inspector` មួយចំនួននៅក្រោម `LOCAL_ONLY_API_PREFIXES` ខ្វះ annotation `x-loopback-only: true`។ ការអនុវត្តវាជាកាតព្វកិច្ច តម្រូវឱ្យបន្ថែម annotation ទាំងនោះទៅក្នុង `openapi.yaml` ជាមុន។ -- `typecheck:noimplicit:core` (ជាការណែនាំ) — ភាគច្រើនត្រូវបានគ្របដណ្តប់ដោយ ratchet `check:type-coverage` ដែលទប់ស្កាត់។ ប្តូរទៅជា ratchet ឬលុបការដំណើរការ `tsc` លើកទីពីរដែលស្ទួន។ -- `test:vitest:ui` (ឥឡូវ **ទប់ស្កាត់**) — ការបរាជ័យដែលមានស្រាប់ត្រូវបានដកចេញយ៉ាងច្បាស់នៅក្នុង `vitest.config.ts` ដោយមានមតិយោបល់តាមដាន `// #8618`; ការបរាជ័យថ្មីនឹងធ្វើឱ្យការងារបរាជ័យ។ -- `check:secrets` (gitleaks, ratchet ទប់ស្កាត់ដែលត្រូវបានកំណត់ថេរនៅលទ្ធផលវិជ្ជមានក្លែងក្លាយ 3 ដែលបានចងក្រងជាឯកសារ) — ដាក់ 3 នោះក្នុង allowlist ដើម្បីឱ្យដល់ 0 ឬបន្ថយទៅជាការណែនាំ។ វាត្រួតស៊ីគ្នាជាមួយការស្កេន secret ដើមរបស់ GitHub + `check:public-creds`។ -- `check:pr-evidence` (ទប់ស្កាត់ និងស្វែងរកអត្ថបទក្នុងតួ PR ដោយ grep) — មានហានិភ័យខ្ពស់នៃលទ្ធផលវិជ្ជមានក្លែងក្លាយ; ប្រសិនបើលុប វានឹងធ្វើឱ្យការអនុវត្ត Hard Rule #18 ចុះខ្សោយ ដូច្នេះនេះពិតជាការសម្រេចចិត្តផ្នែកគោលនយោបាយ។ -- `semgrep` (ដំណើរការដាច់ដោយឡែកជាការណែនាំ) — ត្រួតស៊ីគ្នាជាមួយ CodeQL សម្រាប់ក្រុម OWASP; ភ្ជាប់ baseline របស់វាទៅនឹង ratchet ឬលុបចោល។ +បេក្ខភាពនីមួយៗត្រូវបានផ្ទៀងផ្ទាត់ជាមួយស្ថានភាព gate ជាក់ស្តែងនៅថ្ងៃទី 2026-06-17 (ទុកចិត្ត ប៉ុន្តែត្រូវផ្ទៀងផ្ទាត់); +ការបញ្ចូលគ្នាដែលមើលទៅ "ជាក់ស្តែង" មួយចំនួន បែរជាលាក់បំណុល ហើយ **មិនមែន** ជាការជំនួសដោយផ្ទាល់ដែលគ្មានបញ្ហាទេ។ + +- **`check:docs-sync` ដំណើរការពីរដង** — ដាច់ដោយឡែកនៅក្នុង job `lint` និងម្តងទៀតនៅក្នុង `check:docs-all` (`docs-sync-strict`) ព្រមទាំង husky pre-commit hook។ ✅ **រួចរាល់** — invocation ដាច់ដោយឡែកក្នុង `lint` ត្រូវបានដកចេញ។ +- **ការស្កេន CVE** — ❌ **មិនមែនជាការបញ្ចូលគ្នាដែលគ្មានបញ្ហាទេ។** `audit:deps` បរាជ័យភ្លាមៗលើ CVE កម្រិត high/critical ណាមួយ; `check:vuln-ratchet` (osv) បរាជ័យតែលើ _ការធ្លាក់ចុះ_ ធៀបនឹង baseline ប៉ុណ្ណោះ (បច្ចុប្បន្នមាន 1 MODERATE)។ អត្ថន័យខុសគ្នា — ការលុប `audit:deps` នឹងធ្វើឱ្យបាត់បង់ gate ដាច់ខាតសម្រាប់កម្រិត high/critical។ រក្សាទុកទាំងពីរ។ +- **ការរកឃើញវដ្ត** — ✅ **រួចរាល់** (#15159 G-01/G-02)។ អត្ថបទចាស់នៅទីនេះបានហៅ `check:cycles` ថាជា gate "ពណ៌បៃតង ដែលបានជ្រើសរើសយ៉ាងប្រុងប្រយ័ត្ន" និងបានលើកហេតុផលឱ្យរក្សាវាជា blocking ព្រោះ `check:circular-deps` (dpdm) បានរាយការណ៍វដ្តចំនួន 91។ ស្ថានភាពពណ៌បៃតងនោះគឺជា **ភាពវិជ្ជមានក្លែងក្លាយ**៖ `check:cycles` បានស្កេនថតរងចំនួន 5 (450 files), ផ្គូផ្គងតែ `import|export … from` បែប static ហើយបានបោះបង់រាល់ specifier `@/` និង `@omniroute/open-sse/` ដូច្នេះវាមិនអាចមើលឃើញវដ្ត dynamic-import + alias ដែលមានច្រើនជាងគេក្នុង repo បានទេ។ បានកែរួច៖ ឥឡូវ gate ដើរឆ្លងកាត់ `src` + `open-sse` (5023 files), ប្រមូល specifier ពី TypeScript AST (ដូច្នេះ `import("…")` ត្រូវបានរាប់ ខណៈ `typeof import("…")` នៅទីតាំង type មិនត្រូវបានរាប់) ហើយ resolve `paths` របស់ tsconfig។ វារកឃើញវដ្តចំនួន **14** មិនមែន 0 ទេ។ ដោយសារវដ្តដែលមានស្រាប់ចំនួន 14 មិនអាចត្រូវបានជួសជុលនៅក្នុង gate PR បាន `check:cycles` ឥឡូវនេះគឺជា **ratchet** (`--ratchet`, ពិដាន `metrics.cycles.value = 14` ក្នុង `quality-baseline.json`, `direction: down`) — វារារាំង _ការធ្លាក់ចុះ_ ណាមួយ ហើយចំនួននេះអាចតែថយចុះប៉ុណ្ណោះ។ CI ដំណើរការ `npm run check:cycles:ratchet`។ ការកាត់បន្ថយជាបន្តបន្ទាប់ទៅជាមួយ **A-01**។ `check:circular-deps` (dpdm) នៅតែជាការណែនាំក្នុងនាមជាមតិទីពីរដែលទូលំទូលាយជាង។ +- **ភាពស្មុគស្មាញ** — ✅ **រួចរាល់** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)៖ ការដើរឆ្លងកាត់ ESLint មួយដង រាប់តាម ruleId ដើម្បីឱ្យ baseline របស់ cyclomatic+max-lines និង cognitive នៅដាច់ពីគ្នា; `check:complexity` / `check:cognitive-complexity` រៀងៗខ្លួននៅតែរក្សាទុកសម្រាប់ `--update` នៅមូលដ្ឋាន។ +- **ការប្រឆាំងការបំភាន់សម្រាប់ `/api`** — ✅ **រួចរាល់** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)៖ បញ្ជីសារពើភណ្ឌ FS មួយនៃ `src/app/api`, openapi-routes + docs-symbols នៅតែរាយការណ៍ដោយឯករាជ្យ; មុខងាររៀងៗខ្លួននៅតែរក្សាទុកសម្រាប់ការដំណើរការនៅមូលដ្ឋាន។ +- **`check:node-runtime` ដំណើរការនៅក្នុង 11 jobs** — ⚠️ **ROI ទាប។** Job នីមួយៗប្រើ runner ដាច់ដោយឡែក ហើយការត្រួតពិនិត្យចំណាយពេល <1s; ការសន្សំសរុប ~10s ប៉ុន្តែត្រូវបាត់បង់ guard ក្នុងមួយ job ដែលមានតម្លៃថោក។ មិនសមនឹងការរំខានដោយការផ្លាស់ប្តូរទេ។ +- **`typecheck:noimplicit:core` លើ CI lint** — ✅ **ត្រូវបានដកចេញពី job lint** (ពីមុនជាការណែនាំដោយប្រើ `continue-on-error`); ផ្ទៃ type ដែលជា blocking គឺ `typecheck:core` + `check:type-coverage`។ Script នៅមូលដ្ឋានត្រូវបានរក្សាទុក។ + +### ប្តូរ / សម្រេចចិត្ត (គោលនយោបាយរបស់ប្រតិបត្តិករ) + +- `check:openapi-security-tiers` (ជាការណែនាំ) — ❌ **មិនអាចប្តូរបានដោយគ្មានបញ្ហាទេ។** វាបញ្ចប់ដោយលេខកូដ 0 ប៉ុន្តែព្រមានថា route `traffic-inspector` មួយចំនួននៅក្រោម `LOCAL_ONLY_API_PREFIXES` ខ្វះ annotation `x-loopback-only: true`។ ការបង្ខំអនុវត្តវាតម្រូវឱ្យបន្ថែម annotation ទាំងនោះទៅក្នុង `openapi.yaml` ជាមុនសិន។ +- `typecheck:noimplicit:core` (ជាការណែនាំ) — ភាគច្រើនត្រូវបានគ្របដណ្តប់ដោយ ratchet `check:type-coverage` ដែលជា blocking រួចហើយ។ ប្តូរទៅជា ratchet ឬលុប pass `tsc` ទីពីរដែលស្ទួន។ +- `test:vitest:ui` (ឥឡូវជា **blocking**) — failure ដែលមានស្រាប់ត្រូវបានដកចេញយ៉ាងច្បាស់នៅក្នុង `vitest.config.ts` ជាមួយ comment តាមដាន `// #8618`; failure ថ្មីធ្វើឱ្យ job បរាជ័យ។ +- `check:secrets` (gitleaks, blocking ratchet ដែលបានកំណត់ថេរនៅលទ្ធផលវិជ្ជមានក្លែងក្លាយចំនួន 3 ដែលមានឯកសារពន្យល់) — ដាក់ 3 នោះក្នុង allowlist ដើម្បីឱ្យដល់ 0 ឬបន្ថយទៅជាការណែនាំ។ ត្រួតគ្នាជាមួយការស្កេន secret ដើមរបស់ GitHub + `check:public-creds`។ +- `check:pr-evidence` (blocking, ប្រើ greps លើអត្ថបទក្នុង PR body) — មានហានិភ័យ false-positive ខ្ពស់; ប្រសិនបើលុប វានឹងធ្វើឱ្យការអនុវត្ត Hard Rule #18 ចុះខ្សោយ ដូច្នេះនេះជាការសម្រេចចិត្តផ្នែកគោលនយោបាយពិតប្រាកដ។ +- `semgrep` (standalone ជាការណែនាំ) — ត្រួតគ្នាជាមួយ CodeQL សម្រាប់ក្រុម OWASP; ភ្ជាប់ baseline របស់វាទៅ ratchet ឬលុបចេញ។ --- diff --git a/docs/i18n/kn/CONTRIBUTING.md b/docs/i18n/kn/CONTRIBUTING.md index dbda93e3e43..7948751d39b 100644 --- a/docs/i18n/kn/CONTRIBUTING.md +++ b/docs/i18n/kn/CONTRIBUTING.md @@ -398,22 +398,22 @@ model definitions ಅನ್ನು `open-sse/config/providerRegistry.ts` ನಲ --- -## Pull Request ಪರಿಶೀಲನಾಪಟ್ಟಿ - -- [ ] Tests ಯಶಸ್ವಿಯಾಗುತ್ತವೆ (`npm test`) -- [ ] Linting ಯಶಸ್ವಿಯಾಗುತ್ತದೆ (`npm run lint`) -- [ ] Build ಯಶಸ್ವಿಯಾಗುತ್ತದೆ (`npm run build`) -- [ ] ಹೊಸ public functions ಮತ್ತು interfaces ಗಾಗಿ TypeScript types ಸೇರಿಸಲಾಗಿದೆ -- [ ] hardcoded secrets ಅಥವಾ fallback values ಇಲ್ಲ -- [ ] Public upstream credentials ಅನ್ನು `resolvePublicCred()` ಮೂಲಕ embed ಮಾಡಲಾಗಿದೆ ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ನೋಡಿ), literals ಆಗಿ ಎಂದಿಗೂ ಅಲ್ಲ -- [ ] Error responses ಗಳು `buildErrorBody()` / `sanitizeErrorMessage()` ಮೂಲಕ ಹಾದುಹೋಗುತ್ತವೆ — response bodies ನಲ್ಲಿ ಕಚ್ಚಾ stack traces ಇಲ್ಲ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ನೋಡಿ) -- [ ] Shell commands (`exec` / `spawn`) runtime values ಅನ್ನು string interpolation ಮೂಲಕವಲ್ಲ, `env` ಮೂಲಕ ರವಾನಿಸುತ್ತವೆ -- [ ] ಎಲ್ಲಾ inputs ಅನ್ನು Zod schemas ಮೂಲಕ ಮೌಲ್ಯೀಕರಿಸಲಾಗಿದೆ -- [ ] ಬಳಕೆದಾರರಿಗೆ ಗೋಚರಿಸುವ ಬದಲಾವಣೆಗಳಿಗಾಗಿ `changelog.d/{features|fixes|maintenance}/-.md` ಅಡಿಯಲ್ಲಿ Changelog **fragment** ಸೇರಿಸಲಾಗಿದೆ ([`changelog.d/README.md`](./changelog.d/README.md) ನೋಡಿ) — `CHANGELOG.md` ಅನ್ನು ನೇರವಾಗಿ **ತಿದ್ದುಪಡಿ ಮಾಡಬೇಡಿ**; fragments ಅನ್ನು release ಸಮಯದಲ್ಲಿ ಒಟ್ಟುಗೂಡಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಅವು PR ಗಳ ನಡುವೆ ಎಂದಿಗೂ ಸಂಘರ್ಷಿಸುವುದಿಲ್ಲ -- [ ] Documentation ನವೀಕರಿಸಲಾಗಿದೆ (ಅನ್ವಯಿಸಿದರೆ) -- [ ] ಯಾವುದೇ ಹೊಸ CodeQL / Secret-Scanning alerts ತೆರೆಯಲಾಗಿಲ್ಲ, ಅಥವಾ ಪ್ರತಿಯೊಂದನ್ನೂ ಸಂಬಂಧಿತ `docs/security/` doc ಅನ್ನು ಉಲ್ಲೇಖಿಸುವ ತಾಂತ್ರಿಕ ಸಮರ್ಥನೆಯೊಂದಿಗೆ ವಜಾಗೊಳಿಸಲಾಗಿದೆ -- [ ] child processes ಅನ್ನು spawn ಮಾಡುವ routes (`/api/mcp/`, `/api/cli-tools/runtime/`) ಅನ್ನು `src/server/authz/routeGuard.ts` ನಲ್ಲಿ `isLocalOnlyPath()` ಎಂದು ವರ್ಗೀಕರಿಸಲಾಗಿದೆ — [ಕಠಿಣ ನಿಯಮ #15](docs/security/ROUTE_GUARD_TIERS.md) ನೋಡಿ -- [ ] commit messages ನಲ್ಲಿ `Co-Authored-By` trailers ಇಲ್ಲ — commits ಗಳು repository ಮಾಲೀಕರ Git identity ಅಡಿಯಲ್ಲಿ ಮಾತ್ರ ಕಾಣಿಸಬೇಕು (ಕಠಿಣ ನಿಯಮ #16) +## ಪುಲ್ ರಿಕ್ವೆಸ್ಟ್ ಪರಿಶೀಲನಾ ಪಟ್ಟಿ + +- [ ] ಪರೀಕ್ಷೆಗಳು ಯಶಸ್ವಿಯಾಗುತ್ತವೆ (`npm test`) +- [ ] ಲಿಂಟಿಂಗ್ ಯಶಸ್ವಿಯಾಗುತ್ತದೆ (`npm run lint`) +- [ ] ಬಿಲ್ಡ್ ಯಶಸ್ವಿಯಾಗುತ್ತದೆ (`npm run build`) +- [ ] ಹೊಸ ಸಾರ್ವಜನಿಕ ಫಂಕ್ಷನ್ಗಳು ಮತ್ತು ಇಂಟರ್ಫೇಸ್ಗಳಿಗೆ TypeScript ಟೈಪ್ಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ +- [ ] ಹಾರ್ಡ್ಕೋಡ್ ಮಾಡಿದ ರಹಸ್ಯಗಳು ಅಥವಾ ಪರ್ಯಾಯ ಮೌಲ್ಯಗಳಿಲ್ಲ +- [ ] ಸಾರ್ವಜನಿಕ ಅಪ್ಸ್ಟ್ರೀಮ್ ರುಜುವಾತುಗಳನ್ನು `resolvePublicCred()` ಮೂಲಕ ಎಂಬೆಡ್ ಮಾಡಲಾಗಿದೆ ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ನೋಡಿ), ಎಂದಿಗೂ ಲಿಟರಲ್ಗಳಾಗಿ ಅಲ್ಲ +- [ ] ದೋಷ ಪ್ರತಿಕ್ರಿಯೆಗಳನ್ನು `buildErrorBody()` / `sanitizeErrorMessage()` ಮೂಲಕ ರವಾನಿಸಲಾಗಿದೆ — ಪ್ರತಿಕ್ರಿಯೆ ಬಾಡಿಗಳಲ್ಲಿ ಕಚ್ಚಾ ಸ್ಟ್ಯಾಕ್ ಟ್ರೇಸ್ಗಳಿಲ್ಲ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ನೋಡಿ) +- [ ] ಶೆಲ್ ಕಮಾಂಡ್ಗಳು (`exec` / `spawn`) ರನ್ಟೈಮ್ ಮೌಲ್ಯಗಳನ್ನು ಸ್ಟ್ರಿಂಗ್ ಇಂಟರ್ಪೊಲೇಶನ್ ಮೂಲಕ ಅಲ್ಲ, `env` ಮೂಲಕ ರವಾನಿಸುತ್ತವೆ +- [ ] ಎಲ್ಲಾ ಇನ್ಪುಟ್ಗಳನ್ನು Zod ಸ್ಕೀಮಾಗಳೊಂದಿಗೆ ಮೌಲ್ಯೀಕರಿಸಲಾಗಿದೆ +- [ ] ಬಳಕೆದಾರರಿಗೆ ಗೋಚರಿಸುವ ಬದಲಾವಣೆಗಳಿಗಾಗಿ `changelog.d/{features|fixes|maintenance}/-.md` ಅಡಿಯಲ್ಲಿ ಚೇಂಜ್ಲಾಗ್ **ಫ್ರ್ಯಾಗ್ಮೆಂಟ್** ಸೇರಿಸಲಾಗಿದೆ ([`changelog.d/README.md`](./changelog.d/README.md) ನೋಡಿ) — `CHANGELOG.md` ಅನ್ನು ನೇರವಾಗಿ ಸಂಪಾದಿಸ**ಬೇಡಿ**; ಫ್ರ್ಯಾಗ್ಮೆಂಟ್ಗಳನ್ನು ಬಿಡುಗಡೆ ಸಮಯದಲ್ಲಿ ಒಟ್ಟುಗೂಡಿಸಲಾಗುತ್ತದೆ ಮತ್ತು PRಗಳ ನಡುವೆ ಎಂದಿಗೂ ಸಂಘರ್ಷಿಸುವುದಿಲ್ಲ +- [ ] ದಸ್ತಾವೇಜನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ (ಅನ್ವಯಿಸಿದರೆ) +- [ ] ಯಾವುದೇ ಹೊಸ CodeQL / Secret-Scanning ಎಚ್ಚರಿಕೆಗಳನ್ನು ತೆರೆಯಲಾಗಿಲ್ಲ, ಅಥವಾ ಪ್ರತಿಯೊಂದನ್ನೂ ಸಂಬಂಧಿತ `docs/security/` ದಸ್ತಾವೇಜನ್ನು ಉಲ್ಲೇಖಿಸುವ ತಾಂತ್ರಿಕ ಸಮರ್ಥನೆಯೊಂದಿಗೆ ವಜಾಗೊಳಿಸಲಾಗಿದೆ +- [ ] ಚೈಲ್ಡ್ ಪ್ರೊಸೆಸ್ಗಳನ್ನು ಸ್ಪಾನ್ ಮಾಡುವ ರೂಟ್ಗಳನ್ನು (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` ನಲ್ಲಿನ `isLocalOnlyPath()` ಆಗಿ ವರ್ಗೀಕರಿಸಲಾಗಿದೆ — [ಕಠಿಣ ನಿಯಮ #15](docs/security/ROUTE_GUARD_TIERS.md) ನೋಡಿ +- [ ] ಕಮಿಟ್ ಸಂದೇಶಗಳಲ್ಲಿ AI/ಬಾಟ್ `Co-authored-by` ಟ್ರೇಲರ್ಗಳಿಲ್ಲ (ಕಠಿಣ ನಿಯಮ #16) — ಮರುಬಳಕೆ ಮಾಡಲಾದ ಕೆಲಸದ ಮಾನವ ಸಹಯೋಗಿಗಳಿಗೆ ಪ್ರಮಾಣಿತ `Co-authored-by: Name ` ಟ್ರೇಲರ್ಗಳೊಂದಿಗೆ ಮನ್ನಣೆ ನೀಡಲಾಗಿದೆ --- diff --git a/docs/i18n/kn/docs/architecture/QUALITY_GATES.md b/docs/i18n/kn/docs/architecture/QUALITY_GATES.md index 969b176cb06..04c3cbf5c3e 100644 --- a/docs/i18n/kn/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/kn/docs/architecture/QUALITY_GATES.md @@ -19,259 +19,259 @@ ### ಅಭ್ಯರ್ಥಿ ಪ್ರವೇಶ -CI ಮತ್ತು Quality Gates ವರ್ಕ್ಫ್ಲೋಗಳು ಪ್ರತಿಯೊಂದೂ ಸ್ಥಿರ ತೀರ್ಪನ್ನು ಹೊರಸೂಸುತ್ತವೆ: `Gate / CI` ಮತ್ತು -`Gate / Quality`. ಅವುಗಳ ಆವೃತ್ತಿಗೊಳಿಸಿದ ಪ್ರವೇಶ ನೀತಿಯು ಪ್ರತಿಯೊಂದು ಅಪ್ಸ್ಟ್ರೀಮ್ ಜಾಬ್ ಅನ್ನು -ಕಡ್ಡಾಯ ಅಥವಾ ಸಲಹಾತ್ಮಕ ಎಂದು ಪಟ್ಟಿಮಾಡುತ್ತದೆ. ಅನ್ವಯವಾಗುವ ಕಡ್ಡಾಯ ಜಾಬ್ ಯಶಸ್ವಿಯಾಗಬೇಕು: ಕಾಣೆಯಾದ, -ರದ್ದಾದ, ಬಿಟ್ಟುಬಿಡಲಾದ, ಬಾಕಿಯಿರುವ ಮತ್ತು ಅಜ್ಞಾತ ಫಲಿತಾಂಶಗಳು PASS ಅನ್ನು ಸ್ಥಾಪಿಸಲಾರವು. ಮಾನ್ಯವಾದ +CI ಮತ್ತು Quality Gates ವರ್ಕ್ಫ್ಲೋಗಳು ಪ್ರತಿಯೊಂದೂ ಸ್ಥಿರ ತೀರ್ಪನ್ನು ನೀಡುತ್ತವೆ: `Gate / CI` ಮತ್ತು +`Gate / Quality`. ಅವುಗಳ ಆವೃತ್ತಿಗೊಳಿಸಲಾದ ಪ್ರವೇಶ ನೀತಿಯು ಪ್ರತಿ ಅಪ್ಸ್ಟ್ರೀಮ್ ಜಾಬ್ ಅನ್ನು +ಕಡ್ಡಾಯ ಅಥವಾ ಸಲಹಾತ್ಮಕ ಎಂದು ಪಟ್ಟಿ ಮಾಡುತ್ತದೆ. ಅನ್ವಯವಾಗುವ ಕಡ್ಡಾಯ ಜಾಬ್ ಯಶಸ್ವಿಯಾಗಬೇಕು: ಕಾಣೆಯಾದ, +ರದ್ದಾದ, ಸ್ಕಿಪ್ ಆದ, ಬಾಕಿ ಇರುವ ಮತ್ತು ಅಜ್ಞಾತ ಫಲಿತಾಂಶಗಳು PASS ಅನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಮಾನ್ಯವಾದ docs-only ಅಥವಾ catalog-only ವರ್ಗೀಕರಣವು ಕೋಡ್ ಲೇನ್ ಅನ್ನು ಅನ್ವಯವಾಗದಂತೆ ಮಾಡಬಹುದು; -ಕರಡು PR ಅಂಗೀಕೃತ ಅಭ್ಯರ್ಥಿಯಲ್ಲ. `hotfix` ಲೇಬಲ್ ಸಾಕ್ಷ್ಯದ ಅಗತ್ಯವನ್ನು ಮನ್ನಾ ಮಾಡುವುದಿಲ್ಲ. +ಡ್ರಾಫ್ಟ್ PR ಅನ್ನು ಅಂಗೀಕೃತ ಅಭ್ಯರ್ಥಿಯಾಗಿ ಪರಿಗಣಿಸಲಾಗುವುದಿಲ್ಲ. `hotfix` ಲೇಬಲ್ ಸಾಕ್ಷ್ಯದ ಅಗತ್ಯವನ್ನು ಮನ್ನಾ ಮಾಡುವುದಿಲ್ಲ. -ಎರಡೂ ವರ್ಕ್ಫ್ಲೋಗಳು PR-ಗಳು ಮತ್ತು main/release ಬ್ರಾಂಚ್ಗಳಿಗೆ ಪುಶ್ಗಳು, ಹಸ್ತಚಾಲಿತ ಡಿಸ್ಪ್ಯಾಚ್ ಹಾಗೂ -ಮರ್ಜ್-ಗ್ರೂಪ್ ಈವೆಂಟ್ಗಳನ್ನು ಒಳಗೊಳ್ಳುತ್ತವೆ. ಪುಶ್, ಡಿಸ್ಪ್ಯಾಚ್ ಮತ್ತು ಮರ್ಜ್-ಗ್ರೂಪ್ ಪೂರ್ಣ ಆಯ್ಕೆಯನ್ನು ಚಲಾಯಿಸುತ್ತವೆ. ಫೋರ್ಕ್ಗಳು -ಮತ್ತು ಮರ್ಜ್ ಗ್ರೂಪ್ಗಳು, ಸಾಮಾನ್ಯವಾಗಿ ಸ್ವಯಂ-ಹೋಸ್ಟ್ ಮಾಡಿದ ರನ್ನರ್ಗಳನ್ನು ಆಯ್ಕೆಮಾಡುವ ಜಾಬ್ಗಳಿಗೆ ಹೋಸ್ಟ್ ಮಾಡಿದ ರನ್ನರ್ಗಳನ್ನು -ಬಳಸುತ್ತವೆ; ರೋಲ್ಔಟ್ಗೆ ಮೊದಲು ಸಾಕಷ್ಟು ಹೋಸ್ಟ್ ಮಾಡಿದ ಸಾಮರ್ಥ್ಯವನ್ನು ಪರಿಶೀಲಿಸಬೇಕು. +ಎರಡೂ ವರ್ಕ್ಫ್ಲೋಗಳು PRಗಳು ಮತ್ತು main/release ಬ್ರಾಂಚ್ಗಳಿಗೆ ಪುಶ್ಗಳು, ಹಸ್ತಚಾಲಿತ dispatch ಹಾಗೂ +merge-group ಈವೆಂಟ್ಗಳನ್ನು ಒಳಗೊಳ್ಳುತ್ತವೆ. Push, dispatch ಮತ್ತು merge-group ಸಂಪೂರ್ಣ ಆಯ್ಕೆಯನ್ನು ಚಲಾಯಿಸುತ್ತವೆ. Forkಗಳು +ಮತ್ತು merge groupಗಳು, ಇಲ್ಲದಿದ್ದರೆ self-hosted ರನ್ನರ್ಗಳನ್ನು ಆಯ್ಕೆಮಾಡುವ ಜಾಬ್ಗಳಿಗೆ hosted ರನ್ನರ್ಗಳನ್ನು ಬಳಸುತ್ತವೆ; +ರೋಲ್ಔಟ್ಗೆ ಮೊದಲು ಸಾಕಷ್ಟು hosted ಸಾಮರ್ಥ್ಯವನ್ನು ಪರಿಶೀಲಿಸಬೇಕು. -ಪ್ರತಿ JSON ರಸೀದಿಯು ಚೆಕ್ಔಟ್ ಮಾಡಿದ SHA, ವರ್ಕ್ಫ್ಲೋ ರನ್ ಮತ್ತು ಪ್ರಯತ್ನವನ್ನು ಗುರುತಿಸುತ್ತದೆ. -ಚೆಕ್ಔಟ್/ಈವೆಂಟ್ SHA ಅಸಾಮ್ಯವನ್ನು CLI ತಿರಸ್ಕರಿಸುತ್ತದೆ. ವರ್ಕ್ಫ್ಲೋ ಪರೀಕ್ಷೆಗಳು ನೀತಿ ಸದಸ್ಯತ್ವವನ್ನು -ತೀರ್ಪು ಜಾಬ್ನ `needs` ಪಟ್ಟಿಗೆ ಬದ್ಧಗೊಳಿಸುತ್ತವೆ, ಆದ್ದರಿಂದ ಹೊಸ ಅಥವಾ ತೆಗೆದುಹಾಕಿದ ಲೇನ್ ಮೌನವಾಗಿ ಕಣ್ಮರೆಯಾಗಲು ಸಾಧ್ಯವಿಲ್ಲ. -ರಸೀದಿಗಳು ತಮ್ಮದೇ ವರ್ಕ್ಫ್ಲೋವನ್ನು ಒಳಗೊಳ್ಳುತ್ತವೆ, ಪ್ರಕಟಣೆ, ಡಿಪ್ಲಾಯ್ಮೆಂಟ್ ಅಥವಾ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ -ಸಲಹಾತ್ಮಕ ಸ್ಕ್ಯಾನರ್ನ ಆಂತರಿಕ ಅಂಶಗಳನ್ನಲ್ಲ. ಬ್ರಾಂಚ್ ನಿಯಮಗಳಲ್ಲಿ ಎರಡೂ ಚೆಕ್ ಹೆಸರುಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವುದು -ಪ್ರತ್ಯೇಕ ಆಡಳಿತಾತ್ಮಕ ಬದಲಾವಣೆಯಾಗಿದೆ; ಈ ಜಾಬ್ಗಳನ್ನು ಸೇರಿಸುವುದರಿಂದ ಮಾತ್ರ ಬ್ರಾಂಚ್ ರಕ್ಷಿತವಾಗುವುದಿಲ್ಲ. +ಪ್ರತಿ JSON ರಸೀದಿಯು ಚೆಕ್ಔಟ್ ಮಾಡಲಾದ SHA, ವರ್ಕ್ಫ್ಲೋ ರನ್ ಮತ್ತು ಪ್ರಯತ್ನವನ್ನು ಗುರುತಿಸುತ್ತದೆ. +ಚೆಕ್ಔಟ್/event SHA ಅಸಂಗತತೆಯನ್ನು CLI ತಿರಸ್ಕರಿಸುತ್ತದೆ. ವರ್ಕ್ಫ್ಲೋ ಪರೀಕ್ಷೆಗಳು ನೀತಿ ಸದಸ್ಯತ್ವವನ್ನು +ತೀರ್ಪು ಜಾಬ್ನ `needs` ಪಟ್ಟಿಗೆ ಬಿಗಿದಿಡುತ್ತವೆ, ಹೀಗಾಗಿ ಹೊಸದಾಗಿ ಸೇರಿಸಲಾದ ಅಥವಾ ತೆಗೆದುಹಾಕಲಾದ ಲೇನ್ ಮೌನವಾಗಿ ಕಣ್ಮರೆಯಾಗಲು ಸಾಧ್ಯವಿಲ್ಲ. +ರಸೀದಿಗಳು ತಮ್ಮದೇ ವರ್ಕ್ಫ್ಲೋವನ್ನು ಒಳಗೊಳ್ಳುತ್ತವೆ; ಪ್ರಕಟಣೆ, ನಿಯೋಜನೆ ಅಥವಾ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ +ಸಲಹಾತ್ಮಕ ಸ್ಕ್ಯಾನರ್ನ ಆಂತರಿಕ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಅಲ್ಲ. ಬ್ರಾಂಚ್ ನಿಯಮಗಳಲ್ಲಿ ಎರಡೂ ಚೆಕ್ ಹೆಸರುಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವುದು +ಪ್ರತ್ಯೇಕ ಆಡಳಿತಾತ್ಮಕ ಬದಲಾವಣೆಯಾಗಿದೆ; ಈ ಜಾಬ್ಗಳನ್ನು ಸೇರಿಸುವುದರಿಂದ ಮಾತ್ರ ಬ್ರಾಂಚ್ ಸಂರಕ್ಷಿತವಾಗುವುದಿಲ್ಲ. ### ಸ್ಥಿರ ಸ್ಕ್ಯಾನ್ ಇನ್ವೆಂಟರಿ -ಆವೃತ್ತಿಗೊಳಿಸಿದ npm-ಅಲಿಯಾಸ್ ಇನ್ವೆಂಟರಿ ಮತ್ತು ಸ್ಥಿರ-ಸ್ಕ್ಯಾನ್ ಸದಸ್ಯತ್ವವು -`config/quality/gate-manifest.json` ನಲ್ಲಿ ಇವೆ. ಸ್ಕ್ರಿಪ್ಟ್ ಹೆಸರುಗಳು ಮತ್ತು ನಿಖರ ಕಮಾಂಡ್ಗಳನ್ನು -`package.json` ವಿರುದ್ಧ ಮೌಲ್ಯೀಕರಿಸಲು `npm run check:gate-manifest` ಅನ್ನು ಚಲಾಯಿಸಿ; ಸೇರ್ಪಡೆಗಳು, ತೆಗೆದುಹಾಕುವಿಕೆಗಳು ಮತ್ತು -ಕಮಾಂಡ್ ವ್ಯತ್ಯಾಸಗಳು ಸ್ಥಳೀಯ ಹುಕ್ ಹಾಗೂ CI-ಯಲ್ಲಿನ ಬದಲಾವಣೆ-ವರ್ಗೀಕರಣ ಜಾಬ್ಗಳೆರಡನ್ನೂ ವಿಫಲಗೊಳಿಸುತ್ತವೆ. -ಅಲಿಯಾಸ್ ಎಂಬುದು ವರ್ಕ್ಫ್ಲೋ ಜಾಬ್, ಮ್ಯಾಟ್ರಿಕ್ಸ್ ಇನ್ಸ್ಟಾನ್ಸ್ ಅಥವಾ ಟೆಸ್ಟ್ ಕೇಸ್ ಅಲ್ಲ: ಈ ಎಣಿಕೆಗಳನ್ನು -ಪರಸ್ಪರ ವಿನಿಮಯಸಾಧ್ಯವೆಂದು ಪ್ರಸ್ತುತಪಡಿಸಬಾರದು. +ಆವೃತ್ತಿಗೊಳಿಸಲಾದ npm-alias ಇನ್ವೆಂಟರಿ ಮತ್ತು ಸ್ಥಿರ-ಸ್ಕ್ಯಾನ್ ಸದಸ್ಯತ್ವವು +`config/quality/gate-manifest.json` ನಲ್ಲಿವೆ. ಸ್ಕ್ರಿಪ್ಟ್ ಹೆಸರುಗಳು ಮತ್ತು ನಿಖರ ಕಮಾಂಡ್ಗಳನ್ನು +`package.json` ಗೆ ಹೋಲಿಸಿ ಮೌಲ್ಯೀಕರಿಸಲು `npm run check:gate-manifest` ಅನ್ನು ಚಲಾಯಿಸಿ; ಸೇರ್ಪಡೆಗಳು, ತೆಗೆದುಹಾಕುವಿಕೆಗಳು ಮತ್ತು +ಕಮಾಂಡ್ ವ್ಯತ್ಯಾಸಗಳು ಸ್ಥಳೀಯ hook ಮತ್ತು CIಯಲ್ಲಿನ ಬದಲಾವಣೆ-ವರ್ಗೀಕರಣ ಜಾಬ್ಗಳೆರಡನ್ನೂ ವಿಫಲಗೊಳಿಸುತ್ತವೆ. +alias ಎಂಬುದು ವರ್ಕ್ಫ್ಲೋ ಜಾಬ್, matrix instance ಅಥವಾ test case ಅಲ್ಲ: ಈ ಎಣಿಕೆಗಳನ್ನು +ಪರಸ್ಪರ ಬದಲಾಯಿಸಬಹುದಾದವುಗಳಂತೆ ಪ್ರಸ್ತುತಪಡಿಸಬಾರದು. -ಆಯ್ಕೆಮಾಡಿದ ಅಲಿಯಾಸ್ಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸದೆ ಪರಿಶೀಲಿಸಲು `npm run quality:scan -- --list` ಅಥವಾ `npm run quality:scan:fast -- --list` -ಬಳಸಿ. ರನ್ನರ್ npm ಎಂಟ್ರಿಪಾಯಿಂಟ್ ಅನ್ನು ಆಹ್ವಾನಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಅದರ ರನ್ಟೈಮ್ (ಕಾನ್ಫಿಗರ್ ಮಾಡಿರುವಲ್ಲಿ Bun ಸೇರಿದಂತೆ) ಉಳಿಯುತ್ತದೆ. -ಮ್ಯಾನಿಫೆಸ್ಟ್ ಆ ಪ್ರೊಫೈಲ್ಗಳ ಹೊರಗಿನ ಅಲಿಯಾಸ್ಗಳನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿ ಆಹ್ವಾನಿಸಲಾದವುಗಳೆಂದು ದಾಖಲಿಸುತ್ತದೆ, ಮತ್ತು +ಆಯ್ಕೆಮಾಡಲಾದ aliasಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸದೆ ಪರಿಶೀಲಿಸಲು `npm run quality:scan -- --list` ಅಥವಾ `npm run quality:scan:fast -- --list` +ಬಳಸಿ. ರನ್ನರ್ npm entrypoint ಅನ್ನು ಆವಾಹಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಅದರ runtime (ಕಾನ್ಫಿಗರ್ ಮಾಡಿರುವಲ್ಲಿ Bun ಸೇರಿದಂತೆ) ಉಳಿಯುತ್ತದೆ. +manifest ಆ ಪ್ರೊಫೈಲ್ಗಳ ಹೊರಗಿನ aliasಗಳನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿ ಆವಾಹಿಸಲಾದವುಗಳೆಂದು ದಾಖಲಿಸುತ್ತದೆ ಮತ್ತು ಓದಲು-ಮಾತ್ರವಾದ ಸ್ಕ್ಯಾನ್ ಪ್ರೊಫೈಲ್ಗಳಲ್ಲಿ ನಿರ್ವಹಣಾ ಕಮಾಂಡ್ಗಳನ್ನು ನಿಷೇಧಿಸಲಾಗಿದೆ. -ಈ ಪ್ರೊಫೈಲ್ಗಳು ಸ್ಥಿರ ಸ್ಕ್ಯಾನ್ ಅನ್ನು ಮಾತ್ರ ಒಳಗೊಳ್ಳುತ್ತವೆ. ಅವು ಉತ್ಪನ್ನ ಪರೀಕ್ಷೆಗಳು, -ಕವರೇಜ್, ಪ್ಯಾಕೇಜಿಂಗ್, ಬಾಹ್ಯ ಚೆಕ್ಗಳು ಅಥವಾ ಅಭ್ಯರ್ಥಿಯ ಸಂಪೂರ್ಣ ಬಿಡುಗಡೆ ಅಂಗೀಕಾರವನ್ನು ಪ್ರಮಾಣೀಕರಿಸುವುದಿಲ್ಲ. +ಈ ಪ್ರೊಫೈಲ್ಗಳು ಸ್ಥಿರ ಸ್ಕ್ಯಾನ್ ಅನ್ನು ಮಾತ್ರ ಒಳಗೊಳ್ಳುತ್ತವೆ. ಇವು ಉತ್ಪನ್ನ ಪರೀಕ್ಷೆಗಳು, +ವ್ಯಾಪ್ತಿ, ಪ್ಯಾಕೇಜಿಂಗ್, ಬಾಹ್ಯ ಚೆಕ್ಗಳು ಅಥವಾ ಅಭ್ಯರ್ಥಿಯ ಸಂಪೂರ್ಣ ಬಿಡುಗಡೆ ಅಂಗೀಕಾರವನ್ನು ಪ್ರಮಾಣೀಕರಿಸುವುದಿಲ್ಲ. ವರ್ಕ್ಫ್ಲೋ ಪ್ರವೇಶವು ಲಿಂಕ್ ಮಾಡಲಾದ `config/quality/admission-policy.json` ಮತ್ತು -`scripts/quality/admission-verdict.mjs` ಅನ್ನು ಬಳಸುತ್ತದೆ. ಬಿಡುಗಡೆ-ವೀಕ್ಷಕ ಪ್ರೊಫೈಲ್ಗಳು ಪ್ರತ್ಯೇಕವಾಗಿಯೇ ಉಳಿಯುತ್ತವೆ; -ಅವುಗಳಿಗೆ ಅನ್ವಯವಾಗುವ ಚೆಕ್ಗಳು ಮತ್ತು ರಸೀದಿಗಳನ್ನು ಸ್ವತಂತ್ರವಾಗಿ ಪರಿಶೀಲಿಸಿ. ಕೆಳಗಿನ ಗದ್ಯರೂಪದ -ಇನ್ವೆಂಟರಿ ಒಂದು ಉಲ್ಲೇಖವೇ ಹೊರತು, ಗೇಟ್ ನಿಜವಾಗಿಯೂ ಚಲಾಯಿತೆಂಬುದಕ್ಕೆ ಪುರಾವೆಯಲ್ಲ. +`scripts/quality/admission-verdict.mjs` ಅನ್ನು ಬಳಸುತ್ತದೆ. Release-observer ಪ್ರೊಫೈಲ್ಗಳು ಪ್ರತ್ಯೇಕವಾಗಿಯೇ ಉಳಿಯುತ್ತವೆ; +ಅವುಗಳ ಅನ್ವಯವಾಗುವ ಚೆಕ್ಗಳು ಮತ್ತು ರಸೀದಿಗಳನ್ನು ಸ್ವತಂತ್ರವಾಗಿ ಪರಿಶೀಲಿಸಿ. ಕೆಳಗಿನ ಗದ್ಯರೂಪದ +ಇನ್ವೆಂಟರಿ ಒಂದು ಉಲ್ಲೇಖವಾಗಿದೆ; ಗೇಟ್ ನಿಜವಾಗಿಯೂ ಚಲಾಯಿಸಲ್ಪಟ್ಟಿದೆ ಎಂಬುದಕ್ಕೆ ಪುರಾವೆಯಲ್ಲ. -ಸ್ಕ್ರಿಪ್ಟ್ಗಳು `scripts/check/` (ನೀತಿ ಗೇಟ್ಗಳು) ಮತ್ತು `scripts/quality/` (ರ್ಯಾಚೆಟ್ ಎಂಜಿನ್) ಅಡಿಯಲ್ಲಿ ಇವೆ. -CI-ಯ ಸತ್ಯದ ಮೂಲವು `.github/workflows/ci.yml` ಆಗಿದೆ. +ಸ್ಕ್ರಿಪ್ಟ್ಗಳು `scripts/check/` (ನೀತಿ ಗೇಟ್ಗಳು) ಮತ್ತು `scripts/quality/` (ratchet ಎಂಜಿನ್) ಅಡಿಯಲ್ಲಿ ಇವೆ. +CIಗೆ ಮೂಲ ಸತ್ಯವು `.github/workflows/ci.yml` ಆಗಿದೆ. ### ಬಿಡುಗಡೆ PR ವೇಗದ-ಮಾರ್ಗ (`quality.yml`) -`.github/workflows/quality.yml` main/release PR-ಗಳು, ರಕ್ಷಿತ-ಬ್ರಾಂಚ್ -ಪುಶ್ಗಳು, ಡಿಸ್ಪ್ಯಾಚ್ ಮತ್ತು ಮರ್ಜ್ ಗ್ರೂಪ್ಗಳಲ್ಲಿ CI-ಗೆ ಪೂರಕವಾಗಿರುತ್ತದೆ. PR-ಗಳು ಪಥ-ಫಿಲ್ಟರ್ ಮಾಡಿದ ವೇಗದ ಚೆಕ್ಗಳನ್ನು ಬಳಸುತ್ತವೆ. ಶಾಶ್ವತವಾಗಿ -ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದ ನಕಲಿ ಬಿಲ್ಡ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ; ನೈಜ ಬಿಲ್ಡ್/ಪ್ಯಾಕೇಜ್/ಬೂಟ್ ಚೆಕ್ಗಳು CI-ಯಲ್ಲಿಯೇ ಉಳಿದಿವೆ. - -| ಜಾಬ್ | ವ್ಯಾಪ್ತಿ | ತಡೆಯುವಿಕೆ | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | ಡಾಕ್ಸ್/ಕೋಡ್ PR-ಗಳು; API ಡಾಕ್ಸ್ ಉಲ್ಲೇಖಗಳು ಮತ್ತು docs-all | ಹೌದು | -| `Fast Quality Gates` | ಕೋಡ್ PR-ಗಳು; ಸ್ಥಿರ ಚೆಕ್ಗಳು, ಟೈಪ್ಚೆಕ್, ಡ್ಯಾಶ್ಬೋರ್ಡ್ ಟೈಪ್ಚೆಕ್, ಪರಿಣಾಮಕ್ಕೊಳಗಾದ ಯೂನಿಟ್ ಪರೀಕ್ಷೆಗಳು | ಹೌದು | -| `Forgotten sibling tests` | ಕೋಡ್ PR-ಗಳು; ಬದಲಾದ ಮಾಡ್ಯೂಲ್ಗಳಿಂದ ಸ್ಥಿರ ಬಳಕೆದಾರರು ಮತ್ತು ಸಂಭಾವ್ಯ ಸಹೋದರ ಪರೀಕ್ಷೆಗಳವರೆಗೆ ಪತ್ತೆಹಚ್ಚಲಾಗುತ್ತದೆ; ಬ್ಯಾರೆಲ್ ಮತ್ತು ಡೈನಾಮಿಕ್-ಇಂಪೋರ್ಟ್ ಪಥಗಳನ್ನು ಉಲ್ಲೇಖಿತ ಅಲೌಲೀಸ್ಟ್ ವಿನಾಯಿತಿಗಳೊಂದಿಗೆ ಸಲಹಾತ್ಮಕ ಡಯಾಗ್ನೋಸ್ಟಿಕ್ಗಳಾಗಿ ವರದಿ ಮಾಡಲಾಗುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | -| `Vitest (fast-path)` | ಕೋಡ್ PR-ಗಳು; ವೇಗದ vitest ಸೂಟ್ | ಹೌದು | -| `Unit Tests fast-path` | ಕೋಡ್ PR-ಗಳು; 4-ಶಾರ್ಡ್ ಯೂನಿಟ್ ಸೂಟ್ | ಹೌದು | -| `No new ESLint warnings` | ಕೋಡ್ PR-ಗಳು; ಸಪ್ರೆಷನ್ಗಳನ್ನು ಪರಿಗಣಿಸುವ ಲಿಂಟ್ ಗಾರ್ಡ್ | ಹೌದು, ಫೋರ್ಕ್ಗಳು ಸೇರಿದಂತೆ | -| `Merge integrity (changelog + generated skills)` | ಕರಡು ಅಲ್ಲದ PR-ಗಳು; ಚೇಂಜ್ಲಾಗ್ ಮತ್ತು ರಚಿಸಲಾದ ಸ್ಕಿಲ್ ಸಿಂಕ್ | ಹೌದು, ಫೋರ್ಕ್ಗಳು ಸೇರಿದಂತೆ | - -#### ಮರೆತುಹೋದ ಸಹೋದರ ಪರೀಕ್ಷೆಗಳ ವರದಿ - -`npm run check:forgotten-sibling-tests` ಪರೀಕ್ಷಾ-ಪರಿಣಾಮ ನಕ್ಷೆಯ ಹಿಂದಿರುವ ಇಂಪೋರ್ಟ್ ರಿಸಾಲ್ವರ್ ಅನ್ನು ಮರುಬಳಕೆ ಮಾಡುತ್ತದೆ. -ಬದಲಾದ ಪ್ರತಿಯೊಂದು ಪ್ರೊಡಕ್ಷನ್ ಮಾಡ್ಯೂಲ್ಗಾಗಿ, ಸಂಭಾವ್ಯ -ಪರೀಕ್ಷೆಯು ಪುಲ್-ರಿಕ್ವೆಸ್ಟ್ ಡಿಫ್ನಲ್ಲಿ ಇಲ್ಲದಿದ್ದಾಗ ಇದು ನಿರ್ಣಾಯಕ `changed module/symbol -> static consumer -> candidate sibling test` ಸರಪಳಿಗಳನ್ನು ವರದಿ ಮಾಡುತ್ತದೆ. -ಯಾವುದೇ ತಡೆಯುವ ರೋಲ್ಔಟ್ಗೆ ಮುನ್ನ ಕ್ಯಾಲಿಬ್ರೇಶನ್ಗಾಗಿ Markdown ಸಾರಾಂಶ ಮತ್ತು JSON ಫಲಿತಾಂಶವನ್ನು -`forgotten-sibling-tests` ವರ್ಕ್ಫ್ಲೋ ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ ಆಗಿ ಉಳಿಸಿಕೊಳ್ಳಲಾಗುತ್ತದೆ. - -ಬ್ಯಾರೆಲ್ ಮರು-ರಫ್ತುಗಳು ಮತ್ತು ಡೈನಾಮಿಕ್ ಆಮದುಗಳು ರೆಸಲ್ಯೂಷನ್ ಡಯಾಗ್ನೋಸ್ಟಿಕ್ಸ್ಗೆ ಮಾತ್ರ ಸೀಮಿತವಾಗಿವೆ; ಅವು ಎಂದಿಗೂ -ತಡೆಯುವ ಫಲಿತಾಂಶವನ್ನು ಸೃಷ್ಟಿಸುವುದಿಲ್ಲ. ಪರಿಶೀಲಿಸಲಾದ ವಿನಾಯಿತಿಗಳು -`config/quality/forgotten-sibling-allowlist.json` ನಲ್ಲಿ ಇರುತ್ತವೆ. ಪ್ರತಿ ನಮೂದಿನಲ್ಲಿ ಗ್ರಾಹಕ ಮತ್ತು ಅಭ್ಯರ್ಥಿ -ಪರೀಕ್ಷೆಯ ಹೆಸರನ್ನು ನಮೂದಿಸಬೇಕು, ನಿರ್ದಿಷ್ಟ ತಾರ್ಕಿಕ ಕಾರಣವನ್ನು ನೀಡಬೇಕು ಮತ್ತು GitHub issue ಅಥವಾ pull requestಗೆ ಲಿಂಕ್ ಮಾಡಬೇಕು. ದೋಷಪೂರಿತ ನಮೂದುಗಳು -ಮುಚ್ಚಿದ ಸ್ಥಿತಿಯಲ್ಲಿ ವಿಫಲಗೊಳ್ಳುತ್ತವೆ. ಅಳಿಸಲಾದ ಅಭ್ಯರ್ಥಿ ಪರೀಕ್ಷೆ ಅಥವಾ `.skip`/`.todo` ಸೇರಿಸುವ diff ಅನ್ನು ವಿನಾಯಿತಿಗಳು ನಿರ್ಬಂಧಿಸಲಾರವು; -assertion ದುರ್ಬಲಗೊಳಿಸುವಿಕೆ ಮತ್ತು ಇತರ ಮರೆಮಾಚುವಿಕೆಗಳು ಸ್ವತಂತ್ರವಾಗಿ ತಡೆಯುವ -`check:test-masking` ಗೇಟ್ನ ನಿಯಂತ್ರಣದಲ್ಲಿಯೇ ಇರುತ್ತವೆ. - -### ಜಾಬ್: `lint` - -`main` ಗೆ ಸಲ್ಲಿಸುವ ಪ್ರತಿಯೊಂದು PR ನಲ್ಲಿಯೂ ರನ್ ಆಗುತ್ತದೆ. ವಿಫಲವಾದರೆ ವಿಲೀನವನ್ನು ತಡೆಯುತ್ತದೆ. - -| ಸ್ಕ್ರಿಪ್ಟ್ (`npm run ...`) | ಪರಿಶೀಲಿಸುವುದು | ತಡೆಯುತ್ತದೆಯೇ | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `check:node-runtime` | Node.js ಆವೃತ್ತಿಯು ಬೆಂಬಲಿತ ವ್ಯಾಪ್ತಿಯಲ್ಲಿದೆ | ಹೌದು | -| `check:cycles` | ವೃತ್ತಾಕಾರದ ಆಮದುಗಳು — ಎಲ್ಲಾ `src/` + `open-sse/` ಮಾಡ್ಯೂಲ್ಗಳು | ಹೌದು | -| `check:route-validation:t06` | ಎಲ್ಲಾ ರೂಟ್ಗಳಲ್ಲಿ Zod ಸ್ಕೀಮಾಗಳು ಇವೆ (Tier 6 ನೀತಿ) | ಹೌದು | -| `check:any-budget:t11` | `@ts-expect-error // any` ಎಣಿಕೆಯು ಬಜೆಟ್ ಅನ್ನು ಮೀರುವುದಿಲ್ಲ (Tier 11 catraca) | ಹೌದು | -| `check:provider-consistency` | `providers.ts`ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು providerಗೆ `providerRegistry.ts`ನಲ್ಲಿ ಹೊಂದಾಣಿಕೆಯ entry ಇದೆ (ಮತ್ತು allowlist ವ್ಯಾಪ್ತಿಯಲ್ಲಿ ಇದರ ವಿರುದ್ಧವೂ ಅನ್ವಯಿಸುತ್ತದೆ) | ಹೌದು | -| `check:model-lifecycle` | ಕೈಯಿಂದ ನಿರ್ವಹಿಸಲಾಗುವ ಮೂರು routing tableಗಳು checked-in lifecycle snapshot (#11503) ಜೊತೆಗೆ ಸ್ಥಿರವಾಗಿರುತ್ತವೆ: `FITNESS_TABLE` (`taskFitness.ts`) ನಲ್ಲಿ `REGISTRY` route ಮಾಡಬಹುದಾದ ಯಾವುದೇ retired idಗೆ score ನೀಡಲಾಗುವುದಿಲ್ಲ; ಪ್ರತಿಯೊಂದು `BUILT_IN_ALIASES` target `REGISTRY`ಯಲ್ಲಿ ಇರುತ್ತದೆ ಮತ್ತು retired-id snapshotನಲ್ಲಿ ಇರುವುದಿಲ್ಲ; `REGISTRY`ಯಲ್ಲಿ ಇನ್ನೂ ಇರುವ ಪ್ರತಿಯೊಂದು retired id ಅನ್ನು forward ಮಾಡಲಾಗುತ್ತದೆ ಅಥವಾ `allowedRetiredInCatalog`ನಲ್ಲಿ ಪಟ್ಟಿ ಮಾಡಲಾಗುತ್ತದೆ; ಮತ್ತು ಯಾವುದೇ `DEFAULT_DEGRADATION_MAP` source ಅಥವಾ target ಆ snapshotನಲ್ಲಿ retired ಆಗಿ ಕಾಣಿಸುವುದಿಲ್ಲ. ಪ್ರಸ್ತುತ live upstream ಮೂಲಕ model ಅನ್ನು ಒದಗಿಸಲಾಗುತ್ತಿದೆ ಎಂಬುದನ್ನು ಇದು ಸಾಬೀತುಪಡಿಸುವುದಿಲ್ಲ. Offline — `config/quality/model-lifecycle.json` ಜೊತೆ ಹೋಲಿಸುತ್ತದೆ; ಇದನ್ನು `npm run quality:refresh-model-lifecycle` ಬಳಸಿ ಕೈಯಿಂದ refresh ಮಾಡಲಾಗುತ್ತದೆ (network; CIಗೆ ಜೋಡಿಸಲಾಗಿಲ್ಲ). `allowedRetiredInCatalog` ಒಂದು burn-down ratchet ಆಗಿದೆ: tracking issue ಇದ್ದಾಗ ಮಾತ್ರ entry ಸೇರಿಸಿ. | ಹೌದು | -| `check:fetch-targets` | client-side `src/`ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು `fetch("/api/...")` ನೈಜ `route.ts`ಗೆ resolve ಆಗುತ್ತದೆ | ಹೌದು | -| `check:deps` | repoದಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು `package.json`ನಾದ್ಯಂತ ಇರುವ ಎಲ್ಲಾ `npm install` ಮಾಡಬಹುದಾದ depsಗಳು `dependency-allowlist.json`ನಲ್ಲಿ ಇರುತ್ತವೆ; ಹೊಸ unpinned ಅಥವಾ slopsquatted packageಗಳನ್ನು flag ಮಾಡಲಾಗುತ್ತದೆ | ಹೌದು | -| `audit:deps` | `npm audit` (root + electron) — ಯಾವುದೇ high/critical advisoryಗಳಿಲ್ಲ (osv `check:vuln-ratchet` ಜೊತೆ overlap ಆಗುತ್ತದೆ; Rationalization Backlog ನೋಡಿ) | ಹೌದು | -| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hashಗಳು, host overrideಗಳಿಲ್ಲ | ಹೌದು | -| `check:licenses` | ಉತ್ಪಾದನಾ ಅವಲಂಬನೆಗಳಿಗಾಗಿ SPDX ಪರವಾನಗಿ ಅನುಮತಿಪಟ್ಟಿ | ಹೌದು | -| `check:tracked-artifacts` | ಯಾವುದೇ ಬಿಲ್ಡ್ ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ಗಳು / ಕಮಿಟ್ ಮಾಡಲಾದ `node_modules` ಸಿಂಲಿಂಕ್ಗಳು ಇರಬಾರದು (husky pre-commitನಲ್ಲಿಯೂ ಚಲಿಸುತ್ತದೆ; pre-push ಅನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಹಗುರವಾಗಿಡಲಾಗಿದೆ — #6716) | ಹೌದು | -| `check:ai-attribution` | PR ಕಮಿಟ್ಗಳು, ಶೀರ್ಷಿಕೆ ಅಥವಾ ಪಠ್ಯದಲ್ಲಿ ಯಾವುದೇ AI/bot `Co-Authored-By` ಟ್ರೇಲರ್ ಅಥವಾ AI-ರಚನೆಯ ಫುಟರ್ ಇರಬಾರದು — ಕಠಿಣ ನಿಯಮ #16 (`quality.yml` ನಲ್ಲಿನ PR→`release/**` ಗಾಗಿನ fast-gates ಲೂಪ್ನಲ್ಲಿ — ಈವೆಂಟ್ ಪೇಲೋಡ್ ಅನ್ನು ಓದುತ್ತದೆ, PR ಅಲ್ಲದಿದ್ದಾಗ ಯಾವುದೇ ಕಾರ್ಯ ಮಾಡುವುದಿಲ್ಲ — ಮತ್ತು PR→`main` ಗಾಗಿ `ci.yml` lintನಲ್ಲಿನ PR-ಮಾತ್ರದ ಹಂತ; ಹಾಗೆಯೇ husky `commit-msg` ಹುಕ್; ಮಾನವ ಸಹ-ಲೇಖಕರಿಗೆ ಅನುಮತಿಯಿದೆ; #14436) | -| `check:vitest-exclusions` | ಪ್ರತಿಯೊಂದು Vitest ಹೊರತುಪಡಿಸುವಿಕೆಯೂ ಟ್ರ್ಯಾಕಿಂಗ್ ಸಮಸ್ಯೆಯನ್ನು ಹೆಸರಿಸಬೇಕು ಮತ್ತು `config/quality/vitest-exclusions.json` ನಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳಬೇಕು (#13204) | ಹೌದು | -| `check:file-size` | ಯಾವುದೇ ಮೂಲ ಫೈಲ್ ಪ್ರತಿ-ವಿಸ್ತರಣೆಯ ಮಿತಿಯನ್ನು ಮೀರಬಾರದು (ರ್ಯಾಚೆಟ್: `frozen` ಪಟ್ಟಿಯಲ್ಲಿರುವ ಸ್ಥಿರಗೊಳಿಸಲಾದ ದೊಡ್ಡ ಫೈಲ್ಗಳು) | ಹೌದು | -| `check:error-helper` | executors/handlersನಲ್ಲಿನ ದೋಷ ಪ್ರತಿಕ್ರಿಯೆಗಳು `buildErrorBody()` / `sanitizeErrorMessage()` ಅನ್ನು ಬಳಸಬೇಕು (ಕಠಿಣ ನಿಯಮ #12) | ಹೌದು | -| `check:migration-numbering` | Migration SQL ಫೈಲ್ಗಳು ಯಾವುದೇ ಅಂತರಗಳು ಅಥವಾ ನಕಲುಗಳಿಲ್ಲದೆ ಅನುಕ್ರಮವಾಗಿ ಸಂಖ್ಯೀಕರಿಸಲ್ಪಟ್ಟಿವೆ | ಹೌದು | -| `check:public-creds` | `publicCreds.ts` ಹೊರಗೆ ಯಾವುದೇ ಅಕ್ಷರಶಃ OAuth `client_id`/`client_secret` ಅಥವಾ Firebase Web ಕೀಲಿಗಳಿಲ್ಲ (ಕಠಿಣ ನಿಯಮ #11) | ಹೌದು | -| `check:db-rules` | `src/lib/db/` ಮಾಡ್ಯೂಲ್ಗಳ ಹೊರಗೆ ಯಾವುದೇ ಕಚ್ಚಾ SQL ಇಲ್ಲ; `localDb.ts` ನಿಂದ ಯಾವುದೇ ಬ್ಯಾರೆಲ್-ಆಮದುಗಳಿಲ್ಲ (ಕಠಿಣ ನಿಯಮಗಳು #2/#5) | ಹೌದು | -| `check:known-symbols` | ಅವುಗಳ ಡಿಸ್ಪ್ಯಾಚ್ ಕೋಷ್ಟಕಗಳಲ್ಲಿ ನೋಂದಾಯಿಸಲಾದ ಪ್ರೊವೈಡರ್ ಎಕ್ಸಿಕ್ಯೂಟರ್ಗಳು, ರೂಟಿಂಗ್ ತಂತ್ರಗಳು ಮತ್ತು ಅನುವಾದಕಗಳು ಡಿಸ್ಕ್ನಲ್ಲಿರುವ ಫೈಲ್ಗಳಿಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತವೆ — ಯಾವುದೇ ಅನಾಥ ಅಥವಾ ಘೋಷಿಸದ ಸಂಕೇತಗಳಿಲ್ಲ | ಹೌದು | -| `check:route-guard-membership` | ಚೈಲ್ಡ್ ಪ್ರೊಸೆಸ್ ಅನ್ನು ರಚಿಸುವ ಪ್ರತಿಯೊಂದು ರೂಟ್ ಅನ್ನು `isLocalOnlyPath()` ಮೂಲಕ ವರ್ಗೀಕರಿಸಲಾಗಿದೆ (ಕಠಿಣ ನಿಯಮಗಳು #15/#17) | ಹೌದು | -| `check:test-discovery` | ರೆಪೊದಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು `*.test.ts` / `*.spec.ts` ಫೈಲ್ ಅನ್ನು ಕನಿಷ್ಠ ಒಂದು ಟೆಸ್ಟ್ ರನ್ನರ್ ಸಂಗ್ರಹಿಸುತ್ತದೆ (ರ್ಯಾಚೆಟ್: `test-discovery-baseline.json` ನಲ್ಲಿರುವ ಅನಾಥ ಪಟ್ಟಿ ಕೇವಲ ಕುಗ್ಗಬಹುದು) | ಹೌದು | -| `check:agent-skills-sync` | ರಚಿಸಲಾದ agent-skills ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ಗಳು ಅವುಗಳ ಮೂಲ ಕ್ಯಾಟಲಾಗ್ಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತವೆ (ಯಾವುದೇ ವ್ಯತ್ಯಾಸವಿಲ್ಲ) | -| `check:provider-asset-provenance` | ಪೂರೈಕೆದಾರರ ಲೋಗೋಗಳು/ಸ್ವತ್ತುಗಳು ದಾಖಲಿಸಲಾದ ಮೂಲದಾಖಲೆ ನಮೂದನ್ನು ಹೊಂದಿವೆ | -| `lint:json` | JSON ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್ಗಳು ಪಾರ್ಸ್ ಆಗುತ್ತವೆ ಮತ್ತು ರೆಪೊ lint ನಿಯಮಗಳನ್ನು ಪೂರೈಸುತ್ತವೆ | -| `typecheck:core` | ದೋಷಗಳಿಲ್ಲದ TypeScript ಕಂಪೈಲೇಶನ್ (ಸಲಹಾತ್ಮಕ ಎಚ್ಚರಿಕೆಗಳು ಮಾತ್ರ) | ಹೌದು | -| `typecheck:noimplicit:core` | ಕಟ್ಟುನಿಟ್ಟಿನ `noImplicitAny` — ಭವಿಷ್ಯೋನ್ಮುಖ; ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅನೇಕ ಕರೆ ಸ್ಥಳಗಳಿಗೆ ಇನ್ನೂ ಅನೋಟೇಶನ್ಗಳು ಅಗತ್ಯವಿವೆ | **ಸಲಹಾತ್ಮಕ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` ಗೆ ಸೀಮಿತವಾದ `tsc` (#7033) — `typecheck:core` ನ ಆಯ್ದ 27-ಫೈಲ್ ಅನುಮತಿಪಟ್ಟಿಯಲ್ಲಿ ಯಾವುದೇ ಡ್ಯಾಶ್ಬೋರ್ಡ್ TSX ಒಳಗೊಂಡಿಲ್ಲ ಮತ್ತು `next build` ಕೂಡ ಅದನ್ನು ಎಂದಿಗೂ ಟೈಪ್-ಚೆಕ್ ಮಾಡುವುದಿಲ್ಲ (`next.config.mjs` ನಲ್ಲಿ `ignoreBuildErrors: true` ಹೊಂದಿಸಲಾಗಿದೆ), ಆದ್ದರಿಂದ ಅಲ್ಲಿನ ಅನಾಥ-ಐಡೆಂಟಿಫೈಯರ್ ರಿಗ್ರೆಷನ್ಗಳು (#6625/#6909) CIಗೆ ಗೋಚರಿಸುತ್ತಿರಲಿಲ್ಲ. ಸ್ಥಿರಗೊಳಿಸಲಾದ ಪ್ರತಿ-ಫೈಲ್/ಪ್ರತಿ-TS-ಕೋಡ್ ಎಣಿಕೆಯ ಬೇಸ್ಲೈನ್ಗೆ (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ನಂತೆಯೇ ಅದೇ stale-enforcement ಮಾದರಿ) ಹೋಲಿಸಿ ವ್ಯತ್ಯಾಸಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ — ಬೇಸ್ಲೈನ್ ಎಣಿಕೆಯನ್ನು ಮೀರಿದ ಹೊಸ ದೋಷಗಳು ಮಾತ್ರ ಗೇಟ್ ವಿಫಲಗೊಳ್ಳುವಂತೆ ಮಾಡುತ್ತವೆ; ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ದೋಷವನ್ನು ಸರಿಪಡಿಸಿದಾಗ `--update` ಮೂಲಕ ಮಿತಿಯನ್ನು ಕೆಳಗಿಳಿಸಿ. | ಹೌದು | - -### ಜಾಬ್: `quality-gate` - -`test-coverage` ನಂತರ ರನ್ ಆಗುತ್ತದೆ. ವಿಫಲವಾದರೆ ವಿಲೀನವನ್ನು ತಡೆಯುತ್ತದೆ. - -| ಸ್ಕ್ರಿಪ್ಟ್ | ಪರಿಶೀಲಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `quality:collect` | `quality-metrics.json` ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ (ESLint ಎಚ್ಚರಿಕೆಗಳ ಸಂಖ್ಯೆ, ವಿಲೀನಗೊಳಿಸಿದ ಶಾರ್ಡ್ ವರದಿಯಿಂದ ಕವರೇಜ್) | ಹೌದು (ರ್ಯಾಚೆಟ್ಗಿಂತ ಮುಂಚಿತ) | -| `quality:ratchet` | `quality-baseline.json` ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು ಮೆಟ್ರಿಕ್ ಹಿಂಜರಿದಿಲ್ಲ (ESLint ಎಚ್ಚರಿಕೆಗಳು ≤ ಬೇಸ್ಲೈನ್; ಕವರೇಜ್ ≥ ಬೇಸ್ಲೈನ್) | ಹೌದು | -| `check:duplication` | ಕೋಡ್ ನಕಲೀಕರಣವು (jscpd@4) `quality-baseline.json` ನಲ್ಲಿನ ಬೇಸ್ಲೈನ್ ಅನ್ನು ಮೀರುವುದಿಲ್ಲ | ಹೌದು | -| `check:complexity` | ಫೈಲ್-ಮಟ್ಟದ ಸೈಕ್ಲೋಮ್ಯಾಟಿಕ್ ಸಂಕೀರ್ಣತೆಯು ಮಿತಿಯನ್ನು ಮೀರುವುದಿಲ್ಲ (ಕೋರ್ ESLint `complexity` + `max-lines-per-function`) | ಹೌದು | -| `check:cognitive-complexity` | ಅರಿವಿನ ಸಂಕೀರ್ಣತೆಯ ರ್ಯಾಚೆಟ್ (`eslint-plugin-sonarjs`) — ಪ್ರತ್ಯೇಕ ESLint ಪಾಸ್; CI ಎರಡನ್ನೂ ವಿಲೀನಗೊಳಿಸಿ ಏಕೈಕ `check:complexity-ratchets` ಹಂತವಾಗಿ ಚಲಾಯಿಸುತ್ತದೆ | ಹೌದು | -| `check:dead-code` | ಬಳಕೆಯಾಗದ ಎಕ್ಸ್ಪೋರ್ಟ್ಗಳು / ಫೈಲ್ಗಳ ರ್ಯಾಚೆಟ್ (knip) ಬೇಸ್ಲೈನ್ಗೆ ಹೋಲಿಸಿದಾಗ ಹಿಂಜರಿಯುವುದಿಲ್ಲ | ಹೌದು | -| `check:compression-budget` | ಸಂಕುಚನ ಬೆಂಚ್ಮಾರ್ಕ್ ಬಜೆಟ್ — ಪ್ರತಿ-ಎಂಜಿನ್ ಟೋಕನ್-ಉಳಿತಾಯದ ಕನಿಷ್ಠ ಮಿತಿಗಳು ಹಿಂಜರಿಯಬಾರದು | ಹೌದು | -| `check:type-coverage` | ಟೈಪ್ ಮಾಡಲಾದ ಶೇಕಡಾವಾರು ರ್ಯಾಚೆಟ್ (`type-coverage`) ಹಿಂಜರಿಯುವುದಿಲ್ಲ; ಬಹುಮಟ್ಟಿಗೆ `typecheck:noimplicit:core` ಅನ್ನು ಒಳಗೊಳ್ಳುತ್ತದೆ | ಹೌದು | -| `check:codeql-ratchet` | ತೆರೆದಿರುವ CodeQL ಎಚ್ಚರಿಕೆಗಳ ಸಂಖ್ಯೆ ಹಿಂಜರಿಯುವುದಿಲ್ಲ (`gh api` ಮೂಲಕ ಓದುತ್ತದೆ; ಟೋಕನ್ ಇಲ್ಲದಿದ್ದರೆ ಸೌಮ್ಯವಾಗಿ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ) — ರಿಫ್ರೆಶ್ ಆವರ್ತನೆ ಮತ್ತು ಕೈಯಾರೆ ಪ್ರಚೋದಿಸುವಿಕೆಗಾಗಿ: ಕೆಳಗಿನ "CodeQL ರ್ಯಾಚೆಟ್" ನೋಡಿ | ಹೌದು | +`.github/workflows/quality.yml` main/release PRಗಳು, ಸಂರಕ್ಷಿತ-ಬ್ರಾಂಚ್ +ಪುಶ್ಗಳು, dispatch ಮತ್ತು merge groupಗಳಲ್ಲಿ CIಗೆ ಪೂರಕವಾಗಿದೆ. PRಗಳು ಪಥ-ಫಿಲ್ಟರ್ ಮಾಡಿದ ವೇಗದ ಚೆಕ್ಗಳನ್ನು ಬಳಸುತ್ತವೆ. ಶಾಶ್ವತವಾಗಿ +ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ನಕಲಿ build ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ; ನೈಜ build/package/boot ಚೆಕ್ಗಳು CIಯಲ್ಲಿಯೇ ಉಳಿದಿವೆ. + +| ಜಾಬ್ | ವ್ಯಾಪ್ತಿ | ನಿರ್ಬಂಧಕ | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | Docs/code PRಗಳು; API docs refs ಮತ್ತು docs-all | ಹೌದು | +| `Fast Quality Gates` | Code PRಗಳು; static checks, typecheck, dashboard typecheck, ಪರಿಣಾಮಕ್ಕೊಳಗಾದ unit tests | ಹೌದು | +| `Forgotten sibling tests` | Code PRಗಳು; ಬದಲಾದ modules ಅನ್ನು static consumers ಮತ್ತು candidate sibling testsಗೆ ಟ್ರೇಸ್ ಮಾಡಲಾಗುತ್ತದೆ; barrel ಮತ್ತು dynamic-import paths ಅನ್ನು ಉಲ್ಲೇಖಿತ allowlist ವಿನಾಯಿತಿಗಳೊಂದಿಗೆ ಸಲಹಾತ್ಮಕ diagnostics ಆಗಿ ವರದಿ ಮಾಡಲಾಗುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | +| `Vitest (fast-path)` | Code PRಗಳು; ವೇಗದ vitest suite | ಹೌದು | +| `Unit Tests fast-path` | Code PRಗಳು; 4-shard unit suite | ಹೌದು | +| `No new ESLint warnings` | Code PRಗಳು; suppressions-aware lint guard | ಹೌದು, forks ಸೇರಿದಂತೆ | +| `Merge integrity (changelog + generated skills)` | ಡ್ರಾಫ್ಟ್ ಅಲ್ಲದ PRಗಳು; changelog ಮತ್ತು generated skill sync | ಹೌದು, forks ಸೇರಿದಂತೆ | + +#### ಮರೆತುಹೋದ sibling tests ವರದಿ + +`npm run check:forgotten-sibling-tests` test-impact map ಹಿಂದಿರುವ import resolver ಅನ್ನು ಮರುಬಳಕೆ ಮಾಡುತ್ತದೆ. +ಬದಲಾದ ಪ್ರತಿಯೊಂದು production moduleಗೆ, ಅಭ್ಯರ್ಥಿ +test pull-request diffನಲ್ಲಿ ಇಲ್ಲದಿದ್ದಾಗ, ಇದು ನಿರ್ಣಾಯಕ +`changed module/symbol -> static consumer -> candidate sibling test` ಸರಪಳಿಗಳನ್ನು ವರದಿ ಮಾಡುತ್ತದೆ. ಯಾವುದೇ ನಿರ್ಬಂಧಕ ರೋಲ್ಔಟ್ಗೆ ಮುನ್ನ ಮಾಪನಾಂಕ ನಿರ್ಣಯಕ್ಕಾಗಿ +Markdown ಸಾರಾಂಶ ಮತ್ತು JSON ಫಲಿತಾಂಶವನ್ನು `forgotten-sibling-tests` ವರ್ಕ್ಫ್ಲೋ artifact ಆಗಿ ಉಳಿಸಿಕೊಳ್ಳಲಾಗುತ್ತದೆ. + +Barrel re-exports ಮತ್ತು dynamic imports ಕೇವಲ resolution diagnostics ಆಗಿವೆ; ಅವು ಎಂದಿಗೂ +ತಡೆಯುವ finding ಅನ್ನು ಸೃಷ್ಟಿಸುವುದಿಲ್ಲ. ಪರಿಶೀಲಿಸಲಾದ ವಿನಾಯಿತಿಗಳು +`config/quality/forgotten-sibling-allowlist.json` ನಲ್ಲಿ ಇರುತ್ತವೆ. ಪ್ರತಿಯೊಂದು ನಮೂದು consumer ಮತ್ತು candidate +test ಅನ್ನು ಹೆಸರಿಸಬೇಕು, ನಿರ್ದಿಷ್ಟ ತಾರ್ಕಿಕ ಕಾರಣವನ್ನು ನೀಡಬೇಕು ಮತ್ತು GitHub issue ಅಥವಾ pull requestಗೆ ಲಿಂಕ್ ಮಾಡಬೇಕು. ದೋಷಪೂರಿತ ನಮೂದುಗಳು +ಮುಚ್ಚಿದ ಸ್ಥಿತಿಯಲ್ಲಿ ವಿಫಲವಾಗುತ್ತವೆ. ವಿನಾಯಿತಿಗಳು ಅಳಿಸಲಾದ candidate test ಅಥವಾ `.skip`/`.todo` ಸೇರಿಸುವ diff ಅನ್ನು ನಿರ್ಲಕ್ಷಿಸುವಂತೆ ಮಾಡಲಾಗುವುದಿಲ್ಲ; +assertion ದುರ್ಬಲಗೊಳಿಸುವಿಕೆ ಮತ್ತು ಇತರ masking ಕ್ರಮಗಳು ಸ್ವತಂತ್ರವಾಗಿ ತಡೆಯುವ +`check:test-masking` gateನ ವ್ಯಾಪ್ತಿಯಲ್ಲಿಯೇ ಉಳಿಯುತ್ತವೆ. + +### Job: `lint` + +`main` ಗೆ ಸಲ್ಲಿಸುವ ಪ್ರತಿಯೊಂದು PRನಲ್ಲೂ ರನ್ ಆಗುತ್ತದೆ. ವಿಫಲವಾದರೆ merge ಅನ್ನು ತಡೆಯುತ್ತದೆ. + +| Script (`npm run ...`) | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುತ್ತದೆಯೇ | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `check:node-runtime` | Node.js ಆವೃತ್ತಿಯು ಬೆಂಬಲಿತ ವ್ಯಾಪ್ತಿಯಲ್ಲಿದೆ | ಹೌದು | +| `check:cycles` | `src/` + `open-sse/` ಎಲ್ಲೆಡೆ ಇರುವ circular imports (AST-ಆಧಾರಿತ, tsconfig `paths` resolve ಮಾಡಲಾಗಿದೆ). Bare = ಸಲಹಾತ್ಮಕ, cycles ಅನ್ನು ಪಟ್ಟಿ ಮಾಡುತ್ತದೆ. `check:cycles:ratchet` (CI ರನ್ ಮಾಡುವುದು) ಎಣಿಕೆಯು `quality-baseline.json` ನಲ್ಲಿರುವ `metrics.cycles` ಮಿತಿಯನ್ನು ಮೀರಿದಾಗ ತಡೆಯುತ್ತದೆ — ಪ್ರಸ್ತುತ 14, `direction: down`, ಆದ್ದರಿಂದ ಅದು ಕಡಿಮೆಯಾಗಲು ಮಾತ್ರ ಸಾಧ್ಯ (#15159 G-01/G-02) | ಹೌದು (ratchet) | +| `check:route-validation:t06` | ಎಲ್ಲಾ routesನಲ್ಲಿ Zod schemas ಇವೆ (Tier 6 policy) | ಹೌದು | +| `check:any-budget:t11` | `@ts-expect-error // any` ಎಣಿಕೆಯು budget ಅನ್ನು ಮೀರುವುದಿಲ್ಲ (Tier 11 catraca) | ಹೌದು | +| `check:provider-consistency` | `providers.ts` ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು providerಗೆ `providerRegistry.ts` ನಲ್ಲಿ ಹೊಂದಾಣಿಕೆಯ entry ಇದೆ (ಮತ್ತು allowlist ವ್ಯಾಪ್ತಿಯಲ್ಲಿ ಇದರ ವಿರುದ್ಧವೂ ಅನ್ವಯಿಸುತ್ತದೆ) | ಹೌದು | +| `check:model-lifecycle` | ಕೈಯಾರೆ ನಿರ್ವಹಿಸಲಾದ ಮೂರು routing tableಗಳು checked-in lifecycle snapshot (#11503) ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಿಂದಿರುತ್ತವೆ: `FITNESS_TABLE` (`taskFitness.ts`) ನಲ್ಲಿ `REGISTRY` route ಮಾಡಬಹುದಾದ ಯಾವುದೇ retired idಗೆ score ನೀಡಲಾಗುವುದಿಲ್ಲ; ಪ್ರತಿಯೊಂದು `BUILT_IN_ALIASES` target `REGISTRY` ನಲ್ಲಿ ಇರುತ್ತದೆ ಮತ್ತು retired-id snapshotನಲ್ಲಿ ಇರುವುದಿಲ್ಲ; `REGISTRY` ನಲ್ಲಿ ಇನ್ನೂ ಇರುವ ಪ್ರತಿಯೊಂದು retired id ಅನ್ನು forward ಮಾಡಲಾಗುತ್ತದೆ ಅಥವಾ `allowedRetiredInCatalog` ನಲ್ಲಿ ಪಟ್ಟಿ ಮಾಡಲಾಗುತ್ತದೆ; ಮತ್ತು ಯಾವುದೇ `DEFAULT_DEGRADATION_MAP` source ಅಥವಾ target ಆ snapshotನಲ್ಲಿ retired ಆಗಿರುವುದಿಲ್ಲ. model ಒಂದನ್ನು ಪ್ರಸ್ತುತ live upstream ಮೂಲಕ serve ಮಾಡಲಾಗುತ್ತಿದೆ ಎಂಬುದನ್ನು ಇದು ಸಾಬೀತುಪಡಿಸುವುದಿಲ್ಲ. Offline — `config/quality/model-lifecycle.json` ಜೊತೆಗೆ ಹೋಲಿಸುತ್ತದೆ; ಇದನ್ನು `npm run quality:refresh-model-lifecycle` ಮೂಲಕ ಕೈಯಾರೆ refresh ಮಾಡಲಾಗುತ್ತದೆ (network; CIಗೆ ಜೋಡಿಸಲಾಗಿಲ್ಲ). `allowedRetiredInCatalog` ಒಂದು burn-down ratchet ಆಗಿದೆ: tracking issue ಇದ್ದಾಗ ಮಾತ್ರ entry ಸೇರಿಸಿ. | ಹೌದು | +| `check:fetch-targets` | client-side `src/` ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು `fetch("/api/...")` ನೈಜ `route.ts` ಗೆ resolve ಆಗುತ್ತದೆ | ಹೌದು | +| `check:deps` | repoದಲ್ಲಿನ ಪ್ರತಿಯೊಂದು `package.json` ನಾದ್ಯಂತ ಇರುವ ಎಲ್ಲಾ `npm install` ಮಾಡಬಹುದಾದ depsಗಳು `dependency-allowlist.json` ನಲ್ಲಿ ಇವೆ; ಹೊಸ unpinned ಅಥವಾ slopsquatted packageಗಳನ್ನು flag ಮಾಡಲಾಗುತ್ತದೆ | ಹೌದು | +| `audit:deps` | `npm audit` (root + electron) — ಯಾವುದೇ high/critical advisoryಗಳಿಲ್ಲ (osv `check:vuln-ratchet` ಜೊತೆಗೆ overlap ಆಗುತ್ತದೆ; Rationalization Backlog ನೋಡಿ) | ಹೌದು | +| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hashಗಳು, ಯಾವುದೇ host overrideಗಳಿಲ್ಲ | ಹೌದು | +| `check:licenses` | ಉತ್ಪಾದನಾ ಅವಲಂಬನೆಗಳಿಗಾಗಿ SPDX ಪರವಾನಗಿ ಅನುಮತಿ ಪಟ್ಟಿ | ಹೌದು | +| `check:tracked-artifacts` | ಯಾವುದೇ ಬಿಲ್ಡ್ ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ಗಳು / ಕಮಿಟ್ ಮಾಡಿದ `node_modules` ಸಿಮ್ಲಿಂಕ್ಗಳು ಇರಬಾರದು (husky pre-commitನಲ್ಲಿಯೂ ರನ್ ಆಗುತ್ತದೆ; pre-push ಅನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಹಗುರವಾಗಿ ಇರಿಸಲಾಗಿದೆ — #6716) | ಹೌದು | +| `check:ai-attribution` | PR ಕಮಿಟ್ಗಳು, ಶೀರ್ಷಿಕೆ ಅಥವಾ ಮುಖ್ಯಪಠ್ಯದಲ್ಲಿ ಯಾವುದೇ AI/bot `Co-Authored-By` ಟ್ರೇಲರ್ ಅಥವಾ AI-ರಚನೆಯ ಅಡಿಟಿಪ್ಪಣಿ ಇರಬಾರದು — ಕಠಿಣ ನಿಯಮ #16 (`quality.yml`ನ PR→`release/**` ವೇಗದ-ಗೇಟ್ಗಳ ಲೂಪ್ನಲ್ಲಿ — ಈವೆಂಟ್ ಪೇಲೋಡ್ ಅನ್ನು ಓದುತ್ತದೆ, PRಗಳ ಹೊರಗೆ ಯಾವುದೇ ಕಾರ್ಯ ಮಾಡುವುದಿಲ್ಲ — ಮತ್ತು PR→`main`ಗಾಗಿ `ci.yml` ಲಿಂಟ್ನಲ್ಲಿರುವ PR-ಮಾತ್ರದ ಹಂತ; husky `commit-msg` ಹುಕ್ ಕೂಡ; ಮಾನವ ಸಹ-ಲೇಖಕರಿಗೆ ಅನುಮತಿ ಇದೆ; #14436) | +| `check:vitest-exclusions` | ಪ್ರತಿಯೊಂದು Vitest ಹೊರಗಿಡುವಿಕೆಯೂ ಟ್ರ್ಯಾಕಿಂಗ್ ಸಮಸ್ಯೆಯನ್ನು ಹೆಸರಿಸಬೇಕು ಮತ್ತು `config/quality/vitest-exclusions.json`ನಲ್ಲಿ ಕಾಣಿಸಬೇಕು (#13204) | ಹೌದು | +| `check:file-size` | ಯಾವುದೇ ಮೂಲ ಫೈಲ್ ಪ್ರತಿ-ವಿಸ್ತರಣೆಯ ಮಿತಿಯನ್ನು ಮೀರಬಾರದು (ರ್ಯಾಚೆಟ್: `frozen` ಪಟ್ಟಿಯಲ್ಲಿರುವ ದೊಡ್ಡ ಫೈಲ್ಗಳನ್ನು ಸ್ಥಿರಗೊಳಿಸಲಾಗಿದೆ) | ಹೌದು | +| `check:error-helper` | ಎಕ್ಸಿಕ್ಯೂಟರ್ಗಳು/ಹ್ಯಾಂಡ್ಲರ್ಗಳಲ್ಲಿನ ದೋಷ ಪ್ರತಿಕ್ರಿಯೆಗಳು `buildErrorBody()` / `sanitizeErrorMessage()` ಅನ್ನು ಬಳಸಬೇಕು (ಕಠಿಣ ನಿಯಮ #12) | ಹೌದು | +| `check:migration-numbering` | Migration SQL ಫೈಲ್ಗಳು ಯಾವುದೇ ಅಂತರಗಳು ಅಥವಾ ನಕಲುಗಳಿಲ್ಲದೆ ಅನುಕ್ರಮವಾಗಿ ಸಂಖ್ಯೆ ಹೊಂದಿವೆ | ಹೌದು | +| `check:public-creds` | `publicCreds.ts` ಹೊರಗೆ ಯಾವುದೇ ಅಕ್ಷರಶಃ OAuth `client_id`/`client_secret` ಅಥವಾ Firebase Web ಕೀಗಳು ಇಲ್ಲ (ಕಠಿಣ ನಿಯಮ #11) | ಹೌದು | +| `check:db-rules` | `src/lib/db/` ಮಾಡ್ಯೂಲ್ಗಳ ಹೊರಗೆ ಯಾವುದೇ ಕಚ್ಚಾ SQL ಇಲ್ಲ; `localDb.ts` ನಿಂದ ಯಾವುದೇ ಬ್ಯಾರೆಲ್-ಆಮದುಗಳಿಲ್ಲ (ಕಠಿಣ ನಿಯಮಗಳು #2/#5) | ಹೌದು | +| `check:known-symbols` | ತಮ್ಮ dispatch ಕೋಷ್ಟಕಗಳಲ್ಲಿ ನೋಂದಾಯಿಸಲಾದ provider executors, routing strategies ಮತ್ತು translators ಡಿಸ್ಕ್ನಲ್ಲಿರುವ ಫೈಲ್ಗಳಿಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತವೆ — ಯಾವುದೇ ಅನಾಥ ಅಥವಾ ಘೋಷಿಸದ symbols ಇಲ್ಲ | ಹೌದು | +| `check:route-guard-membership` | child process ಅನ್ನು ಪ್ರಾರಂಭಿಸುವ ಪ್ರತಿಯೊಂದು route ಅನ್ನು `isLocalOnlyPath()` ಮೂಲಕ ವರ್ಗೀಕರಿಸಲಾಗಿದೆ (ಕಠಿಣ ನಿಯಮಗಳು #15/#17) | ಹೌದು | +| `check:test-discovery` | repoದಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು `*.test.ts` / `*.spec.ts` ಫೈಲ್ ಅನ್ನು ಕನಿಷ್ಠ ಒಂದು test runner ಸಂಗ್ರಹಿಸುತ್ತದೆ (ratchet: `test-discovery-baseline.json` ನಲ್ಲಿರುವ ಅನಾಥ ಪಟ್ಟಿ ಕೇವಲ ಕುಗ್ಗಬಹುದು) | ಹೌದು | +| `check:agent-skills-sync` | ರಚಿಸಲಾದ agent-skills ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ಗಳು ಅವುಗಳ ಮೂಲ ಕ್ಯಾಟಲಾಗ್ಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತವೆ (ಯಾವುದೇ ವ್ಯತ್ಯಾಸವಿಲ್ಲ) | +| `check:provider-asset-provenance` | ಪೂರೈಕೆದಾರರ ಲೋಗೋಗಳು/ಆಸ್ತಿಗಳು ದಾಖಲಿಸಲಾದ ಮೂಲದ ನಮೂದನ್ನು ಹೊಂದಿರುತ್ತವೆ | +| `lint:json` | JSON ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್ಗಳು ಪಾರ್ಸ್ ಆಗುತ್ತವೆ ಮತ್ತು repo lint ನಿಯಮಗಳನ್ನು ಪೂರೈಸುತ್ತವೆ | +| `typecheck:core` | ದೋಷಗಳಿಲ್ಲದೆ TypeScript ಕಂಪೈಲೇಶನ್ (ಸಲಹಾತ್ಮಕ ಎಚ್ಚರಿಕೆಗಳು ಮಾತ್ರ) | ಹೌದು | +| `typecheck:noimplicit:core` | ಕಟ್ಟುನಿಟ್ಟಾದ `noImplicitAny` — ಭವಿಷ್ಯೋನ್ಮುಖ; ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅನೇಕ ಕರೆ ಸ್ಥಳಗಳಿಗೆ ಇನ್ನೂ ಅನೋಟೇಶನ್ಗಳು ಅಗತ್ಯವಿವೆ | **ಸಲಹಾತ್ಮಕ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` ಗೆ ಸೀಮಿತವಾದ `tsc` (#7033) — `typecheck:core` ನ ಆಯ್ದ 27-ಫೈಲ್ allowlist ಯಾವುದೇ dashboard TSX ಅನ್ನು ಒಳಗೊಂಡಿಲ್ಲ, ಮತ್ತು `next build` ಕೂಡ ಅದನ್ನು ಎಂದಿಗೂ type-check ಮಾಡುವುದಿಲ್ಲ (`next.config.mjs` ನಲ್ಲಿ `ignoreBuildErrors: true` ಅನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ), ಆದ್ದರಿಂದ ಅಲ್ಲಿನ ಅನಾಥ-ಗುರುತಿಸುವಿಕೆ ರಿಗ್ರೆಷನ್ಗಳು (#6625/#6909) CIಗೆ ಗೋಚರಿಸುತ್ತಿರಲಿಲ್ಲ. ಸ್ಥಿರಗೊಳಿಸಲಾದ ಪ್ರತಿ-ಫೈಲ್/ಪ್ರತಿ-TS-code ಎಣಿಕೆಯ baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ನಂತೆಯೇ ಅದೇ stale-enforcement ಮಾದರಿ) ವಿರುದ್ಧ diff ಮಾಡುತ್ತದೆ — baseline ಎಣಿಕೆಯನ್ನು ಮೀರಿದ ಹೊಸ ದೋಷಗಳು ಮಾತ್ರ gate ಅನ್ನು ವಿಫಲಗೊಳಿಸುತ್ತವೆ; ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ದೋಷವನ್ನು ಸರಿಪಡಿಸಿದಾಗ `--update` ಬಳಸಿ ratchet ಅನ್ನು ಕಡಿಮೆ ಮಾಡಿ. | ಹೌದು | + +### Job: `quality-gate` + +`test-coverage` ನಂತರ ಚಾಲನೆಯಾಗುತ್ತದೆ. ವಿಫಲವಾದರೆ merge ಅನ್ನು ತಡೆಯುತ್ತದೆ. + +| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `quality:collect` | `quality-metrics.json` ಅನ್ನು ರಚಿಸುತ್ತದೆ (ESLint ಎಚ್ಚರಿಕೆಗಳ ಸಂಖ್ಯೆ, ವಿಲೀನಗೊಳಿಸಿದ ಶಾರ್ಡ್ ವರದಿಯಿಂದ ಕವರೇಜ್) | ಹೌದು (ರ್ಯಾಚೆಟ್ಗೆ ಅಪ್ಸ್ಟ್ರೀಮ್) | +| `quality:ratchet` | `quality-baseline.json` ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು ಮೆಟ್ರಿಕ್ ಹಿನ್ನಡೆ ಕಂಡಿಲ್ಲ (ESLint ಎಚ್ಚರಿಕೆಗಳು ≤ ಬೇಸ್ಲೈನ್; ಕವರೇಜ್ ≥ ಬೇಸ್ಲೈನ್) | ಹೌದು | +| `check:duplication` | ಕೋಡ್ ನಕಲು (jscpd@4), `quality-baseline.json` ನಲ್ಲಿನ ಬೇಸ್ಲೈನ್ ಅನ್ನು ಮೀರುವುದಿಲ್ಲ | ಹೌದು | +| `check:complexity` | ಫೈಲ್-ಮಟ್ಟದ ಸೈಕ್ಲೊಮ್ಯಾಟಿಕ್ ಸಂಕೀರ್ಣತೆಯು ಮಿತಿಯನ್ನು ಮೀರುವುದಿಲ್ಲ (ಕೋರ್ ESLint `complexity` + `max-lines-per-function`) | ಹೌದು | +| `check:cognitive-complexity` | ಕಾಗ್ನಿಟಿವ್ ಸಂಕೀರ್ಣತೆ ರ್ಯಾಚೆಟ್ (`eslint-plugin-sonarjs`) — ಪ್ರತ್ಯೇಕ ESLint ಪಾಸ್; CI ಎರಡನ್ನೂ ವಿಲೀನಗೊಳಿಸಿ ಏಕೈಕ `check:complexity-ratchets` ಹಂತವಾಗಿ ಚಲಾಯಿಸುತ್ತದೆ | ಹೌದು | +| `check:dead-code` | ಬಳಕೆಯಾಗದ ಎಕ್ಸ್ಪೋರ್ಟ್ಗಳು / ಫೈಲ್ಗಳ ರ್ಯಾಚೆಟ್ (knip), ಬೇಸ್ಲೈನ್ಗೆ ಹೋಲಿಸಿದಾಗ ಹಿನ್ನಡೆ ಕಾಣುವುದಿಲ್ಲ | ಹೌದು | +| `check:compression-budget` | ಕಂಪ್ರೆಷನ್ ಬೆಂಚ್ಮಾರ್ಕ್ ಬಜೆಟ್ — ಪ್ರತಿ ಎಂಜಿನ್ನ ಟೋಕನ್-ಉಳಿತಾಯದ ಕನಿಷ್ಠ ಮಿತಿಗಳು ಹಿನ್ನಡೆ ಕಾಣಬಾರದು | ಹೌದು | +| `check:type-coverage` | ಟೈಪ್ ಮಾಡಲಾದ ಶೇಕಡಾವಾರು ರ್ಯಾಚೆಟ್ (`type-coverage`) ಹಿನ್ನಡೆ ಕಾಣುವುದಿಲ್ಲ; ಬಹುಮಟ್ಟಿಗೆ `typecheck:noimplicit:core` ಅನ್ನು ಒಳಗೊಳ್ಳುತ್ತದೆ | ಹೌದು | +| `check:codeql-ratchet` | ತೆರೆದಿರುವ CodeQL ಎಚ್ಚರಿಕೆಗಳ ಸಂಖ್ಯೆ ಹಿನ್ನಡೆ ಕಾಣುವುದಿಲ್ಲ (`gh api` ಮೂಲಕ ಓದುತ್ತದೆ; ಟೋಕನ್ ಇಲ್ಲದಿದ್ದರೆ ಸುರಕ್ಷಿತವಾಗಿ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ) — ನವೀಕರಣ ಅವಧಿ ಮತ್ತು ಹಸ್ತಚಾಲಿತ ಟ್ರಿಗರ್ಗಾಗಿ: ಕೆಳಗಿನ "CodeQL ರ್ಯಾಚೆಟ್" ನೋಡಿ | ಹೌದು | ### ಜಾಬ್: `quality-extended` ಸಂಪೂರ್ಣ ಜಾಬ್ ಸಲಹಾತ್ಮಕವಾಗಿದೆ (`continue-on-error: true`). npm-ಆಧಾರಿತ ರ್ಯಾಚೆಟ್ಗಳು -ನೈಜವಾಗಿ ಚಲಿಸುತ್ತವೆ; ಬಾಹ್ಯ ಸ್ಕ್ಯಾನರ್ಗಳು `gh release download` ಮೂಲಕ ಸ್ಥಾಪಿಸಲ್ಪಡುತ್ತವೆ ಮತ್ತು -ಬೈನರಿ ಇನ್ನೂ ಲಭ್ಯವಿಲ್ಲದಿದ್ದಾಗ ಸ್ವತಃ ಬಿಟ್ಟುಬಿಡುತ್ತವೆ (exit 0). +ನೈಜವಾಗಿ ಚಲಿಸುತ್ತವೆ; ಬಾಹ್ಯ ಸ್ಕ್ಯಾನರ್ಗಳು `gh release download` ಮೂಲಕ ಸ್ಥಾಪನೆಯಾಗುತ್ತವೆ ಮತ್ತು +ಬೈನರಿ ಇನ್ನೂ ಲಭ್ಯವಿಲ್ಲದಿದ್ದಾಗ ಸ್ವಯಂ ಬಿಟ್ಟುಬಿಡುತ್ತವೆ (exit 0). -| ಸ್ಕ್ರಿಪ್ಟ್ | ಪರಿಶೀಲಿಸುವುದು | ತಡೆಯುವಿಕೆ | +| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -| `check:circular-deps` | ವೃತ್ತಾಕಾರದ ಅವಲಂಬನೆಗಳಿಲ್ಲ (dpdm) | **ಸಲಹಾತ್ಮಕ** | +| `check:circular-deps` | ವೃತ್ತಾಕಾರದ ಡಿಪೆಂಡೆನ್ಸಿಗಳು ಇಲ್ಲ (dpdm) | **ಸಲಹಾತ್ಮಕ** | | `check:bundle-size` | ಬಂಡಲ್ ಗಾತ್ರವು ಮಿತಿಯನ್ನು ಮೀರುವುದಿಲ್ಲ | **ಸಲಹಾತ್ಮಕ** | | `check:secrets` | ರಹಸ್ಯಗಳ ಸ್ಕ್ಯಾನಿಂಗ್ (gitleaks) — ಬೈನರಿ ಇಲ್ಲದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | -| `check:vuln-ratchet` | ಅವಲಂಬನೆಗಳ ದುರ್ಬಲತೆಗಳು (osv-scanner) ಹಿಂಜರಿಯುವುದಿಲ್ಲ — ಬೈನರಿ ಇಲ್ಲದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | -| `check:workflows` | ವರ್ಕ್ಫ್ಲೋ ಲಿಂಟ್ (actionlint + zizmor); ಕಾಣೆಯಾದ/ದೋಷಪೂರಿತ ಸ್ಕ್ಯಾನರ್ಗಳು, ಅಮಾನ್ಯ ವರದಿಗಳು ಅಥವಾ ಕಾಣೆಯಾದ ರ್ಯಾಚೆಟ್ ಬೇಸ್ಲೈನ್ INCOMPLETE ಎಂದು ವಿಫಲಗೊಳ್ಳುತ್ತವೆ. ಮಾನ್ಯ ಕಂಡುಬಂದ ಅಂಶಗಳು ಆಯ್ಕೆಮಾಡಿದ ಕಟ್ಟುನಿಟ್ಟಿನ/ಸಲಹಾತ್ಮಕ/ರ್ಯಾಚೆಟ್ ನೀತಿಯನ್ನು ಅನುಸರಿಸುತ್ತವೆ | ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆ ಅಗತ್ಯ; CI ನಲ್ಲಿ zizmor ರ್ಯಾಚೆಟ್ ತಡೆಯುತ್ತದೆ | -| `check:openapi-breaking` | ಬೇಸ್ ಬ್ರಾಂಚ್ಗೆ ಹೋಲಿಸಿದ ಸಾರ್ವಜನಿಕ API ಒಪ್ಪಂದದ (`openapi.yaml`) ಬ್ರೇಕಿಂಗ್ ಬದಲಾವಣೆಗಳು (oasdiff) — `openapiBreaking=N` ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ; oasdiff ಇಲ್ಲದಿದ್ದರೆ ಅಥವಾ ಬೇಸ್ ಸ್ಪೆಕ್ ಪರಿಹರಿಸಲಾಗದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | +| `check:vuln-ratchet` | ಡಿಪೆಂಡೆನ್ಸಿ ದೌರ್ಬಲ್ಯಗಳು (osv-scanner) ಹಿನ್ನಡೆ ಕಾಣುವುದಿಲ್ಲ — ಬೈನರಿ ಇಲ್ಲದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | +| `check:workflows` | ವರ್ಕ್ಫ್ಲೋ ಲಿಂಟ್ (actionlint + zizmor); ಕಾಣೆಯಾದ/ದೋಷಯುಕ್ತ ಸ್ಕ್ಯಾನರ್ಗಳು, ಅಮಾನ್ಯ ವರದಿಗಳು ಅಥವಾ ಕಾಣೆಯಾದ ರ್ಯಾಚೆಟ್ ಬೇಸ್ಲೈನ್ ಅನ್ನು INCOMPLETE ಎಂದು ವಿಫಲಗೊಳಿಸುತ್ತವೆ. ಮಾನ್ಯ ಕಂಡುಬಂದ ಅಂಶಗಳು ಆಯ್ದ ಕಟ್ಟುನಿಟ್ಟಿನ/ಸಲಹಾತ್ಮಕ/ರ್ಯಾಚೆಟ್ ನೀತಿಯನ್ನು ಅನುಸರಿಸುತ್ತವೆ | ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆ ಅಗತ್ಯ; CI ನಲ್ಲಿ zizmor ರ್ಯಾಚೆಟ್ ತಡೆಯುತ್ತದೆ | +| `check:openapi-breaking` | ಮೂಲ ಬ್ರಾಂಚ್ಗೆ ಹೋಲಿಸಿದ ಸಾರ್ವಜನಿಕ API ಒಪ್ಪಂದದಲ್ಲಿನ (`openapi.yaml`) ಬ್ರೇಕಿಂಗ್ ಬದಲಾವಣೆಗಳು (oasdiff) — `openapiBreaking=N` ಅನ್ನು ಹೊರಸೂಸುತ್ತದೆ; oasdiff ಇಲ್ಲದಿದ್ದರೆ ಅಥವಾ ಮೂಲ ಸ್ಪೆಕ್ ಪರಿಹರಿಸಲಾಗದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ | **ಸಲಹಾತ್ಮಕ** | ### ಜಾಬ್: `docs-sync-strict` -`main` ಗೆ ಸಲ್ಲಿಸುವ ಪ್ರತಿಯೊಂದು PR ನಲ್ಲೂ ಚಲಿಸುತ್ತದೆ. ವಿಫಲವಾದರೆ ವಿಲೀನವನ್ನು ತಡೆಯುತ್ತದೆ. - -| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `check:docs-all` | ಕೆಳಗಿನ 6 ಉಪ-ಗೇಟ್ಗಳನ್ನು ಅನುಕ್ರಮವಾಗಿ ಚಲಾಯಿಸುವ ಮೆಟಾ-ಗೇಟ್ | ಹೌದು | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ಆವೃತ್ತಿಗಳ ಹೊಂದಾಣಿಕೆ | ಹೌದು | -| ↳ `check:docs-counts` | ಗದ್ಯದಲ್ಲಿರುವ ಎಣಿಕೆಗಳು (ಪ್ರೊವೈಡರ್ಗಳ ಸಂಖ್ಯೆ, ಮೈಗ್ರೇಶನ್ಗಳ ಸಂಖ್ಯೆ ಇತ್ಯಾದಿ) ನೈಜ ಎಣಿಕೆಗಳ ರ್ಯಾಚೆಟ್ ವಿಂಡೋ ವ್ಯಾಪ್ತಿಯಲ್ಲಿವೆ | ಹೌದು | -| ↳ `check:env-doc-sync` | `.env.example` ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು env ವೇರಿಯಬಲ್ ಅನ್ನು docs ಕೋಷ್ಟಕದಲ್ಲಿ ದಾಖಲಿಸಲಾಗಿದೆ ಮತ್ತು ಪ್ರತಿಕ್ರಮದಲ್ಲಿಯೂ ಹಾಗೆಯೇ ಇದೆ | ಹೌದು | -| ↳ `check:deprecated-versions` | docs ನಲ್ಲಿ ಬಳಕೆಯಿಂದ ತೆಗೆದುಹಾಕಲಾದ ಆವೃತ್ತಿ ಸ್ಟ್ರಿಂಗ್ಗಳಿಲ್ಲ | ಹೌದು | -| ↳ `check:doc-links` | docs ನಲ್ಲಿರುವ ಆಂತರಿಕ markdown ಲಿಂಕ್ಗಳು ನೈಜ ಫೈಲ್ಗಳಿಗೆ ಪರಿಹಾರಗೊಳ್ಳುತ್ತವೆ (`[text]`/`(path)` ರೂಪ) | ಹೌದು | -| ↳ `check:fabricated-docs` | docs ನಲ್ಲಿ ಉಲ್ಲೇಖಿಸಲಾದ routes, env ವೇರಿಯಬಲ್ಗಳು, CLI ಕಮಾಂಡ್ಗಳು, hook ಹೆಸರುಗಳು ಮತ್ತು file paths ಕೋಡ್ಬೇಸ್ನಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿವೆ. `--strict` ಮೂಲಕ ಕಠಿಣ ಗೇಟ್; ಫ್ಲ್ಯಾಗ್ ಇಲ್ಲದಿದ್ದರೆ ಸಾಫ್ಟ್-ಫೇಲ್. | ಹೌದು (CI ನಲ್ಲಿ `--strict` ಮೂಲಕ) | -| `check:cli-i18n` | CLI ಕಮಾಂಡ್ ಸ್ಟ್ರಿಂಗ್ಗಳು ಎಲ್ಲಾ i18n ಲೊಕೇಲ್ ಫೈಲ್ಗಳಲ್ಲಿ ಇವೆ | ಹೌದು | -| `check:openapi-coverage` | OpenAPI ಸ್ಪೆಕ್ ನೈಜ routes ಗಳ ಕನಿಷ್ಠ ರ್ಯಾಚೆಟ್ ಮಾಡಿದ ಕೆಳಮಿತಿಯಷ್ಟಾದರೂ ಒಳಗೊಳ್ಳುತ್ತದೆ | ಹೌದು | -| `check:openapi-security-tiers` | `openapi.yaml` ನಲ್ಲಿನ ಭದ್ರತಾ ಹಂತದ annotations, `routeGuard.ts` ವರ್ಗೀಕರಣಗಳೊಂದಿಗೆ ಹೊಂದಾಣಿಕೆಯಾಗಿವೆ | **ಸಲಹಾತ್ಮಕ** | -| `check:openapi-routes` | `openapi.yaml` ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು path ನೈಜ `route.ts` ಗೆ ಪರಿಹಾರಗೊಳ್ಳುತ್ತದೆ (ಭ್ರಮೆ-ವಿರೋಧಿ) | ಹೌದು | -| `check:docs-symbols` | `docs/**/*.md` ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು `/api/...` ಉಲ್ಲೇಖವು ನೈಜ `route.ts` ಗೆ ಪರಿಹಾರಗೊಳ್ಳುತ್ತದೆ (ಭ್ರಮೆ-ವಿರೋಧಿ) | ಹೌದು | -| `i18n translation drift` | i18n ಲೊಕೇಲ್ ಫೈಲ್ಗಳಲ್ಲಿನ ಅನುವಾದಿಸದ keys — ಎಚ್ಚರಿಕೆ ಮಾತ್ರ | **ಸಲಹಾತ್ಮಕ** | +`main` ಗೆ ಬರುವ ಪ್ರತಿಯೊಂದು PR ನಲ್ಲೂ ಚಲಿಸುತ್ತದೆ. ವಿಫಲವಾದರೆ ವಿಲೀನವನ್ನು ತಡೆಯುತ್ತದೆ. + +| ಸ್ಕ್ರಿಪ್ಟ್ | ಪರಿಶೀಲಿಸುವುದು | ನಿರ್ಬಂಧಿಸುವುದೇ | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `check:docs-all` | ಕೆಳಗಿನ 6 ಉಪ-ಗೇಟ್ಗಳನ್ನು ಅನುಕ್ರಮವಾಗಿ ಚಲಾಯಿಸುವ ಮೆಟಾ-ಗೇಟ್ | ಹೌದು | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ಆವೃತ್ತಿಗಳ ಸ್ಥಿರತೆ | ಹೌದು | +| ↳ `check:docs-counts` | ಗದ್ಯದಲ್ಲಿನ ಎಣಿಕೆಗಳು (ಪ್ರೊವೈಡರ್ಗಳ ಸಂಖ್ಯೆ, ಮೈಗ್ರೇಶನ್ಗಳ ಸಂಖ್ಯೆ, ಇತ್ಯಾದಿ) ನೈಜ ಎಣಿಕೆಗಳ ರಾಚೆಟ್ ವ್ಯಾಪ್ತಿಯೊಳಗಿವೆ | ಹೌದು | +| ↳ `check:env-doc-sync` | `.env.example` ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು env var ಅನ್ನು docs ಕೋಷ್ಟಕದಲ್ಲಿ ದಾಖಲಿಸಲಾಗಿದೆ ಮತ್ತು ಅದರ ವಿರುದ್ಧವೂ ಹಾಗೆಯೇ ಇದೆ | ಹೌದು | +| ↳ `check:deprecated-versions` | docs ನಲ್ಲಿ ಬಳಕೆಯಿಂದ ತೆಗೆದುಹಾಕಲಾದ ಯಾವುದೇ ಆವೃತ್ತಿ ಸ್ಟ್ರಿಂಗ್ಗಳಿಲ್ಲ | ಹೌದು | +| ↳ `check:doc-links` | docs ನಲ್ಲಿರುವ ಆಂತರಿಕ markdown ಲಿಂಕ್ಗಳು ನೈಜ ಫೈಲ್ಗಳಿಗೆ ಪರಿಹರಿಸಲ್ಪಡುತ್ತವೆ (`[text]`/`(path)` ರೂಪ) | ಹೌದು | +| ↳ `check:fabricated-docs` | docs ನಲ್ಲಿ ಉಲ್ಲೇಖಿಸಲಾದ ರೂಟ್ಗಳು, env vars, CLI ಕಮಾಂಡ್ಗಳು, ಹೂಕ್ ಹೆಸರುಗಳು ಮತ್ತು ಫೈಲ್ ಪಥಗಳು ಕೋಡ್ಬೇಸ್ನಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿವೆ. `--strict` ಮೂಲಕ ಹಾರ್ಡ್ ಗೇಟ್; ಫ್ಲ್ಯಾಗ್ ಇಲ್ಲದೆ ಸಾಫ್ಟ್-ಫೇಲ್. | ಹೌದು (CI ನಲ್ಲಿ `--strict` ಮೂಲಕ) | +| `check:cli-i18n` | CLI ಕಮಾಂಡ್ ಸ್ಟ್ರಿಂಗ್ಗಳು ಎಲ್ಲಾ i18n ಲೊಕೇಲ್ ಫೈಲ್ಗಳಲ್ಲಿ ಇವೆ | ಹೌದು | +| `check:openapi-coverage` | OpenAPI ಸ್ಪೆಕ್ ನೈಜ ರೂಟ್ಗಳ ಕನಿಷ್ಠ ರಾಚೆಟ್ ಮಾಡಿದ ಮಿತಿಯನ್ನಾದರೂ ಒಳಗೊಳ್ಳುತ್ತದೆ | ಹೌದು | +| `check:openapi-security-tiers` | `openapi.yaml` ನಲ್ಲಿನ ಭದ್ರತಾ ಹಂತದ ಟಿಪ್ಪಣಿಗಳು `routeGuard.ts` ವರ್ಗೀಕರಣಗಳೊಂದಿಗೆ ಸ್ಥಿರವಾಗಿವೆ | **ಸಲಹಾತ್ಮಕ** | +| `check:openapi-routes` | `openapi.yaml` ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು ಪಥವು ನೈಜ `route.ts` ಗೆ ಪರಿಹರಿಸಲ್ಪಡುತ್ತದೆ (ಕಲ್ಪಿತ ಮಾಹಿತಿಯ ತಡೆ) | ಹೌದು | +| `check:docs-symbols` | `docs/**/*.md` ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು `/api/...` ಉಲ್ಲೇಖವು ನೈಜ `route.ts` ಗೆ ಪರಿಹರಿಸಲ್ಪಡುತ್ತದೆ (ಕಲ್ಪಿತ ಮಾಹಿತಿಯ ತಡೆ) | ಹೌದು | +| `i18n translation drift` | i18n ಲೊಕೇಲ್ ಫೈಲ್ಗಳಲ್ಲಿನ ಅನುವಾದಿಸದ ಕೀಗಳು — ಎಚ್ಚರಿಕೆ ಮಾತ್ರ | **ಸಲಹಾತ್ಮಕ** | ### ಜಾಬ್: `i18n-ui-coverage` -| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `check-ui-keys-coverage` (ಇನ್ಲೈನ್) | UI i18n key ವ್ಯಾಪ್ತಿ ≥ 65% ಆಗಿದೆ | ಹೌದು | -| `check-ui-value-drift` (ಇನ್ಲೈನ್) | ಮರುಬರೆಯಲಾದ ಇಂಗ್ಲಿಷ್ **value** ಯಾವುದೇ ಹಳೆಯ ಅನುವಾದವನ್ನು ಉಳಿಸುವುದಿಲ್ಲ | ಹೌದು | -| `check-new-key-coverage` (ಇನ್ಲೈನ್) | ಒಂದು **ಹೊಸ** ಇಂಗ್ಲಿಷ್ key ಅನ್ನು ಪ್ರತಿಯೊಂದು ಲೊಕೇಲ್ನಲ್ಲೂ ಅನುವಾದಿಸಲಾಗಿದೆ — `__MISSING__:` ಮಾರ್ಕರ್ ಅನ್ನು ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ | ಹೌದು | -| `check-translation-ratio` | ಪ್ರತಿ ಲೊಕೇಲ್ನ ನೈಜ-ಅನುವಾದ ಅನುಪಾತವು (ಅನುಮತಿ ಪಟ್ಟಿಯ ಹೊರಗಿರುವ ಇಂಗ್ಲಿಷ್ಗೆ-ತದ್ರೂಪ / placeholder / ಕಾಣೆಯಾದ leaves) `config/quality/i18n-translation-baseline.json` + slack ಅನ್ನು ಮೀರಬಾರದು | **ಸಲಹಾತ್ಮಕ** | +| ಸ್ಕ್ರಿಪ್ಟ್ | ಪರಿಶೀಲಿಸುವುದು | ನಿರ್ಬಂಧಿಸುವುದೇ | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (inline) | UI i18n ಕೀ ವ್ಯಾಪ್ತಿ ≥ 65% ಆಗಿದೆ | ಹೌದು | +| `check-ui-value-drift` (inline) | ಮರುಬರೆಯಲಾದ ಇಂಗ್ಲಿಷ್ **ಮೌಲ್ಯವು** ಯಾವುದೇ ಹಳೆಯ ಅನುವಾದವನ್ನು ಉಳಿಸುವುದಿಲ್ಲ | ಹೌದು | +| `check-new-key-coverage` (inline) | ಒಂದು **ಹೊಸ** ಇಂಗ್ಲಿಷ್ ಕೀ ಪ್ರತಿ ಲೊಕೇಲ್ನಲ್ಲಿಯೂ ಅನುವಾದಗೊಂಡಿದೆ — `__MISSING__:` ಗುರುತನ್ನು ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ | ಹೌದು | +| `check-translation-ratio` | ಪ್ರತಿ ಲೊಕೇಲ್ನ ನೈಜ-ಅನುವಾದ ಅನುಪಾತವು (ಅನುಮತಿ ಪಟ್ಟಿಯ ಹೊರಗೆ ಇಂಗ್ಲಿಷ್ಗೆ ತದ್ರೂಪವಾದ / ಪ್ಲೇಸ್ಹೋಲ್ಡರ್ / ಕಾಣೆಯಾದ ಲೀಫ್ಗಳು) `config/quality/i18n-translation-baseline.json` + ಸಡಿಲಿಕೆಯ ಮಿತಿಯನ್ನು ಮೀರಬಾರದು | **ಸಲಹಾತ್ಮಕ** | -`fetch-depth: 0` ಅಗತ್ಯವಿದೆ — value-drift ಗೇಟ್, merge base ಗೆ ಹೋಲಿಸಿ `en.json` ನ diff ಪರಿಶೀಲಿಸುತ್ತದೆ. +`fetch-depth: 0` ಅಗತ್ಯವಿದೆ — ಮೌಲ್ಯ-ವ್ಯತ್ಯಾಸ ಗೇಟ್, ವಿಲೀನದ ಮೂಲದ ವಿರುದ್ಧ `en.json` ಅನ್ನು ಹೋಲಿಸುತ್ತದೆ. #### `check-ui-value-drift` — ಹಳೆಯ-ಅನುವಾದ ಗೇಟ್ -ಇತರ ಗೇಟ್ಗಳು ರಚನಾತ್ಮಕವಾಗಿ ಗುರುತಿಸಲಾಗದ ಏಕೈಕ i18n regression ಅನ್ನು ಇದು ಪತ್ತೆಹಚ್ಚುತ್ತದೆ: ಇಂಗ್ಲಿಷ್ value ಅನ್ನು -ಮರುಬರೆಯಲಾಗಿದ್ದರೂ, _ಹಿಂದಿನ_ ಇಂಗ್ಲಿಷ್ನಿಂದ ಪಡೆದ ಅನುವಾದಗಳು ಹಾಗೆಯೇ ಉಳಿಯುತ್ತವೆ; ಪರಿಣಾಮವಾಗಿ -ಇಂಗ್ಲಿಷ್ ಹೊರತಾದ ಭಾಷೆಗಳ ಬಳಕೆದಾರರು ಆತ್ಮವಿಶ್ವಾಸದಿಂದ ಬರೆದಿರುವ, ಆದರೆ ಈಗ ತಪ್ಪಾಗಿರುವ ಪಠ್ಯವನ್ನೇ ಓದುತ್ತಿರುತ್ತಾರೆ. +ಇತರ ಗೇಟ್ಗಳು ರಚನಾತ್ಮಕವಾಗಿ ಪತ್ತೆಹಚ್ಚಲಾಗದ ಏಕೈಕ i18n ರಿಗ್ರೆಷನ್ ಅನ್ನು ಇದು ಪತ್ತೆಹಚ್ಚುತ್ತದೆ: ಒಂದು ಇಂಗ್ಲಿಷ್ ಮೌಲ್ಯವನ್ನು +ಮರುಬರೆಯಲಾಗುತ್ತದೆ ಮತ್ತು _ಹಿಂದಿನ_ ಇಂಗ್ಲಿಷ್ನಿಂದ ಪಡೆದ ಅನುವಾದಗಳು ಹಾಗೆಯೇ ಉಳಿಯುತ್ತವೆ, ಆದ್ದರಿಂದ +ಇಂಗ್ಲಿಷ್ ಹೊರತಾದ ಭಾಷೆಗಳ ಬಳಕೆದಾರರು ಆತ್ಮವಿಶ್ವಾಸದಿಂದ ಬರೆಯಲಾದ, ಈಗ ತಪ್ಪಾಗಿರುವ ಪಠ್ಯವನ್ನೇ ಓದುತ್ತಿರುತ್ತಾರೆ. -ಇದು ನಿಜವಾಗಿಯೂ ಬಿಡುಗಡೆಯಾಗಿತ್ತು. Antigravity login helper ಸೇರಿಸಲಾದಾಗ (#5203) -`oauthModal.googleOAuthWarning` ಅನ್ನು ಮರುಬರೆಯಲಾಯಿತು; **43 ಲೊಕೇಲ್ಗಳಲ್ಲಿ 39** ಲೊಕೇಲ್ಗಳು ಆಪರೇಟರ್ಗಳಿಗೆ "ಸಂಪೂರ್ಣ -URL ಅನ್ನು ನಕಲಿಸಿ ಮತ್ತು ಅದನ್ನು ಕೆಳಗೆ ಅಂಟಿಸಿ" ಎಂದು ಹೇಳುವ ಪಠ್ಯವನ್ನೇ ಉಳಿಸಿಕೊಂಡಿದ್ದವು — ಆ provider ಗಾಗಿ ಪೂರ್ಣಗೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲದ flow. ಈ ಕೆಳಗಿನ ಕಾರಣಗಳಿಂದ -#8463 ವರೆಗೆ ಇದು ಗಮನಕ್ಕೆ ಬರಲಿಲ್ಲ: +ಇದು ನಿಜವಾಗಿಯೂ ಬಿಡುಗಡೆಗೊಂಡಿತ್ತು. Antigravity ಲಾಗಿನ್ ಸಹಾಯಕವನ್ನು ಸೇರಿಸಿದಾಗ (#5203) +`oauthModal.googleOAuthWarning` ಅನ್ನು ಮರುಬರೆಯಲಾಗಿತ್ತು; **43 ಲೊಕೇಲ್ಗಳಲ್ಲಿ 39** ಲೊಕೇಲ್ಗಳು ಆಪರೇಟರ್ಗಳಿಗೆ "ಸಂಪೂರ್ಣ +URL ಅನ್ನು ನಕಲಿಸಿ ಮತ್ತು ಕೆಳಗೆ ಅಂಟಿಸಿ" ಎಂದು ಹೇಳುವ ಪಠ್ಯವನ್ನು ಉಳಿಸಿಕೊಂಡಿದ್ದವು — ಆ ಪ್ರೊವೈಡರ್ಗಾಗಿ ಪೂರ್ಣಗೊಳಿಸಲಾಗದ ಪ್ರಕ್ರಿಯೆ. ಈ ಕೆಳಗಿನ ಕಾರಣಗಳಿಂದ +#8463 ವರೆಗೆ ಇದು ಗಮನಕ್ಕೆ ಬಂದಿರಲಿಲ್ಲ: -- `sync-ui-keys` **ಇಲ್ಲದಿರುವ** keys ಅನ್ನು ಮಾತ್ರ backfill ಮಾಡುತ್ತದೆ, **ಹಳೆಯದಾದ** keys ಅನ್ನು ಎಂದಿಗೂ ಮಾಡುವುದಿಲ್ಲ; -- `check-ui-keys-coverage` key _ಇರುವಿಕೆಯನ್ನು_ ಎಣಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಹಳೆಯ ಅನುವಾದವೂ ಒಳಗೊಂಡಿದೆ ಎಂದು ಪರಿಗಣಿಸಲ್ಪಡುತ್ತದೆ; -- `check-translation-drift` ಎಂಬುದು `docs/i18n//**.md` documentation mirrors ಅನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡುತ್ತದೆ — - ಅದು `src/i18n/messages/*.json` ಅನ್ನು ಎಂದಿಗೂ ಓದುವುದಿಲ್ಲ. 2026-09 ಮರು-ಸಿಂಕ್ನಿಂದ ಜಾಬ್ `docs-sync-strict` ನಲ್ಲಿ ತಡೆಯಲಾಗುತ್ತಿದೆ: - core doc ಅನ್ನು ಸಂಪಾದಿಸಿ → `npm run i18n:run -- --files=` (ವಿಭಾಗ-ಮಟ್ಟದ, ಕಡಿಮೆ ವೆಚ್ಚದ). +- `sync-ui-keys` **ಇಲ್ಲದಿರುವ** ಕೀಗಳನ್ನು ಮಾತ್ರ ಬ್ಯಾಕ್ಫಿಲ್ ಮಾಡುತ್ತದೆ, **ಹಳೆಯದಾದ** ಕೀಗಳನ್ನು ಎಂದಿಗೂ ಅಲ್ಲ; +- `check-ui-keys-coverage` ಕೀಗಳ _ಉಪಸ್ಥಿತಿಯನ್ನು_ ಎಣಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಹಳೆಯ ಅನುವಾದವೂ ವ್ಯಾಪ್ತಿಗೆ ಒಳಪಟ್ಟಂತೆ ಪರಿಗಣಿಸಲ್ಪಡುತ್ತದೆ; +- `check-translation-drift` ಎಂಬುದು `docs/i18n//**.md` ದಸ್ತಾವೇಜೀಕರಣ ಮಿರರ್ಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡುತ್ತದೆ — + ಅದು ಎಂದಿಗೂ `src/i18n/messages/*.json` ಅನ್ನು ಓದುವುದಿಲ್ಲ. 2026-09 ಮರು-ಸಿಂಕ್ನಿಂದ `docs-sync-strict` ಜಾಬ್ನಲ್ಲಿ ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತಿದೆ: + ಪ್ರಮುಖ doc ಅನ್ನು ಸಂಪಾದಿಸಿ → `npm run i18n:run -- --files=` (ವಿಭಾಗ-ಮಟ್ಟದ, ಕಡಿಮೆ ವೆಚ್ಚದ). -**ಡಿಫ್-ಅರಿವುಳ್ಳದ್ದು, ಬೇಸ್ಲೈನ್-ಆಧಾರಿತವಲ್ಲ.** ಇದು ವಿಲೀನದ ಮೂಲದಲ್ಲಿರುವ `en.json` ಅನ್ನು -ವರ್ಕಿಂಗ್ ಟ್ರೀಯೊಂದಿಗೆ ಹೋಲಿಸುತ್ತದೆ; ಇಂಗ್ಲಿಷ್ ಮೌಲ್ಯ ಬದಲಾಗಿರುವ ಪ್ರತಿಯೊಂದು ಕೀಗಾಗಿ, ಇನ್ನೂ -ಬದಲಾಗದ ಅನುವಾದವನ್ನು ಹೊಂದಿರುವ ಯಾವುದೇ ಲೊಕೇಲ್ ಹಳತಾಗಿದೆ. ಇದು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ **ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಬಾಕಿಯನ್ನು ಸ್ಥಗಿತಗೊಳಿಸುತ್ತದೆ** — ದೀರ್ಘಕಾಲದಿಂದ ಇರುವ ಅನುವಾದವು ಯಾವ ಹಳೆಯ ಇಂಗ್ಲಿಷ್ನಿಂದ ಬಂದಿದೆ ಎಂಬುದನ್ನು ಡಿಫ್ -ಬಹಿರಂಗಪಡಿಸಲಾರದು, ಆದ್ದರಿಂದ ಗೇಟ್ ಪ್ರಸ್ತುತ ಬದಲಾವಣೆಯು ಸ್ಪರ್ಶಿಸುವುದನ್ನು ಮಾತ್ರ ನಿರ್ಣಯಿಸುತ್ತದೆ. -ಪರ್ಯಾಯವು (ಪ್ರತಿ-ಕೀ ಹ್ಯಾಶ್ ಬೇಸ್ಲೈನ್) ಸುಮಾರು 600 KB ಗಾತ್ರದ ರಚಿಸಲಾದ ಫೈಲ್ ಅಗತ್ಯಪಡಿಸುತ್ತದೆ, -ಇದು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅತಿ ದೊಡ್ಡ ಬೇಸ್ಲೈನ್ಗಿಂತ 3× ದೊಡ್ಡದಾಗಿದ್ದು, ಪ್ರತಿ i18n PR ನಲ್ಲೂ ಬದಲಾವಣೆಗಳನ್ನು ಉಂಟುಮಾಡುತ್ತದೆ. +**ವ್ಯತ್ಯಾಸ-ಅರಿವಿನದು, ಬೇಸ್ಲೈನ್-ಆಧಾರಿತವಲ್ಲ.** ಇದು ವಿಲೀನ ಬೇಸ್ನಲ್ಲಿರುವ `en.json` ಅನ್ನು +ವರ್ಕಿಂಗ್ ಟ್ರೀಯೊಂದಿಗೆ ಹೋಲಿಸುತ್ತದೆ; ಇಂಗ್ಲಿಷ್ ಮೌಲ್ಯ ಬದಲಾದ ಪ್ರತಿಯೊಂದು ಕೀಗಾಗಿ, ಇನ್ನೂ +ಬದಲಾಯಿಸದ ಅನುವಾದವನ್ನು ಹೊಂದಿರುವ ಯಾವುದೇ ಲೊಕೇಲ್ ಹಳೆಯದಾಗಿದೆ. ಇದು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ **ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಬಾಕಿಯನ್ನು ಸ್ಥಗಿತಗೊಳಿಸುತ್ತದೆ** — ದೀರ್ಘಕಾಲದಿಂದ ಇರುವ ಅನುವಾದವು ಯಾವ ಹಳೆಯ ಇಂಗ್ಲಿಷ್ನಿಂದ ಬಂದಿದೆ ಎಂಬುದನ್ನು +ವ್ಯತ್ಯಾಸವು ಬಹಿರಂಗಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ, ಆದ್ದರಿಂದ ಪ್ರಸ್ತುತ ಬದಲಾವಣೆಯು ಸ್ಪರ್ಶಿಸುವುದನ್ನು ಮಾತ್ರ ಗೇಟ್ ನಿರ್ಣಯಿಸುತ್ತದೆ. +ಪರ್ಯಾಯಕ್ಕೆ (ಪ್ರತಿ-ಕೀ ಹ್ಯಾಶ್ ಬೇಸ್ಲೈನ್) ~600 KB ರಚಿಸಲಾದ ಫೈಲ್ ಅಗತ್ಯವಿರುತ್ತದೆ, +ಇದು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅತಿದೊಡ್ಡ ಬೇಸ್ಲೈನ್ಗಿಂತ 3× ದೊಡ್ಡದು ಮತ್ತು ಪ್ರತಿಯೊಂದು i18n PRನಲ್ಲಿಯೂ ಬದಲಾವಣೆಗೆ ಒಳಗಾಗುತ್ತದೆ. ಇದನ್ನು ಪೂರೈಸಲು ಎರಡು ಮಾರ್ಗಗಳಿವೆ: 1. ಪರಿಣಾಮಕ್ಕೊಳಗಾದ ಅನುವಾದಗಳನ್ನು ನವೀಕರಿಸಿ, ಅಥವಾ -2. ಅವುಗಳನ್ನು `__MISSING__:` ಎಂದು ಹೊಂದಿಸಿ — ಆಗ ರನ್ಟೈಮ್ ಸರಿಪಡಿಸಿದ ಇಂಗ್ಲಿಷ್ ಅನ್ನು ಒದಗಿಸುತ್ತದೆ - (`src/i18n/request.ts::deepMergeFallback`, #7258) ಮತ್ತು ಕೀ ಅನುವಾದಕ್ಕಾಗಿ ಸರದಿಗೆ ಸೇರುತ್ತದೆ. +2. ಅವುಗಳನ್ನು `__MISSING__:` ಎಂದು ಹೊಂದಿಸಿ — ನಂತರ ರನ್ಟೈಮ್ ಸರಿಪಡಿಸಿದ ಇಂಗ್ಲಿಷ್ ಅನ್ನು ಒದಗಿಸುತ್ತದೆ + (`src/i18n/request.ts::deepMergeFallback`, #7258) ಮತ್ತು ಕೀ ಅನುವಾದಕ್ಕಾಗಿ ಸರತಿಗೆ ಸೇರುತ್ತದೆ. -ಸ್ಟ್ರಿಂಗ್ನ **ಅರ್ಥ** ಬದಲಾಗಿದ್ದರೆ, **ಕೀಗೆ ಮರುಹೆಸರಿಸುವುದಕ್ಕೆ** ಆದ್ಯತೆ ನೀಡಿ: ಹೊಸ ಕೀ -ಹಳತಾದ ಅನುವಾದವನ್ನು ಆನುವಂಶಿಕವಾಗಿ ಪಡೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ. #8463 ಬಳಸಿದ ಮಾದರಿ ಇದೇ. +ಸ್ಟ್ರಿಂಗ್ನ **ಅರ್ಥ** ಬದಲಾಗಿದ್ದರೆ, **ಕೀಗೆ ಮರುಹೆಸರಿಸುವುದಕ್ಕೆ** ಆದ್ಯತೆ ನೀಡಿ: ಹೊಸ ಕೀಗೆ +ಹಳೆಯ ಅನುವಾದವನ್ನು ಆನುವಂಶಿಕವಾಗಿ ಪಡೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ. #8463 ಬಳಸಿದ ಮಾದರಿ ಇದೇ. ```bash -npm run i18n:check-value-drift # ಕಟ್ಟುನಿಟ್ಟಿನದು (CI ಚಲಾಯಿಸುವುದು) +npm run i18n:check-value-drift # ಕಟ್ಟುನಿಟ್ಟಾದುದು (CI ಚಲಾಯಿಸುವುದು) npm run i18n:check-value-drift:warn # ವರದಿ ಮಾತ್ರ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -ಮೂಲ ಕ್ಯಾಟಲಾಗ್ ಅನ್ನು ಓದಲು ಸಾಧ್ಯವಾಗದಿದ್ದಾಗ (ಬೇಸ್ ref ಇಲ್ಲದ ಶಾಲೋ -ಕ್ಲೋನ್), `check-openapi-breaking` ಅನ್ನು ಅನುಸರಿಸುವಂತೆ, `SKIP reason=base-unresolved` ಜೊತೆಗೆ 0 ಅನ್ನು ನಿರ್ಗಮನ ಮೌಲ್ಯವಾಗಿ ನೀಡುತ್ತದೆ. +ಬೇಸ್ ಕ್ಯಾಟಲಾಗ್ ಅನ್ನು ಓದಲು ಸಾಧ್ಯವಾಗದಿದ್ದಾಗ (ಬೇಸ್ ref ಇಲ್ಲದ ಶಾಲೋ +ಕ್ಲೋನ್), `check-openapi-breaking` ಅನ್ನು ಅನುಸರಿಸುವಂತೆ `SKIP reason=base-unresolved` ಜೊತೆಗೆ 0 ಮೌಲ್ಯದಿಂದ ನಿರ್ಗಮಿಸುತ್ತದೆ. ### ಜಾಬ್: `i18n` -ಸಂಪೂರ್ಣ i18n ಮೌಲ್ಯೀಕರಣ ಮ್ಯಾಟ್ರಿಕ್ಸ್ (ಪ್ರತಿ ಲೊಕೇಲ್ಗೆ ಒಂದು ಜಾಬ್). ಇಡೀ ಜಾಬ್ ಸಲಹಾತ್ಮಕವಾಗಿದೆ. +ಸಂಪೂರ್ಣ i18n ಮೌಲ್ಯಮಾಪನ ಮ್ಯಾಟ್ರಿಕ್ಸ್ (ಪ್ರತಿ ಲೊಕೇಲ್ಗೆ ಒಂದು ಜಾಬ್). ಸಂಪೂರ್ಣ ಜಾಬ್ ಸಲಹಾತ್ಮಕವಾಗಿದೆ. -| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ------------------------------- | ---------------------------- | ------------------------------------------------------ | -| `validate_translation.py quick` | ಪ್ರತಿ ಲೊಕೇಲ್ನ ಅನುವಾದ ಪೂರ್ಣತೆ | **ಸಲಹಾತ್ಮಕ** (ಇಡೀ ಜಾಬ್ನಲ್ಲಿ `continue-on-error: true`) | +| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ನಿರ್ಬಂಧಿಸುವಿಕೆ | +| ------------------------------- | ------------------------------- | ---------------------------------------------------------- | +| `validate_translation.py quick` | ಪ್ರತಿ ಲೊಕೇಲ್ನ ಅನುವಾದದ ಸಂಪೂರ್ಣತೆ | **ಸಲಹಾತ್ಮಕ** (ಸಂಪೂರ್ಣ ಜಾಬ್ನಲ್ಲಿ `continue-on-error: true`) | ### ಜಾಬ್: `pr-test-policy` -ಪುಲ್ ರಿಕ್ವೆಸ್ಟ್ಗಳಲ್ಲಿ ಮಾತ್ರ ಚಲಿಸುತ್ತದೆ. +ಪುಲ್ ರಿಕ್ವೆಸ್ಟ್ಗಳಲ್ಲಿ ಮಾತ್ರ ರನ್ ಆಗುತ್ತದೆ. -| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, ಅಥವಾ `bin/` ನಲ್ಲಿನ ಪ್ರೊಡಕ್ಷನ್ ಕೋಡ್ ಬದಲಾಯಿಸುವ PRಗಳು ಪರೀಕ್ಷೆಗಳನ್ನು ಸೇರಿಸಬೇಕು ಅಥವಾ ನವೀಕರಿಸಬೇಕು (ಕಠಿಣ ನಿಯಮ #8) | ಹೌದು | -| `check:test-masking` | ಬದಲಾದ ಪರೀಕ್ಷಾ ಫೈಲ್ಗಳು ಒಟ್ಟು assert ಸಂಖ್ಯೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುವುದಿಲ್ಲ ಅಥವಾ `assert.ok(true)` ಪುನರುಕ್ತಿಗಳನ್ನು ಸೇರಿಸುವುದಿಲ್ಲ | ಹೌದು | -| `check:pr-evidence` | PR ವಿವರಣೆಯು ಬದಲಾವಣೆಗೆ ಸಂಬಂಧಿಸಿದ ಪರೀಕ್ಷೆ/VPS ಸಾಕ್ಷ್ಯವನ್ನು ಉಲ್ಲೇಖಿಸುತ್ತದೆ (PR ಗದ್ಯವನ್ನು grep ಮಾಡುವ ಮೂಲಕ ಕಠಿಣ ನಿಯಮ #18 ಅನ್ನು ಯಾಂತ್ರೀಕರಿಸುತ್ತದೆ — ದುರ್ಬಲವಾಗಿದೆ, Backlog ನೋಡಿ) | ಹೌದು | +| ಸ್ಕ್ರಿಪ್ಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ನಿರ್ಬಂಧಿಸುವಿಕೆ | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, ಅಥವಾ `bin/` ನಲ್ಲಿನ ಪ್ರೊಡಕ್ಷನ್ ಕೋಡ್ ಅನ್ನು ಬದಲಾಯಿಸುವ PRಗಳು ಪರೀಕ್ಷೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬೇಕು ಅಥವಾ ನವೀಕರಿಸಬೇಕು (ಕಠಿಣ ನಿಯಮ #8) | ಹೌದು | +| `check:test-masking` | ಬದಲಾದ ಪರೀಕ್ಷಾ ಫೈಲ್ಗಳು ನಿವ್ವಳ ಅಸರ್ಶನ್ ಎಣಿಕೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುವುದಿಲ್ಲ ಅಥವಾ `assert.ok(true)` ನಿರರ್ಥಕ ಸತ್ಯಗಳನ್ನು ಸೇರಿಸುವುದಿಲ್ಲ | ಹೌದು | +| `check:pr-evidence` | PR ವಿವರಣೆಯು ಬದಲಾವಣೆಗಾಗಿ ಪರೀಕ್ಷೆ/VPS ಸಾಕ್ಷ್ಯವನ್ನು ಉಲ್ಲೇಖಿಸುತ್ತದೆ (PR ಪಠ್ಯದಲ್ಲಿ grep ಮಾಡುವ ಮೂಲಕ ಕಠಿಣ ನಿಯಮ #18 ಅನ್ನು ಯಾಂತ್ರೀಕರಿಸುತ್ತದೆ — ದುರ್ಬಲವಾಗಿದೆ, ಬ್ಯಾಕ್ಲಾಗ್ ನೋಡಿ) | ಹೌದು | ### ಜಾಬ್: `test-vitest` -`build` ನಂತರ ಚಲಿಸುತ್ತದೆ. ವಿಫಲವಾದರೆ ವಿಲೀನವನ್ನು ತಡೆಯುತ್ತದೆ. +`build` ನಂತರ ರನ್ ಆಗುತ್ತದೆ. ವಿಫಲವಾದರೆ ವಿಲೀನವನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ. -| ಸೂಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ---------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP ಸರ್ವರ್ (110 ಟೂಲ್ಗಳು), autoCombo, ಕ್ಯಾಶ್ — vitest ರನ್ನರ್ | ಹೌದು | -| `test:vitest:ui` | UI ಕಾಂಪೊನೆಂಟ್ ಪರೀಕ್ಷೆಗಳು — vitest ರನ್ನರ್ | **ತಡೆಯುತ್ತದೆ** — ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ವಿಫಲತೆಗಳನ್ನು `vitest.config.ts` ನಲ್ಲಿ ಸ್ಪಷ್ಟವಾಗಿ ಹೊರಗಿಡಲಾಗಿದೆ; ಹೊಸ ವಿಫಲತೆಗಳು ಜಾಬ್ ಅನ್ನು ವಿಫಲಗೊಳಿಸುತ್ತವೆ | +| ಸೂಟ್ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ನಿರ್ಬಂಧಿಸುವಿಕೆ | +| ---------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP ಸರ್ವರ್ (110 ಉಪಕರಣಗಳು), autoCombo, ಕ್ಯಾಶ್ — vitest ರನ್ನರ್ | ಹೌದು | +| `test:vitest:ui` | UI ಕಾಂಪೊನೆಂಟ್ ಪರೀಕ್ಷೆಗಳು — vitest ರನ್ನರ್ | **ನಿರ್ಬಂಧಿಸುವುದು** — ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ವೈಫಲ್ಯಗಳನ್ನು `vitest.config.ts` ನಲ್ಲಿ ಸ್ಪಷ್ಟವಾಗಿ ಹೊರಗಿಡಲಾಗಿದೆ; ಹೊಸ ವೈಫಲ್ಯಗಳು ಜಾಬ್ ಅನ್ನು ವಿಫಲಗೊಳಿಸುತ್ತವೆ | -### ರಾತ್ರಿಯ ವರ್ಕ್ಫ್ಲೋಗಳು (ವೇಳಾಪಟ್ಟಿ ಪ್ರಕಾರ, ಸಲಹಾತ್ಮಕ) +### ರಾತ್ರಿಯ ವರ್ಕ್ಫ್ಲೋಗಳು (ವೇಳಾಪಟ್ಟಿಯಂತೆ, ಸಲಹಾತ್ಮಕ) -ಇವು cron ವೇಳಾಪಟ್ಟಿಯಲ್ಲಿ (ಮತ್ತು `workflow_dispatch` ಮೂಲಕ) ಚಲಿಸುತ್ತವೆ, PRಗಳಲ್ಲಿ ಎಂದಿಗೂ ಚಲಿಸುವುದಿಲ್ಲ. ಎಲ್ಲವೂ ಸಲಹಾತ್ಮಕವಾಗಿವೆ. +ಇವು cron ವೇಳಾಪಟ್ಟಿಯಂತೆ (ಮತ್ತು `workflow_dispatch` ಮೂಲಕ) ರನ್ ಆಗುತ್ತವೆ, PRಗಳಲ್ಲಿ ಎಂದಿಗೂ ರನ್ ಆಗುವುದಿಲ್ಲ. ಎಲ್ಲವೂ ಸಲಹಾತ್ಮಕವಾಗಿವೆ. -| ವರ್ಕ್ಫ್ಲೋ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ತಡೆಯುವಿಕೆ | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | -| `nightly-property` | ಯಾದೃಚ್ಛಿಕ seed + ಹೆಚ್ಚಿನ ರನ್ ಸಂಖ್ಯೆಯೊಂದಿಗೆ fast-check ಪ್ರಾಪರ್ಟಿ ಪರೀಕ್ಷೆಗಳು | **ಸಲಹಾತ್ಮಕ** | -| `nightly-resilience` | ಹೀಪ್-ಬೆಳವಣಿಗೆ ಗೇಟ್, chaos fault-injection, k6 ಲೋಡ್/soak ಪರೀಕ್ಷೆ | **ಸಲಹಾತ್ಮಕ** | -| `nightly-llm-security` | promptfoo ಇಂಜೆಕ್ಷನ್ ಗಾರ್ಡ್ (ಬ್ಲಾಕ್ ಮೋಡ್) + garak ಪ್ರೋಬ್ಗಳು (ಪ್ರೊವೈಡರ್ ಸೀಕ್ರೆಟ್ ಇಲ್ಲದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡಲಾಗುತ್ತದೆ) | **ಸಲಹಾತ್ಮಕ** | -| `nightly-schemathesis` | `docs/openapi.yaml` ಬಳಸಿ ಲೈವ್ OmniRoute ವಿರುದ್ಧ OpenAPI ಕಾಂಟ್ರಾಕ್ಟ್ fuzzing (schemathesis) — ಸ್ಪೆಕ್ ಉಲ್ಲಂಘನೆಗಳು / ನಿರ್ವಹಿಸದ 500ಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತದೆ (ಹಂತ 8 B.4) | **ಸಲಹಾತ್ಮಕ** | -| `nightly-mutation` | ವೇಗದ ಯೂನಿಟ್ ಲೇನ್ನಾದ್ಯಂತ Stryker mutation-testing ಸ್ಕೋರ್ — ಉಳಿದುಕೊಳ್ಳುವ mutants ದುರ್ಬಲ assertಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತವೆ | **ಸಲಹಾತ್ಮಕ** | -| `nightly-compat` | ಬೆಂಬಲಿತ `engines.node` ಶ್ರೇಣಿಗಳಾದ್ಯಂತ Node ಎಂಜಿನ್ ಹೊಂದಾಣಿಕೆ ಮ್ಯಾಟ್ರಿಕ್ಸ್ | **ಸಲಹಾತ್ಮಕ** | +| ವರ್ಕ್ಫ್ಲೋ | ಮೌಲ್ಯೀಕರಿಸುವುದು | ನಿರ್ಬಂಧಿಸುವಿಕೆ | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | ಯಾದೃಚ್ಛಿಕ ಸೀಡ್ + ಹೆಚ್ಚಿನ ರನ್ ಎಣಿಕೆಯೊಂದಿಗೆ fast-check ಪ್ರಾಪರ್ಟಿ ಪರೀಕ್ಷೆಗಳು | **ಸಲಹಾತ್ಮಕ** | +| `nightly-resilience` | ಹೀಪ್-ಬೆಳವಣಿಗೆ ಗೇಟ್, ಕೆಯಾಸ್ ದೋಷ-ಇಂಜೆಕ್ಷನ್, k6 ಲೋಡ್/ಸೋಕ್ | **ಸಲಹಾತ್ಮಕ** | +| `nightly-llm-security` | promptfoo ಇಂಜೆಕ್ಷನ್ ಗಾರ್ಡ್ (ಬ್ಲಾಕ್ ಮೋಡ್) + garak ಪ್ರೋಬ್ಗಳು (ಪ್ರೊವೈಡರ್ ಸೀಕ್ರೆಟ್ ಇಲ್ಲದಿದ್ದರೆ ಬಿಟ್ಟುಬಿಡಲಾಗುತ್ತದೆ) | **ಸಲಹಾತ್ಮಕ** | +| `nightly-schemathesis` | `docs/openapi.yaml` ಬಳಸಿಕೊಂಡು ಲೈವ್ OmniRoute ವಿರುದ್ಧ OpenAPI ಕಾಂಟ್ರಾಕ್ಟ್ ಫಝಿಂಗ್ (schemathesis) — ಸ್ಪೆಕ್ ಉಲ್ಲಂಘನೆಗಳು / ನಿರ್ವಹಿಸದ 500 ದೋಷಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತದೆ (ಹಂತ 8 B.4) | **ಸಲಹಾತ್ಮಕ** | +| `nightly-mutation` | ವೇಗದ ಯೂನಿಟ್ ಲೇನ್ನಾದ್ಯಂತ Stryker ಮ್ಯೂಟೇಶನ್-ಪರೀಕ್ಷಾ ಸ್ಕೋರ್ — ಉಳಿದುಕೊಳ್ಳುವ ಮ್ಯೂಟಂಟ್ಗಳು ದುರ್ಬಲ ಅಸರ್ಶನ್ಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತವೆ | **ಸಲಹಾತ್ಮಕ** | +| `nightly-compat` | ಬೆಂಬಲಿತ `engines.node` ಶ್ರೇಣಿಗಳಾದ್ಯಂತ Node ಎಂಜಿನ್ ಹೊಂದಾಣಿಕೆ ಮ್ಯಾಟ್ರಿಕ್ಸ್ | **ಸಲಹಾತ್ಮಕ** | --- @@ -534,43 +534,43 @@ CI ಗೇಟ್ಗಳ ಜೊತೆಗೆ, OmniRoute ಒಂದು **ಆಯ್ಕ --- -## ತರ್ಕಬದ್ಧೀಕರಣ ಬಾಕಿಪಟ್ಟಿ (ROI ಪರಿಶೀಲನೆ — ಹಂತ 9 ಅಲೆ 3) +## ತರ್ಕಬದ್ಧಗೊಳಿಸುವಿಕೆ ಬಾಕಿಪಟ್ಟಿ (ROI ಪರಿಶೀಲನೆ — ಹಂತ 9 ಅಲೆ 3) -ಈ ದಾಸ್ತಾನನ್ನು 2026-06-17 ರಂದು `ci.yml` ಗೆ ಹೋಲಿಸಿ ಸಮನ್ವಯಗೊಳಿಸಲಾಗಿದೆ (ಹಿಂದಿನ ಆವೃತ್ತಿಯಲ್ಲಿ +ಈ ಪಟ್ಟಿಯನ್ನು 2026-06-17 ರಂದು `ci.yml` ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆ ಮಾಡಲಾಗಿದೆ (ಹಿಂದಿನ ಆವೃತ್ತಿಯಲ್ಲಿ `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` ಬಿಟ್ಟುಹೋಗಿದ್ದವು). ಸಮನ್ವಯಗೊಳಿಸಿದ ಸಮೂಹದ ROI ಪರಿಶೀಲನೆಯು -ಕೆಳಗಿನ ತರ್ಕಬದ್ಧೀಕರಣ ಅಭ್ಯರ್ಥಿಗಳನ್ನು ಗುರುತಿಸಿದೆ. **ವಿಲೀನಗಳು ಯಾಂತ್ರಿಕ CI -ಬದಲಾವಣೆಗಳಾಗಿವೆ; ಬದಲಾವಣೆಗಳು/ತೆಗೆದುಹಾಕುವಿಕೆಗಳು ಆಪರೇಟರ್ಗೆ ಮೀಸಲಾದ ನೀತಿ ನಿರ್ಧಾರಗಳಾಗಿವೆ.** ಕೆಳಗಿನ ಯಾವುದನ್ನೂ +`check:codeql-ratchet`, `check:pr-evidence` ಬಿಟ್ಟುಹೋಗಿದ್ದವು). ಹೊಂದಾಣಿಕೆ ಮಾಡಿದ ಸಮೂಹದ ROI ಪರಿಶೀಲನೆಯು +ಕೆಳಗಿನ ತರ್ಕಬದ್ಧಗೊಳಿಸುವಿಕೆ ಅಭ್ಯರ್ಥಿಗಳನ್ನು ಗುರುತಿಸಿದೆ. **ವಿಲೀನಗಳು ಯಾಂತ್ರಿಕ CI +ಬದಲಾವಣೆಗಳಾಗಿವೆ; ತಿರುಗಿಸುವಿಕೆಗಳು/ತೆಗೆದುಹಾಕುವಿಕೆಗಳು ನಿರ್ವಾಹಕರಿಗೆ ಮೀಸಲಾದ ನೀತಿ ನಿರ್ಧಾರಗಳಾಗಿವೆ.** ಕೆಳಗಿನ ಯಾವುದನ್ನೂ ಇನ್ನೂ ಅನ್ವಯಿಸಲಾಗಿಲ್ಲ. -**ಮೇಲೆ ದಾಖಲಿಸದೆ ಉಳಿದಿರುವವುಗಳೂ ಇವೆ** (ಸಲಹಾತ್ಮಕ, ಕಡಿಮೆ ಸಂಕೇತ): `docs-lint` job -(markdownlint + Vale, ಸಂಪೂರ್ಣ job `continue-on-error`) ಮತ್ತು ಸ್ವತಂತ್ರ ಸ್ಕ್ಯಾನರ್ workflowಗಳಾದ +**ಮೇಲೆ ದಾಖಲಿಸದಿರುವವುಗಳೂ ಇವೆ** (ಸಲಹಾತ್ಮಕ, ಕಡಿಮೆ ಸಂಕೇತ): `docs-lint` ಜಾಬ್ +(markdownlint + Vale, ಸಂಪೂರ್ಣ ಜಾಬ್ಗೆ `continue-on-error`) ಮತ್ತು ಸ್ವತಂತ್ರ ಸ್ಕ್ಯಾನರ್ ವರ್ಕ್ಫ್ಲೋಗಳಾದ `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ಎಂಬುದು -`quality-baseline.json` ನಲ್ಲಿದೆ, ಆದರೆ `ci.yml` ನಲ್ಲಿನ ತಡೆಗಟ್ಟುವ ratchetಗೆ ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ — ಈ metric -ಪ್ರಸ್ತುತ ಅನಾಥವಾಗಿದೆ. +`quality-baseline.json` ನಲ್ಲಿದೆ, ಆದರೆ `ci.yml` ನಲ್ಲಿ ತಡೆಹಿಡಿಯುವ ರ್ಯಾಚೆಟ್ಗೆ ಜೋಡಿಸಲಾಗಿಲ್ಲ — ಈ ಮೆಟ್ರಿಕ್ ಪ್ರಸ್ತುತ +ಅನಾಥವಾಗಿದೆ. ### ವಿಲೀನ / ನಕಲು ನಿವಾರಣೆ (ಯಾಂತ್ರಿಕ, ಕಡಿಮೆ ಅಪಾಯ) -ಪ್ರತಿ ಅಭ್ಯರ್ಥಿಯನ್ನೂ 2026-06-17 ರಲ್ಲಿದ್ದ ಸಕ್ರಿಯ gate ಸ್ಥಿತಿಗೆ ಹೋಲಿಸಿ ಮೌಲ್ಯೀಕರಿಸಲಾಗಿದೆ (ನಂಬಿ, ಆದರೆ ಪರಿಶೀಲಿಸಿ); -ಹಲವು "ಸ್ಪಷ್ಟ" ವಿಲೀನಗಳು ಅಡಗಿದ ತಾಂತ್ರಿಕ ಸಾಲವನ್ನು ಮರೆಮಾಡುತ್ತವೆ ಎಂದು ಕಂಡುಬಂದಿದ್ದು, ಅವು **ನೇರವಾಗಿ ಬದಲಿಸಬಹುದಾದವುಗಳಲ್ಲ**. - -- **`check:docs-sync` ಎರಡು ಬಾರಿ ಚಲಿಸುತ್ತದೆ** — `lint` job ನಲ್ಲಿ ಸ್ವತಂತ್ರವಾಗಿ ಮತ್ತು `check:docs-all` (`docs-sync-strict`) ಒಳಗೆ ಹಾಗೂ husky pre-commit hookನಲ್ಲಿ ಮತ್ತೊಮ್ಮೆ. ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** — ಸ್ವತಂತ್ರ `lint` invocation ತೆಗೆದುಹಾಕಲಾಗಿದೆ. -- **CVE ಸ್ಕ್ಯಾನಿಂಗ್** — ❌ **ಸ್ವಚ್ಛವಾದ ವಿಲೀನವಲ್ಲ.** ಯಾವುದೇ high/critical CVE ಕಂಡುಬಂದರೆ `audit:deps` ಕಡ್ಡಾಯವಾಗಿ ವಿಫಲವಾಗುತ್ತದೆ; `check:vuln-ratchet` (osv) baselineಗೆ ಹೋಲಿಸಿದಾಗ _ಹಿಂಜರಿತ_ ಉಂಟಾದರೆ ಮಾತ್ರ ವಿಫಲವಾಗುತ್ತದೆ (ಪ್ರಸ್ತುತ 1 MODERATE). ಅರ್ಥವ್ಯಾಪ್ತಿಗಳು ಭಿನ್ನವಾಗಿವೆ — `audit:deps` ತೆಗೆದುಹಾಕಿದರೆ ನಿರಪೇಕ್ಷ high/critical gate ಕಳೆದುಹೋಗುತ್ತದೆ. ಎರಡನ್ನೂ ಉಳಿಸಿಕೊಳ್ಳಿ. -- **Cycle ಪತ್ತೆ** — ❌ **ಸ್ವಚ್ಛವಾದ ವಿಲೀನವಲ್ಲ.** `check:circular-deps` (dpdm) **91 cycles** ವರದಿ ಮಾಡುತ್ತದೆ (ಅದಕ್ಕಾಗಿಯೇ ಅದು ಸಲಹಾತ್ಮಕವಾಗಿದೆ); ಅವುಗಳನ್ನು ಮೊದಲು ಪರಿಹರಿಸದೆ ಅದನ್ನು ತಡೆಗಟ್ಟುವ ಹಂತಕ್ಕೆ ಏರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ, ಮತ್ತು green ಆಗಿರುವ, ಆಯ್ದ `check:cycles` ಗಿಂತ ಇದರ ವ್ಯಾಪ್ತಿ ವಿಶಾಲವಾಗಿದೆ. `check:cycles` ಅನ್ನು ತಡೆಗಟ್ಟುವಂತೆಯೇ ಉಳಿಸಿಕೊಳ್ಳಿ; 91 dpdm cyclesಗಳನ್ನು ಪರಿಹರಿಸುವುದು ಪ್ರತ್ಯೇಕ ಬಾಕಿಪಟ್ಟಿಯಾಗಿದೆ. -- **ಸಂಕೀರ್ಣತೆ** — ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ಒಂದೇ ESLint walk, ruleId ಪ್ರಕಾರ ಎಣಿಕೆ ಮಾಡುವುದರಿಂದ cyclomatic+max-lines ಮತ್ತು cognitive baselineಗಳು ಸ್ವತಂತ್ರವಾಗಿ ಉಳಿಯುತ್ತವೆ; ಸ್ಥಳೀಯ `--update` ಗಾಗಿ ಪ್ರತ್ಯೇಕ `check:complexity` / `check:cognitive-complexity` ಉಳಿದಿವೆ. -- **`/api` anti-hallucination** — ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ಯ ಒಂದೇ FS inventory, openapi-routes + docs-symbols ಇನ್ನೂ ಸ್ವತಂತ್ರವಾಗಿ ವರದಿ ಮಾಡುತ್ತವೆ; ಸ್ಥಳೀಯ runಗಳಿಗಾಗಿ ಪ್ರತ್ಯೇಕವಾದವುಗಳು ಉಳಿದಿವೆ. -- **`check:node-runtime` 11 jobಗಳಲ್ಲಿ ಚಲಿಸುತ್ತದೆ** — ⚠️ **ಕಡಿಮೆ ROI.** ಪ್ರತಿಯೊಂದೂ ಪ್ರತ್ಯೇಕ runner ಆಗಿದ್ದು check <1s ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ; ಅಗ್ಗದ ಪ್ರತಿ-job guard ಅನ್ನು ಕಳೆದುಕೊಳ್ಳುವುದಕ್ಕೆ ಪ್ರತಿಯಾಗಿ ಒಟ್ಟು ಉಳಿತಾಯ ~10s. ಈ ಬದಲಾವಣೆಯ ಗೊಂದಲಕ್ಕೆ ತಕ್ಕಷ್ಟು ಮೌಲ್ಯವಿಲ್ಲ. -- **CI lintನಲ್ಲಿನ `typecheck:noimplicit:core`** — ✅ **lint jobನಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ** (ಇದು ಸಲಹಾತ್ಮಕ `continue-on-error` ಆಗಿತ್ತು); ತಡೆಗಟ್ಟುವ type surface ಎಂದರೆ `typecheck:core` + `check:type-coverage`. ಸ್ಥಳೀಯ script ಉಳಿಸಿಕೊಳ್ಳಲಾಗಿದೆ. - -### ಬದಲಿಸಿ / ನಿರ್ಧರಿಸಿ (ಆಪರೇಟರ್ ನೀತಿ) - -- `check:openapi-security-tiers` (ಸಲಹಾತ್ಮಕ) — ❌ **ನೇರವಾಗಿ ಬದಲಿಸಲಾಗುವುದಿಲ್ಲ.** ಇದು 0 ನೊಂದಿಗೆ ನಿರ್ಗಮಿಸುತ್ತದೆ, ಆದರೆ `LOCAL_ONLY_API_PREFIXES` ಅಡಿಯಲ್ಲಿರುವ ಹಲವಾರು `traffic-inspector` routeಗಳಲ್ಲಿ `x-loopback-only: true` annotation ಇಲ್ಲವೆಂದು ಎಚ್ಚರಿಸುತ್ತದೆ. ಅದನ್ನು ಜಾರಿಗೊಳಿಸಲು ಮೊದಲು ಆ annotationಗಳನ್ನು `openapi.yaml` ಗೆ ಸೇರಿಸಬೇಕು. -- `typecheck:noimplicit:core` (ಸಲಹಾತ್ಮಕ) — ತಡೆಗಟ್ಟುವ `check:type-coverage` ratchet ಇದನ್ನು ಬಹುಮಟ್ಟಿಗೆ ಒಳಗೊಳ್ಳುತ್ತದೆ. ಇದನ್ನು ratchetಗೆ ಬದಲಿಸಿ ಅಥವಾ ಅನಗತ್ಯವಾಗಿ ಮರುಕಳಿಸುವ ಎರಡನೇ `tsc` pass ಅನ್ನು ತೆಗೆದುಹಾಕಿ. -- `test:vitest:ui` (ಈಗ **ತಡೆಗಟ್ಟುವಂತಿದೆ**) — ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದ ವೈಫಲ್ಯಗಳನ್ನು `vitest.config.ts` ನಲ್ಲಿ `// #8618` tracking commentಗಳೊಂದಿಗೆ ಸ್ಪಷ್ಟವಾಗಿ ಹೊರಗಿಡಲಾಗಿದೆ; ಹೊಸ ವೈಫಲ್ಯಗಳು job ಅನ್ನು ವಿಫಲಗೊಳಿಸುತ್ತವೆ. -- `check:secrets` (gitleaks, ದಾಖಲಿಸಲಾದ 3 false-positiveಗಳಲ್ಲಿ ಸ್ಥಿರಗೊಳಿಸಲಾದ ತಡೆಗಟ್ಟುವ ratchet) — 0 ತಲುಪಲು ಆ 3 ಅನ್ನು allowlistಗೆ ಸೇರಿಸಿ, ಅಥವಾ ಸಲಹಾತ್ಮಕ ಹಂತಕ್ಕೆ ಇಳಿಸಿ. ಇದು GitHub native secret-scanning + `check:public-creds` ಜೊತೆ ಅತಿಕ್ರಮಿಸುತ್ತದೆ. -- `check:pr-evidence` (ತಡೆಗಟ್ಟುವ, PR-body ಗದ್ಯವನ್ನು greps ಮಾಡುತ್ತದೆ) — false-positive ಅಪಾಯ ಹೆಚ್ಚು; ಇದನ್ನು ತೆಗೆದುಹಾಕಿದರೆ Hard Rule #18 ಜಾರಿ ದುರ್ಬಲಗೊಳ್ಳುತ್ತದೆ, ಆದ್ದರಿಂದ ಇದು ನಿಜವಾದ ನೀತಿ ನಿರ್ಧಾರವಾಗಿದೆ. -- `semgrep` (ಸ್ವತಂತ್ರ ಸಲಹಾತ್ಮಕ) — OWASP familyಗಳಿಗೆ ಸಂಬಂಧಿಸಿದಂತೆ CodeQL ಜೊತೆ ಅತಿಕ್ರಮಿಸುತ್ತದೆ; ಅದರ baseline ಅನ್ನು ratchetಗೆ ಸಂಪರ್ಕಿಸಿ ಅಥವಾ ತೆಗೆದುಹಾಕಿ. +ಪ್ರತಿ ಅಭ್ಯರ್ಥಿಯನ್ನೂ 2026-06-17 ರಂದು ಲೈವ್ ಗೇಟ್ ಸ್ಥಿತಿಯ ವಿರುದ್ಧ ಮೌಲ್ಯೀಕರಿಸಲಾಗಿದೆ (ನಂಬಿ, ಆದರೆ ಪರಿಶೀಲಿಸಿ); +ಹಲವಾರು "ಸ್ಪಷ್ಟ" ವಿಲೀನಗಳು ಸಾಲವನ್ನು ಮರೆಮಾಡಿರುವುದು ಕಂಡುಬಂದಿದ್ದು, ಅವು **ಸ್ವಚ್ಛ ಪರ್ಯಾಯಗಳಲ್ಲ**. + +- **`check:docs-sync` ಎರಡು ಬಾರಿ ರನ್ ಆಗುತ್ತದೆ** — `lint` ಜಾಬ್ನಲ್ಲಿ ಸ್ವತಂತ್ರವಾಗಿ ಮತ್ತು `check:docs-all` (`docs-sync-strict`) ಒಳಗೆ ಮತ್ತೊಮ್ಮೆ, ಹಾಗೆಯೇ husky pre-commit hookನಲ್ಲಿಯೂ. ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** — ಸ್ವತಂತ್ರ `lint` ಆಹ್ವಾನವನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ. +- **CVE ಸ್ಕ್ಯಾನಿಂಗ್** — ❌ **ಸ್ವಚ್ಛ ವಿಲೀನವಲ್ಲ.** ಯಾವುದೇ high/critical CVE ಕಂಡುಬಂದರೆ `audit:deps` ಕಟ್ಟುನಿಟ್ಟಾಗಿ ವಿಫಲಗೊಳ್ಳುತ್ತದೆ; `check:vuln-ratchet` (osv) baselineಗೆ ಹೋಲಿಸಿದಾಗ _ಹಿಂಜರಿತ_ ಉಂಟಾದರೆ ಮಾತ್ರ ವಿಫಲಗೊಳ್ಳುತ್ತದೆ (ಪ್ರಸ್ತುತ 1 MODERATE). ಅರ್ಥವ್ಯವಸ್ಥೆಗಳು ವಿಭಿನ್ನವಾಗಿವೆ — `audit:deps` ತೆಗೆದುಹಾಕಿದರೆ ಸಂಪೂರ್ಣ high/critical ಗೇಟ್ ಕಳೆದುಹೋಗುತ್ತದೆ. ಎರಡನ್ನೂ ಉಳಿಸಿ. +- **ಚಕ್ರ ಪತ್ತೆ** — ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** (#15159 G-01/G-02). ಇಲ್ಲಿನ ಹಳೆಯ ಪಠ್ಯವು `check:cycles` ಅನ್ನು "ಹಸಿರು, ಆಯ್ದ" ಗೇಟ್ ಎಂದು ಕರೆದಿತ್ತು ಮತ್ತು `check:circular-deps` (dpdm) 91 ಚಕ್ರಗಳನ್ನು ವರದಿ ಮಾಡಿದ್ದರಿಂದ ಅದನ್ನು ತಡೆಹಿಡಿಯುವ ಗೇಟ್ ಆಗಿ ಉಳಿಸುವುದನ್ನು ಸಮರ್ಥಿಸಿತ್ತು. ಆ ಹಸಿರು ಸ್ಥಿತಿ **ತಪ್ಪು ಹಸಿರು** ಆಗಿತ್ತು: `check:cycles` 5 ಉಪಡೈರೆಕ್ಟರಿಗಳನ್ನು (450 ಫೈಲ್ಗಳು) ಸ್ಕ್ಯಾನ್ ಮಾಡುತ್ತಿತ್ತು, ಸ್ಥಿರ `import|export … from` ಮಾತ್ರ ಹೊಂದಿಸುತ್ತಿತ್ತು ಮತ್ತು ಪ್ರತಿಯೊಂದು `@/` ಹಾಗೂ `@omniroute/open-sse/` ಸ್ಪೆಸಿಫೈಯರ್ ಅನ್ನು ಕೈಬಿಡುತ್ತಿತ್ತು; ಆದ್ದರಿಂದ ರೆಪೊದಲ್ಲಿ ಪ್ರಾಬಲ್ಯ ಹೊಂದಿದ್ದ dynamic-import + alias ಚಕ್ರಗಳನ್ನು ಅದು ನೋಡಲಾಗುತ್ತಿರಲಿಲ್ಲ. ಸರಿಪಡಿಸಲಾಗಿದೆ: ಗೇಟ್ ಈಗ `src` + `open-sse` (5023 ಫೈಲ್ಗಳು) ಅನ್ನು ಸಂಚರಿಸುತ್ತದೆ, TypeScript AST ನಿಂದ ಸ್ಪೆಸಿಫೈಯರ್ಗಳನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ (ಹೀಗಾಗಿ `import("…")` ಎಣಿಕೆಯಾಗುತ್ತದೆ ಮತ್ತು type-position `typeof import("…")` ಎಣಿಕೆಯಾಗುವುದಿಲ್ಲ), ಹಾಗೂ tsconfig `paths` ಅನ್ನು ಪರಿಹರಿಸುತ್ತದೆ. ಇದು 0 ಅಲ್ಲ, **14** ಚಕ್ರಗಳನ್ನು ಕಂಡುಹಿಡಿಯುತ್ತದೆ. ಗೇಟ್ PRನಲ್ಲಿ ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ 14 ಚಕ್ರಗಳನ್ನು ಸರಿಪಡಿಸಲಾಗದ ಕಾರಣ, `check:cycles` ಈಗ ಒಂದು **ರ್ಯಾಚೆಟ್** ಆಗಿದೆ (`--ratchet`, `quality-baseline.json` ನಲ್ಲಿ ಗರಿಷ್ಠ ಮಿತಿ `metrics.cycles.value = 14`, `direction: down`) — ಇದು ಯಾವುದೇ _ಹಿಂಜರಿತವನ್ನು_ ತಡೆಯುತ್ತದೆ ಮತ್ತು ಎಣಿಕೆ ಕೇವಲ ಕಡಿಮೆಯಾಗಬಹುದು. CI `npm run check:cycles:ratchet` ಅನ್ನು ರನ್ ಮಾಡುತ್ತದೆ. ಕ್ರಮೇಣ ಕಡಿತವು **A-01** ಜೊತೆಗೆ ಸಾಗುತ್ತದೆ. ವಿಶಾಲವಾದ ಎರಡನೇ ಅಭಿಪ್ರಾಯವಾಗಿ `check:circular-deps` (dpdm) ಸಲಹಾತ್ಮಕವಾಗಿಯೇ ಉಳಿಯುತ್ತದೆ. +- **ಸಂಕೀರ್ಣತೆ** — ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ಒಂದು ESLint ಸಂಚಾರ, ruleId ಪ್ರಕಾರ ಎಣಿಸುತ್ತದೆ; ಆದ್ದರಿಂದ cyclomatic+max-lines ಮತ್ತು cognitive baselineಗಳು ಸ್ವತಂತ್ರವಾಗಿರುತ್ತವೆ; ಪ್ರತ್ಯೇಕ `check:complexity` / `check:cognitive-complexity` ಸ್ಥಳೀಯ `--update` ಗಾಗಿ ಉಳಿಯುತ್ತವೆ. +- **`/api` ಭ್ರಮೆ-ವಿರೋಧಿ ಪರಿಶೀಲನೆ** — ✅ **ಪೂರ್ಣಗೊಂಡಿದೆ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ಯ ಒಂದು FS ಪಟ್ಟಿ; openapi-routes + docs-symbols ಇನ್ನೂ ಸ್ವತಂತ್ರವಾಗಿ ವರದಿ ಮಾಡುತ್ತವೆ; ಪ್ರತ್ಯೇಕ ಪರಿಶೀಲನೆಗಳು ಸ್ಥಳೀಯ ರನ್ಗಳಿಗಾಗಿ ಉಳಿಯುತ್ತವೆ. +- **`check:node-runtime` 11 ಜಾಬ್ಗಳಲ್ಲಿ ರನ್ ಆಗುತ್ತದೆ** — ⚠️ **ಕಡಿಮೆ ROI.** ಪ್ರತಿಯೊಂದೂ ಪ್ರತ್ಯೇಕ ರನ್ನರ್ ಆಗಿದ್ದು, ಪರಿಶೀಲನೆಗೆ <1s ಬೇಕಾಗುತ್ತದೆ; ಅಗ್ಗದ ಪ್ರತಿ-ಜಾಬ್ ಸುರಕ್ಷತಾ ಪರಿಶೀಲನೆಯನ್ನು ಕಳೆದುಕೊಳ್ಳುವ ಬದಲಾಗಿ ಒಟ್ಟು ಉಳಿತಾಯ ~10s ಮಾತ್ರ. ಈ ಬದಲಾವಣೆಯ ಗೊಂದಲಕ್ಕೆ ತಕ್ಕ ಮೌಲ್ಯವಿಲ್ಲ. +- **CI lintನಲ್ಲಿ `typecheck:noimplicit:core`** — ✅ **lint ಜಾಬ್ನಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ** (ಇದು ಸಲಹಾತ್ಮಕ `continue-on-error` ಆಗಿತ್ತು); ತಡೆಹಿಡಿಯುವ ಪ್ರಕಾರ ಮೇಲ್ಮೈ `typecheck:core` + `check:type-coverage` ಆಗಿದೆ. ಸ್ಥಳೀಯ ಸ್ಕ್ರಿಪ್ಟ್ ಉಳಿಸಲಾಗಿದೆ. + +### ತಿರುಗಿಸಿ / ನಿರ್ಧರಿಸಿ (ನಿರ್ವಾಹಕರ ನೀತಿ) + +- `check:openapi-security-tiers` (ಸಲಹಾತ್ಮಕ) — ❌ **ನೇರವಾಗಿ ತಿರುಗಿಸಲಾಗುವುದಿಲ್ಲ.** ಇದು 0 ನೊಂದಿಗೆ ನಿರ್ಗಮಿಸುತ್ತದೆ, ಆದರೆ `LOCAL_ONLY_API_PREFIXES` ಅಡಿಯಲ್ಲಿರುವ ಹಲವಾರು `traffic-inspector` ರೂಟ್ಗಳಲ್ಲಿ `x-loopback-only: true` annotation ಇಲ್ಲವೆಂದು ಎಚ್ಚರಿಸುತ್ತದೆ. ಇದನ್ನು ಜಾರಿಗೊಳಿಸುವ ಮೊದಲು ಆ annotationಗಳನ್ನು `openapi.yaml` ಗೆ ಸೇರಿಸುವುದು ಅಗತ್ಯ. +- `typecheck:noimplicit:core` (ಸಲಹಾತ್ಮಕ) — ತಡೆಹಿಡಿಯುವ `check:type-coverage` ರ್ಯಾಚೆಟ್ ಇದನ್ನು ಬಹುಮಟ್ಟಿಗೆ ಒಳಗೊಂಡಿದೆ. ಇದನ್ನು ರ್ಯಾಚೆಟ್ಗೆ ತಿರುಗಿಸಿ ಅಥವಾ ಅನಗತ್ಯವಾದ ಎರಡನೇ `tsc` ಪಾಸ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ. +- `test:vitest:ui` (ಈಗ **ತಡೆಹಿಡಿಯುವ**) — ಮೊದಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ವೈಫಲ್ಯಗಳನ್ನು `vitest.config.ts` ನಲ್ಲಿ `// #8618` ಟ್ರ್ಯಾಕಿಂಗ್ ಕಾಮೆಂಟ್ಗಳೊಂದಿಗೆ ಸ್ಪಷ್ಟವಾಗಿ ಹೊರಗಿಡಲಾಗಿದೆ; ಹೊಸ ವೈಫಲ್ಯಗಳು ಜಾಬ್ ಅನ್ನು ವಿಫಲಗೊಳಿಸುತ್ತವೆ. +- `check:secrets` (gitleaks, ದಾಖಲೀಕರಿಸಿದ 3 false-positiveಗಳಲ್ಲಿ ಸ್ಥಗಿತಗೊಳಿಸಿದ ತಡೆಹಿಡಿಯುವ ರ್ಯಾಚೆಟ್) — 0 ತಲುಪಲು ಆ 3 ಅನ್ನು allowlistಗೆ ಸೇರಿಸಿ, ಅಥವಾ ಸಲಹಾತ್ಮಕ ಮಟ್ಟಕ್ಕೆ ಇಳಿಸಿ. ಇದು GitHubನ ಮೂಲ secret-scanning + `check:public-creds` ಜೊತೆ ಅತಿಕ್ರಮಿಸುತ್ತದೆ. +- `check:pr-evidence` (ತಡೆಹಿಡಿಯುವ, PR-body ಗದ್ಯವನ್ನು grep ಮಾಡುತ್ತದೆ) — false-positive ಅಪಾಯ ಹೆಚ್ಚು; ತೆಗೆದುಹಾಕಿದರೆ Hard Rule #18 ಜಾರಿ ದುರ್ಬಲಗೊಳ್ಳುತ್ತದೆ, ಆದ್ದರಿಂದ ಇದು ನಿಜವಾದ ನೀತಿ ನಿರ್ಧಾರವಾಗಿದೆ. +- `semgrep` (ಸಲಹಾತ್ಮಕ ಸ್ವತಂತ್ರ ಪರಿಶೀಲನೆ) — OWASP ವರ್ಗಗಳಿಗೆ ಸಂಬಂಧಿಸಿ CodeQL ಜೊತೆ ಅತಿಕ್ರಮಿಸುತ್ತದೆ; ಅದರ baseline ಅನ್ನು ರ್ಯಾಚೆಟ್ಗೆ ಜೋಡಿಸಿ ಅಥವಾ ತೆಗೆದುಹಾಕಿ. --- diff --git a/docs/i18n/ko/CONTRIBUTING.md b/docs/i18n/ko/CONTRIBUTING.md index 7e8a422a767..5bbf64536bf 100644 --- a/docs/i18n/ko/CONTRIBUTING.md +++ b/docs/i18n/ko/CONTRIBUTING.md @@ -386,22 +386,22 @@ handler/executor 내부에서 클라이언트에 전달되는 오류 메시지 --- -## 풀 리퀘스트 체크리스트 +## Pull 리퀘스트 체크리스트 - [ ] 테스트 통과 (`npm test`) -- [ ] 린트 검사 통과 (`npm run lint`) +- [ ] 린팅 통과 (`npm run lint`) - [ ] 빌드 성공 (`npm run build`) - [ ] 새로운 공개 함수 및 인터페이스에 TypeScript 타입 추가 - [ ] 하드코딩된 시크릿 또는 대체 값 없음 -- [ ] 공개 업스트림 자격 증명은 리터럴이 아닌 `resolvePublicCred()`를 통해 포함 ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) 참조) -- [ ] 오류 응답은 `buildErrorBody()` / `sanitizeErrorMessage()`를 통해 처리 — 응답 본문에 원시 스택 트레이스 포함 금지 ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) 참조) +- [ ] 공개 업스트림 자격 증명은 리터럴로 지정하지 않고 `resolvePublicCred()`를 통해 포함(참조: [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) +- [ ] 오류 응답은 `buildErrorBody()` / `sanitizeErrorMessage()`를 통해 처리 — 응답 본문에 원시 스택 트레이스 포함 금지(참조: [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] 셸 명령어(`exec` / `spawn`)는 문자열 보간이 아닌 `env`를 통해 런타임 값을 전달 - [ ] 모든 입력을 Zod 스키마로 검증 -- [ ] 사용자에게 영향을 미치는 변경 사항에 대해 `changelog.d/{features|fixes|maintenance}/-.md` 아래에 변경 로그 **조각** 추가 ([`changelog.d/README.md`](./changelog.d/README.md) 참조) — `CHANGELOG.md`를 직접 편집하지 **말 것**. 조각은 릴리스 시점에 통합되며 PR 간 충돌이 발생하지 않음 +- [ ] 사용자에게 영향을 주는 변경 사항의 경우 `changelog.d/{features|fixes|maintenance}/-.md` 아래에 변경 로그 **조각** 추가(참조: [`changelog.d/README.md`](./changelog.d/README.md)) — `CHANGELOG.md`를 직접 편집하지 말 것. 조각은 릴리스 시점에 통합되며 PR 간 충돌이 발생하지 않음 - [ ] 문서 업데이트(해당하는 경우) -- [ ] 새로운 CodeQL / Secret-Scanning 경고가 발생하지 않았거나, 각 경고를 관련 `docs/security/` 문서를 참조하는 기술적 근거와 함께 해제 -- [ ] 자식 프로세스를 생성하는 라우트(`/api/mcp/`, `/api/cli-tools/runtime/`)를 `src/server/authz/routeGuard.ts`에서 `isLocalOnlyPath()`로 분류 — [하드 규칙 #15](docs/security/ROUTE_GUARD_TIERS.md) 참조 -- [ ] 커밋 메시지에 `Co-Authored-By` 트레일러 포함 금지 — 커밋은 저장소 소유자의 Git ID로만 표시되어야 함(하드 규칙 #16) +- [ ] 새로운 CodeQL / Secret-Scanning 경고가 생성되지 않았거나, 각 경고를 관련 `docs/security/` 문서를 참조한 기술적 근거와 함께 해제 +- [ ] 하위 프로세스를 생성하는 라우트(`/api/mcp/`, `/api/cli-tools/runtime/`)를 `src/server/authz/routeGuard.ts`에서 `isLocalOnlyPath()`로 분류 — [엄격 규칙 #15](docs/security/ROUTE_GUARD_TIERS.md) 참조 +- [ ] 커밋 메시지에 AI/봇 `Co-authored-by` 트레일러 포함 금지(엄격 규칙 #16) — 작업이 재사용된 인간 협업자는 표준 `Co-authored-by: Name ` 트레일러로 크레딧 표기 --- diff --git a/docs/i18n/ko/docs/architecture/QUALITY_GATES.md b/docs/i18n/ko/docs/architecture/QUALITY_GATES.md index 7c217421899..31c080a2389 100644 --- a/docs/i18n/ko/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ko/docs/architecture/QUALITY_GATES.md @@ -19,81 +19,79 @@ ### 후보 승인 CI 및 Quality Gates 워크플로는 각각 안정적인 판정 결과인 `Gate / CI`와 -`Gate / Quality`를 출력합니다. 버전이 지정된 승인 정책은 모든 업스트림 작업을 -필수 또는 권고로 열거합니다. 적용 가능한 필수 작업은 성공해야 합니다. 누락, -취소, 건너뜀, 대기 중 및 알 수 없는 결과로는 PASS를 확정할 수 없습니다. 유효한 +`Gate / Quality`를 생성합니다. 버전이 관리되는 승인 정책은 모든 업스트림 작업을 +필수 또는 권고로 열거합니다. 적용 가능한 필수 작업은 성공해야 합니다. 누락됨, +취소됨, 건너뜀, 대기 중 및 알 수 없는 결과로는 PASS를 확정할 수 없습니다. 유효한 문서 전용 또는 카탈로그 전용 분류는 코드 레인을 적용 대상에서 제외할 수 있지만, -초안 PR은 승인된 후보가 아닙니다. `hotfix` 레이블은 증거 요건을 면제하지 않습니다. +초안 PR은 승인된 후보가 아닙니다. `hotfix` 레이블이 증거 요건을 면제하지는 않습니다. -두 워크플로 모두 PR, main/release 브랜치로의 푸시, 수동 디스패치 및 -병합 그룹 이벤트를 포함합니다. 푸시, 디스패치 및 병합 그룹은 전체 선택 항목을 -실행합니다. 포크와 병합 그룹은 원래 자체 호스팅 러너를 선택하는 작업에 대해 -호스팅 러너를 사용합니다. 따라서 출시 전에 충분한 호스팅 용량을 검증해야 합니다. +두 워크플로 모두 PR과 main/release 브랜치로의 푸시, 수동 디스패치 및 +병합 그룹 이벤트를 다룹니다. 푸시, 디스패치 및 병합 그룹은 전체 선택 항목을 +실행합니다. 포크와 병합 그룹은 원래 자체 호스팅 러너를 선택하는 작업에 +호스팅 러너를 사용합니다. 롤아웃 전에 충분한 호스팅 용량을 확인해야 합니다. 각 JSON 영수증은 체크아웃된 SHA, 워크플로 실행 및 시도를 식별합니다. -CLI는 체크아웃 SHA와 이벤트 SHA가 일치하지 않으면 거부합니다. 워크플로 테스트는 -정책 멤버십을 판정 작업의 `needs` 목록에 연결하므로 새 레인이 추가되거나 기존 레인이 -제거되어도 조용히 사라질 수 없습니다. 영수증은 자체 워크플로만 대상으로 하며, -게시, 배포 또는 기존 권고 스캐너의 내부 동작은 포함하지 않습니다. 브랜치 규칙에서 -두 검사 이름을 모두 활성화하는 것은 별도의 관리 변경 사항입니다. 이러한 작업을 -추가하는 것만으로는 브랜치가 보호되지 않습니다. +CLI는 체크아웃 SHA와 이벤트 SHA의 불일치를 거부합니다. 워크플로 테스트는 정책 +멤버십을 판정 작업의 `needs` 목록에 연결하므로 새로 추가되거나 제거된 레인이 +조용히 사라질 수 없습니다. 영수증은 자체 워크플로를 다루며, 게시, 배포 또는 +기존 권고 스캐너의 내부 동작은 다루지 않습니다. 브랜치 규칙에서 두 검사 이름을 +모두 활성화하는 것은 별도의 관리 변경 사항입니다. 이러한 작업을 추가하는 것만으로는 +브랜치가 보호되지 않습니다. ### 정적 스캔 인벤토리 -버전이 지정된 npm 별칭 인벤토리와 정적 스캔 멤버십은 +버전이 관리되는 npm 별칭 인벤토리와 정적 스캔 멤버십은 `config/quality/gate-manifest.json`에 있습니다. `package.json`을 기준으로 스크립트 이름과 정확한 명령을 검증하려면 `npm run check:gate-manifest`를 실행하세요. 추가, 제거 및 명령 드리프트가 발생하면 로컬 훅과 CI의 변경 분류 작업이 모두 실패합니다. 별칭은 워크플로 작업, 매트릭스 인스턴스 또는 테스트 케이스가 아닙니다. -따라서 이러한 개수를 서로 동일한 것으로 제시해서는 안 됩니다. +따라서 이러한 개수를 서로 호환되는 것처럼 제시해서는 안 됩니다. -선택된 별칭을 실행하지 않고 검사하려면 `npm run quality:scan -- --list` 또는 -`npm run quality:scan:fast -- --list`를 사용하세요. 러너는 npm 진입점을 호출하므로 -구성된 경우 Bun을 포함한 런타임이 유지됩니다. 매니페스트는 해당 프로필 외부의 -별칭을 별도 호출 항목으로 기록하며, 읽기 전용 스캔 프로필에서는 유지보수 명령이 -금지됩니다. +선택된 별칭을 실행하지 않고 확인하려면 `npm run quality:scan -- --list` 또는 +`npm run quality:scan:fast -- --list`를 사용하세요. 러너는 npm 진입점을 +호출하므로 구성된 경우 Bun을 포함한 런타임이 유지됩니다. 매니페스트는 해당 +프로필 외부의 별칭을 별도 호출 항목으로 기록하며, 읽기 전용 스캔 프로필에서는 +유지보수 명령이 금지됩니다. -이러한 프로필은 정적 스캔만 포함합니다. 제품 테스트, 커버리지, 패키징, 외부 검사 -또는 후보의 전체 릴리스 승인을 보증하지 않습니다. 워크플로 승인은 연결된 -`config/quality/admission-policy.json`과 +이러한 프로필은 정적 스캔만 다룹니다. 제품 테스트, 커버리지, 패키징, +외부 검사 또는 후보의 전체 릴리스 승인을 보증하지 않습니다. 워크플로 승인은 +연결된 `config/quality/admission-policy.json`과 `scripts/quality/admission-verdict.mjs`를 사용합니다. 릴리스 관찰자 프로필은 -별도로 유지됩니다. 해당 프로필에 적용 가능한 검사와 영수증을 독립적으로 -검토하세요. 아래의 서술형 인벤토리는 참조 자료일 뿐, 게이트가 실제로 실행되었다는 -증거는 아닙니다. +별도로 유지됩니다. 적용 가능한 검사와 영수증을 독립적으로 확인하세요. 아래의 +서술형 인벤토리는 참조 자료일 뿐, 게이트가 실제로 실행되었다는 증거는 아닙니다. -스크립트는 `scripts/check/`(정책 게이트)와 `scripts/quality/`(래칫 엔진) 아래에 -있습니다. CI의 단일 진실 공급원은 `.github/workflows/ci.yml`입니다. +스크립트는 `scripts/check/`(정책 게이트)와 `scripts/quality/`(래칫 엔진)에 있습니다. +CI의 단일 진실 공급원은 `.github/workflows/ci.yml`입니다. ### 릴리스 PR 빠른 경로(`quality.yml`) `.github/workflows/quality.yml`은 main/release PR, 보호된 브랜치로의 푸시, -디스패치 및 병합 그룹에서 CI를 보완합니다. PR은 경로 필터가 적용된 빠른 검사를 -사용합니다. 영구적으로 비활성화되어 있던 중복 빌드는 제거되었습니다. 실제 -빌드/패키지/부팅 검사는 CI에 그대로 남아 있습니다. - -| 작업 | 범위 | 차단 여부 | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `Docs Gates (fast-path)` | 문서/코드 PR, API 문서 참조 및 전체 문서 | 예 | -| `Fast Quality Gates` | 코드 PR, 정적 검사, 타입 검사, 대시보드 타입 검사, 영향받는 단위 테스트 | 예 | -| `Forgotten sibling tests` | 코드 PR, 변경된 모듈을 정적 소비자 및 후보 형제 테스트까지 추적, 배럴 및 동적 가져오기 경로는 참조된 허용 목록 예외와 함께 권고 진단으로 보고됨 | **권고** | -| `Vitest (fast-path)` | 코드 PR, 빠른 vitest 스위트 | 예 | -| `Unit Tests fast-path` | 코드 PR, 4-샤드 단위 테스트 스위트 | 예 | -| `No new ESLint warnings` | 코드 PR, 억제 설정을 인식하는 린트 가드 | 예, 포크 포함 | -| `Merge integrity (changelog + generated skills)` | 초안이 아닌 PR, 변경 로그 및 생성된 스킬 동기화 | 예, 포크 포함 | +디스패치 및 병합 그룹에서 CI를 보완합니다. PR은 경로 필터링된 빠른 검사를 사용합니다. +영구적으로 비활성화된 중복 빌드는 제거되었으며, 실제 빌드/패키지/부팅 검사는 CI에 남아 있습니다. + +| 작업 | 범위 | 차단 여부 | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `Docs Gates (fast-path)` | 문서/코드 PR, API 문서 참조 및 전체 문서 | 예 | +| `Fast Quality Gates` | 코드 PR, 정적 검사, 타입 검사, 대시보드 타입 검사, 영향받는 단위 테스트 | 예 | +| `Forgotten sibling tests` | 코드 PR, 변경된 모듈을 정적 소비자와 후보 형제 테스트까지 추적, 배럴 및 동적 임포트 경로는 참조된 허용 목록 예외와 함께 권고 진단으로 보고됨 | **권고** | +| `Vitest (fast-path)` | 코드 PR, 빠른 vitest 스위트 | 예 | +| `Unit Tests fast-path` | 코드 PR, 4샤드 단위 테스트 스위트 | 예 | +| `No new ESLint warnings` | 코드 PR, 억제 규칙을 인식하는 린트 가드 | 예, 포크 포함 | +| `Merge integrity (changelog + generated skills)` | 초안이 아닌 PR, 변경 로그 및 생성된 스킬 동기화 | 예, 포크 포함 | #### 누락된 형제 테스트 보고서 -`npm run check:forgotten-sibling-tests`는 테스트 영향도 맵에서 사용하는 가져오기 -해결기를 재사용합니다. 변경된 모든 프로덕션 모듈에 대해 후보 테스트가 풀 리퀘스트 -차이에 없으면 결정론적인 -`changed module/symbol -> static consumer -> candidate sibling test` 체인을 보고합니다. -차단 방식으로 출시하기 전 보정을 위해 Markdown 요약과 JSON 결과는 -`forgotten-sibling-tests` 워크플로 아티팩트로 보존됩니다. +`npm run check:forgotten-sibling-tests`는 테스트 영향도 맵의 기반이 되는 임포트 리졸버를 재사용합니다. +변경된 각 프로덕션 모듈에 대해 후보 테스트가 풀 리퀘스트 diff에 없으면 결정론적인 +`변경된 모듈/심볼 -> 정적 소비자 -> 후보 형제 테스트` 체인을 보고합니다. 차단 방식으로 +롤아웃하기 전 보정을 위해 Markdown 요약과 JSON 결과는 `forgotten-sibling-tests` +워크플로 아티팩트로 보존됩니다. -배럴 재내보내기와 동적 임포트는 해석 진단에만 사용되며, 차단 결과를 생성하지 않습니다. -검토된 예외는 `config/quality/forgotten-sibling-allowlist.json`에 있습니다. 각 항목에는 소비자와 후보 +배럴 재내보내기와 동적 가져오기는 오직 해석 진단에만 사용되며, 차단 +결과를 생성하지 않습니다. 검토된 예외는 +`config/quality/forgotten-sibling-allowlist.json`에 있습니다. 각 항목에는 소비자와 후보 테스트를 명시하고, 구체적인 근거를 제시하며, GitHub 이슈 또는 풀 리퀘스트를 연결해야 합니다. 형식이 잘못된 항목은 -차단됩니다. 예외는 삭제된 후보 테스트나 `.skip`/`.todo`를 추가하는 diff를 억제할 수 없습니다. +폐쇄형으로 실패합니다. 예외는 삭제된 후보 테스트나 `.skip`/`.todo`를 추가하는 diff를 억제할 수 없습니다. 어서션 약화 및 기타 마스킹은 독립적으로 차단하는 `check:test-masking` 게이트가 계속 담당합니다. @@ -101,133 +99,126 @@ CLI는 체크아웃 SHA와 이벤트 SHA가 일치하지 않으면 거부합니 `main`을 대상으로 하는 모든 PR에서 실행됩니다. 실패 시 병합을 차단합니다. -| 스크립트 (`npm run ...`) | 검증 항목 | 차단 여부 | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `check:node-runtime` | Node.js 버전이 지원 범위 내에 있는지 | 예 | -| `check:cycles` | 순환 임포트 — 모든 `src/` + `open-sse/` 모듈 | 예 | -| `check:route-validation:t06` | 모든 라우트에 Zod 스키마가 있는지(Tier 6 정책) | 예 | -| `check:any-budget:t11` | `@ts-expect-error // any` 개수가 예산을 초과하지 않는지(Tier 11 catraca) | 예 | -| `check:provider-consistency` | `providers.ts`의 모든 provider에는 `providerRegistry.ts`에 일치하는 항목이 있으며, 그 반대도 마찬가지입니다(allowlist 내에서) | 예 | -| `check:model-lifecycle` | 수동으로 유지 관리되는 세 개의 라우팅 테이블이 체크인된 수명 주기 스냅샷(#11503)과 일관성을 유지합니다. `FITNESS_TABLE`(`taskFitness.ts`)은 `REGISTRY`가 라우팅할 수 있는 폐기된 id에 점수를 부여하지 않고, 모든 `BUILT_IN_ALIASES` 대상은 `REGISTRY`에 존재하며 폐기된 id 스냅샷에는 없고, `REGISTRY`에 여전히 남아 있는 모든 폐기된 id는 전달되거나 `allowedRetiredInCatalog`에 나열되며, `DEFAULT_DEGRADATION_MAP`의 source 또는 target은 해당 스냅샷에서 폐기된 것으로 표시되지 않습니다. 이는 모델이 현재 실제 upstream에서 제공되고 있음을 입증하지는 않습니다. 오프라인 — `config/quality/model-lifecycle.json`과 비교하며, `npm run quality:refresh-model-lifecycle`을 사용하여 수동으로 새로 고칩니다(network 필요, CI에는 연결되지 않음). `allowedRetiredInCatalog`는 점진적 축소를 위한 ratchet입니다. 추적 issue가 있는 경우에만 항목을 추가하세요. | 예 | -| `check:fetch-targets` | 클라이언트 측 `src/`의 모든 `fetch("/api/...")`가 실제 `route.ts`로 확인됩니다 | 예 | -| `check:deps` | repo 내 모든 `package.json`에서 `npm install` 가능한 모든 deps가 `dependency-allowlist.json`에 포함되어 있으며, 새로 추가된 고정되지 않은 패키지 또는 slopsquatting 패키지는 표시됩니다 | 예 | -| `audit:deps` | `npm audit`(root + electron) — high/critical advisory가 없음(osv `check:vuln-ratchet`과 중복됨. Rationalization Backlog 참조) | 예 | -| `check:lockfile` | `package-lock.json` 무결성 — https registry, integrity hash, host override 없음 | 예 | -| `check:licenses` | 프로덕션 종속성에 대한 SPDX 라이선스 허용 목록 | 예 | -| `check:tracked-artifacts` | 빌드 아티팩트 / 커밋된 `node_modules` 심볼릭 링크 없음(husky pre-commit에서도 실행됨; pre-push는 의도적으로 가볍게 유지 — #6716) | 예 | -| `check:ai-attribution` | PR 커밋, 제목 또는 본문에 AI/봇 `Co-Authored-By` 트레일러나 AI 생성 푸터 없음 — 엄격한 규칙 #16(`quality.yml`의 PR→`release/**` 빠른 게이트 루프에서 실행 — 이벤트 페이로드를 읽으며 PR이 아니면 아무 작업도 하지 않음 — 및 `ci.yml` lint의 PR→`main`용 PR 전용 단계; husky `commit-msg` 훅에서도 실행; 사람 공동 작성자는 허용됨; #14436) | -| `check:vitest-exclusions` | 모든 Vitest 제외 항목은 추적 이슈를 명시하고 `config/quality/vitest-exclusions.json`에 있어야 함(#13204) | 예 | -| `check:file-size` | 소스 파일이 확장자별 상한을 초과하지 않음(래칫: 대용량 파일은 `frozen` 목록에 고정됨) | 예 | -| `check:error-helper` | 실행기/핸들러의 오류 응답은 `buildErrorBody()` / `sanitizeErrorMessage()`를 사용함(엄격한 규칙 #12) | 예 | -| `check:migration-numbering` | 마이그레이션 SQL 파일은 누락되거나 중복된 번호 없이 순차적으로 번호가 지정되어야 함 | 예 | -| `check:public-creds` | `publicCreds.ts` 외부에 리터럴 OAuth `client_id`/`client_secret` 또는 Firebase Web 키가 없어야 함(엄격 규칙 #11) | 예 | -| `check:db-rules` | `src/lib/db/` 모듈 외부에 원시 SQL이 없어야 하며, `localDb.ts`에서 배럴 임포트를 사용하지 않아야 함(엄격 규칙 #2/#5) | 예 | -| `check:known-symbols` | 디스패치 테이블에 등록된 제공자 실행기, 라우팅 전략 및 변환기가 디스크의 파일과 일치해야 하며, 고립되거나 선언되지 않은 심벌이 없어야 함 | 예 | -| `check:route-guard-membership` | 하위 프로세스를 생성하는 모든 라우트는 `isLocalOnlyPath()`로 분류되어야 함(엄격 규칙 #15/#17) | 예 | -| `check:test-discovery` | 저장소의 모든 `*.test.ts` / `*.spec.ts` 파일은 하나 이상의 테스트 러너에 의해 수집되어야 함(래칫: `test-discovery-baseline.json`의 고립 파일 목록은 줄어들기만 해야 함) | 예 | -| `check:agent-skills-sync` | 생성된 agent-skills 아티팩트가 소스 카탈로그와 일치함(드리프트 없음) | -| `check:provider-asset-provenance` | 제공자 로고/에셋에 기록된 출처 항목이 있음 | -| `lint:json` | JSON 구성 파일이 올바르게 파싱되고 저장소 린트 규칙을 충족함 | -| `typecheck:core` | 오류 없는 TypeScript 컴파일(권고 경고만 있음) | 예 | -| `typecheck:noimplicit:core` | 엄격한 `noImplicitAny` — 향후 적용을 위한 항목이며, 기존의 많은 호출 지점에는 여전히 타입 주석이 필요함 | **권고** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**`로 범위가 한정된 `tsc` (#7033) — `typecheck:core`의 선별된 27개 파일 허용 목록에는 대시보드 TSX가 전혀 포함되지 않으며, `next build` 역시 이를 타입 검사하지 않으므로(`next.config.mjs`에서 `ignoreBuildErrors: true` 설정), 해당 위치의 고립된 식별자 회귀(#6625/#6909)가 CI에서 감지되지 않았음. 고정된 파일별/TS 코드별 개수 기준선(`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols`와 동일한 오래된 항목 강제 적용 패턴)과 차이를 비교함 — 기준선의 개수를 초과하는 새로운 오류만 게이트를 실패하게 하며, 기존 오류를 수정한 경우 `--update`를 사용해 기준선을 낮출 수 있음. | 예 | +| 스크립트 (`npm run ...`) | 검증 항목 | 차단 여부 | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| `check:node-runtime` | Node.js 버전이 지원 범위 내에 있는지 확인 | 예 | +| `check:cycles` | `src/` + `open-sse/` 전체의 순환 가져오기를 검사합니다(AST 기반, tsconfig `paths` 해석). 기본 실행은 권고용이며 순환 목록을 표시합니다. `check:cycles:ratchet`(CI에서 실행되는 항목)은 순환 수가 `quality-baseline.json`의 `metrics.cycles` 상한을 초과하면 차단합니다. 현재 상한은 14이고 `direction: down`이므로 감소만 가능합니다(#15159 G-01/G-02) | 예(래칫) | +| `check:route-validation:t06` | 모든 라우트에 Zod 스키마가 있는지 확인(Tier 6 정책) | 예 | +| `check:any-budget:t11` | `@ts-expect-error // any` 개수가 예산을 초과하지 않는지 확인(Tier 11 catraca) | 예 | +| `check:provider-consistency` | `providers.ts`의 모든 프로바이더에는 `providerRegistry.ts`에 일치하는 항목이 있으며, 그 반대도 동일합니다(허용 목록 내에서). | 예 | +| `check:model-lifecycle` | 수동으로 유지 관리되는 세 개의 라우팅 테이블이 체크인된 수명 주기 스냅샷(#11503)과 일관성을 유지합니다. `FITNESS_TABLE`(`taskFitness.ts`)은 `REGISTRY`가 라우팅할 수 있는 사용 종료 ID에 점수를 부여하지 않으며, 모든 `BUILT_IN_ALIASES` 대상은 `REGISTRY`에 존재하고 사용 종료 ID 스냅샷에는 없습니다. `REGISTRY`에 아직 남아 있는 모든 사용 종료 ID는 포워딩되거나 `allowedRetiredInCatalog`에 나열되며, `DEFAULT_DEGRADATION_MAP`의 소스나 대상은 해당 스냅샷에서 사용 종료 상태로 표시되지 않습니다. 이는 모델이 현재 실제 업스트림에서 제공되고 있음을 입증하지는 않습니다. 오프라인 검사로, `config/quality/model-lifecycle.json`과 비교합니다. 이 파일은 `npm run quality:refresh-model-lifecycle`을 사용해 수동으로 갱신합니다(네트워크 필요, CI에는 연결되지 않음). `allowedRetiredInCatalog`는 단계적 축소를 위한 래칫입니다. 추적 이슈가 있는 경우에만 항목을 추가하십시오. | 예 | +| `check:fetch-targets` | 클라이언트 측 `src/`에 있는 모든 `fetch("/api/...")`가 실제 `route.ts`로 해석됩니다. | 예 | +| `check:deps` | 저장소의 모든 `package.json`에 있는 `npm install` 가능한 모든 종속성이 `dependency-allowlist.json`에 포함되어 있으며, 새로 추가된 버전이 고정되지 않은 패키지나 슬롭스쿼팅 패키지는 플래그로 표시됩니다. | 예 | +| `audit:deps` | `npm audit`(루트 + electron) — 높음/심각 수준의 보안 권고 없음(osv `check:vuln-ratchet`과 중복됨. Rationalization Backlog 참조) | 예 | +| `check:lockfile` | `package-lock.json` 무결성 — https 레지스트리, 무결성 해시, 호스트 재정의 없음 | 예 | +| `check:licenses` | 프로덕션 종속성에 대한 SPDX 라이선스 허용 목록 | 예 | +| `check:tracked-artifacts` | 빌드 아티팩트 / 커밋된 `node_modules` 심볼릭 링크 없음(husky pre-commit에서도 실행됨; pre-push는 의도적으로 가볍게 유지 — #6716) | 예 | +| `check:ai-attribution` | PR 커밋, 제목 또는 본문에 AI/봇 `Co-Authored-By` 트레일러나 AI 생성 푸터 없음 — 엄격한 규칙 #16(PR→`release/**`에 대한 `quality.yml` 빠른 게이트 루프에서 이벤트 페이로드를 읽으며, PR이 아닌 경우 아무 작업도 하지 않음 — 그리고 PR→`main`에 대한 `ci.yml` 린트의 PR 전용 단계; husky `commit-msg` 훅에서도 실행됨; 사람 공동 작성자는 허용됨; #14436) | +| `check:vitest-exclusions` | 모든 Vitest 제외 항목은 추적 이슈를 명시하고 `config/quality/vitest-exclusions.json`에 포함되어야 함(#13204) | 예 | +| `check:file-size` | 소스 파일이 확장자별 상한을 초과하지 않음(래칫: 대용량 파일은 `frozen` 목록에 고정) | 예 | +| `check:error-helper` | 실행기/핸들러의 오류 응답은 `buildErrorBody()` / `sanitizeErrorMessage()`를 사용함(엄격한 규칙 #12) | 예 | +| `check:migration-numbering` | 마이그레이션 SQL 파일은 누락되거나 중복된 번호 없이 순차적으로 번호가 지정되어야 함 | 예 | +| `check:public-creds` | `publicCreds.ts` 외부에 OAuth `client_id`/`client_secret` 또는 Firebase Web 키 리터럴이 없어야 함(강제 규칙 #11) | 예 | +| `check:db-rules` | `src/lib/db/` 모듈 외부에 원시 SQL이 없어야 하며, `localDb.ts`에서 배럴 임포트를 사용하지 않아야 함(강제 규칙 #2/#5) | 예 | +| `check:known-symbols` | 디스패치 테이블에 등록된 공급자 실행기, 라우팅 전략 및 변환기가 디스크의 파일과 일치해야 하며, 연결되지 않았거나 선언되지 않은 심볼이 없어야 함 | 예 | +| `check:route-guard-membership` | 자식 프로세스를 생성하는 모든 라우트는 `isLocalOnlyPath()`로 분류되어야 함(강제 규칙 #15/#17) | 예 | +| `check:test-discovery` | 저장소의 모든 `*.test.ts` / `*.spec.ts` 파일은 하나 이상의 테스트 러너에서 수집되어야 함(래칫: `test-discovery-baseline.json`의 고아 목록은 줄어들기만 할 수 있음) | 예 | +| `check:agent-skills-sync` | 생성된 agent-skills 아티팩트가 소스 카탈로그와 일치함(드리프트 없음) | +| `check:provider-asset-provenance` | 공급자 로고/에셋에 기록된 출처 항목이 있음 | +| `lint:json` | JSON 구성 파일이 정상적으로 파싱되고 저장소 린트 규칙을 충족함 | +| `typecheck:core` | 오류 없이 TypeScript 컴파일(권고 경고만 있음) | 예 | +| `typecheck:noimplicit:core` | 엄격한 `noImplicitAny` — 향후 적용을 위한 항목이며, 기존의 많은 호출 지점에는 여전히 어노테이션이 필요함 | **권고** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**`로 범위가 지정된 `tsc` (#7033) — `typecheck:core`의 엄선된 27개 파일 허용 목록에는 대시보드 TSX가 전혀 포함되지 않으며, `next build` 역시 이를 타입 검사하지 않으므로(`next.config.mjs`에서 `ignoreBuildErrors: true` 설정), 해당 영역의 고립된 식별자 회귀(#6625/#6909)가 CI에서 감지되지 않았음. 고정된 파일별/TS 코드별 개수 기준선(`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols`와 동일한 오래된 항목 강제 적용 패턴)과 비교함 — 기준선에 기록된 개수를 초과하는 새로운 오류만 게이트를 실패하게 하며, 기존 오류가 수정되면 `--update`를 사용하여 기준선을 낮출 수 있음. | 예 | ### 작업: `quality-gate` `test-coverage` 이후에 실행됩니다. 실패하면 병합을 차단합니다. -| 스크립트 | 검증 항목 | 차단 여부 | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `quality:collect` | `quality-metrics.json` 생성(ESLint 경고 수, 병합된 샤드 보고서의 커버리지) | 예(래칫의 선행 단계) | -| `quality:ratchet` | `quality-baseline.json`의 각 메트릭이 퇴보하지 않았는지 확인(ESLint 경고 ≤ 기준선, 커버리지 ≥ 기준선) | 예 | -| `check:duplication` | 코드 중복(jscpd@4)이 `quality-baseline.json`의 기준선을 초과하지 않는지 확인 | 예 | -| `check:complexity` | 파일 수준 순환 복잡도가 상한을 초과하지 않는지 확인(핵심 ESLint `complexity` + `max-lines-per-function`) | 예 | -| `check:cognitive-complexity` | 인지 복잡도 래칫(`eslint-plugin-sonarjs`) — 별도의 ESLint 패스이며, CI에서는 두 검사를 단일 `check:complexity-ratchets` 단계로 병합하여 실행 | 예 | -| `check:dead-code` | 사용되지 않는 내보내기/파일 래칫(knip)이 기준선보다 퇴보하지 않는지 확인 | 예 | -| `check:compression-budget` | 압축 벤치마크 예산 — 엔진별 토큰 절감률 하한이 퇴보하지 않아야 함 | 예 | -| `check:type-coverage` | 타입 지정 비율 래칫(`type-coverage`)이 퇴보하지 않는지 확인하며, `typecheck:noimplicit:core`를 대부분 포괄함 | 예 | -| `check:codeql-ratchet` | 미해결 CodeQL 경고 수가 증가하지 않는지 확인(`gh api`로 조회하며, 토큰이 없으면 정상적으로 건너뜀) — 갱신 주기 및 수동 트리거는 아래의 "CodeQL 래칫" 참조 | 예 | +| 스크립트 | 검증 항목 | 차단 여부 | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| `quality:collect` | `quality-metrics.json` 생성(ESLint 경고 수, 병합된 샤드 보고서의 커버리지) | 예(래칫의 선행 단계) | +| `quality:ratchet` | `quality-baseline.json`의 각 메트릭이 악화되지 않았는지 확인(ESLint 경고 ≤ 기준선, 커버리지 ≥ 기준선) | 예 | +| `check:duplication` | 코드 중복(jscpd@4)이 `quality-baseline.json`의 기준선을 초과하지 않는지 확인 | 예 | +| `check:complexity` | 파일 수준 순환 복잡도가 상한을 초과하지 않는지 확인(코어 ESLint `complexity` + `max-lines-per-function`) | 예 | +| `check:cognitive-complexity` | 인지 복잡도 래칫(`eslint-plugin-sonarjs`) — 별도의 ESLint 패스이며, CI에서는 두 패스를 단일 `check:complexity-ratchets` 단계로 병합하여 실행 | 예 | +| `check:dead-code` | 사용되지 않는 내보내기/파일 래칫(knip)이 기준선 대비 악화되지 않는지 확인 | 예 | +| `check:compression-budget` | 압축 벤치마크 예산 — 엔진별 토큰 절감률 하한이 악화되지 않아야 함 | 예 | +| `check:type-coverage` | 타입 지정 비율 래칫(`type-coverage`)이 악화되지 않는지 확인하며, 대부분 `typecheck:noimplicit:core`를 포괄 | 예 | +| `check:codeql-ratchet` | 열린 CodeQL 경고 수가 악화되지 않는지 확인(`gh api`를 통해 조회하며, 토큰이 없으면 정상적으로 건너뜀) — 갱신 주기 및 수동 트리거는 아래의 "CodeQL 래칫" 참조 | 예 | ### 작업: `quality-extended` 전체 작업은 권고용입니다(`continue-on-error: true`). npm 기반 래칫은 -실제로 실행됩니다. 외부 스캐너는 `gh release download`를 통해 설치되며, 바이너리가 -여전히 없으면 자체적으로 건너뜁니다(exit 0). - -| 스크립트 | 검증 항목 | 차단 여부 | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| `check:circular-deps` | 순환 종속성이 없는지 확인(dpdm) | **권고** | -| `check:bundle-size` | 번들 크기가 상한을 초과하지 않는지 확인 | **권고** | -| `check:secrets` | 비밀 정보 스캔(gitleaks) — 바이너리가 없으면 건너뜀 | **권고** | -| `check:vuln-ratchet` | 종속성 취약점(osv-scanner)이 퇴보하지 않는지 확인 — 바이너리가 없으면 건너뜀 | **권고** | -| `check:workflows` | 워크플로 린트(actionlint + zizmor). 스캐너 누락/오작동, 유효하지 않은 보고서 또는 래칫 기준선 누락 시 INCOMPLETE로 실패. 유효한 발견 사항에는 선택한 엄격/권고/래칫 정책 적용 | 실행 필수, CI에서 zizmor 래칫은 차단됨 | -| `check:openapi-breaking` | 기본 브랜치 대비 공개 API 계약(`openapi.yaml`)의 호환성을 깨뜨리는 변경 사항(oasdiff) — `openapiBreaking=N` 생성. oasdiff가 없거나 기본 명세를 확인할 수 없으면 건너뜀 | **권고** | +실제로 실행되며, 외부 스캐너는 `gh release download`를 통해 설치되고 바이너리가 +여전히 없으면 자체적으로 건너뜁니다(종료 코드 0). + +| 스크립트 | 검증 항목 | 차단 여부 | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `check:circular-deps` | 순환 종속성이 없는지 확인(dpdm) | **권고** | +| `check:bundle-size` | 번들 크기가 상한을 초과하지 않는지 확인 | **권고** | +| `check:secrets` | 비밀 정보 스캔(gitleaks) — 바이너리가 없으면 건너뜀 | **권고** | +| `check:vuln-ratchet` | 종속성 취약점(osv-scanner)이 악화되지 않는지 확인 — 바이너리가 없으면 건너뜀 | **권고** | +| `check:workflows` | 워크플로 린트(actionlint + zizmor). 스캐너가 없거나 손상된 경우, 보고서가 유효하지 않은 경우 또는 래칫 기준선이 없는 경우 INCOMPLETE로 실패합니다. 유효한 발견 항목에는 선택된 엄격/권고/래칫 정책이 적용됩니다 | 실행 필수, CI에서 zizmor 래칫은 차단 항목 | +| `check:openapi-breaking` | 기본 브랜치 대비 공개 API 계약(`openapi.yaml`)의 호환성을 깨뜨리는 변경(oasdiff) — `openapiBreaking=N` 생성. oasdiff가 없거나 기본 명세를 확인할 수 없으면 건너뜀 | **권고** | ### 작업: `docs-sync-strict` -`main`에 대한 모든 PR에서 실행됩니다. 실패하면 병합을 차단합니다. - -| 스크립트 | 검증 항목 | 차단 여부 | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- | -| `check:docs-all` | 아래 6개의 하위 게이트를 순차적으로 실행하는 메타 게이트 | 예 | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt 버전 일관성 | 예 | -| ↳ `check:docs-counts` | 문서 본문의 개수(프로바이더 수, 마이그레이션 수 등)가 실제 개수의 래칫 허용 범위 내에 있는지 확인 | 예 | -| ↳ `check:env-doc-sync` | `.env.example`의 모든 환경 변수가 문서 표에 기록되어 있고, 그 반대도 성립하는지 확인 | 예 | -| ↳ `check:deprecated-versions` | 문서에 지원 중단된 버전 문자열이 없는지 확인 | 예 | -| ↳ `check:doc-links` | 문서의 내부 마크다운 링크가 실제 파일로 연결되는지 확인(`[text]`/`(path)` 형식) | 예 | -| ↳ `check:fabricated-docs` | 문서에서 언급한 라우트, 환경 변수, CLI 명령, 훅 이름 및 파일 경로가 코드베이스에 존재하는지 확인. `--strict` 사용 시 하드 게이트이며, 플래그가 없으면 소프트 실패. | 예(CI에서 `--strict` 사용) | -| `check:cli-i18n` | CLI 명령 문자열이 모든 i18n 로케일 파일에 있는지 확인 | 예 | -| `check:openapi-coverage` | OpenAPI 명세가 실제 라우트 중 래칫 방식으로 설정된 최소 기준 이상을 포함하는지 확인 | 예 | -| `check:openapi-security-tiers` | `openapi.yaml`의 보안 등급 주석이 `routeGuard.ts` 분류와 일치하는지 확인 | **권고** | -| `check:openapi-routes` | `openapi.yaml`의 모든 경로가 실제 `route.ts`로 연결되는지 확인(환각 방지) | 예 | -| `check:docs-symbols` | `docs/**/*.md`의 모든 `/api/...` 참조가 실제 `route.ts`로 연결되는지 확인(환각 방지) | 예 | -| `i18n translation drift` | i18n 로케일 파일의 번역되지 않은 키 — 경고만 표시 | **권고** | +`main`에 대한 모든 PR에서 실행됩니다. 실패 시 병합을 차단합니다. + +| 스크립트 | 검증 내용 | 차단 여부 | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | 아래의 6개 하위 게이트를 순차적으로 실행하는 메타 게이트 | 예 | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt 버전 일관성 | 예 | +| ↳ `check:docs-counts` | 문서 본문의 수치(제공자 수, 마이그레이션 수 등)가 실제 수치의 래칫 범위 내에 있는지 확인 | 예 | +| ↳ `check:env-doc-sync` | `.env.example`의 모든 환경 변수가 문서 표에 기록되어 있고, 그 반대도 성립하는지 확인 | 예 | +| ↳ `check:deprecated-versions` | 문서에 지원 중단된 버전 문자열이 없는지 확인 | 예 | +| ↳ `check:doc-links` | 문서의 내부 마크다운 링크가 실제 파일로 연결되는지 확인(`[text]`/`(path)` 형식) | 예 | +| ↳ `check:fabricated-docs` | 문서에 언급된 라우트, 환경 변수, CLI 명령어, 훅 이름 및 파일 경로가 코드베이스에 존재하는지 확인. `--strict`를 사용하면 하드 게이트이며, 플래그가 없으면 소프트 실패. | 예(CI에서 `--strict` 사용) | +| `check:cli-i18n` | CLI 명령어 문자열이 모든 i18n 로케일 파일에 존재하는지 확인 | 예 | +| `check:openapi-coverage` | OpenAPI 명세가 래칫으로 설정된 실제 라우트의 최소 기준 이상을 포괄하는지 확인 | 예 | +| `check:openapi-security-tiers` | `openapi.yaml`의 보안 계층 어노테이션이 `routeGuard.ts` 분류와 일치하는지 확인 | **권고** | +| `check:openapi-routes` | `openapi.yaml`의 모든 경로가 실제 `route.ts`로 연결되는지 확인(환각 방지) | 예 | +| `check:docs-symbols` | `docs/**/*.md`의 모든 `/api/...` 참조가 실제 `route.ts`로 연결되는지 확인(환각 방지) | 예 | +| `i18n translation drift` | i18n 로케일 파일의 번역되지 않은 키 — 경고만 표시 | **권고** | ### 작업: `i18n-ui-coverage` -| 스크립트 | 검증 항목 | 차단 여부 | +| 스크립트 | 검증 내용 | 차단 여부 | | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check-ui-keys-coverage` (인라인) | UI i18n 키 적용 범위가 65% 이상인지 확인 | 예 | -| `check-ui-value-drift` (인라인) | 다시 작성된 영어 **값**으로 인해 오래된 번역이 남아 있지 않은지 확인 | 예 | +| `check-ui-keys-coverage` (인라인) | UI i18n 키 커버리지가 65% 이상인지 확인 | 예 | +| `check-ui-value-drift` (인라인) | 재작성된 영어 **값**에 오래된 번역이 남아 있지 않은지 확인 | 예 | | `check-new-key-coverage` (인라인) | **새로운** 영어 키가 모든 로케일에서 번역되었는지 확인 — `__MISSING__:` 마커는 거부됨 | 예 | -| `check-translation-ratio` | 로케일별 실제 번역 비율(허용 목록에 포함되지 않은 영어와 동일한 값 / 플레이스홀더 / 누락된 리프)이 `config/quality/i18n-translation-baseline.json` + 여유치를 초과하지 않아야 함 | **권고** | +| `check-translation-ratio` | 로케일별 실제 번역 비율(허용 목록에 포함되지 않은 영어와 동일한 값 / 플레이스홀더 / 누락된 리프)이 `config/quality/i18n-translation-baseline.json` + 여유분을 초과하지 않아야 함 | **권고** | -`fetch-depth: 0`이 필요합니다 — 값 드리프트 게이트가 병합 기준점을 기준으로 `en.json`의 차이를 비교합니다. +`fetch-depth: 0`이 필요합니다. 값 드리프트 게이트는 병합 기준점을 기준으로 `en.json`의 차이를 비교합니다. #### `check-ui-value-drift` — 오래된 번역 게이트 다른 게이트가 구조적으로 감지할 수 없는 한 가지 i18n 회귀를 포착합니다. 영어 값이 -다시 작성되었지만 _이전_ 영어에서 파생된 번역은 그대로 남아 비영어권 사용자가 -확신에 찬 어조의, 이제는 잘못된 문구를 계속 읽게 되는 경우입니다. +재작성되었지만 _이전_ 영어에서 파생된 번역은 그대로 남아 있어, 영어가 아닌 언어의 +사용자가 확신에 찬 어조로 작성된, 이제는 잘못된 문구를 계속 읽게 되는 경우입니다. -이 문제는 실제로 배포되었습니다. Antigravity 로그인 도우미가 도입되었을 때(#5203) -`oauthModal.googleOAuthWarning`이 다시 작성되었지만, **43개 로케일 중 39개**에는 -운영자에게 "전체 URL을 복사하여 아래에 붙여넣으라"고 안내하는 문구가 그대로 남았습니다. -해당 프로바이더에서는 완료할 수 없는 흐름이었습니다. 이 문제는 다음 이유로 #8463까지 +이 문제는 실제로 배포되었습니다. Antigravity 로그인 도우미가 추가되었을 때(#5203) +`oauthModal.googleOAuthWarning`이 재작성되었지만, **43개 로케일 중 39개**에는 운영자에게 +"전체 URL을 복사하여 아래에 붙여 넣으라"고 안내하는 문구가 그대로 남아 있었습니다. +해당 제공자에서는 완료할 수 없는 흐름이었습니다. 이 문제는 다음 이유로 #8463까지 발견되지 않았습니다. -- `sync-ui-keys`는 **누락된** 키만 채우며, **오래된** 키는 절대 갱신하지 않습니다. -- `check-ui-keys-coverage`는 키의 _존재 여부_를 계산하므로, 오래된 번역도 적용된 것으로 집계됩니다. +- `sync-ui-keys`는 **없는** 키만 백필하며, **오래된** 키는 절대 처리하지 않습니다. +- `check-ui-keys-coverage`는 키의 _존재 여부_를 계산하므로, 오래된 번역도 커버된 것으로 간주됩니다. - `check-translation-drift`는 `docs/i18n//**.md` 문서 미러를 추적하며 — - `src/i18n/messages/*.json`은 절대 읽지 않습니다. 2026-09 재동기화 이후 작업 - `docs-sync-strict`에서 차단됩니다. 핵심 문서 편집 → `npm run i18n:run -- --files=` - (섹션 단위로 실행되며 비용이 적음). + `src/i18n/messages/*.json`은 전혀 읽지 않습니다. 2026-09 재동기화 이후 작업 + `docs-sync-strict`에서 차단됩니다. 핵심 문서를 편집하면 → `npm run i18n:run -- --files=`를 실행하세요(섹션 수준으로 처리되어 비용이 적음). -**diff를 인식하며, 기준선에 의존하지 않습니다.** 병합 베이스의 `en.json`과 -작업 트리를 비교합니다. 영어 값이 변경된 모든 키에 대해, 변경되지 않은 번역을 -여전히 유지하는 로케일은 오래된 것으로 간주됩니다. 이는 의도적으로 **기존 부채를 동결합니다**. -diff만으로는 오래된 번역이 어떤 이전 영어 문구에서 비롯되었는지 알 수 없으므로, 이 게이트는 -현재 변경 사항이 건드린 부분만 판단합니다. 대안인 키별 해시 기준선은 -약 600 KB의 생성 파일을 필요로 하며, 이는 현재 가장 큰 기준선의 3배이고 모든 i18n PR마다 변경됩니다. +**차이 인식 방식이며, 기준선에 의존하지 않습니다.** 병합 기준점의 `en.json`과 작업 트리를 비교합니다. 영어 값이 변경된 모든 키에 대해, 변경되지 않은 번역을 그대로 유지하는 로케일은 오래된 상태로 간주됩니다. 이는 의도적으로 **기존 부채를 동결**합니다. 차이만으로는 오래된 번역이 어떤 이전 영어 문구에서 비롯되었는지 알 수 없으므로, 이 게이트는 현재 변경 사항이 건드리는 부분만 판단합니다. 대안인 키별 해시 기준선은 약 600 KB의 생성 파일을 필요로 하며, 이는 기존 최대 기준선의 3배 크기이고 모든 i18n PR마다 변경됩니다. 이를 충족하는 방법은 두 가지입니다. 1. 영향을 받는 번역을 업데이트하거나 -2. 해당 값을 `__MISSING__:`로 설정합니다. 그러면 런타임이 수정된 영어를 제공하고 - (`src/i18n/request.ts::deepMergeFallback`, #7258) 해당 키는 번역 대기열에 추가됩니다. +2. 해당 값을 `__MISSING__:<새 영어 문구>`로 설정합니다. 그러면 런타임은 수정된 영어 문구를 제공하고 + (`src/i18n/request.ts::deepMergeFallback`, #7258), 해당 키는 번역 대기열에 추가됩니다. -문자열의 **의미**가 변경되었다면 **키 이름을 변경하는 것**이 좋습니다. 새 키는 -오래된 번역을 상속할 수 없습니다. #8463에서 사용한 패턴이 바로 이것입니다. +문자열의 **의미**가 변경되었다면 **키 이름을 변경**하는 것이 좋습니다. 새 키는 오래된 번역을 상속할 수 없습니다. #8463에서 이 패턴을 사용했습니다. ```bash npm run i18n:check-value-drift # 엄격 모드(CI에서 실행하는 방식) @@ -235,8 +226,7 @@ npm run i18n:check-value-drift:warn # 보고만 수행 BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -기본 카탈로그를 읽을 수 없는 경우(기본 ref가 없는 얕은 clone) -`check-openapi-breaking`과 동일하게 `SKIP reason=base-unresolved`를 출력하고 종료 코드 0으로 종료합니다. +기준 카탈로그를 읽을 수 없는 경우(기준 ref가 없는 얕은 클론), `check-openapi-breaking`과 동일하게 `SKIP reason=base-unresolved`를 출력하고 종료 코드 0으로 종료합니다. ### 작업: `i18n` @@ -244,39 +234,39 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift | 스크립트 | 검증 항목 | 차단 여부 | | ------------------------------- | -------------------- | ---------------------------------------------------- | -| `validate_translation.py quick` | 로케일별 번역 완성도 | **권고**(전체 작업에 `continue-on-error: true` 적용) | +| `validate_translation.py quick` | 로케일별 번역 완전성 | **권고**(전체 작업에 `continue-on-error: true` 적용) | ### 작업: `pr-test-policy` 풀 리퀘스트에서만 실행됩니다. -| 스크립트 | 검증 항목 | 차단 여부 | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` 또는 `bin/`의 프로덕션 코드를 변경하는 PR은 테스트를 포함하거나 업데이트해야 함(강경 규칙 #8) | 예 | -| `check:test-masking` | 변경된 테스트 파일이 순 어설션 수를 줄이거나 `assert.ok(true)` 항진식을 추가하지 않는지 확인 | 예 | -| `check:pr-evidence` | PR 본문에 변경 사항에 대한 테스트/VPS 증거가 명시되어 있는지 확인(PR 본문을 grep하여 강경 규칙 #18을 자동화함 — 취약하므로 Backlog 참조) | 예 | +| 스크립트 | 검증 항목 | 차단 여부 | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` 또는 `bin/`의 프로덕션 코드를 변경하는 PR은 테스트를 포함하거나 업데이트해야 함(강제 규칙 #8) | 예 | +| `check:test-masking` | 변경된 테스트 파일이 순 어설션 수를 줄이거나 `assert.ok(true)` 같은 항진 명제를 추가하지 않는지 확인 | 예 | +| `check:pr-evidence` | PR 본문에 변경 사항에 대한 테스트/VPS 근거가 명시되어 있는지 확인(PR 설명을 grep하여 강제 규칙 #18을 자동화 — 취약함, Backlog 참조) | 예 | ### 작업: `test-vitest` -`build` 후에 실행됩니다. 실패 시 병합을 차단합니다. +`build` 이후에 실행됩니다. 실패하면 병합을 차단합니다. -| 스위트 | 검증 항목 | 차단 여부 | -| ---------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP 서버(도구 110개), autoCombo, cache — vitest 러너 | 예 | -| `test:vitest:ui` | UI 컴포넌트 테스트 — vitest 러너 | **차단** — 기존 실패는 `vitest.config.ts`에서 명시적으로 제외되며, 새로운 실패가 발생하면 작업이 실패함 | +| 스위트 | 검증 항목 | 차단 여부 | +| ---------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP 서버(도구 110개), autoCombo, 캐시 — vitest 러너 | 예 | +| `test:vitest:ui` | UI 컴포넌트 테스트 — vitest 러너 | **차단** — 기존 실패 항목은 `vitest.config.ts`에서 명시적으로 제외되며, 새로운 실패는 작업을 실패 처리함 | ### 야간 워크플로(예약 실행, 권고) -cron 일정에 따라(그리고 `workflow_dispatch`를 통해) 실행되며, PR에서는 실행되지 않습니다. 모두 권고 사항입니다. +이 워크플로는 cron 일정에 따라 실행되며(`workflow_dispatch`로도 실행 가능), PR에서는 실행되지 않습니다. 모두 권고 사항입니다. | 워크플로 | 검증 항목 | 차단 여부 | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `nightly-property` | 무작위 seed와 높은 실행 횟수를 사용하는 fast-check 속성 테스트 | **권고** | -| `nightly-resilience` | heap 증가 게이트, chaos fault-injection, k6 부하/지속 테스트 | **권고** | -| `nightly-llm-security` | promptfoo injection guard(차단 모드) + garak probe(provider secret이 없으면 건너뜀) | **권고** | -| `nightly-schemathesis` | `docs/openapi.yaml`을 사용하여 실행 중인 OmniRoute를 대상으로 수행하는 OpenAPI 계약 퍼징(schemathesis) — 명세 위반/처리되지 않은 500 오류를 드러냄(단계 8 B.4) | **권고** | -| `nightly-mutation` | 빠른 단위 테스트 레인에 대한 Stryker mutation-testing 점수 — 살아남은 mutant는 취약한 어설션을 드러냄 | **권고** | -| `nightly-compat` | 지원되는 `engines.node` 범위 전반의 Node 엔진 호환성 매트릭스 | **권고** | +| `nightly-property` | 무작위 시드와 높은 실행 횟수를 사용하는 fast-check 속성 테스트 | **권고** | +| `nightly-resilience` | 힙 증가 게이트, 카오스 장애 주입, k6 부하/소크 테스트 | **권고** | +| `nightly-llm-security` | promptfoo 인젝션 가드(차단 모드) + garak 프로브(프로바이더 시크릿이 없으면 건너뜀) | **권고** | +| `nightly-schemathesis` | `docs/openapi.yaml`을 사용하여 실행 중인 OmniRoute를 대상으로 수행하는 OpenAPI 계약 퍼징(schemathesis) — 명세 위반/처리되지 않은 500 오류를 드러냄(Fase 8 B.4) | **권고** | +| `nightly-mutation` | 빠른 단위 테스트 레인에 대한 Stryker 변이 테스트 점수 — 살아남은 변이는 취약한 어설션을 드러냄 | **권고** | +| `nightly-compat` | 지원되는 `engines.node` 범위 전반에 걸친 Node 엔진 호환성 매트릭스 | **권고** | --- @@ -534,43 +524,43 @@ CI 게이트 외에도 OmniRoute는 **선택 사항**인 `agent-lsp` 스캐폴 --- -## 합리화 백로그 (ROI 검토 — 9단계 3차) +## 합리화 백로그(ROI 검토 — 9단계 3차) -이 인벤토리는 2026-06-17에 `ci.yml`을 기준으로 대조되었습니다(이전 버전에서는 +이 인벤토리는 2026-06-17에 `ci.yml`을 기준으로 대조되었습니다(이전 버전에는 `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`가 누락됨). 대조된 항목에 대한 ROI 검토를 통해 -다음과 같은 합리화 후보가 식별되었습니다. **병합은 기계적인 CI 변경이며, -전환/제거는 운영자에게 유보된 정책 결정입니다.** 아래 내용은 아직 +`check:codeql-ratchet`, `check:pr-evidence`가 누락되어 있었습니다). 대조된 항목에 대한 ROI 검토를 통해 +다음과 같은 합리화 후보를 식별했습니다. **병합은 기계적인 CI +변경이며, 전환/제거는 운영자가 결정해야 하는 정책 사항입니다.** 아래 항목은 아직 적용되지 않았습니다. -**위에서 문서화되지 않은 추가 항목**(권고 수준, 신호가 약함): `docs-lint` 작업 -(markdownlint + Vale, 전체 작업에 `continue-on-error` 적용) 및 독립형 스캐너 워크플로 +**위에 문서화되지 않은 추가 항목**(권고 수준, 낮은 신호): `docs-lint` 작업 +(markdownlint + Vale, 전체 작업에 `continue-on-error` 적용)과 독립형 스캐너 워크플로 `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0`은 -`quality-baseline.json`에 있지만 `ci.yml`의 차단형 래칫과 연결되어 있지 않습니다. 현재 이 메트릭은 +`quality-baseline.json`에 있지만 `ci.yml`의 차단형 래칫과 연결되어 있지 않습니다. 즉, 현재 이 메트릭은 고립된 상태입니다. -### 병합 / 중복 제거 (기계적, 위험도 낮음) +### 병합 / 중복 제거(기계적, 낮은 위험) 각 후보는 2026-06-17의 실제 게이트 상태를 기준으로 검증되었습니다(신뢰하되 검증); -몇몇 "명백한" 병합이 실제로는 부채를 숨기고 있는 것으로 드러났으며 **즉시 대체 가능한 깔끔한 변경이 아닙니다**. - -- **`check:docs-sync`가 두 번 실행됨** — `lint` 작업에서 독립적으로 실행되고, `check:docs-all` 내부(`docs-sync-strict`)와 husky pre-commit 훅에서 다시 실행됩니다. ✅ **완료** — 독립적인 `lint` 호출이 제거되었습니다. -- **CVE 스캔** — ❌ **깔끔하게 병합할 수 없음.** `audit:deps`는 high/critical CVE가 하나라도 있으면 즉시 실패합니다. `check:vuln-ratchet`(osv)은 기준선(현재 MODERATE 1건) 대비 _회귀_가 있을 때만 실패합니다. 의미 체계가 다르므로 `audit:deps`를 제거하면 절대적인 high/critical 게이트를 잃게 됩니다. 둘 다 유지합니다. -- **순환 종속성 탐지** — ❌ **깔끔하게 병합할 수 없음.** `check:circular-deps`(dpdm)는 **91개의 순환**을 보고합니다(이 때문에 권고 수준임). 이를 먼저 해결하지 않고는 차단형으로 승격할 수 없으며, 정상 상태인 선별된 `check:cycles`보다 범위가 더 넓습니다. `check:cycles`는 차단형으로 유지하고, dpdm 순환 91개 해결은 별도의 백로그로 관리합니다. -- **복잡도** — ✅ **완료** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ESLint를 한 번 순회하며 ruleId별로 집계하므로 cyclomatic+max-lines와 cognitive 기준선이 서로 독립적으로 유지됩니다. 개별 `check:complexity` / `check:cognitive-complexity`는 로컬 `--update`용으로 유지됩니다. -- **`/api` 환각 방지** — ✅ **완료** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`의 FS 인벤토리를 한 번만 생성하며, openapi-routes + docs-symbols는 계속 독립적으로 보고합니다. 개별 항목은 로컬 실행용으로 유지됩니다. -- **`check:node-runtime`이 11개 작업에서 실행됨** — ⚠️ **ROI 낮음.** 각각 별도의 러너이며 검사는 1초 미만입니다. 총 절감 시간은 약 10초지만, 작업별로 저렴한 보호 장치를 잃게 됩니다. 변경에 따른 혼란을 감수할 가치가 없습니다. -- **CI lint의 `typecheck:noimplicit:core`** — ✅ **lint 작업에서 제거됨**(기존에는 권고 수준의 `continue-on-error`였음). 차단형 타입 표면은 `typecheck:core` + `check:type-coverage`입니다. 로컬 스크립트는 유지되었습니다. - -### 전환 / 결정 (운영자 정책) - -- `check:openapi-security-tiers` (권고 수준) — ❌ **깔끔하게 전환할 수 없음.** 종료 코드는 0이지만 `LOCAL_ONLY_API_PREFIXES` 아래의 여러 `traffic-inspector` 라우트에 `x-loopback-only: true` 주석이 없다고 경고합니다. 이를 강제하려면 먼저 해당 주석을 `openapi.yaml`에 추가해야 합니다. -- `typecheck:noimplicit:core` (권고 수준) — 차단형 `check:type-coverage` 래칫에 대부분 포함됩니다. 래칫으로 전환하거나 중복되는 두 번째 `tsc` 패스를 제거합니다. -- `test:vitest:ui` (현재 **차단형**) — 기존 실패는 `vitest.config.ts`에서 `// #8618` 추적 주석과 함께 명시적으로 제외되어 있으며, 새로운 실패는 작업 실패로 처리됩니다. -- `check:secrets` (gitleaks, 문서화된 오탐 3건에 고정된 차단형 래칫) — 3건을 허용 목록에 추가하여 0으로 만들거나 권고 수준으로 강등합니다. GitHub 네이티브 secret-scanning + `check:public-creds`와 중복됩니다. -- `check:pr-evidence` (차단형, PR 본문을 grep으로 검사) — 오탐 위험이 높습니다. 제거하면 강제 규칙 #18의 집행력이 약화되므로 이는 실질적인 정책 결정 사항입니다. -- `semgrep` (권고 수준의 독립형 항목) — OWASP 계열에 대해 CodeQL과 중복됩니다. 기준선을 래칫에 연결하거나 제거합니다. +여러 "명백한" 병합이 실제로는 부채를 숨기고 있는 것으로 드러났으며 **즉시 대체할 수 있는 깔끔한 변경이 아닙니다**. + +- **`check:docs-sync`가 두 번 실행됨** — `lint` 작업에서 독립적으로 실행되고, `check:docs-all`(`docs-sync-strict`) 및 husky pre-commit 훅 내부에서 다시 실행됩니다. ✅ **완료** — 독립적인 `lint` 호출을 제거했습니다. +- **CVE 스캔** — ❌ **깔끔하게 병합할 수 없습니다.** `audit:deps`는 high/critical CVE가 하나라도 있으면 즉시 실패합니다. 반면 `check:vuln-ratchet`(osv)은 기준선(현재 MODERATE 1개) 대비 _회귀_가 있을 때만 실패합니다. 의미 체계가 다르므로 `audit:deps`를 제거하면 high/critical에 대한 절대적 게이트를 잃게 됩니다. 둘 다 유지합니다. +- **순환 감지** — ✅ **완료**(#15159 G-01/G-02). 이전 설명에서는 `check:cycles`를 "정상 상태인 선별된" 게이트로 부르고, `check:circular-deps`(dpdm)가 순환 91개를 보고했기 때문에 이를 차단형으로 유지해야 한다고 정당화했습니다. 그러나 그 정상 상태는 **거짓 정상**이었습니다. `check:cycles`는 5개 하위 디렉터리(파일 450개)를 스캔하고 정적 `import|export … from`만 일치시켰으며, 모든 `@/` 및 `@omniroute/open-sse/` 지정자를 누락했기 때문에 저장소의 대부분을 차지하는 동적 import + 별칭 순환을 감지할 수 없었습니다. 수정 후 게이트는 이제 `src` + `open-sse`(파일 5023개)를 순회하고 TypeScript AST에서 지정자를 수집하며(`import("…")`는 계산하고 타입 위치의 `typeof import("…")`는 계산하지 않음), tsconfig `paths`를 해석합니다. 발견되는 순환은 0개가 아니라 **14개**입니다. 기존 순환 14개는 게이트 PR에서 수정할 수 없으므로, `check:cycles`는 이제 **래칫**입니다(`--ratchet`, `quality-baseline.json`의 상한 `metrics.cycles.value = 14`, `direction: down`). 모든 _회귀_를 차단하며 개수는 감소만 가능합니다. CI는 `npm run check:cycles:ratchet`을 실행합니다. 점진적 감소 작업은 **A-01**과 함께 진행합니다. `check:circular-deps`(dpdm)는 더 광범위한 보조 검증 수단으로서 권고 수준으로 유지합니다. +- **복잡도** — ✅ **완료**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): 단일 ESLint 순회에서 ruleId별로 집계하므로 순환 복잡도+최대 줄 수와 인지 복잡도 기준선이 서로 독립적으로 유지됩니다. 개별 `check:complexity` / `check:cognitive-complexity`는 로컬 `--update`를 위해 유지합니다. +- **`/api` 환각 방지** — ✅ **완료**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`에 대한 단일 FS 인벤토리를 사용하며, openapi-routes + docs-symbols는 계속 독립적으로 보고합니다. 개별 항목은 로컬 실행을 위해 유지합니다. +- **`check:node-runtime`이 11개 작업에서 실행됨** — ⚠️ **낮은 ROI.** 각각 별도의 러너이며 검사는 1초 미만입니다. 총 절감 시간은 약 10초인 반면, 저비용 작업별 가드가 사라집니다. 변경에 따른 혼란을 감수할 가치가 없습니다. +- **CI lint의 `typecheck:noimplicit:core`** — ✅ **lint 작업에서 제거됨**(기존에는 `continue-on-error`가 적용된 권고 수준이었음). 차단형 타입 범위는 `typecheck:core` + `check:type-coverage`입니다. 로컬 스크립트는 유지했습니다. + +### 전환 / 결정(운영자 정책) + +- `check:openapi-security-tiers`(권고 수준) — ❌ **깔끔하게 전환할 수 없습니다.** 종료 코드는 0이지만, `LOCAL_ONLY_API_PREFIXES` 아래의 여러 `traffic-inspector` 라우트에 `x-loopback-only: true` 주석이 없다고 경고합니다. 이를 강제하려면 먼저 해당 주석을 `openapi.yaml`에 추가해야 합니다. +- `typecheck:noimplicit:core`(권고 수준) — 차단형 `check:type-coverage` 래칫이 대부분 대체합니다. 래칫으로 전환하거나 중복되는 두 번째 `tsc` 패스를 제거합니다. +- `test:vitest:ui`(현재 **차단형**) — 기존 실패는 `vitest.config.ts`에서 `// #8618` 추적 주석과 함께 명시적으로 제외되어 있습니다. 새로운 실패가 발생하면 작업이 실패합니다. +- `check:secrets`(gitleaks, 문서화된 오탐 3개에서 고정된 차단형 래칫) — 3개 항목을 허용 목록에 추가하여 0을 달성하거나 권고 수준으로 강등합니다. GitHub 네이티브 비밀 스캔 + `check:public-creds`와 중복됩니다. +- `check:pr-evidence`(차단형, PR 본문 산문을 grep으로 검색) — 오탐 위험이 높습니다. 제거하면 Hard Rule #18의 강제력이 약화되므로 이는 실질적인 정책 결정 사항입니다. +- `semgrep`(권고 수준의 독립형 작업) — OWASP 계열에 대해 CodeQL과 중복됩니다. 기준선을 래칫에 연결하거나 제거합니다. --- diff --git a/docs/i18n/lt/CONTRIBUTING.md b/docs/i18n/lt/CONTRIBUTING.md index ccccf3fe7df..e2967aa4145 100644 --- a/docs/i18n/lt/CONTRIBUTING.md +++ b/docs/i18n/lt/CONTRIBUTING.md @@ -400,22 +400,22 @@ Parašykite vienetinius testus kataloge `tests/unit/`, kurie apimtų bent: --- -## Pull Request kontrolinis sąrašas +## „Pull Request“ kontrolinis sąrašas - [ ] Testai sėkmingi (`npm test`) -- [ ] Linting patikra sėkminga (`npm run lint`) +- [ ] Statinė analizė sėkminga (`npm run lint`) - [ ] Kompiliavimas sėkmingas (`npm run build`) -- [ ] Pridėti naujų viešųjų funkcijų ir sąsajų TypeScript tipai -- [ ] Nėra kode įrašytų paslapčių ar atsarginių reikšmių -- [ ] Vieši pirminio teikėjo prisijungimo duomenys įterpti naudojant `resolvePublicCred()` (žr. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), o ne kaip literalai -- [ ] Klaidų atsakymai apdorojami naudojant `buildErrorBody()` / `sanitizeErrorMessage()` — atsakymų turinyje nėra neapdorotų dėklo išklotinių (žr. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Apvalkalo komandos (`exec` / `spawn`) vykdymo meto reikšmes perduoda per `env`, o ne naudodamos eilučių interpoliaciją +- [ ] Naujoms viešosioms funkcijoms ir sąsajoms pridėti TypeScript tipai +- [ ] Nėra kode tiesiogiai įrašytų paslapčių ar atsarginių reikšmių +- [ ] Vieši išorinės sistemos prisijungimo duomenys įterpiami naudojant `resolvePublicCred()` (žr. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), niekada nenaudojant literalų +- [ ] Klaidų atsakymai apdorojami per `buildErrorBody()` / `sanitizeErrorMessage()` — atsakymų turinyje nėra neapdorotų dėklo trasų (žr. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Apvalkalo komandos (`exec` / `spawn`) vykdymo reikšmes perduoda per `env`, o ne naudodamos eilučių interpoliaciją - [ ] Visos įvestys patikrintos naudojant Zod schemas -- [ ] Naudotojams matomiems pakeitimams pridėtas pakeitimų žurnalo **fragmentas** kataloge `changelog.d/{features|fixes|maintenance}/-.md` (žr. [`changelog.d/README.md`](./changelog.d/README.md)) — **neredaguokite** `CHANGELOG.md` tiesiogiai; fragmentai sujungiami leidimo metu ir niekada nesukelia konfliktų tarp PR +- [ ] Naudotojams matomiems pakeitimams pridėtas pakeitimų žurnalo **fragmentas**, esantis `changelog.d/{features|fixes|maintenance}/-.md` (žr. [`changelog.d/README.md`](./changelog.d/README.md)) — **neredaguokite** `CHANGELOG.md` tiesiogiai; fragmentai sujungiami leidimo metu ir niekada nesukelia konfliktų tarp „Pull Request“ užklausų - [ ] Dokumentacija atnaujinta (jei taikoma) -- [ ] Neatsirado naujų CodeQL / Secret-Scanning įspėjimų arba kiekvienas iš jų atmestas pateikus techninį pagrindimą su nuoroda į atitinkamą `docs/security/` dokumentą -- [ ] Maršrutai, paleidžiantys antrinius procesus (`/api/mcp/`, `/api/cli-tools/runtime/`), faile `src/server/authz/routeGuard.ts` klasifikuojami kaip `isLocalOnlyPath()` — žr. [Griežtąją taisyklę Nr. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Įvykdymo pranešimuose nėra `Co-Authored-By` galinių eilučių — įvykdymai turi būti rodomi tik su saugyklos savininko Git tapatybe (Griežtoji taisyklė Nr. 16) +- [ ] Neatsirado naujų CodeQL / Secret-Scanning įspėjimų arba kiekvienas jų atmestas pateikus techninį pagrindimą su nuoroda į atitinkamą `docs/security/` dokumentą +- [ ] Maršrutai, paleidžiantys antrinius procesus (`/api/mcp/`, `/api/cli-tools/runtime/`), faile `src/server/authz/routeGuard.ts` klasifikuoti kaip `isLocalOnlyPath()` — žr. [griežtą taisyklę Nr. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Įvykdymo pranešimuose nėra DI / robotų `Co-authored-by` užbaigiamųjų eilučių (griežta taisyklė Nr. 16) — žmonės bendradarbiai, kurių darbas panaudojamas pakartotinai, nurodomi standartinėmis `Co-authored-by: Name ` užbaigiamosiomis eilutėmis --- diff --git a/docs/i18n/lt/docs/architecture/QUALITY_GATES.md b/docs/i18n/lt/docs/architecture/QUALITY_GATES.md index 873d550b4e3..cfcb55fc496 100644 --- a/docs/i18n/lt/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/lt/docs/architecture/QUALITY_GATES.md @@ -21,213 +21,215 @@ tos pačios sistemos atkūrimo planą rasite CI ir kokybės užkardų darbo eigos pateikia po stabilų verdiktą: `Gate / CI` ir `Gate / Quality`. Jų versijuojamoje priėmimo politikoje kiekviena ankstesnė užduotis -įvardijama kaip privaloma arba rekomendacinė. Taikoma privaloma užduotis turi būti sėkminga: -trūkstami, atšaukti, praleisti, laukiantys ir nežinomi rezultatai negali patvirtinti PASS. -Galiojanti tik dokumentacijos arba tik katalogo klasifikacija gali padaryti kodo vykdymo šaką -netaikomą; juodraštinis PR nelaikomas priimtu kandidatu. Žyma `hotfix` neatleidžia nuo -įrodymų pateikimo. - -Abi darbo eigos apima PR ir siuntimus į pagrindines / leidimo šakas, rankinį paleidimą ir -sujungimo grupių įvykius. Siuntimo, paleidimo ir sujungimo grupių atvejais vykdomas visas -rinkinys. Išsišakojusios saugyklos ir sujungimo grupės naudoja prieglobos vykdykles užduotims, -kurios kitais atvejais pasirinktų savarankiškai administruojamas vykdykles; prieš diegimą -reikia patikrinti, ar prieglobos pajėgumų pakanka. - -Kiekviename JSON kvite nurodomi paimtos versijos SHA, darbo eigos vykdymas ir bandymas. -CLI atmeta neatitiktį tarp paimtos versijos ir įvykio SHA. Darbo eigos testai susieja -politikos narystę su verdikto užduoties `needs` sąrašu, kad nauja arba pašalinta vykdymo šaka -negalėtų nepastebimai dingti. Kvitai apima tik savo darbo eigą, o ne publikavimą, diegimą ar -esamo rekomendacinio skaitytuvo vidinį veikimą. Abiejų patikros pavadinimų aktyvinimas šakų -taisyklėse yra atskiras administracinis pakeitimas; vien šių užduočių pridėjimas šakos -neapsaugo. - -### Statinės patikros inventorius - -Versijuojamas npm alternatyviųjų pavadinimų inventorius ir statinės patikros narystė saugomi -`config/quality/gate-manifest.json`. Paleiskite `npm run check:gate-manifest`, kad pagal -`package.json` patikrintumėte scenarijų pavadinimus ir tikslias komandas; papildymai, -pašalinimai ir komandų neatitikimai lemia tiek vietinio kabliuko, tiek pakeitimų -klasifikavimo užduočių CI aplinkoje nesėkmę. Alternatyvusis pavadinimas nėra darbo eigos -užduotis, matricos egzempliorius ar testo atvejis: šių skaičių negalima pateikti kaip -tarpusavyje pakeičiamų. - -Naudokite `npm run quality:scan -- --list` arba `npm run quality:scan:fast -- --list`, -kad peržiūrėtumėte pasirinktus alternatyviuosius pavadinimus jų nevykdydami. Vykdyklė -paleidžia npm įvesties tašką, todėl išlaikoma jo vykdymo aplinka (įskaitant Bun, kur jis -sukonfigūruotas). Apraše užregistruoti už šių profilių ribų esantys alternatyvieji -pavadinimai kaip paleidžiami atskirai, o priežiūros komandos draudžiamos tik skaitymui -skirtuose patikros profiliuose. - -Šie profiliai apima tik statinę patikrą. Jie nepatvirtina produkto testų, aprėpties, -pakavimo, išorinių patikrų ar viso kandidato priėmimo leidimui. Priėmimas darbo eigoje -naudoja susietus `config/quality/admission-policy.json` ir +įvardijama kaip privaloma arba rekomendacinė. Taikoma privaloma užduotis turi būti +sėkminga: trūkstami, atšaukti, praleisti, laukiantys ir nežinomi rezultatai negali +patvirtinti PASS. Tinkama tik dokumentų arba tik katalogo pakeitimų klasifikacija +gali padaryti kodo vykdymo šaką netaikomą; juodraštinė PR nelaikoma priimtu kandidatu. +Žyma `hotfix` neatleidžia nuo įrodymų pateikimo. + +Abi darbo eigos apima PR ir siuntimus į pagrindines / leidimo šakas, rankinį paleidimą +ir sujungimo grupės įvykius. Siuntimo, rankinio paleidimo ir sujungimo grupės atvejais +vykdomas visas rinkinys. Išsišakojusios saugyklos ir sujungimo grupės naudoja prieglobos +vykdykles užduotims, kurios kitu atveju pasirinktų savarankiškai valdomas vykdykles; +prieš diegimą būtina patikrinti, ar prieglobos pajėgumų pakanka. + +Kiekviename JSON kvite nurodomi paimtos versijos SHA, darbo eigos paleidimas ir bandymas. +CLI atmeta atvejį, kai paimtos versijos ir įvykio SHA nesutampa. Darbo eigos testai +susieja politikos narystę su verdikto užduoties `needs` sąrašu, kad nauja ar pašalinta +vykdymo šaka negalėtų nepastebimai dingti. Kvitai apima tik savo darbo eigą, o ne +publikavimą, diegimą ar esamo rekomendacinio skaitytuvo vidinę veiklą. Abiejų patikrų +pavadinimų aktyvinimas šakų taisyklėse yra atskiras administracinis pakeitimas; +vien šių užduočių pridėjimas šakos neapsaugo. + +### Statinės analizės inventorius + +Versijuojamas npm alternatyviųjų pavadinimų inventorius ir statinės analizės sudėtis +saugomi faile `config/quality/gate-manifest.json`. Paleiskite +`npm run check:gate-manifest`, kad patikrintumėte scenarijų pavadinimus ir tikslias +komandas pagal `package.json`; papildymai, pašalinimai ir komandų neatitikimai sukelia +klaidą tiek vietiniame kabliuke, tiek CI pakeitimų klasifikavimo užduotyse. +Alternatyvusis pavadinimas nėra darbo eigos užduotis, matricos egzempliorius ar testo +atvejis: šie skaičiai neturi būti pateikiami kaip lygiaverčiai. + +Naudokite `npm run quality:scan -- --list` arba +`npm run quality:scan:fast -- --list`, kad peržiūrėtumėte pasirinktus alternatyviuosius +pavadinimus jų nevykdydami. Vykdyklė iškviečia npm įėjimo tašką, todėl išsaugoma jo +vykdymo aplinka (įskaitant Bun, kur jis sukonfigūruotas). Apraše alternatyvieji +pavadinimai, nepriklausantys šiems profiliams, pažymėti kaip iškviečiami atskirai, +o priežiūros komandos draudžiamos tik skaitymui skirtuose analizės profiliuose. + +Šie profiliai apima tik statinę analizę. Jie nepatvirtina produkto testų, aprėpties, +pakavimo, išorinių patikrų ar visapusiško kandidato priėmimo leidimui. Darbo eigos +priėmimui naudojami susieti `config/quality/admission-policy.json` ir `scripts/quality/admission-verdict.mjs`. Leidimo stebėtojo profiliai lieka atskiri; -jų taikomas patikras ir kvitus tikrinkite nepriklausomai. Toliau pateiktas tekstinis -inventorius yra informacinis, o ne įrodymas, kad užkarda iš tikrųjų buvo paleista. +jų taikomas patikras ir kvitus tikrinkite nepriklausomai. Toliau pateikiamas tekstinis +inventorius yra informacinis ir neįrodo, kad užkarda iš tikrųjų buvo paleista. -Scenarijai yra kataloguose `scripts/check/` (politikos užkardos) ir `scripts/quality/` -(griežtinimo mechanizmas). CI tiesos šaltinis yra `.github/workflows/ci.yml`. +Scenarijai yra kataloguose `scripts/check/` (politikos užkardos) ir +`scripts/quality/` (kartelės kėlimo variklis). +Pagrindinis CI informacijos šaltinis yra `.github/workflows/ci.yml`. ### Spartusis leidimo PR kelias (`quality.yml`) -`.github/workflows/quality.yml` papildo CI pagrindinių / leidimo šakų PR, siuntimų į -apsaugotas šakas, rankinio paleidimo ir sujungimo grupių atvejais. PR naudoja pagal kelius -filtruojamas sparčiąsias patikras. Visam laikui išjungtas pasikartojantis kūrimas buvo -pašalintas; tikrosios kūrimo / pakavimo / paleidimo patikros lieka CI. - -| Užduotis | Aprėptis | Blokuojanti | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `Docs Gates (fast-path)` | Dokumentacijos / kodo PR; API dokumentacijos nuorodos ir visa dokumentacija | Taip | -| `Fast Quality Gates` | Kodo PR; statinės patikros, tipų patikra, ataskaitų srities tipų patikra, paveikti vienetų testai | Taip | -| `Forgotten sibling tests` | Kodo PR; pakeisti moduliai atsekami iki statinių naudotojų ir galimų susijusių testų; grupuojančių modulių ir dinaminių importų keliai pateikiami kaip rekomendacinė diagnostika, atsižvelgiant į nurodytas leidžiamojo sąrašo išimtis | **Rekomendacinė** | -| `Vitest (fast-path)` | Kodo PR; spartusis vitest rinkinys | Taip | -| `Unit Tests fast-path` | Kodo PR; į 4 dalis suskaidytas vienetų testų rinkinys | Taip | -| `No new ESLint warnings` | Kodo PR; lint apsauga, atsižvelgianti į įspėjimų slopinimą | Taip, įskaitant išsišakojusias saugyklas | -| `Merge integrity (changelog + generated skills)` | Ne juodraštiniai PR; pakeitimų žurnalo ir sugeneruotų įgūdžių sinchronizavimas | Taip, įskaitant išsišakojusias saugyklas | +`.github/workflows/quality.yml` papildo CI pagrindinių / leidimo šakų PR, siuntimų +į apsaugotas šakas, rankinio paleidimo ir sujungimo grupių atvejais. PR naudojamos +pagal kelius filtruojamos sparčiosios patikros. Visam laikui išjungta besidubliuojanti +kompiliavimo užduotis pašalinta; tikrosios kompiliavimo / pakavimo / paleidimo patikros +lieka CI. + +| Užduotis | Aprėptis | Blokuojanti | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | +| `Docs Gates (fast-path)` | Dokumentų / kodo PR; API dokumentacijos nuorodos ir visi dokumentai | Taip | +| `Fast Quality Gates` | Kodo PR; statinės patikros, tipų patikra, valdymo skydelio tipų patikra, paveikti vienetų testai | Taip | +| `Forgotten sibling tests` | Kodo PR; pakeisti moduliai atsekami iki statinių naudotojų ir galimų susijusių testų; eksportavimo modulio ir dinaminio importavimo keliai pateikiami kaip rekomendacinė diagnostika, atsižvelgiant į nurodytas leidžiamojo sąrašo išimtis | **Rekomendacinė** | +| `Vitest (fast-path)` | Kodo PR; spartusis vitest rinkinys | Taip | +| `Unit Tests fast-path` | Kodo PR; į 4 dalis suskaidytas vienetų testų rinkinys | Taip | +| `No new ESLint warnings` | Kodo PR; į slopinimus atsižvelgianti lint apsauga | Taip, įskaitant išsišakojusias saugyklas | +| `Merge integrity (changelog + generated skills)` | Ne juodraštinės PR; pakeitimų žurnalo ir sugeneruotų įgūdžių sinchronizavimas | Taip, įskaitant išsišakojusias saugyklas | #### Pamirštų susijusių testų ataskaita -`npm run check:forgotten-sibling-tests` pakartotinai naudoja importų sprendiklį, kuriuo -grindžiamas testų poveikio žemėlapis. Kiekvienam pakeistam produkciniam moduliui jis pateikia -deterministines grandines -`pakeistas modulis / simbolis -> statinis naudotojas -> galimas susijęs testas`, kai galimo -testo nėra ištraukimo užklausos pakeitimų rinkinyje. Markdown santrauka ir JSON rezultatas -išsaugomi kaip `forgotten-sibling-tests` darbo eigos artefaktas, skirtas kalibravimui prieš -bet kokį blokuojančio režimo diegimą. - -Pakartotiniai eksportai per „barrel“ failus ir dinaminiai importai naudojami tik kaip raiškos diagnostika; jie niekada nesukuria -blokuojančio radinio. Peržiūrėtos išimtys pateikiamos faile -`config/quality/forgotten-sibling-allowlist.json`. Kiekviename įraše turi būti nurodytas vartotojo ir kandidato -testas, pateiktas konkretus pagrindimas ir nuoroda į GitHub problemą arba pakeitimų užklausą. Netinkamai suformuoti įrašai -atmetami. Išimtys negali paslėpti pašalinto kandidato testo arba skirtumo, kuriuo pridedama `.skip`/`.todo`; -teiginių susilpninimas ir kiti maskavimo būdai lieka atskirai blokuojančios -`check:test-masking` patikros atsakomybė. +`npm run check:forgotten-sibling-tests` pakartotinai naudoja importų sprendimo +mechanizmą, kuriuo grindžiamas testų poveikio žemėlapis. Kiekvienam pakeistam +produkcinio kodo moduliui jis pateikia deterministines +`pakeistas modulis / simbolis -> statinis naudotojas -> galimas susijęs testas` +grandines, kai galimo testo nėra įtrauktame pull-request skirtume. Markdown suvestinė +ir JSON rezultatas išsaugomi kaip darbo eigos artefaktas `forgotten-sibling-tests`, +kad prieš bet kokį blokuojantį diegimą būtų galima atlikti kalibravimą. + +„Barrel“ pakartotiniai eksportai ir dinaminiai importai naudojami tik skyrimo diagnostikai; jie niekada +nesukuria blokuojančio radinio. Peržiūrėtos išimtys pateikiamos faile +`config/quality/forgotten-sibling-allowlist.json`. Kiekviename įraše turi būti nurodytas vartotojas ir +galimas testas, pateiktas konkretus pagrindimas bei nuoroda į GitHub problemą arba ištraukimo užklausą. Netinkamai suformuoti įrašai +atmetami. Išimtys negali paslėpti ištrinto galimo testo arba skirtumo, kuriuo pridedama `.skip`/`.todo`; +teiginių susilpninimą ir kitus maskavimo atvejus toliau kontroliuoja nepriklausomai blokuojantis +`check:test-masking` kontrolės mechanizmas. ### Užduotis: `lint` -Vykdoma kiekvienai į `main` nukreiptai pakeitimų užklausai. Nesėkmės atveju blokuoja suliejimą. - -| Scenarijus (`npm run ...`) | Tikrina | Blokuoja | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Ar Node.js versija patenka į palaikomą diapazoną | Taip | -| `check:cycles` | Ciklinius importus — visuose `src/` + `open-sse/` moduliuose | Taip | -| `check:route-validation:t06` | Ar visuose maršrutuose yra Zod schemos (6 lygio politika) | Taip | -| `check:any-budget:t11` | Ar `@ts-expect-error // any` skaičius neviršija limito (11 lygio „catraca“) | Taip | -| `check:provider-consistency` | Kiekvienam `providers.ts` teikėjui yra atitinkamas įrašas faile `providerRegistry.ts` (ir atvirkščiai, kiek tai leidžia leidžiamųjų sąrašas) | Taip | -| `check:model-lifecycle` | Trys rankiniu būdu prižiūrimos maršrutizavimo lentelės išlieka suderintos su į saugyklą įtraukta gyvavimo ciklo momentine kopija (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nepriskiria balo jokiam nebenaudojamam identifikatoriui, kurį gali maršrutizuoti `REGISTRY`; kiekvienas `BUILT_IN_ALIASES` tikslas yra `REGISTRY` ir jo nėra nebenaudojamų identifikatorių momentinėje kopijoje; kiekvienas nebenaudojamas identifikatorius, vis dar esantis `REGISTRY`, yra peradresuojamas arba nurodytas `allowedRetiredInCatalog`; ir joks `DEFAULT_DEGRADATION_MAP` šaltinis ar tikslas toje momentinėje kopijoje nėra pažymėtas kaip nebenaudojamas. Tai neįrodo, kad modelį šiuo metu teikia veikianti išorinė sistema. Tikrinama neprisijungus — lyginama su `config/quality/model-lifecycle.json`, kuris rankiniu būdu atnaujinamas naudojant `npm run quality:refresh-model-lifecycle` (reikalingas tinklas; neintegruota į CI). `allowedRetiredInCatalog` yra palaipsnio mažinimo reketas: įrašą pridėkite tik turėdami stebėjimo užduotį. | Taip | -| `check:fetch-targets` | Kiekvienas `fetch("/api/...")` kliento pusės kataloge `src/` nurodo tikrą `route.ts` | Taip | -| `check:deps` | Visos naudojant `npm install` įdiegiamos priklausomybės iš visų saugyklos failų `package.json` yra faile `dependency-allowlist.json`; nauji neprisegti arba dėl rašybos klaidomis pagrįstų tiekimo grandinės atakų įtartini paketai pažymimi | Taip | -| `audit:deps` | `npm audit` (šakninis projektas ir electron) — nėra didelio ar kritinio lygio įspėjimų (iš dalies dubliuoja osv `check:vuln-ratchet`; žr. racionalizavimo darbų sąrašą) | Taip | -| `check:lockfile` | `package-lock.json` vientisumas — https registras, vientisumo maišos, nėra pagrindinio kompiuterio perrašymų | Taip | -| `check:licenses` | SPDX licencijų leidžiamų reikšmių sąrašas gamybinėms priklausomybėms | Taip | -| `check:tracked-artifacts` | Nėra kompiliavimo artefaktų / į versijų kontrolę įtrauktų `node_modules` simbolinių nuorodų (taip pat vykdoma „husky“ prieš patvirtinant pakeitimus; patikra prieš siunčiant pakeitimus sąmoningai minimali — #6716) | Taip | -| `check:ai-attribution` | PR patvirtinimuose, pavadinime ar apraše nėra DI / roboto `Co-Authored-By` prierašo ar DI generavimo poraštės — griežta taisyklė Nr. 16 (`quality.yml` greitųjų patikrų cikle, skirtame PR→`release/**` — nuskaito įvykio naudingąją apkrovą, o ne PR atveju nieko nedaro — ir tik PR skirtame `ci.yml` lint patikros žingsnyje, skirtame PR→`main`; taip pat „husky“ `commit-msg` kabliuke; bendraautoriai žmonės leidžiami; #14436) | -| `check:vitest-exclusions` | Kiekvienoje „Vitest“ išimtyje nurodoma sekimo užduotis ir ji pateikiama faile `config/quality/vitest-exclusions.json` (#13204) | Taip | -| `check:file-size` | Nė vienas šaltinio failas neviršija jo plėtiniui nustatytos ribos (fiksatorius: dideli failai, kurių dydis užfiksuotas `frozen` sąraše) | Taip | -| `check:error-helper` | Klaidų atsakuose vykdyklėse / apdorojimo priemonėse naudojamos `buildErrorBody()` / `sanitizeErrorMessage()` (griežta taisyklė Nr. 12) | Taip | -| `check:migration-numbering` | Migracijų SQL failai numeruojami nuosekliai, be tarpų ar pasikartojimų | Taip | -| `check:public-creds` | Už `publicCreds.ts` ribų nėra tiesiogiai įrašytų OAuth `client_id` / `client_secret` arba Firebase žiniatinklio raktų (griežta taisyklė Nr. 11) | Taip | -| `check:db-rules` | Už `src/lib/db/` modulių ribų nėra neapdoroto SQL; nėra apibendrinamųjų importų iš `localDb.ts` (griežtos taisyklės Nr. 2 / Nr. 5) | Taip | -| `check:known-symbols` | Teikėjų vykdytojai, maršruto parinkimo strategijos ir transformuotojai, užregistruoti jų nukreipimo lentelėse, atitinka diske esančius failus — nėra nesusietų ar nedeklaruotų simbolių | Taip | -| `check:route-guard-membership` | Kiekvienas maršrutas, paleidžiantis antrinį procesą, yra klasifikuojamas naudojant `isLocalOnlyPath()` (griežtos taisyklės Nr. 15 / Nr. 17) | Taip | -| `check:test-discovery` | Kiekvieną saugykloje esantį `*.test.ts` / `*.spec.ts` failą aptinka bent viena testų vykdymo priemonė (reketo principas: nesusietų failų sąrašas faile `test-discovery-baseline.json` gali tik trumpėti) | Taip | -| `check:agent-skills-sync` | Sugeneruoti agento įgūdžių artefaktai atitinka jų šaltinio katalogą (nėra neatitikimų) | -| `check:provider-asset-provenance` | Teikėjų logotipai / ištekliai turi užregistruotą kilmės įrašą | -| `lint:json` | JSON konfigūracijos failai sėkmingai analizuojami ir atitinka saugyklos lint taisykles | -| `typecheck:core` | TypeScript kompiliavimas be klaidų (tik patariamojo pobūdžio įspėjimai) | Taip | -| `typecheck:noimplicit:core` | Griežtas `noImplicitAny` — orientuotas į ateitį; daugeliui esamų iškvietimo vietų vis dar reikia anotacijų | **Patariamasis** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, apribotas iki `src/app/(dashboard)/**` (#7033) — `typecheck:core` kruopščiai atrinktas 27 failų leidžiamasis sąrašas neapima jokio dashboard TSX failo, o `next build` taip pat niekada neatlieka jų tipų patikros (`next.config.mjs` nustato `ignoreBuildErrors: true`), todėl ten atsiradusios nesusietų identifikatorių regresijos (#6625/#6909) CI likdavo nepastebėtos. Skirtumai lyginami su fiksuotu baziniu kiekvieno failo ir kiekvieno TS kodo klaidų skaičiumi (`config/quality/dashboard-typecheck-baseline.json`, toks pats pasenusių įrašų tikrinimo modelis kaip `check:known-symbols`) — patikra nepavyksta tik dėl NAUJŲ klaidų, viršijančių bazinį skaičių; ištaisius esamą klaidą, bazinį lygį sumažinkite naudodami `--update`. | Taip | +Vykdoma kiekvienai PR į `main`. Nesėkmės atveju sujungimas blokuojamas. + +| Scenarijus (`npm run ...`) | Tikrina | Blokuojantis | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Ar Node.js versija patenka į palaikomą diapazoną | Taip | +| `check:cycles` | Ciklinius importus visame `src/` + `open-sse/` (AST pagrindu, išsprendžiant tsconfig `paths`). Bazinis režimas = patariamasis, pateikia ciklų sąrašą. `check:cycles:ratchet` (vykdomas CI) blokuoja, kai skaičius viršija `quality-baseline.json` nustatytą `metrics.cycles` ribą — šiuo metu 14, `direction: down`, todėl jis gali tik mažėti (#15159 G-01/G-02) | Taip (reketo režimu) | +| `check:route-validation:t06` | Ar visiems maršrutams pateiktos Zod schemos (6 lygio politika) | Taip | +| `check:any-budget:t11` | Ar `@ts-expect-error // any` skaičius neviršija biudžeto (11 lygio reketo mechanizmas) | Taip | +| `check:provider-consistency` | Kiekvienas teikėjas faile `providers.ts` turi atitinkamą įrašą faile `providerRegistry.ts` (ir atvirkščiai, atsižvelgiant į leidžiamųjų sąrašą) | Taip | +| `check:model-lifecycle` | Trys rankiniu būdu prižiūrimos maršruto parinkimo lentelės išlieka suderintos su repozitorijoje saugoma gyvavimo ciklo momentine kopija (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nepriskiria balo jokiam nebenaudojamam id, kurį gali nukreipti `REGISTRY`; kiekvienas `BUILT_IN_ALIASES` tikslas yra `REGISTRY` ir jo nėra nebenaudojamų id momentinėje kopijoje; kiekvienas nebenaudojamas id, vis dar esantis `REGISTRY`, yra persiunčiamas arba įtrauktas į `allowedRetiredInCatalog`; joks `DEFAULT_DEGRADATION_MAP` šaltinis ar tikslas toje momentinėje kopijoje nėra pažymėtas kaip nebenaudojamas. Tai neįrodo, kad modelį šiuo metu aptarnauja veikiantis išorinis tiekėjas. Veikia neprisijungus — lygina su `config/quality/model-lifecycle.json`, kuris atnaujinamas rankiniu būdu naudojant `npm run quality:refresh-model-lifecycle` (reikalingas tinklas; neintegruota į CI). `allowedRetiredInCatalog` yra laipsniško mažinimo reketo mechanizmas: įrašą pridėkite tik kartu su sekimo užduotimi. | Taip | +| `check:fetch-targets` | Kiekvienas `fetch("/api/...")` kliento pusės kataloge `src/` nurodo į realų `route.ts` | Taip | +| `check:deps` | Visos naudojant `npm install` įdiegiamos priklausomybės iš kiekvieno repozitorijos failo `package.json` yra faile `dependency-allowlist.json`; nauji nefiksuotų versijų arba dėl rašybos klaidų galimai užgrobtų paketų atvejai pažymimi | Taip | +| `audit:deps` | `npm audit` (šakninis projektas + electron) — nėra aukšto ar kritinio lygio įspėjimų (iš dalies sutampa su osv `check:vuln-ratchet`; žr. racionalizavimo neatliktų darbų sąrašą) | Taip | +| `check:lockfile` | `package-lock.json` vientisumas — https registras, vientisumo maišos, nėra pagrindinio kompiuterio perrašymų | Taip | +| `check:licenses` | Gamybinių priklausomybių SPDX licencijų leidžiamasis sąrašas | Taip | +| `check:tracked-artifacts` | Nėra kompiliavimo artefaktų / į versijų valdymą įtrauktų `node_modules` simbolinių nuorodų (taip pat vykdoma per husky prieš patvirtinimą; prieš išsiuntimą atliekama patikra sąmoningai minimali — #6716) | Taip | +| `check:ai-attribution` | PR patvirtinimuose, pavadinime ar apraše nėra DI / roboto `Co-Authored-By` prierašo ar DI generavimo poraštės — griežta taisyklė Nr. 16 (`quality.yml` sparčiųjų patikrų cikle, skirtame PR→`release/**` — nuskaito įvykio naudingąją apkrovą, ne PR atveju neatlieka jokių veiksmų — ir tik PR skirtame `ci.yml` analizės žingsnyje, skirtame PR→`main`; taip pat husky `commit-msg` kabliuke; žmonės bendraautoriai leidžiami; #14436) | +| `check:vitest-exclusions` | Kiekvienoje Vitest išimtyje nurodyta sekimo užduotis ir ji pateikiama faile `config/quality/vitest-exclusions.json` (#13204) | Taip | +| `check:file-size` | Joks šaltinio failas neviršija atitinkamam plėtiniui nustatytos ribos (reketinis ribojimas: dideli failai užfiksuoti sąraše `frozen`) | Taip | +| `check:error-helper` | Klaidų atsakymuose vykdyklėse / doroklėse naudojama `buildErrorBody()` / `sanitizeErrorMessage()` (griežta taisyklė Nr. 12) | Taip | +| `check:migration-numbering` | Migracijos SQL failai sunumeruoti nuosekliai, be praleistų ar pasikartojančių numerių | Taip | +| `check:public-creds` | Už `publicCreds.ts` ribų nėra tiesiogiai įrašytų OAuth `client_id`/`client_secret` ar Firebase Web raktų (griežta taisyklė Nr. 11) | Taip | +| `check:db-rules` | Už `src/lib/db/` modulių ribų nėra neapdorotų SQL užklausų; nėra apibendrinamųjų importų iš `localDb.ts` (griežtos taisyklės Nr. 2/Nr. 5) | Taip | +| `check:known-symbols` | Teikėjų vykdytojai, maršruto parinkimo strategijos ir transformuotojai, užregistruoti jų išsiuntimo lentelėse, atitinka diske esančius failus — nėra nesusietų ar nedeklaruotų simbolių | Taip | +| `check:route-guard-membership` | Kiekvienas maršrutas, paleidžiantis antrinį procesą, yra klasifikuojamas naudojant `isLocalOnlyPath()` (griežtos taisyklės Nr. 15/Nr. 17) | Taip | +| `check:test-discovery` | Kiekvieną saugykloje esantį `*.test.ts` / `*.spec.ts` failą aptinka bent viena testų vykdymo priemonė (terkšlė: nesusietų failų sąrašas faile `test-discovery-baseline.json` gali tik trumpėti) | Taip | +| `check:agent-skills-sync` | Sugeneruoti agentų įgūdžių artefaktai atitinka jų šaltinio katalogą (nėra nukrypimų) | +| `check:provider-asset-provenance` | Teikėjų logotipai / ištekliai turi užregistruotą kilmės įrašą | +| `lint:json` | JSON konfigūracijos failai yra tinkamai analizuojami ir atitinka saugyklos lint taisykles | +| `typecheck:core` | TypeScript kompiliavimas be klaidų (tik patariamojo pobūdžio įspėjimai) | Taip | +| `typecheck:noimplicit:core` | Griežtas `noImplicitAny` — orientuotas į ateitį; daugeliui jau esamų iškvietimo vietų vis dar reikia anotacijų | **Patariamasis** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, apribotas iki `src/app/(dashboard)/**` (#7033) — `typecheck:core` kuruojamame 27 failų leidžiamųjų sąraše nėra jokio ataskaitų srities TSX failo, o `next build` taip pat niekada netikrina jo tipų (`next.config.mjs` nustato `ignoreBuildErrors: true`), todėl ten atsiradusios vienišų identifikatorių regresijos (#6625/#6909) CI sistemoje buvo nematomos. Skirtumai lyginami su fiksuotu kiekvieno failo ir kiekvieno TS kodo skaičiaus baziniu lygiu (`config/quality/dashboard-typecheck-baseline.json`, taikant tą patį pasenimo kontrolės modelį kaip `check:known-symbols`) — patikrą sustabdo tik NAUJOS klaidos, viršijančios bazinį skaičių; ištaisius jau egzistuojančią klaidą, bazinį lygį mažinkite naudodami `--update`. | Taip | ### Užduotis: `quality-gate` -Vykdoma po `test-coverage`. Nesėkmės atveju sujungimas blokuojamas. +Vykdoma po `test-coverage`. Nesėkmės atveju blokuoja suliejimą. -| Scenarijus | Tikrina | Blokuojantis | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `quality:collect` | Sugeneruoja `quality-metrics.json` (ESLint įspėjimų skaičius, aprėptis iš sujungtos segmentų ataskaitos) | Taip (prieš kartelės tikrinimą) | -| `quality:ratchet` | Nė viena `quality-baseline.json` metrika nepablogėjo (ESLint įspėjimų ≤ bazinė reikšmė; aprėptis ≥ bazinė reikšmė) | Taip | -| `check:duplication` | Kodo dubliavimas (jscpd@4) neviršija `quality-baseline.json` bazinės reikšmės | Taip | -| `check:complexity` | Failo lygmens ciklomatinis sudėtingumas neviršija ribos (pagrindinės ESLint taisyklės `complexity` + `max-lines-per-function`) | Taip | -| `check:cognitive-complexity` | Kognityvinio sudėtingumo kartelė (`eslint-plugin-sonarjs`) — atskiras ESLint vykdymas; CI abu patikrinimus vykdo kartu kaip vieną `check:complexity-ratchets` veiksmą | Taip | -| `check:dead-code` | Nenaudojamų eksportų / failų kartelė (knip) nepablogėjo, palyginti su bazine reikšme | Taip | -| `check:compression-budget` | Glaudinimo etalono biudžetas — kiekvieno variklio mažiausias sutaupytų leksemų kiekis neturi pablogėti | Taip | -| `check:type-coverage` | Tipizuotos dalies procentinės aprėpties kartelė (`type-coverage`) nepablogėjo; iš esmės pakeičia `typecheck:noimplicit:core` | Taip | -| `check:codeql-ratchet` | Atvirų CodeQL įspėjimų skaičius nepadidėjo (nuskaitoma per `gh api`; jei nėra prieigos rakto, patikra korektiškai praleidžiama) — atnaujinimo dažnį ir rankinį paleidimą žr. toliau „CodeQL kartelė“ | Taip | +| Scenarijus | Tikrina | Blokuojantis | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `quality:collect` | Sugeneruoja `quality-metrics.json` (ESLint įspėjimų skaičių, aprėptį iš sujungtos segmentų ataskaitos) | Taip (vykdomas prieš „ratchet“) | +| `quality:ratchet` | Nė viena `quality-baseline.json` metrika nepablogėjo (ESLint įspėjimų ≤ bazinė reikšmė; aprėptis ≥ bazinė reikšmė) | Taip | +| `check:duplication` | Kodo dubliavimas (jscpd@4) neviršija `quality-baseline.json` bazinės reikšmės | Taip | +| `check:complexity` | Failo lygmens ciklomatinis sudėtingumas neviršija ribos (bazinis ESLint `complexity` + `max-lines-per-function`) | Taip | +| `check:cognitive-complexity` | Kognityvinio sudėtingumo „ratchet“ (`eslint-plugin-sonarjs`) — atskiras ESLint vykdymas; CI abu vykdo sujungtus į vieną `check:complexity-ratchets` veiksmą | Taip | +| `check:dead-code` | Nenaudojamų eksportų / failų „ratchet“ (knip) nepablogėjo, palyginti su bazine reikšme | Taip | +| `check:compression-budget` | Glaudinimo našumo testo biudžetas — kiekvieno variklio minimali sutaupytų žetonų riba negali pablogėti | Taip | +| `check:type-coverage` | Tipais aprašytos dalies procentinis „ratchet“ (`type-coverage`) nepablogėjo; iš esmės apima `typecheck:noimplicit:core` | Taip | +| `check:codeql-ratchet` | Atvirų CodeQL įspėjimų skaičius nepablogėjo (nuskaitoma per `gh api`; jei nėra prieigos rakto, korektiškai praleidžiama) — atnaujinimo dažnį ir rankinį paleidimą žr. toliau „CodeQL ratchet“ | Taip | ### Užduotis: `quality-extended` -Visa užduotis yra rekomendacinė (`continue-on-error: true`). npm pagrįstos kartelės -vykdomos iš tikrųjų; išoriniai skaitytuvai įdiegiami naudojant `gh release download` -ir patys praleidžia patikrą (exit 0), jei vykdomojo failo vis dar nėra. +Visa užduotis yra rekomendacinė (`continue-on-error: true`). npm pagrįsti „ratchet“ +tikrinimai vykdomi iš tikrųjų; išoriniai skaitytuvai įdiegiami naudojant `gh release download` +ir patys praleidžia vykdymą (exit 0), jei dvejetainio failo vis dar nėra. -| Scenarijus | Tikrina | Blokuojantis | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -| `check:circular-deps` | Nėra ciklinių priklausomybių (dpdm) | **Rekomendacinis** | -| `check:bundle-size` | Paketo dydis neviršija ribos | **Rekomendacinis** | -| `check:secrets` | Paslapčių paieška (gitleaks) — praleidžiama, jei nėra vykdomojo failo | **Rekomendacinis** | -| `check:vuln-ratchet` | Priklausomybių pažeidžiamumai (osv-scanner) nepablogėjo — praleidžiama, jei nėra vykdomojo failo | **Rekomendacinis** | -| `check:workflows` | Darbo eigų analizė (actionlint + zizmor); nesami / neveikiantys skaitytuvai, netinkamos ataskaitos arba trūkstama kartelės bazinė reikšmė sukelia INCOMPLETE. Tinkami radiniai apdorojami pagal pasirinktą griežtą / rekomendacinę / kartelės politiką | Vykdymas privalomas; zizmor kartelė blokuoja CI | -| `check:openapi-breaking` | Viešojo API kontrakto (`openapi.yaml`) nesuderinami pakeitimai, palyginti su bazine šaka (oasdiff) — sugeneruoja `openapiBreaking=N`; praleidžiama, jei nėra oasdiff arba nepavyksta gauti bazinės specifikacijos | **Rekomendacinis** | +| Scenarijus | Tikrina | Blokuojantis | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| `check:circular-deps` | Nėra ciklinių priklausomybių (dpdm) | **Rekomendacinis** | +| `check:bundle-size` | Paketo dydis neviršija ribos | **Rekomendacinis** | +| `check:secrets` | Paslapčių paieška (gitleaks) — praleidžiama, jei nėra dvejetainio failo | **Rekomendacinis** | +| `check:vuln-ratchet` | Priklausomybių pažeidžiamumai (osv-scanner) nepablogėjo — praleidžiama, jei nėra dvejetainio failo | **Rekomendacinis** | +| `check:workflows` | Darbo eigų tikrinimas (actionlint + zizmor); jei skaitytuvų nėra arba jie neveikia, ataskaitos netinkamos ar nėra „ratchet“ bazinės reikšmės, tikrinimas baigiamas būsena INCOMPLETE. Tinkami radiniai apdorojami pagal pasirinktą griežtą / rekomendacinę / „ratchet“ politiką | Vykdymas privalomas; zizmor „ratchet“ blokuoja CI | +| `check:openapi-breaking` | Viešosios API sutarties (`openapi.yaml`) nesuderinami pakeitimai, palyginti su bazine šaka (oasdiff) — sugeneruoja `openapiBreaking=N`; praleidžiama, jei nėra oasdiff arba nepavyksta nustatyti bazinės specifikacijos | **Rekomendacinis** | ### Užduotis: `docs-sync-strict` -Vykdoma kiekvienai į `main` nukreiptai PR. Nesėkmės atveju blokuoja sujungimą. - -| Scenarijus | Tikrina | Blokuojantis | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | -| `check:docs-all` | Metatikra, nuosekliai paleidžianti 6 toliau nurodytas dalines tikras | Taip | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versijų nuoseklumą | Taip | -| ↳ `check:docs-counts` | Ar tekste pateikti skaičiai (teikėjų skaičius, migracijų skaičius ir kt.) patenka į realiems skaičiams taikomą kartelės intervalo ribą | Taip | -| ↳ `check:env-doc-sync` | Ar kiekvienas aplinkos kintamasis iš `.env.example` yra aprašytas dokumentacijos lentelėje ir atvirkščiai | Taip | -| ↳ `check:deprecated-versions` | Ar dokumentacijoje nėra nebenaudojamų versijų eilučių | Taip | -| ↳ `check:doc-links` | Ar vidinės „Markdown“ nuorodos dokumentacijoje nurodo realius failus (`[text]`/`(path)` forma) | Taip | -| ↳ `check:fabricated-docs` | Ar dokumentacijoje minimi maršrutai, aplinkos kintamieji, CLI komandos, kablių pavadinimai ir failų keliai egzistuoja kodų bazėje. Griežtoji patikra naudojant `--strict`; be žymos klaida nėra blokuojanti. | Taip (CI aplinkoje naudojant `--strict`) | -| `check:cli-i18n` | Ar CLI komandų eilutės yra visuose i18n lokalės failuose | Taip | -| `check:openapi-coverage` | Ar OpenAPI specifikacija apima bent pagal kartelę nustatytą minimalų realių maršrutų skaičių | Taip | -| `check:openapi-security-tiers` | Ar saugumo lygio anotacijos faile `openapi.yaml` atitinka `routeGuard.ts` klasifikacijas | **Rekomendacinis** | -| `check:openapi-routes` | Ar kiekvienas kelias faile `openapi.yaml` nurodo realų `route.ts` (apsauga nuo haliucinacijų) | Taip | -| `check:docs-symbols` | Ar kiekviena `/api/...` nuoroda failuose `docs/**/*.md` nurodo realų `route.ts` (apsauga nuo haliucinacijų) | Taip | -| `i18n translation drift` | Neišversti raktai i18n lokalės failuose — tik įspėjimas | **Rekomendacinis** | +Vykdoma kiekvienai į `main` šaką nukreiptai PR. Nesėkmės atveju sujungimas blokuojamas. + +| Scenarijus | Tikrina | Blokuojantis | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `check:docs-all` | Metapatikra, kuri nuosekliai paleidžia 6 toliau nurodytas dalines patikras | Taip | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versijų nuoseklumą | Taip | +| ↳ `check:docs-counts` | Ar tekste nurodyti skaičiai (teikėjų skaičius, migracijų skaičius ir kt.) patenka į realiems skaičiams taikomą laipsniškai griežtinamą intervalą | Taip | +| ↳ `check:env-doc-sync` | Ar kiekvienas `.env.example` aplinkos kintamasis dokumentuotas dokumentacijos lentelėje ir atvirkščiai | Taip | +| ↳ `check:deprecated-versions` | Ar dokumentacijoje nėra nebenaudojamų versijų eilučių | Taip | +| ↳ `check:doc-links` | Ar vidinės dokumentacijos markdown nuorodos nurodo esamus failus (`[tekstas]`/`(kelias)` forma) | Taip | +| ↳ `check:fabricated-docs` | Ar dokumentacijoje nurodyti maršrutai, aplinkos kintamieji, CLI komandos, kablių pavadinimai ir failų keliai egzistuoja kodų bazėje. Griežta patikra naudojant `--strict`; be šios žymos klaida neblokuoja. | Taip (CI naudojant `--strict`) | +| `check:cli-i18n` | Ar CLI komandų eilutės yra visuose i18n lokalės failuose | Taip | +| `check:openapi-coverage` | Ar OpenAPI specifikacija apima bent laipsniškai didinamą minimalią realių maršrutų dalį | Taip | +| `check:openapi-security-tiers` | Ar `openapi.yaml` saugumo lygių anotacijos atitinka `routeGuard.ts` klasifikacijas | **Rekomendacinis** | +| `check:openapi-routes` | Ar kiekvienas `openapi.yaml` kelias atitinka realų `route.ts` (apsauga nuo haliucinacijų) | Taip | +| `check:docs-symbols` | Ar kiekviena `/api/...` nuoroda faile `docs/**/*.md` atitinka realų `route.ts` (apsauga nuo haliucinacijų) | Taip | +| `i18n translation drift` | Neišversti raktai i18n lokalės failuose — tik įspėjimas | **Rekomendacinis** | ### Užduotis: `i18n-ui-coverage` -| Scenarijus | Tikrina | Blokuojantis | -| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `check-ui-keys-coverage` (įterptas) | Ar UI i18n raktų aprėptis yra ≥ 65 % | Taip | -| `check-ui-value-drift` (įterptas) | Ar perrašius anglišką **reikšmę** nelieka pasenusių vertimų | Taip | -| `check-new-key-coverage` (įterptas) | Ar **naujas** angliškas raktas išverstas kiekvienoje lokalėje — žymeklis `__MISSING__:` atmetamas | Taip | -| `check-translation-ratio` | Realių vertimų santykis kiekvienoje lokalėje (angliškai versijai identiški / vietaženklio / trūkstami įrašai, nepatenkantys į leidžiamųjų sąrašą) neturi viršyti `config/quality/i18n-translation-baseline.json` + leidžiamos paklaidos | **Rekomendacinis** | +| Scenarijus | Tikrina | Blokuojantis | +| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `check-ui-keys-coverage` (įterptas) | Ar UI i18n raktų aprėptis yra ≥ 65% | Taip | +| `check-ui-value-drift` (įterptas) | Ar perrašius anglišką **reikšmę** nelieka pasenusio vertimo | Taip | +| `check-new-key-coverage` (įterptas) | Ar **naujas** angliškas raktas išverstas kiekvienoje lokalėje — `__MISSING__:` žymuo neleidžiamas | Taip | +| `check-translation-ratio` | Tikrų vertimų dalis kiekvienoje lokalėje (už leidžiamųjų sąrašo ribų esantys identiški angliškiems / vietos rezervavimo / trūkstami lapai) negali viršyti `config/quality/i18n-translation-baseline.json` + leidžiamos paklaidos | **Rekomendacinis** | -Reikalingas `fetch-depth: 0` — reikšmių skirtumų patikra lygina `en.json` su sujungimo baze. +Reikalingas `fetch-depth: 0` — reikšmių nuokrypio patikra palygina `en.json` su sujungimo baze. #### `check-ui-value-drift` — pasenusių vertimų patikra -Aptinka vieną i18n regresijos atvejį, kurio kitos patikros dėl savo struktūros negali pastebėti: angliška reikšmė +Aptinka vieną i18n regresijos tipą, kurio kitos patikros dėl savo struktūros negali pastebėti: angliška reikšmė perrašoma, o pagal _ankstesnį_ anglišką tekstą sukurti vertimai lieka nepakeisti, todėl -ne anglakalbiai naudotojai ir toliau mato užtikrintai suformuluotą, bet jau klaidingą tekstą. +ne anglakalbiai naudotojai toliau skaito įtikinamai suformuluotą, bet dabar jau klaidingą tekstą. Tai iš tikrųjų pateko į leidimą. `oauthModal.googleOAuthWarning` buvo perrašytas, kai buvo -pridėtas „Antigravity“ prisijungimo pagalbininkas (#5203); **39 iš 43 lokalių** liko tekstas, nurodantis operatoriams „nukopijuoti -visą URL ir įklijuoti jį toliau“ — šio teikėjo atveju tokio proceso užbaigti neįmanoma. Tai liko +pridėtas Antigravity prisijungimo pagalbininkas (#5203); **39 iš 43 lokalių** liko tekstas, nurodantis operatoriams „nukopijuoti +visą URL ir įklijuoti jį toliau“ — tokiu būdu šio teikėjo srauto užbaigti neįmanoma. Tai liko nepastebėta iki #8463, nes: -- `sync-ui-keys` užpildo tik **nesamus** raktus, bet niekada neatnaujina **pasenusių**; -- `check-ui-keys-coverage` skaičiuoja rakto _buvimą_, todėl pasenęs vertimas laikomas padengtu; -- `check-translation-drift` stebi `docs/i18n//**.md` dokumentacijos kopijas — +- `sync-ui-keys` užpildo tik **trūkstamus** raktus, o ne **pasenusius**; +- `check-ui-keys-coverage` skaičiuoja raktų _buvimą_, todėl pasenęs vertimas laikomas padengtu; +- `check-translation-drift` stebi `docs/i18n//**.md` dokumentacijos atspindžius — jis niekada neskaito `src/i18n/messages/*.json`. Užduotyje `docs-sync-strict` ši patikra blokuoja nuo - 2026-09 pakartotinio sinchronizavimo: redaguojant pagrindinį dokumentą → `npm run i18n:run -- --files=` (skyriaus lygmens, nebrangu). + 2026-09 pakartotinio sinchronizavimo: redaguojant pagrindinį dokumentą → `npm run i18n:run -- --files=` (skilties lygmens, nebrangu). -**Atsižvelgia į skirtumus, o ne remiasi bazine būsena.** Sujungimo bazėje esantis `en.json` palyginamas su -darbo medžiu; kiekvienam raktui, kurio angliška reikšmė pasikeitė, bet kuri lokalė, kurioje vis dar yra -nepakeistas vertimas, laikoma pasenusia. Taip sąmoningai **įšaldoma anksčiau susikaupusi skola** — skirtumas -negali parodyti, iš kurios senos angliškos reikšmės atsirado ilgą laiką naudotas vertimas, todėl patikra vertina -tik tai, ką paliečia dabartinis pakeitimas. Alternatyva (kiekvieno rakto maišos bazinė būsena) pareikalautų -~600 KB sugeneruoto failo, 3 kartus didesnio už didžiausią esamą bazinės būsenos failą, kuris keistųsi su kiekvienu i18n PR. +**Atsižvelgia į skirtumus, o ne remiasi bazine versija.** Ji palygina `en.json` sujungimo bazėje su +darbine kopija; kiekvienam raktui, kurio angliška reikšmė pasikeitė, bet kurios lokalės nepakeistas +vertimas laikomas pasenusiu. Taip sąmoningai **įšaldoma anksčiau susikaupusi skola** — skirtumai +negali parodyti, iš kurios senos angliškos reikšmės atsirado ilgą laiką egzistuojantis vertimas, todėl patikra vertina +tik tai, ką paliečia dabartinis pakeitimas. Alternatyva (kiekvieno rakto kontrolinėmis sumomis paremta bazinė versija) pareikalautų +~600 KB sugeneruoto failo, 3× didesnio už didžiausią esamą bazinį failą, kuris keistųsi su kiekvienu i18n PR. -Patikrą galima įvykdyti dviem būdais: +Yra du būdai patikrą įvykdyti sėkmingai: 1. atnaujinti paveiktus vertimus arba -2. nustatyti jų reikšmę į `__MISSING__:` — tada vykdymo metu pateikiamas pataisytas angliškas tekstas +2. nustatyti jų reikšmę į `__MISSING__:` — vykdymo metu tuomet pateikiamas pataisytas angliškas tekstas (`src/i18n/request.ts::deepMergeFallback`, #7258), o raktas įtraukiamas į vertimo eilę. Jei pasikeitė eilutės **prasmė**, geriau **pervadinti raktą**: naujas raktas negali paveldėti @@ -235,52 +237,52 @@ pasenusio vertimo. Toks šablonas buvo panaudotas #8463. ```bash npm run i18n:check-value-drift # griežta patikra (vykdoma CI) -npm run i18n:check-value-drift:warn # tik pateikti ataskaitą +npm run i18n:check-value-drift:warn # tik ataskaita BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Baigiama su 0 ir `SKIP reason=base-unresolved`, kai bazinio katalogo negalima perskaityti (paviršinis -klonas be bazinės nuorodos), taip atkartojant `check-openapi-breaking`. +Baigiama su 0 ir `SKIP reason=base-unresolved`, kai bazinio katalogo nepavyksta perskaityti (negilus +klonas be bazinės nuorodos), analogiškai kaip `check-openapi-breaking`. ### Užduotis: `i18n` Visa i18n tikrinimo matrica (po vieną užduotį kiekvienai lokalei). Visa užduotis yra rekomendacinė. -| Scenarijus | Kas tikrinama | Blokuoja | -| ------------------------------- | ------------------------------------ | ------------------------------------------------------------- | -| `validate_translation.py quick` | Kiekvienos lokalės vertimų išsamumas | **Rekomendacinė** (`continue-on-error: true` visai užduočiai) | +| Scenarijus | Tikrina | Blokuoja | +| ------------------------------- | ----------------------------------- | ------------------------------------------------------------- | +| `validate_translation.py quick` | Kiekvienos lokalės vertimo išsamumą | **Rekomendacinė** (`continue-on-error: true` visai užduočiai) | ### Užduotis: `pr-test-policy` -Vykdoma tik sujungimo užklausoms. +Vykdoma tik gavimo užklausoms. -| Scenarijus | Kas tikrinama | Blokuoja | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -| `check:pr-test-policy` | PR, keičiantys produkcinį kodą kataloguose `src/`, `open-sse/`, `electron/` arba `bin/`, turi įtraukti arba atnaujinti testus (griežta taisyklė Nr. 8) | Taip | -| `check:test-masking` | Pakeisti testų failai nesumažina bendro patikrų skaičiaus ir neprideda `assert.ok(true)` tautologijų | Taip | -| `check:pr-evidence` | PR apraše pateikiami pakeitimo testavimo / VPS įrodymai (automatizuoja griežtą taisyklę Nr. 18, ieškodamas PR tekste — nepatikima, žr. darbų sąrašą) | Taip | +| Scenarijus | Tikrina | Blokuoja | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | PR, keičiantys produkcinį kodą kataloguose `src/`, `open-sse/`, `electron/` arba `bin/`, privalo įtraukti arba atnaujinti testus (griežtoji taisyklė #8) | Taip | +| `check:test-masking` | Pakeisti testų failai nesumažina bendro teiginių skaičiaus ir neprideda `assert.ok(true)` tautologijų | Taip | +| `check:pr-evidence` | PR apraše pateikiami pakeitimo testavimo / VPS įrodymai (automatizuojama griežtoji taisyklė #18, ieškant PR tekste — nepatikima, žr. darbų sąrašą) | Taip | ### Užduotis: `test-vitest` Vykdoma po `build`. Nesėkmės atveju sujungimas blokuojamas. -| Rinkinys | Kas tikrinama | Blokuoja | -| ---------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP serveris (110 įrankių), autoCombo, podėlis — vitest vykdyklė | Taip | -| `test:vitest:ui` | UI komponentų testai — vitest vykdyklė | **Blokuoja** — anksčiau egzistavusios klaidos aiškiai išskirtos faile `vitest.config.ts`; naujos klaidos nutraukia užduotį | +| Rinkinys | Tikrina | Blokuoja | +| ---------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP serverį (110 įrankių), autoCombo, podėlį — vitest vykdyklė | Taip | +| `test:vitest:ui` | UI komponentų testus — vitest vykdyklė | **Blokuoja** — ankstesnės nesėkmės aiškiai neįtrauktos faile `vitest.config.ts`; dėl naujų nesėkmių užduotis nepavyksta | -### Naktinės darbo eigos (suplanuotos, rekomendacinės) +### Naktinės darbo sekos (suplanuotos, rekomendacinės) -Jos vykdomos pagal cron tvarkaraštį (ir naudojant `workflow_dispatch`), bet niekada nevykdomos PR. Visos jos yra rekomendacinės. +Jos vykdomos pagal cron tvarkaraštį (ir `workflow_dispatch`), bet niekada nevykdomos PR. Visos jos yra rekomendacinės. -| Darbo eiga | Kas tikrinama | Blokuoja | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `nightly-property` | fast-check savybių testai su atsitiktine pradine reikšme ir dideliu vykdymų skaičiumi | **Rekomendacinė** | -| `nightly-resilience` | atminties krūvos augimo patikra, chaoso trikčių įterpimas, k6 apkrovos / ilgalaikiai testai | **Rekomendacinė** | -| `nightly-llm-security` | promptfoo injekcijų apsauga (blokavimo režimas) ir garak zondai (praleidžiami, jei nėra teikėjo paslapties) | **Rekomendacinė** | -| `nightly-schemathesis` | OpenAPI sutarties neapibrėžtųjų įvesčių testavimas (schemathesis) veikiančioje OmniRoute naudojant `docs/openapi.yaml` — atskleidžia specifikacijos pažeidimus / neapdorotas 500 klaidas (8 etapas, B.4) | **Rekomendacinė** | -| `nightly-mutation` | Stryker mutacijų testavimo įvertis greitojoje vienetinių testų juostoje — išlikę mutantai atskleidžia silpnas patikras | **Rekomendacinė** | -| `nightly-compat` | Node variklio suderinamumo matrica palaikomuose `engines.node` diapazonuose | **Rekomendacinė** | +| Darbo seka | Tikrina | Blokuoja | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `nightly-property` | fast-check savybių testus su atsitiktine pradine reikšme ir dideliu vykdymų skaičiumi | **Rekomendacinė** | +| `nightly-resilience` | atminties krūvos augimo ribą, chaoso trikčių įterpimą, k6 apkrovos / ilgalaikės apkrovos testus | **Rekomendacinė** | +| `nightly-llm-security` | promptfoo injekcijų apsaugą (blokavimo režimu) ir garak patikras (praleidžiamos be teikėjo paslapties) | **Rekomendacinė** | +| `nightly-schemathesis` | OpenAPI sutarties neapibrėžtąjį testavimą (schemathesis) veikiančioje OmniRoute, naudojant `docs/openapi.yaml` — aptinka specifikacijos pažeidimus / neapdorotas 500 klaidas (8 etapas B.4) | **Rekomendacinė** | +| `nightly-mutation` | Stryker mutacinio testavimo įvertį sparčiojoje vienetinių testų juostoje — išlikę mutantai atskleidžia silpnus teiginius | **Rekomendacinė** | +| `nightly-compat` | Node variklio suderinamumo matricą visuose palaikomuose `engines.node` diapazonuose | **Rekomendacinė** | --- @@ -550,43 +552,43 @@ prisijungimo klaidą ir niekada nenutraukia seansų. --- -## Racionalizavimo darbų sąrašas (ROI peržiūra — 9 etapas, 3 banga) +## Racionalizavimo darbų sąrašas (ROI peržiūra — 9 fazė, 3 banga) -Šis inventorius buvo suderintas su `ci.yml` 2026-06-17 (ankstesnėje versijoje nebuvo +Šis sąrašas buvo suderintas su `ci.yml` 2026-06-17 (ankstesnėje versijoje nebuvo `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Suderinto rinkinio ROI peržiūra -nustatė toliau nurodytus racionalizavimo kandidatus. **Sujungimai yra mechaniniai CI -pakeitimai; perjungimai ir pašalinimai yra operatoriui palikti politikos sprendimai.** Nė vienas -toliau nurodytas pakeitimas dar nepritaikytas. +nustatė toliau pateiktus racionalizavimo kandidatus. **Sujungimai yra mechaniniai CI +pakeitimai; perjungimai ir pašalinimai yra operatoriui palikti politikos sprendimai.** Niekas iš toliau +pateiktų pakeitimų dar nepritaikyta. -**Taip pat pirmiau neaprašyta** (rekomendacinio pobūdžio, silpnas signalas): `docs-lint` užduotis -(markdownlint + Vale, visai užduočiai taikoma `continue-on-error`) ir atskiros skaitytuvų darbo eigos -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` yra faile -`quality-baseline.json`, tačiau nėra susietas su blokuojančiu reketiniu patikrinimu faile `ci.yml` — šiuo metu -metrika yra atsieta. +**Taip pat pirmiau nedokumentuota** (patariamojo pobūdžio, silpnas signalas): `docs-lint` užduotis +(markdownlint + Vale, visai užduočiai taikoma `continue-on-error`) ir atskiros skenerių darbo eigos +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` yra +`quality-baseline.json`, tačiau nėra prijungta prie blokuojančio reketo `ci.yml` faile — šiuo metu ši metrika +yra nesusieta. -### Sujungimas / dubliavimo šalinimas (mechaninis, mažesnė rizika) +### Sujungimas / dubliavimo pašalinimas (mechaniniai pakeitimai, mažesnė rizika) -Kiekvienas kandidatas buvo patikrintas pagal faktinę kontrolinių patikrų būseną 2026-06-17 (pasitikėk, bet tikrink); -paaiškėjo, kad keli „akivaizdūs“ sujungimai slepia techninę skolą ir **nėra** tinkami tiesiogiai pakeisti esamus sprendimus. +Kiekvienas kandidatas buvo patikrintas pagal faktinę vartų būseną 2026-06-17 (pasitikėk, bet patikrink); +paaiškėjo, kad keli „akivaizdūs“ sujungimai slepia techninę skolą ir **nėra** tiesiogiai pritaikomi. -- **`check:docs-sync` vykdomas du kartus** — atskirai `lint` užduotyje ir dar kartą `check:docs-all` (`docs-sync-strict`) viduje bei husky prieš patvirtinimą vykdomame kabliuke. ✅ **ATLIKTA** — atskiras iškvietimas iš `lint` pašalintas. -- **CVE nuskaitymas** — ❌ **NĖRA paprastas sujungimas.** `audit:deps` griežtai nesėkmingas aptikus bet kokį aukšto ar kritinio lygio CVE; `check:vuln-ratchet` (osv) nesėkmingas tik esant _regresijai_, palyginti su bazine reikšme (šiuo metu 1 MODERATE). Semantika skiriasi — pašalinus `audit:deps` būtų prarasta absoliuti aukšto ar kritinio lygio kontrolė. Palikti abu. -- **Ciklų aptikimas** — ❌ **NĖRA paprastas sujungimas.** `check:circular-deps` (dpdm) praneša apie **91 ciklą** (todėl jis yra rekomendacinio pobūdžio); jo negalima padaryti blokuojančio, kol šie ciklai nebus pašalinti, be to, jo aprėptis platesnė nei sėkmingai vykdomo, kruopščiai atrinkto `check:cycles`. Palikti `check:cycles` blokuojantį; 91 dpdm ciklo pašalinimas yra atskiras darbų sąrašo punktas. -- **Sudėtingumas** — ✅ **ATLIKTA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): vienas ESLint perėjimas, skaičiuojama pagal ruleId, todėl ciklomatinio sudėtingumo bei didžiausio eilučių skaičiaus ir kognityvinio sudėtingumo bazinės reikšmės išlieka nepriklausomos; atskiri `check:complexity` / `check:cognitive-complexity` palikti vietiniam `--update`. -- **`/api` apsauga nuo haliucinacijų** — ✅ **ATLIKTA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): viena `src/app/api` FS inventorizacija, openapi-routes + docs-symbols ir toliau teikia atskiras ataskaitas; atskiri patikrinimai palikti vietiniam vykdymui. -- **`check:node-runtime` vykdomas 11 užduočių** — ⚠️ **maža ROI.** Kiekviena užduotis vykdoma atskirame vykdyklės egzemplioriuje, o patikrinimas trunka <1 s; iš viso būtų sutaupyta ~10 s, tačiau būtų prarasta nebrangi kiekvienos užduoties apsauga. Neverta dėl to daryti pakeitimų. -- **`typecheck:noimplicit:core` CI lint užduotyje** — ✅ **pašalinta iš lint užduoties** (buvo rekomendacinio pobūdžio `continue-on-error`); blokuojamą tipų paviršių sudaro `typecheck:core` + `check:type-coverage`. Vietinis scenarijus paliktas. +- **`check:docs-sync` vykdoma du kartus** — atskirai `lint` užduotyje ir dar kartą `check:docs-all` (`docs-sync-strict`) viduje bei husky prieš patvirtinimą vykdomame kabliuke. ✅ **ATLIKTA** — atskiras iškvietimas `lint` užduotyje pašalintas. +- **CVE skenavimas** — ❌ **NETINKA tiesiogiai sujungti.** `audit:deps` griežtai nesėkmingai baigiasi aptikusi bet kokį aukšto / kritinio lygio CVE; `check:vuln-ratchet` (osv) nesėkmingai baigiasi tik esant _regresijai_, palyginti su bazine reikšme (šiuo metu 1 MODERATE). Semantika skiriasi — pašalinus `audit:deps` būtų prarasti absoliutūs aukšto / kritinio lygio vartai. Palikti abu. +- **Ciklų aptikimas** — ✅ **ATLIKTA** (#15159 G-01/G-02). Ankstesniame tekste `check:cycles` buvo vadinama „žaliais, kuruojamais“ vartais ir jos blokavimas buvo grindžiamas tuo, kad `check:circular-deps` (dpdm) pranešė apie 91 ciklą. Tas žalias rezultatas buvo **klaidingai teigiamas**: `check:cycles` skenavo 5 pakatalogius (450 failų), aptiko tik statinius `import|export … from` ir atmetė kiekvieną `@/` bei `@omniroute/open-sse/` specifikatorių, todėl negalėjo aptikti dinaminių importų ir pseudonimų ciklų, kurių saugykloje buvo daugiausia. Ištaisyta: dabar vartai pereina per `src` + `open-sse` (5023 failus), surenka specifikatorius iš TypeScript AST (todėl `import("…")` įskaičiuojamas, o tipo pozicijoje esantis `typeof import("…")` — ne) ir išsprendžia tsconfig `paths`. Aptinkama **14** ciklų, o ne 0. Kadangi 14 anksčiau egzistavusių ciklų negalima ištaisyti vartų PR, `check:cycles` dabar yra **reketas** (`--ratchet`, riba `metrics.cycles.value = 14` faile `quality-baseline.json`, `direction: down`) — jis blokuoja bet kokią _regresiją_, o skaičius gali tik mažėti. CI vykdo `npm run check:cycles:ratchet`. Mažinimo darbai vykdomi kartu su **A-01**. `check:circular-deps` (dpdm) lieka patariamojo pobūdžio kaip platesnė antroji nuomonė. +- **Sudėtingumas** — ✅ **ATLIKTA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): vienas ESLint perėjimas, skaičiuojama pagal ruleId, todėl ciklomatinio sudėtingumo ir maksimalaus eilučių skaičiaus bei kognityvinio sudėtingumo bazinės reikšmės lieka nepriklausomos; atskiros `check:complexity` / `check:cognitive-complexity` paliekamos vietiniam `--update`. +- **`/api` apsauga nuo haliucinacijų** — ✅ **ATLIKTA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): viena `src/app/api` FS inventorizacija, openapi-routes + docs-symbols vis dar teikia atskiras ataskaitas; atskiros patikros paliktos vietiniam vykdymui. +- **`check:node-runtime` vykdoma 11 užduočių** — ⚠️ **maža ROI.** Kiekvienai naudojamas atskiras vykdytojas, o patikra trunka <1 s; iš viso būtų sutaupyta ~10 s, tačiau būtų prarasta nebrangi kiekvienos užduoties apsauga. Neverta sukeliamo triukšmo. +- **`typecheck:noimplicit:core` CI lint užduotyje** — ✅ **pašalinta iš lint užduoties** (buvo patariamojo pobūdžio `continue-on-error`); blokuojamas tipų paviršius yra `typecheck:core` + `check:type-coverage`. Vietinis scenarijus paliktas. ### Perjungti / nuspręsti (operatoriaus politika) -- `check:openapi-security-tiers` (rekomendacinio pobūdžio) — ❌ **NEGALIMA paprastai perjungti.** Jis baigiamas su 0 kodu, tačiau įspėja, kad keliems `traffic-inspector` maršrutams, esantiems `LOCAL_ONLY_API_PREFIXES`, trūksta anotacijos `x-loopback-only: true`. Prieš įjungiant privalomą vykdymą pirmiausia reikia pridėti šias anotacijas į `openapi.yaml`. -- `typecheck:noimplicit:core` (rekomendacinio pobūdžio) — didžiąja dalimi pakeistas blokuojančiu reketiniu `check:type-coverage` patikrinimu. Paversti reketiniu patikrinimu arba pašalinti perteklinį antrą `tsc` perėjimą. -- `test:vitest:ui` (dabar **blokuojantis**) — ankstesnės klaidos aiškiai neįtrauktos faile `vitest.config.ts`, naudojant `// #8618` sekimo komentarus; dėl naujų klaidų užduotis tampa nesėkminga. -- `check:secrets` (gitleaks, blokuojantis reketinis patikrinimas, užfiksuotas ties 3 dokumentuotais klaidingai teigiamais rezultatais) — įtraukti tuos 3 atvejus į leidžiamųjų sąrašą, kad būtų pasiektas 0, arba pakeisti į rekomendacinio pobūdžio patikrinimą. Persidengia su GitHub savuoju paslapčių nuskaitymu + `check:public-creds`. -- `check:pr-evidence` (blokuojantis, ieško atitikmenų PR turinio tekste) — didelė klaidingai teigiamų rezultatų rizika; jį pašalinus susilpnėtų griežtos taisyklės Nr. 18 vykdymo užtikrinimas, todėl tai yra tikras politikos sprendimas. -- `semgrep` (atskiras rekomendacinio pobūdžio patikrinimas) — OWASP kategorijose persidengia su CodeQL; susieti jo bazinę reikšmę su reketiniu patikrinimu arba pašalinti. +- `check:openapi-security-tiers` (patariamojo pobūdžio) — ❌ **NETINKA tiesiogiai perjungti.** Ji baigiama su 0 kodu, tačiau įspėja, kad keliems `traffic-inspector` maršrutams, esantiems `LOCAL_ONLY_API_PREFIXES`, trūksta anotacijos `x-loopback-only: true`. Norint ją padaryti privalomą, pirmiausia reikia pridėti tas anotacijas į `openapi.yaml`. +- `typecheck:noimplicit:core` (patariamojo pobūdžio) — didžiąja dalimi pakeista blokuojančiu `check:type-coverage` reketu. Perjungti į reketą arba pašalinti perteklinį antrąjį `tsc` perėjimą. +- `test:vitest:ui` (dabar **blokuojanti**) — anksčiau egzistavusios triktys aiškiai neįtrauktos faile `vitest.config.ts` su `// #8618` sekimo komentarais; dėl naujų trikčių užduotis baigiama nesėkmingai. +- `check:secrets` (gitleaks, blokuojantis reketas, užfiksuotas ties 3 dokumentuotais klaidingai teigiamais rezultatais) — įtraukti šiuos 3 į leidžiamųjų sąrašą, kad būtų pasiektas 0, arba pažeminti iki patariamojo pobūdžio. Dubliuojasi su GitHub integruotu paslapčių skenavimu + `check:public-creds`. +- `check:pr-evidence` (blokuojanti, ieško atitikmenų PR aprašo tekste) — didelė klaidingai teigiamų rezultatų rizika; ją pašalinus susilpnėtų griežtosios taisyklės Nr. 18 vykdymas, todėl tai tikras politikos sprendimas. +- `semgrep` (atskira patariamojo pobūdžio patikra) — dubliuojasi su CodeQL OWASP šeimoms; prijungti jos bazinę reikšmę prie reketo arba pašalinti. --- diff --git a/docs/i18n/lv/CONTRIBUTING.md b/docs/i18n/lv/CONTRIBUTING.md index 93d02493d2a..427199ec2a0 100644 --- a/docs/i18n/lv/CONTRIBUTING.md +++ b/docs/i18n/lv/CONTRIBUTING.md @@ -391,20 +391,20 @@ Uzrakstiet vienību testus direktorijā `tests/unit/`, kas aptver vismaz: ## Pull Request kontrolsaraksts -- [ ] Testi ir veiksmīgi (`npm test`) -- [ ] Lint pārbaude ir veiksmīga (`npm run lint`) -- [ ] Būvēšana ir veiksmīga (`npm run build`) -- [ ] Jaunām publiskajām funkcijām un saskarnēm ir pievienoti TypeScript tipi -- [ ] Nav cietkodētu noslēpumu vai rezerves vērtību -- [ ] Publiskie augšupējā nodrošinātāja akreditācijas dati ir iegulti, izmantojot `resolvePublicCred()` (skatiet [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nekad kā literāļi -- [ ] Kļūdu atbildes tiek novirzītas caur `buildErrorBody()` / `sanitizeErrorMessage()` — atbildes pamattekstā nav neapstrādātu steka izsekojumu (skatiet [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Čaulas komandas (`exec` / `spawn`) izpildlaika vērtības padod, izmantojot `env`, nevis virkņu interpolāciju -- [ ] Visas ievades tiek validētas ar Zod shēmām -- [ ] Lietotājiem redzamām izmaiņām ir pievienots izmaiņu žurnāla **fragment** fails `changelog.d/{features|fixes|maintenance}/-.md` (skatiet [`changelog.d/README.md`](./changelog.d/README.md)) — **ne**rediģējiet `CHANGELOG.md` tieši; fragmenti tiek apkopoti laidiena izveides laikā un nekad nerada konfliktus starp PR -- [ ] Dokumentācija ir atjaunināta (ja piemērojams) -- [ ] Nav atvērti jauni CodeQL / Secret-Scanning brīdinājumi, vai arī katrs no tiem ir noraidīts ar tehnisku pamatojumu, atsaucoties uz atbilstošo `docs/security/` dokumentu -- [ ] Maršruti, kas palaiž bērnprocesus (`/api/mcp/`, `/api/cli-tools/runtime/`), failā `src/server/authz/routeGuard.ts` ir klasificēti ar `isLocalOnlyPath()` — skatiet [Stingro noteikumu #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Komitziņojumos nav `Co-Authored-By` papildinājumu — komitiem ir jāparādās tikai repozitorija īpašnieka Git identitātes vārdā (Stingrais noteikums #16) +- [ ] Testi ir sekmīgi (`npm test`) +- [ ] Lintēšana ir sekmīga (`npm run lint`) +- [ ] Būvēšana ir sekmīga (`npm run build`) +- [ ] Jaunajām publiskajām funkcijām un saskarnēm ir pievienoti TypeScript tipi +- [ ] Nav nekodētu noslēpumu vai atkāpšanās vērtību +- [ ] Publiskie augšupstraumes akreditācijas dati ir iegulti, izmantojot `resolvePublicCred()` (skatiet [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), un nekad nav norādīti kā literāļi +- [ ] Kļūdu atbildes tiek apstrādātas, izmantojot `buildErrorBody()` / `sanitizeErrorMessage()` — atbilžu pamattekstā nav neapstrādātu steka izsekojumu (skatiet [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Čaulas komandas (`exec` / `spawn`) izpildlaika vērtības nodod, izmantojot `env`, nevis virkņu interpolāciju +- [ ] Visas ievades ir validētas, izmantojot Zod shēmas +- [ ] Lietotājam redzamajām izmaiņām sadaļā `changelog.d/{features|fixes|maintenance}/-.md` ir pievienots izmaiņu žurnāla **fragments** (skatiet [`changelog.d/README.md`](./changelog.d/README.md)) — **nerediģējiet** `CHANGELOG.md` tieši; fragmenti tiek apkopoti laidiena izveides laikā un nekad nerada konfliktus starp PR +- [ ] Dokumentācija ir atjaunināta (ja attiecināms) +- [ ] Nav izveidots neviens jauns CodeQL / Secret-Scanning brīdinājums, vai arī katrs brīdinājums ir noraidīts ar tehnisku pamatojumu, atsaucoties uz attiecīgo `docs/security/` dokumentu +- [ ] Maršruti, kas palaiž bērnprocesus (`/api/mcp/`, `/api/cli-tools/runtime/`), failā `src/server/authz/routeGuard.ts` ir klasificēti kā `isLocalOnlyPath()` — skatiet [Stingro noteikumu Nr. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Izpildes ziņojumos nav AI/robotu `Co-authored-by` nobeiguma rindu (Stingrais noteikums Nr. 16) — cilvēki, kuru darbs tiek atkārtoti izmantots, tiek norādīti ar standarta `Co-authored-by: Name ` nobeiguma rindām --- diff --git a/docs/i18n/lv/docs/architecture/QUALITY_GATES.md b/docs/i18n/lv/docs/architecture/QUALITY_GATES.md index 8f2ba6e5e44..cd450480bde 100644 --- a/docs/i18n/lv/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/lv/docs/architecture/QUALITY_GATES.md @@ -15,269 +15,271 @@ replikācijas plānu skatiet --- -## Vārtu inventarizācija un izpildes profili - -### Kandidātu pielaide - -CI un kvalitātes vārtu darbplūsmas katra izdod stabilu verdiktu: `Gate / CI` un -`Gate / Quality`. To versijotā pielaides politika uzskaita katru augšupējo uzdevumu -kā obligātu vai konsultatīvu. Piemērojamam obligātajam uzdevumam jābeidzas sekmīgi: -trūkstoši, atcelti, izlaisti, gaidoši un nezināmi rezultāti nevar noteikt PASS. Derīga -klasifikācija “tikai dokumentācija” vai “tikai katalogs” var padarīt koda joslu -nepiemērojamu; melnraksta PR netiek pieņemts kā kandidāts. `hotfix` etiķete neatceļ -pierādījumu prasības. - -Abas darbplūsmas aptver PR un izmaiņu nosūtīšanu uz galvenajiem/laidiena zariem, manuālu -palaišanu un apvienošanas grupu notikumus. Izmaiņu nosūtīšanas, manuālās palaišanas un -apvienošanas grupas gadījumā tiek izpildīta pilnā atlase. Atzarojumi un apvienošanas -grupas izmanto mitinātus izpildītājus uzdevumiem, kuri citādi izvēlētos pašmitinātus -izpildītājus; pirms ieviešanas jāpārbauda, vai mitinātā jauda ir pietiekama. - -Katrā JSON kvītī ir norādīts izrakstītais SHA, darbplūsmas izpilde un mēģinājums. -CLI noraida neatbilstību starp izrakstījuma un notikuma SHA. Darbplūsmas testi sasaista -politikas dalību ar verdikta uzdevuma `needs` sarakstu, lai jauna vai noņemta josla -nevarētu nemanāmi pazust. Kvītis aptver savu darbplūsmu, nevis publicēšanu, izvietošanu -vai esoša konsultatīva skenera iekšējo darbību. Abu pārbaužu nosaukumu aktivizēšana -zaru noteikumos ir atsevišķa administratīva izmaiņa; šo uzdevumu pievienošana pati par -sevi neaizsargā zaru. - -### Statiskās skenēšanas inventarizācija - -Versijotā npm aizstājvārdu inventarizācija un statiskās skenēšanas dalība atrodas +## Vārtu inventārs un izpildes profili + +### Kandidātu pielaišana + +CI un kvalitātes vārtu darbplūsmas katra izvada stabilu verdiktu: `Gate / CI` un +`Gate / Quality`. To versijotā pielaišanas politika uzskaita katru augšupējo darbu +kā obligātu vai konsultatīvu. Piemērojamam obligātajam darbam jābeidzas sekmīgi: +trūkstoši, atcelti, izlaisti, gaidoši un nezināmi rezultāti nevar apstiprināt PASS. +Derīga klasifikācija «tikai dokumentācija» vai «tikai katalogs» var padarīt koda +izpildes zaru nepiemērojamu; melnraksta PR nav pieņemts kandidāts. `hotfix` etiķete +neatceļ pierādījumu prasību. + +Abas darbplūsmas aptver PR un izmaiņu nosūtīšanu uz galvenajiem/laidiena zariem, +manuālu palaišanu un apvienošanas grupas notikumus. Izmaiņu nosūtīšana, manuāla +palaišana un apvienošanas grupa izpilda pilno atlasi. Atzarojumi un apvienošanas +grupas izmanto mitinātus izpildītājus darbiem, kuri citādi atlasītu pašmitinātus +izpildītājus; pirms ieviešanas jāpārbauda pietiekamas mitinātās jaudas pieejamība. + +Katra JSON kvīts identificē izrakstīto SHA, darbplūsmas izpildi un mēģinājumu. +CLI noraida neatbilstību starp izrakstījuma un notikuma SHA. Darbplūsmas testi +saista politikas dalību ar verdikta darba `needs` sarakstu, lai jauns vai noņemts +izpildes zars nevarētu nemanāmi pazust. Kvītis aptver savu darbplūsmu, nevis +publicēšanu, izvietošanu vai esoša konsultatīvā skenera iekšējo darbību. Abu +pārbaužu nosaukumu aktivizēšana zaru noteikumos ir atsevišķa administratīva +izmaiņa; šo darbu pievienošana pati par sevi neaizsargā zaru. + +### Statiskās skenēšanas inventārs + +Versijotais npm aizstājvārdu inventārs un statiskās skenēšanas dalība atrodas `config/quality/gate-manifest.json`. Palaidiet `npm run check:gate-manifest`, lai validētu skriptu nosaukumus un precīzās komandas pret `package.json`; papildinājumi, -noņemšanas un komandu novirzes izraisa kļūmi gan lokālajā āķī, gan izmaiņu klasifikācijas -uzdevumos CI. Aizstājvārds nav darbplūsmas uzdevums, matricas instance vai testa gadījums: -šos skaitus nedrīkst pasniegt kā savstarpēji aizstājamus. +noņemšanas un komandu novirzes izraisa kļūmi gan lokālajā āķī, gan izmaiņu +klasifikācijas darbos CI vidē. Aizstājvārds nav darbplūsmas darbs, matricas instance +vai testa gadījums: šos skaitus nedrīkst pasniegt kā savstarpēji aizstājamus. Izmantojiet `npm run quality:scan -- --list` vai `npm run quality:scan:fast -- --list`, -lai pārskatītu atlasītos aizstājvārdus, tos neizpildot. Izpildītājs izsauc npm -ieejas punktu, tāpēc tiek saglabāta tā izpildvide (tostarp Bun, kur tas ir konfigurēts). -Manifests reģistrē ārpus šiem profiliem esošos aizstājvārdus kā atsevišķi izsaucamus, -un tikai lasāmos skenēšanas profilos uzturēšanas komandas ir aizliegtas. - -Šie profili aptver tikai statisko skenēšanu. Tie neapliecina produkta testus, -pārklājumu, pakotņu veidošanu, ārējās pārbaudes vai kandidāta pilnīgu pieņemšanu laidienam. -Darbplūsmas pielaide izmanto saistīto `config/quality/admission-policy.json` un -`scripts/quality/admission-verdict.mjs`. Laidiena novērotāja profili paliek atsevišķi; -pārbaudiet to piemērojamās pārbaudes un kvītis neatkarīgi. Tālāk esošā teksta -inventarizācija ir uzziņas materiāls, nevis pierādījums, ka vārti patiešām tika izpildīti. - -Skripti atrodas zem `scripts/check/` (politikas vārti) un `scripts/quality/` (sprūdrata dzinis). -CI patiesības avots ir `.github/workflows/ci.yml`. +lai pārbaudītu atlasītos aizstājvārdus, tos neizpildot. Izpildītājs izsauc npm +ieejas punktu, tāpēc tiek saglabāta tā izpildlaika vide (tostarp Bun, kur tas +konfigurēts). Manifests reģistrē aizstājvārdus ārpus šiem profiliem kā atsevišķi +izsaucamus, un tikai lasāmas skenēšanas profilos uzturēšanas komandas ir aizliegtas. + +Šie profili aptver tikai statisko skenēšanu. Tie nesertificē produkta testus, +pārklājumu, pakošanu, ārējās pārbaudes vai kandidāta pilnīgu pieņemšanu laidienam. +Darbplūsmas pielaišana izmanto saistīto `config/quality/admission-policy.json` un +`scripts/quality/admission-verdict.mjs`. Laidiena novērotāja profili paliek +atsevišķi; pārbaudiet tiem piemērojamās pārbaudes un kvītis neatkarīgi. Tālāk +sniegtais tekstuālais inventārs ir uzziņai, nevis pierādījums tam, ka vārti +patiešām tika izpildīti. + +Skripti atrodas zem `scripts/check/` (politikas vārti) un `scripts/quality/` +(pakāpeniskās pastiprināšanas dzinis). CI patiesības avots ir +`.github/workflows/ci.yml`. ### Laidiena PR ātrais ceļš (`quality.yml`) -`.github/workflows/quality.yml` papildina CI galveno/laidiena zaru PR, izmaiņu nosūtīšanai -uz aizsargātiem zariem, manuālai palaišanai un apvienošanas grupām. PR izmanto pēc ceļiem -filtrētas ātrās pārbaudes. Pastāvīgi atspējotā dublētā būvēšana tika noņemta; īstās -būvēšanas/pakotņu veidošanas/palaišanas pārbaudes paliek CI. - -| Uzdevums | Tvērums | Bloķējošs | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | Dokumentācijas/koda PR; API dokumentācijas atsauces un visa dokumentācija | Jā | -| `Fast Quality Gates` | Koda PR; statiskās pārbaudes, tipu pārbaude, informācijas paneļa tipu pārbaude, ietekmētie vienību testi | Jā | -| `Forgotten sibling tests` | Koda PR; mainītie moduļi tiek izsekoti līdz statiskajiem patērētājiem un kandidātu radniecīgajiem testiem; barelu un dinamiskā importa ceļi tiek ziņoti kā konsultatīva diagnostika ar norādītiem atļauto izņēmumu saraksta izņēmumiem | **Konsultatīvs** | -| `Vitest (fast-path)` | Koda PR; ātrais vitest komplekts | Jā | -| `Unit Tests fast-path` | Koda PR; 4 daļās sadalīts vienību testu komplekts | Jā | -| `No new ESLint warnings` | Koda PR; lintēšanas aizsargs, kas ņem vērā apspiešanas | Jā, tostarp atzarojumiem | -| `Merge integrity (changelog + generated skills)` | PR, kas nav melnraksti; izmaiņu žurnāla un ģenerēto prasmju sinhronizācija | Jā, tostarp atzarojumiem | - -#### Ziņojums par aizmirstajiem radniecīgajiem testiem - -`npm run check:forgotten-sibling-tests` atkārtoti izmanto importa atrisinātāju, kas ir -testu ietekmes kartes pamatā. Katram mainītajam produkcijas modulim tas ziņo deterministiskas -`mainītais modulis/simbols -> statiskais patērētājs -> kandidāta radniecīgais tests` ķēdes, -ja kandidāta testa nav izmaiņu pieprasījuma atšķirībās. Markdown kopsavilkums un JSON -rezultāts tiek saglabāti kā `forgotten-sibling-tests` darbplūsmas artefakts kalibrēšanai -pirms jebkādas bloķējošas ieviešanas. - -Barrel atkārtotie eksporti un dinamiskie importi kalpo tikai izšķirtspējas diagnostikai; tie nekad nerada -bloķējošu atradni. Pārskatītie izņēmumi atrodas failā +`.github/workflows/quality.yml` papildina CI galveno/laidiena zaru PR, aizsargāto +zaru izmaiņu nosūtīšanā, manuālā palaišanā un apvienošanas grupās. PR izmanto pēc +ceļiem filtrētas ātrās pārbaudes. Pastāvīgi atspējotais dublētais būvējums tika +noņemts; īstās būvēšanas/pakošanas/palaišanas pārbaudes paliek CI vidē. + +| Darbs | Tvērums | Bloķējošs | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `Docs Gates (fast-path)` | Dokumentācijas/koda PR; API dokumentācijas atsauces un visa dokumentācija | Jā | +| `Fast Quality Gates` | Koda PR; statiskās pārbaudes, tipu pārbaude, informācijas paneļa tipu pārbaude, ietekmētie vienībtesti | Jā | +| `Forgotten sibling tests` | Koda PR; mainītie moduļi, kas izsekoti līdz statiskajiem patērētājiem un saistīto testu kandidātiem; mucas un dinamiskās importēšanas ceļi tiek ziņoti kā konsultatīva diagnostika ar atsauktiem atļauto izņēmumu saraksta izņēmumiem | **Konsultatīvs** | +| `Vitest (fast-path)` | Koda PR; ātrais vitest komplekts | Jā | +| `Unit Tests fast-path` | Koda PR; 4 daļās sadalīts vienībtestu komplekts | Jā | +| `No new ESLint warnings` | Koda PR; lintēšanas aizsargs, kas ņem vērā slāpēšanas | Jā, tostarp atzarojumiem | +| `Merge integrity (changelog + generated skills)` | PR, kas nav melnraksti; izmaiņu žurnāla un ģenerēto prasmju sinhronizācija | Jā, tostarp atzarojumiem | + +#### Aizmirsto saistīto testu pārskats + +`npm run check:forgotten-sibling-tests` atkārtoti izmanto importēšanas atrisinātāju, +kas ir testu ietekmes kartes pamatā. Katram mainītajam produkcijas modulim tas +ziņo deterministiskas `mainītais modulis/simbols -> statiskais patērētājs -> saistītā testa kandidāts` +ķēdes, ja kandidāta testa nav izmaiņu pieprasījuma atšķirībās. Markdown kopsavilkums +un JSON rezultāts tiek saglabāti kā `forgotten-sibling-tests` darbplūsmas artefakts +kalibrēšanai pirms jebkādas bloķējošas ieviešanas. + +Barrel tipa atkārtotie eksporti un dinamiskie importi ir tikai izšķirtspējas diagnostika; tie nekad nerada +bloķējošu konstatējumu. Pārskatītie izņēmumi atrodas failā `config/quality/forgotten-sibling-allowlist.json`. Katrā ierakstā jānorāda patērētājs un kandidāta -tests, jāsniedz konkrēts pamatojums un jāpievieno saite uz GitHub problēmu vai izmaiņu pieprasījumu. Nederīgi ieraksti tiek -noraidīti. Izņēmumi nevar ignorēt dzēstu kandidāta testu vai izmaiņu kopu, kas pievieno `.skip`/`.todo`; -apgalvojumu vājināšana un cita maskēšana joprojām ir neatkarīgi bloķējošā -`check:test-masking` vārtejas pārziņā. +tests, jāsniedz konkrēts pamatojums un jāpievieno saite uz GitHub problēmu vai izmaiņu pieprasījumu. Nederīgi ieraksti +drošības nolūkā tiek noraidīti. Izņēmumi nevar ignorēt dzēstu kandidāta testu vai izmaiņas, kas pievieno `.skip`/`.todo`; +apgalvojumu vājināšanu un citu maskēšanu joprojām pārvalda neatkarīgi bloķējošā +`check:test-masking` pārbaude. ### Uzdevums: `lint` Tiek izpildīts katram izmaiņu pieprasījumam uz `main`. Kļūmes gadījumā bloķē sapludināšanu. -| Skripts (`npm run ...`) | Pārbauda | Bloķējošs | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Node.js versija ir atbalstītajā diapazonā | Jā | -| `check:cycles` | Cikliskie importi — visi `src/` + `open-sse/` moduļi | Jā | -| `check:route-validation:t06` | Zod shēmas ir pieejamas visiem maršrutiem (6. līmeņa politika) | Jā | -| `check:any-budget:t11` | `@ts-expect-error // any` skaits nepārsniedz budžetu (11. līmeņa catraca) | Jā | -| `check:provider-consistency` | Katram pakalpojumu sniedzējam failā `providers.ts` ir atbilstošs ieraksts failā `providerRegistry.ts` (un otrādi, atļauto ierakstu saraksta ietvaros) | Jā | -| `check:model-lifecycle` | Trīs manuāli uzturētās maršrutēšanas tabulas saglabā savstarpēju atbilstību ar repozitorijā iekļauto dzīves cikla momentuzņēmumu (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nepiešķir vērtējumu nevienam izņemtam ID, kuru `REGISTRY` var maršrutēt; katrs `BUILT_IN_ALIASES` mērķis ir iekļauts `REGISTRY` un nav atrodams izņemto ID momentuzņēmumā; katrs izņemtais ID, kas joprojām atrodas `REGISTRY`, tiek pāradresēts vai ir norādīts sarakstā `allowedRetiredInCatalog`; un neviens `DEFAULT_DEGRADATION_MAP` avots vai mērķis šajā momentuzņēmumā nav atzīmēts kā izņemts. Tas nepierāda, ka modeli pašlaik nodrošina aktīvs augšupstraumes pakalpojums. Bezsaistes pārbaude — salīdzina ar `config/quality/model-lifecycle.json`, kas manuāli tiek atjaunināts ar `npm run quality:refresh-model-lifecycle` (nepieciešams tīkls; nav integrēts CI). `allowedRetiredInCatalog` ir pakāpeniskas samazināšanas sprūdrata mehānisms: pievienojiet ierakstu tikai kopā ar izsekošanas pieteikumu. | Jā | -| `check:fetch-targets` | Katrs `fetch("/api/...")` klienta puses direktorijā `src/` norāda uz reālu `route.ts` | Jā | -| `check:deps` | Visas ar `npm install` instalējamās atkarības visos repozitorija failos `package.json` ir iekļautas failā `dependency-allowlist.json`; jaunas atkarības bez fiksētas versijas vai ar nosaukumiem, kas var liecināt par slopsquatting uzbrukumu, tiek atzīmētas | Jā | -| `audit:deps` | `npm audit` (saknes projekts + Electron) — nav augstas/kritiskas bīstamības ieteikumu (daļēji pārklājas ar OSV `check:vuln-ratchet`; skatiet racionalizācijas neizdarīto darbu sarakstu) | Jā | -| `check:lockfile` | `package-lock.json` integritāte — HTTPS reģistrs, integritātes jaucējvērtības, nav resursdatoru pārrakstīšanas iestatījumu | Jā | -| `check:licenses` | SPDX licenču atļauto saraksts produkcijas atkarībām | Jā | -| `check:tracked-artifacts` | Nav būvējuma artefaktu / repozitorijā iekļautu `node_modules` simbolisko saišu (tiek izpildīts arī husky pirmskomita pārbaudē; pirms nosūtīšanas pārbaude apzināti ir viegla — #6716) | Jā | -| `check:ai-attribution` | PR komitos, virsrakstā vai aprakstā nav AI/bota `Co-Authored-By` noslēguma rindas vai AI ģenerēšanas kājenes — stingrais noteikums Nr. 16 (`quality.yml` ātro pārbaužu ciklā PR→`release/**` — nolasa notikuma datu saturu, ārpus PR neveic nekādas darbības — un tikai PR paredzētā `ci.yml` lintēšanas solī PR→`main`; kā arī husky `commit-msg` āķī; cilvēki līdzautori ir atļauti; #14436) | -| `check:vitest-exclusions` | Katram Vitest izņēmumam ir norādīts izsekošanas pieteikums, un tas ir iekļauts failā `config/quality/vitest-exclusions.json` (#13204) | Jā | -| `check:file-size` | Neviens pirmkoda fails nepārsniedz attiecīgajam paplašinājumam noteikto ierobežojumu (sprūdrata princips: lielie faili ir fiksēti sarakstā `frozen`) | Jā | -| `check:error-helper` | Kļūdu atbildēs izpildītājos/apdarinātājos tiek izmantots `buildErrorBody()` / `sanitizeErrorMessage()` (stingrais noteikums Nr. 12) | Jā | -| `check:migration-numbering` | Migrāciju SQL faili ir secīgi numurēti, bez iztrūkumiem vai dublikātiem | Jā | -| `check:public-creds` | Ārpus `publicCreds.ts` nav literālu OAuth `client_id`/`client_secret` vai Firebase tīmekļa atslēgu (stingrais noteikums #11) | Jā | -| `check:db-rules` | Ārpus `src/lib/db/` moduļiem nav neapstrādāta SQL; nav apkopojošo importu no `localDb.ts` (stingrie noteikumi #2/#5) | Jā | -| `check:known-symbols` | Pakalpojumu sniedzēju izpildītāji, maršrutēšanas stratēģijas un tulkotāji, kas reģistrēti to nosūtīšanas tabulās, atbilst diskā esošajiem failiem — nav bāreņu vai nedeklarētu simbolu | Jā | -| `check:route-guard-membership` | Katrs maršruts, kas palaiž bērnprocesu, ir klasificēts ar `isLocalOnlyPath()` (stingrie noteikumi #15/#17) | Jā | -| `check:test-discovery` | Katru repozitorijā esošo `*.test.ts` / `*.spec.ts` failu apkopo vismaz viens testu izpildītājs (sprūdratmehānisms: bāreņu saraksts failā `test-discovery-baseline.json` var tikai samazināties) | Jā | -| `check:agent-skills-sync` | Ģenerētie agentu prasmju artefakti atbilst to avota katalogam (nav noviržu) | -| `check:provider-asset-provenance` | Pakalpojumu sniedzēju logotipiem/resursiem ir reģistrēts izcelsmes ieraksts | -| `lint:json` | JSON konfigurācijas faili tiek parsēti un atbilst repozitorija lintēšanas noteikumiem | -| `typecheck:core` | TypeScript kompilācija bez kļūdām (tikai konsultatīvi brīdinājumi) | Jā | -| `typecheck:noimplicit:core` | Stingrs `noImplicitAny` — uz nākotni vērsta pārbaude; daudzām jau esošām izsaukuma vietām joprojām nepieciešamas anotācijas | **Konsultatīvs** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, kas attiecas tikai uz `src/app/(dashboard)/**` (#7033) — `typecheck:core` rūpīgi atlasītais 27 failu atļauju saraksts neietver nevienu informācijas paneļa TSX failu, un arī `next build` tiem nekad neveic tipu pārbaudi (`next.config.mjs` iestata `ignoreBuildErrors: true`), tādēļ nesaistītu identifikatoru regresijas tur (#6625/#6909) CI nebija pamanāmas. Atšķirības tiek noteiktas pret fiksētu katra faila un TS koda skaita bāzes līniju (`config/quality/dashboard-typecheck-baseline.json`, tāds pats novecojušu ierakstu kontroles modelis kā `check:known-symbols`) — pārbaude neizdodas tikai tad, ja ir JAUNAS kļūdas, kas pārsniedz bāzes līnijas skaitu; kad jau esoša kļūda ir novērsta, pazeminiet bāzes līmeni ar `--update`. | Jā | - -### Uzdevums: `quality-gate` - -Tiek izpildīts pēc `test-coverage`. Kļūmes gadījumā bloķē sapludināšanu. - -| Skripts | Pārbauda | Bloķējošs | -| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `quality:collect` | Izveido `quality-metrics.json` (ESLint brīdinājumu skaits, pārklājums no apvienotā segmentu pārskata) | Jā (pirms ratchet pārbaudes) | -| `quality:ratchet` | Neviena `quality-baseline.json` metrika nav pasliktinājusies (ESLint brīdinājumi ≤ bāzes līmenis; pārklājums ≥ bāzes līmenis) | Jā | -| `check:duplication` | Koda dublēšanās (jscpd@4) nepārsniedz `quality-baseline.json` noteikto bāzes līmeni | Jā | -| `check:complexity` | Faila līmeņa ciklomātiskā sarežģītība nepārsniedz ierobežojumu (pamata ESLint `complexity` + `max-lines-per-function`) | Jā | -| `check:cognitive-complexity` | Kognitīvās sarežģītības ratchet pārbaude (`eslint-plugin-sonarjs`) — atsevišķa ESLint izpilde; CI abas pārbaudes apvieno vienā `check:complexity-ratchets` solī | Jā | -| `check:dead-code` | Neizmantoto eksportu/failu ratchet pārbaude (knip) neuzrāda pasliktinājumu salīdzinājumā ar bāzes līmeni | Jā | -| `check:compression-budget` | Saspiešanas etalontesta budžets — minimālais katram dzinim noteiktais marķieru ietaupījums nedrīkst samazināties | Jā | -| `check:type-coverage` | Tipizācijas procentuālās daļas ratchet pārbaude (`type-coverage`) neuzrāda pasliktinājumu; lielā mērā aizstāj `typecheck:noimplicit:core` | Jā | -| `check:codeql-ratchet` | Atvērto CodeQL brīdinājumu skaits nepalielinās (nolasa, izmantojot `gh api`; korekti izlaiž bez pilnvaras) — atjaunošanas biežumu un manuālo palaišanu skatiet tālāk sadaļā "CodeQL ratchet" | Jā | +| Skripts (`npm run ...`) | Pārbauda | Bloķējošs | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Node.js versija ir atbalstītajā diapazonā | Jā | +| `check:cycles` | Cikliskos importus visā `src/` + `open-sse/` (balstīts uz AST, atrisināti tsconfig `paths`). Palaižot atsevišķi, pārbaude ir informatīva un uzskaita ciklus. `check:cycles:ratchet` (ko izpilda CI) bloķē, ja skaits pārsniedz `quality-baseline.json` definēto `metrics.cycles` robežvērtību — pašlaik 14, `direction: down`, tādēļ tā var tikai samazināties (#15159 G-01/G-02) | Jā (pakāpeniskā robežkontrole) | +| `check:route-validation:t06` | Zod shēmu esamību visos maršrutos (6. līmeņa politika) | Jā | +| `check:any-budget:t11` | `@ts-expect-error // any` skaits nepārsniedz budžetu (11. līmeņa sprūdrata kontrole) | Jā | +| `check:provider-consistency` | Katram pakalpojumu sniedzējam failā `providers.ts` ir atbilstošs ieraksts failā `providerRegistry.ts` (un otrādi — atļauto vienumu saraksta ietvaros) | Jā | +| `check:model-lifecycle` | Trīs manuāli uzturētās maršrutēšanas tabulas saglabā atbilstību repozitorijā iekļautajam dzīves cikla momentuzņēmumam (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nepiešķir vērtējumu nevienam ekspluatāciju beigušam id, kuru `REGISTRY` var maršrutēt; katrs `BUILT_IN_ALIASES` mērķis ir ietverts `REGISTRY` un nav atrodams ekspluatāciju beigušo id momentuzņēmumā; katrs ekspluatāciju beigušais id, kas joprojām atrodas `REGISTRY`, tiek pārsūtīts vai norādīts `allowedRetiredInCatalog`; un neviens `DEFAULT_DEGRADATION_MAP` avots vai mērķis šajā momentuzņēmumā nav atzīmēts kā ekspluatāciju beidzis. Tas nepierāda, ka modeli pašlaik apkalpo aktīvs augšupstraumes pakalpojums. Bezsaistes pārbaude — salīdzina ar `config/quality/model-lifecycle.json`, kas tiek manuāli atsvaidzināts ar `npm run quality:refresh-model-lifecycle` (nepieciešams tīkls; nav integrēts CI). `allowedRetiredInCatalog` ir pakāpeniskas samazināšanas sprūdrata mehānisms: pievienojiet ierakstu tikai kopā ar izsekošanas problēmu. | Jā | +| `check:fetch-targets` | Katrs `fetch("/api/...")` klienta puses direktorijā `src/` norāda uz reālu `route.ts` | Jā | +| `check:deps` | Visas ar `npm install` instalējamās atkarības visos repozitorija `package.json` failos ir iekļautas `dependency-allowlist.json`; jaunās atkarības bez fiksētas versijas vai ar iespējamu slopsquatting risku tiek atzīmētas | Jā | +| `audit:deps` | `npm audit` (saknes projekts + electron) — nav augsta/kritiska līmeņa drošības paziņojumu (daļēji pārklājas ar osv `check:vuln-ratchet`; skatiet Racionalizācijas neizdarīto darbu sarakstu) | Jā | +| `check:lockfile` | `package-lock.json` integritāte — https reģistrs, integritātes kontrolsummas, bez resursdatora pārrakstīšanas | Jā | +| `check:licenses` | SPDX licenču atļauto vērtību saraksts produkcijas atkarībām | Jā | +| `check:tracked-artifacts` | Nav būvējuma artefaktu / repozitorijā iekļautu `node_modules` simbolisko saišu (tiek palaista arī husky pirmsiesniegšanas pārbaudē; pirms nosūtīšanas pārbaude ir apzināti vienkārša — #6716) | Jā | +| `check:ai-attribution` | PR komitos, virsrakstā vai pamattekstā nav AI/bota `Co-Authored-By` noslēguma rindas vai AI ģenerēšanas kājenes — stingrais noteikums Nr. 16 (`quality.yml` ātro pārbaužu ciklā PR→`release/**` gadījumā — nolasa notikuma derīgo slodzi, bet ārpus PR neveic nekādas darbības — un tikai PR paredzētā `ci.yml` linting pārbaudes solī PR→`main` gadījumā; kā arī husky `commit-msg` āķī; cilvēki kā līdzautori ir atļauti; #14436) | +| `check:vitest-exclusions` | Katram Vitest izņēmumam ir norādīts izsekošanas pieteikums, un tas ir iekļauts `config/quality/vitest-exclusions.json` (#13204) | Jā | +| `check:file-size` | Neviens avota fails nepārsniedz attiecīgajam paplašinājumam noteikto ierobežojumu (pakāpeniskais ierobežojums: iesaldētie lielie faili ir `frozen` sarakstā) | Jā | +| `check:error-helper` | Kļūdu atbildēs izpildītājos/apstrādātājos tiek izmantots `buildErrorBody()` / `sanitizeErrorMessage()` (stingrais noteikums Nr. 12) | Jā | +| `check:migration-numbering` | Migrācijas SQL faili ir secīgi numurēti, bez iztrūkumiem vai dublikātiem | Jā | +| `check:public-creds` | Ārpus `publicCreds.ts` nav literālu OAuth `client_id`/`client_secret` vai Firebase tīmekļa atslēgu (stingrais noteikums Nr. 11) | Jā | +| `check:db-rules` | Ārpus `src/lib/db/` moduļiem nav neapstrādāta SQL; no `localDb.ts` netiek veikti apvienotie importi (stingrie noteikumi Nr. 2/Nr. 5) | Jā | +| `check:known-symbols` | Pakalpojumu sniedzēju izpildītāji, maršrutēšanas stratēģijas un tulkotāji, kas reģistrēti to dispečertabulās, atbilst diskā esošajiem failiem — nav bāreņsimbolu vai nedeklarētu simbolu | Jā | +| `check:route-guard-membership` | Katrs maršruts, kas palaiž bērnprocesu, ir klasificēts ar `isLocalOnlyPath()` (stingrie noteikumi Nr. 15/Nr. 17) | Jā | +| `check:test-discovery` | Katru repozitorijā esošo `*.test.ts` / `*.spec.ts` failu apkopo vismaz viens testu izpildītājs (sprūdrata princips: bāreņfailu saraksts failā `test-discovery-baseline.json` var tikai samazināties) | Jā | +| `check:agent-skills-sync` | Ģenerētie agentu prasmju artefakti atbilst to avota katalogam (nav noviržu) | +| `check:provider-asset-provenance` | Pakalpojumu sniedzēju logotipiem/resursiem ir reģistrēts izcelsmes ieraksts | +| `lint:json` | JSON konfigurācijas faili tiek parsēti un atbilst repozitorija lintēšanas noteikumiem | +| `typecheck:core` | TypeScript kompilācija bez kļūdām (tikai konsultatīvi brīdinājumi) | Jā | +| `typecheck:noimplicit:core` | Stingrais `noImplicitAny` — paredzēts turpmākai ieviešanai; daudzām jau esošām izsaukuma vietām joprojām ir nepieciešamas anotācijas | **Konsultatīvs** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, kas attiecas tikai uz `src/app/(dashboard)/**` (#7033) — `typecheck:core` atlasītais 27 failu atļauto failu saraksts neietver nevienu informācijas paneļa TSX failu, un `next build` arī nekad neveic tā tipu pārbaudi (`next.config.mjs` iestata `ignoreBuildErrors: true`), tādēļ nesaistītu identifikatoru regresijas šajos failos (#6625/#6909) CI sistēmai nebija pamanāmas. Atšķirības tiek salīdzinātas ar fiksētu bāzes līmeni, kurā norādīts skaits katram failam un katram TS kodam (`config/quality/dashboard-typecheck-baseline.json`, tāds pats novecojušu ierakstu kontroles modelis kā `check:known-symbols`) — pārbaude neizdodas tikai tad, ja rodas JAUNAS kļūdas, kas pārsniedz bāzes līmeņa skaitu; samaziniet bāzes līmeni ar `--update`, kad jau esoša kļūda ir novērsta. | Jā | + +### Darbs: `quality-gate` + +Tiek izpildīts pēc `test-coverage`. Kļūmes gadījumā bloķē apvienošanu. + +| Skripts | Validē | Bloķējošs | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | +| `quality:collect` | Izveido `quality-metrics.json` (ESLint brīdinājumu skaits, pārklājums no apvienotā segmentu pārskata) | Jā (pirms ratchet) | +| `quality:ratchet` | Neviena metrika failā `quality-baseline.json` nav pasliktinājusies (ESLint brīdinājumi ≤ bāzes līmenis; pārklājums ≥ bāzes līmenis) | Jā | +| `check:duplication` | Koda dublēšanās (jscpd@4) nepārsniedz bāzes līmeni failā `quality-baseline.json` | Jā | +| `check:complexity` | Faila līmeņa ciklomātiskā sarežģītība nepārsniedz ierobežojumu (pamata ESLint `complexity` + `max-lines-per-function`) | Jā | +| `check:cognitive-complexity` | Kognitīvās sarežģītības ratchet (`eslint-plugin-sonarjs`) — atsevišķa ESLint pārbaude; CI izpilda abas apvienoti vienā `check:complexity-ratchets` solī | Jā | +| `check:dead-code` | Neizmantoto eksportu/failu ratchet (knip) rezultāts nav pasliktinājies salīdzinājumā ar bāzes līmeni | Jā | +| `check:compression-budget` | Saspiešanas etalonmērījuma budžets — katram dzinim noteiktais minimālais marķieru ietaupījums nedrīkst samazināties | Jā | +| `check:type-coverage` | Tipizētā koda procentuālās daļas ratchet (`type-coverage`) rezultāts nav pasliktinājies; lielā mērā aizstāj `typecheck:noimplicit:core` | Jā | +| `check:codeql-ratchet` | Atvērto CodeQL brīdinājumu skaits nav palielinājies (nolasa, izmantojot `gh api`; bez pilnvaras marķiera pārbaude tiek korekti izlaista) — atsvaidzināšanas biežumu un manuālo palaišanu skatiet tālāk sadaļā "CodeQL ratchet" | Jā | ### Uzdevums: `quality-extended` -Viss uzdevums ir konsultatīvs (`continue-on-error: true`). Uz npm balstītās ratchet pārbaudes -tiek izpildītas pilnībā; ārējie skeneri tiek instalēti, izmantojot `gh release download`, un paši izlaiž pārbaudi (exit 0), -ja binārais fails joprojām nav pieejams. +Viss uzdevums ir konsultatīvs (`continue-on-error: true`). Uz npm balstītās ratchet pārbaudes tiek izpildītas +pilnvērtīgi; ārējie skeneri tiek instalēti ar `gh release download` un paši izlaiž pārbaudi (izejas kods 0), +ja binārā faila joprojām nav. -| Skripts | Pārbauda | Bloķējošs | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | -| `check:circular-deps` | Nav ciklisku atkarību (dpdm) | **Konsultatīvs** | -| `check:bundle-size` | Pakotnes izmērs nepārsniedz ierobežojumu | **Konsultatīvs** | -| `check:secrets` | Noslēpumu skenēšana (gitleaks) — tiek izlaista, ja binārā faila nav | **Konsultatīvs** | -| `check:vuln-ratchet` | Atkarību ievainojamības (osv-scanner) nepasliktinās — tiek izlaista, ja binārā faila nav | **Konsultatīvs** | -| `check:workflows` | Darbplūsmu lint pārbaude (actionlint + zizmor); trūkstoši/bojāti skeneri, nederīgi pārskati vai trūkstošs ratchet bāzes līmenis izraisa INCOMPLETE kļūmi. Derīgi atradumi tiek apstrādāti atbilstoši izvēlētajai stingrajai/konsultatīvajai/ratchet politikai | Izpilde ir obligāta; zizmor ratchet pārbaude CI vidē ir bloķējoša | -| `check:openapi-breaking` | Publiskā API līguma (`openapi.yaml`) nesaderīgas izmaiņas salīdzinājumā ar bāzes zaru (oasdiff) — izvada `openapiBreaking=N`; tiek izlaista, ja oasdiff nav pieejams vai bāzes specifikāciju nevar atrisināt | **Konsultatīvs** | +| Skripts | Validē | Bloķējošs | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| `check:circular-deps` | Nav ciklisku atkarību (dpdm) | **Konsultatīvs** | +| `check:bundle-size` | Pakotnes izmērs nepārsniedz ierobežojumu | **Konsultatīvs** | +| `check:secrets` | Noslēpumu skenēšana (gitleaks) — tiek izlaista, ja binārā faila nav | **Konsultatīvs** | +| `check:vuln-ratchet` | Atkarību ievainojamību (osv-scanner) stāvoklis nav pasliktinājies — tiek izlaista, ja binārā faila nav | **Konsultatīvs** | +| `check:workflows` | Darbplūsmu lint pārbaude (actionlint + zizmor); trūkstoši vai bojāti skeneri, nederīgi pārskati vai trūkstošs ratchet bāzes līmenis izraisa INCOMPLETE kļūmi. Derīgi atradumi tiek apstrādāti saskaņā ar izvēlēto stingro/konsultatīvo/ratchet politiku | Izpilde obligāta; zizmor ratchet ir bloķējošs CI vidē | +| `check:openapi-breaking` | Publiskā API līguma (`openapi.yaml`) nesaderīgas izmaiņas salīdzinājumā ar bāzes zaru (oasdiff) — izvada `openapiBreaking=N`; tiek izlaista, ja oasdiff nav pieejams vai bāzes specifikāciju nevar atrisināt | **Konsultatīvs** | ### Uzdevums: `docs-sync-strict` Tiek izpildīts katram PR uz `main`. Kļūmes gadījumā bloķē sapludināšanu. -| Skripts | Pārbauda | Bloķējošs | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- | -| `check:docs-all` | Meta-pārbaude, kas secīgi izpilda 6 tālāk norādītās apakšpārbaudes | Jā | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versiju konsekvenci | Jā | -| ↳ `check:docs-counts` | Tekstā norādītie skaitļi (nodrošinātāju skaits, migrāciju skaits utt.) atrodas faktisko skaitļu pakāpeniski paaugstināmā sliekšņa diapazonā | Jā | -| ↳ `check:env-doc-sync` | Katrs `.env.example` vides mainīgais ir dokumentēts dokumentācijas tabulā un otrādi | Jā | -| ↳ `check:deprecated-versions` | Dokumentācijā nav novecojušu versiju virkņu | Jā | -| ↳ `check:doc-links` | Dokumentācijas iekšējās markdown saites norāda uz reāliem failiem (`[text]`/`(path)` formā) | Jā | -| ↳ `check:fabricated-docs` | Dokumentācijā minētie maršruti, vides mainīgie, CLI komandas, āķu nosaukumi un failu ceļi pastāv kodu bāzē. Stingra pārbaude ar `--strict`; bez karodziņa kļūme nav bloķējoša. | Jā (CI vidē ar `--strict`) | -| `check:cli-i18n` | CLI komandu virknes ir ietvertas visos i18n lokalizāciju failos | Jā | -| `check:openapi-coverage` | OpenAPI specifikācija aptver vismaz pakāpeniski paaugstināmu reālo maršrutu minimālo slieksni | Jā | -| `check:openapi-security-tiers` | Drošības līmeņu anotācijas failā `openapi.yaml` atbilst klasifikācijām failā `routeGuard.ts` | **Konsultatīvs** | -| `check:openapi-routes` | Katrs ceļš failā `openapi.yaml` atbilst reālam `route.ts` failam (pret halucinācijām) | Jā | -| `check:docs-symbols` | Katra `/api/...` atsauce failos `docs/**/*.md` atbilst reālam `route.ts` failam (pret halucinācijām) | Jā | -| `i18n translation drift` | Neiztulkotas atslēgas i18n lokalizāciju failos — tikai brīdinājums | **Konsultatīvs** | +| Skripts | Pārbauda | Bloķējošs | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | Meta-vārteja, kas secīgi izpilda 6 tālāk norādītās apakšvārtejas | Jā | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versiju konsekvenci | Jā | +| ↳ `check:docs-counts` | Vai tekstā norādītie skaitļi (nodrošinātāju skaits, migrāciju skaits utt.) ir faktisko skaitļu pakāpeniski noteiktajā diapazonā | Jā | +| ↳ `check:env-doc-sync` | Vai katrs vides mainīgais failā `.env.example` ir dokumentēts dokumentācijas tabulā un otrādi | Jā | +| ↳ `check:deprecated-versions` | Vai dokumentācijā nav novecojušu versiju virkņu | Jā | +| ↳ `check:doc-links` | Vai iekšējās markdown saites dokumentācijā norāda uz reāliem failiem (`[text]`/`(path)` formā) | Jā | +| ↳ `check:fabricated-docs` | Vai dokumentācijā minētie maršruti, vides mainīgie, CLI komandas, āķu nosaukumi un failu ceļi pastāv kodu bāzē. Stingrā vārteja ar `--strict`; bez karoga kļūme ir nebloķējoša. | Jā (CI vidē ar `--strict`) | +| `check:cli-i18n` | Vai CLI komandu virknes ir visos i18n lokalizācijas failos | Jā | +| `check:openapi-coverage` | Vai OpenAPI specifikācija aptver vismaz pakāpeniski noteikto reālo maršrutu minimumu | Jā | +| `check:openapi-security-tiers` | Vai drošības līmeņu anotācijas failā `openapi.yaml` atbilst `routeGuard.ts` klasifikācijām | **Ieteikuma rakstura** | +| `check:openapi-routes` | Vai katrs ceļš failā `openapi.yaml` atbilst reālam `route.ts` (pret halucinācijām) | Jā | +| `check:docs-symbols` | Vai katra `/api/...` atsauce failos `docs/**/*.md` atbilst reālam `route.ts` (pret halucinācijām) | Jā | +| `i18n translation drift` | Netulkotas atslēgas i18n lokalizācijas failos — tikai brīdinājums | **Ieteikuma rakstura** | ### Darbs: `i18n-ui-coverage` -| Skripts | Pārbauda | Bloķējošs | -| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (iekļauts) | UI i18n atslēgu pārklājums ir ≥ 65% | Jā | -| `check-ui-value-drift` (iekļauts) | Pārrakstīta angļu valodas **vērtība** neatstāj novecojušu tulkojumu | Jā | -| `check-new-key-coverage` (iekļauts) | **Jauna** angļu valodas atslēga ir iztulkota katrā lokalizācijā — `__MISSING__:` marķieris tiek noraidīts | Jā | -| `check-translation-ratio` | Reālo tulkojumu attiecība katrā lokalizācijā (ārpus atļauto vienumu saraksta esošas lapas, kas ir identiskas angļu valodai, satur vietturus vai nav iztulkotas) nedrīkst pārsniegt `config/quality/i18n-translation-baseline.json` + pielaidi | **Konsultatīvs** | +| Skripts | Pārbauda | Bloķējošs | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `check-ui-keys-coverage` (iekļauts) | Vai UI i18n atslēgu pārklājums ir ≥ 65% | Jā | +| `check-ui-value-drift` (iekļauts) | Vai pārrakstīta angļu valodas **vērtība** neatstāj novecojušu tulkojumu | Jā | +| `check-new-key-coverage` (iekļauts) | Vai **jauna** angļu valodas atslēga ir iztulkota katrā lokalizācijā — marķieris `__MISSING__:` tiek noraidīts | Jā | +| `check-translation-ratio` | Reālo tulkojumu attiecība katrā lokalizācijā (angļu valodai identiskas / vietturu / trūkstošas lapas ārpus atļauto elementu saraksta) nedrīkst pārsniegt `config/quality/i18n-translation-baseline.json` + pielaidi | **Ieteikuma rakstura** | -Nepieciešams `fetch-depth: 0` — vērtību novirzes pārbaude salīdzina `en.json` ar apvienošanas bāzi. +Nepieciešams `fetch-depth: 0` — vērtību novirzes vārteja salīdzina `en.json` ar sapludināšanas bāzi. -#### `check-ui-value-drift` — novecojušu tulkojumu pārbaude +#### `check-ui-value-drift` — novecojušu tulkojumu vārteja -Atklāj to vienu i18n regresijas veidu, kuru citas pārbaudes strukturāli nespēj konstatēt: angļu valodas vērtība -tiek pārrakstīta, bet no _iepriekšējā_ angļu teksta atvasinātie tulkojumi paliek nemainīti, tādēļ -lietotāji, kuri nelieto angļu valodu, turpina lasīt pārliecinoši formulētu, bet nu jau nepareizu tekstu. +Atklāj vienu i18n regresijas veidu, ko pārējās vārtejas strukturāli nespēj pamanīt: angļu valodas vērtība +tiek pārrakstīta, bet no _iepriekšējā_ angļu valodas teksta atvasinātie tulkojumi paliek, tāpēc +lietotāji, kuri nelieto angļu valodu, turpina lasīt pārliecinoši formulētu, taču tagad nepareizu tekstu. -Tas patiešām nonāca laidienā. `oauthModal.googleOAuthWarning` tika pārrakstīts, kad tika ieviests Antigravity -pieteikšanās palīgs (#5203); **39 no 43 lokalizācijām** saglabāja tekstu, kas operatoriem norādīja „nokopēt -pilno URL un ielīmēt to zemāk” — šim nodrošinātājam šādu plūsmu nav iespējams pabeigt. Tas +Tas tiešām nonāca laidienā. `oauthModal.googleOAuthWarning` tika pārrakstīts, kad tika ieviests Antigravity +pieteikšanās palīgs (#5203); **39 no 43 lokalizācijām** saglabāja tekstu, kas operatoriem lika „kopēt +pilno URL un ielīmēt to tālāk” — šī plūsma attiecīgajam nodrošinātājam nav izpildāma. Tas palika nepamanīts līdz #8463, jo: -- `sync-ui-keys` aizpilda tikai **neesošas** atslēgas, bet nekad neatjaunina **novecojušas**; -- `check-ui-keys-coverage` uzskaita atslēgas _esamību_, tādēļ novecojis tulkojums tiek uzskatīts par pārklātu; +- `sync-ui-keys` aizpilda tikai **trūkstošas** atslēgas, bet nekad neatjaunina **novecojušas**; +- `check-ui-keys-coverage` uzskaita atslēgas _esamību_, tāpēc novecojis tulkojums tiek uzskatīts par segtu; - `check-translation-drift` izseko `docs/i18n//**.md` dokumentācijas spoguļkopijas — - tas nekad nelasa `src/i18n/messages/*.json`. Darbā `docs-sync-strict` šī pārbaude ir bloķējoša kopš - 2026-09 atkārtotās sinhronizācijas: rediģējiet pamatdokumentu → `npm run i18n:run -- --files=` (sadaļas līmenī, ātri). + tas nekad nelasa `src/i18n/messages/*.json`. Bloķējošs darbā `docs-sync-strict` kopš + 2026-09 atkārtotās sinhronizācijas: rediģējiet pamatdokumentu → `npm run i18n:run -- --files=` (sadaļas līmenī, ar zemām izmaksām). -**Ņem vērā izmaiņu starpību, nevis balstās uz etalonu.** Tas salīdzina `en.json` sapludināšanas bāzes punktā ar -darba koku; katrai atslēgai, kuras angļu valodas vērtība ir mainījusies, ikviena lokalizācija, kurā joprojām ir -neskarts tulkojums, tiek uzskatīta par novecojušu. Tas apzināti **iesaldē iepriekš pastāvējušo parādu** — izmaiņu -starpība nevar atklāt, no kura vecā angļu teksta ir radies sen pastāvošs tulkojums, tāpēc pārbaude vērtē -tikai to, ko skar pašreizējās izmaiņas. Alternatīvai pieejai (katras atslēgas jaucējvērtību etalonam) būtu nepieciešams -~600 KB ģenerēts fails, kas ir 3× lielāks par lielāko esošo etalonu un tiktu mainīts katrā i18n PR. +**Ņem vērā izmaiņas, nevis balstās uz bāzes stāvokli.** Tas salīdzina `en.json` sapludināšanas bāzes punktā ar +darba koku; katrai atslēgai, kuras angļu valodas vērtība ir mainījusies, jebkura lokalizācija, kurā joprojām ir +neskarts tulkojums, ir novecojusi. Tas apzināti **iesaldē iepriekš pastāvošo parādu** — izmaiņu salīdzinājums +nevar atklāt, no kuras vecās angļu valodas versijas ir radies ilgstoši pastāvošs tulkojums, tāpēc pārbaude vērtē +tikai to, ko skar pašreizējās izmaiņas. Alternatīva (katras atslēgas jaucējvērtību bāzes fails) prasītu +~600 KB ģenerētu failu, kas ir 3× lielāks par lielāko esošo bāzes failu un tiktu mainīts katrā i18n PR. To var izpildīt divos veidos: 1. atjaunināt skartos tulkojumus vai -2. iestatīt tos uz `__MISSING__:` — izpildlaikā tad tiek parādīts izlabotais teksts angļu valodā +2. iestatīt tos uz `__MISSING__:` — izpildlaikā tad tiek nodrošināts izlabotais teksts angļu valodā (`src/i18n/request.ts::deepMergeFallback`, #7258), un atslēga tiek ievietota tulkošanas rindā. Ja ir mainījusies virknes **nozīme**, ieteicams **pārdēvēt atslēgu**: jauna atslēga nevar mantot -novecojušu tulkojumu. Šādu pieeju izmantoja #8463. +novecojušu tulkojumu. Šo pieeju izmantoja #8463. ```bash npm run i18n:check-value-drift # stingrā pārbaude (to izpilda CI) -npm run i18n:check-value-drift:warn # tikai ziņošana +npm run i18n:check-value-drift:warn # tikai ziņojums BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Beidz darbu ar kodu 0 un `SKIP reason=base-unresolved`, ja bāzes katalogu nevar nolasīt (sekls -klons bez bāzes atsauces), tāpat kā `check-openapi-breaking`. +Beidzas ar kodu 0 un `SKIP reason=base-unresolved`, ja bāzes katalogu nevar nolasīt (sekls +klons bez bāzes atsauces), atbilstoši `check-openapi-breaking` darbībai. ### Uzdevums: `i18n` Pilna i18n validācijas matrica (viens uzdevums katrai lokalizācijai). Viss uzdevums ir konsultatīvs. -| Skripts | Pārbauda | Bloķēšana | +| Skripts | Pārbauda | Bloķējošs | | ------------------------------- | ---------------------------------------- | ------------------------------------------------------------ | -| `validate_translation.py quick` | Tulkojuma pilnīgumu katrai lokalizācijai | **Konsultatīva** (`continue-on-error: true` visam uzdevumam) | +| `validate_translation.py quick` | Tulkojuma pilnīgumu katrai lokalizācijai | **Konsultatīvs** (`continue-on-error: true` visam uzdevumam) | ### Uzdevums: `pr-test-policy` Tiek izpildīts tikai izmaiņu pieprasījumiem. -| Skripts | Pārbauda | Bloķēšana | +| Skripts | Pārbauda | Bloķējošs | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | PR, kas maina produkcijas kodu mapēs `src/`, `open-sse/`, `electron/` vai `bin/`, ir jāiekļauj vai jāatjaunina testi (Stingrais noteikums #8) | Jā | -| `check:test-masking` | Mainītie testu faili nesamazina kopējo apgalvojumu skaitu un nepievieno `assert.ok(true)` tautoloģijas | Jā | -| `check:pr-evidence` | PR aprakstā ir minēti izmaiņu testēšanas/VPS pierādījumi (automatizē Stingro noteikumu #18, pārmeklējot PR tekstu — trausli, skatiet neizdarīto darbu sarakstu) | Jā | +| `check:pr-test-policy` | PR, kas maina produkcijas kodu mapēs `src/`, `open-sse/`, `electron/` vai `bin/`, ir jāiekļauj vai jāatjaunina testi (stingrais noteikums #8) | Jā | +| `check:test-masking` | Mainītie testu faili nesamazina kopējo neto apgalvojumu skaitu un nepievieno `assert.ok(true)` tautoloģijas | Jā | +| `check:pr-evidence` | PR aprakstā ir norādīti izmaiņu testēšanas/VPS pierādījumi (automatizē stingro noteikumu #18, meklējot PR tekstā — trausli, skatiet neizpildīto darbu sarakstu) | Jā | ### Uzdevums: `test-vitest` Tiek izpildīts pēc `build`. Kļūmes gadījumā bloķē sapludināšanu. -| Komplekts | Pārbauda | Bloķēšana | -| ---------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP serveri (110 rīki), autoCombo, kešatmiņu — vitest izpildītājs | Jā | -| `test:vitest:ui` | UI komponentu testus — vitest izpildītājs | **Bloķē** — iepriekš pastāvošās kļūmes ir nepārprotami izslēgtas failā `vitest.config.ts`; jaunas kļūmes izraisa uzdevuma kļūmi | +| Komplekts | Pārbauda | Bloķējošs | +| ---------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP serveri (110 rīki), autoCombo, kešatmiņu — vitest izpildītājs | Jā | +| `test:vitest:ui` | UI komponentu testus — vitest izpildītājs | **Bloķējošs** — iepriekš pastāvošās kļūmes ir skaidri izslēgtas failā `vitest.config.ts`; jaunas kļūmes izraisa uzdevuma kļūmi | ### Nakts darbplūsmas (ieplānotas, konsultatīvas) Tās tiek izpildītas pēc cron grafika (un ar `workflow_dispatch`), bet nekad PR ietvaros. Visas ir konsultatīvas. -| Darbplūsma | Pārbauda | Bloķēšana | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | fast-check īpašību testus ar nejaušu sākumvērtību un lielu izpildes reižu skaitu | **Konsultatīva** | -| `nightly-resilience` | kaudzes pieauguma pārbaudi, haosa kļūmju ievadīšanu, k6 slodzes/ilgstošas slodzes testus | **Konsultatīva** | -| `nightly-llm-security` | promptfoo injekciju aizsardzību (bloķēšanas režīmā) + garak zondes (tiek izlaistas bez pakalpojuma sniedzēja noslēpuma) | **Konsultatīva** | -| `nightly-schemathesis` | OpenAPI līguma izpludināšanas testēšanu (schemathesis) pret aktīvu OmniRoute, izmantojot `docs/openapi.yaml` — atklāj specifikācijas pārkāpumus / neapstrādātas 500 kļūdas (8. fāze B.4) | **Konsultatīva** | -| `nightly-mutation` | Stryker mutāciju testēšanas rezultātu ātro vienībtestu posmā — izdzīvojušās mutācijas atklāj vājus apgalvojumus | **Konsultatīva** | -| `nightly-compat` | Node dzinēja saderības matricu visos atbalstītajos `engines.node` diapazonos | **Konsultatīva** | +| Darbplūsma | Pārbauda | Bloķējoša | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | fast-check īpašību testus ar nejaušu sākumvērtību un lielu izpildes reižu skaitu | **Konsultatīva** | +| `nightly-resilience` | kaudzes pieauguma pārbaudi, haosa kļūmju injicēšanu, k6 slodzes/ilgstošas slodzes testus | **Konsultatīva** | +| `nightly-llm-security` | promptfoo injekciju aizsardzību (bloķēšanas režīmā) + garak pārbaudes (tiek izlaistas bez pakalpojuma sniedzēja noslēpuma) | **Konsultatīva** | +| `nightly-schemathesis` | OpenAPI līguma izpludināšanas testēšanu (schemathesis) pret aktīvu OmniRoute, izmantojot `docs/openapi.yaml` — atklāj specifikācijas pārkāpumus / neapstrādātas 500 kļūdas (8. posms B.4) | **Konsultatīva** | +| `nightly-mutation` | Stryker mutāciju testēšanas rezultātu ātrajā vienību testu joslā — izdzīvojušās mutācijas atklāj vājus apgalvojumus | **Konsultatīva** | +| `nightly-compat` | Node dzinēja saderības matricu atbalstītajos `engines.node` diapazonos | **Konsultatīva** | --- @@ -544,43 +546,43 @@ savienojuma kļūdu un nekad nepārtrauc sesijas. --- -## Racionalizācijas neizdarīto darbu saraksts (ROI pārskatīšana — 9. fāzes 3. vilnis) +## Racionalizācijas neizdarīto darbu saraksts (ROI pārskats — 9. fāze, 3. vilnis) -Šis uzskaitījums 2026-06-17 tika salīdzināts ar `ci.yml` (iepriekšējā versijā nebija iekļauti +Šis inventārs 2026-06-17 tika saskaņots ar `ci.yml` (iepriekšējā versijā bija izlaisti `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Saskaņotās kopas ROI pārskatīšanā -tika identificēti tālāk minētie racionalizācijas kandidāti. **Apvienošana ir mehāniska CI -izmaiņa; statusa maiņa/atmešana ir politikas lēmums, kas atstāts operatora ziņā.** Nekas no tālāk -minētā vēl nav ieviests. +`check:codeql-ratchet`, `check:pr-evidence`). Saskaņotās kopas ROI pārskatā +tika identificēti tālāk norādītie racionalizācijas kandidāti. **Apvienošanas ir mehāniskas CI +izmaiņas; pārslēgšanas/atmešanas ir politikas lēmumi, kas atstāti operatora ziņā.** Nekas no tālāk minētā +vēl nav piemērots. **Iepriekš nav dokumentēti arī** (konsultatīvi, zems signāla līmenis): `docs-lint` darbs -(markdownlint + Vale, visam darbam iestatīts `continue-on-error`) un savrupās skeneru darbplūsmas -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ir norādīts -`quality-baseline.json`, taču `ci.yml` tas nav piesaistīts bloķējošam sliekšņa mehānismam — šis rādītājs -pašlaik ir bāreņrādītājs. - -### Apvienošana / dublikātu novēršana (mehāniska, zemāks risks) - -Katrs kandidāts 2026-06-17 tika pārbaudīts pret aktuālo kontroles statusu (uzticies, bet pārbaudi); -vairāki „acīmredzami” apvienošanas gadījumi izrādījās slēpj parādu un **nav** tieši aizstājēji. - -- **`check:docs-sync` tiek izpildīts divreiz** — atsevišķi `lint` darbā un vēlreiz `check:docs-all` (`docs-sync-strict`) ietvaros, kā arī husky pirmsiesniegšanas āķī. ✅ **PABEIGTS** — atsevišķā izsaukšana no `lint` ir noņemta. -- **CVE skenēšana** — ❌ **NAV vienkārši apvienojama.** `audit:deps` izraisa kļūmi jebkuras augstas/kritiskas CVE gadījumā; `check:vuln-ratchet` (osv) izraisa kļūmi tikai _regresijas_ gadījumā salīdzinājumā ar bāzes līmeni (pašlaik 1 MODERATE). Atšķirīga semantika — `audit:deps` atmešana likvidētu absolūto augsta/kritiska līmeņa kontroli. Saglabāt abus. -- **Ciklu noteikšana** — ❌ **NAV vienkārši apvienojama.** `check:circular-deps` (dpdm) ziņo par **91 ciklu** (tādēļ tā ir konsultatīva); to nevar padarīt bloķējošu, vispirms šos ciklus nenovēršot, un tās tvērums ir plašāks nekā sekmīgajai, rūpīgi atlasītajai `check:cycles`. Saglabāt `check:cycles` kā bloķējošu pārbaudi; 91 dpdm cikla novēršana ir atsevišķs neizdarīto darbu vienums. -- **Sarežģītība** — ✅ **PABEIGTS** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): viena ESLint caurskate, uzskaite pēc ruleId, lai ciklomātiskās sarežģītības+max-lines un kognitīvās sarežģītības bāzes līmeņi paliktu neatkarīgi; individuālās `check:complexity` / `check:cognitive-complexity` pārbaudes saglabātas lokālai `--update` lietošanai. -- **`/api` pret-halucināciju pārbaude** — ✅ **PABEIGTS** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): viena `src/app/api` failu sistēmas inventarizācija; openapi-routes + docs-symbols joprojām ziņo neatkarīgi; individuālās pārbaudes saglabātas lokālai izpildei. -- **`check:node-runtime` tiek izpildīts 11 darbos** — ⚠️ **zema ROI.** Katram ir atsevišķs izpildītājs, un pārbaude ilgst <1 s; kopējais ietaupījums būtu ~10 s, taču tiktu zaudēta vienkārša katra darba aizsardzība. Nav vērts radīt liekas izmaiņas. -- **`typecheck:noimplicit:core` CI lint pārbaudē** — ✅ **noņemts no lint darba** (bija konsultatīvs `continue-on-error`); bloķējošo tipu tvērumu nodrošina `typecheck:core` + `check:type-coverage`. Lokālais skripts saglabāts. - -### Statusa maiņa / lēmums (operatora politika) - -- `check:openapi-security-tiers` (konsultatīvs) — ❌ **NAV vienkārši padarāms par bloķējošu.** Tas beidz darbu ar kodu 0, taču brīdina, ka vairākiem `traffic-inspector` maršrutiem zem `LOCAL_ONLY_API_PREFIXES` trūkst anotācijas `x-loopback-only: true`. Lai to ieviestu kā obligātu pārbaudi, vispirms šīs anotācijas jāpievieno failam `openapi.yaml`. -- `typecheck:noimplicit:core` (konsultatīvs) — lielā mērā dublē bloķējošā `check:type-coverage` sliekšņa mehānisma funkcijas. Pārveidot par sliekšņa mehānismu vai atmest redundanto otro `tsc` izpildi. -- `test:vitest:ui` (tagad **bloķējošs**) — iepriekš pastāvošās kļūmes ir skaidri izslēgtas failā `vitest.config.ts`, izmantojot `// #8618` izsekošanas komentārus; jaunas kļūmes izraisa darba kļūmi. -- `check:secrets` (gitleaks, bloķējošs sliekšņa mehānisms, fiksēts pie 3 dokumentētiem kļūdaini pozitīviem rezultātiem) — iekļaut šos 3 atļauto vienumu sarakstā, lai sasniegtu 0, vai pazemināt līdz konsultatīvam statusam. Pārklājas ar GitHub iebūvēto noslēpumu skenēšanu + `check:public-creds`. -- `check:pr-evidence` (bloķējošs, meklē atbilstības PR apraksta tekstā) — augsts kļūdaini pozitīvu rezultātu risks; atmešana vājinātu stingrā noteikuma Nr. 18 izpildi, tādēļ tas ir īsts politikas lēmums. -- `semgrep` (konsultatīvs, savrupa darbplūsma) — OWASP kategorijās pārklājas ar CodeQL; piesaistīt tā bāzes līmeni sliekšņa mehānismam vai atmest. +(markdownlint + Vale, visam darbam iestatīts `continue-on-error`) un savrupās skenēšanas darbplūsmas +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ir ietverts +`quality-baseline.json`, bet nav piesaistīts bloķējošam sprūdratam failā `ci.yml` — šī metrika +pašlaik ir bāreņmetrika. + +### Apvienošana / dublikātu novēršana (mehāniski, zemāks risks) + +Katrs kandidāts 2026-06-17 tika pārbaudīts pret aktuālo vārtu stāvokli (uzticies, bet pārbaudi); +vairākas „acīmredzamas” apvienošanas tomēr slēpa tehnisko parādu un **nav** tīri, tieši aizstājēji. + +- **`check:docs-sync` tiek palaists divreiz** — atsevišķi `lint` darbā un vēlreiz `check:docs-all` (`docs-sync-strict`) ietvaros un husky pirmskomita āķī. ✅ **PABEIGTS** — atsevišķā izsaukšana `lint` darbā ir noņemta. +- **CVE skenēšana** — ❌ **NAV tīri apvienojama.** `audit:deps` izraisa stingru kļūmi jebkuras augstas/kritiskas CVE gadījumā; `check:vuln-ratchet` (osv) izraisa kļūmi tikai _regresijas_ gadījumā salīdzinājumā ar bāzes līmeni (pašlaik 1 MODERATE). Atšķirīga semantika — atmetot `audit:deps`, tiktu zaudēti absolūtie augstas/kritiskas nozīmības vārti. Paturēt abus. +- **Ciklu noteikšana** — ✅ **PABEIGTS** (#15159 G-01/G-02). Iepriekšējā tekstā `check:cycles` bija nosaukts par „zaļajiem, rūpīgi atlasītajiem” vārtiem, un to bloķējošais statuss tika pamatots ar to, ka `check:circular-deps` (dpdm) ziņoja par 91 ciklu. Šis zaļais statuss bija **kļūdaini zaļš**: `check:cycles` skenēja 5 apakšdirektorijus (450 failus), atpazina tikai statiskos `import|export … from` un atmeta katru `@/` un `@omniroute/open-sse/` specifikatoru, tādēļ tas nevarēja konstatēt dinamiskās importēšanas un aizstājvārdu ciklus, kas dominēja repozitorijā. Labots: tagad vārti apstaigā `src` + `open-sse` (5023 failus), apkopo specifikatorus no TypeScript AST (tādēļ `import("…")` tiek ieskaitīts, bet tipa pozīcijas `typeof import("…")` — netiek) un atrisina tsconfig `paths`. Tas atrod **14** ciklus, nevis 0. Tā kā 14 iepriekš pastāvošus ciklus nevar novērst vārtu PR ietvaros, `check:cycles` tagad ir **sprūdrats** (`--ratchet`, griesti `metrics.cycles.value = 14` failā `quality-baseline.json`, `direction: down`) — tas bloķē jebkuru _regresiju_, un ciklu skaits var tikai samazināties. CI izpilda `npm run check:cycles:ratchet`. Pakāpeniskā samazināšana notiek kopā ar **A-01**. `check:circular-deps` (dpdm) paliek konsultatīvs kā plašāks otrais viedoklis. +- **Sarežģītība** — ✅ **PABEIGTS** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): viena ESLint apstaigāšana, uzskaite pēc ruleId, lai ciklomātiskās sarežģītības+max-lines un kognitīvās sarežģītības bāzes līmeņi paliktu neatkarīgi; individuālie `check:complexity` / `check:cognitive-complexity` paliek lokālai `--update` izmantošanai. +- **`/api` prethalucināciju pārbaude** — ✅ **PABEIGTS** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): viena `src/app/api` failu sistēmas inventarizācija; openapi-routes + docs-symbols joprojām sniedz pārskatus neatkarīgi; individuālās pārbaudes paliek lokālai izpildei. +- **`check:node-runtime` tiek palaists 11 darbos** — ⚠️ **zema ROI.** Katrs izmanto atsevišķu izpildītāju, un pārbaude ilgst <1 s; kopējais ietaupījums ir ~10 s, taču tiktu zaudēta lēta katra darba aizsargpārbaude. Nav vērts radīt izmaiņu troksni. +- **`typecheck:noimplicit:core` CI lintēšanas darbā** — ✅ **noņemts no lintēšanas darba** (bija konsultatīvs `continue-on-error`); bloķējošo tipu virsmu nodrošina `typecheck:core` + `check:type-coverage`. Lokālais skripts ir saglabāts. + +### Pārslēgt / izlemt (operatora politika) + +- `check:openapi-security-tiers` (konsultatīvs) — ❌ **NAV tīri pārslēdzams.** Tas iziet ar kodu 0, bet brīdina, ka vairākiem `traffic-inspector` maršrutiem zem `LOCAL_ONLY_API_PREFIXES` trūkst anotācijas `x-loopback-only: true`. Lai to padarītu obligātu, vispirms šīs anotācijas jāpievieno failam `openapi.yaml`. +- `typecheck:noimplicit:core` (konsultatīvs) — lielākoties to aizstāj bloķējošais `check:type-coverage` sprūdrats. Pārslēgt uz sprūdratu vai atmest lieko otro `tsc` izpildi. +- `test:vitest:ui` (tagad **bloķējošs**) — iepriekš pastāvošās kļūmes ir tieši izslēgtas failā `vitest.config.ts` ar `// #8618` izsekošanas komentāriem; jaunas kļūmes izraisa darba kļūmi. +- `check:secrets` (gitleaks, bloķējošs sprūdrats, iesaldēts pie 3 dokumentētiem kļūdaini pozitīviem rezultātiem) — pievienot šos 3 atļauto vienumu sarakstam, lai sasniegtu 0, vai pazemināt līdz konsultatīvam statusam. Pārklājas ar GitHub iebūvēto slepeno datu skenēšanu + `check:public-creds`. +- `check:pr-evidence` (bloķējošs, meklē atbilstības PR apraksta prozas tekstā) — augsts kļūdaini pozitīvu rezultātu risks; atmešana vājinātu Stingrā noteikuma Nr. 18 izpildi, tāpēc šis ir īsts politikas lēmums. +- `semgrep` (konsultatīva savrupā pārbaude) — OWASP kategorijās pārklājas ar CodeQL; piesaistīt tā bāzes līmeni sprūdratam vai atmest. --- diff --git a/docs/i18n/ml/CONTRIBUTING.md b/docs/i18n/ml/CONTRIBUTING.md index 63053805f4f..af40eea32b4 100644 --- a/docs/i18n/ml/CONTRIBUTING.md +++ b/docs/i18n/ml/CONTRIBUTING.md @@ -394,22 +394,22 @@ Handler/executor-കൾക്കുള്ളിൽ, ക്ലയന്റില --- -## Pull Request ചെക്ക്ലിസ്റ്റ് +## പുൾ റിക്വസ്റ്റ് ചെക്ക്ലിസ്റ്റ് - [ ] ടെസ്റ്റുകൾ വിജയിക്കുന്നു (`npm test`) -- [ ] Linting വിജയിക്കുന്നു (`npm run lint`) -- [ ] Build വിജയിക്കുന്നു (`npm run build`) -- [ ] പുതിയ പൊതു function-ുകൾക്കും interface-ുകൾക്കും TypeScript type-ുകൾ ചേർത്തിട്ടുണ്ട് -- [ ] Hardcode ചെയ്ത secret-ുകളോ fallback മൂല്യങ്ങളോ ഇല്ല -- [ ] പൊതു അപ്സ്ട്രീം ക്രെഡൻഷ്യലുകൾ `resolvePublicCred()` വഴി ഉൾച്ചേർത്തിട്ടുണ്ട് ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) കാണുക), ഒരിക്കലും literal-ുകളായി ഉൾപ്പെടുത്തിയിട്ടില്ല -- [ ] പിശക് response-ുകൾ `buildErrorBody()` / `sanitizeErrorMessage()` വഴി കടന്നുപോകുന്നു — response body-കളിൽ അസംസ്കൃത stack trace-ുകൾ ഇല്ല ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) കാണുക) -- [ ] Shell command-ുകൾ (`exec` / `spawn`) runtime മൂല്യങ്ങൾ string interpolation വഴിയല്ല, `env` വഴിയാണ് കൈമാറുന്നത് -- [ ] എല്ലാ input-ുകളും Zod schema-കൾ ഉപയോഗിച്ച് സാധൂകരിച്ചിട്ടുണ്ട് -- [ ] ഉപയോക്താവിനെ ബാധിക്കുന്ന മാറ്റങ്ങൾക്ക് `changelog.d/{features|fixes|maintenance}/-.md`-ന് കീഴിൽ changelog **fragment** ചേർത്തിട്ടുണ്ട് ([`changelog.d/README.md`](./changelog.d/README.md) കാണുക) — `CHANGELOG.md` നേരിട്ട് തിരുത്തരുത്; release സമയത്ത് fragment-ുകൾ സമാഹരിക്കപ്പെടുന്നതിനാൽ PR-ുകൾക്കിടയിൽ ഒരിക്കലും conflict ഉണ്ടാകില്ല -- [ ] ഡോക്യുമെന്റേഷൻ പുതുക്കിയിട്ടുണ്ട് (ബാധകമെങ്കിൽ) -- [ ] പുതിയ CodeQL / Secret-Scanning alert-ുകൾ തുറന്നിട്ടില്ല, അല്ലെങ്കിൽ പ്രസക്തമായ `docs/security/` ഡോക്യുമെന്റ് പരാമർശിക്കുന്ന സാങ്കേതിക ന്യായീകരണത്തോടെ ഓരോന്നും നിരസിച്ചിട്ടുണ്ട് -- [ ] Child process-ുകൾ spawn ചെയ്യുന്ന route-ുകൾ (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts`-ൽ `isLocalOnlyPath()` ആയി വർഗ്ഗീകരിച്ചിട്ടുണ്ട് — [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md) കാണുക -- [ ] Commit സന്ദേശങ്ങളിൽ `Co-Authored-By` trailer-ുകൾ ഇല്ല — commit-ുകൾ repository ഉടമയുടെ Git identity-യിൽ മാത്രം ദൃശ്യമാകണം (Hard Rule #16) +- [ ] ലിന്റിംഗ് വിജയിക്കുന്നു (`npm run lint`) +- [ ] ബിൽഡ് വിജയിക്കുന്നു (`npm run build`) +- [ ] പുതിയ പൊതു ഫങ്ഷനുകൾക്കും ഇന്റർഫേസുകൾക്കും TypeScript ടൈപ്പുകൾ ചേർത്തിട്ടുണ്ട് +- [ ] ഹാർഡ്കോഡ് ചെയ്ത രഹസ്യങ്ങളോ ഫാൾബാക്ക് മൂല്യങ്ങളോ ഇല്ല +- [ ] പൊതു അപ്സ്ട്രീം ക്രെഡൻഷ്യലുകൾ ലിറ്ററലുകളായി ഒരിക്കലും ഉൾപ്പെടുത്താതെ `resolvePublicCred()` വഴി ഉൾപ്പെടുത്തിയിട്ടുണ്ട് ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) കാണുക) +- [ ] പിശക് പ്രതികരണങ്ങൾ `buildErrorBody()` / `sanitizeErrorMessage()` വഴി റൂട്ട് ചെയ്യുന്നു — പ്രതികരണ ബോഡികളിൽ അസംസ്കൃത സ്റ്റാക്ക് ട്രെയ്സുകൾ ഇല്ല ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) കാണുക) +- [ ] ഷെൽ കമാൻഡുകൾ (`exec` / `spawn`) റൺടൈം മൂല്യങ്ങൾ സ്ട്രിങ് ഇന്റർപൊളേഷൻ വഴിയല്ല, `env` വഴി കൈമാറുന്നു +- [ ] എല്ലാ ഇൻപുട്ടുകളും Zod സ്കീമകൾ ഉപയോഗിച്ച് സാധൂകരിച്ചിട്ടുണ്ട് +- [ ] ഉപയോക്താവിന് ദൃശ്യമാകുന്ന മാറ്റങ്ങൾക്കായി `changelog.d/{features|fixes|maintenance}/-.md` എന്നതിനു കീഴിൽ ചേഞ്ച്ലോഗ് **ഫ്രാഗ്മെന്റ്** ചേർത്തിട്ടുണ്ട് ([`changelog.d/README.md`](./changelog.d/README.md) കാണുക) — `CHANGELOG.md` നേരിട്ട് എഡിറ്റ് ചെയ്യരുത്; റിലീസ് സമയത്ത് ഫ്രാഗ്മെന്റുകൾ സമാഹരിക്കപ്പെടുന്നതിനാൽ PR-കൾ തമ്മിൽ ഒരിക്കലും വൈരുദ്ധ്യമുണ്ടാകില്ല +- [ ] ഡോക്യുമെന്റേഷൻ അപ്ഡേറ്റ് ചെയ്തിട്ടുണ്ട് (ബാധകമെങ്കിൽ) +- [ ] പുതിയ CodeQL / Secret-Scanning അലേർട്ടുകളൊന്നും സൃഷ്ടിച്ചിട്ടില്ല, അല്ലെങ്കിൽ പ്രസക്തമായ `docs/security/` ഡോക്യുമെന്റ് പരാമർശിക്കുന്ന സാങ്കേതിക ന്യായീകരണത്തോടെ ഓരോന്നും നിരസിച്ചിട്ടുണ്ട് +- [ ] ചൈൽഡ് പ്രോസസ്സുകൾ സൃഷ്ടിക്കുന്ന റൂട്ടുകൾ (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts`-ൽ `isLocalOnlyPath()` ആയി വർഗ്ഗീകരിച്ചിട്ടുണ്ട് — [കർശന നിയമം #15](docs/security/ROUTE_GUARD_TIERS.md) കാണുക +- [ ] കമ്മിറ്റ് സന്ദേശങ്ങളിൽ AI/ബോട്ട് `Co-authored-by` ട്രെയിലറുകളില്ല (കർശന നിയമം #16) — വീണ്ടും ഉപയോഗിച്ചിട്ടുള്ള പ്രവൃത്തിയുടെ ഉടമകളായ മനുഷ്യ സഹപ്രവർത്തകർക്ക് സാധാരണ `Co-authored-by: Name ` ട്രെയിലറുകൾ ഉപയോഗിച്ച് അംഗീകാരം നൽകിയിട്ടുണ്ട് --- diff --git a/docs/i18n/ml/docs/architecture/QUALITY_GATES.md b/docs/i18n/ml/docs/architecture/QUALITY_GATES.md index de3473e529a..9c09de08c0e 100644 --- a/docs/i18n/ml/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ml/docs/architecture/QUALITY_GATES.md @@ -17,198 +17,215 @@ ## ഗേറ്റ് ഇൻവെന്ററിയും നിർവഹണ പ്രൊഫൈലുകളും -### കാൻഡിഡേറ്റ് പ്രവേശനം +### സ്ഥാനാർഥി പ്രവേശനം -CI, Quality Gates വർക്ക്ഫ്ലോകൾ ഓരോന്നും സ്ഥിരമായൊരു വിധി പുറപ്പെടുവിക്കുന്നു: `Gate / CI`, `Gate / Quality`. -അവയുടെ പതിപ്പിട്ട പ്രവേശന നയം ഓരോ അപ്സ്ട്രീം ജോബിനെയും നിർബന്ധിതമോ ഉപദേശപരമോ ആയി പട്ടികപ്പെടുത്തുന്നു. -ബാധകമായ ഒരു നിർബന്ധിത ജോബ് വിജയിക്കണം: ലഭ്യമല്ലാത്തതോ റദ്ദാക്കിയതോ ഒഴിവാക്കിയതോ തീർപ്പാകാത്തതോ അജ്ഞാതമായതോ ആയ ഫലങ്ങൾക്ക് PASS സ്ഥിരീകരിക്കാനാവില്ല. സാധുവായ docs-only അല്ലെങ്കിൽ catalog-only വർഗ്ഗീകരണത്തിന് ഒരു കോഡ് ലെയ്ൻ ബാധകമല്ലാതാക്കാം; -ഒരു draft PR അംഗീകരിക്കപ്പെട്ട കാൻഡിഡേറ്റല്ല. `hotfix` ലേബൽ തെളിവിന്റെ ആവശ്യകത ഒഴിവാക്കുന്നില്ല. +CI, Quality Gates വർക്ക്ഫ്ലോകൾ ഓരോന്നും സ്ഥിരമായ ഒരു വിധി പുറപ്പെടുവിക്കുന്നു: `Gate / CI`, +`Gate / Quality`. അവയുടെ പതിപ്പിട്ട പ്രവേശന നയം, ഓരോ അപ്സ്ട്രീം ജോബിനെയും +നിർബന്ധിതമോ ഉപദേശപരമോ ആയി പട്ടികപ്പെടുത്തുന്നു. ബാധകമായ ഒരു നിർബന്ധിത ജോബ് വിജയിക്കണം: +ലഭ്യമല്ലാത്തത്, റദ്ദാക്കിയത്, ഒഴിവാക്കിയത്, തീർപ്പാകാത്തത്, അജ്ഞാതമായ ഫലങ്ങൾ എന്നിവയ്ക്ക് PASS +സ്ഥാപിക്കാനാവില്ല. സാധുവായ docs-only അല്ലെങ്കിൽ catalog-only വർഗ്ഗീകരണം ഒരു കോഡ് ലെയ്നെ +ബാധകമല്ലാതാക്കാം; ഒരു ഡ്രാഫ്റ്റ് PR സ്വീകാര്യമായ സ്ഥാനാർഥിയല്ല. `hotfix` ലേബൽ തെളിവിന്റെ +ആവശ്യകത ഒഴിവാക്കുന്നില്ല. രണ്ട് വർക്ക്ഫ്ലോകളും PR-കൾ, main/release ബ്രാഞ്ചുകളിലേക്കുള്ള പുഷുകൾ, മാനുവൽ ഡിസ്പാച്ച്, -merge-group ഇവന്റുകൾ എന്നിവ ഉൾക്കൊള്ളുന്നു. Push, dispatch, merge-group എന്നിവ പൂർണ്ണമായ തിരഞ്ഞെടുപ്പ് പ്രവർത്തിപ്പിക്കുന്നു. സാധാരണയായി self-hosted റണ്ണറുകൾ തിരഞ്ഞെടുക്കുന്ന ജോബുകൾക്ക് forks-ഉം merge groups-ഉം hosted റണ്ണറുകൾ ഉപയോഗിക്കുന്നു; റോളൗട്ടിന് മുമ്പ് മതിയായ hosted ശേഷി ഉറപ്പാക്കണം. - -ഓരോ JSON രസീതും ചെക്ക്ഔട്ട് ചെയ്ത SHA, വർക്ക്ഫ്ലോ റൺ, ശ്രമം എന്നിവ തിരിച്ചറിയുന്നു. -ചെക്ക്ഔട്ട്/event SHA പൊരുത്തക്കേട് CLI നിരസിക്കുന്നു. ഒരു പുതിയ ലെയ്നോ നീക്കംചെയ്ത ലെയ്നോ നിശ്ശബ്ദമായി അപ്രത്യക്ഷമാകാതിരിക്കാൻ വർക്ക്ഫ്ലോ ടെസ്റ്റുകൾ പോളിസി അംഗത്വത്തെ വിധി ജോബിന്റെ `needs` ലിസ്റ്റുമായി ബന്ധിപ്പിക്കുന്നു. -രസീതുകൾ അവയുടെ സ്വന്തം വർക്ക്ഫ്ലോയെ മാത്രമാണ് ഉൾക്കൊള്ളുന്നത്; പ്രസിദ്ധീകരണം, ഡിപ്ലോയ്മെന്റ്, നിലവിലുള്ള ഒരു ഉപദേശപരമായ സ്കാനറിന്റെ ആന്തരിക പ്രവർത്തനം എന്നിവയെ ഉൾക്കൊള്ളുന്നില്ല. ബ്രാഞ്ച് നിയമങ്ങളിൽ രണ്ട് ചെക്ക് നാമങ്ങളും സജീവമാക്കുന്നത് ഒരു പ്രത്യേക അഡ്മിനിസ്ട്രേറ്റീവ് മാറ്റമാണ്; ഈ ജോബുകൾ ചേർക്കുന്നതുകൊണ്ട് മാത്രം ഒരു ബ്രാഞ്ച് പരിരക്ഷിക്കപ്പെടുന്നില്ല. +merge-group ഇവന്റുകൾ എന്നിവ ഉൾക്കൊള്ളുന്നു. Push, dispatch, merge-group എന്നിവ പൂർണ്ണമായ +തിരഞ്ഞെടുപ്പ് പ്രവർത്തിപ്പിക്കുന്നു. സാധാരണയായി self-hosted റണ്ണറുകൾ തിരഞ്ഞെടുക്കുന്ന ജോബുകൾക്ക് +ഫോർക്കുകളും merge group-ുകളും hosted റണ്ണറുകൾ ഉപയോഗിക്കുന്നു; പുറത്തിറക്കുന്നതിന് മുമ്പ് +മതിയായ hosted ശേഷി പരിശോധിച്ചുറപ്പിക്കണം. + +ഓരോ JSON രസീതും ചെക്ക് ഔട്ട് ചെയ്ത SHA, വർക്ക്ഫ്ലോ റൺ, ശ്രമം എന്നിവ തിരിച്ചറിയുന്നു. +ചെക്ക്ഔട്ട്/event SHA പൊരുത്തക്കേട് CLI നിരസിക്കുന്നു. പുതിയതോ നീക്കംചെയ്തതോ ആയ ഒരു ലെയ്ൻ +നിശ്ശബ്ദമായി അപ്രത്യക്ഷമാകാതിരിക്കാൻ, വർക്ക്ഫ്ലോ ടെസ്റ്റുകൾ നയത്തിലെ അംഗത്വത്തെ വിധി ജോബിന്റെ +`needs` പട്ടികയുമായി ബന്ധിപ്പിക്കുന്നു. രസീതുകൾ അവയുടെ സ്വന്തം വർക്ക്ഫ്ലോയെ ഉൾക്കൊള്ളുന്നു; +പ്രസിദ്ധീകരണം, വിന്യാസം, അല്ലെങ്കിൽ നിലവിലുള്ള ഒരു ഉപദേശപരമായ സ്കാനറിന്റെ ആന്തരിക പ്രവർത്തനം +എന്നിവയെ അല്ല. ബ്രാഞ്ച് നിയമങ്ങളിൽ രണ്ട് ചെക്ക് പേരുകളും സജീവമാക്കുന്നത് വേറിട്ടൊരു +അഡ്മിനിസ്ട്രേറ്റീവ് മാറ്റമാണ്; ഈ ജോബുകൾ ചേർക്കുന്നതുകൊണ്ടുമാത്രം ഒരു ബ്രാഞ്ചിന് സംരക്ഷണം +ലഭിക്കില്ല. ### സ്റ്റാറ്റിക് സ്കാൻ ഇൻവെന്ററി -പതിപ്പിട്ട npm-alias ഇൻവെന്ററിയും static-scan അംഗത്വവും -`config/quality/gate-manifest.json`-ൽ സ്ഥിതിചെയ്യുന്നു. സ്ക്രിപ്റ്റ് നാമങ്ങളും കൃത്യമായ കമാൻഡുകളും `package.json`-നോട് ഒത്തുനോക്കി സാധൂകരിക്കാൻ `npm run check:gate-manifest` പ്രവർത്തിപ്പിക്കുക; ചേർക്കലുകൾ, നീക്കംചെയ്യലുകൾ, കമാൻഡ് വ്യതിയാനങ്ങൾ എന്നിവ ലോക്കൽ ഹുക്കിനെയും CI-യിലെ മാറ്റ-വർഗ്ഗീകരണ ജോബുകളെയും പരാജയപ്പെടുത്തും. -ഒരു alias എന്നത് ഒരു വർക്ക്ഫ്ലോ ജോബോ matrix instance-ഓ test case-ഓ അല്ല: ഈ എണ്ണങ്ങളെ പരസ്പരം മാറ്റിസ്ഥാപിക്കാവുന്നവയായി അവതരിപ്പിക്കരുത്. - -തിരഞ്ഞെടുത്ത aliases പ്രവർത്തിപ്പിക്കാതെ പരിശോധിക്കാൻ `npm run quality:scan -- --list` അല്ലെങ്കിൽ `npm run quality:scan:fast -- --list` ഉപയോഗിക്കുക. -റണ്ണർ npm entrypoint പ്രവർത്തിപ്പിക്കുന്നതിനാൽ അതിന്റെ runtime—കോൺഫിഗർ ചെയ്തിടത്ത് Bun ഉൾപ്പെടെ—നിലനിർത്തപ്പെടുന്നു. -ആ പ്രൊഫൈലുകൾക്ക് പുറത്തുള്ള aliases പ്രത്യേകം പ്രവർത്തിപ്പിക്കുന്നവയായി manifest രേഖപ്പെടുത്തുന്നു; read-only scan പ്രൊഫൈലുകളിൽ maintenance കമാൻഡുകൾ നിരോധിച്ചിരിക്കുന്നു. - -ഈ പ്രൊഫൈലുകൾ static scan മാത്രമാണ് ഉൾക്കൊള്ളുന്നത്. അവ product tests, -coverage, packaging, external checks, അല്ലെങ്കിൽ ഒരു കാൻഡിഡേറ്റിന്റെ സമ്പൂർണ്ണ release acceptance എന്നിവ സാക്ഷ്യപ്പെടുത്തുന്നില്ല. -വർക്ക്ഫ്ലോ പ്രവേശനം ലിങ്ക് ചെയ്ത `config/quality/admission-policy.json`, -`scripts/quality/admission-verdict.mjs` എന്നിവ ഉപയോഗിക്കുന്നു. Release-observer പ്രൊഫൈലുകൾ വേറിട്ടുതന്നെ തുടരുന്നു; -അവയുടെ ബാധകമായ ചെക്കുകളും രസീതുകളും സ്വതന്ത്രമായി പരിശോധിക്കുക. താഴെയുള്ള വിവരണാത്മക -ഇൻവെന്ററി ഒരു റഫറൻസാണ്, ഒരു ഗേറ്റ് യഥാർത്ഥത്തിൽ പ്രവർത്തിച്ചു എന്നതിനുള്ള തെളിവല്ല. - -സ്ക്രിപ്റ്റുകൾ `scripts/check/`-ലും (policy gates) `scripts/quality/`-ലും (ratchet engine) സ്ഥിതിചെയ്യുന്നു. -CI-യുടെ ആധികാരിക ഉറവിടം `.github/workflows/ci.yml` ആണ്. - -### Release PR ഫാസ്റ്റ്-പാത്ത് (`quality.yml`) - -`.github/workflows/quality.yml`, main/release PR-കൾ, protected-branch -pushes, dispatch, merge groups എന്നിവയിൽ CI-യെ പൂരകമാക്കുന്നു. PR-കൾ path-filtered fast checks ഉപയോഗിക്കുന്നു. സ്ഥിരമായി പ്രവർത്തനരഹിതമാക്കിയിരുന്ന duplicate build നീക്കംചെയ്തു; യഥാർത്ഥ build/package/boot ചെക്കുകൾ CI-യിൽ തുടരുന്നു. - -| ജോബ് | പരിധി | തടയുന്നത് | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `Docs Gates (fast-path)` | Docs/code PR-കൾ; API docs refs, docs-all | അതെ | -| `Fast Quality Gates` | Code PR-കൾ; static checks, typecheck, dashboard typecheck, ബാധിക്കപ്പെട്ട unit tests | അതെ | -| `Forgotten sibling tests` | Code PR-കൾ; മാറ്റിയ modules-ൽ നിന്ന് static consumers-ലേക്കും candidate sibling tests-ലേക്കും ട്രെയ്സ് ചെയ്യുന്നു; barrel, dynamic-import paths എന്നിവ referenced allowlist exceptions സഹിതം ഉപദേശപരമായ diagnostics ആയി റിപ്പോർട്ട് ചെയ്യുന്നു | **ഉപദേശപരം** | -| `Vitest (fast-path)` | Code PR-കൾ; fast vitest suite | അതെ | -| `Unit Tests fast-path` | Code PR-കൾ; 4-shard unit suite | അതെ | -| `No new ESLint warnings` | Code PR-കൾ; suppressions-aware lint guard | അതെ, forks ഉൾപ്പെടെ | -| `Merge integrity (changelog + generated skills)` | Non-draft PR-കൾ; changelog, generated skill sync | അതെ, forks ഉൾപ്പെടെ | - -#### മറന്നുപോയ sibling tests റിപ്പോർട്ട് - -`npm run check:forgotten-sibling-tests`, test-impact map-ന് പിന്നിലുള്ള import resolver പുനരുപയോഗിക്കുന്നു. -മാറ്റം വരുത്തിയ ഓരോ production module-നും, candidate -test pull-request diff-ൽ ഇല്ലെങ്കിൽ നിർണ്ണായകമായ -`changed module/symbol -> static consumer -> candidate sibling test` ശൃംഖലകൾ ഇത് റിപ്പോർട്ട് ചെയ്യുന്നു. ഏതെങ്കിലും blocking rollout-ന് മുമ്പുള്ള calibration-നായി Markdown സംഗ്രഹവും JSON ഫലവും -`forgotten-sibling-tests` വർക്ക്ഫ്ലോ artifact ആയി നിലനിർത്തുന്നു. +പതിപ്പിട്ട npm-alias ഇൻവെന്ററിയും സ്റ്റാറ്റിക്-സ്കാൻ അംഗത്വവും +`config/quality/gate-manifest.json`-ലാണ്. സ്ക്രിപ്റ്റ് പേരുകളും കൃത്യമായ കമാൻഡുകളും +`package.json`-നോട് ഒത്തുനോക്കി സാധൂകരിക്കാൻ `npm run check:gate-manifest` പ്രവർത്തിപ്പിക്കുക; +കൂട്ടിച്ചേർക്കലുകൾ, നീക്കംചെയ്യലുകൾ, കമാൻഡ് വ്യതിയാനം എന്നിവ ലോക്കൽ ഹുക്കിനെയും CI-യിലെ +മാറ്റ-വർഗ്ഗീകരണ ജോബുകളെയും പരാജയപ്പെടുത്തും. ഒരു alias എന്നത് വർക്ക്ഫ്ലോ ജോബോ, മാട്രിക്സ് +ഇൻസ്റ്റൻസോ, ടെസ്റ്റ് കേസോ അല്ല: ഈ എണ്ണങ്ങൾ പരസ്പരം മാറ്റിസ്ഥാപിക്കാവുന്നവയായി അവതരിപ്പിക്കരുത്. + +തിരഞ്ഞെടുത്ത alias-കൾ പ്രവർത്തിപ്പിക്കാതെ പരിശോധിക്കാൻ `npm run quality:scan -- --list` +അല്ലെങ്കിൽ `npm run quality:scan:fast -- --list` ഉപയോഗിക്കുക. റണ്ണർ npm എൻട്രിപോയിന്റ് +വിളിക്കുന്നതിനാൽ, അതിന്റെ റൺടൈം—കോൺഫിഗർ ചെയ്തിടത്ത് Bun ഉൾപ്പെടെ—നിലനിർത്തപ്പെടുന്നു. +ഈ പ്രൊഫൈലുകൾക്ക് പുറത്തുള്ള alias-കൾ പ്രത്യേകം അഭ്യർത്ഥിക്കപ്പെടുന്നവയായി മാനിഫെസ്റ്റ് +രേഖപ്പെടുത്തുന്നു; read-only സ്കാൻ പ്രൊഫൈലുകളിൽ പരിപാലന കമാൻഡുകൾ അനുവദനീയമല്ല. + +ഈ പ്രൊഫൈലുകൾ സ്റ്റാറ്റിക് സ്കാൻ മാത്രമാണ് ഉൾക്കൊള്ളുന്നത്. ഉൽപ്പന്ന ടെസ്റ്റുകൾ, കവറേജ്, +പാക്കേജിംഗ്, ബാഹ്യ പരിശോധനകൾ, അല്ലെങ്കിൽ ഒരു സ്ഥാനാർഥിയുടെ പൂർണ്ണ റിലീസ് സ്വീകാര്യത +എന്നിവയ്ക്ക് ഇവ സാക്ഷ്യപത്രം നൽകുന്നില്ല. വർക്ക്ഫ്ലോ പ്രവേശനം ബന്ധിപ്പിച്ചിരിക്കുന്ന +`config/quality/admission-policy.json`, `scripts/quality/admission-verdict.mjs` എന്നിവ +ഉപയോഗിക്കുന്നു. Release-observer പ്രൊഫൈലുകൾ വേറിട്ടുതന്നെ തുടരുന്നു; അവയ്ക്ക് ബാധകമായ +പരിശോധനകളും രസീതുകളും സ്വതന്ത്രമായി പരിശോധിക്കുക. ചുവടെയുള്ള ഗദ്യരൂപത്തിലുള്ള ഇൻവെന്ററി +ഒരു റഫറൻസാണ്, ഒരു ഗേറ്റ് യഥാർഥത്തിൽ പ്രവർത്തിച്ചു എന്നതിന്റെ തെളിവല്ല. + +സ്ക്രിപ്റ്റുകൾ `scripts/check/`-ലും (നയ ഗേറ്റുകൾ) `scripts/quality/`-ലും (റാച്ചറ്റ് എൻജിൻ) +സ്ഥിതിചെയ്യുന്നു. CI-യുടെ ആധികാരിക ഉറവിടം `.github/workflows/ci.yml` ആണ്. + +### റിലീസ് PR ഫാസ്റ്റ്-പാത്ത് (`quality.yml`) + +`.github/workflows/quality.yml`, main/release PR-കളിലും സംരക്ഷിത-ബ്രാഞ്ച് പുഷുകളിലും +dispatch, merge group എന്നിവയിലും CI-യെ പൂരകമാക്കുന്നു. PR-കൾ പാത്ത്-ഫിൽട്ടർ ചെയ്ത വേഗത്തിലുള്ള +പരിശോധനകൾ ഉപയോഗിക്കുന്നു. സ്ഥിരമായി പ്രവർത്തനരഹിതമാക്കിയിരുന്ന ഡ്യൂപ്ലിക്കേറ്റ് ബിൽഡ് +നീക്കംചെയ്തു; യഥാർഥ build/package/boot പരിശോധനകൾ CI-യിൽ തുടരുന്നു. + +| ജോബ് | വ്യാപ്തി | തടസ്സപ്പെടുത്തുന്നത് | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | Docs/code PR-കൾ; API docs റഫറൻസുകളും docs-all-ഉം | അതെ | +| `Fast Quality Gates` | Code PR-കൾ; സ്റ്റാറ്റിക് പരിശോധനകൾ, typecheck, dashboard typecheck, ബാധിക്കപ്പെട്ട unit ടെസ്റ്റുകൾ | അതെ | +| `Forgotten sibling tests` | Code PR-കൾ; മാറ്റംവന്ന മൊഡ്യൂളുകളിൽ നിന്ന് സ്റ്റാറ്റിക് ഉപഭോക്താക്കളിലേക്കും സാധ്യതയുള്ള sibling ടെസ്റ്റുകളിലേക്കും പിന്തുടരുന്നു; barrel, dynamic-import പാത്തുകൾ allowlist-ൽ പരാമർശിച്ചിട്ടുള്ള ഒഴിവാക്കലുകളോടെ ഉപദേശപരമായ ഡയഗ്നോസ്റ്റിക്കുകളായി റിപ്പോർട്ട് ചെയ്യുന്നു | **ഉപദേശപരം** | +| `Vitest (fast-path)` | Code PR-കൾ; വേഗത്തിലുള്ള vitest സ്യൂട്ട് | അതെ | +| `Unit Tests fast-path` | Code PR-കൾ; 4-shard unit സ്യൂട്ട് | അതെ | +| `No new ESLint warnings` | Code PR-കൾ; suppression-കളെ പരിഗണിക്കുന്ന lint ഗാർഡ് | അതെ, forks ഉൾപ്പെടെ | +| `Merge integrity (changelog + generated skills)` | ഡ്രാഫ്റ്റ് അല്ലാത്ത PR-കൾ; changelog, generated skill സമന്വയം | അതെ, forks ഉൾപ്പെടെ | + +#### മറന്നുപോയ sibling ടെസ്റ്റുകളുടെ റിപ്പോർട്ട് + +`npm run check:forgotten-sibling-tests`, test-impact മാപ്പിന് പിന്നിലുള്ള import resolver +വീണ്ടും ഉപയോഗിക്കുന്നു. മാറ്റംവന്ന ഓരോ production മൊഡ്യൂളിനും, സാധ്യതയുള്ള ടെസ്റ്റ് +pull-request diff-ൽ ഇല്ലാത്തപ്പോൾ, നിർണായകമായ +`changed module/symbol -> static consumer -> candidate sibling test` ശൃംഖലകൾ അത് റിപ്പോർട്ട് +ചെയ്യുന്നു. തടസ്സപ്പെടുത്തുന്ന രീതിയിലുള്ള ഏതെങ്കിലും rollout-നു മുമ്പുള്ള കാലിബ്രേഷനായി, +Markdown സംഗ്രഹവും JSON ഫലവും `forgotten-sibling-tests` വർക്ക്ഫ്ലോ ആർട്ടിഫാക്റ്റായി +നിലനിർത്തുന്നു. Barrel re-export-ുകളും dynamic import-ുകളും resolution diagnostics മാത്രമാണ്; അവ ഒരിക്കലും -blocking finding സൃഷ്ടിക്കില്ല. അവലോകനം ചെയ്ത exceptions -`config/quality/forgotten-sibling-allowlist.json`-ൽ നിലനിൽക്കുന്നു. ഓരോ entry-യും consumer-നെയും candidate -test-നെയും വ്യക്തമാക്കുകയും, നിർദ്ദിഷ്ടമായ ഒരു ന്യായീകരണം നൽകുകയും, ഒരു GitHub issue-ലേക്കോ pull request-ലേക്കോ link ചെയ്യുകയും വേണം. തെറ്റായ ഘടനയിലുള്ള entries -അനുവദിക്കപ്പെടില്ല. ഇല്ലാതാക്കിയ candidate test-നെയോ `.skip`/`.todo` ചേർക്കുന്ന diff-നെയോ exceptions-ന് ഒഴിവാക്കാനാവില്ല; -assertion ദുർബലപ്പെടുത്തലും മറ്റ് masking രീതികളും സ്വതന്ത്രമായി blocking ചെയ്യുന്ന -`check:test-masking` gate-ന്റെ നിയന്ത്രണത്തിൽ തുടരും. +തടസ്സപ്പെടുത്തുന്ന finding സൃഷ്ടിക്കില്ല. അവലോകനം ചെയ്ത exceptions +`config/quality/forgotten-sibling-allowlist.json`-ലാണ്. ഓരോ entry-യും consumer-ഉം candidate +test-ഉം വ്യക്തമാക്കുകയും, കൃത്യമായ കാരണം നൽകുകയും, ഒരു GitHub issue അല്ലെങ്കിൽ pull request-ലേക്ക് link ചെയ്യുകയും വേണം. തെറ്റായ രൂപത്തിലുള്ള entries fail +closed ചെയ്യും. ഇല്ലാതാക്കിയ candidate test-നെയോ `.skip`/`.todo` ചേർക്കുന്ന diff-നെയോ exceptions-ന് suppress ചെയ്യാനാവില്ല; +assertion ദുർബലപ്പെടുത്തലും മറ്റ് masking-ഉം സ്വതന്ത്രമായി merge തടയുന്ന +`check:test-masking` gate-ന്റെ പരിധിയിൽ തുടരും. ### Job: `lint` `main`-ലേക്കുള്ള ഓരോ PR-ലും പ്രവർത്തിക്കുന്നു. പരാജയപ്പെട്ടാൽ merge തടയുന്നു. -| Script (`npm run ...`) | പരിശോധിക്കുന്നത് | Blocking | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | Node.js version പിന്തുണയ്ക്കുന്ന പരിധിക്കുള്ളിലാണോ എന്ന് | അതെ | -| `check:cycles` | Circular import-ുകൾ — എല്ലാ `src/` + `open-sse/` module-ുകളും | അതെ | -| `check:route-validation:t06` | എല്ലാ route-ുകളിലും Zod schema-കൾ ഉണ്ടോ എന്ന് (Tier 6 policy) | അതെ | -| `check:any-budget:t11` | `@ts-expect-error // any`-യുടെ എണ്ണം budget കവിയുന്നില്ലെന്ന് (Tier 11 catraca) | അതെ | -| `check:provider-consistency` | `providers.ts`-ലെ ഓരോ provider-നും `providerRegistry.ts`-ൽ പൊരുത്തപ്പെടുന്ന ഒരു entry ഉണ്ട് (അതുപോലെ മറിച്ചും, allowlist-ന്റെ പരിധിക്കുള്ളിൽ) | ഉണ്ട് | -| `check:model-lifecycle` | കൈകൊണ്ട് പരിപാലിക്കുന്ന മൂന്ന് routing table-കൾ checked-in lifecycle snapshot-ുമായി (#11503) സ്ഥിരത പുലർത്തുന്നു: `REGISTRY`-ക്ക് route ചെയ്യാനാകുന്ന retired id ഒന്നിനും `FITNESS_TABLE` (`taskFitness.ts`) score നൽകുന്നില്ല; എല്ലാ `BUILT_IN_ALIASES` target-ുകളും `REGISTRY`-യിൽ ഉണ്ടായിരിക്കുകയും retired-id snapshot-ൽ ഇല്ലാതിരിക്കുകയും ചെയ്യുന്നു; ഇപ്പോഴും `REGISTRY`-യിലുള്ള എല്ലാ retired id-കളും forward ചെയ്യപ്പെട്ടവയോ `allowedRetiredInCatalog`-ൽ ചേർത്തവയോ ആണ്; കൂടാതെ `DEFAULT_DEGRADATION_MAP`-ലെ source-കളോ target-ുകളോ ആ snapshot-ൽ retired ആയി കാണപ്പെടുന്നില്ല. ഒരു model നിലവിൽ live upstream വഴി സേവിക്കപ്പെടുന്നു എന്ന് ഇത് തെളിയിക്കുന്നില്ല. Offline — `config/quality/model-lifecycle.json`-മായി താരതമ്യം ചെയ്യുന്നു; ഇത് `npm run quality:refresh-model-lifecycle` ഉപയോഗിച്ച് കൈകൊണ്ട് പുതുക്കുന്നു (network; CI-യുമായി ബന്ധിപ്പിച്ചിട്ടില്ല). `allowedRetiredInCatalog` ഒരു burn-down ratchet ആണ്: tracking issue ഉണ്ടെങ്കിൽ മാത്രം ഒരു entry ചേർക്കുക. | ഉണ്ട് | -| `check:fetch-targets` | client-side `src/`-ലെ ഓരോ `fetch("/api/...")`-ഉം യഥാർത്ഥ `route.ts`-ലേക്ക് resolve ചെയ്യുന്നു | ഉണ്ട് | -| `check:deps` | repo-യിലെ എല്ലാ `package.json`-കളിലുമുള്ള `npm install` ചെയ്യാവുന്ന എല്ലാ deps-ഉം `dependency-allowlist.json`-ൽ ഉണ്ട്; പുതുതായി ചേർത്ത unpinned അല്ലെങ്കിൽ slopsquatted package-ുകൾ flag ചെയ്യപ്പെടുന്നു | ഉണ്ട് | -| `audit:deps` | `npm audit` (root + electron) — high/critical advisory-കൾ ഇല്ല (osv `check:vuln-ratchet`-മായി overlap ചെയ്യുന്നു; Rationalization Backlog കാണുക) | ഉണ്ട് | -| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hash-ുകൾ, host override-ുകൾ ഇല്ല | ഉണ്ട് | -| `check:licenses` | പ്രൊഡക്ഷൻ ഡിപെൻഡൻസികൾക്കായുള്ള SPDX ലൈസൻസ് അനുവദനീയ പട്ടിക | അതെ | -| `check:tracked-artifacts` | ബിൽഡ് ആർട്ടിഫാക്റ്റുകളോ കമ്മിറ്റ് ചെയ്ത `node_modules` സിംലിങ്കുകളോ ഇല്ല (husky pre-commit-ലും പ്രവർത്തിക്കുന്നു; pre-push മനഃപൂർവം ലഘുവാക്കിയിരിക്കുന്നു — #6716) | അതെ | -| `check:ai-attribution` | PR കമ്മിറ്റുകളിലോ ശീർഷകത്തിലോ ബോഡിയിലോ AI/bot `Co-Authored-By` ട്രെയിലറോ AI-ജനറേഷൻ ഫൂട്ടറോ ഇല്ല — കർശന നിയമം #16 (`quality.yml`-ലെ PR→`release/**` fast-gates ലൂപ്പിൽ — ഇവന്റ് പേലോഡ് വായിക്കുന്നു, PR അല്ലാത്തവയിൽ ഒന്നും ചെയ്യുന്നില്ല — കൂടാതെ PR→`main`-നുള്ള `ci.yml` lint-ലെ PR-മാത്രം ഘട്ടത്തിലും; husky `commit-msg` ഹുക്കിലും; മനുഷ്യ സഹ-രചയിതാക്കളെ അനുവദിച്ചിരിക്കുന്നു; #14436) | -| `check:vitest-exclusions` | ഓരോ Vitest ഒഴിവാക്കലും ഒരു ട്രാക്കിംഗ് ഇഷ്യൂ വ്യക്തമാക്കുകയും `config/quality/vitest-exclusions.json`-ൽ ഉൾപ്പെട്ടിരിക്കുകയും വേണം (#13204) | അതെ | -| `check:file-size` | ഒരു സോഴ്സ് ഫയലും ഓരോ എക്സ്റ്റൻഷനുമുള്ള പരിധി കവിയരുത് (റാച്ചറ്റ്: ഫ്രീസ് ചെയ്ത വലിയ ഫയലുകൾ `frozen` പട്ടികയിൽ) | അതെ | -| `check:error-helper` | executors/handlers-ലെ പിശക് റെസ്പോൺസുകൾ `buildErrorBody()` / `sanitizeErrorMessage()` ഉപയോഗിക്കുന്നു (കർശന നിയമം #12) | അതെ | -| `check:migration-numbering` | Migration SQL ഫയലുകൾ ഇടവേളകളോ ആവർത്തനങ്ങളോ ഇല്ലാതെ ക്രമാനുഗതമായി നമ്പർ ചെയ്തിരിക്കുന്നു | അതെ | -| `check:public-creds` | `publicCreds.ts`-ന് പുറത്ത് ലിറ്ററൽ OAuth `client_id`/`client_secret` അല്ലെങ്കിൽ Firebase Web കീകൾ ഇല്ല (കർശന നിയമം #11) | അതെ | -| `check:db-rules` | `src/lib/db/` മൊഡ്യൂളുകൾക്ക് പുറത്ത് അസംസ്കൃത SQL ഇല്ല; `localDb.ts`-ൽ നിന്ന് ബാരൽ-ഇംപോർട്ടുകൾ ഇല്ല (കർശന നിയമങ്ങൾ #2/#5) | അതെ | -| `check:known-symbols` | അവയുടെ ഡിസ്പാച്ച് പട്ടികകളിൽ രജിസ്റ്റർ ചെയ്തിരിക്കുന്ന പ്രൊവൈഡർ എക്സിക്യൂട്ടറുകൾ, റൂട്ടിംഗ് തന്ത്രങ്ങൾ, ട്രാൻസ്ലേറ്ററുകൾ എന്നിവ ഡിസ്കിലെ ഫയലുകളുമായി പൊരുത്തപ്പെടുന്നു — അനാഥമായതോ പ്രഖ്യാപിക്കാത്തതോ ആയ സിംബലുകൾ ഇല്ല | അതെ | -| `check:route-guard-membership` | ചൈൽഡ് പ്രോസസ് ആരംഭിക്കുന്ന ഓരോ റൂട്ടും `isLocalOnlyPath()` ഉപയോഗിച്ച് വർഗ്ഗീകരിച്ചിരിക്കുന്നു (കർശന നിയമങ്ങൾ #15/#17) | അതെ | -| `check:test-discovery` | റിപ്പോസിറ്ററിയിലെ ഓരോ `*.test.ts` / `*.spec.ts` ഫയലും കുറഞ്ഞത് ഒരു ടെസ്റ്റ് റണ്ണറെങ്കിലും ശേഖരിക്കുന്നു (റാച്ചറ്റ്: `test-discovery-baseline.json`-ലെ അനാഥ ഫയലുകളുടെ പട്ടികയ്ക്ക് ചുരുങ്ങാൻ മാത്രമേ കഴിയൂ) | അതെ | +| Script (`npm run ...`) | പരിശോധിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Node.js പതിപ്പ് പിന്തുണയ്ക്കുന്ന പരിധിക്കുള്ളിലാണെന്ന് | അതെ | +| `check:cycles` | `src/` + `open-sse/` മുഴുവനിലുമുള്ള circular import-ുകൾ (AST-അധിഷ്ഠിതം, tsconfig `paths` resolve ചെയ്തവ). Bare = advisory, cycle-ുകൾ പട്ടികപ്പെടുത്തുന്നു. `check:cycles:ratchet` (CI പ്രവർത്തിപ്പിക്കുന്നത്) `quality-baseline.json`-ലെ `metrics.cycles` പരിധിയെ എണ്ണം കവിയുമ്പോൾ തടയുന്നു — നിലവിൽ 14, `direction: down`, അതിനാൽ അത് കുറയാൻ മാത്രമേ കഴിയൂ (#15159 G-01/G-02) | അതെ (ratchet) | +| `check:route-validation:t06` | എല്ലാ route-ുകളിലും Zod schema-കൾ ഉണ്ടെന്ന് (Tier 6 policy) | അതെ | +| `check:any-budget:t11` | `@ts-expect-error // any` എണ്ണം budget കവിയുന്നില്ലെന്ന് (Tier 11 catraca) | അതെ | +| `check:provider-consistency` | `providers.ts`-ലെ ഓരോ provider-നും `providerRegistry.ts`-ൽ പൊരുത്തപ്പെടുന്ന ഒരു entry ഉണ്ട് (അതുപോലെ തിരിച്ചും, allowlist-ന്റെ പരിധിക്കുള്ളിൽ) | അതെ | +| `check:model-lifecycle` | കൈകൊണ്ട് പരിപാലിക്കുന്ന മൂന്ന് routing table-കൾ checked-in lifecycle snapshot-മായി (#11503) സ്ഥിരത പുലർത്തുന്നു: `REGISTRY`-ക്ക് route ചെയ്യാൻ കഴിയുന്ന retired id ഒന്നിനും `FITNESS_TABLE` (`taskFitness.ts`) score നൽകുന്നില്ല; ഓരോ `BUILT_IN_ALIASES` target-ഉം `REGISTRY`-യിൽ ഉണ്ടായിരിക്കുകയും retired-id snapshot-ൽ ഇല്ലാതിരിക്കുകയും ചെയ്യുന്നു; `REGISTRY`-യിൽ ഇപ്പോഴും ഉള്ള ഓരോ retired id-യും forward ചെയ്യപ്പെട്ടതോ `allowedRetiredInCatalog`-ൽ ലിസ്റ്റ് ചെയ്തതോ ആണ്; കൂടാതെ `DEFAULT_DEGRADATION_MAP`-ലെ source-ഓ target-ഓ ആ snapshot-ൽ retired ആയി കാണപ്പെടുന്നില്ല. ഒരു model നിലവിൽ live upstream വഴി serve ചെയ്യപ്പെടുന്നു എന്ന് ഇത് തെളിയിക്കുന്നില്ല. Offline — `config/quality/model-lifecycle.json`-മായി താരതമ്യം ചെയ്യുന്നു; ഇത് `npm run quality:refresh-model-lifecycle` ഉപയോഗിച്ച് കൈകൊണ്ട് പുതുക്കുന്നു (network; CI-യുമായി ബന്ധിപ്പിച്ചിട്ടില്ല). `allowedRetiredInCatalog` ഒരു burn-down ratchet ആണ്: tracking issue ഉണ്ടെങ്കിൽ മാത്രം ഒരു entry ചേർക്കുക. | അതെ | +| `check:fetch-targets` | client-side `src/`-ലെ ഓരോ `fetch("/api/...")`-ഉം യഥാർത്ഥ `route.ts`-ലേക്ക് resolve ചെയ്യുന്നു | അതെ | +| `check:deps` | repo-യിലെ ഓരോ `package.json`-ലുമുള്ള `npm install` ചെയ്യാവുന്ന എല്ലാ deps-ഉം `dependency-allowlist.json`-ൽ ഉണ്ട്; pin ചെയ്യാത്തതോ slopsquat ചെയ്തതോ ആയ പുതിയ package-കൾ flag ചെയ്യപ്പെടുന്നു | അതെ | +| `audit:deps` | `npm audit` (root + electron) — high/critical advisory-കൾ ഒന്നുമില്ല (osv `check:vuln-ratchet`-മായി overlap ചെയ്യുന്നു; Rationalization Backlog കാണുക) | അതെ | +| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hash-കൾ, host override-കൾ ഇല്ല | അതെ | +| `check:licenses` | പ്രൊഡക്ഷൻ ഡിപെൻഡൻസികൾക്കായുള്ള SPDX ലൈസൻസ് അനുവദനീയ പട്ടിക | അതെ | +| `check:tracked-artifacts` | ബിൽഡ് ആർട്ടിഫാക്റ്റുകളോ കമ്മിറ്റ് ചെയ്ത `node_modules` സിംലിങ്കുകളോ ഇല്ല (`husky` pre-commit-ലും പ്രവർത്തിക്കുന്നു; pre-push മനഃപൂർവം ലഘുവാക്കിയിരിക്കുന്നു — #6716) | അതെ | +| `check:ai-attribution` | PR കമ്മിറ്റുകളിലോ ശീർഷകത്തിലോ ബോഡിയിലോ AI/bot `Co-Authored-By` ട്രെയിലറോ AI-ജനറേഷൻ ഫൂട്ടറോ ഇല്ല — കർശന നിയമം #16 (`quality.yml`-ലെ PR→`release/**` fast-gates ലൂപ്പിൽ — ഇവന്റ് പേലോഡ് വായിക്കുന്നു, PR അല്ലെങ്കിൽ ഒന്നും ചെയ്യുന്നില്ല — കൂടാതെ PR→`main` എന്നതിനായുള്ള `ci.yml` lint-ലെ PR-മാത്രമായ ഘട്ടത്തിലും; `husky` `commit-msg` ഹുക്കിലും; മനുഷ്യ സഹ-രചയിതാക്കളെ അനുവദിച്ചിരിക്കുന്നു; #14436) | +| `check:vitest-exclusions` | ഓരോ Vitest ഒഴിവാക്കലും ഒരു ട്രാക്കിംഗ് ഇഷ്യൂ വ്യക്തമാക്കുകയും `config/quality/vitest-exclusions.json`-ൽ ഉൾപ്പെടുകയും ചെയ്യുന്നു (#13204) | അതെ | +| `check:file-size` | ഒരു സോഴ്സ് ഫയലും ഓരോ എക്സ്റ്റൻഷനുമുള്ള പരമാവധി പരിധി കവിയുന്നില്ല (റാച്ചറ്റ്: `frozen` പട്ടികയിലെ സ്ഥിരപ്പെടുത്തിയ വലിയ ഫയലുകൾ) | അതെ | +| `check:error-helper` | executors/handlers-ലെ പിശക് പ്രതികരണങ്ങൾ `buildErrorBody()` / `sanitizeErrorMessage()` ഉപയോഗിക്കുന്നു (കർശന നിയമം #12) | അതെ | +| `check:migration-numbering` | Migration SQL ഫയലുകൾ വിടവുകളോ തനിപ്പകർപ്പുകളോ ഇല്ലാതെ ക്രമാനുഗതമായി നമ്പർ ചെയ്തിരിക്കുന്നു | അതെ | +| `check:public-creds` | `publicCreds.ts`-ന് പുറത്ത് അക്ഷരാർഥത്തിലുള്ള OAuth `client_id`/`client_secret` അല്ലെങ്കിൽ Firebase Web കീകൾ ഇല്ല (കർശന നിയമം #11) | അതെ | +| `check:db-rules` | `src/lib/db/` മൊഡ്യൂളുകൾക്ക് പുറത്ത് അസംസ്കൃത SQL ഇല്ല; `localDb.ts`-ൽ നിന്ന് barrel-import-കൾ ഇല്ല (കർശന നിയമങ്ങൾ #2/#5) | അതെ | +| `check:known-symbols` | അവയുടെ dispatch ടേബിളുകളിൽ രജിസ്റ്റർ ചെയ്തിരിക്കുന്ന provider executors, routing strategies, translators എന്നിവ ഡിസ്കിലുള്ള ഫയലുകളുമായി പൊരുത്തപ്പെടുന്നു — അനാഥമായതോ പ്രഖ്യാപിക്കാത്തതോ ആയ symbols ഇല്ല | അതെ | +| `check:route-guard-membership` | child process സൃഷ്ടിക്കുന്ന എല്ലാ route-കളും `isLocalOnlyPath()` പ്രകാരം വർഗ്ഗീകരിച്ചിരിക്കുന്നു (കർശന നിയമങ്ങൾ #15/#17) | അതെ | +| `check:test-discovery` | repo-യിലെ ഓരോ `*.test.ts` / `*.spec.ts` ഫയലും കുറഞ്ഞത് ഒരു test runner എങ്കിലും ശേഖരിക്കുന്നു (ratchet: `test-discovery-baseline.json`-ലെ orphan list ചുരുങ്ങാൻ മാത്രമേ കഴിയൂ) | അതെ | | `check:agent-skills-sync` | സൃഷ്ടിച്ച agent-skills ആർട്ടിഫാക്റ്റുകൾ അവയുടെ സോഴ്സ് കാറ്റലോഗുമായി പൊരുത്തപ്പെടുന്നു (വ്യതിയാനമില്ല) | -| `check:provider-asset-provenance` | പ്രൊവൈഡർ ലോഗോകൾക്കും/അസറ്റുകൾക്കും രേഖപ്പെടുത്തിയ ഉറവിട എൻട്രി ഉണ്ടായിരിക്കുന്നു | -| `lint:json` | JSON കോൺഫിഗറേഷൻ ഫയലുകൾ പാഴ്സ് ചെയ്യപ്പെടുകയും repo lint നിയമങ്ങൾ പാലിക്കുകയും ചെയ്യുന്നു | -| `typecheck:core` | പിശകുകളില്ലാതെയുള്ള TypeScript കംപൈലേഷൻ (ഉപദേശാത്മക മുന്നറിയിപ്പുകൾ മാത്രം) | അതെ | -| `typecheck:noimplicit:core` | കർശനമായ `noImplicitAny` — ഭാവിയിലേക്കുള്ളത്; മുമ്പേ നിലവിലുള്ള നിരവധി call site-കൾക്ക് ഇപ്പോഴും annotations ആവശ്യമാണ് | **ഉപദേശാത്മകം** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**`-ലേക്ക് പരിമിതപ്പെടുത്തിയ `tsc` (#7033) — `typecheck:core`-ന്റെ പ്രത്യേകം തിരഞ്ഞെടുത്ത 27-ഫയൽ allowlist-ൽ dashboard TSX ഒന്നും ഉൾപ്പെടുന്നില്ല, കൂടാതെ `next build` അതിനെ ഒരിക്കലും type-check ചെയ്യുന്നുമില്ല (`next.config.mjs`-ൽ `ignoreBuildErrors: true` സജ്ജീകരിച്ചിരിക്കുന്നു); അതിനാൽ അവിടെയുള്ള orphaned-identifier regressions (#6625/#6909) CI-ക്ക് അദൃശ്യമായിരുന്നു. മാറ്റങ്ങൾ ഫ്രീസ് ചെയ്ത ഓരോ-ഫയൽ/ഓരോ-TS-code എണ്ണത്തിന്റെ baseline-നോട് (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols`-ലേതുപോലുള്ള അതേ stale-enforcement രീതി) താരതമ്യം ചെയ്യുന്നു — baseline ചെയ്ത എണ്ണത്തിനപ്പുറമുള്ള പുതിയ പിശകുകൾ മാത്രമാണ് gate പരാജയപ്പെടുത്തുന്നത്; മുമ്പേ നിലവിലുണ്ടായിരുന്ന ഒരു പിശക് പരിഹരിക്കുമ്പോൾ `--update` ഉപയോഗിച്ച് baseline കുറയ്ക്കുക. | അതെ | +| `check:provider-asset-provenance` | Provider ലോഗോകൾക്കും അസറ്റുകൾക്കും രേഖപ്പെടുത്തിയ provenance എൻട്രിയുണ്ട് | +| `lint:json` | JSON കോൺഫിഗ് ഫയലുകൾ പാഴ്സ് ചെയ്യപ്പെടുകയും repo lint നിയമങ്ങൾ പാലിക്കുകയും ചെയ്യുന്നു | +| `typecheck:core` | പിശകുകളില്ലാതെയുള്ള TypeScript കമ്പൈലേഷൻ (ഉപദേശക മുന്നറിയിപ്പുകൾ മാത്രം) | ഉണ്ട് | +| `typecheck:noimplicit:core` | കർശനമായ `noImplicitAny` — ഭാവിയെ ലക്ഷ്യമിട്ടുള്ളത്; മുമ്പേ നിലവിലുള്ള നിരവധി call site-കൾക്ക് ഇപ്പോഴും annotations ആവശ്യമാണ് | **ഉപദേശകം** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**`-ലേക്ക് പരിമിതപ്പെടുത്തിയ `tsc` (#7033) — `typecheck:core`-ന്റെ ശ്രദ്ധാപൂർവം തിരഞ്ഞെടുത്ത 27-ഫയൽ allowlist-ൽ dashboard TSX ഒന്നും ഉൾപ്പെടുന്നില്ല; കൂടാതെ `next build` അതിനെ ഒരിക്കലും type-check ചെയ്യുന്നുമില്ല (`next.config.mjs`-ൽ `ignoreBuildErrors: true` സജ്ജീകരിച്ചിരിക്കുന്നു). അതിനാൽ അവിടെയുള്ള orphaned-identifier regressions (#6625/#6909) CI-ക്ക് ദൃശ്യമായിരുന്നില്ല. ഓരോ ഫയലിലെയും/ഓരോ TS കോഡിലെയും എണ്ണം അടിസ്ഥാനമാക്കിയുള്ള, മാറ്റമില്ലാതെ സൂക്ഷിച്ച baseline-നോട് (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols`-ലെ അതേ stale-enforcement രീതി) വ്യത്യാസങ്ങൾ താരതമ്യം ചെയ്യുന്നു — baseline എണ്ണത്തിന് അപ്പുറമുള്ള പുതിയ പിശകുകൾ മാത്രം gate പരാജയപ്പെടുത്തും; മുമ്പേ നിലവിലുള്ള ഒരു പിശക് പരിഹരിക്കുമ്പോൾ `--update` ഉപയോഗിച്ച് baseline ക്രമേണ കുറയ്ക്കുക. | ഉണ്ട് | ### Job: `quality-gate` `test-coverage`-ന് ശേഷം പ്രവർത്തിക്കുന്നു. പരാജയപ്പെട്ടാൽ merge തടയുന്നു. -| സ്ക്രിപ്റ്റ് | സാധൂകരിക്കുന്നത് | തടയുന്നത് | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | -| `quality:collect` | `quality-metrics.json` സൃഷ്ടിക്കുന്നു (ESLint മുന്നറിയിപ്പുകളുടെ എണ്ണം, ലയിപ്പിച്ച ഷാർഡ് റിപ്പോർട്ടിൽ നിന്നുള്ള കവറേജ്) | അതെ (റാച്ചറ്റിന് മുമ്പുള്ളത്) | -| `quality:ratchet` | `quality-baseline.json`-ലെ ഓരോ മെട്രിക്കും പിന്നോട്ട് പോയിട്ടില്ല (ESLint മുന്നറിയിപ്പുകൾ ≤ ബേസ്ലൈൻ; കവറേജ് ≥ ബേസ്ലൈൻ) | അതെ | -| `check:duplication` | കോഡ് ഡ്യൂപ്ലിക്കേഷൻ (jscpd@4) `quality-baseline.json`-ലെ ബേസ്ലൈൻ കവിയുന്നില്ല | അതെ | -| `check:complexity` | ഫയൽ-തല സൈക്ലോമാറ്റിക് സങ്കീർണ്ണത പരിധി കവിയുന്നില്ല (കോർ ESLint `complexity` + `max-lines-per-function`) | അതെ | -| `check:cognitive-complexity` | കോഗ്നിറ്റീവ് സങ്കീർണ്ണത റാച്ചറ്റ് (`eslint-plugin-sonarjs`) — പ്രത്യേക ESLint പാസ്; CI ഇവ രണ്ടും ലയിപ്പിച്ച് ഒറ്റ `check:complexity-ratchets` ഘട്ടമായി പ്രവർത്തിപ്പിക്കുന്നു | അതെ | -| `check:dead-code` | ഉപയോഗിക്കാത്ത എക്സ്പോർട്ടുകൾ / ഫയലുകൾക്കായുള്ള റാച്ചറ്റ് (knip) ബേസ്ലൈനുമായി താരതമ്യപ്പെടുത്തുമ്പോൾ പിന്നോട്ട് പോകുന്നില്ല | അതെ | -| `check:compression-budget` | കംപ്രഷൻ ബെഞ്ച്മാർക്ക് ബജറ്റ് — ഓരോ എൻജിനിലെയും ടോക്കൺ-സേവിംഗ്സ് കുറഞ്ഞ പരിധികൾ പിന്നോട്ട് പോകരുത് | അതെ | -| `check:type-coverage` | ടൈപ്പ് ചെയ്ത ശതമാനത്തിനുള്ള റാച്ചറ്റ് (`type-coverage`) പിന്നോട്ട് പോകുന്നില്ല; `typecheck:noimplicit:core`-നെ ഏറെക്കുറെ ഉൾക്കൊള്ളുന്നു | അതെ | -| `check:codeql-ratchet` | തുറന്ന CodeQL അലേർട്ടുകളുടെ എണ്ണം പിന്നോട്ട് പോകുന്നില്ല (`gh api` വഴി വായിക്കുന്നു; ടോക്കൺ ഇല്ലെങ്കിൽ പ്രശ്നമില്ലാതെ ഒഴിവാക്കുന്നു) — പുതുക്കൽ ഇടവേളയ്ക്കും മാനുവൽ ട്രിഗറിനും: താഴെയുള്ള "CodeQL റാച്ചറ്റ്" കാണുക | അതെ | - -### ജോബ്: `quality-extended` - -മുഴുവൻ ജോബും ഉപദേശാത്മകമാണ് (`continue-on-error: true`). npm അടിസ്ഥാനമാക്കിയുള്ള റാച്ചറ്റുകൾ -യഥാർത്ഥത്തിൽ പ്രവർത്തിക്കുന്നു; ബാഹ്യ സ്കാനറുകൾ `gh release download` വഴി ഇൻസ്റ്റാൾ ചെയ്യുകയും ഒരു -ബൈനറി ഇപ്പോഴും ലഭ്യമല്ലെങ്കിൽ സ്വയം ഒഴിവാകുകയും ചെയ്യുന്നു (exit 0). - -| സ്ക്രിപ്റ്റ് | സാധൂകരിക്കുന്നത് | തടയുന്നത് | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -| `check:circular-deps` | സർക്കുലർ ഡിപെൻഡൻസികളില്ല (dpdm) | **ഉപദേശാത്മകം** | -| `check:bundle-size` | ബണ്ടിൽ വലുപ്പം പരിധി കവിയുന്നില്ല | **ഉപദേശാത്മകം** | -| `check:secrets` | രഹസ്യങ്ങളുടെ സ്കാനിംഗ് (gitleaks) — ബൈനറി ഇല്ലെങ്കിൽ ഒഴിവാക്കുന്നു | **ഉപദേശാത്മകം** | -| `check:vuln-ratchet` | ഡിപെൻഡൻസി ദുർബലതകൾ (osv-scanner) പിന്നോട്ട് പോകുന്നില്ല — ബൈനറി ഇല്ലെങ്കിൽ ഒഴിവാക്കുന്നു | **ഉപദേശാത്മകം** | -| `check:workflows` | വർക്ക്ഫ്ലോ ലിന്റ് (actionlint + zizmor); സ്കാനറുകൾ ഇല്ലാത്തതോ തകരാറിലായതോ ആണെങ്കിൽ, റിപ്പോർട്ടുകൾ അസാധുവാണെങ്കിൽ, അല്ലെങ്കിൽ റാച്ചറ്റ് ബേസ്ലൈൻ ഇല്ലെങ്കിൽ INCOMPLETE ആയി പരാജയപ്പെടുന്നു. സാധുവായ കണ്ടെത്തലുകൾ തിരഞ്ഞെടുത്ത കർശന/ഉപദേശാത്മക/റാച്ചറ്റ് നയം പിന്തുടരുന്നു | എക്സിക്യൂഷൻ നിർബന്ധം; CI-യിൽ zizmor റാച്ചറ്റ് തടയും | -| `check:openapi-breaking` | ബേസ് ബ്രാഞ്ചുമായി താരതമ്യപ്പെടുത്തിയുള്ള പൊതു API കരാറിലെ (`openapi.yaml`) ബ്രേക്കിംഗ് മാറ്റങ്ങൾ (oasdiff) — `openapiBreaking=N` സൃഷ്ടിക്കുന്നു; oasdiff ഇല്ലെങ്കിൽ അല്ലെങ്കിൽ ബേസ് സ്പെക് പരിഹരിക്കാനാകുന്നില്ലെങ്കിൽ ഒഴിവാക്കുന്നു | **ഉപദേശാത്മകം** | - -### ജോബ്: `docs-sync-strict` - -`main`-ലേക്കുള്ള ഓരോ PR-ലും പ്രവർത്തിക്കുന്നു. പരാജയപ്പെട്ടാൽ ലയനം തടയുന്നു. - -| സ്ക്രിപ്റ്റ് | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `check:docs-all` | താഴെയുള്ള 6 ഉപ-ഗേറ്റുകൾ ക്രമാനുഗതമായി പ്രവർത്തിപ്പിക്കുന്ന മെറ്റാ-ഗേറ്റ് | അതെ | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt പതിപ്പുകളുടെ സ്ഥിരത | അതെ | -| ↳ `check:docs-counts` | ഗദ്യത്തിലെ എണ്ണങ്ങൾ (പ്രൊവൈഡർമാരുടെ എണ്ണം, മൈഗ്രേഷനുകളുടെ എണ്ണം തുടങ്ങിയവ) യഥാർഥ എണ്ണങ്ങളുടെ റാച്ചറ്റ് പരിധിക്കുള്ളിലാണെന്ന് | അതെ | -| ↳ `check:env-doc-sync` | `.env.example`-ലെ എല്ലാ പരിസ്ഥിതി വേരിയബിളുകളും ഡോക്സ് പട്ടികയിൽ രേഖപ്പെടുത്തിയിട്ടുണ്ടെന്നും തിരിച്ചും അങ്ങനെ തന്നെയാണെന്നും | അതെ | -| ↳ `check:deprecated-versions` | ഡോക്സിൽ ഒഴിവാക്കിയ പതിപ്പ് സ്ട്രിങ്ങുകളൊന്നുമില്ലെന്ന് | അതെ | -| ↳ `check:doc-links` | ഡോക്സിലെ ആന്തരിക markdown ലിങ്കുകൾ യഥാർഥ ഫയലുകളിലേക്ക് പരിഹരിക്കപ്പെടുന്നുവെന്ന് (`[text]`/`(path)` രൂപം) | അതെ | -| ↳ `check:fabricated-docs` | ഡോക്സിൽ ഉദ്ധരിച്ചിരിക്കുന്ന റൂട്ടുകൾ, പരിസ്ഥിതി വേരിയബിളുകൾ, CLI കമാൻഡുകൾ, ഹുക്ക് പേരുകൾ, ഫയൽ പാതകൾ എന്നിവ കോഡ്ബേസിൽ നിലവിലുണ്ടെന്ന്. `--strict` വഴിയുള്ള ഹാർഡ് ഗേറ്റ്; ഫ്ലാഗ് ഇല്ലെങ്കിൽ സോഫ്റ്റ്-ഫെയിൽ. | അതെ (CI-യിൽ `--strict` വഴി) | -| `check:cli-i18n` | CLI കമാൻഡ് സ്ട്രിങ്ങുകൾ എല്ലാ i18n ലോക്കേൽ ഫയലുകളിലും ഉണ്ടെന്ന് | അതെ | -| `check:openapi-coverage` | യഥാർഥ റൂട്ടുകളുടെ റാച്ചറ്റ് ചെയ്ത ഏറ്റവും കുറഞ്ഞ പരിധിയെങ്കിലും OpenAPI സ്പെക് ഉൾക്കൊള്ളുന്നുവെന്ന് | അതെ | -| `check:openapi-security-tiers` | `openapi.yaml`-ലെ സുരക്ഷാ ടയർ വ്യാഖ്യാനങ്ങൾ `routeGuard.ts`-ലെ വർഗ്ഗീകരണങ്ങളുമായി പൊരുത്തപ്പെടുന്നുവെന്ന് | **ഉപദേശാത്മകം** | -| `check:openapi-routes` | `openapi.yaml`-ലെ ഓരോ പാതയും യഥാർഥ `route.ts`-ലേക്ക് പരിഹരിക്കപ്പെടുന്നുവെന്ന് (കെട്ടിച്ചമയ്ക്കൽ തടയൽ) | അതെ | -| `check:docs-symbols` | `docs/**/*.md`-ലെ ഓരോ `/api/...` പരാമർശവും യഥാർഥ `route.ts`-ലേക്ക് പരിഹരിക്കപ്പെടുന്നുവെന്ന് (കെട്ടിച്ചമയ്ക്കൽ തടയൽ) | അതെ | -| `i18n translation drift` | i18n ലോക്കേൽ ഫയലുകളിലെ വിവർത്തനം ചെയ്യാത്ത കീകൾ — മുന്നറിയിപ്പ് മാത്രം | **ഉപദേശാത്മകം** | +| സ്ക്രിപ്റ്റ് | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `quality:collect` | `quality-metrics.json` സൃഷ്ടിക്കുന്നു (ESLint മുന്നറിയിപ്പുകളുടെ എണ്ണം, ലയിപ്പിച്ച shard റിപ്പോർട്ടിൽ നിന്നുള്ള coverage) | അതെ (ratchet-ന് മുമ്പുള്ളത്) | +| `quality:ratchet` | `quality-baseline.json`-ലെ ഓരോ metric-ഉം മോശമായിട്ടില്ല (ESLint മുന്നറിയിപ്പുകൾ ≤ baseline; coverage ≥ baseline) | അതെ | +| `check:duplication` | കോഡ് ആവർത്തനം (jscpd@4) `quality-baseline.json`-ലെ baseline കവിയുന്നില്ല | അതെ | +| `check:complexity` | ഫയൽ-തല cyclomatic complexity പരിധി കവിയുന്നില്ല (core ESLint `complexity` + `max-lines-per-function`) | അതെ | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — പ്രത്യേക ESLint pass; CI ഇവ രണ്ടും ലയിപ്പിച്ച് ഒരൊറ്റ `check:complexity-ratchets` ഘട്ടമായി പ്രവർത്തിപ്പിക്കുന്നു | അതെ | +| `check:dead-code` | ഉപയോഗിക്കാത്ത exports / files ratchet (knip) baseline-നെ അപേക്ഷിച്ച് മോശമാകുന്നില്ല | അതെ | +| `check:compression-budget` | Compression benchmark budget — ഓരോ engine-ന്റെയും token-savings കുറഞ്ഞ പരിധികൾ മോശമാകരുത് | അതെ | +| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) മോശമാകുന്നില്ല; `typecheck:noimplicit:core`-നെ വലിയ തോതിൽ ഉൾക്കൊള്ളുന്നു | അതെ | +| `check:codeql-ratchet` | തുറന്ന CodeQL alert-ുകളുടെ എണ്ണം മോശമാകുന്നില്ല (`gh api` വഴി വായിക്കുന്നു; token ഇല്ലെങ്കിൽ തടസ്സമില്ലാതെ skip ചെയ്യുന്നു) — പുതുക്കൽ ഇടവേളയ്ക്കും manual trigger-നും: താഴെയുള്ള "CodeQL ratchet" കാണുക | അതെ | + +### Job: `quality-extended` + +മുഴുവൻ job-ഉം ഉപദേശാത്മകമാണ് (`continue-on-error: true`). npm അടിസ്ഥാനമാക്കിയുള്ള ratchet-ുകൾ +യഥാർത്ഥത്തിൽ പ്രവർത്തിക്കുന്നു; ബാഹ്യ scanner-ുകൾ `gh release download` വഴി install ചെയ്യുകയും binary +ഇപ്പോഴും ലഭ്യമല്ലെങ്കിൽ സ്വയം skip ചെയ്യുകയും ചെയ്യുന്നു (exit 0). + +| സ്ക്രിപ്റ്റ് | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| `check:circular-deps` | Circular dependency-കൾ ഇല്ല (dpdm) | **ഉപദേശാത്മകം** | +| `check:bundle-size` | Bundle വലുപ്പം പരിധി കവിയുന്നില്ല | **ഉപദേശാത്മകം** | +| `check:secrets` | രഹസ്യവിവരങ്ങൾക്കായുള്ള scanning (gitleaks) — binary ഇല്ലെങ്കിൽ skip ചെയ്യുന്നു | **ഉപദേശാത്മകം** | +| `check:vuln-ratchet` | Dependency vulnerability-കൾ (osv-scanner) മോശമാകുന്നില്ല — binary ഇല്ലെങ്കിൽ skip ചെയ്യുന്നു | **ഉപദേശാത്മകം** | +| `check:workflows` | Workflow lint (actionlint + zizmor); ലഭ്യമല്ലാത്ത/തകരാറിലായ scanner-ുകൾ, അസാധുവായ report-ുകൾ, അല്ലെങ്കിൽ ലഭ്യമല്ലാത്ത ratchet baseline എന്നിവ INCOMPLETE ആയി പരാജയപ്പെടുന്നു. സാധുവായ കണ്ടെത്തലുകൾ തിരഞ്ഞെടുത്ത strict/advisory/ratchet നയം പിന്തുടരുന്നു | നിർവഹണം നിർബന്ധം; CI-യിൽ zizmor ratchet തടസ്സപ്പെടുത്തുന്നു | +| `check:openapi-breaking` | അടിസ്ഥാന branch-നെ അപേക്ഷിച്ച് public API contract-ലുള്ള (`openapi.yaml`) breaking change-ുകൾ (oasdiff) — `openapiBreaking=N` സൃഷ്ടിക്കുന്നു; oasdiff ഇല്ലെങ്കിലോ അടിസ്ഥാന spec പരിഹരിക്കാനാകുന്നില്ലെങ്കിലോ skip ചെയ്യുന്നു | **ഉപദേശാത്മകം** | + +### Job: `docs-sync-strict` + +`main`-ലേക്കുള്ള ഓരോ PR-ലും പ്രവർത്തിക്കുന്നു. പരാജയപ്പെട്ടാൽ merge തടയുന്നു. + +| സ്ക്രിപ്റ്റ് | പരിശോധിക്കുന്നത് | തടയുന്നത് | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `check:docs-all` | താഴെയുള്ള 6 ഉപ-ഗേറ്റുകൾ ക്രമാനുസൃതമായി പ്രവർത്തിപ്പിക്കുന്ന മെറ്റാ-ഗേറ്റ് | അതെ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt പതിപ്പുകളുടെ സ്ഥിരത | അതെ | +| ↳ `check:docs-counts` | ഗദ്യത്തിലെ എണ്ണങ്ങൾ (പ്രൊവൈഡർ എണ്ണം, മൈഗ്രേഷൻ എണ്ണം മുതലായവ) യഥാർഥ എണ്ണങ്ങളുടെ റാച്ചറ്റ് പരിധിക്കുള്ളിലാണെന്ന് | അതെ | +| ↳ `check:env-doc-sync` | `.env.example`-ലെ എല്ലാ env var-കളും docs പട്ടികയിൽ രേഖപ്പെടുത്തിയിട്ടുണ്ടെന്നും തിരിച്ചും അങ്ങനെ തന്നെയാണെന്നും | അതെ | +| ↳ `check:deprecated-versions` | docs-ൽ ഒഴിവാക്കിയ പതിപ്പ് സ്ട്രിങ്ങുകൾ ഇല്ലെന്ന് | അതെ | +| ↳ `check:doc-links` | docs-ലെ ആന്തരിക markdown ലിങ്കുകൾ യഥാർഥ ഫയലുകളിലേക്ക് പരിഹരിക്കപ്പെടുന്നുവെന്ന് (`[text]`/`(path)` രൂപം) | അതെ | +| ↳ `check:fabricated-docs` | docs-ൽ പരാമർശിച്ച routes, env var-കൾ, CLI കമാൻഡുകൾ, hook പേരുകൾ, file path-കൾ എന്നിവ codebase-ൽ നിലവിലുണ്ടെന്ന്. `--strict` വഴി ഹാർഡ് ഗേറ്റ്; ഫ്ലാഗില്ലെങ്കിൽ സോഫ്റ്റ്-ഫെയിൽ. | അതെ (CI-യിൽ `--strict` വഴി) | +| `check:cli-i18n` | CLI കമാൻഡ് സ്ട്രിങ്ങുകൾ എല്ലാ i18n locale ഫയലുകളിലും ഉണ്ടെന്ന് | അതെ | +| `check:openapi-coverage` | OpenAPI spec യഥാർഥ routes-ന്റെ കുറഞ്ഞത് റാച്ചറ്റ് ചെയ്ത അടിസ്ഥാനപരിധിയെങ്കിലും ഉൾക്കൊള്ളുന്നുവെന്ന് | അതെ | +| `check:openapi-security-tiers` | `openapi.yaml`-ലെ സുരക്ഷാ ടയർ annotations `routeGuard.ts` വർഗ്ഗീകരണങ്ങളുമായി പൊരുത്തപ്പെടുന്നുവെന്ന് | **ഉപദേശാത്മകം** | +| `check:openapi-routes` | `openapi.yaml`-ലെ ഓരോ path-ഉം യഥാർഥ `route.ts`-ലേക്ക് പരിഹരിക്കപ്പെടുന്നുവെന്ന് (വ്യാജസൃഷ്ടി തടയൽ) | അതെ | +| `check:docs-symbols` | `docs/**/*.md`-ലെ ഓരോ `/api/...` പരാമർശവും യഥാർഥ `route.ts`-ലേക്ക് പരിഹരിക്കപ്പെടുന്നുവെന്ന് (വ്യാജസൃഷ്ടി തടയൽ) | അതെ | +| `i18n translation drift` | i18n locale ഫയലുകളിലെ പരിഭാഷപ്പെടുത്താത്ത keys — മുന്നറിയിപ്പ് മാത്രം | **ഉപദേശാത്മകം** | ### ജോലി: `i18n-ui-coverage` -| സ്ക്രിപ്റ്റ് | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | -| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `check-ui-keys-coverage` (ഇൻലൈൻ) | UI i18n കീ കവറേജ് ≥ 65% ആണെന്ന് | അതെ | -| `check-ui-value-drift` (ഇൻലൈൻ) | മാറ്റിയെഴുതിയ ഒരു ഇംഗ്ലീഷ് **മൂല്യം** പഴകിയ വിവർത്തനമൊന്നും അവശേഷിപ്പിക്കുന്നില്ലെന്ന് | അതെ | -| `check-new-key-coverage` (ഇൻലൈൻ) | ഒരു **പുതിയ** ഇംഗ്ലീഷ് കീ എല്ലാ ലോക്കേലുകളിലും വിവർത്തനം ചെയ്തിട്ടുണ്ടെന്ന് — `__MISSING__:` മാർക്കർ നിരസിക്കപ്പെടും | അതെ | -| `check-translation-ratio` | ഓരോ ലോക്കേലിലെയും യഥാർഥ വിവർത്തന അനുപാതം (അനുവദനീയ പട്ടികയ്ക്ക് പുറത്തുള്ള ഇംഗ്ലീഷിനോട് സമാനമായ / പ്ലേസ്ഹോൾഡർ / നഷ്ടപ്പെട്ട ഇലകൾ) `config/quality/i18n-translation-baseline.json` + ഇളവ് കവിയാൻ പാടില്ല | **ഉപദേശാത്മകം** | +| സ്ക്രിപ്റ്റ് | പരിശോധിക്കുന്നത് | തടയുന്നത് | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | +| `check-ui-keys-coverage` (inline) | UI i18n key കവറേജ് ≥ 65% ആണെന്ന് | അതെ | +| `check-ui-value-drift` (inline) | തിരുത്തിയെഴുതിയ ഒരു ഇംഗ്ലീഷ് **value** പഴകിയ പരിഭാഷയൊന്നും ശേഷിപ്പിക്കുന്നില്ലെന്ന് | അതെ | +| `check-new-key-coverage` (inline) | ഒരു **പുതിയ** ഇംഗ്ലീഷ് key എല്ലാ locale-ലും പരിഭാഷപ്പെടുത്തിയിട്ടുണ്ടെന്ന് — `__MISSING__:` marker നിരസിക്കപ്പെടും | അതെ | +| `check-translation-ratio` | ഓരോ locale-ലെയും യഥാർഥ-പരിഭാഷ അനുപാതം (allowlist-ന് പുറത്തുള്ള ഇംഗ്ലീഷിനോട് സമാനമായ / placeholder / നഷ്ടമായ leaves) `config/quality/i18n-translation-baseline.json` + slack കവിയരുത് | **ഉപദേശാത്മകം** | -`fetch-depth: 0` ആവശ്യമാണ് — മൂല്യ-ഡ്രിഫ്റ്റ് ഗേറ്റ് മെർജ് ബേസുമായി താരതമ്യം ചെയ്ത് `en.json`-ന്റെ വ്യത്യാസം പരിശോധിക്കുന്നു. +`fetch-depth: 0` ആവശ്യമാണ് — value-drift ഗേറ്റ് merge base-നെതിരെ `en.json` diff ചെയ്യുന്നു. -#### `check-ui-value-drift` — പഴകിയ വിവർത്തന ഗേറ്റ് +#### `check-ui-value-drift` — പഴകിയ-പരിഭാഷാ ഗേറ്റ് -മറ്റ് ഗേറ്റുകൾക്ക് ഘടനാപരമായി കണ്ടെത്താനാകാത്ത ഏക i18n റിഗ്രഷൻ ഇത് കണ്ടെത്തുന്നു: ഒരു ഇംഗ്ലീഷ് മൂല്യം -മാറ്റിയെഴുതിയിട്ടും _മുൻപത്തെ_ ഇംഗ്ലീഷിൽനിന്ന് സൃഷ്ടിച്ച വിവർത്തനങ്ങൾ അവശേഷിക്കുന്നതിനാൽ, -ഇംഗ്ലീഷ് ഇതര ഉപയോക്താക്കൾ ആത്മവിശ്വാസത്തോടെ എഴുതിയിട്ടുള്ള, എന്നാൽ ഇപ്പോൾ തെറ്റായ പകർപ്പ് തുടർന്നും വായിക്കുന്നു. +മറ്റ് ഗേറ്റുകൾക്ക് ഘടനാപരമായി കാണാൻ കഴിയാത്ത ഒരേയൊരു i18n regression ഇത് കണ്ടെത്തുന്നു: ഒരു ഇംഗ്ലീഷ് value +തിരുത്തിയെഴുതിയിട്ടും _മുമ്പത്തെ_ ഇംഗ്ലീഷ് value-യിൽ നിന്ന് ഉരുത്തിരിഞ്ഞ പരിഭാഷകൾ അവിടെത്തന്നെ ശേഷിക്കുന്നു; അതിനാൽ +ഇംഗ്ലീഷിതര ഉപയോക്താക്കൾ ആത്മവിശ്വാസത്തോടെ എഴുതപ്പെട്ടതെങ്കിലും ഇപ്പോൾ തെറ്റായ ഉള്ളടക്കം തുടർന്നും വായിക്കുന്നു. -ഇത് യഥാർഥത്തിൽ റിലീസ് ചെയ്തിരുന്നു. Antigravity -ലോഗിൻ സഹായി എത്തിയപ്പോൾ (#5203) `oauthModal.googleOAuthWarning` മാറ്റിയെഴുതപ്പെട്ടു; **43 ലോക്കേലുകളിൽ 39 എണ്ണവും** ഓപ്പറേറ്റർമാരോട് "പൂർണ്ണ URL പകർത്തി താഴെ ഒട്ടിക്കുക" എന്ന് പറയുന്ന വാചകം നിലനിർത്തി — ആ പ്രൊവൈഡറിന് പൂർത്തിയാക്കാനാകാത്ത ഒരു പ്രവാഹമാണത്. താഴെ പറയുന്ന കാരണങ്ങളാൽ #8463 വരെ -ഇത് ശ്രദ്ധിക്കപ്പെടാതെ പോയി: +ഇത് യഥാർഥത്തിൽ റിലീസ് ചെയ്യപ്പെട്ടു. Antigravity login helper ചേർത്തപ്പോൾ (#5203) +`oauthModal.googleOAuthWarning` തിരുത്തിയെഴുതപ്പെട്ടു; **43 locale-കളിൽ 39 എണ്ണത്തിലും** ഓപ്പറേറ്റർമാരോട് "പൂർണ്ണ URL +പകർത്തി താഴെ ഒട്ടിക്കുക" എന്ന് പറയുന്ന വാചകം നിലനിന്നു — ആ provider-നായി പൂർത്തിയാക്കാനാകാത്ത ഒരു flow. #8463 വരെ +ഇത് ശ്രദ്ധിക്കപ്പെടാതെ പോയതിന്റെ കാരണങ്ങൾ: -- `sync-ui-keys` **ഇല്ലാത്ത** കീകൾ മാത്രമേ ബാക്ക്ഫിൽ ചെയ്യൂ, **പഴകിയവ** ഒരിക്കലും ചെയ്യില്ല; -- `check-ui-keys-coverage` കീയുടെ _സാന്നിധ്യം_ കണക്കാക്കുന്നതിനാൽ പഴകിയ വിവർത്തനവും കവർ ചെയ്തതായി കണക്കാക്കപ്പെടുന്നു; -- `check-translation-drift` `docs/i18n//**.md` ഡോക്യുമെന്റേഷൻ മിററുകളെയാണ് പിന്തുടരുന്നത് — - അത് ഒരിക്കലും `src/i18n/messages/*.json` വായിക്കുന്നില്ല. 2026-09 പുനഃസമന്വയം മുതൽ `docs-sync-strict` ജോലിയിൽ തടസ്സപ്പെടുത്തുന്നു: ഒരു പ്രധാന ഡോക് തിരുത്തുക → `npm run i18n:run -- --files=` (വിഭാഗ-തലത്തിലുള്ളത്, ചെലവ് കുറഞ്ഞത്). +- `sync-ui-keys` **ഇല്ലാത്ത** keys മാത്രമേ backfill ചെയ്യൂ, **പഴകിയവ** ഒരിക്കലും ചെയ്യില്ല; +- `check-ui-keys-coverage` key-യുടെ _സാന്നിധ്യം_ എണ്ണുന്നതിനാൽ, പഴകിയ പരിഭാഷയും ഉൾപ്പെടുത്തിയതായി കണക്കാക്കപ്പെടുന്നു; +- `check-translation-drift` `docs/i18n//**.md` documentation mirrors ആണ് ട്രാക്ക് ചെയ്യുന്നത് — + അത് ഒരിക്കലും `src/i18n/messages/*.json` വായിക്കുന്നില്ല. 2026-09 re-sync മുതൽ `docs-sync-strict` ജോലിയിൽ തടയുന്നു: + ഒരു core doc തിരുത്തുക → `npm run i18n:run -- --files=` (section-level, ചെലവുകുറഞ്ഞത്). -**വ്യത്യാസം കണക്കിലെടുക്കുന്നു, അടിസ്ഥാനരേഖയെ ആശ്രയിക്കുന്നില്ല.** ഇത് merge base-ലെ `en.json`-നെ -working tree-യുമായി താരതമ്യം ചെയ്യുന്നു; ഇംഗ്ലീഷ് മൂല്യം മാറിയ ഓരോ key-ക്കും, മാറ്റമില്ലാത്ത -വിവർത്തനം ഇപ്പോഴും നിലനിർത്തുന്ന locale കാലഹരണപ്പെട്ടതാണ്. ഇത് മനഃപൂർവം **നിലവിലുള്ള കടബാധ്യതയെ അതേപടി നിർത്തുന്നു** — ദീർഘകാലമായി നിലനിൽക്കുന്ന ഒരു വിവർത്തനം ഏത് പഴയ ഇംഗ്ലീഷ് വാചകത്തിൽനിന്നാണ് വന്നതെന്ന് -ഒരു diff-ന് വെളിപ്പെടുത്താനാകില്ല, അതിനാൽ നിലവിലെ മാറ്റം സ്പർശിക്കുന്നവയെ മാത്രമാണ് gate വിലയിരുത്തുന്നത്. -മറ്റൊരു മാർഗമായ ഓരോ key-ക്കും പ്രത്യേകം hash baseline ഉപയോഗിക്കുന്നതിന്, നിലവിലുള്ള ഏറ്റവും വലിയ baseline-ന്റെ 3× വലുപ്പമുള്ള -~600 KB generated file ആവശ്യമായി വരും; ഓരോ i18n PR-ലും അത് മാറിക്കൊണ്ടിരിക്കുകയും ചെയ്യും. +**Diff-aware ആണ്, baseline-backed അല്ല.** ഇത് merge base-ലെ `en.json`-നെ working tree-യുമായി താരതമ്യം ചെയ്യുന്നു; ഇംഗ്ലീഷ് മൂല്യം മാറിയ ഓരോ key-ക്കും, മാറ്റമൊന്നും വരുത്താത്ത translation ഇപ്പോഴും കൈവശമുള്ള locale കാലഹരണപ്പെട്ടതായി കണക്കാക്കുന്നു. ഇത് മനഃപൂർവം **നിലവിലുള്ള കടബാധ്യതയെ അതേപടി നിർത്തുന്നു** — ദീർഘകാലമായി നിലനിൽക്കുന്ന ഒരു translation ഏത് പഴയ ഇംഗ്ലീഷ് മൂല്യത്തിൽനിന്ന് വന്നതാണെന്ന് diff-ന് വെളിപ്പെടുത്താനാകില്ല; അതിനാൽ നിലവിലെ മാറ്റം സ്പർശിക്കുന്നവയെ മാത്രമാണ് gate വിലയിരുത്തുന്നത്. ബദൽ മാർഗമായ (ഓരോ key-ക്കും hash baseline) ഏകദേശം 600 KB വലുപ്പമുള്ള generated file ആവശ്യപ്പെടും; ഇത് നിലവിലുള്ള ഏറ്റവും വലിയ baseline-ന്റെ 3 മടങ്ങാണ്, കൂടാതെ ഓരോ i18n PR-ലും അനാവശ്യ മാറ്റങ്ങൾ സൃഷ്ടിക്കും. ഇത് പാലിക്കാൻ രണ്ട് മാർഗങ്ങളുണ്ട്: -1. ബാധിക്കപ്പെട്ട വിവർത്തനങ്ങൾ പുതുക്കുക, അല്ലെങ്കിൽ -2. അവയെ `__MISSING__:` ആയി സജ്ജീകരിക്കുക — തുടർന്ന് runtime തിരുത്തിയ ഇംഗ്ലീഷ് നൽകും - (`src/i18n/request.ts::deepMergeFallback`, #7258), കൂടാതെ key വിവർത്തനത്തിനായി queue ചെയ്യപ്പെടും. +1. ബാധിക്കപ്പെട്ട translations പുതുക്കുക, അല്ലെങ്കിൽ +2. അവയെ `__MISSING__:` ആയി സജ്ജീകരിക്കുക — തുടർന്ന് runtime തിരുത്തിയ ഇംഗ്ലീഷ് നൽകുകയും + (`src/i18n/request.ts::deepMergeFallback`, #7258) ആ key translation-നുള്ള queue-യിൽ ചേർക്കുകയും ചെയ്യും. -സ്ട്രിങ്ങിന്റെ **അർത്ഥം** മാറിയിട്ടുണ്ടെങ്കിൽ, **key-യുടെ പേര് മാറ്റുന്നതാണ്** ഉചിതം: ഒരു പുതിയ key-ക്ക് -കാലഹരണപ്പെട്ട വിവർത്തനം പാരമ്പര്യമായി ലഭിക്കാനാവില്ല. #8463 ഉപയോഗിച്ച മാതൃക അതാണ്. +string-ന്റെ **അർത്ഥം** മാറിയിട്ടുണ്ടെങ്കിൽ, **key-യുടെ പേര് മാറ്റുന്നതിന്** മുൻഗണന നൽകുക: ഒരു പുതിയ key-ക്ക് കാലഹരണപ്പെട്ട translation പാരമ്പര്യമായി ലഭിക്കാനാവില്ല. #8463 ഉപയോഗിച്ച മാതൃക അതാണ്. ```bash npm run i18n:check-value-drift # കർശനം (CI പ്രവർത്തിപ്പിക്കുന്നത്) @@ -216,48 +233,47 @@ npm run i18n:check-value-drift:warn # റിപ്പോർട്ട് മ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -അടിസ്ഥാന catalog വായിക്കാനാകാത്തപ്പോൾ (base ref ഇല്ലാത്ത shallow -clone), `check-openapi-breaking`-നെ അനുകരിച്ച് `SKIP reason=base-unresolved` സഹിതം 0 എന്ന നിലയിൽ അവസാനിക്കുന്നു. +base catalog വായിക്കാനാകാത്തപ്പോൾ (base ref ഇല്ലാത്ത shallow clone), `check-openapi-breaking`-ന്റെ പ്രവർത്തനം അനുകരിച്ച് `SKIP reason=base-unresolved` സഹിതം 0 exit code നൽകുന്നു. ### Job: `i18n` -പൂർണ്ണ i18n validation matrix (ഓരോ locale-നും ഓരോ job). മുഴുവൻ job-ഉം ഉപദേശാത്മകമാണ്. +സമ്പൂർണ്ണ i18n validation matrix (ഓരോ locale-നും ഓരോ job). മുഴുവൻ job-വും advisory ആണ്. -| Script | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | -| ------------------------------- | --------------------------------- | ---------------------------------------------------------- | -| `validate_translation.py quick` | ഓരോ locale-ലെയും വിവർത്തന പൂർണ്ണത | **ഉപദേശാത്മകം** (മുഴുവൻ job-ലും `continue-on-error: true`) | +| Script | പരിശോധിക്കുന്നത് | Blocking | +| ------------------------------- | -------------------------------------------- | ------------------------------------------------------- | +| `validate_translation.py quick` | ഓരോ locale-ലെയും translation-ന്റെ സമ്പൂർണ്ണത | **Advisory** (മുഴുവൻ job-ലും `continue-on-error: true`) | ### Job: `pr-test-policy` pull request-ുകളിൽ മാത്രം പ്രവർത്തിക്കുന്നു. -| Script | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, അല്ലെങ്കിൽ `bin/` എന്നിവയിലെ production code മാറ്റുന്ന PR-ുകളിൽ tests ഉൾപ്പെടുത്തുകയോ പുതുക്കുകയോ വേണം (Hard Rule #8) | അതെ | -| `check:test-masking` | മാറ്റിയ test file-ുകൾ മൊത്തം assert എണ്ണം കുറയ്ക്കുകയോ `assert.ok(true)` tautology-കൾ ചേർക്കുകയോ ചെയ്യുന്നില്ല | അതെ | -| `check:pr-evidence` | മാറ്റത്തിനുള്ള test/VPS തെളിവ് PR body-യിൽ ഉദ്ധരിച്ചിരിക്കുന്നു (PR ഗദ്യം grep ചെയ്ത് Hard Rule #18 യാന്ത്രികമാക്കുന്നു — ദുർബലമാണ്, Backlog കാണുക) | അതെ | +| Script | പരിശോധിക്കുന്നത് | Blocking | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, അല്ലെങ്കിൽ `bin/` എന്നിവയിലെ production code മാറ്റുന്ന PR-ുകളിൽ tests ഉൾപ്പെടുത്തുകയോ പുതുക്കുകയോ വേണം (Hard Rule #8) | അതെ | +| `check:test-masking` | മാറ്റിയ test files ആകെ assert count കുറയ്ക്കുകയോ `assert.ok(true)` tautologies ചേർക്കുകയോ ചെയ്യുന്നില്ല | അതെ | +| `check:pr-evidence` | മാറ്റത്തിനുള്ള test/VPS തെളിവുകൾ PR body-ൽ ഉദ്ധരിക്കുന്നു (PR prose grep ചെയ്ത് Hard Rule #18 യാന്ത്രികമാക്കുന്നു — ഇത് ദുർബലമാണ്; Backlog കാണുക) | അതെ | ### Job: `test-vitest` `build`-ന് ശേഷം പ്രവർത്തിക്കുന്നു. പരാജയപ്പെട്ടാൽ merge തടയുന്നു. -| Suite | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | -| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | അതെ | -| `test:vitest:ui` | UI component tests — vitest runner | **തടസ്സപ്പെടുത്തുന്നു** — നിലവിലുള്ള പരാജയങ്ങൾ `vitest.config.ts`-ൽ വ്യക്തമായി ഒഴിവാക്കിയിരിക്കുന്നു; പുതിയ പരാജയങ്ങൾ job പരാജയപ്പെടുത്തും | +| Suite | പരിശോധിക്കുന്നത് | Blocking | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | അതെ | +| `test:vitest:ui` | UI component tests — vitest runner | **Blocking** — മുമ്പേ നിലവിലുള്ള failures `vitest.config.ts`-ൽ വ്യക്തമായി ഒഴിവാക്കിയിരിക്കുന്നു; പുതിയ failures job പരാജയപ്പെടുത്തും | -### രാത്രികാല workflows (ക്രമീകരിച്ചവ, ഉപദേശാത്മകം) +### Nightly workflows (scheduled, advisory) -ഇവ cron schedule-ൽ (കൂടാതെ `workflow_dispatch` വഴിയും) പ്രവർത്തിക്കുന്നു; PR-ുകളിൽ ഒരിക്കലും പ്രവർത്തിക്കില്ല. എല്ലാം ഉപദേശാത്മകമാണ്. +ഇവ cron schedule-ൽ (കൂടാതെ `workflow_dispatch` വഴിയും) പ്രവർത്തിക്കുന്നു; PR-ുകളിൽ ഒരിക്കലും പ്രവർത്തിക്കില്ല. എല്ലാം advisory ആണ്. -| Workflow | സാധൂകരിക്കുന്നത് | തടസ്സപ്പെടുത്തുന്നത് | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `nightly-property` | random seed + ഉയർന്ന run count ഉപയോഗിച്ചുള്ള fast-check property tests | **ഉപദേശാത്മകം** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **ഉപദേശാത്മകം** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret ഇല്ലെങ്കിൽ ഒഴിവാക്കപ്പെടും) | **ഉപദേശാത്മകം** | -| `nightly-schemathesis` | `docs/openapi.yaml` ഉപയോഗിച്ച് live OmniRoute-നെതിരെയുള്ള OpenAPI contract fuzzing (schemathesis) — spec ലംഘനങ്ങൾ / കൈകാര്യം ചെയ്യാത്ത 500-കൾ വെളിപ്പെടുത്തുന്നു (Fase 8 B.4) | **ഉപദേശാത്മകം** | -| `nightly-mutation` | fast unit lane-ലുടനീളമുള്ള Stryker mutation-testing score — അതിജീവിക്കുന്ന mutants ദുർബലമായ asserts വെളിപ്പെടുത്തുന്നു | **ഉപദേശാത്മകം** | -| `nightly-compat` | പിന്തുണയ്ക്കുന്ന `engines.node` ranges-ലുടനീളമുള്ള Node engine compatibility matrix | **ഉപദേശാത്മകം** | +| Workflow | പരിശോധിക്കുന്നത് | Blocking | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | random seed-ഉം ഉയർന്ന run count-ഉം ഉപയോഗിച്ചുള്ള fast-check property tests | **Advisory** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **Advisory** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret ഇല്ലെങ്കിൽ ഒഴിവാക്കപ്പെടും) | **Advisory** | +| `nightly-schemathesis` | `docs/openapi.yaml` ഉപയോഗിച്ച് live OmniRoute-നെതിരെയുള്ള OpenAPI contract fuzzing (schemathesis) — spec ലംഘനങ്ങൾ / കൈകാര്യം ചെയ്യാത്ത 500s വെളിപ്പെടുത്തുന്നു (Fase 8 B.4) | **Advisory** | +| `nightly-mutation` | വേഗത്തിലുള്ള unit lane-ലെ Stryker mutation-testing score — അതിജീവിക്കുന്ന mutants ദുർബലമായ asserts വെളിപ്പെടുത്തുന്നു | **Advisory** | +| `nightly-compat` | പിന്തുണയ്ക്കുന്ന `engines.node` ranges-ലുടനീളമുള്ള Node engine compatibility matrix | **Advisory** | --- @@ -513,41 +529,41 @@ CI ഗേറ്റുകൾക്ക് പുറമേ, OmniRoute ഒരു ** ## യുക്തിസഹമാക്കൽ ബാക്ക്ലോഗ് (ROI അവലോകനം — ഘട്ടം 9 തരംഗം 3) -ഈ ഇൻവെന്ററി 2026-06-17-ന് `ci.yml`-മായി ഒത്തുനോക്കി (മുൻ പതിപ്പിൽ +ഈ ഇൻവെന്ററി 2026-06-17-ന് `ci.yml`-മായി പൊരുത്തപ്പെടുത്തി (മുൻ പതിപ്പിൽ `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` എന്നിവ വിട്ടുപോയിരുന്നു). ഒത്തുനോക്കിയ സെറ്റിന്റെ ROI അവലോകനം -താഴെപ്പറയുന്ന യുക്തിസഹമാക്കൽ സ്ഥാനാർഥികളെ തിരിച്ചറിഞ്ഞു. **ലയിപ്പിക്കലുകൾ യാന്ത്രിക CI -മാറ്റങ്ങളാണ്; ഫ്ലിപ്പുകൾ/ഒഴിവാക്കലുകൾ ഓപ്പറേറ്റർക്കായി നീക്കിവെച്ചിരിക്കുന്ന നയപരമായ തീരുമാനങ്ങളാണ്.** താഴെയുള്ളതൊന്നും -ഇതുവരെ പ്രയോഗിച്ചിട്ടില്ല. +`check:codeql-ratchet`, `check:pr-evidence` എന്നിവ വിട്ടുപോയിരുന്നു). പൊരുത്തപ്പെടുത്തിയ സെറ്റിന്റെ ROI അവലോകനം +താഴെപ്പറയുന്ന യുക്തിസഹമാക്കൽ സ്ഥാനാർഥികളെ കണ്ടെത്തി. **ലയിപ്പിക്കലുകൾ യാന്ത്രിക CI +മാറ്റങ്ങളാണ്; ഫ്ലിപ്പുകൾ/ഒഴിവാക്കലുകൾ ഓപ്പറേറ്റർക്കായി നീക്കിവച്ചിരിക്കുന്ന നയപരമായ തീരുമാനങ്ങളാണ്.** താഴെപ്പറയുന്നവയിൽ +ഒന്നും ഇതുവരെ പ്രയോഗിച്ചിട്ടില്ല. **മുകളിൽ രേഖപ്പെടുത്താത്തവയും** (ഉപദേശാത്മകം, കുറഞ്ഞ സിഗ്നൽ): `docs-lint` ജോലി (markdownlint + Vale, മുഴുവൻ ജോലിക്കും `continue-on-error`) കൂടാതെ സ്വതന്ത്ര സ്കാനർ വർക്ക്ഫ്ലോകളായ -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` -`quality-baseline.json`-ൽ ഉണ്ടെങ്കിലും `ci.yml`-ലെ ഒരു ബ്ലോക്കിംഗ് റാച്ചറ്റുമായി ബന്ധിപ്പിച്ചിട്ടില്ല — ഈ മെട്രിക് +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `quality-baseline.json`-ൽ +`semgrepFindings: 0` ഉണ്ട്, എന്നാൽ `ci.yml`-ലെ ഒരു ബ്ലോക്കിങ് റാച്ചറ്റുമായി അത് ബന്ധിപ്പിച്ചിട്ടില്ല — ഈ മെട്രിക് നിലവിൽ അനാഥമാണ്. -### ലയിപ്പിക്കൽ / ഡീഡ്യൂപ്ലിക്കേഷൻ (യാന്ത്രികം, കുറഞ്ഞ അപകടസാധ്യത) +### ലയിപ്പിക്കൽ / ഡ്യൂപ്ലിക്കേഷൻ നീക്കംചെയ്യൽ (യാന്ത്രികം, കുറഞ്ഞ അപകടസാധ്യത) -ഓരോ സ്ഥാനാർഥിയും 2026-06-17-ലെ തത്സമയ ഗേറ്റ് നിലയ്ക്കെതിരെ സാധൂകരിച്ചു (വിശ്വസിക്കുക, എന്നാൽ പരിശോധിക്കുക); -"വ്യക്തമായത്" എന്ന് തോന്നിയ പല ലയിപ്പിക്കലുകളും കടം മറച്ചുവെച്ചിരുന്നതായി തെളിഞ്ഞു; അവ **ശുദ്ധമായ പകരക്കാരല്ല**. +ഓരോ സ്ഥാനാർഥിയെയും 2026-06-17-ലെ തത്സമയ ഗേറ്റ് നിലയ്ക്കെതിരെ സാധൂകരിച്ചു (വിശ്വസിക്കുക, എന്നാൽ പരിശോധിക്കുക); +"വ്യക്തമായ" പല ലയിപ്പിക്കലുകളും മറഞ്ഞിരിക്കുന്ന സാങ്കേതിക കടം ഒളിപ്പിക്കുന്നതായി കണ്ടെത്തി, അവ **ശുദ്ധമായ പകരക്കാരല്ല**. -- **`check:docs-sync` രണ്ടുതവണ പ്രവർത്തിക്കുന്നു** — `lint` ജോലിയിൽ സ്വതന്ത്രമായും `check:docs-all`-ന്റെ (`docs-sync-strict`) ഉള്ളിലും husky pre-commit ഹുക്കിലും വീണ്ടും. ✅ **പൂർത്തിയായി** — സ്വതന്ത്രമായ `lint` ഇൻവൊക്കേഷൻ നീക്കംചെയ്തു. -- **CVE സ്കാനിംഗ്** — ❌ **ശുദ്ധമായ ലയിപ്പിക്കൽ അല്ല.** ഏതെങ്കിലും ഉയർന്ന/ഗുരുതര CVE ഉണ്ടെങ്കിൽ `audit:deps` കർശനമായി പരാജയപ്പെടും; `check:vuln-ratchet` (osv) ബേസ്ലൈനുമായി താരതമ്യപ്പെടുത്തുമ്പോൾ ഒരു _പിന്നോട്ടുപോക്ക്_ ഉണ്ടായാൽ മാത്രമേ പരാജയപ്പെടൂ (നിലവിൽ 1 MODERATE). വ്യത്യസ്ത സെമാന്റിക്സ് — `audit:deps` ഒഴിവാക്കിയാൽ സമ്പൂർണ്ണമായ ഉയർന്ന/ഗുരുതര ഗേറ്റ് നഷ്ടപ്പെടും. രണ്ടും നിലനിർത്തുക. -- **സൈക്കിൾ കണ്ടെത്തൽ** — ❌ **ശുദ്ധമായ ലയിപ്പിക്കൽ അല്ല.** `check:circular-deps` (dpdm) **91 സൈക്കിളുകൾ** റിപ്പോർട്ട് ചെയ്യുന്നു (അതുകൊണ്ടാണ് ഇത് ഉപദേശാത്മകമായിരിക്കുന്നത്); അവ ആദ്യം പരിഹരിക്കാതെ ഇതിനെ ബ്ലോക്കിംഗിലേക്ക് ഉയർത്താനാവില്ല, കൂടാതെ ഗ്രീൻ നിലയിലുള്ള, ശ്രദ്ധാപൂർവം തിരഞ്ഞെടുത്ത `check:cycles`-നെക്കാൾ വിശാലമായ വ്യാപ്തിയും ഇതിനുണ്ട്. `check:cycles` ബ്ലോക്കിംഗായി നിലനിർത്തുക; 91 dpdm സൈക്കിളുകൾ പരിഹരിക്കുന്നത് വേറൊരു ബാക്ക്ലോഗാണ്. -- **സങ്കീർണ്ണത** — ✅ **പൂർത്തിയായി** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ഒരൊറ്റ ESLint വാക്ക്, ruleId അനുസരിച്ച് എണ്ണുന്നതിനാൽ cyclomatic+max-lines, cognitive ബേസ്ലൈനുകൾ സ്വതന്ത്രമായി തുടരുന്നു; പ്രാദേശിക `--update`-നായി വ്യക്തിഗത `check:complexity` / `check:cognitive-complexity` നിലനിർത്തുന്നു. -- **`/api` ആന്റി-ഹാലൂസിനേഷൻ** — ✅ **പൂർത്തിയായി** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-യുടെ ഒരൊറ്റ FS ഇൻവെന്ററി; openapi-routes + docs-symbols ഇപ്പോഴും സ്വതന്ത്രമായി റിപ്പോർട്ട് ചെയ്യുന്നു; പ്രാദേശിക റണ്ണുകൾക്കായി വ്യക്തിഗതവ നിലനിർത്തുന്നു. -- **`check:node-runtime` 11 ജോലികളിൽ പ്രവർത്തിക്കുന്നു** — ⚠️ **കുറഞ്ഞ ROI.** ഓരോന്നും വേറിട്ട റണ്ണറാണ്, ചെക്ക് <1s മാത്രമാണ്; വിലകുറഞ്ഞ ഓരോ-ജോലി ഗാർഡ് നഷ്ടപ്പെടുത്തുന്നതിന് പകരമായി ലഭിക്കുന്ന ആകെ ലാഭം ~10s മാത്രം. ഈ മാറ്റച്ചെലവിന് തക്കതല്ല. -- **CI lint-ലെ `typecheck:noimplicit:core`** — ✅ **lint ജോലിയിൽ നിന്ന് നീക്കംചെയ്തു** (ഉപദേശാത്മകമായ `continue-on-error` ആയിരുന്നു); ബ്ലോക്കിംഗ് ടൈപ്പ് ഉപരിതലം `typecheck:core` + `check:type-coverage` ആണ്. പ്രാദേശിക സ്ക്രിപ്റ്റ് നിലനിർത്തി. +- **`check:docs-sync` രണ്ടുതവണ പ്രവർത്തിക്കുന്നു** — `lint` ജോലിയിൽ സ്വതന്ത്രമായും `check:docs-all` (`docs-sync-strict`)-ന്റെ ഉള്ളിലും husky pre-commit ഹുക്കിലും വീണ്ടും. ✅ **പൂർത്തിയായി** — സ്വതന്ത്ര `lint` ഇൻവൊക്കേഷൻ നീക്കംചെയ്തു. +- **CVE സ്കാനിങ്** — ❌ **ശുദ്ധമായി ലയിപ്പിക്കാനാകില്ല.** ഏതെങ്കിലും high/critical CVE കണ്ടെത്തിയാൽ `audit:deps` കർശനമായി പരാജയപ്പെടുന്നു; `check:vuln-ratchet` (osv) ബേസ്ലൈനുമായി താരതമ്യപ്പെടുത്തിയുള്ള ഒരു _പിന്നോട്ടുപോക്ക്_ ഉണ്ടായാൽ മാത്രമാണ് പരാജയപ്പെടുന്നത് (നിലവിൽ 1 MODERATE). അർത്ഥശാസ്ത്രം വ്യത്യസ്തമാണ് — `audit:deps` ഒഴിവാക്കിയാൽ സമ്പൂർണ്ണ high/critical ഗേറ്റ് നഷ്ടപ്പെടും. രണ്ടും നിലനിർത്തുക. +- **സൈക്കിൾ കണ്ടെത്തൽ** — ✅ **പൂർത്തിയായി** (#15159 G-01/G-02). ഇവിടെയുള്ള പഴയ വാചകം `check:cycles`-നെ "ഹരിതമായ, ക്യൂറേറ്റ് ചെയ്ത" ഗേറ്റ് എന്ന് വിളിക്കുകയും `check:circular-deps` (dpdm) 91 സൈക്കിളുകൾ റിപ്പോർട്ട് ചെയ്തതിനാൽ അത് ബ്ലോക്കിങ്ങായി നിലനിർത്തുന്നതിനെ ന്യായീകരിക്കുകയും ചെയ്തിരുന്നു. ആ ഹരിതനില ഒരു **വ്യാജ ഹരിതനില** ആയിരുന്നു: `check:cycles` 5 ഉപഡയറക്ടറികൾ (450 ഫയലുകൾ) സ്കാൻ ചെയ്തു, സ്റ്റാറ്റിക് `import|export … from` മാത്രമാണ് പൊരുത്തപ്പെടുത്തിയത്, കൂടാതെ എല്ലാ `@/`, `@omniroute/open-sse/` സ്പെസിഫയറുകളും ഒഴിവാക്കി; അതിനാൽ റിപ്പോയിൽ ആധിപത്യം പുലർത്തിയ dynamic-import + alias സൈക്കിളുകൾ അതിന് കാണാനായില്ല. പരിഹരിച്ചു: ഗേറ്റ് ഇപ്പോൾ `src` + `open-sse` (5023 ഫയലുകൾ) പരിശോധിക്കുന്നു, TypeScript AST-യിൽ നിന്ന് സ്പെസിഫയറുകൾ ശേഖരിക്കുന്നു (അതിനാൽ `import("…")` കണക്കാക്കപ്പെടും, എന്നാൽ type-position `typeof import("…")` കണക്കാക്കപ്പെടില്ല), കൂടാതെ tsconfig `paths` റിസോൾവ് ചെയ്യുന്നു. ഇത് 0 അല്ല, **14** സൈക്കിളുകൾ കണ്ടെത്തുന്നു. നിലവിലുള്ള 14 സൈക്കിളുകൾ ഒരു ഗേറ്റ് PR-ൽ പരിഹരിക്കാനാകാത്തതിനാൽ, `check:cycles` ഇപ്പോൾ ഒരു **റാച്ചറ്റ്** ആണ് (`--ratchet`, `quality-baseline.json`-ൽ പരിധി `metrics.cycles.value = 14`, `direction: down`) — ഏതൊരു _പിന്നോട്ടുപോക്കും_ ഇത് തടയുന്നു, എണ്ണം കുറയുക മാത്രമേ ചെയ്യാനാകൂ. CI `npm run check:cycles:ratchet` പ്രവർത്തിപ്പിക്കുന്നു. കുറച്ചുകൊണ്ടുവരൽ **A-01**-നൊപ്പം നടക്കും. വിശാലമായ രണ്ടാമത്തെ അഭിപ്രായമായി `check:circular-deps` (dpdm) ഉപദേശാത്മകമായി തുടരുന്നു. +- **സങ്കീർണ്ണത** — ✅ **പൂർത്തിയായി** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ഒരൊറ്റ ESLint പരിശോധന, ruleId അനുസരിച്ച് എണ്ണുന്നതിനാൽ cyclomatic+max-lines, cognitive ബേസ്ലൈനുകൾ സ്വതന്ത്രമായി തുടരുന്നു; പ്രാദേശിക `--update`-നായി വ്യക്തിഗത `check:complexity` / `check:cognitive-complexity` നിലനിർത്തിയിട്ടുണ്ട്. +- **`/api` ആന്റി-ഹാലൂസിനേഷൻ** — ✅ **പൂർത്തിയായി** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-യുടെ ഒരൊറ്റ FS ഇൻവെന്ററി, openapi-routes + docs-symbols ഇപ്പോഴും സ്വതന്ത്രമായി റിപ്പോർട്ട് ചെയ്യുന്നു; പ്രാദേശിക റണ്ണുകൾക്കായി വ്യക്തിഗതവ നിലനിർത്തിയിട്ടുണ്ട്. +- **`check:node-runtime` 11 ജോലികളിൽ പ്രവർത്തിക്കുന്നു** — ⚠️ **കുറഞ്ഞ ROI.** ഓരോന്നും പ്രത്യേക റണ്ണറാണ്, പരിശോധന <1s ആണ്; വിലകുറഞ്ഞ ഓരോ-ജോലി സംരക്ഷണവും നഷ്ടപ്പെടുന്നതിന് പകരമായി മൊത്തം ലാഭം ~10s മാത്രം. മാറ്റത്തിന്റെ ബുദ്ധിമുട്ടിന് തക്ക മൂല്യമില്ല. +- **CI lint-ലെ `typecheck:noimplicit:core`** — ✅ **lint ജോലിയിൽ നിന്ന് നീക്കംചെയ്തു** (ഉപദേശാത്മകമായ `continue-on-error` ആയിരുന്നു); ബ്ലോക്കിങ് ടൈപ്പ് ഉപരിതലം `typecheck:core` + `check:type-coverage` ആണ്. പ്രാദേശിക സ്ക്രിപ്റ്റ് നിലനിർത്തി. ### ഫ്ലിപ്പ് / തീരുമാനം (ഓപ്പറേറ്റർ നയം) -- `check:openapi-security-tiers` (ഉപദേശാത്മകം) — ❌ **വൃത്തിയായി ഫ്ലിപ്പ് ചെയ്യാനാവില്ല.** ഇത് 0-യിൽ എക്സിറ്റ് ചെയ്യുന്നു, എന്നാൽ `LOCAL_ONLY_API_PREFIXES`-ന് കീഴിലുള്ള നിരവധി `traffic-inspector` റൂട്ടുകളിൽ `x-loopback-only: true` അനോട്ടേഷൻ ഇല്ലെന്ന് മുന്നറിയിപ്പ് നൽകുന്നു. ഇത് നിർബന്ധമാക്കുന്നതിന് ആദ്യം ആ അനോട്ടേഷനുകൾ `openapi.yaml`-ലേക്ക് ചേർക്കേണ്ടതുണ്ട്. -- `typecheck:noimplicit:core` (ഉപദേശാത്മകം) — ബ്ലോക്കിംഗ് `check:type-coverage` റാച്ചറ്റ് ഇതിനെ വലിയ തോതിൽ ഉൾക്കൊള്ളുന്നു. ഒരു റാച്ചറ്റിലേക്ക് ഫ്ലിപ്പ് ചെയ്യുക, അല്ലെങ്കിൽ ആവർത്തനപരമായ രണ്ടാമത്തെ `tsc` പാസ് ഒഴിവാക്കുക. -- `test:vitest:ui` (ഇപ്പോൾ **ബ്ലോക്കിംഗ്**) — മുമ്പേ ഉണ്ടായിരുന്ന പരാജയങ്ങൾ `vitest.config.ts`-ൽ `// #8618` ട്രാക്കിംഗ് കമന്റുകളോടെ വ്യക്തമായി ഒഴിവാക്കിയിട്ടുണ്ട്; പുതിയ പരാജയങ്ങൾ ജോലിയെ പരാജയപ്പെടുത്തും. -- `check:secrets` (gitleaks, രേഖപ്പെടുത്തിയ 3 തെറ്റായ പോസിറ്റീവുകളിൽ ഫ്രീസ് ചെയ്തിരിക്കുന്ന ബ്ലോക്കിംഗ് റാച്ചറ്റ്) — 0-ൽ എത്താൻ ആ 3 എണ്ണം allowlist ചെയ്യുക, അല്ലെങ്കിൽ ഉപദേശാത്മകമായി താഴ്ത്തുക. GitHub-ന്റെ നേറ്റീവ് secret-scanning + `check:public-creds` എന്നിവയുമായി ഓവർലാപ്പ് ചെയ്യുന്നു. -- `check:pr-evidence` (ബ്ലോക്കിംഗ്, PR-body ഗദ്യം grep ചെയ്യുന്നു) — തെറ്റായ പോസിറ്റീവുകൾക്ക് ഉയർന്ന സാധ്യത; ഒഴിവാക്കിയാൽ Hard Rule #18-ന്റെ നടപ്പാക്കൽ ദുർബലമാകും, അതിനാൽ ഇത് യഥാർഥ നയപരമായ തീരുമാനമാണ്. -- `semgrep` (സ്വതന്ത്രവും ഉപദേശാത്മകവും) — OWASP വിഭാഗങ്ങളിൽ CodeQL-മായി ഓവർലാപ്പ് ചെയ്യുന്നു; അതിന്റെ ബേസ്ലൈൻ ഒരു റാച്ചറ്റുമായി ബന്ധിപ്പിക്കുക, അല്ലെങ്കിൽ ഒഴിവാക്കുക. +- `check:openapi-security-tiers` (ഉപദേശാത്മകം) — ❌ **വൃത്തിയായി ഫ്ലിപ്പ് ചെയ്യാനാകില്ല.** ഇത് 0-ൽ എക്സിറ്റ് ചെയ്യുന്നുവെങ്കിലും `LOCAL_ONLY_API_PREFIXES`-ന്റെ കീഴിലുള്ള നിരവധി `traffic-inspector` റൂട്ടുകളിൽ `x-loopback-only: true` അനോട്ടേഷൻ ഇല്ലെന്ന് മുന്നറിയിപ്പ് നൽകുന്നു. ഇത് നിർബന്ധമാക്കുന്നതിന് ആദ്യം ആ അനോട്ടേഷനുകൾ `openapi.yaml`-ൽ ചേർക്കേണ്ടതുണ്ട്. +- `typecheck:noimplicit:core` (ഉപദേശാത്മകം) — ബ്ലോക്കിങ് `check:type-coverage` റാച്ചറ്റ് ഇതിനെ വലിയൊരളവിൽ ഉൾക്കൊള്ളുന്നു. ഒരു റാച്ചറ്റിലേക്ക് ഫ്ലിപ്പ് ചെയ്യുക, അല്ലെങ്കിൽ ആവർത്തനമായ രണ്ടാമത്തെ `tsc` പാസ് ഒഴിവാക്കുക. +- `test:vitest:ui` (ഇപ്പോൾ **ബ്ലോക്കിങ്**) — മുൻപേ നിലവിലുണ്ടായിരുന്ന പരാജയങ്ങൾ `vitest.config.ts`-ൽ `// #8618` ട്രാക്കിങ് കമന്റുകൾ ഉപയോഗിച്ച് വ്യക്തമായി ഒഴിവാക്കിയിട്ടുണ്ട്; പുതിയ പരാജയങ്ങൾ ജോലി പരാജയപ്പെടുത്തും. +- `check:secrets` (gitleaks, രേഖപ്പെടുത്തിയ 3 false-positive-ുകളിൽ ഫ്രീസ് ചെയ്ത ബ്ലോക്കിങ് റാച്ചറ്റ്) — 0-ൽ എത്താൻ ആ 3 എണ്ണം allowlist ചെയ്യുക, അല്ലെങ്കിൽ ഉപദേശാത്മകമായി തരംതാഴ്ത്തുക. GitHub-ന്റെ നേറ്റീവ് secret-scanning + `check:public-creds` എന്നിവയുമായി ഓവർലാപ്പ് ചെയ്യുന്നു. +- `check:pr-evidence` (ബ്ലോക്കിങ്, PR-body ഗദ്യം greps ചെയ്യുന്നു) — false-positive സാധ്യത ഉയർന്നതാണ്; ഒഴിവാക്കിയാൽ Hard Rule #18 നടപ്പാക്കൽ ദുർബലമാകും, അതിനാൽ ഇത് യഥാർത്ഥ നയപരമായ തീരുമാനമാണ്. +- `semgrep` (ഉപദേശാത്മക സ്വതന്ത്ര ഘടകം) — OWASP കുടുംബങ്ങളിൽ CodeQL-മായി ഓവർലാപ്പ് ചെയ്യുന്നു; അതിന്റെ ബേസ്ലൈൻ ഒരു റാച്ചറ്റുമായി ബന്ധിപ്പിക്കുക, അല്ലെങ്കിൽ ഒഴിവാക്കുക. --- diff --git a/docs/i18n/mr/CONTRIBUTING.md b/docs/i18n/mr/CONTRIBUTING.md index b3000894eca..6fa11f4365d 100644 --- a/docs/i18n/mr/CONTRIBUTING.md +++ b/docs/i18n/mr/CONTRIBUTING.md @@ -387,20 +387,20 @@ OAuth क्रेडेन्शियल्स `src/lib/oauth/constants/oauth. ## Pull Request तपासणी सूची -- [ ] चाचण्या उत्तीर्ण (`npm test`) -- [ ] लिंटिंग उत्तीर्ण (`npm run lint`) -- [ ] बिल्ड यशस्वी (`npm run build`) -- [ ] नवीन सार्वजनिक फंक्शन्स आणि इंटरफेसेससाठी TypeScript प्रकार जोडले +- [ ] चाचण्या यशस्वी होतात (`npm test`) +- [ ] लिंटिंग यशस्वी होते (`npm run lint`) +- [ ] बिल्ड यशस्वी होते (`npm run build`) +- [ ] नवीन सार्वजनिक फंक्शन्स आणि इंटरफेसेससाठी TypeScript प्रकार जोडले आहेत - [ ] कोणतीही हार्डकोड केलेली गुपिते किंवा फॉलबॅक मूल्ये नाहीत -- [ ] सार्वजनिक अपस्ट्रीम क्रेडेन्शियल्स `resolvePublicCred()` द्वारे एम्बेड केलेली आहेत ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) पहा), लिटरल्स म्हणून कधीही नाहीत -- [ ] त्रुटी प्रतिसाद `buildErrorBody()` / `sanitizeErrorMessage()` मधून पाठवले जातात — प्रतिसादांच्या बॉडीमध्ये कोणतेही रॉ स्टॅक ट्रेस नाहीत ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) पहा) +- [ ] सार्वजनिक अपस्ट्रीम क्रेडेन्शियल्स `resolvePublicCred()` द्वारे एम्बेड केली आहेत ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) पहा), लिटरल्स म्हणून कधीही नाही +- [ ] त्रुटी प्रतिसाद `buildErrorBody()` / `sanitizeErrorMessage()` द्वारे पाठवले जातात — प्रतिसादांच्या बॉडीमध्ये रॉ स्टॅक ट्रेसेस नाहीत ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) पहा) - [ ] शेल कमांड्स (`exec` / `spawn`) रनटाइम मूल्ये स्ट्रिंग इंटरपोलेशनद्वारे नव्हे, तर `env` द्वारे पाठवतात - [ ] सर्व इनपुट्स Zod स्कीमांद्वारे प्रमाणित केले आहेत -- [ ] वापरकर्त्यांना दिसणाऱ्या बदलांसाठी `changelog.d/{features|fixes|maintenance}/-.md` अंतर्गत चेंजलॉग **फ्रॅगमेंट** जोडला आहे ([`changelog.d/README.md`](./changelog.d/README.md) पहा) — `CHANGELOG.md` थेट संपादित करू **नका**; फ्रॅगमेंट्स रिलीजच्या वेळी एकत्रित केले जातात आणि PRs दरम्यान कधीही संघर्ष निर्माण करत नाहीत -- [ ] दस्तऐवजीकरण अद्ययावत केले (लागू असल्यास) +- [ ] वापरकर्त्यांना दिसणाऱ्या बदलांसाठी `changelog.d/{features|fixes|maintenance}/-.md` अंतर्गत चेंजलॉग **फ्रॅगमेंट** जोडला आहे ([`changelog.d/README.md`](./changelog.d/README.md) पहा) — `CHANGELOG.md` थेट संपादित करू **नका**; फ्रॅगमेंट्स रिलीजच्या वेळी एकत्रित केले जातात आणि PRs दरम्यान त्यांचा कधीही संघर्ष होत नाही +- [ ] दस्तऐवजीकरण अद्ययावत केले आहे (लागू असल्यास) - [ ] कोणतेही नवीन CodeQL / Secret-Scanning अलर्ट उघडलेले नाहीत किंवा प्रत्येक अलर्ट संबंधित `docs/security/` दस्तऐवजाचा संदर्भ देणाऱ्या तांत्रिक समर्थनासह डिसमिस केला आहे -- [ ] चाइल्ड प्रोसेसेस स्पॉन करणारे रूट्स (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` मधील `isLocalOnlyPath()` म्हणून वर्गीकृत केले आहेत — [कठोर नियम #15](docs/security/ROUTE_GUARD_TIERS.md) पहा -- [ ] कमिट संदेशांमध्ये कोणतेही `Co-Authored-By` ट्रेलर्स नाहीत — कमिट्स केवळ रिपॉझिटरी मालकाच्या Git ओळखीखाली दिसले पाहिजेत (कठोर नियम #16) +- [ ] चाइल्ड प्रोसेसेस सुरू करणारे रूट्स (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` मध्ये `isLocalOnlyPath()` म्हणून वर्गीकृत केले आहेत — [कठोर नियम #15](docs/security/ROUTE_GUARD_TIERS.md) पहा +- [ ] कमिट संदेशांमध्ये AI/bot `Co-authored-by` ट्रेलर्स नाहीत (कठोर नियम #16) — ज्यांचे काम पुन्हा वापरले आहे अशा मानवी सहकाऱ्यांना मानक `Co-authored-by: Name ` ट्रेलर्सद्वारे श्रेय दिले आहे --- diff --git a/docs/i18n/mr/docs/architecture/QUALITY_GATES.md b/docs/i18n/mr/docs/architecture/QUALITY_GATES.md index 9f4f1621ef3..04148937ccf 100644 --- a/docs/i18n/mr/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/mr/docs/architecture/QUALITY_GATES.md @@ -15,256 +15,257 @@ --- -## गेट इन्व्हेंटरी आणि अंमलबजावणी प्रोफाइल +## गेट इन्व्हेंटरी आणि अंमलबजावणी प्रोफाइल्स -### उमेदवार प्रवेश +### उमेदवार स्वीकृती CI आणि Quality Gates वर्कफ्लो प्रत्येकी एक स्थिर निकाल देतात: `Gate / CI` आणि -`Gate / Quality`. त्यांचे आवृत्तीकृत प्रवेश धोरण प्रत्येक अपस्ट्रीम जॉब आवश्यक किंवा सल्लागार म्हणून -सूचीबद्ध करते. लागू होणारा आवश्यक जॉब यशस्वी झालाच पाहिजे: अनुपस्थित, -रद्द केलेले, वगळलेले, प्रलंबित आणि अज्ञात निकाल PASS स्थापित करू शकत नाहीत. वैध -केवळ-दस्तऐवज किंवा केवळ-कॅटलॉग वर्गीकरणामुळे कोड लेन लागू न होणारी ठरू शकते; +`Gate / Quality`. त्यांचे आवृत्तीकृत स्वीकृती धोरण प्रत्येक अपस्ट्रीम जॉब आवश्यक +किंवा सल्लात्मक म्हणून सूचीबद्ध करते. लागू असलेला आवश्यक जॉब यशस्वी होणे आवश्यक आहे: +गहाळ, रद्द केलेले, वगळलेले, प्रलंबित आणि अज्ञात निकाल PASS सिद्ध करू शकत नाहीत. वैध +केवळ-दस्तऐवज किंवा केवळ-कॅटलॉग वर्गीकरणामुळे कोड लेन अनुपयुक्त ठरू शकते; मसुदा PR हा स्वीकारलेला उमेदवार नाही. `hotfix` लेबल पुराव्याची आवश्यकता रद्द करत नाही. -दोन्ही वर्कफ्लो PRs आणि main/release शाखांवरील pushes, manual dispatch आणि -merge-group events समाविष्ट करतात. Push, dispatch आणि merge-group पूर्ण निवड चालवतात. Forks -आणि merge groups अशा जॉबसाठी hosted runners वापरतात जे अन्यथा self-hosted -runners निवडतात; rollout पूर्वी पुरेशी hosted क्षमता सत्यापित केली पाहिजे. +दोन्ही वर्कफ्लो PRs आणि main/release शाखांवरील pushes, मॅन्युअल dispatch आणि +merge-group इव्हेंट्स समाविष्ट करतात. Push, dispatch आणि merge-group संपूर्ण निवड चालवतात. Forks +आणि merge groups अशा जॉबसाठी hosted runners वापरतात, जे अन्यथा self-hosted +runners निवडतात; रोलआउटपूर्वी पुरेशी hosted क्षमता सत्यापित करणे आवश्यक आहे. -प्रत्येक JSON पावती check out केलेला SHA, workflow run आणि attempt ओळखते. -CLI checkout/event SHA विसंगती नाकारते. Workflow tests धोरणातील सदस्यत्व -निकाल जॉबच्या `needs` सूचीशी बांधतात, जेणेकरून नवीन किंवा काढलेली लेन नकळत अदृश्य होऊ शकत नाही. -पावत्या त्यांच्या स्वतःच्या वर्कफ्लोला समाविष्ट करतात, प्रकाशन, deployment किंवा विद्यमान -सल्लागार scanner चे अंतर्गत कार्य नाही. Branch rules मध्ये दोन्ही check names सक्रिय करणे हा -स्वतंत्र प्रशासकीय बदल आहे; हे jobs जोडल्याने स्वतःहून branch संरक्षित होत नाही. +प्रत्येक JSON पावती checkout केलेला SHA, workflow run आणि attempt ओळखते. +CLI checkout/event SHA विसंगती नाकारते. Workflow चाचण्या धोरणातील सदस्यत्व +निकाल जॉबच्या `needs` सूचीशी बांधतात, ज्यामुळे एखादी नवीन किंवा काढून टाकलेली लेन लक्षात न येता अदृश्य होऊ शकत नाही. +पावत्या त्यांच्या स्वतःच्या workflow ला समाविष्ट करतात; publication, deployment किंवा +विद्यमान advisory scanner च्या अंतर्गत बाबींना नाही. Branch rules मध्ये दोन्ही check names सक्रिय करणे हा +स्वतंत्र प्रशासकीय बदल आहे; हे jobs जोडल्याने आपोआप branch संरक्षित होत नाही. -### स्थिर स्कॅन इन्व्हेंटरी +### स्टॅटिक स्कॅन इन्व्हेंटरी आवृत्तीकृत npm-alias इन्व्हेंटरी आणि static-scan सदस्यत्व `config/quality/gate-manifest.json` मध्ये आहेत. Script names आणि अचूक commands -`package.json` शी पडताळण्यासाठी `npm run check:gate-manifest` चालवा; भर, काढणे आणि -command drift मुळे local hook तसेच CI मधील change-classification jobs दोन्ही अयशस्वी होतात. -Alias हा workflow job, matrix instance किंवा test case नाही: या संख्या -परस्पर अदलाबदल करण्यायोग्य म्हणून सादर करू नयेत. - -निवडलेले aliases अंमलात न आणता तपासण्यासाठी `npm run quality:scan -- --list` किंवा `npm run quality:scan:fast -- --list` -वापरा. Runner npm entrypoint ला कॉल करतो, त्यामुळे त्याचे runtime (कॉन्फिगर केलेले असल्यास Bun सह) जतन केले जाते. -Manifest त्या profiles बाहेरील aliases स्वतंत्रपणे कॉल केलेले म्हणून नोंदवतो आणि +`package.json` शी पडताळण्यासाठी `npm run check:gate-manifest` चालवा; additions, removals आणि +command drift मुळे local hook आणि CI मधील change-classification jobs दोन्ही अयशस्वी होतात. +Alias म्हणजे workflow job, matrix instance किंवा test case नाही: या संख्या +परस्पर बदलून वापरता येण्यासारख्या म्हणून सादर करू नयेत. + +निवडलेले aliases कार्यान्वित न करता तपासण्यासाठी `npm run quality:scan -- --list` किंवा +`npm run quality:scan:fast -- --list` वापरा. +Runner npm entrypoint कार्यान्वित करतो, त्यामुळे त्याचे runtime (जिथे कॉन्फिगर केले आहे तिथे Bun सहित) जतन केले जाते. +Manifest त्या प्रोफाइल्सच्या बाहेरील aliases स्वतंत्रपणे कार्यान्वित केलेले म्हणून नोंदवतो आणि read-only scan profiles मध्ये maintenance commands प्रतिबंधित आहेत. -ही profiles केवळ static scan समाविष्ट करतात. ती product tests, -coverage, packaging, external checks किंवा उमेदवाराची पूर्ण release acceptance प्रमाणित करत नाहीत. +ही प्रोफाइल्स केवळ static scan समाविष्ट करतात. ती product tests, +coverage, packaging, external checks किंवा उमेदवाराची संपूर्ण release acceptance प्रमाणित करत नाहीत. Workflow admission लिंक केलेले `config/quality/admission-policy.json` आणि `scripts/quality/admission-verdict.mjs` वापरते. Release-observer profiles स्वतंत्र राहतात; -त्यांचे लागू होणारे checks आणि receipts स्वतंत्रपणे तपासा. खालील गद्य -इन्व्हेंटरी हा संदर्भ आहे, एखादा gate प्रत्यक्षात चालला याचा पुरावा नाही. +त्यांचे लागू checks आणि receipts स्वतंत्रपणे तपासा. खालील गद्य +इन्व्हेंटरी हा संदर्भ आहे; gate प्रत्यक्षात चालला याचा पुरावा नाही. Scripts `scripts/check/` (policy gates) आणि `scripts/quality/` (ratchet engine) अंतर्गत आहेत. -CI चा अधिकृत स्रोत `.github/workflows/ci.yml` आहे. +CI साठी सत्याचा अधिकृत स्रोत `.github/workflows/ci.yml` आहे. -### Release PR जलद मार्ग (`quality.yml`) +### Release PR जलद-मार्ग (`quality.yml`) `.github/workflows/quality.yml` हे main/release PRs, protected-branch -pushes, dispatch आणि merge groups वरील CI ला पूरक आहे. PRs path-filtered जलद checks वापरतात. कायमस्वरूपी -अक्षम केलेला duplicate build काढण्यात आला; वास्तविक build/package/boot checks CI मध्ये कायम आहेत. - -| जॉब | व्याप्ती | अवरोधक | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `Docs Gates (fast-path)` | Docs/code PRs; API docs refs आणि docs-all | होय | -| `Fast Quality Gates` | Code PRs; static checks, typecheck, dashboard typecheck, प्रभावित unit tests | होय | -| `Forgotten sibling tests` | Code PRs; बदललेल्या modules पासून static consumers आणि candidate sibling tests पर्यंत मागोवा; barrel आणि dynamic-import paths हे सल्लागार diagnostics म्हणून नोंदवले जातात, तसेच संदर्भित allowlist अपवादही नोंदवले जातात | **सल्लागार** | -| `Vitest (fast-path)` | Code PRs; जलद vitest suite | होय | -| `Unit Tests fast-path` | Code PRs; 4-shard unit suite | होय | -| `No new ESLint warnings` | Code PRs; suppressions-aware lint guard | होय, forks सह | -| `Merge integrity (changelog + generated skills)` | Non-draft PRs; changelog आणि generated skill sync | होय, forks सह | - -#### विस्मृतीत गेलेल्या sibling tests चा अहवाल - -`npm run check:forgotten-sibling-tests` test-impact map च्या मागील import resolver चा पुनर्वापर करते. +pushes, dispatch आणि merge groups वर CI ला पूरक ठरते. PRs path-filtered fast checks वापरतात. कायमस्वरूपी +अक्षम केलेला duplicate build काढून टाकण्यात आला; वास्तविक build/package/boot checks CI मध्ये कायम आहेत. + +| जॉब | व्याप्ती | अवरोधक | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `Docs Gates (fast-path)` | Docs/code PRs; API docs refs आणि docs-all | होय | +| `Fast Quality Gates` | Code PRs; static checks, typecheck, dashboard typecheck, impacted unit tests | होय | +| `Forgotten sibling tests` | Code PRs; बदललेले modules हे static consumers आणि candidate sibling tests पर्यंत ट्रेस केले जातात; barrel आणि dynamic-import paths सल्लात्मक diagnostics म्हणून नोंदवले जातात, तसेच संदर्भित allowlist exceptions | **सल्लात्मक** | +| `Vitest (fast-path)` | Code PRs; fast vitest suite | होय | +| `Unit Tests fast-path` | Code PRs; 4-shard unit suite | होय | +| `No new ESLint warnings` | Code PRs; suppressions-aware lint guard | होय, forks सहित | +| `Merge integrity (changelog + generated skills)` | मसुदा नसलेले PRs; changelog आणि generated skill sync | होय, forks सहित | + +#### विसरलेल्या sibling tests चा अहवाल + +`npm run check:forgotten-sibling-tests` test-impact map मागील import resolver पुन्हा वापरते. प्रत्येक बदललेल्या production module साठी, candidate -test pull-request diff मध्ये अनुपस्थित असताना ते निर्धारक -`changed module/symbol -> static consumer -> candidate sibling test` साखळ्या नोंदवते. कोणत्याही blocking rollout पूर्वी calibration साठी Markdown summary आणि JSON result +test हा pull-request diff मध्ये अनुपस्थित असताना ते निश्चित +`changed module/symbol -> static consumer -> candidate sibling test` साखळ्या नोंदवते. +कोणत्याही blocking rollout पूर्वी calibration करण्यासाठी Markdown summary आणि JSON result `forgotten-sibling-tests` workflow artifact म्हणून राखून ठेवले जातात. -Barrel पुनर्निर्यात आणि डायनॅमिक आयात केवळ निराकरण निदानासाठी आहेत; त्या कधीही -अवरोधक निष्कर्ष निर्माण करत नाहीत. पुनरावलोकन केलेले अपवाद +Barrel री-एक्सपोर्ट्स आणि डायनॅमिक इम्पोर्ट्स केवळ रिझोल्यूशन निदानांसाठी आहेत; ते कधीही +ब्लॉक करणारा निष्कर्ष निर्माण करत नाहीत. पुनरावलोकन केलेले अपवाद `config/quality/forgotten-sibling-allowlist.json` मध्ये असतात. प्रत्येक नोंदीमध्ये consumer आणि candidate -चाचणीचे नाव असणे, विशिष्ट कारण देणे आणि GitHub issue किंवा pull request ची लिंक देणे आवश्यक आहे. सदोष नोंदी -सुरक्षितपणे अयशस्वी होतात. अपवाद हटवलेली candidate चाचणी किंवा `.skip`/`.todo` जोडणारा diff दडपू शकत नाहीत; -assertion कमकुवत करणे आणि इतर masking स्वतंत्रपणे अवरोधक असलेल्या -`check:test-masking` gate च्याच अखत्यारीत राहतात. - -### Job: `lint` - -`main` वरील प्रत्येक PR साठी चालते. अयशस्वी झाल्यास merge अवरोधित करते. - -| Script (`npm run ...`) | काय प्रमाणित करते | अवरोधक | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | -| `check:node-runtime` | Node.js आवृत्ती समर्थित श्रेणीत आहे | होय | -| `check:cycles` | चक्रीय आयात — सर्व `src/` + `open-sse/` modules | होय | -| `check:route-validation:t06` | सर्व routes वर Zod schemas उपस्थित आहेत (Tier 6 धोरण) | होय | -| `check:any-budget:t11` | `@ts-expect-error // any` ची संख्या budget पेक्षा जास्त नाही (Tier 11 catraca) | होय | -| `check:provider-consistency` | `providers.ts` मधील प्रत्येक provider साठी `providerRegistry.ts` मध्ये जुळणारी नोंद आहे (आणि उलटही, allowlist च्या मर्यादेत) | होय | -| `check:model-lifecycle` | हाताने देखभाल केल्या जाणाऱ्या तीन routing tables, तपासून commit केलेल्या lifecycle snapshot (#11503) शी सुसंगत राहतात: `FITNESS_TABLE` (`taskFitness.ts`) अशा कोणत्याही retired id ला score देत नाही ज्याकडे `REGISTRY` route करू शकते; प्रत्येक `BUILT_IN_ALIASES` target हा `REGISTRY` मध्ये उपस्थित आणि retired-id snapshot मध्ये अनुपस्थित असतो; `REGISTRY` मध्ये अजूनही असलेला प्रत्येक retired id forward केलेला असतो किंवा `allowedRetiredInCatalog` मध्ये सूचीबद्ध असतो; आणि कोणताही `DEFAULT_DEGRADATION_MAP` source किंवा target त्या snapshot मध्ये retired म्हणून दिसत नाही. यावरून एखादे model सध्या live upstream द्वारे उपलब्ध करून दिले जात आहे, हे सिद्ध होत नाही. Offline — `config/quality/model-lifecycle.json` शी तुलना करते; ते `npm run quality:refresh-model-lifecycle` वापरून हाताने refresh केले जाते (network; CI मध्ये जोडलेले नाही). `allowedRetiredInCatalog` हा burn-down ratchet आहे: केवळ tracking issue असल्यासच नोंद जोडा. | होय | -| `check:fetch-targets` | client-side `src/` मधील प्रत्येक `fetch("/api/...")` प्रत्यक्ष `route.ts` कडे resolve होतो | होय | -| `check:deps` | repo मधील प्रत्येक `package.json` मधील `npm install` करता येणाऱ्या सर्व deps या `dependency-allowlist.json` मध्ये आहेत; नवीन unpinned किंवा slopsquatted packages flag केली जातात | होय | -| `audit:deps` | `npm audit` (root + electron) — कोणत्याही high/critical advisories नाहीत (osv `check:vuln-ratchet` शी overlap होते; Rationalization Backlog पाहा) | होय | -| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hashes, कोणतेही host overrides नाहीत | होय | -| `check:licenses` | उत्पादन अवलंबनांसाठी SPDX परवाना अनुमतसूची | होय | -| `check:tracked-artifacts` | कोणतेही बिल्ड आर्टिफॅक्ट्स / कमिट केलेले `node_modules` सिमलिंक्स नाहीत (husky pre-commit मध्येही चालते; pre-push हेतुपुरस्सर हलके ठेवले आहे — #6716) | होय | -| `check:ai-attribution` | PR कमिट्स, शीर्षक किंवा मजकुरामध्ये कोणताही AI/bot `Co-Authored-By` ट्रेलर किंवा AI-निर्मिती फूटर नाही — कठोर नियम #16 (`quality.yml` मधील PR→`release/**` साठीच्या fast-gates लूपमध्ये — इव्हेंट पेलोड वाचते, PR नसल्यास काहीही करत नाही — आणि `ci.yml` lint मधील PR→`main` साठीच्या केवळ-PR पायरीमध्ये; तसेच husky `commit-msg` हुकमध्ये; मानवी सह-लेखकांना परवानगी आहे; #14436) | -| `check:vitest-exclusions` | प्रत्येक Vitest वगळण्यात ट्रॅकिंग इश्यू नमूद केलेला असतो आणि ते `config/quality/vitest-exclusions.json` मध्ये दिसते (#13204) | होय | -| `check:file-size` | कोणतीही स्रोत फाइल प्रति-विस्तार मर्यादा ओलांडत नाही (रॅचेट: `frozen` सूचीतील गोठवलेल्या मोठ्या फाइल्स) | होय | -| `check:error-helper` | एक्झिक्युटर्स/हँडलर्समधील त्रुटी प्रतिसाद `buildErrorBody()` / `sanitizeErrorMessage()` वापरतात (कठोर नियम #12) | होय | -| `check:migration-numbering` | Migration SQL फाइल्सना कोणत्याही क्रमांकातील उड्या किंवा पुनरावृत्ती नसलेले सलग क्रमांक दिलेले आहेत | होय | -| `check:public-creds` | `publicCreds.ts` च्या बाहेर अक्षरशः नमूद केलेले OAuth `client_id`/`client_secret` किंवा Firebase Web कीज नाहीत (कठोर नियम #11) | होय | -| `check:db-rules` | `src/lib/db/` मॉड्यूल्सच्या बाहेर थेट SQL नाही; `localDb.ts` मधून बॅरल-इम्पोर्ट्स नाहीत (कठोर नियम #2/#5) | होय | -| `check:known-symbols` | त्यांच्या डिस्पॅच टेबल्समध्ये नोंदणीकृत प्रोव्हायडर एक्झिक्युटर्स, राउटिंग धोरणे आणि ट्रान्सलेटर्स डिस्कवरील फाइल्सशी जुळतात — कोणतीही अनाथ किंवा अघोषित सिंबल्स नाहीत | होय | -| `check:route-guard-membership` | चाइल्ड प्रोसेस सुरू करणारा प्रत्येक रूट `isLocalOnlyPath()` द्वारे वर्गीकृत केला जातो (कठोर नियम #15/#17) | होय | -| `check:test-discovery` | रेपोमधील प्रत्येक `*.test.ts` / `*.spec.ts` फाइल किमान एका टेस्ट रनरद्वारे संकलित केली जाते (रॅचेट: `test-discovery-baseline.json` मधील अनाथ फाइल्सची यादी केवळ कमी होऊ शकते) | होय | -| `check:agent-skills-sync` | व्युत्पन्न agent-skills आर्टिफॅक्ट्स त्यांच्या स्रोत कॅटलॉगशी जुळतात (कोणताही फरक नाही) | -| `check:provider-asset-provenance` | Provider लोगो/अॅसेट्ससाठी नोंदवलेली उगम नोंद उपलब्ध आहे | -| `lint:json` | JSON कॉन्फिगरेशन फाइल्स पार्स होतात आणि repo च्या lint नियमांची पूर्तता करतात | -| `typecheck:core` | त्रुटींशिवाय TypeScript संकलन (केवळ सल्लात्मक इशारे) | होय | -| `typecheck:noimplicit:core` | कठोर `noImplicitAny` — भविष्याभिमुख; आधीपासून अस्तित्वात असलेल्या अनेक कॉल साइट्सना अजूनही अॅनोटेशन्सची आवश्यकता आहे | **सल्लात्मक** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` पुरते मर्यादित `tsc` (#7033) — `typecheck:core` च्या निवडक 27-फाइल allowlist मध्ये कोणतेही dashboard TSX समाविष्ट नाही आणि `next build` देखील त्याचे कधीही type-checking करत नाही (`next.config.mjs` मध्ये `ignoreBuildErrors: true` सेट केले आहे), त्यामुळे तेथील orphaned-identifier regressions (#6625/#6909) CI साठी अदृश्य होते. गोठवलेल्या प्रति-फाइल/प्रति-TS-code संख्या baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` प्रमाणेच stale-enforcement नमुना) विरुद्ध फरक तपासले जातात — baseline संख्येपलीकडील केवळ नवीन त्रुटींमुळे gate अयशस्वी होते; आधीपासून अस्तित्वात असलेली त्रुटी दुरुस्त केल्यावर `--update` वापरून baseline क्रमशः कमी करा. | होय | - -### Job: `quality-gate` - -`test-coverage` नंतर चालते. अयशस्वी झाल्यास merge अवरोधित करते. - -| स्क्रिप्ट | पडताळणी | अवरोधक | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| `quality:collect` | `quality-metrics.json` तयार करते (ESLint चेतावणी संख्या, विलीन केलेल्या शार्ड अहवालातील कव्हरेज) | होय (रॅचेटच्या अपस्ट्रीममध्ये) | -| `quality:ratchet` | `quality-baseline.json` मधील प्रत्येक मेट्रिकची अधोगती झालेली नाही (ESLint चेतावण्या ≤ बेसलाइन; कव्हरेज ≥ बेसलाइन) | होय | -| `check:duplication` | कोड डुप्लिकेशन (jscpd@4) `quality-baseline.json` मधील बेसलाइनपेक्षा जास्त नाही | होय | -| `check:complexity` | फाइल-स्तरीय सायक्लोमॅटिक जटिलता कमाल मर्यादेपेक्षा जास्त नाही (कोर ESLint `complexity` + `max-lines-per-function`) | होय | -| `check:cognitive-complexity` | कॉग्निटिव्ह जटिलता रॅचेट (`eslint-plugin-sonarjs`) — स्वतंत्र ESLint पास; CI दोन्ही एकत्रित करून एकाच `check:complexity-ratchets` टप्प्याच्या रूपात चालवते | होय | -| `check:dead-code` | न वापरलेल्या एक्सपोर्ट्स / फाइल्सचे रॅचेट (knip) बेसलाइनच्या तुलनेत अधोगती होऊ देत नाही | होय | -| `check:compression-budget` | कॉम्प्रेशन बेंचमार्क बजेट — प्रत्येक इंजिनसाठी टोकन-बचतीच्या किमान मर्यादांची अधोगती होता कामा नये | होय | -| `check:type-coverage` | टाइप केलेल्या टक्केवारीचे रॅचेट (`type-coverage`) अधोगती होऊ देत नाही; मोठ्या प्रमाणात `typecheck:noimplicit:core` समाविष्ट करते | होय | -| `check:codeql-ratchet` | खुल्या CodeQL अलर्टची संख्या वाढत नाही (`gh api` द्वारे वाचते; टोकनशिवाय सुलभपणे वगळते) — रीफ्रेश वारंवारता आणि मॅन्युअल ट्रिगर: खालील "CodeQL रॅचेट" पहा | होय | +test नमूद करणे, विशिष्ट कारण देणे आणि GitHub issue किंवा pull request ची लिंक देणे आवश्यक आहे. चुकीच्या स्वरूपातील नोंदी +fail closed होतात. अपवाद हटवलेली candidate test किंवा `.skip`/`.todo` जोडणारा diff दडपू शकत नाहीत; +assertion कमकुवत करणे आणि इतर masking यांची जबाबदारी स्वतंत्रपणे ब्लॉक करणाऱ्या +`check:test-masking` gate कडेच राहते. + +### जॉब: `lint` + +`main` वरील प्रत्येक PR साठी चालतो. अपयश आल्यास merge ब्लॉक करतो. + +| स्क्रिप्ट (`npm run ...`) | काय प्रमाणित करते | ब्लॉक करणारे | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `check:node-runtime` | Node.js आवृत्ती समर्थित श्रेणीत आहे | होय | +| `check:cycles` | संपूर्ण `src/` + `open-sse/` मधील circular imports (AST-आधारित, tsconfig `paths` resolve केलेले). स्वतंत्रपणे चालवल्यास = सल्लात्मक, cycles ची सूची दाखवते. `check:cycles:ratchet` (जे CI चालवते) `quality-baseline.json` मधील `metrics.cycles` कमाल मर्यादेपेक्षा संख्या जास्त झाल्यास ब्लॉक करते — सध्या 14, `direction: down`, त्यामुळे ती केवळ कमी होऊ शकते (#15159 G-01/G-02) | होय (ratchet) | +| `check:route-validation:t06` | सर्व routes वर Zod schemas उपस्थित आहेत (Tier 6 धोरण) | होय | +| `check:any-budget:t11` | `@ts-expect-error // any` ची संख्या budget पेक्षा जास्त नाही (Tier 11 catraca) | होय | +| `check:provider-consistency` | `providers.ts` मधील प्रत्येक provider साठी `providerRegistry.ts` मध्ये जुळणारी नोंद आहे (आणि उलटही, allowlist च्या मर्यादेत) | होय | +| `check:model-lifecycle` | हाताने सांभाळले जाणारे तीन routing tables तपासून ठेवलेल्या lifecycle snapshot (#11503) शी सुसंगत राहतात: `FITNESS_TABLE` (`taskFitness.ts`) अशा कोणत्याही निवृत्त id ला score देत नाही ज्याकडे `REGISTRY` route करू शकते; प्रत्येक `BUILT_IN_ALIASES` target `REGISTRY` मध्ये उपस्थित आणि retired-id snapshot मध्ये अनुपस्थित आहे; `REGISTRY` मध्ये अजूनही असलेला प्रत्येक निवृत्त id पुढे पाठवला जातो किंवा `allowedRetiredInCatalog` मध्ये सूचीबद्ध केला जातो; आणि कोणताही `DEFAULT_DEGRADATION_MAP` source किंवा target त्या snapshot मध्ये निवृत्त म्हणून दिसत नाही. यावरून एखादे model सध्या थेट upstream द्वारे उपलब्ध केले जात आहे, हे सिद्ध होत नाही. Offline — `config/quality/model-lifecycle.json` शी तुलना करते; हे `npm run quality:refresh-model-lifecycle` वापरून हाताने refresh केले जाते (network; CI मध्ये जोडलेले नाही). `allowedRetiredInCatalog` हे burn-down ratchet आहे: tracking issue असल्यासच नोंद जोडा. | होय | +| `check:fetch-targets` | client-side `src/` मधील प्रत्येक `fetch("/api/...")` वास्तविक `route.ts` शी resolve होतो | होय | +| `check:deps` | repo मधील प्रत्येक `package.json` तील सर्व `npm install`-योग्य deps `dependency-allowlist.json` मध्ये आहेत; नवीन unpinned किंवा slopsquatted packages flag केले जातात | होय | +| `audit:deps` | `npm audit` (root + electron) — कोणतेही high/critical advisories नाहीत (osv `check:vuln-ratchet` शी overlap होते; Rationalization Backlog पहा) | होय | +| `check:lockfile` | `package-lock.json` ची अखंडता — https registry, integrity hashes, कोणतेही host overrides नाहीत | होय | +| `check:licenses` | उत्पादन अवलंबनांसाठी SPDX परवाना अनुमतसूची | होय | +| `check:tracked-artifacts` | कोणतीही बिल्ड आर्टिफॅक्ट्स / कमिट केलेल्या `node_modules` सिमलिंक्स नाहीत (husky pre-commit मध्येही चालते; pre-push हेतुपुरस्सर हलके ठेवले आहे — #6716) | होय | +| `check:ai-attribution` | PR कमिट्स, शीर्षक किंवा मजकुरात कोणताही AI/bot `Co-Authored-By` ट्रेलर किंवा AI-निर्मिती फूटर नाही — कठोर नियम #16 (`quality.yml` मधील PR→`release/**` साठीच्या fast-gates लूपमध्ये — इव्हेंट पेलोड वाचतो, PR नसल्यास काहीही करत नाही — आणि `ci.yml` lint मध्ये PR→`main` साठी केवळ-PR पायरी; तसेच husky `commit-msg` हुक; मानवी सह-लेखकांना परवानगी आहे; #14436) | +| `check:vitest-exclusions` | प्रत्येक Vitest वगळण्यात ट्रॅकिंग इश्यू नमूद केलेला असतो आणि ते `config/quality/vitest-exclusions.json` मध्ये दिसते (#13204) | होय | +| `check:file-size` | कोणतीही स्रोत फाइल प्रति-विस्तार मर्यादा ओलांडत नाही (रॅचेट: `frozen` सूचीतील गोठवलेल्या मोठ्या फाइल्स) | होय | +| `check:error-helper` | executors/handlers मधील त्रुटी प्रतिसाद `buildErrorBody()` / `sanitizeErrorMessage()` वापरतात (कठोर नियम #12) | होय | +| `check:migration-numbering` | Migration SQL फाइल्सना कोणतीही पोकळी किंवा डुप्लिकेट नसलेले सलग क्रमांक दिलेले आहेत | होय | +| `check:public-creds` | `publicCreds.ts` च्या बाहेर कोणतेही अक्षरशः OAuth `client_id`/`client_secret` किंवा Firebase Web कीज नाहीत (कठोर नियम #11) | होय | +| `check:db-rules` | `src/lib/db/` मॉड्यूल्सच्या बाहेर कोणतेही रॉ SQL नाही; `localDb.ts` मधून कोणतेही barrel-imports नाहीत (कठोर नियम #2/#5) | होय | +| `check:known-symbols` | त्यांच्या dispatch tables मध्ये नोंदणीकृत provider executors, routing strategies आणि translators हे डिस्कवरील फाइल्सशी जुळतात — कोणतेही अनाथ किंवा अघोषित symbols नाहीत | होय | +| `check:route-guard-membership` | child process सुरू करणारा प्रत्येक route `isLocalOnlyPath()` द्वारे वर्गीकृत केला जातो (कठोर नियम #15/#17) | होय | +| `check:test-discovery` | repo मधील प्रत्येक `*.test.ts` / `*.spec.ts` फाइल किमान एका test runner द्वारे संकलित केली जाते (ratchet: `test-discovery-baseline.json` मधील orphan list फक्त कमी होऊ शकते) | होय | +| `check:agent-skills-sync` | व्युत्पन्न agent-skills आर्टिफॅक्ट्स त्यांच्या स्रोत कॅटलॉगशी जुळतात (कोणताही फरक नाही) | +| `check:provider-asset-provenance` | प्रदाता लोगो/आर्टिफॅक्ट्ससाठी नोंदवलेली उगम नोंद उपलब्ध आहे | +| `lint:json` | JSON कॉन्फिगरेशन फाइल्स पार्स होतात आणि रेपोच्या लिंट नियमांची पूर्तता करतात | +| `typecheck:core` | त्रुटींविना TypeScript संकलन (केवळ सल्लात्मक इशारे) | होय | +| `typecheck:noimplicit:core` | कठोर `noImplicitAny` — भविष्योन्मुख; आधीपासून अस्तित्वात असलेल्या अनेक कॉल साइट्सना अजूनही ॲनोटेशन्सची आवश्यकता आहे | **सल्लात्मक** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` पुरते मर्यादित `tsc` (#7033) — `typecheck:core` च्या काळजीपूर्वक निवडलेल्या 27-फाइल अनुमतीसूचीत कोणतेही डॅशबोर्ड TSX समाविष्ट नाही आणि `next build` देखील त्याची कधीही प्रकार-तपासणी करत नाही (`next.config.mjs` मध्ये `ignoreBuildErrors: true` सेट केले आहे), त्यामुळे तेथील अनाथ-आयडेंटिफायर रिग्रेशन्स (#6625/#6909) CI ला दिसत नव्हते. गोठवलेल्या प्रति-फाइल/प्रति-TS-कोड संख्या बेसलाइनशी (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` प्रमाणेच जुन्या नोंदींच्या अंमलबजावणीचा नमुना) फरक तपासते — बेसलाइन संख्येपलीकडील केवळ नवीन त्रुटींमुळे गेट अयशस्वी होते; आधीपासून असलेली त्रुटी दुरुस्त केल्यावर `--update` वापरून बेसलाइन कमी करा. | होय | + +### जॉब: `quality-gate` + +`test-coverage` नंतर चालतो. अयशस्वी झाल्यास मर्ज अवरोधित करतो. + +| स्क्रिप्ट | काय प्रमाणित करते | अवरोधक | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `quality:collect` | `quality-metrics.json` तयार करते (ESLint चेतावण्यांची संख्या, विलीन केलेल्या शार्ड अहवालातील कव्हरेज) | होय (रॅचेटच्या अपस्ट्रीमला) | +| `quality:ratchet` | `quality-baseline.json` मधील प्रत्येक मेट्रिकची घसरण झालेली नाही (ESLint चेतावण्या ≤ बेसलाइन; कव्हरेज ≥ बेसलाइन) | होय | +| `check:duplication` | कोडची पुनरावृत्ती (jscpd@4) `quality-baseline.json` मधील बेसलाइनपेक्षा जास्त नाही | होय | +| `check:complexity` | फाइल-स्तरीय सायक्लोमॅटिक जटिलता कमाल मर्यादेपेक्षा जास्त नाही (मूलभूत ESLint `complexity` + `max-lines-per-function`) | होय | +| `check:cognitive-complexity` | संज्ञानात्मक जटिलता रॅचेट (`eslint-plugin-sonarjs`) — स्वतंत्र ESLint पास; CI हे दोन्ही एकत्रित करून एकच `check:complexity-ratchets` चरण म्हणून चालवते | होय | +| `check:dead-code` | न वापरलेल्या एक्सपोर्ट्स / फाइल्सच्या रॅचेटची (knip) बेसलाइनच्या तुलनेत घसरण होत नाही | होय | +| `check:compression-budget` | कॉम्प्रेशन बेंचमार्क बजेट — प्रत्येक इंजिनसाठी टोकन-बचतीच्या किमान मर्यादांची घसरण होता कामा नये | होय | +| `check:type-coverage` | टाइप केलेल्या कोडच्या टक्केवारीचे रॅचेट (`type-coverage`) घसरत नाही; हे बहुतांशी `typecheck:noimplicit:core` समाविष्ट करते | होय | +| `check:codeql-ratchet` | उघड्या CodeQL अलर्टची संख्या वाढत नाही (`gh api` द्वारे वाचते; टोकन नसल्यास सुरळीतपणे वगळते) — रीफ्रेश वारंवारता आणि मॅन्युअल ट्रिगर: खालील "CodeQL रॅचेट" पहा | होय | ### जॉब: `quality-extended` -संपूर्ण जॉब सल्लात्मक आहे (`continue-on-error: true`). npm-आधारित रॅचेट्स प्रत्यक्षात -चालतात; बाह्य स्कॅनर्स `gh release download` द्वारे इन्स्टॉल होतात आणि बायनरी अद्याप -अनुपस्थित असल्यास स्वतःहून वगळले जातात (exit 0). +संपूर्ण जॉब सल्लागार स्वरूपाचा आहे (`continue-on-error: true`). npm-आधारित रॅचेट्स +प्रत्यक्ष चालतात; बाह्य स्कॅनर्स `gh release download` द्वारे स्थापित होतात आणि बायनरी अद्याप +उपलब्ध नसल्यास स्वतःच वगळले जातात (exit 0). -| स्क्रिप्ट | पडताळणी | अवरोधक | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -| `check:circular-deps` | कोणतीही चक्रीय अवलंबित्वे नाहीत (dpdm) | **सल्लात्मक** | -| `check:bundle-size` | बंडलचा आकार कमाल मर्यादेपेक्षा जास्त नाही | **सल्लात्मक** | -| `check:secrets` | गुपितांचे स्कॅनिंग (gitleaks) — बायनरी अनुपस्थित असल्यास वगळते | **सल्लात्मक** | -| `check:vuln-ratchet` | अवलंबित्वांमधील असुरक्षितता (osv-scanner) वाढत नाही — बायनरी अनुपस्थित असल्यास वगळते | **सल्लात्मक** | -| `check:workflows` | वर्कफ्लो लिंट (actionlint + zizmor); स्कॅनर्स अनुपस्थित/बिघडलेले असणे, अवैध अहवाल किंवा रॅचेट बेसलाइन अनुपस्थित असणे यामुळे INCOMPLETE म्हणून अपयश येते. वैध निष्कर्ष निवडलेल्या strict/advisory/ratchet धोरणाचे पालन करतात | अंमलबजावणी आवश्यक; CI मध्ये zizmor रॅचेट अवरोधक आहे | -| `check:openapi-breaking` | बेस ब्रँचच्या तुलनेत सार्वजनिक API करारातील (`openapi.yaml`) ब्रेकिंग बदल (oasdiff) — `openapiBreaking=N` उत्सर्जित करते; oasdiff अनुपस्थित असल्यास किंवा बेस स्पेकचे निराकरण शक्य नसल्यास वगळते | **सल्लात्मक** | +| स्क्रिप्ट | काय प्रमाणित करते | अवरोधक स्थिती | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `check:circular-deps` | कोणतीही चक्रीय अवलंबित्वे नाहीत (dpdm) | **सल्लागार** | +| `check:bundle-size` | बंडलचा आकार कमाल मर्यादेपेक्षा जास्त नाही | **सल्लागार** | +| `check:secrets` | गुपितांचे स्कॅनिंग (gitleaks) — बायनरी उपलब्ध नसल्यास वगळते | **सल्लागार** | +| `check:vuln-ratchet` | अवलंबित्वांमधील असुरक्षा (osv-scanner) वाढत नाहीत — बायनरी उपलब्ध नसल्यास वगळते | **सल्लागार** | +| `check:workflows` | वर्कफ्लो लिंट (actionlint + zizmor); स्कॅनर्स अनुपलब्ध/बिघडलेले असल्यास, अहवाल अवैध असल्यास किंवा रॅचेट बेसलाइन अनुपलब्ध असल्यास INCOMPLETE म्हणून अपयशी ठरते. वैध निष्कर्ष निवडलेल्या कठोर/सल्लागार/रॅचेट धोरणाचे पालन करतात | अंमलबजावणी आवश्यक; CI मध्ये zizmor रॅचेट अवरोधक | +| `check:openapi-breaking` | बेस ब्रँचच्या तुलनेत सार्वजनिक API करारामधील (`openapi.yaml`) ब्रेकिंग बदल (oasdiff) — `openapiBreaking=N` तयार करते; oasdiff उपलब्ध नसल्यास किंवा बेस स्पेसिफिकेशनचे निराकरण शक्य नसल्यास वगळते | **सल्लागार** | ### जॉब: `docs-sync-strict` -`main` कडे असलेल्या प्रत्येक PR वर चालतो. अपयश आल्यास मर्ज अवरोधित करतो. - -| स्क्रिप्ट | काय सत्यापित करते | अवरोधक | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `check:docs-all` | खालील 6 उप-गेट्स अनुक्रमाने चालवणारा मेटा-गेट | होय | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt आवृत्ती सुसंगतता | होय | -| ↳ `check:docs-counts` | गद्यातील मोजण्या (प्रदाता संख्या, माइग्रेशन संख्या इ.) वास्तविक मोजण्यांच्या रॅचेट मर्यादेत आहेत | होय | -| ↳ `check:env-doc-sync` | `.env.example` मधील प्रत्येक env var दस्तऐवजांच्या तक्त्यात नोंदवलेला आहे आणि त्याउलटही | होय | -| ↳ `check:deprecated-versions` | दस्तऐवजांमध्ये कालबाह्य आवृत्ती स्ट्रिंग नाहीत | होय | -| ↳ `check:doc-links` | दस्तऐवजांमधील अंतर्गत markdown दुवे वास्तविक फाइल्सकडे निर्देशित होतात (`[text]`/`(path)` स्वरूप) | होय | -| ↳ `check:fabricated-docs` | दस्तऐवजांत नमूद केलेले routes, env vars, CLI commands, hook names आणि file paths कोडबेसमध्ये अस्तित्वात आहेत. `--strict` द्वारे कठोर गेट; फ्लॅगशिवाय सौम्य अपयश. | होय (CI मध्ये `--strict` द्वारे) | -| `check:cli-i18n` | CLI command strings सर्व i18n locale files मध्ये उपलब्ध आहेत | होय | -| `check:openapi-coverage` | OpenAPI spec मध्ये वास्तविक routes च्या किमान रॅचेट केलेल्या मर्यादेइतके कव्हरेज आहे | होय | -| `check:openapi-security-tiers` | `openapi.yaml` मधील सुरक्षा स्तर भाष्ये `routeGuard.ts` वर्गीकरणांशी सुसंगत आहेत | **सल्लात्मक** | -| `check:openapi-routes` | `openapi.yaml` मधील प्रत्येक path वास्तविक `route.ts` कडे निर्देशित होतो (कल्पित माहितीविरोधी) | होय | -| `check:docs-symbols` | `docs/**/*.md` मधील प्रत्येक `/api/...` संदर्भ वास्तविक `route.ts` कडे निर्देशित होतो (कल्पित माहितीविरोधी) | होय | -| `i18n translation drift` | i18n locale files मधील अनुवाद न केलेल्या keys — केवळ इशारा | **सल्लात्मक** | +`main` वरील प्रत्येक PR साठी चालते. अपयश आल्यास मर्ज अवरोधित करते. + +| स्क्रिप्ट | काय सत्यापित करते | अवरोधक | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `check:docs-all` | खालील 6 उप-गेट्स अनुक्रमे चालवणारे मेटा-गेट | होय | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt आवृत्तीतील सुसंगतता | होय | +| ↳ `check:docs-counts` | गद्यातील संख्या (प्रदात्यांची संख्या, स्थलांतरांची संख्या इ.) वास्तविक संख्यांच्या रॅचेट मर्यादेत आहेत | होय | +| ↳ `check:env-doc-sync` | `.env.example` मधील प्रत्येक पर्यावरणीय चल दस्तऐवजांच्या तक्त्यात नोंदवलेला आहे आणि त्याउलटही | होय | +| ↳ `check:deprecated-versions` | दस्तऐवजांमध्ये कालबाह्य आवृत्ती स्ट्रिंग नाहीत | होय | +| ↳ `check:doc-links` | दस्तऐवजांमधील अंतर्गत markdown दुवे वास्तविक फाइल्सकडे निर्देशित होतात (`[text]`/`(path)` स्वरूप) | होय | +| ↳ `check:fabricated-docs` | दस्तऐवजांमध्ये उद्धृत केलेले रूट्स, पर्यावरणीय चल, CLI कमांड्स, हुकची नावे आणि फाइल पाथ्स कोडबेसमध्ये अस्तित्वात आहेत. `--strict` द्वारे कठोर गेट; फ्लॅगशिवाय सौम्य अपयश. | होय (CI मध्ये `--strict` द्वारे) | +| `check:cli-i18n` | CLI कमांड स्ट्रिंग्स सर्व i18n लोकेल फाइल्समध्ये उपस्थित आहेत | होय | +| `check:openapi-coverage` | OpenAPI तपशील वास्तविक रूट्सच्या किमान रॅचेट केलेल्या तळमर्यादेला व्यापतो | होय | +| `check:openapi-security-tiers` | `openapi.yaml` मधील सुरक्षा स्तर भाष्ये `routeGuard.ts` वर्गीकरणांशी सुसंगत आहेत | **सल्लात्मक** | +| `check:openapi-routes` | `openapi.yaml` मधील प्रत्येक पाथ वास्तविक `route.ts` कडे निर्देशित होतो (भ्रमनिर्मितीविरोधी) | होय | +| `check:docs-symbols` | `docs/**/*.md` मधील प्रत्येक `/api/...` संदर्भ वास्तविक `route.ts` कडे निर्देशित होतो (भ्रमनिर्मितीविरोधी) | होय | +| `i18n translation drift` | i18n लोकेल फाइल्समधील अनुवाद न केलेल्या की — केवळ इशारा | **सल्लात्मक** | ### जॉब: `i18n-ui-coverage` -| स्क्रिप्ट | काय सत्यापित करते | अवरोधक | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `check-ui-keys-coverage` (inline) | UI i18n key कव्हरेज ≥ 65% आहे | होय | -| `check-ui-value-drift` (inline) | पुन्हा लिहिलेल्या इंग्रजी **मूल्यामुळे** कोणताही जुना अनुवाद मागे राहत नाही | होय | -| `check-new-key-coverage` (inline) | एखादी **नवीन** इंग्रजी key प्रत्येक locale मध्ये अनुवादित केली आहे — `__MISSING__:` marker नाकारला जातो | होय | -| `check-translation-ratio` | प्रत्येक locale साठी वास्तविक-अनुवाद गुणोत्तर (allowlist बाहेरील इंग्रजीशी-समान / placeholder / missing leaves) `config/quality/i18n-translation-baseline.json` + slack पेक्षा अधिक नसावे | **सल्लात्मक** | +| स्क्रिप्ट | काय सत्यापित करते | अवरोधक | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `check-ui-keys-coverage` (इनलाइन) | UI i18n की कव्हरेज ≥ 65% आहे | होय | +| `check-ui-value-drift` (इनलाइन) | पुन्हा लिहिलेल्या इंग्रजी **मूल्यामुळे** कोणताही कालबाह्य अनुवाद मागे राहत नाही | होय | +| `check-new-key-coverage` (इनलाइन) | **नवीन** इंग्रजी की प्रत्येक लोकेलमध्ये अनुवादित केलेली आहे — `__MISSING__:` मार्कर नाकारला जातो | होय | +| `check-translation-ratio` | प्रत्येक लोकेलसाठी वास्तविक-अनुवाद गुणोत्तर (इंग्रजीशी समान / प्लेसहोल्डर / अनुमतीसूचीबाहेरील गहाळ लीफ) `config/quality/i18n-translation-baseline.json` + शिथिलता यापेक्षा अधिक नसावे | **सल्लात्मक** | -`fetch-depth: 0` आवश्यक आहे — value-drift gate merge base च्या तुलनेत `en.json` चा फरक तपासतो. +`fetch-depth: 0` आवश्यक आहे — मूल्य-ड्रिफ्ट गेट मर्ज बेसच्या तुलनेत `en.json` चा फरक तपासतो. -#### `check-ui-value-drift` — जुना-अनुवाद गेट +#### `check-ui-value-drift` — कालबाह्य-अनुवाद गेट -इतर गेट्सना रचनात्मकदृष्ट्या दिसू न शकणारी i18n मधील एक त्रुटी हे पकडते: इंग्रजी मूल्य -पुन्हा लिहिले जाते आणि _मागील_ इंग्रजीवरून तयार केलेले अनुवाद तसेच मागे राहतात, त्यामुळे -इंग्रजीतर वापरकर्ते आत्मविश्वासाने लिहिलेला, पण आता चुकीचा असलेला मजकूर वाचत राहतात. +इतर गेट्सना संरचनात्मकदृष्ट्या दिसू न शकणारी एक i18n प्रतिगती हे पकडते: एखादे इंग्रजी मूल्य +पुन्हा लिहिले जाते आणि _मागील_ इंग्रजीवर आधारित अनुवाद तसेच मागे राहतात, त्यामुळे +इंग्रजीतर वापरकर्ते आत्मविश्वासपूर्ण शैलीतील, पण आता चुकीचा असलेला मजकूर वाचत राहतात. -हे प्रत्यक्षात रिलीझ झाले होते. Antigravity login helper जोडला गेला तेव्हा (#5203) -`oauthModal.googleOAuthWarning` पुन्हा लिहिले गेले; **43 पैकी 39 locales** मध्ये operators ना -"संपूर्ण URL कॉपी करा आणि खाली पेस्ट करा" असे सांगणारा मजकूर कायम राहिला — त्या प्रदात्यासाठी -पूर्णच होऊ न शकणारी प्रक्रिया. #8463 पर्यंत ही बाब लक्षात आली नाही, कारण: +हे प्रत्यक्षात रिलीज झाले होते. Antigravity लॉगिन सहाय्यक जोडला गेला तेव्हा (#5203) +`oauthModal.googleOAuthWarning` पुन्हा लिहिले गेले; **43 पैकी 39 लोकेल्समध्ये** ऑपरेटर्सना "संपूर्ण +URL कॉपी करा आणि खाली पेस्ट करा" असे सांगणारा मजकूर कायम राहिला — अशी प्रक्रिया जी त्या प्रदात्यासाठी पूर्णच होऊ शकत नाही. #8463 पर्यंत +हे लक्षात आले नाही, कारण: -- `sync-ui-keys` केवळ **अनुपस्थित** keys भरून काढते, **जुन्या** keys कधीही नाही; -- `check-ui-keys-coverage` key ची _उपस्थिती_ मोजते, त्यामुळे जुना अनुवादही कव्हर झालेला म्हणून गणला जातो; -- `check-translation-drift` हे `docs/i18n//**.md` दस्तऐवजीकरण mirrors ट्रॅक करते — - ते `src/i18n/messages/*.json` कधीही वाचत नाही. 2026-09 re-sync पासून `docs-sync-strict` जॉबमध्ये अवरोधक: - मुख्य दस्तऐवज संपादित करा → `npm run i18n:run -- --files=` (विभाग-स्तरीय, कमी खर्चिक). +- `sync-ui-keys` केवळ **अनुपस्थित** की भरतो, **कालबाह्य** की कधीही भरत नाही; +- `check-ui-keys-coverage` कीची _उपस्थिती_ मोजतो, त्यामुळे कालबाह्य अनुवाद कव्हर झालेला म्हणून गणला जातो; +- `check-translation-drift` हे `docs/i18n//**.md` दस्तऐवजीकरण प्रतिबिंबांचा मागोवा घेते — + ते `src/i18n/messages/*.json` कधीही वाचत नाही. 2026-09 पुनः-सिंक्रोनायझेशनपासून `docs-sync-strict` जॉबमध्ये अवरोधक: मुख्य दस्तऐवज संपादित करा → `npm run i18n:run -- --files=` (विभाग-स्तरीय, कमी खर्चिक). -**फरक-जागरूक, आधाररेषेवर अवलंबून नाही.** हे merge base वरील `en.json` ची working tree शी तुलना करते; ज्या प्रत्येक key चे इंग्रजी मूल्य बदलले आहे, त्या key साठी अजूनही न बदललेले भाषांतर असलेले कोणतेही locale कालबाह्य मानले जाते. यामुळे जाणीवपूर्वक **आधीपासून अस्तित्वात असलेले तांत्रिक ऋण गोठवले जाते** — दीर्घकाळापासून असलेले भाषांतर कोणत्या जुन्या इंग्रजी मजकुरावरून आले आहे हे diff मधून समजू शकत नाही, त्यामुळे gate फक्त सध्याच्या बदलाने स्पर्श केलेल्या गोष्टींचेच मूल्यमापन करते. पर्यायी पद्धतीसाठी (प्रत्येक key साठी hash baseline) ~600 KB ची generated file लागेल, जी सध्या अस्तित्वात असलेल्या सर्वांत मोठ्या baseline च्या 3 पट आहे आणि प्रत्येक i18n PR वर बदलत राहील. +**फरक-जागरूक, आधाररेषेवर अवलंबून नाही.** हे मर्ज बेसवरील `en.json` ची वर्किंग ट्रीशी तुलना करते; ज्या प्रत्येक कीचे इंग्रजी मूल्य बदलले आहे, त्या कीसाठी अजूनही न बदललेले भाषांतर असलेले कोणतेही लोकेल कालबाह्य मानले जाते. हे जाणीवपूर्वक **आधीपासूनचे प्रलंबित काम गोठवते** — दीर्घकाळ अस्तित्वात असलेले भाषांतर कोणत्या जुन्या इंग्रजी मजकुरावरून आले हे फरकातून समजू शकत नाही, त्यामुळे गेट केवळ सध्याच्या बदलाने स्पर्श केलेल्या गोष्टींचे मूल्यमापन करते. पर्यायासाठी (प्रत्येक कीसाठी हॅश आधाररेषा) सुमारे 600 KB आकाराची जनरेट केलेली फाइल लागेल, जी विद्यमान सर्वांत मोठ्या आधाररेषेच्या 3× असेल आणि प्रत्येक i18n PR वेळी बदलेल. -याची पूर्तता करण्याचे दोन मार्ग: +ही अट पूर्ण करण्याचे दोन मार्ग: 1. प्रभावित भाषांतरे अद्ययावत करा, किंवा -2. ती `__MISSING__:` अशी सेट करा — त्यानंतर runtime सुधारित इंग्रजी मजकूर पुरवतो - (`src/i18n/request.ts::deepMergeFallback`, #7258) आणि ती key भाषांतरासाठी रांगेत जाते. +2. त्यांना `__MISSING__:` असे सेट करा — त्यानंतर रनटाइम सुधारित इंग्रजी मजकूर देते + (`src/i18n/request.ts::deepMergeFallback`, #7258) आणि ती की भाषांतरासाठी रांगेत जाते. -जर string चा **अर्थ** बदलला असेल, तर **key चे नाव बदलण्यास** प्राधान्य द्या: नवीन key ला कालबाह्य भाषांतर वारशाने मिळू शकत नाही. #8463 मध्ये हाच नमुना वापरला होता. +स्ट्रिंगचा **अर्थ** बदलला असल्यास, **कीचे नाव बदलण्याला** प्राधान्य द्या: नवीन कीला कालबाह्य भाषांतर वारशाने मिळू शकत नाही. #8463 मध्ये हाच पॅटर्न वापरला होता. ```bash -npm run i18n:check-value-drift # कठोर (CI जे चालवते) -npm run i18n:check-value-drift:warn # फक्त अहवाल +npm run i18n:check-value-drift # कठोर (CI जे चालवते ते) +npm run i18n:check-value-drift:warn # केवळ अहवाल BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -base catalog वाचता येत नसल्यास (base ref नसलेला shallow clone), `check-openapi-breaking` प्रमाणेच `SKIP reason=base-unresolved` सह 0 exit code देते. +बेस कॅटलॉग वाचता येत नसल्यास (`base ref` नसलेला shallow clone), `check-openapi-breaking` प्रमाणेच `SKIP reason=base-unresolved` सह 0 एक्झिट कोड देते. -### Job: `i18n` +### जॉब: `i18n` -संपूर्ण i18n प्रमाणीकरण matrix (प्रत्येक locale साठी एक job). संपूर्ण job सल्लात्मक आहे. +संपूर्ण i18n प्रमाणीकरण मॅट्रिक्स (प्रत्येक लोकेलसाठी एक जॉब). संपूर्ण जॉब सल्लात्मक आहे. -| Script | काय प्रमाणित करते | अवरोधक | -| ------------------------------- | --------------------------------------- | -------------------------------------------------------- | -| `validate_translation.py quick` | प्रत्येक locale साठी भाषांतराची पूर्णता | **सल्लात्मक** (संपूर्ण job वर `continue-on-error: true`) | +| स्क्रिप्ट | काय प्रमाणित करते | ब्लॉकिंग | +| ------------------------------- | ------------------------------------- | ------------------------------------------------------- | +| `validate_translation.py quick` | प्रत्येक लोकेलसाठी भाषांतराची पूर्णता | **सल्लात्मक** (संपूर्ण जॉबवर `continue-on-error: true`) | -### Job: `pr-test-policy` +### जॉब: `pr-test-policy` फक्त pull requests वर चालते. -| Script | काय प्रमाणित करते | अवरोधक | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, किंवा `bin/` मधील production code बदलणाऱ्या PRs मध्ये tests समाविष्ट किंवा अद्ययावत करणे आवश्यक आहे (Hard Rule #8) | होय | -| `check:test-masking` | बदललेल्या test files मुळे निव्वळ assert संख्या कमी होत नाही किंवा `assert.ok(true)` tautologies जोडल्या जात नाहीत | होय | -| `check:pr-evidence` | PR body मध्ये बदलासाठी test/VPS पुराव्याचा संदर्भ असतो (PR prose grep करून Hard Rule #18 स्वयंचलित करते — नाजूक आहे, Backlog पहा) | होय | +| स्क्रिप्ट | काय प्रमाणित करते | ब्लॉकिंग | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, किंवा `bin/` मधील प्रॉडक्शन कोड बदलणाऱ्या PRs मध्ये चाचण्यांचा समावेश किंवा अद्ययावत चाचण्या असणे आवश्यक आहे (कठोर नियम #8) | होय | +| `check:test-masking` | बदललेल्या चाचणी फाइल्स निव्वळ assert संख्या कमी करत नाहीत किंवा `assert.ok(true)` सारखी स्वयंसिद्ध विधाने जोडत नाहीत | होय | +| `check:pr-evidence` | PR च्या मजकुरात बदलासाठी चाचणी/VPS पुराव्याचा उल्लेख आहे (PR मधील गद्य मजकुरावर grep करून कठोर नियम #18 यांत्रिकरीत्या लागू करते — नाजूक; Backlog पहा) | होय | -### Job: `test-vitest` +### जॉब: `test-vitest` -`build` नंतर चालते. अपयश आल्यास merge अवरोधित करते. +`build` नंतर चालते. अपयशी झाल्यास मर्ज ब्लॉक करते. -| Suite | काय प्रमाणित करते | अवरोधक | -| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | होय | -| `test:vitest:ui` | UI component tests — vitest runner | **अवरोधक** — आधीपासूनची अपयशे `vitest.config.ts` मध्ये स्पष्टपणे वगळली आहेत; नवीन अपयशांमुळे job अयशस्वी होतो | +| संच | काय प्रमाणित करते | ब्लॉकिंग | +| ---------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP सर्व्हर (110 टूल्स), autoCombo, cache — vitest रनर | होय | +| `test:vitest:ui` | UI कॉम्पोनंट चाचण्या — vitest रनर | **ब्लॉकिंग** — आधीपासूनची अपयशे `vitest.config.ts` मध्ये स्पष्टपणे वगळली आहेत; नवीन अपयशांमुळे जॉब अपयशी होतो | -### रात्रीचे workflows (नियोजित, सल्लात्मक) +### रात्रीच्या वर्कफ्लोज (शेड्यूल केलेले, सल्लात्मक) -हे cron schedule वर (आणि `workflow_dispatch` द्वारे) चालतात, PRs वर कधीही चालत नाहीत. सर्व सल्लात्मक आहेत. +हे cron शेड्यूलवर (आणि `workflow_dispatch` द्वारे) चालतात, PRs वर कधीही चालत नाहीत. हे सर्व सल्लात्मक आहेत. -| Workflow | काय प्रमाणित करते | अवरोधक | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `nightly-property` | random seed + उच्च run count सह fast-check property tests | **सल्लात्मक** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **सल्लात्मक** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret शिवाय वगळले जातात) | **सल्लात्मक** | -| `nightly-schemathesis` | `docs/openapi.yaml` वापरून live OmniRoute विरुद्ध OpenAPI contract fuzzing (schemathesis) — spec उल्लंघने / हाताळले न गेलेले 500s समोर आणते (Fase 8 B.4) | **सल्लात्मक** | -| `nightly-mutation` | fast unit lane वरील Stryker mutation-testing score — टिकून राहिलेले mutants कमकुवत asserts समोर आणतात | **सल्लात्मक** | -| `nightly-compat` | समर्थित `engines.node` ranges मधील Node engine compatibility matrix | **सल्लात्मक** | +| वर्कफ्लो | काय प्रमाणित करते | ब्लॉकिंग | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `nightly-property` | यादृच्छिक seed आणि मोठ्या run count सह fast-check property चाचण्या | **सल्लात्मक** | +| `nightly-resilience` | heap-growth गेट, chaos fault-injection, k6 load/soak | **सल्लात्मक** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret शिवाय वगळले जातात) | **सल्लात्मक** | +| `nightly-schemathesis` | `docs/openapi.yaml` वापरून लाइव्ह OmniRoute विरुद्ध OpenAPI contract fuzzing (schemathesis) — स्पेसिफिकेशनचे उल्लंघन / न हाताळलेल्या 500s उघड करते (Fase 8 B.4) | **सल्लात्मक** | +| `nightly-mutation` | जलद unit lane वरील Stryker mutation-testing स्कोअर — टिकून राहिलेले mutants कमकुवत asserts उघड करतात | **सल्लात्मक** | +| `nightly-compat` | समर्थित `engines.node` श्रेणींमधील Node engine सुसंगतता मॅट्रिक्स | **सल्लात्मक** | --- @@ -526,43 +527,43 @@ CI गेटच्या पलीकडे, OmniRoute मध्ये **ऐच --- -## सुसूत्रीकरण प्रलंबित कामे (ROI पुनरावलोकन — टप्पा 9 लाट 3) +## सुसूत्रीकरण अनुशेष (ROI पुनरावलोकन — टप्पा 9 लाट 3) -ही यादी 2026-06-17 रोजी `ci.yml` शी ताळमेळ करून अद्ययावत केली होती (आधीच्या आवृत्तीत +ही सूची 2026-06-17 रोजी `ci.yml` च्या तुलनेत समेट करण्यात आली होती (आधीच्या आवृत्तीमध्ये `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` वगळले गेले होते). ताळमेळ केलेल्या संचाच्या ROI पुनरावलोकनातून -खालील सुसूत्रीकरणाचे उमेदवार ओळखले गेले. **विलीनीकरणे ही यांत्रिक CI -बदल आहेत; स्थिती-बदल/वगळणे हे ऑपरेटरसाठी राखीव धोरणात्मक निर्णय आहेत.** खालीलपैकी काहीही +`check:codeql-ratchet`, `check:pr-evidence` वगळले गेले होते). समेट केलेल्या संचाच्या ROI पुनरावलोकनाने +खालील सुसूत्रीकरण उमेदवार ओळखले. **विलीनीकरणे ही यांत्रिक CI +बदल आहेत; फ्लिप/वगळण्याचे निर्णय हे ऑपरेटरसाठी राखीव धोरणात्मक निर्णय आहेत.** खालीलपैकी काहीही अद्याप लागू केलेले नाही. -**वरील भागात ज्यांचे दस्तऐवजीकरणही झालेले नाही** (सल्लात्मक, कमी संकेतक्षम): `docs-lint` जॉब -(markdownlint + Vale, संपूर्ण जॉबसाठी `continue-on-error`) आणि स्वतंत्र स्कॅनर वर्कफ्लो +**वर दस्तऐवजीकरण न केलेले आणखी घटक** (सल्लात्मक, कमी संकेत): `docs-lint` जॉब +(markdownlint + Vale, संपूर्ण जॉब `continue-on-error`) आणि स्वतंत्र स्कॅनर वर्कफ्लो `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` हे `quality-baseline.json` मध्ये आहे, परंतु `ci.yml` मधील ब्लॉकिंग रॅचेटशी जोडलेले नाही — हे मेट्रिक सध्या अनाथ आहे. -### विलीनीकरण / डुप्लिकेशन काढणे (यांत्रिक, कमी जोखीम) +### विलीनीकरण / डिड्युप्लिकेशन (यांत्रिक, कमी जोखीम) -प्रत्येक उमेदवाराची 2026-06-17 रोजी प्रत्यक्ष गेट स्थितीशी पडताळणी केली होती (विश्वास ठेवा, पण पडताळा); -अनेक "स्पष्ट" वाटणारी विलीनीकरणे प्रत्यक्षात प्रलंबित तांत्रिक कर्ज लपवत असल्याचे आढळले आणि ती **स्वच्छ पर्याय** नाहीत. +प्रत्येक उमेदवाराची 2026-06-17 रोजी प्रत्यक्ष गेट स्थितीच्या तुलनेत पडताळणी करण्यात आली (विश्वास ठेवा, पण पडताळा); +अनेक "सुस्पष्ट" विलीनीकरणांमध्ये तांत्रिक ऋण दडलेले असल्याचे आढळले आणि ती **स्वच्छ थेट पर्याय** नाहीत. -- **`check:docs-sync` दोनदा चालते** — `lint` जॉबमध्ये स्वतंत्रपणे आणि पुन्हा `check:docs-all` (`docs-sync-strict`) व husky pre-commit हुकमध्ये. ✅ **पूर्ण** — स्वतंत्र `lint` आवाहन काढले. -- **CVE स्कॅनिंग** — ❌ **स्वच्छ विलीनीकरण नाही.** कोणत्याही उच्च/गंभीर CVE वर `audit:deps` थेट अपयशी ठरते; `check:vuln-ratchet` (osv) फक्त आधाररेषेच्या तुलनेत _प्रतिगमन_ झाल्यास अपयशी ठरते (सध्या 1 MODERATE). अर्थविषयक वर्तन वेगळे आहे — `audit:deps` वगळल्यास निरपेक्ष उच्च/गंभीर गेट गमावले जाईल. दोन्ही ठेवा. -- **चक्रीय अवलंबित्व शोधणे** — ❌ **स्वच्छ विलीनीकरण नाही.** `check:circular-deps` (dpdm) **91 चक्रे** नोंदवते (म्हणूनच ते सल्लात्मक आहे); ती आधी सोडवल्याशिवाय त्याला ब्लॉकिंग दर्जा देता येणार नाही आणि त्याची व्याप्ती हिरव्या स्थितीतील, निवडक `check:cycles` पेक्षा व्यापक आहे. `check:cycles` ब्लॉकिंग ठेवा; 91 dpdm चक्रे सोडवणे हे स्वतंत्र प्रलंबित काम आहे. -- **जटिलता** — ✅ **पूर्ण** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): एक ESLint फेरी, `ruleId` नुसार मोजणी, त्यामुळे cyclomatic+max-lines आणि cognitive आधाररेषा स्वतंत्र राहतात; स्थानिक `--update` साठी स्वतंत्र `check:complexity` / `check:cognitive-complexity` कायम आहेत. -- **`/api` भ्रमविरोधी तपासणी** — ✅ **पूर्ण** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ची एक FS यादी, openapi-routes + docs-symbols अजूनही स्वतंत्रपणे अहवाल देतात; स्थानिक रनसाठी स्वतंत्र तपासण्या कायम आहेत. -- **`check:node-runtime` 11 जॉबमध्ये चालते** — ⚠️ **कमी ROI.** प्रत्येक स्वतंत्र रनर आहे आणि तपासणी <1s आहे; स्वस्त प्रति-जॉब संरक्षक गमावण्याच्या बदल्यात एकूण बचत ~10s. या उलथापालथीचे मूल्य नाही. -- **CI lint वरील `typecheck:noimplicit:core`** — ✅ **lint जॉबमधून काढले** (ते सल्लात्मक `continue-on-error` होते); ब्लॉकिंग प्रकार-पृष्ठभाग म्हणजे `typecheck:core` + `check:type-coverage`. स्थानिक स्क्रिप्ट कायम ठेवली. +- **`check:docs-sync` दोनदा चालते** — `lint` जॉबमध्ये स्वतंत्रपणे आणि पुन्हा `check:docs-all` (`docs-sync-strict`) तसेच husky pre-commit हुकमध्ये. ✅ **पूर्ण** — स्वतंत्र `lint` आवाहन काढून टाकले. +- **CVE स्कॅनिंग** — ❌ **स्वच्छ विलीनीकरण नाही.** कोणत्याही उच्च/गंभीर CVE वर `audit:deps` हार्ड-फेल होते; `check:vuln-ratchet` (osv) फक्त आधाररेषेच्या तुलनेत _प्रतिगमन_ झाल्यास अपयशी होते (सध्या 1 MODERATE). अर्थभेद आहेत — `audit:deps` वगळल्यास निरपेक्ष उच्च/गंभीर गेट नष्ट होईल. दोन्ही ठेवा. +- **चक्र शोध** — ✅ **पूर्ण** (#15159 G-01/G-02). येथील जुन्या मजकुराने `check:cycles` ला "हिरवा, निवडक" गेट म्हटले होते आणि `check:circular-deps` (dpdm) ने 91 चक्रे नोंदवल्यामुळे ते ब्लॉकिंग ठेवण्याचे समर्थन केले होते. तो हिरवा निकाल **खोटा हिरवा** होता: `check:cycles` ने 5 उपनिर्देशिका (450 फाइल्स) स्कॅन केल्या, फक्त स्थिर `import|export … from` जुळवले आणि प्रत्येक `@/` व `@omniroute/open-sse/` स्पेसिफायर वगळला, त्यामुळे रेपोमध्ये प्रबळ असलेली डायनॅमिक-import + alias चक्रे त्याला दिसू शकली नाहीत. दुरुस्त केले: गेट आता `src` + `open-sse` (5023 फाइल्स) मधून जाते, TypeScript AST मधून स्पेसिफायर संकलित करते (म्हणून `import("…")` मोजले जाते आणि type-position `typeof import("…")` मोजले जात नाही), तसेच tsconfig `paths` रिजॉल्व्ह करते. त्याला 0 नव्हे, तर **14** चक्रे आढळतात. आधीपासून अस्तित्वात असलेली 14 चक्रे गेट PR मध्ये दुरुस्त करता येत नसल्यामुळे, `check:cycles` आता **रॅचेट** आहे (`--ratchet`, `quality-baseline.json` मध्ये कमाल मर्यादा `metrics.cycles.value = 14`, `direction: down`) — ते कोणतेही _प्रतिगमन_ ब्लॉक करते आणि संख्या फक्त कमी होऊ शकते. CI मध्ये `npm run check:cycles:ratchet` चालते. कमी करण्याचे काम **A-01** सोबत केले जाईल. व्यापक दुसरे मत म्हणून `check:circular-deps` (dpdm) सल्लात्मक राहते. +- **गुंतागुंत** — ✅ **पूर्ण** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): एक ESLint वॉक, ruleId नुसार मोजणी, जेणेकरून cyclomatic+max-lines आणि cognitive आधाररेषा स्वतंत्र राहतील; स्थानिक `--update` साठी स्वतंत्र `check:complexity` / `check:cognitive-complexity` कायम राहतात. +- **`/api` भ्रम-विरोधी तपासणी** — ✅ **पूर्ण** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ची एक FS सूची, openapi-routes + docs-symbols अजूनही स्वतंत्रपणे अहवाल देतात; स्थानिक रनसाठी स्वतंत्र तपासण्या कायम राहतात. +- **`check:node-runtime` 11 जॉबमध्ये चालते** — ⚠️ **कमी ROI.** प्रत्येक स्वतंत्र रनर आहे आणि तपासणी <1s आहे; स्वस्त प्रति-जॉब संरक्षक गमावण्याच्या बदल्यात एकूण बचत ~10s. या उलथापालथीची किंमत योग्य नाही. +- **CI lint वरील `typecheck:noimplicit:core`** — ✅ **lint जॉबमधून काढले** (पूर्वी सल्लात्मक `continue-on-error` होते); ब्लॉकिंग प्रकार-पृष्ठभाग म्हणजे `typecheck:core` + `check:type-coverage`. स्थानिक स्क्रिप्ट कायम ठेवली. -### स्थिती बदला / निर्णय घ्या (ऑपरेटर धोरण) +### फ्लिप / निर्णय (ऑपरेटर धोरण) -- `check:openapi-security-tiers` (सल्लात्मक) — ❌ **स्वच्छपणे स्थिती बदलता येत नाही.** ते 0 सह बाहेर पडते, पण `LOCAL_ONLY_API_PREFIXES` अंतर्गत असलेल्या अनेक `traffic-inspector` रूट्समध्ये `x-loopback-only: true` भाष्य नसल्याची चेतावणी देते. त्याची अंमलबजावणी सक्तीची करण्यासाठी आधी `openapi.yaml` मध्ये ती भाष्ये जोडावी लागतील. -- `typecheck:noimplicit:core` (सल्लात्मक) — ब्लॉकिंग `check:type-coverage` रॅचेटने बहुतांशी समाविष्ट केलेले आहे. त्याला रॅचेटमध्ये बदला किंवा अनावश्यक दुसरी `tsc` फेरी वगळा. -- `test:vitest:ui` (आता **ब्लॉकिंग**) — आधीपासून अस्तित्वात असलेली अपयशे `vitest.config.ts` मध्ये `// #8618` ट्रॅकिंग टिप्पण्यांसह स्पष्टपणे वगळली आहेत; नवीन अपयशांमुळे जॉब अपयशी ठरतो. -- `check:secrets` (gitleaks, दस्तऐवजीकरण केलेल्या 3 चुकीच्या सकारात्मक निष्कर्षांवर गोठवलेले ब्लॉकिंग रॅचेट) — 0 पर्यंत पोहोचण्यासाठी त्या 3 नोंदी allowlist मध्ये जोडा किंवा सल्लात्मक दर्जावर आणा. GitHub चे मूळ secret-scanning + `check:public-creds` यांच्याशी आच्छादन आहे. -- `check:pr-evidence` (ब्लॉकिंग, PR-body मधील गद्य मजकूर grep करते) — चुकीच्या सकारात्मक निष्कर्षांचा उच्च धोका; वगळल्यास Hard Rule #18 ची अंमलबजावणी कमकुवत होते, त्यामुळे हा खरोखरच धोरणात्मक निर्णय आहे. -- `semgrep` (स्वतंत्र सल्लात्मक तपासणी) — OWASP कुटुंबांसाठी CodeQL शी आच्छादन आहे; त्याची आधाररेषा रॅचेटशी जोडा किंवा ते वगळा. +- `check:openapi-security-tiers` (सल्लात्मक) — ❌ **स्वच्छपणे फ्लिप करता येत नाही.** ते 0 सह बाहेर पडते, परंतु `LOCAL_ONLY_API_PREFIXES` अंतर्गत अनेक `traffic-inspector` रूट्समध्ये `x-loopback-only: true` भाष्य नसल्याची चेतावणी देते. त्याची अंमलबजावणी करण्यासाठी आधी `openapi.yaml` मध्ये ही भाष्ये जोडावी लागतील. +- `typecheck:noimplicit:core` (सल्लात्मक) — ब्लॉकिंग `check:type-coverage` रॅचेटमध्ये मोठ्या प्रमाणावर समाविष्ट आहे. रॅचेटमध्ये फ्लिप करा किंवा अनावश्यक दुसरा `tsc` पास वगळा. +- `test:vitest:ui` (आता **ब्लॉकिंग**) — आधीपासून अस्तित्वात असलेली अपयशे `vitest.config.ts` मध्ये `// #8618` ट्रॅकिंग टिप्पण्यांसह स्पष्टपणे वगळली आहेत; नवीन अपयशांमुळे जॉब अपयशी होतो. +- `check:secrets` (gitleaks, 3 दस्तऐवजीकृत चुकीच्या-सकारात्मक निकालांवर गोठवलेले ब्लॉकिंग रॅचेट) — 0 पर्यंत पोहोचण्यासाठी त्या 3 निकालांना allowlist मध्ये जोडा किंवा सल्लात्मक स्तरावर अवनत करा. GitHub चे मूळ secret-scanning + `check:public-creds` यांच्याशी आच्छादित होते. +- `check:pr-evidence` (ब्लॉकिंग, PR-body मधील गद्य मजकुरावर grep करते) — चुकीच्या-सकारात्मक निकालांचा उच्च धोका; वगळल्यास कठोर नियम #18 ची अंमलबजावणी कमकुवत होते, त्यामुळे हा खरोखरच धोरणात्मक निर्णय आहे. +- `semgrep` (स्वतंत्र सल्लात्मक) — OWASP कुटुंबांसाठी CodeQL शी आच्छादित होते; त्याची आधाररेषा रॅचेटशी जोडा किंवा वगळा. --- diff --git a/docs/i18n/ms/CONTRIBUTING.md b/docs/i18n/ms/CONTRIBUTING.md index 1bb3f9ad7e0..e8e80e7f712 100644 --- a/docs/i18n/ms/CONTRIBUTING.md +++ b/docs/i18n/ms/CONTRIBUTING.md @@ -389,19 +389,19 @@ Tulis ujian unit dalam `tests/unit/` yang sekurang-kurangnya merangkumi: ## Senarai Semak Pull Request - [ ] Ujian lulus (`npm test`) -- [ ] Pelintiran lulus (`npm run lint`) +- [ ] Pelintan lulus (`npm run lint`) - [ ] Binaan berjaya (`npm run build`) - [ ] Jenis TypeScript ditambahkan untuk fungsi dan antara muka awam baharu - [ ] Tiada rahsia atau nilai sandaran yang dikod keras -- [ ] Bukti kelayakan huluan awam dibenamkan melalui `resolvePublicCred()` (lihat [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), bukan sebagai nilai literal -- [ ] Respons ralat disalurkan melalui `buildErrorBody()` / `sanitizeErrorMessage()` — tiada surihan tindanan mentah dalam badan respons (lihat [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Kelayakan huluan awam dibenamkan melalui `resolvePublicCred()` (lihat [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), bukan sebagai literal +- [ ] Respons ralat disalurkan melalui `buildErrorBody()` / `sanitizeErrorMessage()` — tiada surih tindanan mentah dalam badan respons (lihat [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Perintah shell (`exec` / `spawn`) menghantar nilai masa jalan melalui `env`, bukan melalui interpolasi rentetan - [ ] Semua input disahkan dengan skema Zod -- [ ] **Fragmen** log perubahan ditambahkan di bawah `changelog.d/{features|fixes|maintenance}/-.md` untuk perubahan yang dapat dilihat oleh pengguna (lihat [`changelog.d/README.md`](./changelog.d/README.md)) — jangan edit `CHANGELOG.md` secara langsung; fragmen dihimpunkan semasa keluaran dan tidak akan bercanggah antara PR +- [ ] **Fragmen** log perubahan ditambahkan di bawah `changelog.d/{features|fixes|maintenance}/-.md` untuk perubahan yang memberi kesan kepada pengguna (lihat [`changelog.d/README.md`](./changelog.d/README.md)) — **jangan** edit `CHANGELOG.md` secara langsung; fragmen digabungkan semasa keluaran dan tidak pernah bercanggah antara PR - [ ] Dokumentasi dikemas kini (jika berkenaan) -- [ ] Tiada amaran CodeQL / Secret-Scanning baharu dibuka, atau setiap amaran ditolak dengan justifikasi teknikal yang merujuk dokumen `docs/security/` yang berkaitan -- [ ] Laluan yang melancarkan proses anak (`/api/mcp/`, `/api/cli-tools/runtime/`) diklasifikasikan sebagai `isLocalOnlyPath()` dalam `src/server/authz/routeGuard.ts` — lihat [Peraturan Tegas #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Tiada treler `Co-Authored-By` dalam mesej komit — komit mesti dipaparkan semata-mata di bawah identiti Git pemilik repositori (Peraturan Tegas #16) +- [ ] Tiada amaran CodeQL / Secret-Scanning baharu dibuka, atau setiap satunya ditolak dengan justifikasi teknikal yang merujuk dokumen `docs/security/` yang berkaitan +- [ ] Laluan yang mencetuskan proses anak (`/api/mcp/`, `/api/cli-tools/runtime/`) diklasifikasikan sebagai `isLocalOnlyPath()` dalam `src/server/authz/routeGuard.ts` — lihat [Peraturan Tegas #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Tiada treler `Co-authored-by` AI/bot dalam mesej komit (Peraturan Tegas #16) — kolaborator manusia yang hasil kerja mereka digunakan semula diberi penghargaan dengan treler standard `Co-authored-by: Name ` --- diff --git a/docs/i18n/ms/docs/architecture/QUALITY_GATES.md b/docs/i18n/ms/docs/architecture/QUALITY_GATES.md index 2e186f8a8be..9143fb05ea0 100644 --- a/docs/i18n/ms/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ms/docs/architecture/QUALITY_GATES.md @@ -17,83 +17,81 @@ bebas alat bagi sistem yang sama, lihat ## Inventori get dan profil pelaksanaan -### Penerimaan calon +### Kemasukan calon Aliran kerja CI dan Quality Gates masing-masing menghasilkan keputusan yang stabil: `Gate / CI` dan -`Gate / Quality`. Dasar penerimaan berversi mereka menyenaraikan setiap tugas huluan -sebagai wajib atau nasihat. Tugas wajib yang berkenaan mesti berjaya: hasil yang tiada, +`Gate / Quality`. Dasar kemasukan berversi mereka menyenaraikan setiap kerja huluan +sebagai wajib atau nasihat. Kerja wajib yang berkenaan mesti berjaya: hasil yang tiada, dibatalkan, dilangkau, belum selesai dan tidak diketahui tidak boleh menetapkan PASS. Pengelasan docs-only atau catalog-only yang sah boleh menjadikan laluan kod tidak berkenaan; -PR draf bukan calon yang diterima. Label `hotfix` tidak mengetepikan bukti. +PR draf bukan calon yang diterima. Label `hotfix` tidak mengetepikan keperluan bukti. -Kedua-dua aliran kerja meliputi PR dan push ke cabang main/release, pencetusan manual dan -peristiwa merge-group. Push, dispatch dan merge-group menjalankan pemilihan penuh. Fork -dan merge group menggunakan pelaksana dihoskan untuk tugas yang sebaliknya memilih pelaksana -dihoskan sendiri; kapasiti hos yang mencukupi mesti disahkan sebelum pelaksanaan. +Kedua-dua aliran kerja meliputi PR dan tolakan ke cabang main/release, pelaksanaan manual dan +peristiwa kumpulan cantuman. Tolakan, pelaksanaan dan kumpulan cantuman menjalankan pemilihan penuh. Fork +dan kumpulan cantuman menggunakan pelaksana yang dihoskan untuk kerja yang sebaliknya memilih pelaksana +dihoskan sendiri; kapasiti pengehosan yang mencukupi mesti disahkan sebelum pelaksanaan secara meluas. -Setiap resit JSON mengenal pasti SHA yang di-checkout, pelaksanaan aliran kerja dan percubaan. +Setiap resit JSON mengenal pasti SHA yang telah di-checkout, pelaksanaan aliran kerja dan percubaan. CLI menolak ketidakpadanan SHA checkout/peristiwa. Ujian aliran kerja mengikat keahlian dasar -kepada senarai `needs` tugas keputusan supaya laluan baharu atau yang dialih keluar tidak boleh -hilang secara senyap. Resit tersebut meliputi aliran kerjanya sendiri, bukan penerbitan, -penggunaan, atau kandungan dalaman pengimbas nasihat yang sedia ada. Mengaktifkan kedua-dua -nama semakan dalam peraturan cabang ialah perubahan pentadbiran yang berasingan; penambahan -tugas ini tidak dengan sendirinya melindungi cabang. +kepada senarai `needs` bagi kerja keputusan supaya laluan baharu atau yang dialih keluar tidak boleh lenyap secara senyap. +Resit meliputi aliran kerja masing-masing, bukan penerbitan, penggunaan, atau aspek dalaman +pengimbas nasihat sedia ada. Mengaktifkan kedua-dua nama semakan dalam peraturan cabang ialah +perubahan pentadbiran yang berasingan; penambahan kerja ini tidak dengan sendirinya melindungi cabang. ### Inventori imbasan statik -Inventori npm-alias berversi dan keahlian imbasan statik disimpan dalam +Inventori alias npm berversi dan keahlian imbasan statik berada dalam `config/quality/gate-manifest.json`. Jalankan `npm run check:gate-manifest` untuk mengesahkan -nama skrip dan arahan tepat dengan `package.json`; penambahan, pengalihan keluar dan -perubahan arahan akan menggagalkan kedua-dua hook setempat dan tugas pengelasan perubahan dalam CI. -Alias bukan tugas aliran kerja, tika matriks atau kes ujian: kiraan ini tidak boleh +nama skrip dan arahan tepat terhadap `package.json`; penambahan, pengalihan keluar dan +perubahan arahan menyebabkan kegagalan pada cangkuk setempat serta kerja pengelasan perubahan dalam CI. +Alias bukan kerja aliran kerja, tika matriks atau kes ujian: kiraan ini tidak boleh dikemukakan sebagai boleh saling ditukar ganti. Gunakan `npm run quality:scan -- --list` atau `npm run quality:scan:fast -- --list` -untuk memeriksa alias yang dipilih tanpa melaksanakannya. Pelaksana memanggil titik masuk -npm, maka masa jalan alias tersebut (termasuk Bun apabila dikonfigurasikan) dikekalkan. +untuk memeriksa alias yang dipilih tanpa melaksanakannya. Pelaksana memanggil +titik masuk npm, maka masa jalanannya (termasuk Bun apabila dikonfigurasikan) dikekalkan. Manifes merekodkan alias di luar profil tersebut sebagai dipanggil secara berasingan, dan arahan penyelenggaraan dilarang dalam profil imbasan baca sahaja. Profil ini meliputi imbasan statik sahaja. Profil ini tidak memperakui ujian produk, liputan, pembungkusan, semakan luaran atau penerimaan keluaran penuh calon. -Penerimaan aliran kerja menggunakan `config/quality/admission-policy.json` yang dipautkan dan -`scripts/quality/admission-verdict.mjs`. Profil release-observer kekal berasingan; -periksa semakan dan resit yang berkenaan secara berasingan. Inventori -prosa di bawah ialah rujukan, bukan bukti bahawa get benar-benar dilaksanakan. +Kemasukan aliran kerja menggunakan `config/quality/admission-policy.json` yang dipautkan dan +`scripts/quality/admission-verdict.mjs`. Profil pemerhati keluaran kekal berasingan; +periksa semakan dan resit yang berkenaan secara bebas. Inventori prosa +di bawah ialah rujukan, bukan bukti bahawa get benar-benar telah dijalankan. Skrip berada di bawah `scripts/check/` (get dasar) dan `scripts/quality/` (enjin ratchet). Sumber kebenaran CI ialah `.github/workflows/ci.yml`. ### Laluan pantas PR keluaran (`quality.yml`) -`.github/workflows/quality.yml` melengkapi CI pada PR main/release, push cabang -terlindung, dispatch dan merge group. PR menggunakan semakan pantas yang ditapis mengikut laluan. -Binaan pendua yang dilumpuhkan secara kekal telah dialih keluar; semakan build/package/boot -sebenar kekal dalam CI. - -| Tugas | Skop | Menyekat | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `Docs Gates (fast-path)` | PR dokumentasi/kod; rujukan dokumentasi API dan docs-all | Ya | -| `Fast Quality Gates` | PR kod; semakan statik, typecheck, typecheck papan pemuka, ujian unit terjejas | Ya | -| `Forgotten sibling tests` | PR kod; modul diubah dijejaki kepada pengguna statik dan ujian setara calon; laluan barrel dan dynamic-import dilaporkan sebagai diagnostik nasihat, dengan pengecualian senarai izin yang dirujuk | **Nasihat** | -| `Vitest (fast-path)` | PR kod; suit vitest pantas | Ya | -| `Unit Tests fast-path` | PR kod; suit unit 4 serpihan | Ya | -| `No new ESLint warnings` | PR kod; pengadang lint yang mengambil kira penyekatan | Ya, termasuk fork | -| `Merge integrity (changelog + generated skills)` | PR bukan draf; penyegerakan log perubahan dan kemahiran yang dijana | Ya, termasuk fork | +`.github/workflows/quality.yml` melengkapi CI pada PR main/release, tolakan cabang +terlindung, pelaksanaan dan kumpulan cantuman. PR menggunakan semakan pantas yang ditapis mengikut laluan. Binaan pendua yang +dilumpuhkan secara kekal telah dialih keluar; semakan binaan/pakej/boot sebenar kekal dalam CI. + +| Kerja | Skop | Menyekat | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `Docs Gates (fast-path)` | PR dokumentasi/kod; rujukan dokumentasi API dan docs-all | Ya | +| `Fast Quality Gates` | PR kod; semakan statik, semakan jenis, semakan jenis papan pemuka, ujian unit terjejas | Ya | +| `Forgotten sibling tests` | PR kod; modul yang diubah dijejaki kepada pengguna statik dan ujian setara calon; laluan barrel dan import dinamik dilaporkan sebagai diagnostik nasihat, dengan pengecualian senarai dibenarkan yang dirujuk | **Nasihat** | +| `Vitest (fast-path)` | PR kod; suit vitest pantas | Ya | +| `Unit Tests fast-path` | PR kod; suit unit 4 syard | Ya | +| `No new ESLint warnings` | PR kod; pengadang lint yang mengambil kira penindasan | Ya, termasuk fork | +| `Merge integrity (changelog + generated skills)` | PR bukan draf; penyegerakan log perubahan dan kemahiran terjana | Ya, termasuk fork | #### Laporan ujian setara yang terlupa `npm run check:forgotten-sibling-tests` menggunakan semula penyelesai import di sebalik peta impak ujian. Bagi setiap modul pengeluaran yang diubah, ia melaporkan rantaian -`changed module/symbol -> static consumer -> candidate sibling test` yang berketentuan apabila ujian -calon tiada daripada diff pull-request. Ringkasan Markdown dan hasil JSON disimpan sebagai -artifak aliran kerja `forgotten-sibling-tests` untuk penentukuran sebelum sebarang pelaksanaan yang menyekat. +`modul/simbol yang diubah -> pengguna statik -> ujian setara calon` secara berketentuan apabila ujian +calon tiada dalam perbezaan permintaan tarik. Ringkasan Markdown dan hasil JSON disimpan sebagai +artifak aliran kerja `forgotten-sibling-tests` untuk penentukuran sebelum sebarang pelaksanaan secara meluas yang menyekat. Eksport semula barrel dan import dinamik hanyalah diagnostik resolusi; ia tidak pernah menghasilkan -penemuan yang menyekat. Pengecualian yang telah disemak berada dalam -`config/quality/forgotten-sibling-allowlist.json`. Setiap entri mesti menamakan pengguna dan ujian calon, -memberikan rasional khusus, serta memautkan isu atau pull request GitHub. Entri yang tidak sah akan gagal -secara tertutup. Pengecualian tidak boleh menyekat ujian calon yang telah dipadamkan atau diff yang menambahkan `.skip`/`.todo`; +dapatan yang menyekat. Pengecualian yang telah disemak disimpan dalam +`config/quality/forgotten-sibling-allowlist.json`. Setiap entri mesti menyatakan pengguna dan ujian +calon, memberikan rasional khusus, serta memautkan isu atau permintaan tarik GitHub. Entri yang tidak +terbentuk dengan betul akan gagal secara tertutup. Pengecualian tidak boleh menyekat ujian calon yang dipadam atau perbezaan yang menambahkan `.skip`/`.todo`; pelemahan penegasan dan penyamaran lain kekal di bawah tanggungjawab pagar `check:test-masking` yang menyekat secara bebas. @@ -101,130 +99,128 @@ pelemahan penegasan dan penyamaran lain kekal di bawah tanggungjawab pagar Dijalankan pada setiap PR ke `main`. Menyekat penggabungan jika gagal. -| Skrip (`npm run ...`) | Mengesahkan | Menyekat | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Versi Node.js berada dalam julat yang disokong | Ya | -| `check:cycles` | Import berkitar — semua modul `src/` + `open-sse/` | Ya | -| `check:route-validation:t06` | Skema Zod tersedia pada semua laluan (dasar Peringkat 6) | Ya | -| `check:any-budget:t11` | Bilangan `@ts-expect-error // any` tidak melebihi belanjawan (catraca Peringkat 11) | Ya | -| `check:provider-consistency` | Setiap penyedia dalam `providers.ts` mempunyai entri yang sepadan dalam `providerRegistry.ts` (dan sebaliknya, dalam senarai dibenarkan) | Ya | -| `check:model-lifecycle` | Tiga jadual penghalaan yang diselenggara secara manual kekal konsisten dengan petikan kitar hayat yang dimasukkan ke dalam repositori (#11503): `FITNESS_TABLE` (`taskFitness.ts`) tidak memberikan skor kepada mana-mana id yang telah ditamatkan tetapi masih boleh dihalakan oleh `REGISTRY`; setiap sasaran `BUILT_IN_ALIASES` terdapat dalam `REGISTRY` dan tiada dalam petikan id yang telah ditamatkan; setiap id yang telah ditamatkan tetapi masih berada dalam `REGISTRY` dimajukan atau disenaraikan dalam `allowedRetiredInCatalog`; dan tiada sumber atau sasaran `DEFAULT_DEGRADATION_MAP` ditandai sebagai telah ditamatkan dalam petikan tersebut. Ini tidak membuktikan bahawa sesuatu model sedang disediakan oleh perkhidmatan huluan yang aktif. Luar talian — dibandingkan dengan `config/quality/model-lifecycle.json`, yang disegarkan secara manual menggunakan `npm run quality:refresh-model-lifecycle` (rangkaian; tidak disepadukan ke dalam CI). `allowedRetiredInCatalog` ialah mekanisme sehala untuk mengurangkan item secara beransur-ansur: tambahkan entri hanya jika terdapat isu penjejakan. | Ya | -| `check:fetch-targets` | Setiap `fetch("/api/...")` dalam `src/` sebelah klien merujuk kepada `route.ts` yang sebenar | Ya | -| `check:deps` | Semua kebergantungan yang boleh dipasang dengan `npm install` merentas setiap `package.json` dalam repositori terdapat dalam `dependency-allowlist.json`; pakej baharu yang tidak dikunci versinya atau disyaki slopsquatting akan ditandai | Ya | -| `audit:deps` | `npm audit` (akar + electron) — tiada nasihat keselamatan bertahap tinggi/kritikal (bertindih dengan `check:vuln-ratchet` osv; lihat Tunggakan Rasionalisasi) | Ya | -| `check:lockfile` | Integriti `package-lock.json` — pendaftaran https, cincangan integriti, tiada penggantian hos | Ya | -| `check:licenses` | Senarai dibenarkan lesen SPDX untuk kebergantungan produksi | Ya | -| `check:tracked-artifacts` | Tiada artifak binaan / pautan simbolik `node_modules` yang dikomit (turut dijalankan dalam pra-komit husky; pra-tolak sengaja diringankan — #6716) | Ya | -| `check:ai-attribution` | Tiada treler `Co-Authored-By` AI/bot atau pengaki penjanaan AI dalam komit, tajuk atau kandungan PR — Peraturan Tegas #16 (dalam gelung gerbang pantas `quality.yml` untuk PR→`release/**` — membaca muatan peristiwa, tiada operasi di luar PR — dan langkah PR sahaja dalam lint `ci.yml` untuk PR→`main`; juga cangkuk `commit-msg` husky; pengarang bersama manusia dibenarkan; #14436) | -| `check:vitest-exclusions` | Setiap pengecualian Vitest menyatakan isu penjejakan dan muncul dalam `config/quality/vitest-exclusions.json` (#13204) | Ya | -| `check:file-size` | Tiada fail sumber melebihi had bagi setiap sambungan (roda sehala: fail besar dibekukan dalam senarai `frozen`) | Ya | -| `check:error-helper` | Respons ralat dalam pelaksana/pengendali menggunakan `buildErrorBody()` / `sanitizeErrorMessage()` (Peraturan Tegas #12) | Ya | -| `check:migration-numbering` | Fail SQL migrasi dinomborkan secara berurutan, tanpa jurang atau pendua | Ya | -| `check:public-creds` | Tiada `client_id`/`client_secret` OAuth literal atau kunci Web Firebase di luar `publicCreds.ts` (Peraturan Tegas #11) | Ya | -| `check:db-rules` | Tiada SQL mentah di luar modul `src/lib/db/`; tiada import barrel daripada `localDb.ts` (Peraturan Tegas #2/#5) | Ya | -| `check:known-symbols` | Pelaksana penyedia, strategi penghalaan dan penterjemah yang didaftarkan dalam jadual penghantaran masing-masing sepadan dengan fail pada cakera — tiada simbol yatim atau tidak diisytiharkan | Ya | -| `check:route-guard-membership` | Setiap laluan yang menghasilkan proses anak diklasifikasikan oleh `isLocalOnlyPath()` (Peraturan Tegas #15/#17) | Ya | -| `check:test-discovery` | Setiap fail `*.test.ts` / `*.spec.ts` dalam repositori dikumpulkan oleh sekurang-kurangnya satu pelaksana ujian (ratchet: senarai yatim dalam `test-discovery-baseline.json` hanya boleh mengecil) | Ya | -| `check:agent-skills-sync` | Artifak agent-skills yang dijana sepadan dengan katalog sumbernya (tiada penyimpangan) | -| `check:provider-asset-provenance` | Logo/aset penyedia mempunyai entri asal-usul yang direkodkan | -| `lint:json` | Fail konfigurasi JSON dapat dihuraikan dan mematuhi peraturan lint repositori | -| `typecheck:core` | Kompilasi TypeScript tanpa ralat (amaran nasihat sahaja) | Ya | -| `typecheck:noimplicit:core` | `noImplicitAny` yang ketat — untuk kegunaan masa hadapan; banyak tapak panggilan sedia ada masih memerlukan anotasi | **Nasihat** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` yang dikhususkan kepada `src/app/(dashboard)/**` (#7033) — senarai dibenarkan terpilih 27 fail bagi `typecheck:core` tidak menyertakan sebarang TSX papan pemuka, dan `next build` juga tidak pernah menyemak jenisnya (`next.config.mjs` menetapkan `ignoreBuildErrors: true`), maka regresi pengecam yatim di situ (#6625/#6909) tidak dapat dikesan oleh CI. Perbezaan dibandingkan dengan garis dasar kiraan beku bagi setiap fail/setiap kod TS (`config/quality/dashboard-typecheck-baseline.json`, corak penguatkuasaan lapuk yang sama seperti `check:known-symbols`) — hanya ralat BAHARU yang melebihi kiraan garis dasar akan menggagalkan gerbang; kurangkan secara berperingkat menggunakan `--update` apabila ralat sedia ada dibetulkan. | Ya | +| Skrip (`npm run ...`) | Mengesahkan | Menyekat | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Versi Node.js berada dalam julat yang disokong | Ya | +| `check:cycles` | Import kitaran merentas seluruh `src/` + `open-sse/` (berasaskan AST, `paths` tsconfig diselesaikan). Mod biasa = nasihat, menyenaraikan kitaran. `check:cycles:ratchet` (yang dijalankan oleh CI) menyekat apabila bilangannya melebihi had `metrics.cycles` dalam `quality-baseline.json` — pada masa ini 14, `direction: down`, jadi bilangannya hanya boleh menurun (#15159 G-01/G-02) | Ya (ratchet) | +| `check:route-validation:t06` | Skema Zod tersedia pada semua laluan (dasar Tahap 6) | Ya | +| `check:any-budget:t11` | Bilangan `@ts-expect-error // any` tidak melebihi bajet (catraca Tahap 11) | Ya | +| `check:provider-consistency` | Setiap penyedia dalam `providers.ts` mempunyai entri yang sepadan dalam `providerRegistry.ts` (dan sebaliknya, dalam senarai dibenarkan) | Ya | +| `check:model-lifecycle` | Tiga jadual penghalaan yang diselenggara secara manual kekal konsisten dengan petikan kitar hayat yang disimpan dalam repositori (#11503): `FITNESS_TABLE` (`taskFitness.ts`) tidak memberikan skor kepada mana-mana id yang telah ditamatkan tetapi masih boleh dihalakan oleh `REGISTRY`; setiap sasaran `BUILT_IN_ALIASES` terdapat dalam `REGISTRY` dan tiada dalam petikan id yang telah ditamatkan; setiap id yang telah ditamatkan tetapi masih berada dalam `REGISTRY` dimajukan atau disenaraikan dalam `allowedRetiredInCatalog`; dan tiada sumber atau sasaran `DEFAULT_DEGRADATION_MAP` ditandai sebagai telah ditamatkan dalam petikan tersebut. Ini tidak membuktikan bahawa sesuatu model sedang disediakan oleh huluan langsung. Luar talian — membandingkan dengan `config/quality/model-lifecycle.json`, yang disegarkan secara manual menggunakan `npm run quality:refresh-model-lifecycle` (rangkaian; tidak disepadukan ke dalam CI). `allowedRetiredInCatalog` ialah mekanisme sehala pengurangan berperingkat: tambahkan entri hanya bersama isu penjejakan. | Ya | +| `check:fetch-targets` | Setiap `fetch("/api/...")` dalam `src/` sisi klien dipadankan kepada `route.ts` sebenar | Ya | +| `check:deps` | Semua kebergantungan yang boleh dipasang dengan `npm install` merentas setiap `package.json` dalam repositori terdapat dalam `dependency-allowlist.json`; pakej baharu yang tidak dipasak versinya atau disyaki slopsquatting ditandai | Ya | +| `audit:deps` | `npm audit` (akar + electron) — tiada nasihat keselamatan bertahap tinggi/kritikal (bertindih dengan osv `check:vuln-ratchet`; lihat Tunggakan Rasionalisasi) | Ya | +| `check:lockfile` | Integriti `package-lock.json` — pendaftaran https, cincangan integriti, tiada penggantian hos | Ya | +| `check:licenses` | Senarai dibenarkan lesen SPDX untuk kebergantungan produksi | Ya | +| `check:tracked-artifacts` | Tiada artifak binaan / pautan simbolik `node_modules` yang dikomit (turut dijalankan dalam pra-komit husky; pra-tolak sengaja diringankan — #6716) | Ya | +| `check:ai-attribution` | Tiada treler `Co-Authored-By` AI/bot atau pengaki penjanaan AI dalam komit, tajuk atau kandungan PR — Peraturan Tegas #16 (dalam gelung gerbang pantas `quality.yml` untuk PR→`release/**` — membaca muatan peristiwa, tanpa operasi di luar PR — dan langkah khusus PR dalam semakan lint `ci.yml` untuk PR→`main`; turut merangkumi cangkuk `commit-msg` husky; pengarang bersama manusia dibenarkan; #14436) | +| `check:vitest-exclusions` | Setiap pengecualian Vitest menyatakan isu penjejakan dan muncul dalam `config/quality/vitest-exclusions.json` (#13204) | Ya | +| `check:file-size` | Tiada fail sumber melebihi had bagi setiap sambungan (ratchet: fail besar yang dibekukan dalam senarai `frozen`) | Ya | +| `check:error-helper` | Respons ralat dalam pelaksana/pengendali menggunakan `buildErrorBody()` / `sanitizeErrorMessage()` (Peraturan Tegas #12) | Ya | +| `check:migration-numbering` | Fail SQL migrasi dinomborkan secara berurutan, tanpa jurang atau pendua | Ya | +| `check:public-creds` | Tiada `client_id`/`client_secret` OAuth literal atau kunci Web Firebase di luar `publicCreds.ts` (Peraturan Tegas #11) | Ya | +| `check:db-rules` | Tiada SQL mentah di luar modul `src/lib/db/`; tiada import barrel daripada `localDb.ts` (Peraturan Tegas #2/#5) | Ya | +| `check:known-symbols` | Pelaksana penyedia, strategi penghalaan dan penterjemah yang didaftarkan dalam jadual penghantaran mereka sepadan dengan fail pada cakera — tiada simbol yatim atau tidak diisytiharkan | Ya | +| `check:route-guard-membership` | Setiap laluan yang mewujudkan proses anak diklasifikasikan oleh `isLocalOnlyPath()` (Peraturan Tegas #15/#17) | Ya | +| `check:test-discovery` | Setiap fail `*.test.ts` / `*.spec.ts` dalam repositori dikumpulkan oleh sekurang-kurangnya satu pelaksana ujian (ratchet: senarai yatim dalam `test-discovery-baseline.json` hanya boleh mengecil) | Ya | +| `check:agent-skills-sync` | Artifak agent-skills yang dijana sepadan dengan katalog sumbernya (tiada penyimpangan) | +| `check:provider-asset-provenance` | Logo/aset penyedia mempunyai entri asal-usul yang direkodkan | +| `lint:json` | Fail konfigurasi JSON boleh dihuraikan dan mematuhi peraturan lint repo | +| `typecheck:core` | Pengkompilan TypeScript tanpa ralat (amaran nasihat sahaja) | Ya | +| `typecheck:noimplicit:core` | `noImplicitAny` yang ketat — berpandangan ke hadapan; banyak tapak panggilan sedia ada masih memerlukan anotasi | **Nasihat** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` yang diskopkan kepada `src/app/(dashboard)/**` (#7033) — senarai benarkan 27 fail terpilih milik `typecheck:core` tidak menyertakan sebarang TSX papan pemuka, dan `next build` juga tidak pernah melakukan semakan jenis padanya (`next.config.mjs` menetapkan `ignoreBuildErrors: true`), maka regresi pengecam yatim di situ (#6625/#6909) tidak dapat dikesan oleh CI. Perbezaan dibandingkan dengan garis dasar kiraan beku mengikut fail/mengikut kod TS (`config/quality/dashboard-typecheck-baseline.json`, corak penguatkuasaan lapuk yang sama seperti `check:known-symbols`) — hanya ralat BAHARU yang melebihi kiraan garis dasar akan menggagalkan semakan; kurangkan secara berperingkat dengan `--update` apabila ralat sedia ada dibetulkan. | Ya | ### Tugas: `quality-gate` Dijalankan selepas `test-coverage`. Menyekat penggabungan jika gagal. -| Skrip | Mengesahkan | Menyekat | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | Menghasilkan `quality-metrics.json` (bilangan amaran ESLint, liputan daripada laporan serpihan yang digabungkan) | Ya (huluan bagi ratchet) | -| `quality:ratchet` | Setiap metrik dalam `quality-baseline.json` tidak merosot (amaran ESLint ≤ garis dasar; liputan ≥ garis dasar) | Ya | -| `check:duplication` | Penduaan kod (jscpd@4) tidak melebihi garis dasar dalam `quality-baseline.json` | Ya | -| `check:complexity` | Kerumitan siklomatik pada peringkat fail tidak melebihi had (ESLint teras `complexity` + `max-lines-per-function`) | Ya | -| `check:cognitive-complexity` | Ratchet kerumitan kognitif (`eslint-plugin-sonarjs`) — laluan ESLint berasingan; CI menjalankan kedua-duanya secara tergabung sebagai langkah tunggal `check:complexity-ratchets` | Ya | -| `check:dead-code` | Ratchet eksport / fail yang tidak digunakan (knip) tidak merosot berbanding garis dasar | Ya | -| `check:compression-budget` | Bajet penanda aras pemampatan — had minimum penjimatan token bagi setiap enjin tidak boleh merosot | Ya | -| `check:type-coverage` | Ratchet peratusan yang ditaip (`type-coverage`) tidak merosot; sebahagian besarnya merangkumi `typecheck:noimplicit:core` | Ya | -| `check:codeql-ratchet` | Bilangan amaran CodeQL terbuka tidak merosot (dibaca melalui `gh api`; dilangkau secara wajar tanpa token) — kekerapan muat semula dan pencetus manual: lihat "Ratchet CodeQL" di bawah | Ya | +| Skrip | Mengesahkan | Menyekat | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `quality:collect` | Menghasilkan `quality-metrics.json` (bilangan amaran ESLint, liputan daripada laporan serpihan yang digabungkan) | Ya (sebelum ratchet) | +| `quality:ratchet` | Setiap metrik dalam `quality-baseline.json` tidak merosot (amaran ESLint ≤ garis dasar; liputan ≥ garis dasar) | Ya | +| `check:duplication` | Penduaan kod (jscpd@4) tidak melebihi garis dasar dalam `quality-baseline.json` | Ya | +| `check:complexity` | Kerumitan siklomatik pada peringkat fail tidak melebihi had (ESLint teras `complexity` + `max-lines-per-function`) | Ya | +| `check:cognitive-complexity` | Ratchet kerumitan kognitif (`eslint-plugin-sonarjs`) — laluan ESLint berasingan; CI menjalankan kedua-duanya secara tergabung sebagai satu langkah `check:complexity-ratchets` | Ya | +| `check:dead-code` | Ratchet eksport / fail yang tidak digunakan (knip) tidak merosot berbanding garis dasar | Ya | +| `check:compression-budget` | Belanjawan penanda aras pemampatan — had minimum penjimatan token bagi setiap enjin tidak boleh merosot | Ya | +| `check:type-coverage` | Ratchet peratusan ditaip (`type-coverage`) tidak merosot; sebahagian besarnya merangkumi `typecheck:noimplicit:core` | Ya | +| `check:codeql-ratchet` | Bilangan amaran CodeQL terbuka tidak merosot (dibaca melalui `gh api`; dilangkau dengan selamat tanpa token) — kekerapan muat semula dan pencetus manual: lihat "Ratchet CodeQL" di bawah | Ya | ### Tugas: `quality-extended` -Keseluruhan tugas bersifat nasihat (`continue-on-error: true`). Ratchet berasaskan npm dijalankan -sepenuhnya; pengimbas luaran dipasang melalui `gh release download` dan melangkau sendiri (keluar 0) -apabila binari masih tiada. +Keseluruhan tugas bersifat nasihat (`continue-on-error: true`). Ratchet berasaskan npm benar-benar dijalankan; pengimbas luaran dipasang melalui `gh release download` dan melangkau sendiri (exit 0) apabila binari masih tiada. -| Skrip | Mengesahkan | Menyekat | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | -| `check:circular-deps` | Tiada kebergantungan kitaran (dpdm) | **Nasihat** | -| `check:bundle-size` | Saiz berkas tidak melebihi had | **Nasihat** | -| `check:secrets` | Pengimbasan rahsia (gitleaks) — dilangkau jika binari tiada | **Nasihat** | -| `check:vuln-ratchet` | Kerentanan kebergantungan (osv-scanner) tidak merosot — dilangkau jika binari tiada | **Nasihat** | -| `check:workflows` | Lint aliran kerja (actionlint + zizmor); pengimbas yang tiada/rosak, laporan tidak sah atau garis dasar ratchet yang tiada gagal sebagai INCOMPLETE. Penemuan yang sah mengikut dasar tegas/nasihat/ratchet yang dipilih | Pelaksanaan diperlukan; ratchet zizmor menyekat dalam CI | -| `check:openapi-breaking` | Perubahan pemecah kepada kontrak API awam (`openapi.yaml`) berbanding cabang asas (oasdiff) — menghasilkan `openapiBreaking=N`; dilangkau jika oasdiff tiada atau spesifikasi asas tidak dapat diselesaikan | **Nasihat** | +| Skrip | Mengesahkan | Menyekat | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `check:circular-deps` | Tiada kebergantungan kitaran (dpdm) | **Nasihat** | +| `check:bundle-size` | Saiz berkas tidak melebihi had | **Nasihat** | +| `check:secrets` | Pengimbasan rahsia (gitleaks) — dilangkau jika binari tiada | **Nasihat** | +| `check:vuln-ratchet` | Kerentanan kebergantungan (osv-scanner) tidak merosot — dilangkau jika binari tiada | **Nasihat** | +| `check:workflows` | Pelintan aliran kerja (actionlint + zizmor); pengimbas yang tiada/rosak, laporan tidak sah atau garis dasar ratchet yang tiada akan gagal sebagai INCOMPLETE. Dapatan sah mengikut dasar ketat/nasihat/ratchet yang dipilih | Pelaksanaan diperlukan; ratchet zizmor menyekat dalam CI | +| `check:openapi-breaking` | Perubahan yang memecahkan kontrak API awam (`openapi.yaml`) berbanding cabang asas (oasdiff) — menghasilkan `openapiBreaking=N`; dilangkau jika oasdiff tiada atau spesifikasi asas tidak dapat diselesaikan | **Nasihat** | ### Tugas: `docs-sync-strict` Dijalankan pada setiap PR ke `main`. Menyekat penggabungan jika gagal. -| Skrip | Mengesahkan | Menyekat | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `check:docs-all` | Gerbang meta yang menjalankan 6 subgerbang di bawah secara berurutan | Ya | -| ↳ `check:docs-sync` | Konsistensi versi CHANGELOG / OpenAPI / llm.txt | Ya | -| ↳ `check:docs-counts` | Bilangan dalam prosa (bilangan penyedia, bilangan migrasi, dll.) berada dalam tetingkap ratchet bagi bilangan sebenar | Ya | -| ↳ `check:env-doc-sync` | Setiap pemboleh ubah persekitaran dalam `.env.example` didokumentasikan dalam jadual dokumentasi, dan begitu juga sebaliknya | Ya | -| ↳ `check:deprecated-versions` | Tiada rentetan versi yang telah ditamatkan dalam dokumentasi | Ya | -| ↳ `check:doc-links` | Pautan markdown dalaman dalam dokumentasi merujuk kepada fail sebenar (bentuk `[teks]`/`(laluan)`) | Ya | -| ↳ `check:fabricated-docs` | Laluan, pemboleh ubah persekitaran, perintah CLI, nama cangkuk dan laluan fail yang dirujuk dalam dokumentasi wujud dalam pangkalan kod. Gerbang keras melalui `--strict`; kegagalan lembut tanpa bendera. | Ya (melalui `--strict` dalam CI) | -| `check:cli-i18n` | Rentetan perintah CLI terdapat dalam semua fail pelokal i18n | Ya | -| `check:openapi-coverage` | Spesifikasi OpenAPI merangkumi sekurang-kurangnya had minimum laluan sebenar yang ditetapkan secara ratchet | Ya | -| `check:openapi-security-tiers` | Anotasi aras keselamatan dalam `openapi.yaml` selaras dengan pengelasan `routeGuard.ts` | **Nasihat** | -| `check:openapi-routes` | Setiap laluan dalam `openapi.yaml` merujuk kepada `route.ts` sebenar (antihalusinasi) | Ya | -| `check:docs-symbols` | Setiap rujukan `/api/...` dalam `docs/**/*.md` merujuk kepada `route.ts` sebenar (antihalusinasi) | Ya | -| `i18n translation drift` | Kekunci yang tidak diterjemahkan dalam fail pelokal i18n — amaran sahaja | **Nasihat** | +| Skrip | Mengesahkan | Menyekat | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `check:docs-all` | Gerbang meta yang menjalankan 6 subgerbang di bawah secara berurutan | Ya | +| ↳ `check:docs-sync` | Ketekalan versi CHANGELOG / OpenAPI / llm.txt | Ya | +| ↳ `check:docs-counts` | Bilangan dalam prosa (bilangan penyedia, bilangan migrasi, dan sebagainya) berada dalam tetingkap ratchet bagi bilangan sebenar | Ya | +| ↳ `check:env-doc-sync` | Setiap pemboleh ubah persekitaran dalam `.env.example` didokumentasikan dalam jadual dokumentasi, dan sebaliknya | Ya | +| ↳ `check:deprecated-versions` | Tiada rentetan versi lapuk dalam dokumentasi | Ya | +| ↳ `check:doc-links` | Pautan markdown dalaman dalam dokumentasi menghala kepada fail sebenar (bentuk `[text]`/`(path)`) | Ya | +| ↳ `check:fabricated-docs` | Laluan, pemboleh ubah persekitaran, perintah CLI, nama hook dan laluan fail yang dirujuk dalam dokumentasi wujud dalam pangkalan kod. Gerbang keras melalui `--strict`; kegagalan lembut tanpa bendera. | Ya (melalui `--strict` dalam CI) | +| `check:cli-i18n` | Rentetan perintah CLI terdapat dalam semua fail lokal i18n | Ya | +| `check:openapi-coverage` | Spesifikasi OpenAPI merangkumi sekurang-kurangnya ambang minimum yang diratchet bagi laluan sebenar | Ya | +| `check:openapi-security-tiers` | Anotasi peringkat keselamatan dalam `openapi.yaml` selaras dengan pengelasan `routeGuard.ts` | **Nasihat** | +| `check:openapi-routes` | Setiap laluan dalam `openapi.yaml` menghala kepada `route.ts` sebenar (antihalusinasi) | Ya | +| `check:docs-symbols` | Setiap rujukan `/api/...` dalam `docs/**/*.md` menghala kepada `route.ts` sebenar (antihalusinasi) | Ya | +| `i18n translation drift` | Kekunci yang tidak diterjemahkan dalam fail lokal i18n — amaran sahaja | **Nasihat** | ### Tugas: `i18n-ui-coverage` -| Skrip | Mengesahkan | Menyekat | -| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check-ui-keys-coverage` (sebaris) | Liputan kekunci i18n UI ialah ≥ 65% | Ya | -| `check-ui-value-drift` (sebaris) | **Nilai** bahasa Inggeris yang ditulis semula tidak meninggalkan terjemahan lapuk | Ya | -| `check-new-key-coverage` (sebaris) | Kekunci bahasa Inggeris yang **baharu** diterjemahkan dalam setiap pelokal — penanda `__MISSING__:` ditolak | Ya | -| `check-translation-ratio` | Nisbah terjemahan sebenar bagi setiap pelokal (nilai yang sama dengan bahasa Inggeris / ruang letak / entri hilang di luar senarai dibenarkan) tidak boleh melebihi `config/quality/i18n-translation-baseline.json` + kelonggaran | **Nasihat** | +| Skrip | Mengesahkan | Menyekat | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (sebaris) | Liputan kekunci i18n UI ialah ≥ 65% | Ya | +| `check-ui-value-drift` (sebaris) | **Nilai** bahasa Inggeris yang ditulis semula tidak meninggalkan sebarang terjemahan lapuk | Ya | +| `check-new-key-coverage` (sebaris) | Kekunci bahasa Inggeris yang **baharu** diterjemahkan dalam setiap lokal — penanda `__MISSING__:` ditolak | Ya | +| `check-translation-ratio` | Nisbah terjemahan sebenar bagi setiap lokal (sama dengan bahasa Inggeris / ruang letak / entri hilang di luar senarai yang dibenarkan) tidak boleh melebihi `config/quality/i18n-translation-baseline.json` + kelonggaran | **Nasihat** | -Memerlukan `fetch-depth: 0` — gerbang hanyutan nilai membandingkan perbezaan `en.json` dengan asas cantuman. +Memerlukan `fetch-depth: 0` — gerbang sisihan nilai membandingkan perbezaan `en.json` dengan asas cantuman. #### `check-ui-value-drift` — gerbang terjemahan lapuk -Mengesan satu regresi i18n yang tidak dapat dikesan secara struktur oleh gerbang lain: nilai bahasa Inggeris -ditulis semula dan terjemahan yang diterbitkan daripada bahasa Inggeris _sebelumnya_ kekal, menyebabkan -pengguna bukan berbahasa Inggeris terus membaca teks yang ditulis dengan meyakinkan tetapi kini salah. +Mengesan satu regresi i18n yang secara struktur tidak dapat dilihat oleh gerbang lain: nilai bahasa Inggeris +ditulis semula dan terjemahan yang berasal daripada bahasa Inggeris _sebelumnya_ kekal, menyebabkan +pengguna bukan berbahasa Inggeris terus membaca teks yang kedengaran meyakinkan tetapi kini salah. -Perkara ini benar-benar telah dilancarkan. `oauthModal.googleOAuthWarning` ditulis semula apabila pembantu log masuk -Antigravity diperkenalkan (#5203); **39 daripada 43 pelokal** mengekalkan teks yang menyuruh pengendali untuk "menyalin -URL penuh dan menampalnya di bawah" — aliran yang tidak dapat diselesaikan bagi penyedia tersebut. Perkara ini +Ini benar-benar pernah dikeluarkan. `oauthModal.googleOAuthWarning` telah ditulis semula apabila pembantu log masuk +Antigravity diperkenalkan (#5203); **39 daripada 43 lokal** mengekalkan teks yang mengarahkan pengendali untuk "menyalin +URL penuh dan menampalnya di bawah" — aliran yang tidak dapat dilengkapkan untuk penyedia tersebut. Hal ini tidak disedari sehingga #8463 kerana: -- `sync-ui-keys` hanya mengisi semula kekunci yang **tiada**, bukan kekunci yang **lapuk**; -- `check-ui-keys-coverage` mengira _kewujudan_ kekunci, jadi terjemahan lapuk dikira sebagai diliputi; +- `sync-ui-keys` hanya mengisi kekunci yang **tiada**, bukan kekunci yang **lapuk**; +- `check-ui-keys-coverage` mengira _kewujudan_ kekunci, maka terjemahan lapuk dikira sebagai diliputi; - `check-translation-drift` menjejaki cerminan dokumentasi `docs/i18n//**.md` — ia tidak pernah membaca `src/i18n/messages/*.json`. Menyekat dalam tugas `docs-sync-strict` sejak - penyegerakan semula 2026-09: sunting dokumen teras → `npm run i18n:run -- --files=` (pada peringkat bahagian, ringan). + penyegerakan semula 2026-09: sunting dokumen teras → `npm run i18n:run -- --files=` (peringkat bahagian, ringan). -**Peka terhadap perbezaan, bukan disokong garis dasar.** Ia membandingkan `en.json` pada asas cantuman dengan -pepohon kerja; bagi setiap kekunci yang nilai bahasa Inggerisnya berubah, mana-mana locale yang masih mempunyai +**Peka perbezaan, bukan disokong garis dasar.** Ia membandingkan `en.json` pada pangkalan cantuman dengan +pepohon kerja; bagi setiap kekunci yang nilai bahasa Inggerisnya berubah, mana-mana penempatan yang masih mempunyai terjemahan yang tidak disentuh dianggap lapuk. Ini sengaja **membekukan hutang sedia ada** — perbezaan -tidak dapat mendedahkan teks bahasa Inggeris lama yang menjadi sumber sesuatu terjemahan lama, maka get hanya menilai -perkara yang disentuh oleh perubahan semasa. Alternatifnya (garis dasar hash bagi setiap kekunci) memerlukan -fail terjana ~600 KB, 3× lebih besar daripada garis dasar sedia ada yang terbesar, serta berubah pada setiap PR i18n. +tidak dapat menunjukkan versi bahasa Inggeris lama yang menjadi sumber sesuatu terjemahan lama, maka pagar hanya menilai +perkara yang disentuh oleh perubahan semasa. Alternatifnya (garis dasar cincangan bagi setiap kekunci) memerlukan +fail dijana berukuran ~600 KB, 3× lebih besar daripada garis dasar sedia ada yang terbesar, dan berubah pada setiap PR i18n. Dua cara untuk mematuhinya: 1. kemas kini terjemahan yang terjejas, atau -2. tetapkannya kepada `__MISSING__:` — masa jalan kemudiannya menyajikan teks bahasa Inggeris yang telah dibetulkan - (`src/i18n/request.ts::deepMergeFallback`, #7258) dan kekunci tersebut dimasukkan ke dalam baris gilir terjemahan. +2. tetapkannya kepada `__MISSING__:` — masa jalan kemudiannya menyajikan teks bahasa Inggeris yang dibetulkan + (`src/i18n/request.ts::deepMergeFallback`, #7258) dan kekunci tersebut dibariskan untuk diterjemahkan. -Jika **makna** rentetan berubah, utamakan **penamaan semula kekunci**: kekunci baharu tidak boleh mewarisi +Jika **makna** rentetan berubah, utamakan **menamakan semula kekunci**: kekunci baharu tidak boleh mewarisi terjemahan yang lapuk. Itulah corak yang digunakan oleh #8463. ```bash @@ -233,26 +229,26 @@ npm run i18n:check-value-drift:warn # laporan sahaja BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Keluar dengan kod 0 bersama `SKIP reason=base-unresolved` apabila katalog asas tidak dapat dibaca (klon cetek +Keluar dengan kod 0 berserta `SKIP reason=base-unresolved` apabila katalog asas tidak dapat dibaca (klon cetek tanpa rujukan asas), selaras dengan `check-openapi-breaking`. ### Tugas: `i18n` -Matriks pengesahan i18n penuh (satu tugas bagi setiap locale). Keseluruhan tugas bersifat nasihat. +Matriks pengesahan i18n penuh (satu tugas bagi setiap penempatan). Keseluruhan tugas bersifat nasihat. -| Skrip | Mengesahkan | Menyekat | -| ------------------------------- | ----------------------------------------- | ---------------------------------------------------------- | -| `validate_translation.py quick` | Kelengkapan terjemahan bagi setiap locale | **Nasihat** (`continue-on-error: true` pada seluruh tugas) | +| Skrip | Mengesahkan | Menyekat | +| ------------------------------- | --------------------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | Kelengkapan terjemahan bagi setiap penempatan | **Nasihat** (`continue-on-error: true` pada keseluruhan tugas) | ### Tugas: `pr-test-policy` -Dijalankan pada pull request sahaja. +Dijalankan pada permintaan tarik sahaja. -| Skrip | Mengesahkan | Menyekat | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | PR yang mengubah kod pengeluaran dalam `src/`, `open-sse/`, `electron/`, atau `bin/` mesti menyertakan atau mengemas kini ujian (Peraturan Tegas #8) | Ya | -| `check:test-masking` | Fail ujian yang diubah tidak mengurangkan jumlah bersih penegasan atau menambah tautologi `assert.ok(true)` | Ya | -| `check:pr-evidence` | Kandungan PR memetik bukti ujian/VPS untuk perubahan tersebut (mengautomasi Peraturan Tegas #18 dengan menggrep prosa PR — rapuh, lihat Backlog) | Ya | +| Skrip | Mengesahkan | Menyekat | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | PR yang mengubah kod pengeluaran dalam `src/`, `open-sse/`, `electron/`, atau `bin/` mesti menyertakan atau mengemas kini ujian (Peraturan Tegas #8) | Ya | +| `check:test-masking` | Fail ujian yang diubah tidak mengurangkan bilangan bersih penegasan atau menambah tautologi `assert.ok(true)` | Ya | +| `check:pr-evidence` | Isi PR menyatakan bukti ujian/VPS bagi perubahan tersebut (mengautomatikkan Peraturan Tegas #18 dengan menggrep prosa PR — rapuh, lihat Senarai Tertunggak) | Ya | ### Tugas: `test-vitest` @@ -263,18 +259,18 @@ Dijalankan selepas `build`. Menyekat cantuman jika gagal. | `test:vitest` | Pelayan MCP (110 alat), autoCombo, cache — pelaksana vitest | Ya | | `test:vitest:ui` | Ujian komponen UI — pelaksana vitest | **Menyekat** — kegagalan sedia ada dikecualikan secara jelas dalam `vitest.config.ts`; kegagalan baharu menggagalkan tugas | -### Aliran kerja setiap malam (dijadualkan, bersifat nasihat) +### Aliran kerja setiap malam (berjadual, bersifat nasihat) -Ini dijalankan mengikut jadual cron (dan `workflow_dispatch`), tidak sekali-kali pada PR. Semuanya bersifat nasihat. +Ini dijalankan mengikut jadual cron (dan `workflow_dispatch`), tidak pernah pada PR. Semuanya bersifat nasihat. -| Aliran kerja | Mengesahkan | Menyekat | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `nightly-property` | Ujian sifat fast-check dengan benih rawak + bilangan larian yang tinggi | **Nasihat** | -| `nightly-resilience` | Get pertumbuhan heap, suntikan kerosakan huru-hara, beban/rendaman k6 | **Nasihat** | -| `nightly-llm-security` | Pengadang suntikan promptfoo (mod sekat) + prob garak (dilangkau tanpa rahsia penyedia) | **Nasihat** | -| `nightly-schemathesis` | Pengkaburan kontrak OpenAPI (schemathesis) terhadap OmniRoute langsung menggunakan `docs/openapi.yaml` — mendedahkan pelanggaran spesifikasi / ralat 500 yang tidak dikendalikan (Fasa 8 B.4) | **Nasihat** | -| `nightly-mutation` | Skor ujian mutasi Stryker pada laluan unit pantas — mutan yang terselamat mendedahkan penegasan yang lemah | **Nasihat** | -| `nightly-compat` | Matriks keserasian enjin Node merentas julat `engines.node` yang disokong | **Nasihat** | +| Aliran kerja | Mengesahkan | Menyekat | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `nightly-property` | ujian sifat fast-check dengan benih rawak + bilangan larian yang tinggi | **Nasihat** | +| `nightly-resilience` | pagar pertumbuhan timbunan, suntikan kerosakan huru-hara, beban/rendaman k6 | **Nasihat** | +| `nightly-llm-security` | pengadang suntikan promptfoo (mod sekat) + prob garak (dilangkau tanpa rahsia penyedia) | **Nasihat** | +| `nightly-schemathesis` | fuzzing kontrak OpenAPI (schemathesis) terhadap OmniRoute langsung menggunakan `docs/openapi.yaml` — menampilkan pelanggaran spesifikasi / ralat 500 yang tidak dikendalikan (Fasa 8 B.4) | **Nasihat** | +| `nightly-mutation` | skor ujian mutasi Stryker pada laluan unit pantas — mutan yang bertahan menampilkan penegasan yang lemah | **Nasihat** | +| `nightly-compat` | matriks keserasian enjin Node merentas julat `engines.node` yang disokong | **Nasihat** | --- @@ -540,41 +536,41 @@ ralat sambungan dan tidak pernah merosakkan sesi. ## Tunggakan Rasionalisasi (semakan ROI — Fasa 9 Gelombang 3) -Inventori ini telah diselaraskan dengan `ci.yml` pada 2026-06-17 (versi terdahulu tidak menyertakan +Inventori ini telah diselaraskan dengan `ci.yml` pada 2026-06-17 (versi sebelumnya tidak menyertakan `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Semakan ROI bagi set yang telah diselaraskan +`check:codeql-ratchet`, `check:pr-evidence`). Semakan ROI terhadap set yang telah diselaraskan mengenal pasti calon rasionalisasi berikut. **Penggabungan ialah perubahan CI yang -mekanikal; penukaran/pengguguran ialah keputusan dasar yang dikhaskan untuk pengendali.** Tiada apa-apa di bawah -yang telah dilaksanakan lagi. +mekanikal; penukaran/pengguguran ialah keputusan dasar yang dikhaskan untuk pengendali.** Tiada perkara di bawah +yang telah diterapkan lagi. -**Turut tidak didokumentasikan di atas** (bersifat nasihat, isyarat rendah): tugas `docs-lint` -(markdownlint + Vale, keseluruhan tugas menggunakan `continue-on-error`) dan aliran kerja pengimbas kendiri +**Turut tidak didokumenkan di atas** (nasihat sahaja, isyarat rendah): tugas `docs-lint` +(markdownlint + Vale, seluruh tugas menggunakan `continue-on-error`) dan aliran kerja pengimbas kendiri `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` terdapat dalam -`quality-baseline.json` tetapi tidak disambungkan kepada mekanisme sehala yang menyekat dalam `ci.yml` — metrik ini +`quality-baseline.json` tetapi tidak disambungkan kepada mekanisme ratchet yang menyekat dalam `ci.yml` — metrik ini kini terbiar. ### Gabung / nyahpendua (mekanikal, risiko lebih rendah) -Setiap calon telah disahkan berdasarkan keadaan gerbang semasa pada 2026-06-17 (percaya tetapi sahkan); +Setiap calon telah disahkan terhadap keadaan gate sebenar pada 2026-06-17 (percaya tetapi sahkan); beberapa penggabungan yang kelihatan "jelas" sebenarnya menyembunyikan hutang dan **bukan** penggantian terus yang bersih. -- **`check:docs-sync` dijalankan dua kali** — secara kendiri dalam tugas `lint` dan sekali lagi dalam `check:docs-all` (`docs-sync-strict`) serta cangkuk pra-komit husky. ✅ **SELESAI** — pemanggilan kendiri dalam `lint` telah dialih keluar. -- **Pengimbasan CVE** — ❌ **BUKAN penggabungan yang bersih.** `audit:deps` gagal keras bagi mana-mana CVE tinggi/kritikal; `check:vuln-ratchet` (osv) hanya gagal apabila berlaku _regresi_ berbanding garis dasar (kini 1 MODERATE). Semantiknya berbeza — menggugurkan `audit:deps` akan menghilangkan gerbang mutlak bagi tahap tinggi/kritikal. Kekalkan kedua-duanya. -- **Pengesanan kitaran** — ❌ **BUKAN penggabungan yang bersih.** `check:circular-deps` (dpdm) melaporkan **91 kitaran** (itulah sebabnya ia bersifat nasihat); ia tidak boleh dinaik taraf menjadi menyekat tanpa menyelesaikan kitaran tersebut terlebih dahulu, dan skopnya lebih luas daripada `check:cycles` terpilih yang berstatus hijau. Kekalkan `check:cycles` sebagai menyekat; penyelesaian 91 kitaran dpdm merupakan tunggakan yang berasingan. -- **Kerumitan** — ✅ **SELESAI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): satu lintasan ESLint, pengiraan mengikut ruleId supaya garis dasar siklomatik+max-lines dan kognitif kekal bebas; `check:complexity` / `check:cognitive-complexity` individu dikekalkan untuk `--update` setempat. -- **Antihalusinasi `/api`** — ✅ **SELESAI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): satu inventori FS bagi `src/app/api`, openapi-routes + docs-symbols masih melaporkan secara berasingan; semakan individu dikekalkan untuk pelaksanaan setempat. -- **`check:node-runtime` dijalankan dalam 11 tugas** — ⚠️ **ROI rendah.** Setiap satunya menggunakan pelaksana berasingan dan semakan mengambil masa <1s; jumlah penjimatan ~10s, dengan risiko kehilangan kawalan murah bagi setiap tugas. Tidak berbaloi dengan perubahan tersebut. +- **`check:docs-sync` dijalankan dua kali** — secara kendiri dalam tugas `lint` dan sekali lagi dalam `check:docs-all` (`docs-sync-strict`) serta hook pra-komit husky. ✅ **SELESAI** — panggilan kendiri dalam `lint` telah dialih keluar. +- **Pengimbasan CVE** — ❌ **BUKAN penggabungan yang bersih.** `audit:deps` gagal keras bagi sebarang CVE tinggi/kritikal; `check:vuln-ratchet` (osv) hanya gagal apabila terdapat _regresi_ berbanding garis dasar (kini 1 MODERATE). Semantiknya berbeza — menggugurkan `audit:deps` akan menghilangkan gate mutlak bagi tahap tinggi/kritikal. Kekalkan kedua-duanya. +- **Pengesanan kitaran** — ✅ **SELESAI** (#15159 G-01/G-02). Teks lama di sini menyifatkan `check:cycles` sebagai gate "hijau, disusun rapi" dan mewajarkan pengekalan status menyekatnya kerana `check:circular-deps` (dpdm) melaporkan 91 kitaran. Status hijau itu ialah **hijau palsu**: `check:cycles` mengimbas 5 subdirektori (450 fail), hanya memadankan `import|export … from` statik dan menggugurkan setiap penspesifikasi `@/` dan `@omniroute/open-sse/`, maka ia tidak dapat melihat kitaran import dinamik + alias yang mendominasi repo. Telah dibetulkan: gate kini menelusuri `src` + `open-sse` (5023 fail), mengumpulkan penspesifikasi daripada AST TypeScript (maka `import("…")` dikira manakala `typeof import("…")` pada kedudukan jenis tidak dikira), dan menyelesaikan `paths` tsconfig. Ia menemukan **14** kitaran, bukannya 0. Oleh sebab 14 kitaran sedia ada tidak dapat dibetulkan dalam PR gate, `check:cycles` kini merupakan **ratchet** (`--ratchet`, had maksimum `metrics.cycles.value = 14` dalam `quality-baseline.json`, `direction: down`) — ia menyekat sebarang _regresi_ dan bilangannya hanya boleh menurun. CI menjalankan `npm run check:cycles:ratchet`. Pengurangan beransur-ansur dilaksanakan bersama **A-01**. `check:circular-deps` (dpdm) kekal sebagai nasihat dan pandangan kedua yang lebih luas. +- **Kerumitan** — ✅ **SELESAI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): satu penelusuran ESLint, dikira mengikut ruleId supaya garis dasar siklomatik+max-lines dan kognitif kekal berasingan; `check:complexity` / `check:cognitive-complexity` individu dikekalkan untuk `--update` setempat. +- **Anti-halusinasi `/api`** — ✅ **SELESAI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): satu inventori FS bagi `src/app/api`, openapi-routes + docs-symbols masih melaporkan secara berasingan; pemeriksaan individu dikekalkan untuk pelaksanaan setempat. +- **`check:node-runtime` dijalankan dalam 11 tugas** — ⚠️ **ROI rendah.** Setiap satu menggunakan runner berasingan dan pemeriksaan mengambil masa <1s; jumlah penjimatan ~10s, tetapi pengadang murah bagi setiap tugas akan hilang. Tidak berbaloi dengan gangguan yang diperlukan. - **`typecheck:noimplicit:core` dalam lint CI** — ✅ **dialih keluar daripada tugas lint** (sebelum ini bersifat nasihat dengan `continue-on-error`); permukaan jenis yang menyekat ialah `typecheck:core` + `check:type-coverage`. Skrip setempat dikekalkan. ### Tukar / putuskan (dasar pengendali) -- `check:openapi-security-tiers` (bersifat nasihat) — ❌ **TIDAK boleh ditukar dengan bersih.** Ia keluar dengan kod 0 tetapi memberi amaran bahawa beberapa laluan `traffic-inspector` di bawah `LOCAL_ONLY_API_PREFIXES` tidak mempunyai anotasi `x-loopback-only: true`. Penguatkuasaannya memerlukan anotasi tersebut ditambahkan terlebih dahulu pada `openapi.yaml`. -- `typecheck:noimplicit:core` (bersifat nasihat) — sebahagian besarnya telah dirangkumi oleh mekanisme sehala `check:type-coverage` yang menyekat. Tukar kepada mekanisme sehala atau gugurkan lintasan `tsc` kedua yang berlebihan. -- `test:vitest:ui` (kini **menyekat**) — kegagalan sedia ada dikecualikan secara jelas dalam `vitest.config.ts` dengan komen penjejakan `// #8618`; kegagalan baharu akan menggagalkan tugas. -- `check:secrets` (gitleaks, mekanisme sehala menyekat yang dibekukan pada 3 positif palsu yang didokumentasikan) — tambahkan 3 kes tersebut pada senarai izin untuk mencapai 0, atau turunkan taraf kepada bersifat nasihat. Bertindih dengan pengimbasan rahsia natif GitHub + `check:public-creds`. -- `check:pr-evidence` (menyekat, mencari teks kandungan PR menggunakan grep) — risiko positif palsu yang tinggi; menggugurkannya akan melemahkan penguatkuasaan Peraturan Tegas #18, jadi ini sememangnya keputusan dasar. -- `semgrep` (kendiri, bersifat nasihat) — bertindih dengan CodeQL untuk keluarga OWASP; sambungkan garis dasarnya kepada mekanisme sehala atau gugurkannya. +- `check:openapi-security-tiers` (nasihat) — ❌ **TIDAK boleh ditukar dengan bersih.** Ia keluar dengan kod 0 tetapi memberi amaran bahawa beberapa laluan `traffic-inspector` di bawah `LOCAL_ONLY_API_PREFIXES` tidak mempunyai anotasi `x-loopback-only: true`. Penguatkuasaannya memerlukan anotasi tersebut ditambahkan pada `openapi.yaml` terlebih dahulu. +- `typecheck:noimplicit:core` (nasihat) — sebahagian besarnya telah dirangkumi oleh ratchet `check:type-coverage` yang menyekat. Tukar kepada ratchet atau gugurkan laluan `tsc` kedua yang berlebihan. +- `test:vitest:ui` (kini **menyekat**) — kegagalan sedia ada dikecualikan secara eksplisit dalam `vitest.config.ts` dengan komen penjejakan `// #8618`; kegagalan baharu menyebabkan tugas gagal. +- `check:secrets` (gitleaks, ratchet menyekat yang dibekukan pada 3 positif palsu yang didokumenkan) — masukkan ketiga-tiganya ke dalam senarai benarkan untuk mencapai 0, atau turunkan kepada status nasihat. Bertindih dengan pengimbasan rahsia asli GitHub + `check:public-creds`. +- `check:pr-evidence` (menyekat, menggunakan grep pada prosa badan PR) — risiko positif palsu yang tinggi; menggugurkannya akan melemahkan penguatkuasaan Hard Rule #18, jadi ini benar-benar keputusan dasar. +- `semgrep` (kendiri, bersifat nasihat) — bertindih dengan CodeQL untuk keluarga OWASP; sambungkan garis dasarnya kepada ratchet atau gugurkan. --- diff --git a/docs/i18n/mt/CONTRIBUTING.md b/docs/i18n/mt/CONTRIBUTING.md index 101b3c8d04f..eea66919233 100644 --- a/docs/i18n/mt/CONTRIBUTING.md +++ b/docs/i18n/mt/CONTRIBUTING.md @@ -390,22 +390,24 @@ Ikteb testijiet unitarji f'`tests/unit/` li jkopru mill-inqas: --- -## Kaxxa tal-Għarfien tal-Pull Request - -- [ ] Testijiet għaddew (`npm test`) -- [ ] Linting għaddew (`npm run lint`) -- [ ] Build rnexxielu (`npm run build`) -- [ ] It-Tipijiet TypeScript ġew miżjuda għal funzjonijiet u interfaces ġodda pubbliċi -- [ ] M'hemm xejn skrin fiżjati ta' sigrieti jew valuri fallback -- [ ] Kredenzjali upstream pubbliċi ġew imbodding permezz ta' `resolvePublicCred()` (ara [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), qatt bħala literals -- [ ] Ir-risponsi ta' żball jgħaddu minn `buildErrorBody()` / `sanitizeErrorMessage()` — l-ebda trace rwiexi fil-korp tal-Response (ara [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Il-kmandi shell (`exec` / `spawn`) jgħaddu valuri runtime permezz ta' `env`, mhux permezz ta' interpolarzjoni tal-stringa -- [ ] Kull input ġie validat permezz ta' skemi Zod -- [ ] **Fragament** tal-CHANGELOG ġie miżjud taħt `changelog.d/{features|fixes|maintenance}/-.md` għal bidliet li jaffettwaw l-utenti (ara [`changelog.d/README.md`](./changelog.d/README.md)) — tagħmilx direttament editjar `CHANGELOG.md`; il-fragments jiġbru fis-sak ħin tat-tħarir u qatt ma jikkuntrastaw bejn il-PRs -- [ ] Dukumentazzjoni aġġornata (jekk applicable) -- [ ] L-ebda ġdida CodeQL / Secret-Scanning alerts miftuħa, jew kollha riżolvuti b'ġustifikazzjoni teknika li tirreferi għad-dokument rilevanti ta' `docs/security/` -- [ ] Rotot li jħaddmu proċessi iben (`/api/mcp/`, `/api/cli-tools/runtime/`) huma klassifikati bħala `isLocalOnlyPath()` f'`src/server/authz/routeGuard.ts` — ara [Rekwiżiti Ħorox #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] M'hemm l-ebda `Co-Authored-By` trailers fil-messaġġi tal-kommit — il-kommits iridu jidhru biss taħt l-identità Git tal-sid tal-repositorju (Rekwiżit Ħarxa #16) +## Lista ta' Kontroll tal-Pull Request + +- [ ] It-testijiet jgħaddu (`npm test`) +- [ ] Il-linting jgħaddi (`npm run lint`) +- [ ] Il-build jirnexxi (`npm run build`) +- [ ] Żdiedu t-tipi TypeScript għal funzjonijiet u interfaces pubbliċi ġodda +- [ ] L-ebda sigriet jew valur ta' riżerva kkodifikat direttament +- [ ] Il-kredenzjali upstream pubbliċi huma inkorporati permezz ta' `resolvePublicCred()` (ara [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), u qatt bħala litterali +- [ ] Ir-risposti ta' żball jgħaddu minn `buildErrorBody()` / `sanitizeErrorMessage()` — l-ebda stack trace mhux ipproċessat fil-korpi tar-risposti (ara [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Il-kmandi tax-shell (`exec` / `spawn`) jgħaddu l-valuri waqt l-eżekuzzjoni permezz ta' `env`, mhux permezz ta' interpolazzjoni ta' strings +- [ ] L-inputs kollha huma vvalidati bi skemi Zod +- [ ] Żdied **framment** tal-changelog taħt `changelog.d/{features|fixes|maintenance}/-.md` għal bidliet viżibbli għall-utent (ara [`changelog.d/README.md`](./changelog.d/README.md)) — teditjax `CHANGELOG.md` direttament; il-frammenti jiġu aggregati waqt ir-rilaxx u qatt ma joħolqu kunflitti bejn il-PRs +- [ ] Id-dokumentazzjoni ġiet aġġornata (jekk applikabbli) +- [ ] Ma nfetħux twissijiet ġodda ta' CodeQL / Secret-Scanning, jew kull waħda ġiet miċħuda b'ġustifikazzjoni teknika li tirreferi għad-dokument rilevanti f'`docs/security/` +- [ ] Ir-rotot li jniedu proċessi sekondarji (`/api/mcp/`, `/api/cli-tools/runtime/`) huma kklassifikati bħala `isLocalOnlyPath()` f'`src/server/authz/routeGuard.ts` — ara [Regola Stretta #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] L-ebda trailer `Co-authored-by` ta' AI/bot fil-messaġġi tal-commit (Regola Stretta #16) — il-kollaboraturi umani li x-xogħol tagħhom jerġa' jintuża jingħataw kreditu bi trailers standard `Co-authored-by: Name ` + +--- ## Rilaxjar diff --git a/docs/i18n/mt/docs/architecture/QUALITY_GATES.md b/docs/i18n/mt/docs/architecture/QUALITY_GATES.md index d55ae96e06d..38beace51f8 100644 --- a/docs/i18n/mt/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/mt/docs/architecture/QUALITY_GATES.md @@ -19,211 +19,211 @@ ta’ replikazzjoni indipendenti mill-għodda tal-istess sistema, ara l- ### Ammissjoni tal-kandidati -Il-workflows CI u Quality Gates kull wieħed joħroġ verdett stabbli: `Gate / CI` u -`Gate / Quality`. Il-politika tal-ammissjoni tagħhom, li għandha verżjoni, telenka kull job upstream -bħala obbligatorju jew konsultattiv. Job obbligatorju applikabbli jrid jirnexxi: riżultati -neqsin, ikkanċellati, maqbuża, pendenti u mhux magħrufa ma jistgħux jistabbilixxu PASS. Klassifikazzjoni valida -docs-only jew catalog-only tista’ tagħmel code lane mhux applikabbli; -draft PR mhuwiex kandidat aċċettat. Label `hotfix` ma jneħħix il-ħtieġa għall-evidenza. - -Iż-żewġ workflows ikopru PRs u pushes lejn branches main/release, dispatch manwali u -avvenimenti merge-group. Push, dispatch u merge-group jeżegwixxu l-għażla sħiħa. Forks -u merge groups jużaw hosted runners għal jobs li normalment jagħżlu self-hosted -runners; trid tiġi vverifikata kapaċità hosted suffiċjenti qabel ir-rollout. - -Kull irċevuta JSON tidentifika x-SHA checkout, il-workflow run u l-attempt. -Is-CLI jirrifjuta diskrepanza bejn ix-SHA taċ-checkout u dak tal-avveniment. It-testijiet tal-workflow jorbtu s-sħubija fil-politika -mal-lista `needs` tal-job tal-verdett, sabiex lane ġdida jew imneħħija ma tkunx tista’ tisparixxi mingħajr ma tinduna. -L-irċevuti jkopru l-workflow tagħhom stess, mhux il-pubblikazzjoni, id-deployment, jew il-funzjonament intern -ta’ scanner konsultattiv eżistenti. L-attivazzjoni taż-żewġ ismijiet tal-checks fir-regoli tal-branch hija -bidla amministrattiva separata; iż-żieda ta’ dawn il-jobs minnha nnifisha ma tipproteġix branch. - -### Inventarju tal-iskennjar statiku - -L-inventarju npm-alias bil-verżjoni u s-sħubija fl-iskennjar statiku jinsabu f’ +Il-workflows CI u Quality Gates kull wieħed jipproduċi verdett stabbli: `Gate / CI` u +`Gate / Quality`. Il-politika tal-ammissjoni tagħhom bil-verżjonijiet telenka kull job upstream +bħala meħtieġ jew konsultattiv. Job meħtieġ applikabbli għandu jirnexxi: riżultati neqsin, +ikkanċellati, maqbuża, pendenti u mhux magħrufa ma jistgħux jistabbilixxu PASS. Klassifikazzjoni valida +docs-only jew catalog-only tista’ tagħmel lane tal-kodiċi mhux applikabbli; +draft PR mhuwiex kandidat aċċettat. Label `hotfix` ma jneħħix il-ħtieġa tal-evidenza. + +Iż-żewġ workflows ikopru PRs u pushes lejn fergħat main/release, dispatch manwali u +avvenimenti ta’ merge-group. Push, dispatch u merge-group iħaddmu l-għażla sħiħa. Forks +u merge groups jużaw runners hosted għal jobs li altrimenti jagħżlu runners self-hosted; +għandha tiġi vverifikata kapaċità hosted suffiċjenti qabel ir-rollout. + +Kull irċevuta JSON tidentifika s-SHA checked-out, il-workflow run u l-attempt. +Is-CLI jirrifjuta nuqqas ta’ qbil bejn is-SHA taċ-checkout u dak tal-event. It-testijiet tal-workflow jorbtu s-sħubija fil-politika +mal-lista `needs` tal-job tal-verdett sabiex lane ġdida jew imneħħija ma tkunx tista’ tisparixxi mingħajr avviż. +L-irċevuti jkopru l-workflow tagħhom stess, mhux il-pubblikazzjoni, id-deployment, jew l-interni +ta’ scanner konsultattiv eżistenti. L-attivazzjoni taż-żewġ ismijiet taċ-checks fir-regoli tal-fergħat hija +bidla amministrattiva separata; iż-żieda ta’ dawn il-jobs ma tipproteġix fergħa minnha nnifisha. + +### Inventarju tal-iscan statiku + +L-inventarju tal-npm-aliases bil-verżjonijiet u s-sħubija fl-iscan statiku jinsabu f’ `config/quality/gate-manifest.json`. Ħaddem `npm run check:gate-manifest` biex tivvalida -l-ismijiet tal-iskripts u l-kmandi eżatti ma’ `package.json`; żidiet, tneħħijiet u -devjazzjonijiet fil-kmandi jikkawżaw falliment kemm fil-hook lokali kif ukoll fil-jobs tal-klassifikazzjoni tal-bidliet f’CI. -Alias mhuwiex workflow job, istanza ta’ matrix jew każ ta’ test: dawn l-għaddijiet -ma għandhomx jiġu ppreżentati bħala interkambjabbli. +l-ismijiet tal-iskripts u l-kmandi eżatti kontra `package.json`; żidiet, tneħħijiet u +devjazzjoni fil-kmandi jfallu kemm il-hook lokali kif ukoll il-jobs tal-klassifikazzjoni tal-bidliet f’CI. +Alias mhuwiex workflow job, matrix instance jew test case: dawn l-għaddijiet ma għandhomx +jiġu ppreżentati bħala interkambjabbli. Uża `npm run quality:scan -- --list` jew `npm run quality:scan:fast -- --list` biex tispezzjona l-aliases magħżula mingħajr ma teżegwihom. Ir-runner jinvoka l- -entrypoint ta’ npm, għalhekk ir-runtime tiegħu (inkluż Bun fejn ikkonfigurat) jinżamm. +npm entrypoint, għalhekk ir-runtime tiegħu (inkluż Bun fejn ikkonfigurat) jiġi ppreservat. Il-manifest jirreġistra aliases barra dawk il-profili bħala invokati separatament, u -kmandi ta’ manutenzjoni huma pprojbiti fi profili ta’ skennjar read-only. +kmandi ta’ manutenzjoni huma pprojbiti fi profili ta’ scan read-only. -Dawn il-profili jkopru biss l-iskennjar statiku. Ma jiċċertifikawx testijiet tal-prodott, -coverage, packaging, checks esterni jew l-aċċettazzjoni sħiħa ta’ kandidat għar-rilaxx. -L-ammissjoni tal-workflow tuża l-fajl marbut `config/quality/admission-policy.json` u -`scripts/quality/admission-verdict.mjs`. Il-profili release-observer jibqgħu separati; -spezzjona l-checks u l-irċevuti applikabbli tagħhom b’mod indipendenti. L-inventarju deskritt -hawn taħt huwa referenza, mhux prova li gate fil-fatt ġie eżegwit. +Dawn il-profili jkopru biss l-iscan statiku. Ma jiċċertifikawx it-testijiet tal-prodott, +il-coverage, il-packaging, checks esterni jew l-aċċettazzjoni sħiħa ta’ kandidat għar-release. +L-ammissjoni tal-workflow tuża l-`config/quality/admission-policy.json` marbut u +`scripts/quality/admission-verdict.mjs`. Il-profili tar-release-observer jibqgħu separati; +spezzjona ċ-checks u l-irċevuti applikabbli tagħhom b’mod indipendenti. L-inventarju deskrittiv +hawn taħt huwa referenza, mhux prova li gate fil-fatt tħaddem. L-iskripts jinsabu taħt `scripts/check/` (gates tal-politika) u `scripts/quality/` (magna ratchet). Is-sors awtorevoli tas-CI huwa `.github/workflows/ci.yml`. -### Mogħdija rapida għar-Release PR (`quality.yml`) +### Fast-path tal-PR tar-release (`quality.yml`) -`.github/workflows/quality.yml` jikkomplementa s-CI fuq PRs main/release, pushes lejn protected branches, +`.github/workflows/quality.yml` jikkomplementa s-CI fuq PRs main/release, pushes lejn fergħat protetti, dispatch u merge groups. Il-PRs jużaw fast checks iffiltrati skont il-path. Il-build duplikat -diżattivat b’mod permanenti tneħħa; il-checks reali tal-build/package/boot jibqgħu fis-CI. - -| Job | Ambitu | Imblukkar | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -| `Docs Gates (fast-path)` | PRs tad-dokumentazzjoni/kodiċi; referenzi tad-dokumentazzjoni tal-API u docs-all | Iva | -| `Fast Quality Gates` | PRs tal-kodiċi; checks statiċi, typecheck, typecheck tad-dashboard, testijiet unit affettwati | Iva | -| `Forgotten sibling tests` | PRs tal-kodiċi; moduli mibdula traċċati sal-konsumaturi statiċi u testijiet sibling kandidati; paths ta’ barrel u dynamic-import jiġu rrappurtati bħala dijanjostika konsultattiva, b’eċċezzjonijiet referenzjati fl-allowlist | **Konsultattiv** | -| `Vitest (fast-path)` | PRs tal-kodiċi; suite rapida ta’ vitest | Iva | -| `Unit Tests fast-path` | PRs tal-kodiċi; suite ta’ unit tests b’4 shards | Iva | -| `No new ESLint warnings` | PRs tal-kodiċi; kontroll tal-lint konxju tas-suppressions | Iva, inklużi forks | -| `Merge integrity (changelog + generated skills)` | PRs li mhumiex draft; sinkronizzazzjoni taċ-changelog u tal-ħiliet iġġenerati | Iva, inklużi forks | - -#### Rapport dwar forgotten sibling tests - -`npm run check:forgotten-sibling-tests` jerġa’ juża l-import resolver wara l-mappa tal-impatt tat-testijiet. -Għal kull production module mibdul, jirrapporta ktajjen deterministiċi +diżattivat b’mod permanenti tneħħa; iċ-checks reali tal-build/package/boot jibqgħu fis-CI. + +| Job | Ambitu | Jibblokka | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `Docs Gates (fast-path)` | PRs tad-docs/kodiċi; refs tad-dokumentazzjoni tal-API u docs-all | Iva | +| `Fast Quality Gates` | PRs tal-kodiċi; checks statiċi, typecheck, typecheck tad-dashboard, unit tests affettwati | Iva | +| `Forgotten sibling tests` | PRs tal-kodiċi; moduli mibdula traċċati lejn konsumaturi statiċi u sibling tests kandidati; paths tal-barrel u dynamic-import jiġu rrappurtati bħala dijanjostika konsultattiva, b’eċċezzjonijiet referenzjati tal-allowlist | **Konsultattiv** | +| `Vitest (fast-path)` | PRs tal-kodiċi; suite vitest rapida | Iva | +| `Unit Tests fast-path` | PRs tal-kodiċi; suite ta’ unit tests b’4 shards | Iva | +| `No new ESLint warnings` | PRs tal-kodiċi; guard tal-lint konxju tas-suppressions | Iva, inklużi forks | +| `Merge integrity (changelog + generated skills)` | PRs mhux draft; sinkronizzazzjoni tal-changelog u tal-skills iġġenerati | Iva, inklużi forks | + +#### Rapport tat-testijiet sibling minsija + +`npm run check:forgotten-sibling-tests` jerġa’ juża l-import resolver wara t-test-impact map. +Għal kull modulu ta’ produzzjoni mibdul, jirrapporta ktajjen deterministiċi `changed module/symbol -> static consumer -> candidate sibling test` meta t-test kandidat -ikun nieqes mid-diff tal-pull request. Is-sommarju Markdown u r-riżultat JSON jinżammu bħala +ma jkunx fid-diff tal-pull request. Is-sommarju Markdown u r-riżultat JSON jinżammu bħala l-artifact tal-workflow `forgotten-sibling-tests` għall-kalibrazzjoni qabel kwalunkwe rollout li jimblokka. -Ir-re-esportazzjonijiet barrel u l-importazzjonijiet dinamiċi huma biss dijanjostiċi tar-riżoluzzjoni; qatt ma joħolqu +Ir-ri-esportazzjonijiet barrel u l-importazzjonijiet dinamiċi huma biss dijanjostiċi tar-riżoluzzjoni; qatt ma joħolqu sejba li timblokka. L-eċċezzjonijiet rieżaminati jinsabu f' -`config/quality/forgotten-sibling-allowlist.json`. Kull entrata trid issemmi t-test konsumatur u dak kandidat, -tagħti ġustifikazzjoni speċifika, u tinkludi link għal issue jew pull request ta' GitHub. Entrati fformattjati ħażin ifallu -b'mod restrittiv. L-eċċezzjonijiet ma jistgħux jinjoraw test kandidat imħassar jew diff li jżid `.skip`/`.todo`; -id-dgħufija tal-asserzjonijiet u forom oħra ta' masking jibqgħu r-responsabbiltà tal-gate indipendenti u imblokkanti +`config/quality/forgotten-sibling-allowlist.json`. Kull entrata trid issemmi l-konsumatur u t-test +kandidat, tagħti ġustifikazzjoni speċifika, u torbot ma' issue jew pull request ta' GitHub. Entrati fformattjati ħażin ifallu +b'mod magħluq. L-eċċezzjonijiet ma jistgħux jinjoraw test kandidat imħassar jew diff li jżid `.skip`/`.todo`; +id-dgħufija tal-asserzjonijiet u tipi oħra ta' maskra jibqgħu taħt ir-responsabbiltà tal-gate li jimblokka b'mod indipendenti `check:test-masking`. ### Job: `lint` Jitħaddem fuq kull PR lejn `main`. Jimblokka l-merge jekk ifalli. -| Script (`npm run ...`) | Jivvalida | Jimblokka | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Il-verżjoni ta' Node.js tinsab fil-medda appoġġjata | Iva | -| `check:cycles` | Importazzjonijiet ċirkolari — il-moduli kollha ta' `src/` + `open-sse/` | Iva | -| `check:route-validation:t06` | Schemas ta' Zod preżenti fuq ir-routes kollha (politika ta' Tier 6) | Iva | -| `check:any-budget:t11` | L-għadd ta' `@ts-expect-error // any` ma jaqbiżx il-baġit (catraca ta' Tier 11) | Iva | -| `check:provider-consistency` | Kull fornitur f’`providers.ts` għandu entrata korrispondenti f’`providerRegistry.ts` (u viċi versa, fi ħdan l-allowlist) | Iva | -| `check:model-lifecycle` | It-tliet tabelli tar-routing miżmuma manwalment jibqgħu konsistenti mal-istampa tal-lifecycle inkluża fir-repo (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ma tagħti punteġġ lil ebda id irtirat li `REGISTRY` jista’ jidderieġi; kull mira ta’ `BUILT_IN_ALIASES` tinsab f’`REGISTRY` u hija assenti mill-istampa tal-ids irtirati; kull id irtirat li għadu f’`REGISTRY` jiġi ridirett jew ikun elenkat f’`allowedRetiredInCatalog`; u ebda sors jew mira ta’ `DEFAULT_DEGRADATION_MAP` ma jidher bħala rtirat f’dik l-istampa. Dan ma jipprovax li mudell bħalissa qed jiġi pprovdut minn upstream attiv. Offline — iqabbel ma’ `config/quality/model-lifecycle.json`, aġġornat manwalment permezz ta’ `npm run quality:refresh-model-lifecycle` (jeħtieġ in-network; mhux integrat fis-CI). `allowedRetiredInCatalog` huwa ratchet ta’ tnaqqis gradwali: żid entrata biss flimkien ma’ issue ta’ traċċar. | Iva | -| `check:fetch-targets` | Kull `fetch("/api/...")` f’`src/` fuq in-naħa tal-klijent jirrisolvi għal `route.ts` reali | Iva | -| `check:deps` | Id-dipendenzi kollha li jistgħu jiġu installati b’`npm install` fil-`package.json` kollha fir-repo jinsabu f’`dependency-allowlist.json`; pakketti ġodda mhux ippinnjati jew slopsquatted jiġu mmarkati | Iva | -| `audit:deps` | `npm audit` (root + electron) — ebda avviż ta’ severità għolja/kritika (jikkoinċidi ma’ `check:vuln-ratchet` ta’ osv; ara l-Backlog tar-Razzjonalizzazzjoni) | Iva | -| `check:lockfile` | Integrità ta’ `package-lock.json` — reġistru https, hashes tal-integrità, ebda sovrascrittura tal-host | Iva | -| `check:licenses` | Lista ta’ permessi għal-liċenzji SPDX għad-dipendenzi tal-produzzjoni | Iva | -| `check:tracked-artifacts` | Ebda artifact tal-build / symlink ta’ `node_modules` ikkommitjat (jitħaddem ukoll fil-pre-commit ta’ husky; il-pre-push huwa intenzjonalment ħafif — #6716) | Iva | -| `check:ai-attribution` | Ebda trailer `Co-Authored-By` tal-AI/bot jew footer ta’ ġenerazzjoni bl-AI fil-commits, fit-titlu jew fil-kontenut tal-PR — Regola Stretta #16 (fil-loop ta’ kontrolli rapidi ta’ `quality.yml` għal PR→`release/**` — jaqra l-payload tal-event, ma jagħmel xejn barra mill-PRs — u pass għal PR biss fil-lint ta’ `ci.yml` għal PR→`main`; kif ukoll il-hook `commit-msg` ta’ husky; koawturi umani permessi; #14436) | -| `check:vitest-exclusions` | Kull esklużjoni ta’ Vitest issemmi issue ta’ traċċar u tidher f’`config/quality/vitest-exclusions.json` (#13204) | Iva | -| `check:file-size` | Ebda fajl tas-sors ma jaqbeż il-limitu għal kull estensjoni (ratchet: fajls kbar iffriżati fil-lista `frozen`) | Iva | -| `check:error-helper` | Ir-risposti ta’ żball fl-executors/handlers jużaw `buildErrorBody()` / `sanitizeErrorMessage()` (Regola Stretta #12) | Iva | -| `check:migration-numbering` | Il-fajls SQL tal-migrazzjoni huma nnumerati b’mod sekwenzjali, mingħajr lakuni jew duplikati | Iva | -| `check:public-creds` | L-ebda `client_id`/`client_secret` OAuth litterali jew ċwievet Firebase Web barra minn `publicCreds.ts` (Regola Stretta #11) | Iva | -| `check:db-rules` | L-ebda SQL mhux ipproċessat barra mill-moduli `src/lib/db/`; l-ebda importazzjoni aggregata minn `localDb.ts` (Regoli Stretti #2/#5) | Iva | -| `check:known-symbols` | L-eżekuturi tal-fornituri, l-istrateġiji tar-routing, u t-tradutturi rreġistrati fit-tabelli tad-dispaċċ tagħhom jaqblu mal-fajls fuq id-diska — l-ebda simbolu orfni jew mhux iddikjarat | Iva | -| `check:route-guard-membership` | Kull rotta li tniedi proċess sekondarju hija kklassifikata minn `isLocalOnlyPath()` (Regoli Stretti #15/#17) | Iva | -| `check:test-discovery` | Kull fajl `*.test.ts` / `*.spec.ts` fir-repo jinġabar minn tal-inqas eżekutur wieħed tat-testijiet (ratchet: il-lista tal-orfni f’`test-discovery-baseline.json` tista’ biss tiċkien) | Iva | -| `check:agent-skills-sync` | L-artifatti ġġenerati ta’ agent-skills jaqblu mal-katalgu tas-sors tagħhom (mingħajr devjazzjoni) | -| `check:provider-asset-provenance` | Il-logos/assi tal-fornituri għandhom entrata rreġistrata tal-provenjenza | -| `lint:json` | Il-fajls tal-konfigurazzjoni JSON jiġu pproċessati u jissodisfaw ir-regoli tal-lint tar-repożitorju | -| `typecheck:core` | Kompilazzjoni ta’ TypeScript mingħajr żbalji (twissijiet konsultattivi biss) | Iva | -| `typecheck:noimplicit:core` | `noImplicitAny` strett — maħsub għall-futur; ħafna siti ta’ sejħiet eżistenti għadhom jeħtieġu annotazzjonijiet | **Konsultattiv** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limitat għal `src/app/(dashboard)/**` (#7033) — il-lista magħżula ta’ 27 fajl ta’ `typecheck:core` ma tinkludi ebda TSX tad-dashboard, u `next build` lanqas qatt ma jwettaq kontroll tat-tipi fuqu (`next.config.mjs` jistabbilixxi `ignoreBuildErrors: true`), għalhekk rigressjonijiet ta’ identifikaturi orfni hemmhekk (#6625/#6909) ma kinux viżibbli għas-CI. Isiru differenzi ma’ linja bażi ffriżata tal-għadd għal kull fajl/kodiċi TS (`config/quality/dashboard-typecheck-baseline.json`, bl-istess mudell ta’ infurzar kontra valuri skaduti bħal `check:known-symbols`) — żbalji ĠODDA biss lil hinn mill-għadd fil-linja bażi jfallu l-kontroll; naqqas il-linja bażi b’mod progressiv permezz ta’ `--update` meta jiġi rranġat żball eżistenti. | Iva | +| Script (`npm run ...`) | Jivvalida | Jimblokka | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Il-verżjoni ta' Node.js tinsab fil-medda appoġġjata | Iva | +| `check:cycles` | Importazzjonijiet ċirkolari madwar `src/` + `open-sse/` kollha (ibbażati fuq AST, bil-`paths` ta' tsconfig riżolti). Bare = konsultattiv, jelenka ċ-ċikli. `check:cycles:ratchet` (dak li jħaddem is-CI) jimblokka meta l-għadd jaqbeż il-limitu massimu `metrics.cycles` f'`quality-baseline.json` — bħalissa 14, `direction: down`, għalhekk jista' jonqos biss (#15159 G-01/G-02) | Iva (ratchet) | +| `check:route-validation:t06` | Schemas ta' Zod preżenti fuq ir-routes kollha (politika ta' Tier 6) | Iva | +| `check:any-budget:t11` | L-għadd ta' `@ts-expect-error // any` ma jaqbiżx il-baġit (ratchet ta' Tier 11) | Iva | +| `check:provider-consistency` | Kull fornitur f’`providers.ts` għandu entrata korrispondenti f’`providerRegistry.ts` (u viċi versa, fil-limiti tal-lista ta’ permessi) | Iva | +| `check:model-lifecycle` | It-tliet tabelli tar-routing miżmuma manwalment jibqgħu konsistenti mal-istampa tal-istat taċ-ċiklu tal-ħajja inkluża fir-repo (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ma tagħti punteġġ lil ebda id irtirat li `REGISTRY` jista’ jirrotja; kull destinazzjoni ta’ `BUILT_IN_ALIASES` tinsab f’`REGISTRY` u hija assenti mill-istampa tal-istat tal-ids irtirati; kull id irtirat li għadu f’`REGISTRY` jiġi ridirezzjonat jew elenkat f’`allowedRetiredInCatalog`; u ebda sors jew destinazzjoni ta’ `DEFAULT_DEGRADATION_MAP` ma jidher bħala rtirat f’dik l-istampa tal-istat. Dan ma jagħtix prova li mudell bħalissa qed jiġi servut minn upstream attiv. Offline — iqabbel ma’ `config/quality/model-lifecycle.json`, aġġornat manwalment permezz ta’ `npm run quality:refresh-model-lifecycle` (jeħtieġ in-network; mhux integrat fis-CI). `allowedRetiredInCatalog` huwa mekkaniżmu progressiv ta’ tnaqqis: żid entrata biss flimkien ma’ issue għat-traċċar. | Iva | +| `check:fetch-targets` | Kull `fetch("/api/...")` f’`src/` fuq in-naħa tal-klijent jirriżolvi għal `route.ts` reali | Iva | +| `check:deps` | Id-dipendenzi kollha li jistgħu jiġu installati b’`npm install` fil-fajls `package.json` kollha fir-repo jinsabu f’`dependency-allowlist.json`; pakketti ġodda mhux ippinjati jew slopsquatted jiġu mmarkati | Iva | +| `audit:deps` | `npm audit` (root + electron) — ebda avviż ta’ severità għolja/kritika (jikkoinċidi mal-osv `check:vuln-ratchet`; ara l-Lista ta’ Xogħol b'Lura għar-Razzjonalizzazzjoni) | Iva | +| `check:lockfile` | Integrità ta’ `package-lock.json` — reġistru https, hashes tal-integrità, ebda sostituzzjoni tal-host | Iva | +| `check:licenses` | Lista ta’ permessi għal-liċenzji SPDX għad-dipendenzi tal-produzzjoni | Iva | +| `check:tracked-artifacts` | L-ebda artefatt tal-build / symlink ta’ `node_modules` ikkommettut (jitħaddem ukoll fil-pre-commit ta’ husky; il-pre-push huwa intenzjonalment ħafif — #6716) | Iva | +| `check:ai-attribution` | L-ebda trailer `Co-Authored-By` ta’ AI/bot jew footer ta’ ġenerazzjoni bl-AI fil-commits, fit-titlu jew fil-korp tal-PR — Regola Stretta #16 (fil-loop ta’ kontrolli rapidi ta’ `quality.yml` għal PR→`release/**` — jaqra l-payload tal-event, ma jagħmel xejn barra mill-PRs — u pass għal PR biss fil-lint ta’ `ci.yml` għal PR→`main`; kif ukoll il-hook `commit-msg` ta’ husky; koawturi umani huma permessi; #14436) | +| `check:vitest-exclusions` | Kull esklużjoni ta’ Vitest issemmi issue ta’ traċċar u tidher f’`config/quality/vitest-exclusions.json` (#13204) | Iva | +| `check:file-size` | L-ebda fajl tas-sors ma jaqbeż il-limitu għal kull estensjoni (ratchet: fajls kbar iffriżati fil-lista `frozen`) | Iva | +| `check:error-helper` | Ir-risposti ta’ żball fl-executors/handlers jużaw `buildErrorBody()` / `sanitizeErrorMessage()` (Regola Stretta #12) | Iva | +| `check:migration-numbering` | Il-fajls SQL tal-migrazzjoni huma nnumerati b'mod sekwenzjali, mingħajr lakuni jew duplikati | Iva | +| `check:public-creds` | L-ebda `client_id`/`client_secret` OAuth litterali jew ċwievet tal-Web ta' Firebase barra minn `publicCreds.ts` (Regola Stretta #11) | Iva | +| `check:db-rules` | L-ebda SQL mhux ipproċessat barra mill-moduli `src/lib/db/`; l-ebda importazzjoni minn barrel minn `localDb.ts` (Regoli Stretti #2/#5) | Iva | +| `check:known-symbols` | L-eżekuturi tal-fornituri, l-istrateġiji tar-routing, u t-tradutturi rreġistrati fit-tabelli tad-dispaċċ tagħhom jaqblu mal-fajls fuq id-diska — l-ebda simbolu orfni jew mhux iddikjarat | Iva | +| `check:route-guard-membership` | Kull rotta li tniedi proċess subordinat hija kklassifikata minn `isLocalOnlyPath()` (Regoli Stretti #15/#17) | Iva | +| `check:test-discovery` | Kull fajl `*.test.ts` / `*.spec.ts` fir-repo jinġabar minn mill-inqas test runner wieħed (ratchet: il-lista ta' fajls orfni f'`test-discovery-baseline.json` tista' biss tiċkien) | Iva | +| `check:agent-skills-sync` | L-artifacts iġġenerati tal-ħiliet tal-aġent jaqblu mal-katalgu sors tagħhom (mingħajr devjazzjoni) | +| `check:provider-asset-provenance` | Il-logos/assi tal-fornituri għandhom entrata tal-provenjenza rreġistrata | +| `lint:json` | Il-fajls tal-konfigurazzjoni JSON jiġu analizzati u jissodisfaw ir-regoli tal-lint tar-repo | +| `typecheck:core` | Kompilazzjoni TypeScript mingħajr żbalji (twissijiet konsultattivi biss) | Iva | +| `typecheck:noimplicit:core` | `noImplicitAny` strett — immirat għall-futur; ħafna siti ta' sejħiet eżistenti għadhom jeħtieġu annotazzjonijiet | **Konsultattiv** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` limitat għal `src/app/(dashboard)/**` (#7033) — il-lista ta' permessi kkurata ta' 27 fajl ta' `typecheck:core` ma tinkludi ebda TSX tad-dashboard, u `next build` lanqas qatt ma jagħmel verifika tat-tipi tiegħu (`next.config.mjs` jistabbilixxi `ignoreBuildErrors: true`), għalhekk ir-rigressjonijiet ta' identifikaturi orfni hemmhekk (#6625/#6909) ma kinux viżibbli għas-CI. Jagħmel diff ma' linja bażi ffriżata tal-għadd għal kull fajl/għal kull kodiċi TS (`config/quality/dashboard-typecheck-baseline.json`, l-istess mudell ta' infurzar tal-iskadenza bħal `check:known-symbols`) — huma biss żbalji ĠODDA lil hinn mill-għadd fil-linja bażi li jfallu l-kontroll; naqqas progressivament b'`--update` meta jiġi rranġat żball eżistenti. | Iva | ### Kompitu: `quality-gate` -Jitħaddem wara `test-coverage`. Jibblokka l-inkorporazzjoni jekk ifalli. - -| Skript | Jivvalida | Imblokkanti | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `quality:collect` | Jiġġenera `quality-metrics.json` (għadd ta' twissijiet ta' ESLint, kopertura mir-rapport ikkombinat tax-shards) | Iva (qabel ir-ratchet) | -| `quality:ratchet` | Kull metrika f'`quality-baseline.json` ma marritx lura (twissijiet ta' ESLint ≤ il-linja bażi; kopertura ≥ il-linja bażi) | Iva | -| `check:duplication` | Id-duplikazzjoni tal-kodiċi (jscpd@4) ma taqbiżx il-linja bażi f'`quality-baseline.json` | Iva | -| `check:complexity` | Il-kumplessità ċiklomatika fil-livell tal-fajl ma taqbiżx il-limitu (ESLint ewlieni `complexity` + `max-lines-per-function`) | Iva | -| `check:cognitive-complexity` | Ratchet tal-kumplessità konjittiva (`eslint-plugin-sonarjs`) — pass separat ta' ESLint; is-CI jħaddem it-tnejn magħqudin bħala l-pass uniku `check:complexity-ratchets` | Iva | -| `check:dead-code` | Ir-ratchet ta' exports / fajls mhux użati (knip) ma jmurx lura meta mqabbel mal-linja bażi | Iva | -| `check:compression-budget` | Baġit tal-benchmark tal-kompressjoni — il-limiti minimi tal-iffrankar tat-tokens għal kull magna ma jistgħux imorru lura | Iva | -| `check:type-coverage` | Ir-ratchet tal-perċentwal ittajpjat (`type-coverage`) ma jmurx lura; fil-biċċa l-kbira jissostitwixxi `typecheck:noimplicit:core` | Iva | -| `check:codeql-ratchet` | L-għadd ta' twissijiet CodeQL miftuħa ma jmurx lura (jaqra permezz ta' `gh api`; jaqbeż mingħajr żball jekk ma jkunx hemm token) — għall-frekwenza tal-aġġornament u l-attivazzjoni manwali: ara "Ratchet ta' CodeQL" hawn taħt | Iva | - -### Job: `quality-extended` - -Il-job kollu huwa konsultattiv (`continue-on-error: true`). Ir-ratchets ibbażati fuq npm -jitħaddmu tassew; l-iskaners esterni jiġu installati permezz ta' `gh release download` u jaqbżu -awtomatikament (exit 0) meta binarju jkun għadu nieqes. - -| Skript | Jivvalida | Imblokkanti | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -| `check:circular-deps` | Ebda dipendenzi ċirkolari (dpdm) | **Konsultattiv** | -| `check:bundle-size` | Id-daqs tal-bundle ma jaqbiżx il-limitu | **Konsultattiv** | -| `check:secrets` | Skennjar tas-sigrieti (gitleaks) — jaqbeż jekk il-binarju jkun nieqes | **Konsultattiv** | -| `check:vuln-ratchet` | Il-vulnerabbiltajiet tad-dipendenzi (osv-scanner) ma jmorrux lura — jaqbeż jekk il-binarju jkun nieqes | **Konsultattiv** | -| `check:workflows` | Lint tal-workflows (actionlint + zizmor); skaners neqsin/bil-ħsara, rapporti invalidi jew linja bażi tar-ratchet nieqsa jwasslu għal falliment bħala INCOMPLETE. Sejbiet validi jsegwu l-politika stretta/konsultattiva/tar-ratchet magħżula | L-eżekuzzjoni hija meħtieġa; ir-ratchet ta' zizmor huwa imblokkanti fis-CI | -| `check:openapi-breaking` | Bidliet inkompatibbli fil-kuntratt tal-API pubblika (`openapi.yaml`) meta mqabbel mal-fergħa bażi (oasdiff) — jiġġenera `openapiBreaking=N`; jaqbeż jekk oasdiff ikun nieqes jew l-ispeċifikazzjoni bażi ma tkunx tista' tiġi riżolta | **Konsultattiv** | - -### Job: `docs-sync-strict` +Jitħaddem wara `test-coverage`. Jimblokka l-amalgamazzjoni jekk ifalli. + +| Skript | Jivvalida | Jimblokka | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `quality:collect` | Jiġġenera `quality-metrics.json` (għadd ta’ twissijiet ESLint, kopertura mir-rapport ikkombinat tax-shards) | Iva (jiġi qabel ir-ratchet) | +| `quality:ratchet` | Kull metrika f’`quality-baseline.json` ma marritx lura (twissijiet ESLint ≤ il-linja bażi; kopertura ≥ il-linja bażi) | Iva | +| `check:duplication` | Id-duplikazzjoni tal-kodiċi (jscpd@4) ma taqbiżx il-linja bażi f’`quality-baseline.json` | Iva | +| `check:complexity` | Il-kumplessità ċiklomatika fil-livell tal-fajl ma taqbiżx il-limitu (ESLint ewlieni `complexity` + `max-lines-per-function`) | Iva | +| `check:cognitive-complexity` | Ratchet tal-kumplessità konjittiva (`eslint-plugin-sonarjs`) — pass separat ta’ ESLint; is-CI jħaddem it-tnejn ikkombinati bħala l-pass uniku `check:complexity-ratchets` | Iva | +| `check:dead-code` | Ir-ratchet tal-esportazzjonijiet / fajls mhux użati (knip) ma jmurx lura meta mqabbel mal-linja bażi | Iva | +| `check:compression-budget` | Baġit tal-parametru referenzjarju tal-kompressjoni — il-limiti minimi tal-iffrankar tat-tokens għal kull magna ma għandhomx imorru lura | Iva | +| `check:type-coverage` | Ir-ratchet tal-perċentwal ittajpjat (`type-coverage`) ma jmurx lura; fil-biċċa l-kbira jissostitwixxi `typecheck:noimplicit:core` | Iva | +| `check:codeql-ratchet` | L-għadd ta’ twissijiet CodeQL miftuħa ma jmurx lura (jaqra permezz ta’ `gh api`; jaqbeż b’mod sigur mingħajr token) — għaċ-ċiklu tal-aġġornament u l-iskattar manwali: ara "Ratchet ta’ CodeQL" hawn taħt | Iva | + +### Kompitu: `quality-extended` + +Il-kompitu kollu huwa konsultattiv (`continue-on-error: true`). Ir-ratchets ibbażati fuq npm jitħaddmu +tassew; l-iskaners esterni jiġu installati permezz ta’ `gh release download` u jaqbżu lilhom infushom (exit 0) +meta l-binarju jkun għadu nieqes. + +| Skript | Jivvalida | Jimblokka | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `check:circular-deps` | L-ebda dipendenza ċirkolari (dpdm) | **Konsultattiv** | +| `check:bundle-size` | Id-daqs tal-bundle ma jaqbiżx il-limitu | **Konsultattiv** | +| `check:secrets` | Skennjar ta’ sigrieti (gitleaks) — jaqbeż jekk il-binarju jkun nieqes | **Konsultattiv** | +| `check:vuln-ratchet` | Il-vulnerabbiltajiet tad-dipendenzi (osv-scanner) ma jmorrux lura — jaqbeż jekk il-binarju jkun nieqes | **Konsultattiv** | +| `check:workflows` | Verifika tal-workflows (actionlint + zizmor); skaners neqsin/bil-ħsara, rapporti invalidi jew linja bażi tar-ratchet nieqsa jfallu bħala INCOMPLETE. Sejbiet validi jsegwu l-politika magħżula stretta/konsultattiva/tar-ratchet | L-eżekuzzjoni hija meħtieġa; ir-ratchet ta’ zizmor jimblokka fis-CI | +| `check:openapi-breaking` | Bidliet inkompatibbli fil-kuntratt tal-API pubblika (`openapi.yaml`) meta mqabbel mal-fergħa bażi (oasdiff) — jiġġenera `openapiBreaking=N`; jaqbeż jekk oasdiff ikun nieqes jew l-ispeċifikazzjoni bażi ma tkunx tista’ tiġi riżolta | **Konsultattiv** | + +### Kompitu: `docs-sync-strict` Jitħaddem fuq kull PR lejn `main`. Jimblokka l-merge jekk ifalli. -| Skritt | Jivvalida | Jimblokka | +| Skript | Jivvalida | Imblokkanti | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | -| `check:docs-all` | Meta-gate li tħaddem is-6 sub-gates ta' hawn taħt b'mod sekwenzjali | Iva | -| ↳ `check:docs-sync` | Konsistenza tal-verżjonijiet ta' CHANGELOG / OpenAPI / llm.txt | Iva | -| ↳ `check:docs-counts` | L-għadd imsemmi fit-test (għadd ta' fornituri, għadd ta' migrazzjonijiet, eċċ.) jinsab fit-tieqa ratchet tal-għadd reali | Iva | -| ↳ `check:env-doc-sync` | Kull varjabbli tal-ambjent f'`.env.example` hija ddokumentata f'tabella tad-dokumentazzjoni, u viċi versa | Iva | -| ↳ `check:deprecated-versions` | Ma hemm l-ebda string ta' verżjoni deprekata fid-dokumentazzjoni | Iva | +| `check:docs-all` | Meta-gate li jħaddem is-6 sub-gates ta’ hawn taħt b’mod sekwenzjali | Iva | +| ↳ `check:docs-sync` | Konsistenza tal-verżjonijiet bejn CHANGELOG / OpenAPI / llm.txt | Iva | +| ↳ `check:docs-counts` | L-għadd fil-proża (għadd ta’ fornituri, għadd ta’ migrazzjonijiet, eċċ.) jinsab fit-tieqa ratcheted tal-għadd reali | Iva | +| ↳ `check:env-doc-sync` | Kull varjabbli tal-ambjent f’`.env.example` huwa ddokumentat f’tabella tad-dokumentazzjoni, u viċi versa | Iva | +| ↳ `check:deprecated-versions` | Ebda sekwenza ta’ verżjoni deprekata fid-dokumentazzjoni | Iva | | ↳ `check:doc-links` | Il-links markdown interni fid-dokumentazzjoni jirriżolvu għal fajls reali (forma `[test]`/`(path)`) | Iva | -| ↳ `check:fabricated-docs` | Ir-rotot, il-varjabbli tal-ambjent, il-kmandi CLI, l-ismijiet tal-hooks, u l-mogħdijiet tal-fajls iċċitati fid-dokumentazzjoni jeżistu fil-codebase. Gate stretta permezz ta' `--strict`; falliment mhux imblokkanti mingħajr il-flag. | Iva (permezz ta' `--strict` fis-CI) | -| `check:cli-i18n` | L-strings tal-kmandi CLI huma preżenti fil-fajls kollha tal-lokalitajiet i18n | Iva | +| ↳ `check:fabricated-docs` | Ir-rotot, il-varjabbli tal-ambjent, il-kmandi CLI, l-ismijiet tal-hooks, u l-mogħdijiet tal-fajls imsemmija fid-dokumentazzjoni jeżistu fil-codebase. Gate strett permezz ta’ `--strict`; falliment mhux imblokkanti mingħajr il-flag. | Iva (permezz ta’ `--strict` fis-CI) | +| `check:cli-i18n` | Is-sekwenzi tal-kmandi CLI huma preżenti fil-fajls tal-lokalitajiet i18n kollha | Iva | | `check:openapi-coverage` | L-ispeċifikazzjoni OpenAPI tkopri mill-inqas limitu minimu ratcheted tar-rotot reali | Iva | -| `check:openapi-security-tiers` | L-annotazzjonijiet tal-livelli tas-sigurtà f'`openapi.yaml` huma konsistenti mal-klassifikazzjonijiet ta' `routeGuard.ts` | **Konsultattiv** | -| `check:openapi-routes` | Kull mogħdija f'`openapi.yaml` tirriżolvi għal `route.ts` reali (kontra l-alluċinazzjonijiet) | Iva | -| `check:docs-symbols` | Kull referenza għal `/api/...` f'`docs/**/*.md` tirriżolvi għal `route.ts` reali (kontra l-alluċinazzjonijiet) | Iva | +| `check:openapi-security-tiers` | L-annotazzjonijiet tal-livelli tas-sigurtà f’`openapi.yaml` huma konsistenti mal-klassifikazzjonijiet ta’ `routeGuard.ts` | **Konsultattiv** | +| `check:openapi-routes` | Kull mogħdija f’`openapi.yaml` tirriżolvi għal `route.ts` reali (kontra l-alluċinazzjonijiet) | Iva | +| `check:docs-symbols` | Kull referenza `/api/...` f’`docs/**/*.md` tirriżolvi għal `route.ts` reali (kontra l-alluċinazzjonijiet) | Iva | | `i18n translation drift` | Ċwievet mhux tradotti fil-fajls tal-lokalitajiet i18n — twissija biss | **Konsultattiv** | -### Xogħol: `i18n-ui-coverage` +### Kompitu: `i18n-ui-coverage` -| Skritt | Jivvalida | Jimblokka | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (inline) | Il-kopertura taċ-ċwievet i18n tal-UI hija ≥ 65% | Iva | -| `check-ui-value-drift` (inline) | **Valur** bl-Ingliż li jkun inkiteb mill-ġdid ma jħalli warajh l-ebda traduzzjoni skaduta | Iva | -| `check-new-key-coverage` (inline) | Ċavetta **ġdida** bl-Ingliż tkun tradotta f'kull lokalità — markatur `__MISSING__:` jiġi rrifjutat | Iva | -| `check-translation-ratio` | Il-proporzjon ta' traduzzjoni reali għal kull lokalità (valuri identiċi għall-Ingliż / placeholders / entrati neqsin barra mill-allowlist) ma jridx jaqbeż `config/quality/i18n-translation-baseline.json` + il-marġni | **Konsultattiv** | +| Skript | Jivvalida | Imblokkanti | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `check-ui-keys-coverage` (inline) | Il-kopertura taċ-ċwievet i18n tal-UI hija ≥ 65% | Iva | +| `check-ui-value-drift` (inline) | **Valur** bl-Ingliż li jkun inkiteb mill-ġdid ma jħalli l-ebda traduzzjoni skaduta warajh | Iva | +| `check-new-key-coverage` (inline) | Ċavetta **ġdida** bl-Ingliż hija tradotta f’kull lokalità — markatur `__MISSING__:` jiġi rrifjutat | Iva | +| `check-translation-ratio` | Il-proporzjon ta’ traduzzjonijiet reali għal kull lokalità (identiku għall-Ingliż / placeholder / entrati neqsin barra l-lista permessa) ma jridx jaqbeż `config/quality/i18n-translation-baseline.json` + marġni | **Konsultattiv** | -Jeħtieġ `fetch-depth: 0` — il-gate tal-value-drift tqabbel `en.json` mal-merge base. +Jeħtieġ `fetch-depth: 0` — il-gate tad-drift tal-valuri jqabbel `en.json` mal-bażi tal-merge. -#### `check-ui-value-drift` — gate kontra traduzzjonijiet skaduti +#### `check-ui-value-drift` — gate għat-traduzzjonijiet skaduti -Taqbad dik ir-rigressjoni i18n waħda li l-gates l-oħra strutturalment ma jistgħux jaraw: valur bl-Ingliż -jinkiteb mill-ġdid u t-traduzzjonijiet derivati mill-Ingliż _preċedenti_ jibqgħu hemm, biex b'hekk -utenti li ma jużawx l-Ingliż jibqgħu jaqraw test miktub b'kunfidenza iżda li issa huwa żbaljat. +Jaqbad l-unika rigressjoni i18n li l-gates l-oħra strutturalment ma jistgħux jaraw: valur bl-Ingliż +jinkiteb mill-ġdid u t-traduzzjonijiet derivati mill-Ingliż _preċedenti_ jibqgħu hemm, sabiex +utenti li ma jużawx l-Ingliż jibqgħu jaqraw test miktub b’ċertezza, iżda li issa huwa żbaljat. -Dan fil-fatt ġie rilaxxat. `oauthModal.googleOAuthWarning` inkiteb mill-ġdid meta żdied l-għajnun tal-login -Antigravity (#5203); **39 minn 43 lokalità** żammew test li jgħid lill-operaturi biex "jikkopjaw il-URL -sħiħ u jwaħħluh hawn taħt" — fluss li ma jistax jitlesta għal dak il-fornitur. Dan baqa' -ma ndunawx bih sa #8463 minħabba li: +Dan tassew wasal fil-verżjoni rilaxxata. `oauthModal.googleOAuthWarning` inkiteb mill-ġdid meta ġie introdott +l-assistent tal-login Antigravity (#5203); **39 minn 43 lokalità** żammew test li kien jgħid lill-operaturi biex “jikkopjaw +il-URL sħiħ u jwaħħluh hawn taħt” — fluss li ma jistax jitlesta għal dak il-fornitur. Dan baqa’ +ma ġiex innutat sa #8463 għaliex: -- `sync-ui-keys` jimla biss ċwievet li huma **assenti**, qatt dawk li huma **skaduti**; +- `sync-ui-keys` jimla biss ċwievet li huma **assenti**, u qatt dawk li huma **skaduti**; - `check-ui-keys-coverage` jgħodd il-_preżenza_ taċ-ċwievet, għalhekk traduzzjoni skaduta titqies bħala koperta; -- `check-translation-drift` isegwi l-kopji mera tad-dokumentazzjoni `docs/i18n//**.md` — - qatt ma jaqra `src/i18n/messages/*.json`. Ilu jimblokka fix-xogħol `docs-sync-strict` mir-risinkronizzazzjoni - 2026-09: editja dokument ewlieni → `npm run i18n:run -- --files=` (fil-livell tat-taqsima, irħis). +- `check-translation-drift` isegwi l-kopji paralleli tad-dokumentazzjoni `docs/i18n//**.md` — + qatt ma jaqra `src/i18n/messages/*.json`. Imblokkanti fil-kompitu `docs-sync-strict` mir-risinkronizzazzjoni + 2026-09 ’l hawn: editja dokument ewlieni → `npm run i18n:run -- --files=` (fil-livell tat-taqsima, irħis). -**Konxju tad-diff, mhux ibbażat fuq baseline.** Dan iqabbel `en.json` fil-merge base mas-siġra -tax-xogħol; għal kull key li l-valur tagħha bl-Ingliż inbidel, kwalunkwe locale li għadu fih -traduzzjoni mhux mittiefsa jitqies skadut. Dan intenzjonalment **jiffriża d-dejn eżistenti minn qabel** — diff -ma jistax juri minn liema verżjoni antika bl-Ingliż oriġinat traduzzjoni li ilha hemm, għalhekk il-kontroll jiġġudika -biss dak li tmiss il-bidla attwali. L-alternattiva (baseline ta’ hash għal kull key) tkun teħtieġ -fajl iġġenerat ta’ ~600 KB, 3× akbar mill-akbar baseline eżistenti, li jinbidel ma’ kull PR tal-i18n. +**Sensittiv għad-diff, mhux sostnut minn baseline.** Iqabbel `en.json` fil-bażi tal-merge mas- +siġra tax-xogħol; għal kull ċavetta li l-valur Ingliż tagħha nbidel, kwalunkwe locale li għadu +fih traduzzjoni mhux mittiefsa jkun skadut. Dan intenzjonalment **jiffriża d-dejn eżistenti minn qabel** — diff +ma jistax jiżvela minn liema Ingliż antik ġiet traduzzjoni li ilha teżisti, għalhekk il-kontroll jiġġudika +biss dak li tmiss il-bidla attwali. L-alternattiva (baseline ta' hash għal kull ċavetta) tkun teħtieġ +fajl iġġenerat ta' ~600 KB, 3× akbar mill-akbar baseline eżistenti, li jinbidel ma' kull PR tal-i18n. Hemm żewġ modi kif tissodisfah: 1. aġġorna t-traduzzjonijiet affettwati, jew -2. issettjahom għal `__MISSING__:` — waqt l-eżekuzzjoni mbagħad jiġi pprovdut l-Ingliż ikkoreġut - (`src/i18n/request.ts::deepMergeFallback`, #7258) u l-key tidħol fil-kju għat-traduzzjoni. +2. issettjahom għal `__MISSING__:` — waqt it-tħaddim imbagħad jiġi pprovdut l-Ingliż ikkoreġut + (`src/i18n/request.ts::deepMergeFallback`, #7258) u ċ-ċavetta tidħol fil-kju għat-traduzzjoni. -Jekk it-**tifsira** tas-string inbidlet, ippreferi li **tibdel l-isem tal-key**: key ġdida ma tistax tiret -traduzzjoni skaduta. Dan huwa l-mudell li ntuża minn #8463. +Jekk it-**tifsira** tas-sekwenza nbidlet, ippreferi li **tibdel isem iċ-ċavetta**: ċavetta ġdida ma tistax tiret +traduzzjoni skaduta. Dan huwa l-mudell li ntuża f'#8463. ```bash npm run i18n:check-value-drift # strett (dak li jħaddem is-CI) @@ -231,48 +231,48 @@ npm run i18n:check-value-drift:warn # rapport biss BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Joħroġ b’0 u `SKIP reason=base-unresolved` meta l-katalgu bażi ma jkunx jista’ jinqara (shallow -clone mingħajr il-base ref), bl-istess imġiba bħal `check-openapi-breaking`. +Joħroġ b'0 u `SKIP reason=base-unresolved` meta l-katalgu bażi ma jkunx jista' jinqara (klonu baxx +mingħajr ir-ref bażi), bl-istess imġiba bħal `check-openapi-breaking`. -### Job: `i18n` +### Kompitu: `i18n` -Matriċi sħiħa ta’ validazzjoni tal-i18n (job wieħed għal kull locale). Il-job kollu huwa konsultattiv. +Matriċi sħiħa ta' validazzjoni tal-i18n (kompitu wieħed għal kull locale). Il-kompitu kollu huwa konsultattiv. -| Script | Jivvalida | Imblukkar | -| ------------------------------- | -------------------------------------------- | ------------------------------------------------------------- | -| `validate_translation.py quick` | Kompletezza tat-traduzzjoni għal kull locale | **Konsultattiv** (`continue-on-error: true` fuq il-job kollu) | +| Skritt | Jivvalida | Imblukkar | +| ------------------------------- | ----------------------------------------------- | ----------------------------------------------------------------- | +| `validate_translation.py quick` | Il-kompletezza tat-traduzzjoni għal kull locale | **Konsultattiv** (`continue-on-error: true` fuq il-kompitu kollu) | -### Job: `pr-test-policy` +### Kompitu: `pr-test-policy` Jitħaddem fuq pull requests biss. -| Script | Jivvalida | Imblukkar | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | PRs li jibdlu l-code tal-produzzjoni f’`src/`, `open-sse/`, `electron/`, jew `bin/` iridu jinkludu jew jaġġornaw it-tests (Regola Stretta #8) | Iva | -| `check:test-masking` | Il-fajls tat-test mibdula ma jnaqqsux l-għadd nett ta’ asserts u ma jżidux tautoloġiji `assert.ok(true)` | Iva | -| `check:pr-evidence` | Il-body tal-PR jiċċita evidenza minn tests/VPS għall-bidla (jawtomatizza r-Regola Stretta #18 billi jfittex fit-test tal-PR — fraġli, ara l-Backlog) | Iva | +| Skritt | Jivvalida | Imblukkar | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | +| `check:pr-test-policy` | PRs li jibdlu l-kodiċi tal-produzzjoni f'`src/`, `open-sse/`, `electron/`, jew `bin/` iridu jinkludu jew jaġġornaw it-testijiet (Regola Stretta #8) | Iva | +| `check:test-masking` | Il-fajls tat-test mibdula ma jnaqqsux l-għadd nett ta' asserzjonijiet u ma jżidux tautoloġiji `assert.ok(true)` | Iva | +| `check:pr-evidence` | Il-kontenut tal-PR jiċċita evidenza minn testijiet/VPS għall-bidla (jawtomatizza r-Regola Stretta #18 billi jfittex fit-test tal-PR — fraġli, ara l-Backlog) | Iva | -### Job: `test-vitest` +### Kompitu: `test-vitest` -Jitħaddem wara `build`. Jimblokka l-merge jekk ifalli. +Jitħaddem wara `build`. Jibblokka l-merge jekk ifalli. -| Suite | Jivvalida | Imblukkar | -| ---------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Server MCP (110 għodod), autoCombo, cache — runner ta’ vitest | Iva | -| `test:vitest:ui` | Tests tal-komponenti tal-UI — runner ta’ vitest | **Jimblokka** — il-fallimenti eżistenti minn qabel huma espliċitament esklużi f’`vitest.config.ts`; fallimenti ġodda jfallu l-job | +| Ġabra | Jivvalida | Imblukkar | +| ---------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Server MCP (110 għodod), autoCombo, cache — runner ta' vitest | Iva | +| `test:vitest:ui` | Testijiet tal-komponenti tal-UI — runner ta' vitest | **Jimblokka** — il-fallimenti eżistenti minn qabel huma esklużi b'mod espliċitu f'`vitest.config.ts`; fallimenti ġodda jġiegħlu lill-kompitu jfalli | -### Workflows ta’ kull lejl (skedati, konsultattivi) +### Flussi tax-xogħol ta' kull lejl (skedati, konsultattivi) Dawn jitħaddmu fuq skeda cron (u `workflow_dispatch`), qatt fuq PRs. Kollha huma konsultattivi. -| Workflow | Jivvalida | Imblukkar | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | Tests ibbażati fuq proprjetajiet ta’ fast-check b’seed każwali + għadd għoli ta’ runs | **Konsultattiv** | -| `nightly-resilience` | Kontroll tat-tkabbir tal-heap, injezzjoni ta’ ħsarat kaotiċi, load/soak b’k6 | **Konsultattiv** | -| `nightly-llm-security` | Protezzjoni kontra l-injezzjoni ta’ promptfoo (modalità ta’ mblukkar) + probes ta’ garak (jinqabżu mingħajr provider secret) | **Konsultattiv** | -| `nightly-schemathesis` | Fuzzing tal-kuntratt OpenAPI (schemathesis) kontra OmniRoute live permezz ta’ `docs/openapi.yaml` — jikxef ksur tal-ispeċifikazzjoni / 500s mhux immaniġġjati (Fażi 8 B.4) | **Konsultattiv** | -| `nightly-mutation` | Punteġġ tal-mutation testing ta’ Stryker fuq il-linja rapida tal-unit tests — mutants li jibqgħu ħajjin jikxfu asserts dgħajfa | **Konsultattiv** | -| `nightly-compat` | Matriċi tal-kompatibbiltà tal-engine ta’ Node fil-firxiet appoġġjati ta’ `engines.node` | **Konsultattiv** | +| Fluss tax-xogħol | Jivvalida | Imblukkar | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | Testijiet tal-proprjetajiet ta' fast-check b'seed każwali + għadd għoli ta' eżekuzzjonijiet | **Konsultattiv** | +| `nightly-resilience` | Kontroll tat-tkabbir tal-heap, injezzjoni ta' ħsarat kaotiċi, tagħbija/test fit-tul b'k6 | **Konsultattiv** | +| `nightly-llm-security` | Protezzjoni ta' promptfoo kontra l-injezzjoni (modalità ta' mblukkar) + sondi ta' garak (jinqabżu mingħajr sigriet tal-fornitur) | **Konsultattiv** | +| `nightly-schemathesis` | Fuzzing tal-kuntratt OpenAPI (schemathesis) kontra OmniRoute attiv bl-użu ta' `docs/openapi.yaml` — jesponi ksur tal-ispeċifikazzjoni / żbalji 500 mhux immaniġġjati (Fażi 8 B.4) | **Konsultattiv** | +| `nightly-mutation` | Punteġġ tal-ittestjar b'mutazzjonijiet ta' Stryker fuq il-korsija rapida tat-testijiet tal-unità — mutanti li jibqgħu ħajjin jesponu asserzjonijiet dgħajfa | **Konsultattiv** | +| `nightly-compat` | Matriċi ta' kompatibbiltà tal-magna Node fil-firxiet appoġġjati ta' `engines.node` | **Konsultattiv** | --- @@ -539,43 +539,43 @@ ma jitgħabbiex awtomatikament (int tagħżel u tivverifika l-bridge MCP↔LSP); --- -## Lista Pendenti tar-Razzjonalizzazzjoni (rieżami tal-ROI — Fażi 9 Mewġa 3) +## Lista Pendenti ta’ Razzjonalizzazzjoni (rieżami tar-ROI — Fażi 9 Mewġa 3) -Dan l-inventarju ġie rrikonċiljat ma’ `ci.yml` fis-2026-06-17 (il-verżjoni preċedenti kienet ħalliet barra +Dan l-inventarju ġie rrikonċiljat ma’ `ci.yml` fis-2026-06-17 (il-verżjoni preċedenti ħalliet barra `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Rieżami tal-ROI tas-sett irrikonċiljat +`check:codeql-ratchet`, `check:pr-evidence`). Rieżami tar-ROI tas-sett irrikonċiljat identifika l-kandidati għar-razzjonalizzazzjoni li ġejjin. **L-għaqdiet huma bidliet mekkaniċi fis-CI; -il-qlib/tneħħijiet huma deċiżjonijiet ta’ politika riżervati għall-operatur.** Għadu ma ġie applikat -xejn minn dan ta’ hawn taħt. +il-qlib/tneħħija huma deċiżjonijiet ta’ politika riżervati għall-operatur.** Xejn minn dan ta’ hawn taħt +għadu ma ġie applikat. -**Mhux dokumentati hawn fuq ukoll** (konsultattivi, sinjal baxx): il-job `docs-lint` +**Ukoll mhux iddokumentati hawn fuq** (konsultattivi, sinjal dgħajjef): il-job `docs-lint` (markdownlint + Vale, il-job kollu b’`continue-on-error`) u l-workflows awtonomi tal-iskanners `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` jinsab f’ `quality-baseline.json` iżda mhuwiex marbut ma’ ratchet li jimblokka f’`ci.yml` — il-metrika -bħalissa hija iżolata. +bħalissa hija orfni. -### Għaqda / deduplikazzjoni (mekkaniċi, riskju aktar baxx) +### Għaqda / deduplikazzjoni (mekkanika, riskju aktar baxx) -Kull kandidat ġie vvalidat mal-istat attiv tal-gates fis-2026-06-17 (ivverifika anki jekk tafda); -diversi għaqdiet “ovvji” irriżultaw li jaħbu dejn u **mhumiex** sostituzzjonijiet diretti u nodfa. +Kull kandidat ġie vvalidat kontra l-istat attiv tal-kontrolli fis-2026-06-17 (afda-iżda-vverifika); +diversi għaqdiet “ovvji” irriżultaw li jaħbu dejn u **mhumiex** sostituzzjonijiet diretti nodfa. -- **`check:docs-sync` jitħaddem darbtejn** — waħdu fil-job `lint` u għal darb’oħra fi ħdan `check:docs-all` (`docs-sync-strict`) u l-hook pre-commit ta’ husky. ✅ **LEST** — l-invokazzjoni awtonoma f’`lint` tneħħiet. -- **Skennjar tas-CVE** — ❌ **MHIX għaqda nadifa.** `audit:deps` ifalli b’mod assolut għal kwalunkwe CVE ta’ severità għolja/kritika; `check:vuln-ratchet` (osv) ifalli biss fuq _rigressjoni_ meta mqabbel mal-baseline (bħalissa 1 MODERATE). Semantika differenti — it-tneħħija ta’ `audit:deps` telimina l-gate assolut għal severità għolja/kritika. Żomm it-tnejn. -- **Sejbien taċ-ċikli** — ❌ **MHIX għaqda nadifa.** `check:circular-deps` (dpdm) jirrapporta **91 ċiklu** (għalhekk huwa konsultattiv); ma jistax jiġi promoss għal wieħed li jimblokka qabel ma jiġu solvuti, u għandu kamp ta’ applikazzjoni usa’ minn dak ta’ `check:cycles`, li huwa aħdar u kkurat. Żomm `check:cycles` bħala wieħed li jimblokka; ir-riżoluzzjoni tal-91 ċiklu tad-dpdm hija punt separat fil-lista pendenti. -- **Kumplessità** — ✅ **LEST** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): passaġġ wieħed tal-ESLint, b’għadd skont ruleId sabiex il-baselines ta’ cyclomatic+max-lines u cognitive jibqgħu indipendenti; il-kontrolli individwali `check:complexity` / `check:cognitive-complexity` jibqgħu għal `--update` lokali. -- **Kontra l-alluċinazzjoni ta’ `/api`** — ✅ **LEST** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): inventarju wieħed tas-sistema tal-fajls għal `src/app/api`, filwaqt li openapi-routes + docs-symbols xorta jirrapportaw indipendentement; il-kontrolli individwali jibqgħu għall-eżekuzzjonijiet lokali. -- **`check:node-runtime` jitħaddem fi 11-il job** — ⚠️ **ROI baxx.** Kull wieħed juża runner separat u l-kontroll jieħu <1s; l-iffrankar totali huwa ta’ madwar 10s, bil-konsegwenza li tintilef protezzjoni rħisa għal kull job. Ma jiswiex it-tibdil. -- **`typecheck:noimplicit:core` fil-lint tas-CI** — ✅ **tneħħa mill-job lint** (kien konsultattiv b’`continue-on-error`); is-superfiċje tat-tipi li timblokka hija `typecheck:core` + `check:type-coverage`. L-iskript lokali nżamm. +- **`check:docs-sync` jitħaddem darbtejn** — b’mod awtonomu fil-job `lint` u għal darb’oħra ġewwa `check:docs-all` (`docs-sync-strict`) u l-hook pre-commit ta’ husky. ✅ **LEST** — l-invokazzjoni awtonoma f’`lint` tneħħiet. +- **Skennjar tas-CVE** — ❌ **MHUX għaqda nadifa.** `audit:deps` ifalli b’mod strett għal kwalunkwe CVE ta’ severità għolja/kritika; `check:vuln-ratchet` (osv) ifalli biss meta jkun hemm _rigressjoni_ meta mqabbel mal-linja bażi (bħalissa 1 MODERATE). Semantika differenti — it-tneħħija ta’ `audit:deps` telimina l-kontroll assolut għal severità għolja/kritika. Żomm it-tnejn. +- **Individwazzjoni taċ-ċikli** — ✅ **LEST** (#15159 G-01/G-02). It-test l-antik hawn sejjaħ lil `check:cycles` il-kontroll “aħdar u kkurat” u ġġustifika li jibqa’ jimblokka minħabba li `check:circular-deps` (dpdm) irrapporta 91 ċiklu. Dak l-aħdar kien **aħdar falz**: `check:cycles` skennja 5 sottodirettorji (450 fajl), qabbel biss `import|export … from` statiċi, u warrab kull speċifikatur `@/` u `@omniroute/open-sse/`, għalhekk ma setax jara ċ-ċikli ta’ importazzjoni dinamika + aliases li kienu jiddominaw ir-repo. Irranġat: il-kontroll issa jgħaddi minn `src` + `open-sse` (5023 fajl), jiġbor speċifikaturi mill-AST ta’ TypeScript (għalhekk `import("…")` jingħadd filwaqt li `typeof import("…")` f’pożizzjoni ta’ tip ma jingħaddx), u jirriżolvi `paths` ta’ tsconfig. Isib **14-il** ċiklu, mhux 0. Minħabba li 14-il ċiklu preeżistenti ma jistgħux jiġu rranġati fi PR ta’ kontroll, `check:cycles` issa huwa **ratchet** (`--ratchet`, limitu massimu `metrics.cycles.value = 14` f’`quality-baseline.json`, `direction: down`) — jimblokka kwalunkwe _rigressjoni_ u l-għadd jista’ jonqos biss. Is-CI jħaddem `npm run check:cycles:ratchet`. It-tnaqqis progressiv jimxi ma’ **A-01**. `check:circular-deps` (dpdm) jibqa’ konsultattiv bħala t-tieni opinjoni usa’. +- **Kumplessità** — ✅ **LEST** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): passaġġ wieħed ta’ ESLint, jgħodd skont ruleId sabiex il-linji bażi ta’ cyclomatic+max-lines u dawk konjittivi jibqgħu indipendenti; `check:complexity` / `check:cognitive-complexity` individwali jibqgħu għal `--update` lokali. +- **Kontra l-alluċinazzjoni ta’ `/api`** — ✅ **LEST** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): inventarju wieħed tas-sistema tal-fajls ta’ `src/app/api`, openapi-routes + docs-symbols xorta jirrapportaw b’mod indipendenti; il-kontrolli individwali jibqgħu għal eżekuzzjonijiet lokali. +- **`check:node-runtime` jitħaddem fi 11-il job** — ⚠️ **ROI baxx.** Kull wieħed juża runner separat u l-kontroll jieħu <1s; iffrankar totali ta’ ~10s, bir-riskju li jintilef kontroll irħis għal kull job. Ma jiswiex it-taqlib. +- **`typecheck:noimplicit:core` fil-lint tas-CI** — ✅ **tneħħa mill-job lint** (kien konsultattiv b’`continue-on-error`); is-superfiċje tal-kontroll tat-tipi li timblokka hija `typecheck:core` + `check:type-coverage`. L-iskript lokali nżamm. ### Aqleb / iddeċiedi (politika tal-operatur) -- `check:openapi-security-tiers` (konsultattiv) — ❌ **MA JISTAX JINQALEB B’MOD NADIF.** Joħroġ b’0 iżda jwissi li diversi routes ta’ `traffic-inspector` taħt `LOCAL_ONLY_API_PREFIXES` m’għandhomx l-annotazzjoni `x-loopback-only: true`. L-infurzar tiegħu jeħtieġ li l-ewwel jiżdiedu dawk l-annotazzjonijiet ma’ `openapi.yaml`. -- `typecheck:noimplicit:core` (konsultattiv) — fil-biċċa l-kbira huwa kopert mir-ratchet `check:type-coverage` li jimblokka. Aqilbu għal ratchet jew neħħi t-tieni passaġġ `tsc` żejjed. -- `test:vitest:ui` (issa **jimblokka**) — il-fallimenti li kienu jeżistu minn qabel huma esklużi espliċitament f’`vitest.config.ts` b’kummenti ta’ traċċar `// #8618`; fallimenti ġodda jfallu l-job. -- `check:secrets` (gitleaks, ratchet li jimblokka u ffriżat fuq 3 pożittivi foloz dokumentati) — żid it-3 mal-allowlist biex tilħaq 0, jew baxxih għal wieħed konsultattiv. Jikkoinċidi mal-iskannjar nattiv tas-segreti ta’ GitHub + `check:public-creds`. -- `check:pr-evidence` (jimblokka, ifittex b’grep fit-test tal-korp tal-PR) — riskju għoli ta’ pożittivi foloz; jekk jitneħħa jdgħajjef l-infurzar tar-Regola Stretta #18, għalhekk din hija deċiżjoni ta’ politika ġenwina. -- `semgrep` (awtonomu u konsultattiv) — jikkoinċidi ma’ CodeQL għall-familji tal-OWASP; qabbad il-baseline tiegħu ma’ ratchet jew neħħih. +- `check:openapi-security-tiers` (konsultattiv) — ❌ **MA JISTAX jinqaleb b’mod nadif.** Joħroġ b’0 iżda jwissi li diversi routes ta’ `traffic-inspector` taħt `LOCAL_ONLY_API_PREFIXES` m’għandhomx l-annotazzjoni `x-loopback-only: true`. Biex jiġi infurzat, l-ewwel iridu jiżdiedu dawk l-annotazzjonijiet ma’ `openapi.yaml`. +- `typecheck:noimplicit:core` (konsultattiv) — fil-biċċa l-kbira sostitwit mir-ratchet `check:type-coverage` li jimblokka. Aqilbu għal ratchet jew neħħi t-tieni passaġġ żejjed ta’ `tsc`. +- `test:vitest:ui` (issa **jimblokka**) — fallimenti preeżistenti huma espliċitament esklużi f’`vitest.config.ts` b’kummenti ta’ traċċar `// #8618`; fallimenti ġodda jfallu l-job. +- `check:secrets` (gitleaks, ratchet li jimblokka ffriżat fuq 3 pożittivi foloz iddokumentati) — żid it-3 mal-lista ta’ permessi biex tilħaq 0, jew iddegradah għal konsultattiv. Jikkoinċidi mal-iskannjar nattiv tas-sigrieti ta’ GitHub + `check:public-creds`. +- `check:pr-evidence` (jimblokka, ifittex fit-test tal-korp tal-PR) — riskju għoli ta’ pożittivi foloz; jekk jitneħħa jdgħajjef l-infurzar ta’ Hard Rule #18, għalhekk din hija deċiżjoni ġenwina ta’ politika. +- `semgrep` (awtonomu konsultattiv) — jikkoinċidi ma’ CodeQL għall-familji OWASP; qabbad il-linja bażi tiegħu ma’ ratchet jew neħħih. --- diff --git a/docs/i18n/my/CONTRIBUTING.md b/docs/i18n/my/CONTRIBUTING.md index 59ea4143e42..2cc6ab67a87 100644 --- a/docs/i18n/my/CONTRIBUTING.md +++ b/docs/i18n/my/CONTRIBUTING.md @@ -402,20 +402,20 @@ Model definition များကို `open-sse/config/providerRegistry.ts` တ ## Pull Request စစ်ဆေးရန်စာရင်း -- [ ] Tests များ အောင်မြင်သည် (`npm test`) -- [ ] Linting အောင်မြင်သည် (`npm run lint`) -- [ ] Build အောင်မြင်သည် (`npm run build`) -- [ ] Public function နှင့် interface အသစ်များအတွက် TypeScript types များ ထည့်သွင်းထားသည် -- [ ] Hardcoded secrets သို့မဟုတ် fallback values များ မရှိပါ -- [ ] အများသုံး upstream credentials များကို literal များအဖြစ် လုံးဝမထည့်ဘဲ `resolvePublicCred()` မှတစ်ဆင့် ထည့်သွင်းထားသည် ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ကို ကြည့်ပါ) -- [ ] Error response များသည် `buildErrorBody()` / `sanitizeErrorMessage()` ကို ဖြတ်သန်းသည် — response body များထဲတွင် raw stack trace များ မပါဝင်ပါ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ကို ကြည့်ပါ) -- [ ] Shell commands (`exec` / `spawn`) များသည် runtime values များကို string interpolation ဖြင့် မဟုတ်ဘဲ `env` မှတစ်ဆင့် ပေးပို့သည် -- [ ] Input အားလုံးကို Zod schemas များဖြင့် အတည်ပြုစစ်ဆေးထားသည် -- [ ] အသုံးပြုသူနှင့် သက်ဆိုင်သော ပြောင်းလဲမှုများအတွက် Changelog **fragment** ကို `changelog.d/{features|fixes|maintenance}/-.md` အောက်တွင် ထည့်သွင်းထားသည် ([`changelog.d/README.md`](./changelog.d/README.md) ကို ကြည့်ပါ) — `CHANGELOG.md` ကို တိုက်ရိုက် **မပြင်ဆင်ပါနှင့်**။ Fragment များကို release လုပ်ချိန်တွင် စုစည်းပြီး PR များအကြား မည်သည့်အခါမျှ conflict မဖြစ်ပါ -- [ ] Documentation ကို အပ်ဒိတ်လုပ်ထားသည် (သက်ဆိုင်ပါက) -- [ ] CodeQL / Secret-Scanning alert အသစ်များ မဖွင့်ထားပါ၊ သို့မဟုတ် alert တစ်ခုချင်းစီကို သက်ဆိုင်ရာ `docs/security/` doc ကို ကိုးကားသည့် နည်းပညာဆိုင်ရာ အကြောင်းပြချက်ဖြင့် ပယ်ဖျက်ထားသည် -- [ ] Child process များကို စတင်သည့် routes (`/api/mcp/`, `/api/cli-tools/runtime/`) ကို `src/server/authz/routeGuard.ts` ရှိ `isLocalOnlyPath()` အဖြစ် အမျိုးအစားသတ်မှတ်ထားသည် — [တင်းကျပ်သော စည်းမျဉ်း #15](docs/security/ROUTE_GUARD_TIERS.md) ကို ကြည့်ပါ -- [ ] Commit message များတွင် `Co-Authored-By` trailers မပါဝင်ပါ — commit များသည် repository ပိုင်ရှင်၏ Git identity တစ်ခုတည်းအောက်တွင်သာ ပေါ်ရမည် (တင်းကျပ်သော စည်းမျဉ်း #16) +- [ ] စမ်းသပ်မှုများ အောင်မြင်သည် (`npm test`) +- [ ] Linting စစ်ဆေးမှုများ အောင်မြင်သည် (`npm run lint`) +- [ ] Build ပြုလုပ်မှု အောင်မြင်သည် (`npm run build`) +- [ ] အများသုံး function နှင့် interface အသစ်များအတွက် TypeScript type များ ထည့်သွင်းထားသည် +- [ ] Hardcode လုပ်ထားသော secret သို့မဟုတ် fallback value များ မရှိပါ +- [ ] အများသုံး upstream credential များကို literal များအဖြစ် မသုံးဘဲ `resolvePublicCred()` မှတစ်ဆင့် ထည့်သွင်းထားသည် ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ကို ကြည့်ပါ) +- [ ] Error response များကို `buildErrorBody()` / `sanitizeErrorMessage()` မှတစ်ဆင့် ဖြတ်သန်းစေထားပြီး response body များတွင် မူရင်း stack trace များ မပါဝင်ပါ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ကို ကြည့်ပါ) +- [ ] Shell command များ (`exec` / `spawn`) သည် runtime value များကို string interpolation မှတစ်ဆင့် မဟုတ်ဘဲ `env` မှတစ်ဆင့် ပေးပို့သည် +- [ ] Input အားလုံးကို Zod schema များဖြင့် စစ်ဆေးအတည်ပြုထားသည် +- [ ] အသုံးပြုသူအပေါ် သက်ရောက်သည့် ပြောင်းလဲမှုများအတွက် Changelog **fragment** ကို `changelog.d/{features|fixes|maintenance}/-.md` အောက်တွင် ထည့်သွင်းထားသည် ([`changelog.d/README.md`](./changelog.d/README.md) ကို ကြည့်ပါ) — `CHANGELOG.md` ကို တိုက်ရိုက် **မပြင်ဆင်ပါနှင့်**၊ fragment များကို release ပြုလုပ်ချိန်တွင် စုစည်းပြီး PR များအကြား conflict မဖြစ်စေပါ +- [ ] Documentation ကို လိုအပ်ပါက အပ်ဒိတ်လုပ်ထားသည် +- [ ] CodeQL / Secret-Scanning alert အသစ်များ မပေါ်လာပါ၊ သို့မဟုတ် alert တစ်ခုချင်းစီကို သက်ဆိုင်ရာ `docs/security/` doc အား ကိုးကားထားသည့် နည်းပညာဆိုင်ရာ အကြောင်းပြချက်ဖြင့် ပယ်ချထားသည် +- [ ] Child process များကို စတင်သည့် route များ (`/api/mcp/`, `/api/cli-tools/runtime/`) ကို `src/server/authz/routeGuard.ts` ရှိ `isLocalOnlyPath()` အဖြစ် သတ်မှတ်ထားသည် — [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md) ကို ကြည့်ပါ +- [ ] Commit message များတွင် AI/bot `Co-authored-by` trailer များ မပါဝင်ပါ (Hard Rule #16) — ပြန်လည်အသုံးပြုထားသော အလုပ်၏ လူသားပူးပေါင်းဆောင်ရွက်သူများကို စံသတ်မှတ်ထားသည့် `Co-authored-by: Name ` trailer များဖြင့် အသိအမှတ်ပြုထားသည် --- diff --git a/docs/i18n/my/docs/architecture/QUALITY_GATES.md b/docs/i18n/my/docs/architecture/QUALITY_GATES.md index ab0685f726c..e58eaf4744a 100644 --- a/docs/i18n/my/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/my/docs/architecture/QUALITY_GATES.md @@ -15,267 +15,263 @@ ratchet baseline သို့မဟုတ် pass/fail policy ကို အသ --- -## Gate စာရင်းနှင့် လုပ်ဆောင်မှုပရိုဖိုင်များ +## Gate စာရင်းနှင့် လုပ်ဆောင်မှု ပရိုဖိုင်များ ### Candidate လက်ခံခြင်း -CI နှင့် Quality Gates workflow တစ်ခုစီသည် တည်ငြိမ်သော ဆုံးဖြတ်ချက်တစ်ခုဖြစ်သည့် `Gate / CI` နှင့် -`Gate / Quality` ကို ထုတ်ပေးသည်။ ၎င်းတို့၏ version သတ်မှတ်ထားသော လက်ခံရေးမူဝါဒတွင် upstream job တိုင်းကို -မဖြစ်မနေလိုအပ်သော သို့မဟုတ် အကြံပြုသဘောသက်သက်ဖြစ်သော job အဖြစ် စာရင်းပြုစုထားသည်။ သက်ဆိုင်သော မဖြစ်မနေလိုအပ်သည့် job သည် အောင်မြင်ရမည်ဖြစ်ပြီး ပျောက်ဆုံးနေခြင်း၊ -ပယ်ဖျက်ထားခြင်း၊ ကျော်သွားခြင်း၊ စောင့်ဆိုင်းနေခြင်းနှင့် မသိရသေးသော ရလဒ်များဖြင့် PASS ကို သတ်မှတ်နိုင်ခြင်းမရှိပါ။ မှန်ကန်သော -docs-only သို့မဟုတ် catalog-only အမျိုးအစားခွဲခြားမှုသည် code lane တစ်ခုကို မသက်ဆိုင်စေနိုင်သည်။ -draft PR တစ်ခုကို လက်ခံထားသော candidate အဖြစ် မသတ်မှတ်ပါ။ `hotfix` label တစ်ခုက အထောက်အထားလိုအပ်ချက်ကို ပယ်ဖျက်မပေးပါ။ - -Workflow နှစ်ခုစလုံးသည် PR များ၊ main/release branch များသို့ push လုပ်ခြင်းများ၊ manual dispatch နှင့် -merge-group event များကို အကျုံးဝင်စေသည်။ Push၊ dispatch နှင့် merge-group တို့သည် ရွေးချယ်မှုအားလုံးကို အပြည့်အစုံ လုပ်ဆောင်သည်။ Fork များနှင့် -merge group များသည် ပုံမှန်အားဖြင့် self-hosted runner ကို ရွေးချယ်မည့် job များအတွက် hosted runner များကို အသုံးပြုသည်။ -ဖြန့်ချိအသုံးချခြင်းမပြုမီ hosted capacity လုံလောက်မှုရှိကြောင်း အတည်ပြုရမည်။ - -JSON receipt တစ်ခုစီသည် checkout လုပ်ထားသော SHA၊ workflow run နှင့် attempt ကို သတ်မှတ်ဖော်ပြသည်။ -CLI သည် checkout/event SHA မကိုက်ညီမှုကို လက်မခံပါ။ Workflow test များသည် policy membership ကို -verdict job ၏ `needs` စာရင်းနှင့် ချိတ်ဆက်ထားသောကြောင့် lane အသစ်တစ်ခု သို့မဟုတ် ဖယ်ရှားထားသော lane တစ်ခုသည် အသိပေးမှုမရှိဘဲ ပျောက်ကွယ်သွားနိုင်မည်မဟုတ်ပါ။ -Receipt များသည် မိမိတို့၏ workflow ကိုသာ အကျုံးဝင်ပြီး publication၊ deployment သို့မဟုတ် +CI နှင့် Quality Gates workflow တစ်ခုစီသည် တည်ငြိမ်သော ဆုံးဖြတ်ချက်တစ်ခုကို ထုတ်ပေးသည်- `Gate / CI` နှင့် +`Gate / Quality`။ ၎င်းတို့၏ version သတ်မှတ်ထားသော လက်ခံမှုမူဝါဒတွင် upstream job တစ်ခုစီကို +လိုအပ်သော သို့မဟုတ် အကြံပြုသဘောသာဖြစ်သော job အဖြစ် စာရင်းပြုထားသည်။ သက်ဆိုင်သည့် လိုအပ်သော job သည် အောင်မြင်ရမည်- ပျောက်ဆုံးနေခြင်း၊ +ပယ်ဖျက်ထားခြင်း၊ ကျော်သွားခြင်း၊ ဆိုင်းငံ့နေခြင်းနှင့် မသိရှိသော ရလဒ်များဖြင့် PASS ဖြစ်ကြောင်း အတည်မပြုနိုင်ပါ။ မှန်ကန်သော +docs-only သို့မဟုတ် catalog-only အမျိုးအစားခွဲခြားမှုကြောင့် code lane တစ်ခုကို သက်ဆိုင်မှုမရှိဟု သတ်မှတ်နိုင်သည်၊ +draft PR တစ်ခုကို လက်ခံထားသော candidate အဖြစ် မသတ်မှတ်ပါ။ `hotfix` label တစ်ခုကြောင့် အထောက်အထားလိုအပ်ချက်ကို ကင်းလွတ်ခွင့်မပြုပါ။ + +Workflow နှစ်ခုစလုံးသည် PR များ၊ main/release branch များသို့ push များ၊ manual dispatch နှင့် +merge-group event များကို အကျုံးဝင်သည်။ Push၊ dispatch နှင့် merge-group တို့သည် ရွေးချယ်မှုအပြည့်အစုံကို လုပ်ဆောင်သည်။ Fork များနှင့် +merge group များသည် ပုံမှန်အားဖြင့် self-hosted runner များကို ရွေးချယ်မည့် job များအတွက် hosted runner များကို အသုံးပြုသည်၊ +rollout မပြုလုပ်မီ လုံလောက်သော hosted capacity ရှိကြောင်း အတည်ပြုရမည်။ + +JSON receipt တစ်ခုစီသည် checkout ပြုလုပ်ထားသော SHA၊ workflow run နှင့် attempt ကို သတ်မှတ်ဖော်ပြသည်။ +CLI သည် checkout/event SHA မကိုက်ညီမှုကို ငြင်းပယ်သည်။ Workflow test များသည် policy membership ကို +verdict job ၏ `needs` စာရင်းနှင့် ချိတ်ဆက်ထားသဖြင့် အသစ်ထည့်ထားသော သို့မဟုတ် ဖယ်ရှားထားသော lane တစ်ခုသည် အသံတိတ် ပျောက်ကွယ်သွားနိုင်မည်မဟုတ်ပါ။ +Receipt များသည် ၎င်းတို့၏ကိုယ်ပိုင် workflow ကိုသာ အကျုံးဝင်ပြီး publication၊ deployment သို့မဟုတ် ရှိပြီးသား advisory scanner တစ်ခု၏ အတွင်းပိုင်းလုပ်ဆောင်ချက်များကို မအကျုံးဝင်ပါ။ Branch rule များတွင် check name နှစ်ခုစလုံးကို အသက်သွင်းခြင်းသည် -သီးခြား စီမံခန့်ခွဲရေးပြောင်းလဲမှုတစ်ခုဖြစ်ပြီး ဤ job များကို ထည့်သွင်းခြင်းတစ်ခုတည်းဖြင့် branch ကို ကာကွယ်ပေးမည်မဟုတ်ပါ။ +သီးခြား စီမံခန့်ခွဲရေးဆိုင်ရာ ပြောင်းလဲမှုတစ်ခုဖြစ်သည်၊ ဤ job များကို ထည့်သွင်းရုံဖြင့် branch တစ်ခုကို အလိုအလျောက် ကာကွယ်ပေးမည်မဟုတ်ပါ။ ### Static scan စာရင်း -Version သတ်မှတ်ထားသော npm-alias စာရင်းနှင့် static-scan membership တို့ကို -`config/quality/gate-manifest.json` တွင် ထားရှိသည်။ `package.json` နှင့် နှိုင်းယှဉ်၍ -script name များနှင့် command အတိအကျကို အတည်ပြုရန် `npm run check:gate-manifest` ကို လုပ်ဆောင်ပါ။ ထည့်သွင်းခြင်း၊ ဖယ်ရှားခြင်းနှင့် -command ပြောင်းလဲသွားခြင်းတို့ကြောင့် local hook နှင့် CI အတွင်းရှိ change-classification job နှစ်ခုစလုံး ကျရှုံးမည်။ -Alias တစ်ခုသည် workflow job၊ matrix instance သို့မဟုတ် test case မဟုတ်သောကြောင့် ဤအရေအတွက်များကို -တစ်ခုနှင့်တစ်ခု အပြန်အလှန်တူညီသည့်အရာများအဖြစ် မဖော်ပြရပါ။ - -ရွေးချယ်ထားသော alias များကို လုပ်ဆောင်ခြင်းမရှိဘဲ စစ်ဆေးကြည့်ရှုရန် `npm run quality:scan -- --list` သို့မဟုတ် -`npm run quality:scan:fast -- --list` ကို အသုံးပြုပါ။ Runner သည် -npm entrypoint ကို ခေါ်ယူအသုံးပြုသောကြောင့် configure လုပ်ထားသည့်နေရာများတွင် Bun အပါအဝင် ၎င်း၏ runtime ကို ဆက်လက်ထိန်းသိမ်းထားသည်။ -Manifest သည် ထို profile များ၏ ပြင်ပရှိ alias များကို သီးခြားခေါ်ယူလုပ်ဆောင်သည့်အရာများအဖြစ် မှတ်တမ်းတင်ထားပြီး +Version သတ်မှတ်ထားသော npm-alias စာရင်းနှင့် static-scan membership ကို +`config/quality/gate-manifest.json` တွင် ထားရှိသည်။ Script name များနှင့် command အတိအကျကို `package.json` နှင့် တိုက်ဆိုင်စစ်ဆေးရန် +`npm run check:gate-manifest` ကို လုပ်ဆောင်ပါ။ ထည့်သွင်းမှုများ၊ ဖယ်ရှားမှုများနှင့် +command ပြောင်းလဲကွဲလွဲမှုများသည် local hook နှင့် CI အတွင်းရှိ change-classification job များ နှစ်ခုစလုံးကို မအောင်မြင်စေပါ။ +Alias တစ်ခုသည် workflow job၊ matrix instance သို့မဟုတ် test case မဟုတ်ပါ- ဤအရေအတွက်များကို +တူညီဖလှယ်အသုံးပြုနိုင်သကဲ့သို့ မဖော်ပြရပါ။ + +ရွေးချယ်ထားသော alias များကို လုပ်ဆောင်ခြင်းမရှိဘဲ စစ်ဆေးကြည့်ရှုရန် `npm run quality:scan -- --list` သို့မဟုတ် `npm run quality:scan:fast -- --list` +ကို အသုံးပြုပါ။ Runner သည် +npm entrypoint ကို ခေါ်ယူသောကြောင့် configure လုပ်ထားသည့်နေရာတွင် Bun အပါအဝင် ၎င်း၏ runtime ကို ဆက်လက်ထိန်းသိမ်းထားသည်။ +Manifest သည် ဤ profile များ၏ ပြင်ပရှိ alias များကို သီးခြားခေါ်ယူလုပ်ဆောင်သည့်အရာများအဖြစ် မှတ်တမ်းတင်ထားပြီး read-only scan profile များတွင် maintenance command များကို တားမြစ်ထားသည်။ ဤ profile များသည် static scan ကိုသာ အကျုံးဝင်သည်။ ၎င်းတို့သည် product test များ၊ coverage၊ packaging၊ external check များ သို့မဟုတ် candidate တစ်ခု၏ release လက်ခံမှုအပြည့်အစုံကို အသိအမှတ်မပြုပါ။ Workflow လက်ခံမှုသည် ချိတ်ဆက်ထားသော `config/quality/admission-policy.json` နှင့် -`scripts/quality/admission-verdict.mjs` ကို အသုံးပြုသည်။ Release-observer profile များကို သီးခြားထားရှိဆဲဖြစ်ပြီး -၎င်းတို့နှင့် သက်ဆိုင်သော check များနှင့် receipt များကို သီးခြားစစ်ဆေးပါ။ အောက်ပါ စာသားဖြင့်ဖော်ပြထားသော -စာရင်းသည် ကိုးကားရန်သာဖြစ်ပြီး gate တစ်ခု အမှန်တကယ် လုပ်ဆောင်ခဲ့ကြောင်း သက်သေမပြနိုင်ပါ။ +`scripts/quality/admission-verdict.mjs` ကို အသုံးပြုသည်။ Release-observer profile များသည် သီးခြားဆက်ရှိနေသည်၊ +၎င်းတို့၏ သက်ဆိုင်သော check များနှင့် receipt များကို သီးခြားစစ်ဆေးပါ။ အောက်ပါ စာသားဖြင့်ဖော်ပြထားသော +စာရင်းသည် ကိုးကားရန်သာဖြစ်ပြီး gate တစ်ခု အမှန်တကယ် လုပ်ဆောင်ခဲ့ကြောင်း အထောက်အထားမဟုတ်ပါ။ Script များကို `scripts/check/` (policy gate များ) နှင့် `scripts/quality/` (ratchet engine) အောက်တွင် ထားရှိသည်။ -CI အတွက် တစ်ခုတည်းသော အမှန်တရားရင်းမြစ်မှာ `.github/workflows/ci.yml` ဖြစ်သည်။ +CI အတွက် တစ်ခုတည်းသော အမှန်တရားအရင်းအမြစ်မှာ `.github/workflows/ci.yml` ဖြစ်သည်။ ### Release PR fast-path (`quality.yml`) `.github/workflows/quality.yml` သည် main/release PR များ၊ protected-branch push များ၊ dispatch နှင့် merge group များတွင် CI ကို ဖြည့်စွက်ပေးသည်။ PR များသည် path-filtered fast check များကို အသုံးပြုသည်။ အမြဲတမ်း -ပိတ်ထားသည့် ထပ်နေသော build ကို ဖယ်ရှားပြီးဖြစ်သော်လည်း အမှန်တကယ် build/package/boot check များကို CI တွင် ဆက်လက်ထားရှိသည်။ - -| Job | အကျုံးဝင်မှု | ပိတ်ဆို့မှု | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `Docs Gates (fast-path)` | Docs/code PR များ၊ API docs ref များနှင့် docs-all | ဟုတ်သည် | -| `Fast Quality Gates` | Code PR များ၊ static check များ၊ typecheck၊ dashboard typecheck၊ သက်ရောက်မှုရှိသော unit test များ | ဟုတ်သည် | -| `Forgotten sibling tests` | Code PR များ၊ ပြောင်းလဲထားသော module များမှ static consumer များနှင့် ဖြစ်နိုင်ခြေရှိသော sibling test များအထိ ခြေရာခံခြင်း၊ barrel နှင့် dynamic-import path များကို ကိုးကားထားသော allowlist ခြွင်းချက်များနှင့်အတူ အကြံပြုသဘော diagnostic များအဖြစ် အစီရင်ခံသည် | **အကြံပြုသဘော** | -| `Vitest (fast-path)` | Code PR များ၊ လျင်မြန်သော vitest suite | ဟုတ်သည် | -| `Unit Tests fast-path` | Code PR များ၊ 4-shard unit suite | ဟုတ်သည် | -| `No new ESLint warnings` | Code PR များ၊ suppression များကို ထည့်သွင်းစဉ်းစားသော lint guard | ဟုတ်သည်၊ fork များအပါအဝင် | -| `Merge integrity (changelog + generated skills)` | Draft မဟုတ်သော PR များ၊ changelog နှင့် generated skill sync | ဟုတ်သည်၊ fork များအပါအဝင် | - -#### မေ့ကျန်ခဲ့သော sibling test အစီရင်ခံစာ - -`npm run check:forgotten-sibling-tests` သည် test-impact map ၏ နောက်ကွယ်ရှိ import resolver ကို ပြန်လည်အသုံးပြုသည်။ -ပြောင်းလဲထားသော production module တစ်ခုစီအတွက် ဖြစ်နိုင်ခြေရှိသော -test သည် pull-request diff တွင် မပါရှိသည့်အခါ တိကျစွာ ထပ်တူပြန်လည်ရရှိနိုင်သော `changed module/symbol -> static consumer -> candidate sibling test` chain များကို အစီရင်ခံသည်။ -Markdown အနှစ်ချုပ်နှင့် JSON ရလဒ်ကို blocking rollout တစ်စုံတစ်ရာမပြုမီ calibration ပြုလုပ်ရန် +ပိတ်ထားခဲ့သော ထပ်နေသည့် build ကို ဖယ်ရှားခဲ့ပြီး၊ အမှန်တကယ် build/package/boot check များသည် CI တွင် ဆက်ရှိနေသည်။ + +| Job | အကျုံးဝင်မှု | ပိတ်ဆို့မှု | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `Docs Gates (fast-path)` | Docs/code PR များ၊ API docs ref များနှင့် docs-all | ဟုတ်သည် | +| `Fast Quality Gates` | Code PR များ၊ static check များ၊ typecheck၊ dashboard typecheck၊ သက်ရောက်မှုရှိသော unit test များ | ဟုတ်သည် | +| `Forgotten sibling tests` | Code PR များ၊ ပြောင်းလဲထားသော module များကို static consumer များနှင့် candidate sibling test များအထိ ခြေရာခံခြင်း၊ barrel နှင့် dynamic-import path များကို ကိုးကားထားသော allowlist ခြွင်းချက်များနှင့်အတူ အကြံပြုသဘောဆိုင်ရာ diagnostic များအဖြစ် အစီရင်ခံသည် | **အကြံပြုသဘောသာ** | +| `Vitest (fast-path)` | Code PR များ၊ မြန်ဆန်သော vitest suite | ဟုတ်သည် | +| `Unit Tests fast-path` | Code PR များ၊ shard 4 ခုပါ unit suite | ဟုတ်သည် | +| `No new ESLint warnings` | Code PR များ၊ suppression များကို ထည့်သွင်းစဉ်းစားသော lint guard | ဟုတ်သည်၊ fork များအပါအဝင် | +| `Merge integrity (changelog + generated skills)` | Draft မဟုတ်သော PR များ၊ changelog နှင့် generated skill sync | ဟုတ်သည်၊ fork များအပါအဝင် | + +#### Forgotten sibling tests အစီရင်ခံစာ + +`npm run check:forgotten-sibling-tests` သည် test-impact map နောက်ကွယ်ရှိ import resolver ကို ပြန်လည်အသုံးပြုသည်။ +ပြောင်းလဲထားသော production module တစ်ခုစီအတွက် candidate +test သည် pull-request diff တွင် မပါရှိပါက သတ်မှတ်ချက်တူညီစွာ ထပ်မံရရှိနိုင်သော +`changed module/symbol -> static consumer -> candidate sibling test` chain များကို အစီရင်ခံသည်။ ပိတ်ဆို့သည့် rollout တစ်ခုခု မပြုလုပ်မီ ချိန်ညှိနိုင်ရန် Markdown summary နှင့် JSON result ကို `forgotten-sibling-tests` workflow artifact အဖြစ် ထိန်းသိမ်းထားသည်။ -Barrel ပြန်လည်တင်ပို့မှုများနှင့် dynamic import များသည် resolution စစ်ဆေးရေးအချက်အလက်များသာဖြစ်ပြီး၊ -ပိတ်ဆို့သော finding တစ်ခုကို မည်သည့်အခါမျှ မဖန်တီးပါ။ ပြန်လည်သုံးသပ်အတည်ပြုထားသော ခြွင်းချက်များကို +Barrel ပြန်လည် export လုပ်ခြင်းများနှင့် dynamic import များသည် resolution ဆိုင်ရာ ရောဂါရှာဖွေမှုများသာ ဖြစ်ပြီး၊ ပိတ်ဆို့သည့် finding တစ်ခုကို မည်သည့်အခါမျှ မဖန်တီးပါ။ +ပြန်လည်သုံးသပ်အတည်ပြုထားသော ခြွင်းချက်များကို `config/quality/forgotten-sibling-allowlist.json` တွင် ထားရှိသည်။ Entry တစ်ခုစီတွင် consumer နှင့် candidate -test ကို အမည်တပ်ဖော်ပြရမည်၊ တိကျသော အကြောင်းပြချက်ကို ပေးရမည်၊ ထို့ပြင် GitHub issue သို့မဟုတ် pull request တစ်ခုကို link ချိတ်ရမည်။ ပုံစံမမှန်သော entry များသည် -လုံခြုံရေးဦးစားပေးအဖြစ် ပိတ်ဆို့မည်။ ခြွင်းချက်များသည် ဖျက်ထားသော candidate test သို့မဟုတ် `.skip`/`.todo` ထည့်သွင်းထားသော diff ကို ဖုံးကွယ်မပေးနိုင်ပါ။ -assertion အားပျော့စေခြင်းနှင့် အခြားဖုံးကွယ်မှုများကို သီးခြားပိတ်ဆို့သည့် -`check:test-masking` gate က ဆက်လက်တာဝန်ယူသည်။ - -### Job: `lint` - -`main` သို့ PR တင်တိုင်း run သည်။ မအောင်မြင်ပါက merge လုပ်ခြင်းကို ပိတ်ဆို့သည်။ - -| Script (`npm run ...`) | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှုရှိ/မရှိ | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `check:node-runtime` | Node.js version သည် ပံ့ပိုးထားသော range အတွင်း ရှိသည် | ရှိ | -| `check:cycles` | Circular import များ — `src/` + `open-sse/` module အားလုံး | ရှိ | -| `check:route-validation:t06` | route အားလုံးတွင် Zod schema များ ရှိသည် (အဆင့် 6 မူဝါဒ) | ရှိ | -| `check:any-budget:t11` | `@ts-expect-error // any` အရေအတွက်သည် သတ်မှတ်ထားသော budget ကို မကျော်လွန်ပါ (အဆင့် 11 catraca) | ရှိ | -| `check:provider-consistency` | `providers.ts` ရှိ provider တိုင်းတွင် `providerRegistry.ts` အတွင်း ကိုက်ညီသော entry တစ်ခုရှိပြီး အပြန်အလှန်အားဖြင့်လည်း အလားတူဖြစ်သည် (allowlist အတွင်း) | ဟုတ်သည် | -| `check:model-lifecycle` | ကိုယ်တိုင်ထိန်းသိမ်းထားသော routing table သုံးခုသည် repository တွင် ထည့်သွင်းထားသည့် lifecycle snapshot (#11503) နှင့် ကိုက်ညီမှုရှိနေသည်- `FITNESS_TABLE` (`taskFitness.ts`) သည် `REGISTRY` က route လုပ်နိုင်သော retired id မည်သည့်အရာကိုမျှ score မပေးပါ။ `BUILT_IN_ALIASES` target တိုင်းသည် `REGISTRY` တွင် ရှိပြီး retired-id snapshot တွင် မရှိပါ။ `REGISTRY` ထဲတွင် ဆက်လက်ရှိနေသည့် retired id တိုင်းကို forward လုပ်ထားခြင်း သို့မဟုတ် `allowedRetiredInCatalog` တွင် စာရင်းသွင်းထားခြင်း ရှိသည်။ ထို့ပြင် `DEFAULT_DEGRADATION_MAP` ၏ source သို့မဟုတ် target တစ်ခုမျှ ထို snapshot တွင် retired အဖြစ် မပေါ်ပါ။ ဤစစ်ဆေးမှုက model တစ်ခုကို လက်ရှိတွင် အသုံးပြုနိုင်သော upstream မှ အမှန်တကယ် ဝန်ဆောင်မှုပေးနေကြောင်း သက်သေမပြပါ။ Offline — `config/quality/model-lifecycle.json` နှင့် နှိုင်းယှဉ်ပြီး ၎င်းကို `npm run quality:refresh-model-lifecycle` ဖြင့် ကိုယ်တိုင် refresh လုပ်သည် (network လိုအပ်ပြီး CI တွင် ချိတ်ဆက်မထားပါ)။ `allowedRetiredInCatalog` သည် တဖြည်းဖြည်းလျှော့ချရန် ရည်ရွယ်သော ratchet တစ်ခုဖြစ်သည်- tracking issue ရှိမှသာ entry တစ်ခု ထည့်ပါ။ | ဟုတ်သည် | -| `check:fetch-targets` | client-side `src/` ရှိ `fetch("/api/...")` တိုင်းသည် အမှန်တကယ်ရှိသော `route.ts` သို့ resolve လုပ်သည် | ဟုတ်သည် | -| `check:deps` | repo အတွင်းရှိ `package.json` တိုင်းမှ `npm install` လုပ်နိုင်သော dependency အားလုံးသည် `dependency-allowlist.json` တွင် ရှိသည်။ pin မလုပ်ထားသော သို့မဟုတ် slopsquatted package အသစ်များကို flag လုပ်သည် | ဟုတ်သည် | -| `audit:deps` | `npm audit` (root + electron) — high/critical advisory မရှိပါ (osv `check:vuln-ratchet` နှင့် ထပ်နေသည်။ Rationalization Backlog ကို ကြည့်ပါ) | ဟုတ်သည် | -| `check:lockfile` | `package-lock.json` ၏ integrity — https registry၊ integrity hash များနှင့် host override မရှိခြင်း | ဟုတ်သည် | -| `check:licenses` | production dependencies များအတွက် SPDX license allowlist | ဟုတ်သည် | -| `check:tracked-artifacts` | build artifacts / commit လုပ်ထားသော `node_modules` symlinks မရှိရပါ (husky pre-commit တွင်လည်း run သည်; pre-push ကို ရည်ရွယ်ချက်ရှိရှိ ပေါ့ပါးအောင်ထားသည် — #6716) | ဟုတ်သည် | -| `check:ai-attribution` | PR commits၊ title သို့မဟုတ် body တွင် AI/bot `Co-Authored-By` trailer သို့မဟုတ် AI-generation footer မရှိရပါ — Hard Rule #16 (`quality.yml` ရှိ PR→`release/**` အတွက် fast-gates loop ထဲတွင် ပါဝင်သည် — event payload ကို ဖတ်ပြီး PR မဟုတ်ပါက မည်သည့်လုပ်ဆောင်ချက်မျှ မလုပ်ပါ — ထို့ပြင် `ci.yml` lint ရှိ PR→`main` အတွက် PR သီးသန့် step တစ်ခုလည်း ဖြစ်သည်; husky `commit-msg` hook လည်း ပါဝင်သည်; လူသား co-authors များကို ခွင့်ပြုသည်; #14436) | -| `check:vitest-exclusions` | Vitest exclusion တစ်ခုစီတွင် tracking issue တစ်ခုကို အမည်ဖော်ပြထားပြီး `config/quality/vitest-exclusions.json` တွင် ပါဝင်ရမည် (#13204) | ဟုတ်သည် | -| `check:file-size` | source file တစ်ခုမျှ extension အလိုက် သတ်မှတ်ထားသော အများဆုံးအရွယ်အစားကို မကျော်လွန်ရပါ (ratchet: အရွယ်ကြီး file များကို `frozen` စာရင်းတွင် ထိန်းချုပ်ထားသည်) | ဟုတ်သည် | -| `check:error-helper` | executors/handlers များရှိ error responses များသည် `buildErrorBody()` / `sanitizeErrorMessage()` ကို အသုံးပြုရမည် (Hard Rule #12) | ဟုတ်သည် | -| `check:migration-numbering` | Migration SQL ဖိုင်များကို ကွက်လပ် သို့မဟုတ် ထပ်နေမှုမရှိဘဲ အစဉ်လိုက် နံပါတ်တပ်ထားသည် | ဟုတ်သည် | -| `check:public-creds` | `publicCreds.ts` ပြင်ပတွင် OAuth `client_id`/`client_secret` သို့မဟုတ် Firebase Web key များကို တိုက်ရိုက်ထည့်သွင်းထားခြင်း မရှိပါ (တင်းကျပ်သော စည်းမျဉ်း #11) | ဟုတ်သည် | -| `check:db-rules` | `src/lib/db/` module များ၏ ပြင်ပတွင် raw SQL မရှိပါ၊ `localDb.ts` မှ barrel import များ မရှိပါ (တင်းကျပ်သော စည်းမျဉ်းများ #2/#5) | ဟုတ်သည် | -| `check:known-symbols` | ၎င်းတို့၏ dispatch table များတွင် မှတ်ပုံတင်ထားသော provider executor များ၊ routing strategy များနှင့် translator များသည် disk ပေါ်ရှိ ဖိုင်များနှင့် ကိုက်ညီသည် — သီးခြားကျန်နေသော သို့မဟုတ် ကြေညာမထားသော symbol များ မရှိပါ | ဟုတ်သည် | -| `check:route-guard-membership` | child process တစ်ခု စတင်သည့် route တိုင်းကို `isLocalOnlyPath()` ဖြင့် အမျိုးအစားခွဲထားသည် (တင်းကျပ်သော စည်းမျဉ်းများ #15/#17) | ဟုတ်သည် | -| `check:test-discovery` | repo ရှိ `*.test.ts` / `*.spec.ts` ဖိုင်တိုင်းကို အနည်းဆုံး test runner တစ်ခုက စုဆောင်းသည် (ratchet: `test-discovery-baseline.json` ရှိ orphan စာရင်းသည် လျော့နည်းသွားနိုင်ရုံသာရှိသည်) | ဟုတ်သည် | -| `check:agent-skills-sync` | ထုတ်လုပ်ထားသော agent-skills artifact များသည် ၎င်းတို့၏ မူရင်း catalog နှင့် ကိုက်ညီမှုရှိမရှိ စစ်ဆေးသည် (ကွဲလွဲမှုမရှိရ) | -| `check:provider-asset-provenance` | Provider logo/asset များတွင် မှတ်တမ်းတင်ထားသော provenance entry ရှိမရှိ စစ်ဆေးသည် | -| `lint:json` | JSON config file များကို parse လုပ်နိုင်ပြီး repo ၏ lint စည်းမျဉ်းများနှင့် ကိုက်ညီမှုရှိမရှိ စစ်ဆေးသည် | -| `typecheck:core` | Error မရှိဘဲ TypeScript compilation ပြုလုပ်သည် (အကြံပြုချက်ဆိုင်ရာ warning များသာ) | ရှိသည် | -| `typecheck:noimplicit:core` | တင်းကျပ်သော `noImplicitAny` — ရှေ့အနာဂတ်အတွက် ရည်ရွယ်ထားပြီး၊ ယခင်ကတည်းကရှိသော call site အများအပြားတွင် annotation များ ထည့်ရန် လိုအပ်နေသေးသည် | **အကြံပြုချက်သာ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` အတွက်သာ သတ်မှတ်ထားသော `tsc` (#7033) — `typecheck:core` ၏ စိစစ်ရွေးချယ်ထားသည့် file ၂၇ ခုပါ allowlist တွင် dashboard TSX တစ်ခုမျှ မပါဝင်သည့်အပြင် `next build` ကလည်း ၎င်းကို type-check လုံးဝ မလုပ်ပါ (`next.config.mjs` တွင် `ignoreBuildErrors: true` သတ်မှတ်ထားသည်)။ ထို့ကြောင့် ထိုနေရာရှိ orphaned-identifier regression များ (#6625/#6909) ကို CI က မမြင်နိုင်ခဲ့ပါ။ File တစ်ခုချင်းစီနှင့် TS-code တစ်ခုချင်းစီအလိုက် count များကို ပြင်ဆင်၍မရအောင် သတ်မှတ်ထားသည့် baseline (`config/quality/dashboard-typecheck-baseline.json`၊ `check:known-symbols` နှင့် တူညီသော stale-enforcement ပုံစံ) နှင့် diff လုပ်သည် — baseline သတ်မှတ်ထားသည့် count ထက်ကျော်လွန်သော error အသစ်များသာ gate ကို ကျရှုံးစေသည်။ ယခင်ကတည်းကရှိသော error တစ်ခုကို ပြင်ဆင်ပြီးသည့်အခါ `--update` ဖြင့် baseline ကို တဖြည်းဖြည်း လျှော့ချပါ။ | ရှိသည် | +test ကို အမည်ဖော်ပြရမည်၊ တိကျသော အကြောင်းပြချက်တစ်ခု ပေးရမည်ဖြစ်ပြီး GitHub issue သို့မဟုတ် pull request တစ်ခုကို link ချိတ်ရမည်။ ပုံစံမမှန်သော entry များသည် +အလိုအလျောက် ပိတ်ဆို့မည်။ +ခြွင်းချက်များသည် ဖျက်ထားသော candidate test သို့မဟုတ် `.skip`/`.todo` ကို ထည့်သွင်းထားသော diff တစ်ခုကို မဖုံးကွယ်နိုင်ပါ။ +assertion အားလျော့စေခြင်းနှင့် အခြား masking လုပ်ခြင်းများသည် သီးခြားပိတ်ဆို့သည့် +`check:test-masking` gate ၏ တာဝန်အဖြစ် ဆက်လက်တည်ရှိသည်။ + +### အလုပ်: `lint` + +`main` သို့ PR တင်သည့်အခါတိုင်း လုပ်ဆောင်သည်။ မအောင်မြင်ပါက merge လုပ်ခြင်းကို ပိတ်ဆို့သည်။ + +| Script (`npm run ...`) | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့ခြင်း | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:node-runtime` | Node.js version သည် ပံ့ပိုးထားသော အတိုင်းအတာအတွင်း ရှိခြင်း | ဟုတ်သည် | +| `check:cycles` | `src/` + `open-sse/` အားလုံးတစ်လျှောက်ရှိ circular import များ (AST အခြေပြု၍ tsconfig `paths` ကို ဖြေရှင်းထားသည်)။ ရိုးရိုးလုပ်ဆောင်မှု = အကြံပေးချက်သာဖြစ်ပြီး cycle များကို စာရင်းပြုစုသည်။ `check:cycles:ratchet` (CI က လုပ်ဆောင်သည့်အရာ) သည် အရေအတွက်က `quality-baseline.json` ရှိ `metrics.cycles` အများဆုံးသတ်မှတ်ချက်ကို ကျော်လွန်သည့်အခါ ပိတ်ဆို့သည် — လက်ရှိ 14၊ `direction: down` ဖြစ်သောကြောင့် လျော့ကျရုံသာ ရနိုင်သည် (#15159 G-01/G-02) | ဟုတ်သည် (ratchet) | +| `check:route-validation:t06` | route အားလုံးတွင် Zod schema များ ပါရှိခြင်း (Tier 6 မူဝါဒ) | ဟုတ်သည် | +| `check:any-budget:t11` | `@ts-expect-error // any` အရေအတွက်သည် သတ်မှတ်ထားသော budget ကို မကျော်လွန်ခြင်း (Tier 11 catraca) | ဟုတ်သည် | +| `check:provider-consistency` | `providers.ts` ရှိ provider တိုင်းတွင် `providerRegistry.ts` ၌ ကိုက်ညီသော entry တစ်ခုရှိသည် (အပြန်အလှန်အားဖြင့်လည်း allowlist အတွင်း ကိုက်ညီမှုရှိသည်) | ဟုတ်သည် | +| `check:model-lifecycle` | ကိုယ်တိုင်ထိန်းသိမ်းထားသော routing table သုံးခုသည် repository တွင် ထည့်သွင်းထားသော lifecycle snapshot (#11503) နှင့် တစ်သမတ်တည်းရှိနေသည်- `FITNESS_TABLE` (`taskFitness.ts`) သည် `REGISTRY` က route လုပ်နိုင်သည့် အနားပေးပြီးသော id တစ်ခုကိုမျှ score မပေးပါ။ `BUILT_IN_ALIASES` target တိုင်းသည် `REGISTRY` တွင် ရှိပြီး အနားပေးထားသော id snapshot တွင် မရှိပါ။ `REGISTRY` တွင် ကျန်ရှိနေသေးသော အနားပေးထားသည့် id တိုင်းကို forward လုပ်ထားခြင်း သို့မဟုတ် `allowedRetiredInCatalog` တွင် စာရင်းသွင်းထားခြင်း ရှိသည်။ ထို့အပြင် `DEFAULT_DEGRADATION_MAP` ၏ source သို့မဟုတ် target တစ်ခုမျှ အဆိုပါ snapshot တွင် အနားပေးထားသည်ဟု မပေါ်ပါ။ ဤစစ်ဆေးမှုသည် model တစ်ခုကို လက်ရှိအသုံးပြုနေသော live upstream က အမှန်တကယ် ဝန်ဆောင်မှုပေးနေကြောင်း သက်သေမပြပါ။ Offline ဖြစ်ပြီး `config/quality/model-lifecycle.json` နှင့် နှိုင်းယှဉ်သည်။ ၎င်းကို `npm run quality:refresh-model-lifecycle` ဖြင့် ကိုယ်တိုင် refresh လုပ်သည် (network လိုအပ်ပြီး CI နှင့် ချိတ်ဆက်မထားပါ)။ `allowedRetiredInCatalog` သည် တဖြည်းဖြည်းလျှော့ချရန် ရည်ရွယ်သည့် ratchet ဖြစ်သည်- tracking issue တစ်ခုရှိမှသာ entry တစ်ခုကို ထည့်ပါ။ | ဟုတ်သည် | +| `check:fetch-targets` | client-side `src/` ရှိ `fetch("/api/...")` တိုင်းသည် အမှန်တကယ်ရှိသော `route.ts` တစ်ခုသို့ resolve ဖြစ်သည် | ဟုတ်သည် | +| `check:deps` | repo ရှိ `package.json` တိုင်းမှ `npm install` ဖြင့် ထည့်သွင်းနိုင်သော dependency အားလုံးသည် `dependency-allowlist.json` တွင် ရှိသည်။ pin မလုပ်ထားသော သို့မဟုတ် slopsquatting ဖြစ်နိုင်သော package အသစ်များကို အမှတ်အသားပြုသည် | ဟုတ်သည် | +| `audit:deps` | `npm audit` (root + electron) — high/critical advisory မရှိပါ (osv `check:vuln-ratchet` နှင့် ထပ်နေသည်၊ Rationalization Backlog ကို ကြည့်ပါ) | ဟုတ်သည် | +| `check:lockfile` | `package-lock.json` ၏ integrity — https registry၊ integrity hash များ၊ host override မရှိခြင်း | ဟုတ်သည် | +| `check:licenses` | production dependencies များအတွက် SPDX license allowlist | ဟုတ်သည် | +| `check:tracked-artifacts` | build artifacts / commit လုပ်ထားသော `node_modules` symlinks မရှိရပါ (husky pre-commit တွင်လည်း လုပ်ဆောင်သည်။ pre-push ကို ရည်ရွယ်ချက်ရှိရှိ ပေါ့ပါးအောင်ထားသည် — #6716) | ဟုတ်သည် | +| `check:ai-attribution` | PR commits၊ title သို့မဟုတ် body တွင် AI/bot `Co-Authored-By` trailer သို့မဟုတ် AI-generation footer မရှိရပါ — Hard Rule #16 (`quality.yml` ရှိ PR→`release/**` အတွက် fast-gates loop တွင် ပါဝင်သည် — event payload ကို ဖတ်ပြီး PR မဟုတ်ပါက မည်သည့်လုပ်ဆောင်ချက်မျှ မလုပ်ပါ — ထို့အပြင် PR→`main` အတွက် `ci.yml` lint ရှိ PR-only step တွင်လည်း ပါဝင်သည်။ husky `commit-msg` hook လည်း ပါဝင်သည်။ လူသား co-authors များကို ခွင့်ပြုသည်။ #14436) | +| `check:vitest-exclusions` | Vitest exclusion တိုင်းတွင် tracking issue တစ်ခုကို အမည်ဖော်ပြထားပြီး `config/quality/vitest-exclusions.json` တွင် ပါဝင်ရမည် (#13204) | ဟုတ်သည် | +| `check:file-size` | source file တစ်ခုမျှ extension အလိုက် သတ်မှတ်ထားသော အများဆုံးအရွယ်အစားကို မကျော်လွန်ရပါ (ratchet: ကြီးမားသော frozen files များကို `frozen` list တွင် ထည့်ထားသည်) | ဟုတ်သည် | +| `check:error-helper` | executors/handlers ရှိ error responses များတွင် `buildErrorBody()` / `sanitizeErrorMessage()` ကို အသုံးပြုရမည် (Hard Rule #12) | ဟုတ်သည် | +| `check:migration-numbering` | Migration SQL ဖိုင်များကို ကွက်လပ်များ သို့မဟုတ် ထပ်နေမှုများမရှိဘဲ အစဉ်လိုက် နံပါတ်တပ်ထားသည် | ဟုတ်သည် | +| `check:public-creds` | `publicCreds.ts` ပြင်ပတွင် OAuth `client_id`/`client_secret` သို့မဟုတ် Firebase Web key များကို တိုက်ရိုက်ရေးသားထားခြင်းမရှိပါ (တင်းကျပ်သော စည်းမျဉ်း #11) | ဟုတ်သည် | +| `check:db-rules` | `src/lib/db/` module များပြင်ပတွင် raw SQL မရှိပါ။ `localDb.ts` မှ barrel-import များလည်း မရှိပါ (တင်းကျပ်သော စည်းမျဉ်းများ #2/#5) | ဟုတ်သည် | +| `check:known-symbols` | ၎င်းတို့၏ dispatch table များတွင် မှတ်ပုံတင်ထားသော provider executor များ၊ routing strategy များနှင့် translator များသည် disk ပေါ်ရှိ ဖိုင်များနှင့် ကိုက်ညီသည် — ချိတ်ဆက်မထားသော သို့မဟုတ် ကြေညာမထားသော symbol များ မရှိပါ | ဟုတ်သည် | +| `check:route-guard-membership` | child process တစ်ခုကို စတင်သည့် route တိုင်းကို `isLocalOnlyPath()` ဖြင့် အမျိုးအစားခွဲခြားထားသည် (တင်းကျပ်သော စည်းမျဉ်းများ #15/#17) | ဟုတ်သည် | +| `check:test-discovery` | repo အတွင်းရှိ `*.test.ts` / `*.spec.ts` ဖိုင်တိုင်းကို အနည်းဆုံး test runner တစ်ခုက စုဆောင်းသည် (ratchet: `test-discovery-baseline.json` ရှိ orphan စာရင်းသည် လျော့နည်းရုံသာ ဖြစ်နိုင်သည်) | ဟုတ်သည် | +| `check:agent-skills-sync` | ထုတ်လုပ်ထားသော agent-skills artifact များသည် ၎င်းတို့၏ မူရင်း catalog နှင့် ကိုက်ညီကြောင်း စစ်ဆေးသည် (ကွာဟချက်မရှိစေရ) | +| `check:provider-asset-provenance` | Provider logo/asset များတွင် မှတ်တမ်းတင်ထားသော မူရင်းဇာစ်မြစ် entry တစ်ခု ပါရှိကြောင်း စစ်ဆေးသည် | +| `lint:json` | JSON config ဖိုင်များကို parse လုပ်နိုင်ပြီး repo ၏ lint စည်းမျဉ်းများနှင့် ကိုက်ညီကြောင်း စစ်ဆေးသည် | +| `typecheck:core` | Error မရှိဘဲ TypeScript ကို compile လုပ်သည် (အကြံပြုချက်ဆိုင်ရာ warning များသာ) | ဟုတ်သည် | +| `typecheck:noimplicit:core` | တင်းကျပ်သော `noImplicitAny` — အနာဂတ်အတွက် ရည်ရွယ်ထားပြီး ယခင်ကတည်းက ရှိနေသော call site များစွာတွင် annotation များ ထည့်သွင်းရန် လိုအပ်နေသေးသည် | **အကြံပြုချက်သာ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` အတွက်သာ အကျုံးဝင်သော `tsc` (#7033) — `typecheck:core` ၏ ရွေးချယ်ထားသည့် 27-file allowlist တွင် dashboard TSX တစ်ခုမျှ မပါဝင်သကဲ့သို့ `next build` ကလည်း ၎င်းကို မည်သည့်အခါမျှ type-check မလုပ်ပါ (`next.config.mjs` တွင် `ignoreBuildErrors: true` ဟု သတ်မှတ်ထားသည်)။ ထို့ကြောင့် ထိုနေရာရှိ သီးခြားကျန်ရစ်နေသော identifier regression များ (#6625/#6909) ကို CI က မတွေ့နိုင်ခဲ့ပါ။ မပြောင်းလဲစေရန် သတ်မှတ်ထားသော file တစ်ခုချင်းစီ/TS-code တစ်ခုချင်းစီ၏ အရေအတွက် baseline (`config/quality/dashboard-typecheck-baseline.json`၊ `check:known-symbols` နှင့် တူညီသော stale-enforcement ပုံစံ) နှင့် diff ပြုလုပ်သည် — baseline သတ်မှတ်ထားသော အရေအတွက်ထက် ကျော်လွန်သည့် error အသစ်များသာ gate ကို မအောင်မြင်စေသည်။ ယခင်ရှိပြီးသား error တစ်ခုကို ပြင်ဆင်ပြီးသောအခါ `--update` ဖြင့် baseline ကို တဖြည်းဖြည်း လျှော့ချပါ။ | ဟုတ်သည် | ### Job: `quality-gate` -`test-coverage` ပြီးနောက် လုပ်ဆောင်သည်။ မအောင်မြင်ပါက merge လုပ်ခြင်းကို ပိတ်ဆို့သည်။ - -| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `quality:collect` | `quality-metrics.json` ကို ထုတ်ပေးသည် (ESLint သတိပေးချက်အရေအတွက်၊ ပေါင်းစည်းထားသော shard အစီရင်ခံစာမှ coverage) | ဟုတ်သည် (ratchet မတိုင်မီ အဆင့်) | -| `quality:ratchet` | `quality-baseline.json` ရှိ metric တစ်ခုစီသည် ယခင်ထက် ဆုတ်ယုတ်မသွားကြောင်း စစ်ဆေးသည် (ESLint သတိပေးချက်များ ≤ baseline; coverage ≥ baseline) | ဟုတ်သည် | -| `check:duplication` | Code duplication (jscpd@4) သည် `quality-baseline.json` ရှိ baseline ကို မကျော်လွန်ကြောင်း စစ်ဆေးသည် | ဟုတ်သည် | -| `check:complexity` | ဖိုင်အဆင့် cyclomatic complexity သည် သတ်မှတ်ထားသော အများဆုံးပမာဏကို မကျော်လွန်ကြောင်း စစ်ဆေးသည် (core ESLint `complexity` + `max-lines-per-function`) | ဟုတ်သည် | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — သီးခြား ESLint စစ်ဆေးမှုဖြစ်ပြီး CI တွင် နှစ်ခုလုံးကို `check:complexity-ratchets` အဆင့်တစ်ခုတည်းအဖြစ် ပေါင်းစည်း၍ လုပ်ဆောင်သည် | ဟုတ်သည် | -| `check:dead-code` | အသုံးမပြုထားသော exports / ဖိုင်များအတွက် ratchet (knip) သည် baseline နှင့် နှိုင်းယှဉ်ရာတွင် ဆုတ်ယုတ်မသွားကြောင်း စစ်ဆေးသည် | ဟုတ်သည် | -| `check:compression-budget` | Compression benchmark budget — engine တစ်ခုချင်းစီ၏ token-savings အနိမ့်ဆုံးသတ်မှတ်ချက်များ ဆုတ်ယုတ်မသွားရပါ | ဟုတ်သည် | -| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) သည် ဆုတ်ယုတ်မသွားရပါ။ ၎င်းသည် `typecheck:noimplicit:core` ကို အဓိကအားဖြင့် အစားထိုးလွှမ်းခြုံထားသည် | ဟုတ်သည် | -| `check:codeql-ratchet` | ဖွင့်ထားသော CodeQL alert အရေအတွက် မတိုးလာကြောင်း စစ်ဆေးသည် (`gh api` မှတစ်ဆင့် ဖတ်ယူသည်။ token မရှိပါက အမှားမဖြစ်စေဘဲ ကျော်သွားသည်) — ပြန်လည်စစ်ဆေးသည့် အကြိမ်နှုန်းနှင့် ကိုယ်တိုင်စတင်ခြင်းအတွက် အောက်ပါ "CodeQL ratchet" ကို ကြည့်ပါ | ဟုတ်သည် | - -### လုပ်ငန်း: `quality-extended` - -လုပ်ငန်းတစ်ခုလုံးသည် အကြံပြုသဘောသာ ဖြစ်သည် (`continue-on-error: true`)။ npm အခြေပြု ratchet များကို -အမှန်တကယ် လုပ်ဆောင်သည်။ ပြင်ပ scanner များကို `gh release download` မှတစ်ဆင့် ထည့်သွင်းပြီး binary -မရှိသေးပါက မိမိဘာသာ ကျော်သွားသည် (exit 0)။ - -| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -| `check:circular-deps` | Circular dependency မရှိကြောင်း စစ်ဆေးသည် (dpdm) | **အကြံပြုသဘောသာ** | -| `check:bundle-size` | Bundle size သည် သတ်မှတ်ထားသော အများဆုံးပမာဏကို မကျော်လွန်ကြောင်း စစ်ဆေးသည် | **အကြံပြုသဘောသာ** | -| `check:secrets` | Secret scanning (gitleaks) — binary မရှိပါက ကျော်သွားသည် | **အကြံပြုသဘောသာ** | -| `check:vuln-ratchet` | Dependency vulnerability များ (osv-scanner) ဆုတ်ယုတ်မသွားကြောင်း စစ်ဆေးသည် — binary မရှိပါက ကျော်သွားသည် | **အကြံပြုသဘောသာ** | -| `check:workflows` | Workflow lint (actionlint + zizmor)။ scanner ပျောက်ဆုံးခြင်း/ပျက်ယွင်းခြင်း၊ အစီရင်ခံစာ မမှန်ကန်ခြင်း သို့မဟုတ် ratchet baseline ပျောက်ဆုံးခြင်းတို့ကို INCOMPLETE အဖြစ် သတ်မှတ်၍ မအောင်မြင်စေသည်။ တွေ့ရှိချက်အမှန်များသည် ရွေးချယ်ထားသော strict/advisory/ratchet မူဝါဒအတိုင်း လိုက်နာသည် | လုပ်ဆောင်ရန် လိုအပ်သည်။ CI တွင် zizmor ratchet က ပိတ်ဆို့သည် | -| `check:openapi-breaking` | အများသုံး API contract (`openapi.yaml`) တွင် base branch နှင့် နှိုင်းယှဉ်သည့် breaking change များ (oasdiff) — `openapiBreaking=N` ကို ထုတ်ပေးသည်။ oasdiff မရှိပါက သို့မဟုတ် base spec ကို ဖြေရှင်းမရပါက ကျော်သွားသည် | **အကြံပြုသဘောသာ** | - -### လုပ်ငန်း: `docs-sync-strict` - -`main` သို့ ပေးပို့သည့် PR တိုင်းတွင် လုပ်ဆောင်သည်။ မအောင်မြင်ပါက merge လုပ်ခြင်းကို ပိတ်ဆို့သည်။ - -| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | -| `check:docs-all` | အောက်ပါ sub-gate ၆ ခုကို အစဉ်လိုက် လုပ်ဆောင်သည့် meta-gate | ဟုတ်သည် | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ဗားရှင်းများ၏ တစ်သမတ်တည်းဖြစ်မှု | ဟုတ်သည် | -| ↳ `check:docs-counts` | စာသားဖော်ပြချက်များရှိ အရေအတွက်များ (provider အရေအတွက်၊ migration အရေအတွက် စသည်) သည် အမှန်တကယ်အရေအတွက်များ၏ ratchet window အတွင်း ရှိနေခြင်း | ဟုတ်သည် | -| ↳ `check:env-doc-sync` | `.env.example` ရှိ env var တိုင်းကို docs ဇယားတစ်ခုတွင် မှတ်တမ်းတင်ထားပြီး၊ docs ဇယားရှိ env var တိုင်းလည်း `.env.example` တွင် ရှိနေခြင်း | ဟုတ်သည် | -| ↳ `check:deprecated-versions` | docs များတွင် ရပ်ဆိုင်းထားသော ဗားရှင်း string များ မရှိခြင်း | ဟုတ်သည် | -| ↳ `check:doc-links` | docs အတွင်းရှိ internal markdown link များက အမှန်တကယ်ရှိသော ဖိုင်များသို့ ညွှန်းဆိုနိုင်ခြင်း (`[text]`/`(path)` ပုံစံ) | ဟုတ်သည် | -| ↳ `check:fabricated-docs` | docs တွင် ရည်ညွှန်းထားသော route များ၊ env var များ၊ CLI command များ၊ hook အမည်များနှင့် file path များသည် codebase ထဲတွင် အမှန်တကယ်ရှိခြင်း။ `--strict` ဖြင့် hard gate ဖြစ်ပြီး flag မပါလျှင် soft-fail ဖြစ်သည်။ | ဟုတ်သည် (CI တွင် `--strict` မှတစ်ဆင့်) | -| `check:cli-i18n` | CLI command string များသည် i18n locale ဖိုင်အားလုံးတွင် ရှိနေခြင်း | ဟုတ်သည် | -| `check:openapi-coverage` | OpenAPI spec သည် အမှန်တကယ်ရှိသော route များ၏ ratchet လုပ်ထားသည့် အနည်းဆုံးသတ်မှတ်ချက်ကို ပြည့်မီစွာ လွှမ်းခြုံထားခြင်း | ဟုတ်သည် | -| `check:openapi-security-tiers` | `openapi.yaml` ရှိ security tier annotation များသည် `routeGuard.ts` ရှိ classification များနှင့် တစ်သမတ်တည်းဖြစ်ခြင်း | **အကြံပြုချက်သာ** | -| `check:openapi-routes` | `openapi.yaml` ရှိ path တိုင်းသည် အမှန်တကယ်ရှိသော `route.ts` တစ်ခုသို့ ညွှန်းဆိုနိုင်ခြင်း (မရှိသောအရာ ဖန်တီးဖော်ပြမှုကို တားဆီးခြင်း) | ဟုတ်သည် | -| `check:docs-symbols` | `docs/**/*.md` ရှိ `/api/...` ရည်ညွှန်းချက်တိုင်းသည် အမှန်တကယ်ရှိသော `route.ts` တစ်ခုသို့ ညွှန်းဆိုနိုင်ခြင်း (မရှိသောအရာ ဖန်တီးဖော်ပြမှုကို တားဆီးခြင်း) | ဟုတ်သည် | -| `i18n translation drift` | i18n locale ဖိုင်များရှိ ဘာသာမပြန်ရသေးသော key များ — သတိပေးချက်သာ | **အကြံပြုချက်သာ** | +`test-coverage` ပြီးနောက် လုပ်ဆောင်သည်။ မအောင်မြင်ပါက merge ပြုလုပ်ခြင်းကို ပိတ်ဆို့သည်။ + +| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `quality:collect` | `quality-metrics.json` ကို ထုတ်ပေးသည် (ESLint သတိပေးချက်အရေအတွက်၊ ပေါင်းစည်းထားသော shard အစီရင်ခံစာမှ coverage) | ဟုတ်သည် (ratchet မတိုင်မီ) | +| `quality:ratchet` | `quality-baseline.json` ရှိ metric တစ်ခုချင်းစီသည် နောက်ပြန်ဆုတ်မသွားရပါ (ESLint သတိပေးချက်များ ≤ baseline; coverage ≥ baseline) | ဟုတ်သည် | +| `check:duplication` | Code duplication (jscpd@4) သည် `quality-baseline.json` ရှိ baseline ထက် မကျော်လွန်ရပါ | ဟုတ်သည် | +| `check:complexity` | File အဆင့် cyclomatic complexity သည် သတ်မှတ်ထားသော အများဆုံးပမာဏကို မကျော်လွန်ရပါ (core ESLint `complexity` + `max-lines-per-function`) | ဟုတ်သည် | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — သီးခြား ESLint pass; CI သည် နှစ်ခုလုံးကို `check:complexity-ratchets` အဆင့်တစ်ခုတည်းအဖြစ် ပေါင်းစည်း၍ run သည် | ဟုတ်သည် | +| `check:dead-code` | အသုံးမပြုသော exports / files ratchet (knip) သည် baseline နှင့် နှိုင်းယှဉ်လျှင် နောက်ပြန်ဆုတ်မသွားရပါ | ဟုတ်သည် | +| `check:compression-budget` | Compression benchmark budget — engine တစ်ခုချင်းစီ၏ token-savings အနိမ့်ဆုံးသတ်မှတ်ချက်များ နောက်ပြန်ဆုတ်မသွားရပါ | ဟုတ်သည် | +| `check:type-coverage` | ရာခိုင်နှုန်းအလိုက် typed ratchet (`type-coverage`) သည် နောက်ပြန်ဆုတ်မသွားရပါ; `typecheck:noimplicit:core` ကို အများစု လွှမ်းခြုံအစားထိုးထားသည် | ဟုတ်သည် | +| `check:codeql-ratchet` | ဖွင့်ထားသော CodeQL alert အရေအတွက်သည် နောက်ပြန်ဆုတ်မသွားရပါ (`gh api` မှတစ်ဆင့် ဖတ်သည်; token မရှိပါက အမှားမဖြစ်ဘဲ ကျော်သွားသည်) — refresh အကြိမ်ရေနှင့် ကိုယ်တိုင်စတင်ခြင်းအတွက် အောက်ရှိ "CodeQL ratchet" ကို ကြည့်ပါ | ဟုတ်သည် | + +### Job: `quality-extended` + +Job တစ်ခုလုံးသည် အကြံပြုချက်သဘောသာ ဖြစ်သည် (`continue-on-error: true`)။ npm အခြေပြု ratchets များကို +အမှန်တကယ် run သည်; ပြင်ပ scanners များကို `gh release download` မှတစ်ဆင့် install လုပ်ပြီး binary မရှိသေးပါက +ကိုယ်တိုင်ကျော်သွားသည် (exit 0)။ + +| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| `check:circular-deps` | Circular dependencies မရှိရပါ (dpdm) | **အကြံပြုချက်သဘော** | +| `check:bundle-size` | Bundle size သည် သတ်မှတ်ထားသော အများဆုံးပမာဏကို မကျော်လွန်ရပါ | **အကြံပြုချက်သဘော** | +| `check:secrets` | လျှို့ဝှက်ချက်များကို scan လုပ်ခြင်း (gitleaks) — binary မရှိပါက ကျော်သွားသည် | **အကြံပြုချက်သဘော** | +| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) များသည် နောက်ပြန်ဆုတ်မသွားရပါ — binary မရှိပါက ကျော်သွားသည် | **အကြံပြုချက်သဘော** | +| `check:workflows` | Workflow lint (actionlint + zizmor); scanners မရှိခြင်း/ပျက်နေခြင်း၊ မမှန်ကန်သော reports သို့မဟုတ် ratchet baseline မရှိခြင်းတို့ကြောင့် INCOMPLETE အဖြစ် ကျရှုံးသည်။ မှန်ကန်သော တွေ့ရှိချက်များသည် ရွေးချယ်ထားသည့် strict/advisory/ratchet policy ကို လိုက်နာသည် | လုပ်ဆောင်ရန် လိုအပ်သည်; CI တွင် zizmor ratchet က ပိတ်ဆို့သည် | +| `check:openapi-breaking` | Base branch (oasdiff) နှင့် နှိုင်းယှဉ်ရာတွင် public API contract (`openapi.yaml`) ၏ breaking changes — `openapiBreaking=N` ကို ထုတ်ပေးသည်; oasdiff မရှိပါက သို့မဟုတ် base spec ကို ဖြေရှင်းမရပါက ကျော်သွားသည် | **အကြံပြုချက်သဘော** | + +### Job: `docs-sync-strict` + +`main` သို့ PR တိုင်းတွင် run သည်။ မအောင်မြင်ပါက merge လုပ်ခြင်းကို ပိတ်ဆို့သည်။ + +| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | +| `check:docs-all` | အောက်ပါ sub-gate 6 ခုကို အစဉ်လိုက် လုပ်ဆောင်သည့် meta-gate | ရှိ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt version များ တစ်သမတ်တည်းရှိမှု | ရှိ | +| ↳ `check:docs-counts` | စာသားအတွင်းရှိ အရေအတွက်များ (provider အရေအတွက်၊ migration အရေအတွက် စသည်) သည် အမှန်တကယ်အရေအတွက်များ၏ ratchet window အတွင်း ရှိနေမှု | ရှိ | +| ↳ `check:env-doc-sync` | `.env.example` အတွင်းရှိ env var တိုင်းကို docs ဇယားတစ်ခုတွင် မှတ်တမ်းတင်ထားပြီး၊ အပြန်အလှန်အားဖြင့် docs ဇယားရှိ env var တိုင်းသည်လည်း `.env.example` တွင် ရှိနေမှု | ရှိ | +| ↳ `check:deprecated-versions` | docs များတွင် အသုံးမပြုတော့သည့် version string များ မရှိမှု | ရှိ | +| ↳ `check:doc-links` | docs အတွင်းရှိ internal markdown link များသည် အမှန်တကယ်ရှိသော file များသို့ ညွှန်းဆိုမှု (`[text]`/`(path)` ပုံစံ) | ရှိ | +| ↳ `check:fabricated-docs` | docs များတွင် ကိုးကားထားသော route များ၊ env var များ၊ CLI command များ၊ hook name များနှင့် file path များသည် codebase ထဲတွင် အမှန်တကယ် ရှိမှု။ `--strict` ဖြင့် hard gate ဖြစ်ပြီး flag မပါလျှင် soft-fail ဖြစ်သည်။ | ရှိ (CI တွင် `--strict` မှတစ်ဆင့်) | +| `check:cli-i18n` | CLI command string များသည် i18n locale file အားလုံးတွင် ပါရှိမှု | ရှိ | +| `check:openapi-coverage` | OpenAPI spec သည် အမှန်တကယ် route များ၏ ratchet သတ်မှတ်ထားသော အနည်းဆုံးအရေအတွက်ကို လွှမ်းခြုံမှု | ရှိ | +| `check:openapi-security-tiers` | `openapi.yaml` အတွင်းရှိ security tier annotation များသည် `routeGuard.ts` classification များနှင့် တစ်သမတ်တည်းရှိမှု | **အကြံပြုချက်သာ** | +| `check:openapi-routes` | `openapi.yaml` အတွင်းရှိ path တိုင်းသည် အမှန်တကယ်ရှိသော `route.ts` တစ်ခုသို့ ညွှန်းဆိုမှု (မမှန်ကန်သော ဖန်တီးဖော်ပြမှုကို ကာကွယ်ခြင်း) | ရှိ | +| `check:docs-symbols` | `docs/**/*.md` အတွင်းရှိ `/api/...` ကိုးကားချက်တိုင်းသည် အမှန်တကယ်ရှိသော `route.ts` တစ်ခုသို့ ညွှန်းဆိုမှု (မမှန်ကန်သော ဖန်တီးဖော်ပြမှုကို ကာကွယ်ခြင်း) | ရှိ | +| `i18n translation drift` | i18n locale file များအတွင်း ဘာသာမပြန်ရသေးသော key များ — သတိပေးချက်သာ | **အကြံပြုချက်သာ** | ### Job: `i18n-ui-coverage` -| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -| `check-ui-keys-coverage` (inline) | UI i18n key လွှမ်းခြုံမှုသည် ≥ 65% ဖြစ်ခြင်း | ဟုတ်သည် | -| `check-ui-value-drift` (inline) | ပြန်လည်ရေးသားထားသော အင်္ဂလိပ် **တန်ဖိုး** တစ်ခုကြောင့် ခေတ်မမီတော့သော ဘာသာပြန်ချက် တစ်ခုမျှ ကျန်မနေခြင်း | ဟုတ်သည် | -| `check-new-key-coverage` (inline) | **အသစ်** ထည့်ထားသော အင်္ဂလိပ် key ကို locale တိုင်းတွင် ဘာသာပြန်ထားခြင်း — `__MISSING__:` marker ကို လက်မခံပါ | ဟုတ်သည် | -| `check-translation-ratio` | locale တစ်ခုချင်းစီ၏ ဘာသာပြန်ချက်အစစ်အမှန် အချိုး (allowlist ပြင်ပရှိ အင်္ဂလိပ်နှင့် တူညီနေသော / placeholder ဖြစ်သော / ပျောက်ဆုံးနေသော leaf များ) သည် `config/quality/i18n-translation-baseline.json` + slack ကို မကျော်လွန်ရပါ | **အကြံပြုချက်သာ** | +| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `check-ui-keys-coverage` (inline) | UI i18n key လွှမ်းခြုံမှုသည် ≥ 65% ဖြစ်မှု | ရှိ | +| `check-ui-value-drift` (inline) | ပြန်လည်ရေးသားထားသော English **value** ကြောင့် ခေတ်မမီတော့သည့် ဘာသာပြန်ဆိုချက်တစ်ခုမျှ ကျန်မနေမှု | ရှိ | +| `check-new-key-coverage` (inline) | **အသစ်** ထည့်ထားသော English key ကို locale တိုင်းတွင် ဘာသာပြန်ထားမှု — `__MISSING__:` marker ကို လက်မခံပါ | ရှိ | +| `check-translation-ratio` | locale တစ်ခုစီ၏ အမှန်တကယ်ဘာသာပြန်ဆိုမှုအချိုး (allowlist ပြင်ပရှိ English နှင့်တူညီသော / placeholder ဖြစ်သော / ပျောက်ဆုံးနေသော leaf များ) သည် `config/quality/i18n-translation-baseline.json` + slack ထက် မကျော်လွန်ရ | **အကြံပြုချက်သာ** | -`fetch-depth: 0` လိုအပ်သည် — value-drift gate သည် merge base နှင့် `en.json` ကို diff ပြုလုပ်သည်။ +`fetch-depth: 0` လိုအပ်သည် — value-drift gate သည် `en.json` ကို merge base နှင့် diff ပြုလုပ်သည်။ -#### `check-ui-value-drift` — ခေတ်မမီတော့သော ဘာသာပြန်ချက် gate +#### `check-ui-value-drift` — ခေတ်မမီသော ဘာသာပြန်ဆိုချက် gate -အခြား gate များက ဖွဲ့စည်းပုံအရ မမြင်နိုင်သော i18n regression တစ်မျိုးကို ဖမ်းဆီးသည်− အင်္ဂလိပ်တန်ဖိုးတစ်ခုကို -ပြန်လည်ရေးသားလိုက်သော်လည်း _ယခင်_ အင်္ဂလိပ်မှ ဆင်းသက်လာသော ဘာသာပြန်ချက်များက ကျန်နေသဖြင့် -အင်္ဂလိပ်မဟုတ်သော ဘာသာစကားအသုံးပြုသူများသည် ယုံကြည်ချက်ရှိရှိ ရေးသားထားသော်လည်း ယခုအခါ မှားယွင်းနေသော စာသားကို ဆက်လက်ဖတ်နေရသည်။ +အခြား gate များက ဖွဲ့စည်းပုံအရ မတွေ့နိုင်သည့် i18n regression တစ်မျိုးကို ဖမ်းယူပေးသည်။ English value တစ်ခုကို +ပြန်လည်ရေးသားလိုက်သော်လည်း _ယခင်_ English မှ ဆင်းသက်လာသည့် ဘာသာပြန်ဆိုချက်များက ကျန်ရှိနေသောကြောင့် +English မဟုတ်သော ဘာသာစကားအသုံးပြုသူများသည် ယုံကြည်စိတ်ချရသည့် လေသံဖြင့် ရေးထားသော်လည်း ယခုအခါ မှားယွင်းနေသော စာသားကို ဆက်လက်ဖတ်ရှုနေရသည်။ -ဤပြဿနာသည် အမှန်တကယ် ထုတ်လုပ်ဖြန့်ချိသွားခဲ့သည်။ Antigravity -login helper ထည့်သွင်းစဉ် (#5203) `oauthModal.googleOAuthWarning` ကို ပြန်လည်ရေးသားခဲ့သော်လည်း၊ **locale ၄၃ ခုအနက် ၃၉ ခုတွင်** operator များအား "URL အပြည့်အစုံကို copy လုပ်ပြီး အောက်တွင် paste လုပ်ပါ" ဟု ပြောထားသည့် စာသား ဆက်လက်ကျန်ရှိခဲ့သည် — ထို provider အတွက် ပြီးမြောက်အောင် မလုပ်ဆောင်နိုင်သော flow ဖြစ်သည်။ အောက်ပါအကြောင်းရင်းများကြောင့် -#8463 အထိ သတိမပြုမိခဲ့ပါ− +ဤပြဿနာသည် လက်တွေ့ release တွင် အမှန်တကယ် ဖြစ်ပွားခဲ့သည်။ Antigravity +login helper ကို ထည့်သွင်းစဉ် (#5203) `oauthModal.googleOAuthWarning` ကို ပြန်လည်ရေးသားခဲ့သော်လည်း၊ **locale 43 ခုအနက် 39 ခုတွင်** operator များအား "URL အပြည့်အစုံကို copy လုပ်ပြီး အောက်တွင် paste လုပ်ပါ" ဟု ညွှန်ကြားသော စာသားကို ဆက်လက်ထားရှိခဲ့သည် — ထို provider အတွက် ပြီးမြောက်အောင် မလုပ်ဆောင်နိုင်သည့် flow တစ်ခုဖြစ်သည်။ အောက်ပါအကြောင်းရင်းများကြောင့် +#8463 အထိ သတိမပြုမိခဲ့ပါ။ -- `sync-ui-keys` သည် **မရှိသေးသော** key များကိုသာ backfill လုပ်ပြီး **ခေတ်မမီတော့သော** key များကို မလုပ်ပါ; -- `check-ui-keys-coverage` သည် key _ရှိနေမှု_ ကို ရေတွက်သောကြောင့် ခေတ်မမီတော့သော ဘာသာပြန်ချက်ကို လွှမ်းခြုံပြီးဟု သတ်မှတ်သည်; +- `sync-ui-keys` သည် **မရှိသေးသော** key များကိုသာ ဖြည့်စွက်ပေးပြီး **ခေတ်မမီတော့သော** key များကို မည်သည့်အခါမျှ မပြင်ဆင်ပါ။ +- `check-ui-keys-coverage` သည် key _ရှိနေမှု_ ကို ရေတွက်သောကြောင့် ခေတ်မမီသော ဘာသာပြန်ဆိုချက်တစ်ခုကိုလည်း လွှမ်းခြုံထားသည်ဟု သတ်မှတ်သည်။ - `check-translation-drift` သည် `docs/i18n//**.md` documentation mirror များကို ခြေရာခံသည် — - `src/i18n/messages/*.json` ကို လုံးဝမဖတ်ပါ။ 2026-09 re-sync ကတည်းက job `docs-sync-strict` တွင် ပိတ်ဆို့ထားသည်− core doc တစ်ခုကို ပြင်ဆင်ပါ → `npm run i18n:run -- --files=` (section-level ဖြစ်၍ ကုန်ကျစရိတ်နည်းသည်)။ + `src/i18n/messages/*.json` ကို မည်သည့်အခါမျှ မဖတ်ပါ။ 2026-09 re-sync မှစ၍ job `docs-sync-strict` တွင် ပိတ်ဆို့ထားသည်။ core doc တစ်ခုကို ပြင်ဆင်ပါက → `npm run i18n:run -- --files=` (section အဆင့်၊ ကုန်ကျစရိတ်နည်း) ကို လုပ်ဆောင်ပါ။ -**Diff ကို အခြေခံသိရှိပြီး baseline ကို မမှီခိုပါ။** ၎င်းသည် merge base ရှိ `en.json` ကို -working tree နှင့် နှိုင်းယှဉ်သည်။ အင်္ဂလိပ်တန်ဖိုး ပြောင်းလဲသွားသော key တစ်ခုစီအတွက် မူလ -ဘာသာပြန်ဆိုချက်အတိုင်း မပြောင်းလဲဘဲ ရှိနေသေးသော locale တိုင်းကို ခေတ်မမီတော့ဟု သတ်မှတ်သည်။ -ဤနည်းဖြင့် **ယခင်ကတည်းက ရှိနေသော ကြွေးကျန်ကို တမင်တကာ ထိန်းထားသည်** — ကာလကြာရှည် -တည်ရှိနေသော ဘာသာပြန်ဆိုချက်တစ်ခုသည် မည်သည့် အင်္ဂလိပ်စာသားဟောင်းမှ ဆင်းသက်လာကြောင်းကို -diff ဖြင့် မဖော်ထုတ်နိုင်သောကြောင့် gate သည် လက်ရှိပြောင်းလဲမှု ထိတွေ့သည့်အရာများကိုသာ -စစ်ဆေးဆုံးဖြတ်သည်။ အခြားရွေးချယ်စရာဖြစ်သည့် key တစ်ခုချင်းစီအလိုက် hash baseline သည် -အကြီးဆုံး လက်ရှိ baseline ထက် 3× ပိုကြီးသော ~600 KB generated file တစ်ခု လိုအပ်မည်ဖြစ်ပြီး -i18n PR တိုင်းတွင် အပြောင်းအလဲများ ဆက်တိုက်ဖြစ်ပေါ်စေမည်။ +**Diff ကို အခြေခံသိရှိပြီး baseline ကို အားမကိုးပါ။** ၎င်းသည် merge base ရှိ `en.json` ကို +working tree နှင့် နှိုင်းယှဉ်သည်။ အင်္ဂလိပ်တန်ဖိုး ပြောင်းလဲသွားသော key တစ်ခုစီအတွက် မပြောင်းလဲရသေးသော +ဘာသာပြန်တန်ဖိုးကို ဆက်လက်ကိုင်ထားသည့် locale မှန်သမျှသည် ခေတ်မမီတော့ဟု သတ်မှတ်သည်။ ဤနည်းဖြင့် **ယခင်ကတည်းက ရှိနေသော ကြွေးကျန်များကို ရည်ရွယ်ချက်ရှိရှိ ရပ်တန့်ထားသည်** — ကာလရှည်ကြာ ရှိနေသော ဘာသာပြန်ချက်တစ်ခုသည် မည်သည့် အင်္ဂလိပ်စာသားအဟောင်းမှ ဆင်းသက်လာသည်ကို diff တစ်ခုဖြင့် မဖော်ထုတ်နိုင်သောကြောင့် gate သည် +လက်ရှိပြောင်းလဲမှု ထိတွေ့သည့်အရာများကိုသာ အကဲဖြတ်သည်။ အခြားနည်းလမ်းဖြစ်သော key တစ်ခုချင်းစီအလိုက် hash baseline သည် +ထုတ်လုပ်ထားသော ~600 KB ဖိုင်တစ်ခု လိုအပ်မည်ဖြစ်ပြီး လက်ရှိအကြီးဆုံး baseline ထက် 3× ကြီးကာ i18n PR တစ်ခုစီတိုင်းတွင် +မကြာခဏ ပြောင်းလဲမှုများ ဖြစ်ပေါ်စေမည်ဖြစ်သည်။ -၎င်းကို ကျော်ဖြတ်ရန် နည်းလမ်းနှစ်ခုရှိသည်- +၎င်းကို ဖြည့်ဆည်းရန် နည်းလမ်းနှစ်ခုရှိသည်- -1. သက်ရောက်မှုရှိသော ဘာသာပြန်ဆိုချက်များကို update လုပ်ပါ၊ သို့မဟုတ် -2. ၎င်းတို့ကို `__MISSING__:` ဟု သတ်မှတ်ပါ — ထို့နောက် runtime သည် ပြင်ဆင်ပြီးသော - အင်္ဂလိပ်စာသားကို ပေးမည်ဖြစ်ပြီး (`src/i18n/request.ts::deepMergeFallback`, #7258) ထို key ကို - ဘာသာပြန်ရန် queue ထဲသို့ ထည့်မည်။ +1. သက်ရောက်မှုရှိသော ဘာသာပြန်ချက်များကို အပ်ဒိတ်လုပ်ပါ၊ သို့မဟုတ် +2. ၎င်းတို့ကို `__MISSING__:` ဟု သတ်မှတ်ပါ — ထို့နောက် runtime သည် ပြင်ဆင်ထားသော အင်္ဂလိပ်စာသားကို ပေးမည် + (`src/i18n/request.ts::deepMergeFallback`, #7258) ဖြစ်ပြီး ယင်း key ကို ဘာသာပြန်ရန် တန်းစီထားမည်ဖြစ်သည်။ -စာသား၏ **အဓိပ္ပာယ်** ပြောင်းလဲသွားပါက **key ကို အမည်ပြောင်းခြင်း** ကို ဦးစားပေးပါ။ key အသစ်သည် -ခေတ်မမီတော့သော ဘာသာပြန်ဆိုချက်ကို အမွေဆက်ခံနိုင်မည်မဟုတ်ပါ။ #8463 တွင် ဤပုံစံကို အသုံးပြုခဲ့သည်။ +စာသား၏ **အဓိပ္ပာယ်** ပြောင်းလဲသွားပါက **key ကို အမည်ပြောင်းခြင်း** ကို ဦးစားပေးပါ။ key အသစ်တစ်ခုသည် +ခေတ်မမီသော ဘာသာပြန်ချက်ကို ဆက်ခံ၍မရပါ။ ဤသည်မှာ #8463 အသုံးပြုခဲ့သော ပုံစံဖြစ်သည်။ ```bash -npm run i18n:check-value-drift # တင်းကျပ်သော စစ်ဆေးမှု (CI က လုပ်ဆောင်သည့်အရာ) +npm run i18n:check-value-drift # တင်းကျပ်သောမုဒ် (CI အသုံးပြုသည့်အရာ) npm run i18n:check-value-drift:warn # အစီရင်ခံရုံသာ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -အခြေခံ catalog ကို မဖတ်နိုင်သည့်အခါ (base ref မပါသော shallow clone) `SKIP reason=base-unresolved` -နှင့်အတူ 0 ဖြင့် ထွက်ပြီး `check-openapi-breaking` ၏ လုပ်ဆောင်ပုံကို အတုယူထားသည်။ +အခြေခံ catalog ကို မဖတ်နိုင်သည့်အခါ (base ref မပါသော shallow +clone) `check-openapi-breaking` ၏ လုပ်ဆောင်ပုံအတိုင်း `SKIP reason=base-unresolved` ဖြင့် exit code 0 ထုတ်ပေးသည်။ ### Job: `i18n` -i18n validation matrix အပြည့်အစုံ (locale တစ်ခုလျှင် job တစ်ခု)။ Job တစ်ခုလုံးသည် အကြံပြုချက်သဘောသာဖြစ်သည်။ +အပြည့်အစုံသော i18n စစ်ဆေးအတည်ပြုမှု matrix (locale တစ်ခုလျှင် job တစ်ခု)။ Job တစ်ခုလုံးသည် အကြံပြုချက်သဘောသာ ဖြစ်သည်။ -| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------- | -| `validate_translation.py quick` | locale တစ်ခုချင်းစီ၏ ဘာသာပြန်ဆိုမှု ပြည့်စုံခြင်း | **အကြံပြုချက်သဘောသာ** (job တစ်ခုလုံးတွင် `continue-on-error: true`) | +| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | Merge ကို ပိတ်ဆို့မှု | +| ------------------------------- | --------------------------------------------- | ------------------------------------------------------------------- | +| `validate_translation.py quick` | locale တစ်ခုချင်းစီ၏ ဘာသာပြန်ချက် ပြည့်စုံမှု | **အကြံပြုချက်သဘောသာ** (job တစ်ခုလုံးတွင် `continue-on-error: true`) | ### Job: `pr-test-policy` Pull request များတွင်သာ လုပ်ဆောင်သည်။ -| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` သို့မဟုတ် `bin/` ရှိ production code ကို ပြောင်းလဲသော PR များတွင် test များ ထည့်သွင်းခြင်း သို့မဟုတ် update လုပ်ခြင်း ရှိရမည် (Hard Rule #8) | ရှိသည် | -| `check:test-masking` | ပြောင်းလဲထားသော test file များသည် net assert အရေအတွက်ကို မလျှော့ချရသကဲ့သို့ `assert.ok(true)` tautology များကိုလည်း မထည့်ရ | ရှိသည် | -| `check:pr-evidence` | PR body တွင် ပြောင်းလဲမှုအတွက် test/VPS အထောက်အထားကို ရည်ညွှန်းထားရမည် (PR စာသားကို grep လုပ်ခြင်းဖြင့် Hard Rule #18 ကို အလိုအလျောက် အသက်သွင်းထားသည် — ပျက်လွယ်သောကြောင့် Backlog ကို ကြည့်ပါ) | ရှိသည် | +| Script | စစ်ဆေးအတည်ပြုသည့်အရာ | Merge ကို ပိတ်ဆို့မှု | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` သို့မဟုတ် `bin/` ရှိ production code ကို ပြောင်းလဲသည့် PR များတွင် test များကို ထည့်သွင်းရန် သို့မဟုတ် အပ်ဒိတ်လုပ်ရန် လိုအပ်သည် (Hard Rule #8) | ဟုတ်သည် | +| `check:test-masking` | ပြောင်းလဲထားသော test ဖိုင်များသည် စုစုပေါင်း assert အရေအတွက်ကို မလျှော့စေရသည့်အပြင် `assert.ok(true)` ကဲ့သို့ အမြဲမှန်နေသော စစ်ဆေးချက်များကိုလည်း မထည့်ရ | ဟုတ်သည် | +| `check:pr-evidence` | PR body တွင် ပြောင်းလဲမှုအတွက် test/VPS အထောက်အထားကို ကိုးကားထားသည် (PR စာသားကို grep လုပ်ခြင်းဖြင့် Hard Rule #18 ကို စက်ဖြင့် အကောင်အထည်ဖော်သည် — ခိုင်မာမှုနည်းသောကြောင့် Backlog ကို ကြည့်ပါ) | ဟုတ်သည် | ### Job: `test-vitest` `build` ပြီးနောက် လုပ်ဆောင်သည်။ မအောင်မြင်ပါက merge ကို ပိတ်ဆို့သည်။ -| Suite | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ---------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (tool 110 ခု), autoCombo, cache — vitest runner | ရှိသည် | -| `test:vitest:ui` | UI component test များ — vitest runner | **ပိတ်ဆို့သည်** — ယခင်ကတည်းက ရှိနေသော failure များကို `vitest.config.ts` တွင် အတိအလင်း ဖယ်ထုတ်ထားပြီး failure အသစ်များသည် job ကို ကျရှုံးစေသည် | +| Suite | စစ်ဆေးအတည်ပြုသည့်အရာ | Merge ကို ပိတ်ဆို့မှု | +| ---------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (tool 110 ခု), autoCombo, cache — vitest runner | ဟုတ်သည် | +| `test:vitest:ui` | UI component test များ — vitest runner | **ပိတ်ဆို့သည်** — ယခင်ကတည်းက ရှိနေသော မအောင်မြင်မှုများကို `vitest.config.ts` တွင် အတိအလင်း ဖယ်ထုတ်ထားပြီး မအောင်မြင်မှုအသစ်များသည် job ကို မအောင်မြင်စေသည် | -### ညစဉ် workflow များ (အချိန်ဇယားအလိုက်၊ အကြံပြုချက်သဘောသာ) +### ညစဉ် workflow များ (အချိန်ဇယားအတိုင်း၊ အကြံပြုချက်သဘောသာ) -၎င်းတို့သည် cron အချိန်ဇယားအတိုင်း (နှင့် `workflow_dispatch` ဖြင့်) လုပ်ဆောင်ပြီး PR များတွင် -မည်သည့်အခါမျှ မလုပ်ဆောင်ပါ။ အားလုံးသည် အကြံပြုချက်သဘောသာဖြစ်သည်။ +၎င်းတို့သည် cron အချိန်ဇယားအတိုင်း (နှင့် `workflow_dispatch` ဖြင့်) လုပ်ဆောင်ပြီး PR များတွင် မည်သည့်အခါမျှ မလုပ်ဆောင်ပါ။ အားလုံးသည် အကြံပြုချက်သဘောသာ ဖြစ်သည်။ -| Workflow | စစ်ဆေးအတည်ပြုသည့်အရာ | ပိတ်ဆို့မှု | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `nightly-property` | random seed နှင့် မြင့်မားသော run count ကို အသုံးပြုသည့် fast-check property test များ | **အကြံပြုချက်သဘောသာ** | -| `nightly-resilience` | heap-growth gate၊ chaos fault-injection၊ k6 load/soak | **အကြံပြုချက်သဘောသာ** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probe များ (provider secret မရှိပါက ကျော်သွားသည်) | **အကြံပြုချက်သဘောသာ** | -| `nightly-schemathesis` | `docs/openapi.yaml` ကို အသုံးပြု၍ live OmniRoute ပေါ်တွင် OpenAPI contract fuzzing (schemathesis) — spec ချိုးဖောက်မှုများ / ကိုင်တွယ်မထားသော 500 များကို ဖော်ထုတ်ပေးသည် (အဆင့် 8 B.4) | **အကြံပြုချက်သဘောသာ** | -| `nightly-mutation` | မြန်ဆန်သော unit lane ပေါ်ရှိ Stryker mutation-testing score — ဆက်လက်ရှင်သန်နေသော mutant များက အားနည်းသည့် assert များကို ဖော်ထုတ်ပေးသည် | **အကြံပြုချက်သဘောသာ** | -| `nightly-compat` | ပံ့ပိုးထားသော `engines.node` range များတစ်လျှောက် Node engine compatibility matrix | **အကြံပြုချက်သဘောသာ** | +| Workflow | စစ်ဆေးအတည်ပြုသည့်အရာ | Merge ကို ပိတ်ဆို့မှု | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `nightly-property` | ကျပန်း seed နှင့် များပြားသော run အရေအတွက်ကို အသုံးပြုသည့် fast-check property test များ | **အကြံပြုချက်သဘောသာ** | +| `nightly-resilience` | heap တိုးပွားမှု gate၊ chaos fault-injection၊ k6 load/soak | **အကြံပြုချက်သဘောသာ** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probe များ (provider secret မရှိပါက ကျော်သွားသည်) | **အကြံပြုချက်သဘောသာ** | +| `nightly-schemathesis` | `docs/openapi.yaml` ကို အသုံးပြု၍ လည်ပတ်နေသော OmniRoute ကို ဆန့်ကျင်စမ်းသပ်သည့် OpenAPI contract fuzzing (schemathesis) — spec ချိုးဖောက်မှုများ / မကိုင်တွယ်ထားသော 500 များကို ဖော်ထုတ်သည် (Fase 8 B.4) | **အကြံပြုချက်သဘောသာ** | +| `nightly-mutation` | မြန်ဆန်သော unit lane ပေါ်ရှိ Stryker mutation-testing ရမှတ် — ရှင်သန်ကျန်ရစ်သော mutant များက အားနည်းသည့် assert များကို ဖော်ထုတ်သည် | **အကြံပြုချက်သဘောသာ** | +| `nightly-compat` | ပံ့ပိုးထားသော `engines.node` range များတစ်လျှောက် Node engine လိုက်ဖက်ညီမှု matrix | **အကြံပြုချက်သဘောသာ** | --- @@ -534,47 +530,43 @@ diagnostic များကို ဖြေရှင်းနိုင်မည --- -## ကျိုးကြောင်းဆီလျော်အောင် ပြန်လည်စီစဉ်ရန် ကျန်ရှိစာရင်း (ROI ပြန်လည်သုံးသပ်မှု — အဆင့် 9 လှိုင်း 3) +## ကျိုးကြောင်းဆီလျော်အောင် ပြင်ဆင်ရန် ကျန်ရှိစာရင်း (ROI ပြန်လည်သုံးသပ်မှု — အဆင့် 9 လှိုင်း 3) -ဤစာရင်းကို 2026-06-17 ရက်နေ့တွင် `ci.yml` နှင့် တိုက်ဆိုင်စစ်ဆေးထားသည် (ယခင်ဗားရှင်းတွင် +ဤစာရင်းကို 2026-06-17 ရက်နေ့တွင် `ci.yml` နှင့် တိုက်ဆိုင်စစ်ဆေးပြီးဖြစ်သည် (ယခင်ဗားရှင်းတွင် `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` တို့ မပါရှိခဲ့ပါ)။ တိုက်ဆိုင်စစ်ဆေးထားသော အစုကို -ROI ပြန်လည်သုံးသပ်ရာမှ အောက်ပါ ကျိုးကြောင်းဆီလျော်အောင် ပြန်လည်စီစဉ်နိုင်မည့် အရာများကို -ဖော်ထုတ်ခဲ့သည်။ **ပေါင်းစည်းမှုများသည် စက်ပိုင်းဆိုင်ရာ CI အပြောင်းအလဲများဖြစ်ပြီး၊ -ပြောင်းလဲဖွင့်ခြင်း/ဖယ်ရှားခြင်းများသည် အော်ပရေတာအတွက် သီးသန့်ထားသော မူဝါဒဆုံးဖြတ်ချက်များ -ဖြစ်သည်။** အောက်ပါအရာများအနက် မည်သည့်အရာကိုမျှ အသုံးမချရသေးပါ။ - -**အထက်တွင် မှတ်တမ်းမတင်ရသေးသောအရာများလည်း ရှိသည်** (အကြံပြုအဆင့်၊ အချက်ပြမှုနည်း): -`docs-lint` job (markdownlint + Vale၊ job တစ်ခုလုံး `continue-on-error`) နှင့် သီးခြား scanner -workflow များဖြစ်သော `semgrep.yml` / `codeql.yml` / `scorecard.yml` တို့ဖြစ်သည်။ -`semgrepFindings: 0` သည် `quality-baseline.json` ထဲတွင် ရှိသော်လည်း `ci.yml` ထဲရှိ -ပိတ်ဆို့တားဆီးသော ratchet တစ်ခုနှင့် ချိတ်ဆက်ထားခြင်းမရှိပါ — လက်ရှိတွင် ဤ metric သည် -သီးခြားပြတ်တောက်နေသည်။ - -### ပေါင်းစည်းခြင်း / ထပ်နေမှုဖယ်ရှားခြင်း (စက်ပိုင်းဆိုင်ရာ၊ အန္တရာယ်ပိုနည်း) - -အဆိုပြုထားသည့် အရာတစ်ခုစီကို 2026-06-17 ရက်နေ့ရှိ တကယ့် gate အခြေအနေနှင့် တိုက်ဆိုင်၍ -အတည်ပြုထားသည် (ယုံကြည်သော်လည်း ပြန်လည်စစ်ဆေးခြင်း)။ “သိသာထင်ရှား” သော ပေါင်းစည်းမှု -အများအပြားသည် အမှန်တကယ်တွင် ကြွေးကျန်များကို ဖုံးကွယ်ထားကြောင်း တွေ့ရှိရသဖြင့် -**တိုက်ရိုက်အစားထိုးအသုံးပြုနိုင်သော သန့်ရှင်းသည့် ပေါင်းစည်းမှုများ မဟုတ်ပါ**။ - -- **`check:docs-sync` ကို နှစ်ကြိမ် လုပ်ဆောင်နေသည်** — `lint` job ထဲတွင် သီးခြားလုပ်ဆောင်ပြီး `check:docs-all` (`docs-sync-strict`) နှင့် husky pre-commit hook ထဲတွင် ထပ်မံလုပ်ဆောင်သည်။ ✅ **ပြီးစီးပြီ** — သီးခြား `lint` invocation ကို ဖယ်ရှားပြီးဖြစ်သည်။ -- **CVE စကင်ဖတ်ခြင်း** — ❌ **သန့်ရှင်းစွာ ပေါင်းစည်း၍ မရပါ။** `audit:deps` သည် high/critical CVE တစ်ခုခုရှိလျှင် ချက်ချင်း မအောင်မြင်စေသည်။ `check:vuln-ratchet` (osv) သည် baseline နှင့် နှိုင်းယှဉ်၍ _ပိုမိုဆိုးရွားလာမှု_ ရှိမှသာ မအောင်မြင်စေသည် (လက်ရှိတွင် 1 MODERATE)။ အဓိပ္ပာယ်သတ်မှတ်ချက်များ မတူညီပါ — `audit:deps` ကို ဖယ်ရှားပါက absolute high/critical gate ကို ဆုံးရှုံးမည်ဖြစ်သည်။ နှစ်ခုလုံးကို ဆက်လက်ထားရှိပါ။ -- **Cycle ရှာဖွေခြင်း** — ❌ **သန့်ရှင်းစွာ ပေါင်းစည်း၍ မရပါ။** `check:circular-deps` (dpdm) က **cycle 91 ခု** ကို အစီရင်ခံထားသည် (ထို့ကြောင့်ပင် advisory အဖြစ်ထားရှိခြင်းဖြစ်သည်)။ ၎င်းတို့ကို ဦးစွာမဖြေရှင်းဘဲ blocking အဖြစ် မြှင့်တင်၍မရသည့်အပြင် green အခြေအနေရှိပြီး ရွေးချယ်စီစဉ်ထားသော `check:cycles` ထက် scope ပိုကျယ်သည်။ `check:cycles` ကို blocking အဖြစ် ဆက်လက်ထားရှိပါ။ dpdm cycle 91 ခုကို ဖြေရှင်းခြင်းသည် သီးခြား backlog ဖြစ်သည်။ -- **ရှုပ်ထွေးမှု** — ✅ **ပြီးစီးပြီ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`)။ ESLint walk တစ်ကြိမ်တည်းဖြင့် ruleId အလိုက် ရေတွက်သဖြင့် cyclomatic+max-lines နှင့် cognitive baseline များကို သီးခြားဆက်လက်ထိန်းသိမ်းထားသည်။ တစ်ခုချင်းစီဖြစ်သော `check:complexity` / `check:cognitive-complexity` ကို local `--update` အတွက် ဆက်လက်ထားရှိသည်။ -- **`/api` anti-hallucination** — ✅ **ပြီးစီးပြီ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`)။ `src/app/api` ကို FS inventory တစ်ကြိမ်တည်း ပြုလုပ်ပြီး openapi-routes + docs-symbols တို့က သီးခြားစီ ဆက်လက်အစီရင်ခံသည်။ တစ်ခုချင်းစီကို local run များအတွက် ဆက်လက်ထားရှိသည်။ -- **`check:node-runtime` ကို job 11 ခုတွင် လုပ်ဆောင်နေသည်** — ⚠️ **ROI နည်းသည်။** တစ်ခုစီသည် သီးခြား runner ဖြစ်ပြီး check သည် <1s သာ ကြာသည်။ စုစုပေါင်းချွေတာနိုင်သည့်အချိန်မှာ ~10s ဖြစ်ကာ job တစ်ခုချင်းစီအတွက် စရိတ်နည်းသော guard ကို ဆုံးရှုံးရမည့်အခြေအနေနှင့် နှိုင်းယှဉ်လျှင် ပြောင်းလဲရသည့် အားထုတ်မှုနှင့် မထိုက်တန်ပါ။ -- **CI lint ပေါ်ရှိ `typecheck:noimplicit:core`** — ✅ **lint job မှ ဖယ်ရှားပြီးဖြစ်သည်** (ယခင်က advisory `continue-on-error` ဖြစ်ခဲ့သည်)။ blocking type surface မှာ `typecheck:core` + `check:type-coverage` ဖြစ်သည်။ Local script ကို ဆက်လက်ထားရှိသည်။ - -### ပြောင်းလဲဖွင့်ရန် / ဆုံးဖြတ်ရန် (အော်ပရေတာ မူဝါဒ) - -- `check:openapi-security-tiers` (advisory) — ❌ **သန့်ရှင်းစွာ ပြောင်းလဲဖွင့်၍ မရပါ။** ၎င်းသည် 0 ဖြင့် ထွက်သော်လည်း `LOCAL_ONLY_API_PREFIXES` အောက်ရှိ `traffic-inspector` route အများအပြားတွင် `x-loopback-only: true` annotation မရှိကြောင်း သတိပေးသည်။ ၎င်းကို အတင်းအကျပ်လိုက်နာစေရန် ဦးစွာ အဆိုပါ annotation များကို `openapi.yaml` ထဲသို့ ထည့်ရမည်။ -- `typecheck:noimplicit:core` (advisory) — blocking ဖြစ်သော `check:type-coverage` ratchet က အများစုကို လွှမ်းခြုံထားပြီးဖြစ်သည်။ ratchet အဖြစ် ပြောင်းလဲဖွင့်ပါ သို့မဟုတ် ထပ်နေသော ဒုတိယ `tsc` pass ကို ဖယ်ရှားပါ။ -- `test:vitest:ui` (ယခု **blocking**) — ယခင်ကတည်းကရှိသော failure များကို `vitest.config.ts` ထဲတွင် `// #8618` tracking comment များဖြင့် အတိအလင်း ဖယ်ထုတ်ထားသည်။ failure အသစ်များက job ကို မအောင်မြင်စေမည်။ -- `check:secrets` (gitleaks၊ မှတ်တမ်းတင်ထားသော false-positive 3 ခုတွင် ရပ်တန့်ထားသည့် blocking ratchet) — 0 သို့ရောက်ရှိရန် 3 ခုကို allowlist ထဲ ထည့်ပါ သို့မဟုတ် advisory အဆင့်သို့ လျှော့ချပါ။ GitHub native secret-scanning + `check:public-creds` နှင့် ထပ်နေသည်။ -- `check:pr-evidence` (blocking၊ PR-body စာသားကို greps လုပ်သည်) — false-positive ဖြစ်နိုင်ခြေ မြင့်မားသည်။ ဖယ်ရှားပါက Hard Rule #18 ကို အတင်းအကျပ်လိုက်နာစေမှု အားနည်းသွားမည်ဖြစ်သောကြောင့် ၎င်းသည် အမှန်တကယ် မူဝါဒဆိုင်ရာ ဆုံးဖြတ်ချက်ဖြစ်သည်။ -- `semgrep` (advisory standalone) — OWASP family များအတွက် CodeQL နှင့် ထပ်နေသည်။ ၎င်း၏ baseline ကို ratchet တစ်ခုနှင့် ချိတ်ဆက်ပါ သို့မဟုတ် ဖယ်ရှားပါ။ +`check:codeql-ratchet`, `check:pr-evidence` တို့ မပါရှိခဲ့ပါ)။ တိုက်ဆိုင်စစ်ဆေးထားသော အစုကို ROI ပြန်လည်သုံးသပ်ရာမှ +အောက်ပါ ကျိုးကြောင်းဆီလျော်အောင် ပြင်ဆင်နိုင်မည့်အရာများကို ဖော်ထုတ်နိုင်ခဲ့သည်။ **ပေါင်းစည်းမှုများသည် အလိုအလျောက်လုပ်ဆောင်နိုင်သော CI +အပြောင်းအလဲများဖြစ်ပြီး၊ အခြေအနေပြောင်းခြင်း/ဖယ်ရှားခြင်းများသည် အော်ပရေတာအတွက် သီးသန့်ထားရှိသော မူဝါဒဆိုင်ရာ ဆုံးဖြတ်ချက်များဖြစ်သည်။** အောက်ပါအရာများအနက် +မည်သည့်အရာကိုမျှ မကျင့်သုံးရသေးပါ။ + +**အထက်တွင် မှတ်တမ်းမတင်ထားသေးသည့်အရာများလည်း ရှိသည်** (အကြံပြုအဆင့်၊ အချက်ပြအားနည်းသည်) — `docs-lint` အလုပ် +(markdownlint + Vale၊ အလုပ်တစ်ခုလုံး `continue-on-error`) နှင့် သီးခြား scanner workflow များဖြစ်သော +`semgrep.yml` / `codeql.yml` / `scorecard.yml`။ `semgrepFindings: 0` သည် +`quality-baseline.json` တွင် ပါရှိသော်လည်း `ci.yml` အတွင်းရှိ ပိတ်ဆို့သည့် ratchet နှင့် ချိတ်ဆက်ထားခြင်းမရှိပါ — ထို့ကြောင့် ဤမက်ထရစ်သည် +လက်ရှိတွင် ချိတ်ဆက်မှုမရှိဘဲ သီးခြားဖြစ်နေသည်။ + +### ပေါင်းစည်းခြင်း / ထပ်နေမှုဖယ်ရှားခြင်း (အလိုအလျောက်လုပ်ဆောင်နိုင်ပြီး အန္တရာယ်နည်းသည်) + +ပြင်ဆင်နိုင်မည့်အရာတစ်ခုစီကို 2026-06-17 ရက်နေ့ရှိ အသုံးပြုနေသော gate အခြေအနေနှင့် တိုက်ဆိုင်အတည်ပြုထားသည် (ယုံကြည်သော်လည်း စစ်ဆေးအတည်ပြုပါ)။ +“သိသာထင်ရှားသည့်” ပေါင်းစည်းမှုအချို့သည် နောက်ကွယ်ရှိ နည်းပညာကြွေးမြီကို ဖုံးကွယ်ထားကြောင်း တွေ့ရှိရသဖြင့် **တိုက်ရိုက်အစားထိုးအသုံးပြုနိုင်ခြင်း မရှိပါ**။ + +- **`check:docs-sync` ကို နှစ်ကြိမ် လုပ်ဆောင်နေသည်** — `lint` အလုပ်အတွင်း သီးခြားလုပ်ဆောင်ပြီး `check:docs-all` (`docs-sync-strict`) အတွင်းနှင့် husky pre-commit hook အတွင်းတွင်လည်း ထပ်မံလုပ်ဆောင်သည်။ ✅ **ပြီးစီးပြီ** — သီးခြား `lint` ခေါ်ယူမှုကို ဖယ်ရှားပြီးဖြစ်သည်။ +- **CVE စကင်ဖတ်ခြင်း** — ❌ **ပေါင်းစည်းရန် အဆင်သင့်မဖြစ်သေးပါ။** `audit:deps` သည် high/critical CVE တစ်ခုခုရှိပါက ချက်ချင်း မအောင်မြင်စေသည်။ `check:vuln-ratchet` (osv) ကမူ baseline (လက်ရှိတွင် 1 MODERATE) နှင့် နှိုင်းယှဉ်ရာ၌ _ဆုတ်ယုတ်မှု_ ရှိမှသာ မအောင်မြင်စေသည်။ အဓိပ္ပာယ်ဖွင့်ဆိုမှု မတူညီပါ — `audit:deps` ကို ဖယ်ရှားပါက တိကျပြတ်သားသော high/critical gate ကို ဆုံးရှုံးသွားမည်ဖြစ်သည်။ နှစ်ခုစလုံးကို ဆက်လက်ထားရှိပါ။ +- **Cycle ရှာဖွေခြင်း** — ✅ **ပြီးစီးပြီ** (#15159 G-01/G-02)။ ဤနေရာရှိ စာသားဟောင်းတွင် `check:cycles` ကို “အောင်မြင်နေသော၊ ရွေးချယ်စီစဉ်ထားသည့်” gate ဟု ခေါ်ဆိုခဲ့ပြီး `check:circular-deps` (dpdm) က cycle 91 ခုကို အစီရင်ခံထားသဖြင့် ၎င်းကို ပိတ်ဆို့သည့် gate အဖြစ် ဆက်ထားရန် ကျိုးကြောင်းပြခဲ့သည်။ ထိုအောင်မြင်မှုသည် **မှားယွင်းသော အောင်မြင်မှု** ဖြစ်သည် — `check:cycles` သည် subdirectory 5 ခု (ဖိုင် 450 ခု) ကိုသာ စကင်ဖတ်ခဲ့ပြီး static `import|export … from` ကိုသာ ကိုက်ညီစစ်ဆေးကာ `@/` နှင့် `@omniroute/open-sse/` specifier အားလုံးကို ဖယ်ရှားခဲ့သောကြောင့် repo အတွင်း အများစုဖြစ်နေသည့် dynamic-import + alias cycle များကို မမြင်နိုင်ခဲ့ပါ။ ပြင်ဆင်ပြီးနောက် gate သည် ယခု `src` + `open-sse` (ဖိုင် 5023 ခု) ကို ဖြတ်သန်းစစ်ဆေးပြီး TypeScript AST မှ specifier များကို စုဆောင်းသည် (ထို့ကြောင့် `import("…")` ကို ရေတွက်ပြီး type-position `typeof import("…")` ကို မရေတွက်ပါ)၊ ထို့ပြင် tsconfig `paths` ကိုလည်း ဖြေရှင်းပေးသည်။ ၎င်းသည် 0 မဟုတ်ဘဲ cycle **14** ခုကို ရှာတွေ့သည်။ ယခင်ကတည်းကရှိနေသော cycle 14 ခုကို gate PR တစ်ခုတည်းအတွင်း မပြင်ဆင်နိုင်သောကြောင့် `check:cycles` သည် ယခု **ratchet** (`--ratchet`, `quality-baseline.json` အတွင်း ceiling `metrics.cycles.value = 14`, `direction: down`) ဖြစ်လာသည် — မည်သည့် _ဆုတ်ယုတ်မှု_ ကိုမဆို ပိတ်ဆို့ပြီး အရေအတွက်သည် လျော့ကျရန်သာ ခွင့်ပြုသည်။ CI သည် `npm run check:cycles:ratchet` ကို လုပ်ဆောင်သည်။ တဖြည်းဖြည်းလျှော့ချမှုကို **A-01** နှင့်အတူ ဆောင်ရွက်မည်။ `check:circular-deps` (dpdm) ကို ပိုမိုကျယ်ပြန့်သော ဒုတိယအမြင်အဖြစ် အကြံပြုအဆင့်တွင် ဆက်ထားမည်။ +- **ရှုပ်ထွေးမှု** — ✅ **ပြီးစီးပြီ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`) — ESLint ဖြတ်သန်းစစ်ဆေးမှုတစ်ကြိမ်တည်းဖြင့် ruleId အလိုက် ရေတွက်သဖြင့် cyclomatic+max-lines နှင့် cognitive baseline များ သီးခြားတည်ရှိနေသည်။ တစ်ခုချင်းစီဖြစ်သော `check:complexity` / `check:cognitive-complexity` ကို local `--update` အတွက် ဆက်ထားသည်။ +- **`/api` anti-hallucination** — ✅ **ပြီးစီးပြီ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`) — `src/app/api` ၏ FS inventory တစ်ကြိမ်တည်းဖြင့် openapi-routes + docs-symbols တို့က သီးခြားစီ အစီရင်ခံနေဆဲဖြစ်သည်။ တစ်ခုချင်းစီကို local run များအတွက် ဆက်ထားသည်။ +- **`check:node-runtime` ကို အလုပ် 11 ခုတွင် လုပ်ဆောင်နေသည်** — ⚠️ **ROI နည်းသည်။** တစ်ခုစီသည် သီးခြား runner ဖြစ်ပြီး စစ်ဆေးမှုသည် 1s အောက်သာ ကြာသည်။ စုစုပေါင်း ချွေတာနိုင်သည့်အချိန်မှာ ~10s ဖြစ်သော်လည်း အလုပ်တစ်ခုချင်းစီအတွက် စရိတ်နည်းသော guard ကို ဆုံးရှုံးရမည်ဖြစ်သည်။ ပြောင်းလဲရသည့် ဝန်နှင့် မတန်ပါ။ +- **CI lint ပေါ်ရှိ `typecheck:noimplicit:core`** — ✅ **lint အလုပ်မှ ဖယ်ရှားပြီးဖြစ်သည်** (ယခင်က အကြံပြုအဆင့် `continue-on-error` ဖြစ်သည်)။ ပိတ်ဆို့သည့် type surface မှာ `typecheck:core` + `check:type-coverage` ဖြစ်သည်။ Local script ကို ဆက်လက်ထားရှိသည်။ + +### အခြေအနေပြောင်းခြင်း / ဆုံးဖြတ်ခြင်း (အော်ပရေတာ မူဝါဒ) + +- `check:openapi-security-tiers` (အကြံပြုအဆင့်) — ❌ **ပိတ်ဆို့သည့်အခြေအနေသို့ တိုက်ရိုက်ပြောင်း၍ မရသေးပါ။** ၎င်းသည် 0 ဖြင့် ထွက်သော်လည်း `LOCAL_ONLY_API_PREFIXES` အောက်ရှိ `traffic-inspector` route အချို့တွင် `x-loopback-only: true` annotation မရှိကြောင်း သတိပေးသည်။ ၎င်းကို မဖြစ်မနေလိုက်နာစေရန် ဦးစွာ ထို annotation များကို `openapi.yaml` ထဲသို့ ထည့်ရမည်။ +- `typecheck:noimplicit:core` (အကြံပြုအဆင့်) — ပိတ်ဆို့သည့် `check:type-coverage` ratchet က အများအားဖြင့် အစားထိုးလွှမ်းခြုံထားသည်။ Ratchet အဖြစ် ပြောင်းပါ သို့မဟုတ် ထပ်နေသော ဒုတိယ `tsc` ဖြတ်သန်းမှုကို ဖယ်ရှားပါ။ +- `test:vitest:ui` (ယခု **ပိတ်ဆို့နေသည်**) — ယခင်ကတည်းကရှိနေသော မအောင်မြင်မှုများကို `vitest.config.ts` တွင် `// #8618` ခြေရာခံမှတ်ချက်များဖြင့် အတိအလင်း ဖယ်ထုတ်ထားသည်။ မအောင်မြင်မှုအသစ်များက အလုပ်ကို မအောင်မြင်စေသည်။ +- `check:secrets` (gitleaks၊ မှတ်တမ်းတင်ထားသော false-positive 3 ခုတွင် ရပ်တန့်ထားသည့် ပိတ်ဆို့သော ratchet) — 0 သို့ရောက်ရန် ထို 3 ခုကို allowlist ထဲ ထည့်ပါ၊ သို့မဟုတ် အကြံပြုအဆင့်သို့ လျှော့ချပါ။ GitHub ၏ မူလ secret-scanning + `check:public-creds` နှင့် ထပ်နေသည်။ +- `check:pr-evidence` (ပိတ်ဆို့ထားပြီး PR-body စကားပြေစာသားကို grep လုပ်သည်) — false-positive ဖြစ်နိုင်ခြေ မြင့်မားသည်။ ဖယ်ရှားပါက Hard Rule #18 ကို အကောင်အထည်ဖော်မှု အားနည်းသွားမည်ဖြစ်သောကြောင့် ၎င်းသည် အမှန်တကယ် မူဝါဒဆိုင်ရာ ဆုံးဖြတ်ချက်ဖြစ်သည်။ +- `semgrep` (အကြံပြုအဆင့် သီးခြား workflow) — OWASP အမျိုးအစားများအတွက် CodeQL နှင့် ထပ်နေသည်။ ၎င်း၏ baseline ကို ratchet တစ်ခုနှင့် ချိတ်ဆက်ပါ၊ သို့မဟုတ် ဖယ်ရှားပါ။ --- diff --git a/docs/i18n/ne/CONTRIBUTING.md b/docs/i18n/ne/CONTRIBUTING.md index b9f2afa66bc..57117a8de9b 100644 --- a/docs/i18n/ne/CONTRIBUTING.md +++ b/docs/i18n/ne/CONTRIBUTING.md @@ -400,22 +400,22 @@ handlers/executors भित्र, client सम्म पुग्ने error --- -## Pull Request Checklist - -- [ ] Tests सफल हुन्छन् (`npm test`) -- [ ] Linting सफल हुन्छ (`npm run lint`) -- [ ] Build सफल हुन्छ (`npm run build`) -- [ ] नयाँ public functions र interfaces का लागि TypeScript types थपिएका छन् -- [ ] कुनै hardcoded secrets वा fallback values छैनन् -- [ ] सार्वजनिक upstream credentials लाई `resolvePublicCred()` मार्फत embed गरिएको छ ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) हेर्नुहोस्), literals का रूपमा कहिल्यै होइन -- [ ] Error responses लाई `buildErrorBody()` / `sanitizeErrorMessage()` मार्फत route गरिएको छ — response bodies मा raw stack traces छैनन् ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) हेर्नुहोस्) -- [ ] Shell commands (`exec` / `spawn`) ले runtime values लाई string interpolation मार्फत होइन, `env` मार्फत पठाउँछन् -- [ ] सबै inputs लाई Zod schemas प्रयोग गरेर validate गरिएको छ -- [ ] User-facing changes का लागि `changelog.d/{features|fixes|maintenance}/-.md` अन्तर्गत changelog **fragment** थपिएको छ ([`changelog.d/README.md`](./changelog.d/README.md) हेर्नुहोस्) — `CHANGELOG.md` लाई सीधै edit **नगर्नुहोस्**; fragments लाई release को समयमा aggregate गरिन्छ र PRs बीच कहिल्यै conflict हुँदैन -- [ ] Documentation अद्यावधिक गरिएको छ (लागू भएमा) -- [ ] कुनै नयाँ CodeQL / Secret-Scanning alerts खोलिएका छैनन्, वा प्रत्येकलाई सम्बन्धित `docs/security/` doc उल्लेख गर्ने technical justification सहित dismiss गरिएको छ -- [ ] Child processes spawn गर्ने routes (`/api/mcp/`, `/api/cli-tools/runtime/`) लाई `src/server/authz/routeGuard.ts` मा `isLocalOnlyPath()` का रूपमा classify गरिएको छ — [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md) हेर्नुहोस् -- [ ] Commit messages मा `Co-Authored-By` trailers छैनन् — commits केवल repository owner को Git identity अन्तर्गत देखिनुपर्छ (Hard Rule #16) +## पुल अनुरोध जाँचसूची + +- [ ] परीक्षणहरू सफल हुन्छन् (`npm test`) +- [ ] लिन्टिङ सफल हुन्छ (`npm run lint`) +- [ ] बिल्ड सफल हुन्छ (`npm run build`) +- [ ] नयाँ सार्वजनिक फङ्सन र इन्टरफेसहरूका लागि TypeScript प्रकारहरू थपिएका छन् +- [ ] हार्डकोड गरिएका गोप्य मान वा वैकल्पिक मानहरू छैनन् +- [ ] सार्वजनिक अपस्ट्रिम प्रमाणहरू `resolvePublicCred()` मार्फत समावेश गरिएका छन् ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) हेर्नुहोस्), लिटरलका रूपमा कहिल्यै होइन +- [ ] त्रुटि प्रतिक्रियाहरू `buildErrorBody()` / `sanitizeErrorMessage()` मार्फत पठाइन्छन् — प्रतिक्रिया बडीहरूमा कच्चा स्ट्याक ट्रेसहरू छैनन् ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) हेर्नुहोस्) +- [ ] शेल कमान्डहरू (`exec` / `spawn`) ले रनटाइम मानहरू स्ट्रिङ इन्टरपोलेसनमार्फत नभई `env` मार्फत पठाउँछन् +- [ ] सबै इनपुटहरू Zod स्किमाहरूद्वारा प्रमाणीकरण गरिएका छन् +- [ ] प्रयोगकर्ताले देख्ने परिवर्तनहरूका लागि `changelog.d/{features|fixes|maintenance}/-.md` अन्तर्गत चेन्जलग **फ्र्याग्मेन्ट** थपिएको छ ([`changelog.d/README.md`](./changelog.d/README.md) हेर्नुहोस्) — `CHANGELOG.md` लाई सीधै सम्पादन **नगर्नुहोस्**; फ्र्याग्मेन्टहरू रिलिजको समयमा एकत्रित गरिन्छन् र PR हरूबीच कहिल्यै द्वन्द्व हुँदैन +- [ ] दस्तावेज अद्यावधिक गरिएको छ (लागू भएमा) +- [ ] कुनै नयाँ CodeQL / Secret-Scanning अलर्ट खोलिएको छैन, वा प्रत्येकलाई सम्बन्धित `docs/security/` दस्तावेज सन्दर्भ गर्ने प्राविधिक औचित्यसहित खारेज गरिएको छ +- [ ] चाइल्ड प्रोसेस सुरु गर्ने रुटहरू (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` मा `isLocalOnlyPath()` का रूपमा वर्गीकृत गरिएका छन् — [कडा नियम #15](docs/security/ROUTE_GUARD_TIERS.md) हेर्नुहोस् +- [ ] कमिट सन्देशहरूमा AI/bot `Co-authored-by` ट्रेलरहरू छैनन् (कडा नियम #16) — पुनः प्रयोग गरिएको कामका मानव सहकर्मीहरूलाई मानक `Co-authored-by: Name ` ट्रेलरहरूमार्फत श्रेय दिइएको छ --- diff --git a/docs/i18n/ne/docs/architecture/QUALITY_GATES.md b/docs/i18n/ne/docs/architecture/QUALITY_GATES.md index 3db83b3759d..03cac28ffac 100644 --- a/docs/i18n/ne/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ne/docs/architecture/QUALITY_GATES.md @@ -19,212 +19,210 @@ ratchet baseline वा pass/fail नीति प्रयोग गर्छ ### उम्मेदवार स्वीकृति -CI र Quality Gates कार्यप्रवाहहरूले प्रत्येकले स्थिर निर्णय उत्सर्जन गर्छन्: `Gate / CI` र -`Gate / Quality`। तिनको संस्करणबद्ध स्वीकृति नीतिले प्रत्येक अपस्ट्रिम कार्यलाई -आवश्यक वा परामर्शात्मकका रूपमा सूचीकृत गर्छ। लागू हुने आवश्यक कार्य सफल हुनैपर्छ: हराएका, -रद्द गरिएका, छोडिएका, विचाराधीन र अज्ञात नतिजाहरूले PASS स्थापित गर्न सक्दैनन्। मान्य -docs-only वा catalog-only वर्गीकरणले कोड लेनलाई अनुपयुक्त बनाउन सक्छ; +CI र Quality Gates कार्यप्रवाहहरू प्रत्येकले स्थिर निर्णय उत्सर्जन गर्छन्: `Gate / CI` र +`Gate / Quality`। तिनको संस्करणीकृत स्वीकृति नीतिले प्रत्येक अपस्ट्रिम जबलाई +आवश्यक वा परामर्शात्मकका रूपमा सूचीबद्ध गर्छ। लागू हुने आवश्यक जब सफल हुनैपर्छ: हराएका, +रद्द गरिएका, स्किप गरिएका, विचाराधीन र अज्ञात परिणामहरूले PASS स्थापित गर्न सक्दैनन्। वैध +docs-only वा catalog-only वर्गीकरणले कोड लेनलाई लागू नहुने बनाउन सक्छ; ड्राफ्ट PR स्वीकृत उम्मेदवार होइन। `hotfix` लेबलले प्रमाणको आवश्यकता हटाउँदैन। -दुवै कार्यप्रवाहले PR हरू र main/release शाखाहरूमा हुने पुशहरू, म्यानुअल डिस्प्याच र -मर्ज-समूह घटनाहरू समेट्छन्। पुश, डिस्प्याच र मर्ज-समूहले पूर्ण छनोट चलाउँछन्। फोर्कहरू -र मर्ज समूहहरूले अन्यथा self-hosted रनरहरू चयन गर्ने कार्यहरूका लागि hosted रनरहरू -प्रयोग गर्छन्; रोलआउटअघि पर्याप्त hosted क्षमता प्रमाणित गर्नुपर्छ। +दुवै कार्यप्रवाहले PR हरू र main/release शाखाहरूमा हुने पुश, म्यानुअल डिस्प्याच र +merge-group इभेन्टहरू समेट्छन्। पुश, डिस्प्याच र merge-group ले पूर्ण चयन चलाउँछन्। फोर्कहरू +र merge group हरूले अन्यथा self-hosted रनर चयन गर्ने जबहरूका लागि hosted रनर प्रयोग गर्छन्; +रोलआउटअघि पर्याप्त hosted क्षमता प्रमाणित गरिनुपर्छ। प्रत्येक JSON रसिदले चेकआउट गरिएको SHA, कार्यप्रवाह रन र प्रयास पहिचान गर्छ। -CLI ले checkout/event SHA बेमेल अस्वीकार गर्छ। कार्यप्रवाह परीक्षणहरूले नीति सदस्यतालाई -निर्णय कार्यको `needs` सूचीसँग बाँध्छन्, ताकि नयाँ वा हटाइएको लेन चुपचाप हराउन नसकोस्। -रसिदहरूले आफ्नै कार्यप्रवाह समेट्छन्, प्रकाशन, परिनियोजन वा विद्यमान परामर्शात्मक -स्क्यानरका आन्तरिक पक्षहरू होइनन्। शाखा नियमहरूमा दुवै जाँच नाम सक्रिय गर्नु छुट्टै -प्रशासनिक परिवर्तन हो; यी कार्यहरू थप्दैमा शाखा आफैं सुरक्षित हुँदैन। +CLI ले checkout/event SHA बेमेललाई अस्वीकार गर्छ। कार्यप्रवाह परीक्षणहरूले नीति सदस्यतालाई +निर्णय जबको `needs` सूचीसँग बाँध्छन्, ताकि नयाँ वा हटाइएको लेन चुपचाप हराउन नसकोस्। +रसिदहरूले आफ्नै कार्यप्रवाह समेट्छन्, प्रकाशन, डिप्लोयमेन्ट वा विद्यमान परामर्शात्मक +स्क्यानरका आन्तरिक पक्षहरू होइनन्। शाखा नियमहरूमा दुवै चेक नाम सक्रिय गर्नु छुट्टै +प्रशासनिक परिवर्तन हो; यी जबहरू थप्दैमा शाखा आफैँ सुरक्षित हुँदैन। ### स्थिर स्क्यान सूची -संस्करणबद्ध npm-alias सूची र static-scan सदस्यता -`config/quality/gate-manifest.json` मा रहन्छन्। स्क्रिप्ट नामहरू र ठ्याक्कै मिल्ने आदेशहरू -`package.json` सँग प्रमाणीकरण गर्न `npm run check:gate-manifest` चलाउनुहोस्; थप, हटाइ र -आदेशमा आएको विचलनले स्थानीय हुक र CI का परिवर्तन-वर्गीकरण कार्यहरू दुवैलाई असफल बनाउँछ। -एउटा alias कार्यप्रवाह कार्य, matrix instance वा परीक्षण केस होइन: यी गणनाहरूलाई +संस्करणीकृत npm-alias सूची र स्थिर-स्क्यान सदस्यता +`config/quality/gate-manifest.json` मा छन्। स्क्रिप्ट नामहरू र ठ्याक्कै मिल्ने कमाण्डहरू +`package.json` विरुद्ध प्रमाणीकरण गर्न `npm run check:gate-manifest` चलाउनुहोस्; थपाइ, हटाइ र +कमाण्ड विचलनले स्थानीय हुक र CI का परिवर्तन-वर्गीकरण जबहरू दुवैलाई असफल बनाउँछन्। +एउटा alias कार्यप्रवाह जब, matrix instance वा test case होइन: यी गणनाहरूलाई परस्पर साट्न मिल्ने रूपमा प्रस्तुत गर्नु हुँदैन। -चयन गरिएका aliases लाई कार्यान्वयन नगरी निरीक्षण गर्न -`npm run quality:scan -- --list` वा `npm run quality:scan:fast -- --list` प्रयोग गर्नुहोस्। -रनरले npm entrypoint आह्वान गर्छ, त्यसैले यसको runtime (कन्फिगर गरिएको ठाउँमा Bun सहित) -संरक्षित रहन्छ। manifest ले ती प्रोफाइलबाहिरका aliases लाई छुट्टै आह्वान गरिने रूपमा -अभिलेख गर्छ, र read-only scan प्रोफाइलहरूमा मर्मतसम्भार आदेशहरू निषेधित छन्। - -यी प्रोफाइलहरूले static scan मात्र समेट्छन्। तिनले उत्पादन परीक्षण, coverage, packaging, -बाह्य जाँचहरू वा उम्मेदवारको पूर्ण release acceptance प्रमाणित गर्दैनन्। -कार्यप्रवाह स्वीकृतिले लिङ्क गरिएको `config/quality/admission-policy.json` र -`scripts/quality/admission-verdict.mjs` प्रयोग गर्छ। Release-observer प्रोफाइलहरू अलग नै रहन्छन्; -तिनका लागू हुने जाँचहरू र रसिदहरू स्वतन्त्र रूपमा निरीक्षण गर्नुहोस्। तलको गद्य +चयनित alias हरू कार्यान्वयन नगरी निरीक्षण गर्न `npm run quality:scan -- --list` वा +`npm run quality:scan:fast -- --list` प्रयोग गर्नुहोस्। रनरले +npm entrypoint आह्वान गर्छ, त्यसैले यसको runtime (कन्फिगर गरिएको ठाउँमा Bun सहित) सुरक्षित रहन्छ। +manifest ले ती प्रोफाइलहरू बाहिरका alias हरूलाई छुट्टै आह्वान गरिने रूपमा अभिलेख गर्छ, र +read-only scan profile हरूमा maintenance command हरू निषेधित छन्। + +यी प्रोफाइलहरूले स्थिर स्क्यान मात्र समेट्छन्। तिनले product test, +coverage, packaging, external check वा उम्मेदवारको पूर्ण release acceptance प्रमाणित गर्दैनन्। +कार्यप्रवाह स्वीकृतिले लिङ्क गरिएका `config/quality/admission-policy.json` र +`scripts/quality/admission-verdict.mjs` प्रयोग गर्छ। Release-observer profile हरू अलग रहन्छन्; +तिनका लागू हुने चेक र रसिदहरू स्वतन्त्र रूपमा निरीक्षण गर्नुहोस्। तलको गद्य सूची सन्दर्भ हो, गेट वास्तवमै चलेको प्रमाण होइन। -स्क्रिप्टहरू `scripts/check/` (नीति गेटहरू) र `scripts/quality/` (ratchet engine) अन्तर्गत रहन्छन्। +स्क्रिप्टहरू `scripts/check/` (नीति गेटहरू) र `scripts/quality/` (ratchet engine) अन्तर्गत छन्। CI को आधिकारिक स्रोत `.github/workflows/ci.yml` हो। -### Release PR द्रुत-पथ (`quality.yml`) +### रिलीज PR द्रुत-पथ (`quality.yml`) -`.github/workflows/quality.yml` ले main/release PR हरू, सुरक्षित-शाखा पुशहरू, -डिस्प्याच र मर्ज समूहहरूमा CI लाई पूरक बनाउँछ। PR हरूले path-filtered द्रुत जाँचहरू प्रयोग गर्छन्। -स्थायी रूपमा निष्क्रिय गरिएको दोहोरो build हटाइएको छ; वास्तविक build/package/boot जाँचहरू CI मै रहन्छन्। +`.github/workflows/quality.yml` ले main/release PR हरू, protected-branch +पुशहरू, डिस्प्याच र merge group हरूमा CI लाई पूरक बनाउँछ। PR हरूले path-filtered द्रुत चेकहरू प्रयोग गर्छन्। स्थायी रूपमा +निष्क्रिय पारिएको दोहोरो build हटाइएको छ; वास्तविक build/package/boot चेकहरू CI मै रहन्छन्। -| कार्य | कार्यक्षेत्र | अवरोधक | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | Docs/code PR हरू; API docs refs र docs-all | हो | -| `Fast Quality Gates` | Code PR हरू; static checks, typecheck, dashboard typecheck, प्रभावित unit tests | हो | -| `Forgotten sibling tests` | Code PR हरू; परिवर्तन गरिएका modules लाई static consumers र सम्भावित sibling tests सम्म ट्रेस गरिन्छ; barrel र dynamic-import paths लाई सन्दर्भित allowlist exceptions सहित परामर्शात्मक निदानका रूपमा रिपोर्ट गरिन्छ | **परामर्शात्मक** | -| `Vitest (fast-path)` | Code PR हरू; द्रुत vitest suite | हो | -| `Unit Tests fast-path` | Code PR हरू; 4-shard unit suite | हो | -| `No new ESLint warnings` | Code PR हरू; suppressions-aware lint guard | हो, forks सहित | -| `Merge integrity (changelog + generated skills)` | Non-draft PR हरू; changelog र generated skill sync | हो, forks सहित | +| जब | दायरा | अवरोधक | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `Docs Gates (fast-path)` | Docs/code PR हरू; API docs refs र docs-all | हो | +| `Fast Quality Gates` | Code PR हरू; स्थिर चेकहरू, typecheck, dashboard typecheck, प्रभावित unit test हरू | हो | +| `Forgotten sibling tests` | Code PR हरू; परिवर्तन गरिएका मोड्युलहरूबाट static consumer र सम्भावित sibling test हरूसम्म ट्रेस गरिन्छ; barrel र dynamic-import path हरूलाई सन्दर्भित allowlist अपवादहरूसहित परामर्शात्मक diagnostic का रूपमा रिपोर्ट गरिन्छ | **परामर्शात्मक** | +| `Vitest (fast-path)` | Code PR हरू; द्रुत vitest suite | हो | +| `Unit Tests fast-path` | Code PR हरू; 4-shard unit suite | हो | +| `No new ESLint warnings` | Code PR हरू; suppression-aware lint guard | हो, fork हरू सहित | +| `Merge integrity (changelog + generated skills)` | Non-draft PR हरू; changelog र generated skill sync | हो, fork हरू सहित | -#### बिर्सिएका sibling tests को रिपोर्ट +#### बिर्सिएका sibling test हरूको रिपोर्ट `npm run check:forgotten-sibling-tests` ले test-impact map पछाडिको import resolver पुनः प्रयोग गर्छ। -परिवर्तन गरिएको प्रत्येक production module का लागि, सम्भावित -test pull-request diff मा अनुपस्थित हुँदा यसले निर्धारणात्मक +प्रत्येक परिवर्तन गरिएको production module का लागि, pull-request diff मा candidate +test नभएको अवस्थामा यसले निर्धारणात्मक `changed module/symbol -> static consumer -> candidate sibling test` शृङ्खलाहरू रिपोर्ट गर्छ। -कुनै पनि अवरोधक rollout अघि calibration का लागि Markdown सारांश र JSON नतिजालाई -`forgotten-sibling-tests` कार्यप्रवाह artifact का रूपमा सुरक्षित राखिन्छ। +Markdown सारांश र JSON परिणाम कुनै पनि blocking rollout अघि calibration का लागि +`forgotten-sibling-tests` workflow artifact का रूपमा सुरक्षित राखिन्छन्। -Barrel पुनः-निर्यातहरू र गतिशील आयातहरू केवल रिजोल्युसन निदान हुन्; तिनले कहिल्यै -अवरोधक निष्कर्ष सिर्जना गर्दैनन्। समीक्षा गरिएका अपवादहरू -`config/quality/forgotten-sibling-allowlist.json` मा रहन्छन्। प्रत्येक प्रविष्टिले उपभोक्ता र उम्मेदवार -परीक्षणको नाम उल्लेख गर्नुपर्छ, विशिष्ट औचित्य दिनुपर्छ, र GitHub issue वा pull request को लिङ्क दिनुपर्छ। त्रुटिपूर्ण प्रविष्टिहरू -बन्द अवस्थामै असफल हुन्छन्। अपवादहरूले मेटाइएको उम्मेदवार परीक्षण वा `.skip`/`.todo` थप्ने diff लाई दबाउन सक्दैनन्; -assertion कमजोर पार्ने र अन्य masking स्वतन्त्र रूपमा अवरोध गर्ने -`check:test-masking` gate कै जिम्मेवारीमा रहन्छन्। +Barrel पुनः-निर्यातहरू र dynamic imports समाधानसम्बन्धी निदान मात्र हुन्; तिनले कहिल्यै +अवरोधक finding सिर्जना गर्दैनन्। समीक्षा गरिएका अपवादहरू +`config/quality/forgotten-sibling-allowlist.json` मा रहन्छन्। प्रत्येक प्रविष्टिले consumer र candidate +test को नाम उल्लेख गर्नुपर्छ, विशिष्ट औचित्य दिनुपर्छ, र GitHub issue वा pull request मा लिङ्क गर्नुपर्छ। विकृत प्रविष्टिहरू +बन्द अवस्थामा असफल हुन्छन्। अपवादहरूले मेटाइएको candidate test वा `.skip`/`.todo` थप्ने diff लाई दबाउन सक्दैनन्; +assertion कमजोर पार्ने र अन्य masking कार्यहरू स्वतन्त्र रूपमा अवरोध गर्ने +`check:test-masking` gate कै अधीनमा रहन्छन्। ### Job: `lint` -`main` तर्फको प्रत्येक PR मा चल्छ। असफल भएमा merge रोक्छ। - -| Script (`npm run ...`) | प्रमाणीकरण गर्छ | अवरोधक | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | -| `check:node-runtime` | Node.js को संस्करण समर्थित दायराभित्र छ | हो | -| `check:cycles` | चक्रीय आयातहरू — सबै `src/` + `open-sse/` मोड्युलहरू | हो | -| `check:route-validation:t06` | सबै routes मा Zod schemas उपस्थित छन् (Tier 6 नीति) | हो | -| `check:any-budget:t11` | `@ts-expect-error // any` को सङ्ख्याले बजेट नाघ्दैन (Tier 11 catraca) | हो | -| `check:provider-consistency` | `providers.ts` मा भएका प्रत्येक provider सँग `providerRegistry.ts` मा मिल्दो entry छ (र allowlist भित्र यसको उल्टो पनि सत्य छ) | हो | -| `check:model-lifecycle` | हातैले मर्मत गरिएका तीनवटा routing table हरू checked-in lifecycle snapshot (#11503) सँग एकरूप रहन्छन्: `FITNESS_TABLE` (`taskFitness.ts`) ले `REGISTRY` ले route गर्न सक्ने कुनै पनि retired id लाई score गर्दैन; प्रत्येक `BUILT_IN_ALIASES` target `REGISTRY` मा उपस्थित र retired-id snapshot मा अनुपस्थित छ; `REGISTRY` मा अझै रहेको प्रत्येक retired id लाई forward गरिएको छ वा `allowedRetiredInCatalog` मा सूचीबद्ध गरिएको छ; र कुनै पनि `DEFAULT_DEGRADATION_MAP` source वा target उक्त snapshot मा retired देखिँदैन। यसले कुनै model हाल live upstream द्वारा उपलब्ध गराइएको छ भन्ने प्रमाणित गर्दैन। Offline — `config/quality/model-lifecycle.json` सँग तुलना गर्छ, जसलाई `npm run quality:refresh-model-lifecycle` (network; CI मा जडान गरिएको छैन) मार्फत हातैले refresh गरिन्छ। `allowedRetiredInCatalog` एउटा burn-down ratchet हो: tracking issue भएको अवस्थामा मात्र entry थप्नुहोस्। | हो | -| `check:fetch-targets` | client-side `src/` मा भएका प्रत्येक `fetch("/api/...")` वास्तविक `route.ts` मा resolve हुन्छन् | हो | -| `check:deps` | repo का प्रत्येक `package.json` मा रहेका सबै `npm install` गर्न मिल्ने deps `dependency-allowlist.json` मा छन्; नयाँ unpinned वा slopsquatted packages लाई flag गरिन्छ | हो | -| `audit:deps` | `npm audit` (root + electron) — कुनै high/critical advisories छैनन् (osv `check:vuln-ratchet` सँग overlap हुन्छ; Rationalization Backlog हेर्नुहोस्) | हो | -| `check:lockfile` | `package-lock.json` को integrity — https registry, integrity hashes, कुनै host overrides छैनन् | हो | -| `check:licenses` | उत्पादन निर्भरताहरूका लागि SPDX इजाजतपत्र अनुमति-सूची | हो | -| `check:tracked-artifacts` | कुनै बिल्ड आर्टिफ्याक्ट / कमिट गरिएका `node_modules` सिमलिङ्कहरू छैनन् (husky pre-commit मा पनि चल्छ; pre-push जानाजानी हल्का राखिएको छ — #6716) | हो | -| `check:ai-attribution` | PR कमिटहरू, शीर्षक वा मुख्य भागमा कुनै AI/bot `Co-Authored-By` ट्रेलर वा AI-जेनेरेसन फुटर छैन — कठोर नियम #16 (`quality.yml` को PR→`release/**` का लागि fast-gates लूपमा — इभेन्ट पेलोड पढ्छ, PR बाहिर कुनै कार्य गर्दैन — र `ci.yml` lint मा PR→`main` का लागि PR-मात्र चरण; साथै husky `commit-msg` हुक; मानव सह-लेखकहरूलाई अनुमति छ; #14436) | -| `check:vitest-exclusions` | प्रत्येक Vitest बहिष्करणले ट्र्याकिङ इश्यू उल्लेख गर्छ र `config/quality/vitest-exclusions.json` मा देखिन्छ (#13204) | हो | -| `check:file-size` | कुनै पनि स्रोत फाइलले प्रति-एक्सटेन्सन सीमा नाघ्दैन (र्याचेट: `frozen` सूचीमा स्थिर गरिएका ठूला फाइलहरू) | हो | -| `check:error-helper` | executors/handlers का त्रुटि प्रतिक्रियाहरूले `buildErrorBody()` / `sanitizeErrorMessage()` प्रयोग गर्छन् (कठोर नियम #12) | हो | -| `check:migration-numbering` | Migration SQL फाइलहरू कुनै खाली क्रम वा दोहोरो नम्बरबिना क्रमिक रूपमा नम्बर गरिएका छन् | हो | -| `check:public-creds` | `publicCreds.ts` बाहिर कुनै पनि शाब्दिक OAuth `client_id`/`client_secret` वा Firebase Web कुञ्जीहरू छैनन् (कडा नियम #11) | हो | -| `check:db-rules` | `src/lib/db/` मोड्युलहरू बाहिर कुनै कच्चा SQL छैन; `localDb.ts` बाट कुनै barrel-imports छैनन् (कडा नियमहरू #2/#5) | हो | -| `check:known-symbols` | आफ्ना dispatch tables मा दर्ता भएका provider executors, routing strategies, र translators डिस्कमा भएका फाइलहरूसँग मेल खान्छन् — कुनै अनाथ वा अघोषित symbols छैनन् | हो | -| `check:route-guard-membership` | child process सुरु गर्ने प्रत्येक route लाई `isLocalOnlyPath()` द्वारा वर्गीकृत गरिएको छ (कडा नियमहरू #15/#17) | हो | -| `check:test-discovery` | repo मा भएका प्रत्येक `*.test.ts` / `*.spec.ts` फाइल कम्तीमा एउटा test runner द्वारा सङ्कलित हुन्छ (`test-discovery-baseline.json` मा रहेको orphan list केवल घट्न सक्छ) | हो | -| `check:agent-skills-sync` | उत्पन्न गरिएका agent-skills आर्टिफ्याक्टहरू तिनको स्रोत क्याटलगसँग मेल खान्छन् (कुनै विचलन छैन) | -| `check:provider-asset-provenance` | प्रदायकका लोगो/एसेटहरूमा अभिलेख गरिएको उत्पत्ति प्रविष्टि हुन्छ | -| `lint:json` | JSON कन्फिग फाइलहरू पार्स हुन्छन् र repo का lint नियमहरू पूरा गर्छन् | -| `typecheck:core` | त्रुटिबिनाको TypeScript कम्पाइलेसन (सल्लाहकारी चेतावनीहरू मात्र) | हो | -| `typecheck:noimplicit:core` | कडा `noImplicitAny` — भविष्य-उन्मुख; पहिलेबाट रहेका धेरै call site हरूलाई अझै annotation आवश्यक छ | **सल्लाहकारी** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` मा सीमित `tsc` (#7033) — `typecheck:core` को सावधानीपूर्वक चयन गरिएको 27-फाइल allowlist मा कुनै पनि dashboard TSX समावेश छैन, र `next build` ले पनि यसलाई कहिल्यै type-check गर्दैन (`next.config.mjs` ले `ignoreBuildErrors: true` सेट गर्छ), त्यसैले त्यहाँका orphaned-identifier regression हरू (#6625/#6909) CI का लागि अदृश्य थिए। स्थिर गरिएको प्रति-फाइल/प्रति-TS-code सङ्ख्या baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` कै जस्तो stale-enforcement ढाँचा) सँग diff गरिन्छ — baseline गरिएको सङ्ख्याभन्दा बढीका नयाँ त्रुटिहरूले मात्र gate असफल गराउँछन्; पहिलेबाट रहेको त्रुटि समाधान भएपछि `--update` प्रयोग गरेर सीमा क्रमशः घटाउनुहोस्। | हो | +`main` तर्फको प्रत्येक PR मा चल्छ। असफल भएमा merge अवरुद्ध गर्छ। + +| Script (`npm run ...`) | प्रमाणीकरण गर्ने कुरा | अवरोधक | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | Node.js को संस्करण समर्थित दायराभित्र छ | हो | +| `check:cycles` | सम्पूर्ण `src/` + `open-sse/` मा रहेका circular imports (AST-आधारित, tsconfig का `paths` समाधान गरिएका)। Bare = परामर्शात्मक, cycles को सूची देखाउँछ। `check:cycles:ratchet` (CI ले चलाउने) ले गणना `quality-baseline.json` मा रहेको `metrics.cycles` को अधिकतम सीमाभन्दा बढी हुँदा अवरुद्ध गर्छ — हाल 14, `direction: down`, त्यसैले यो घट्न मात्र सक्छ (#15159 G-01/G-02) | हो (ratchet) | +| `check:route-validation:t06` | सबै routes मा Zod schemas उपस्थित छन् (Tier 6 नीति) | हो | +| `check:any-budget:t11` | `@ts-expect-error // any` को गणना budget भन्दा बढी हुँदैन (Tier 11 catraca) | हो | +| `check:provider-consistency` | `providers.ts` मा रहेको प्रत्येक प्रदायकको `providerRegistry.ts` मा मिल्दो प्रविष्टि छ (र यसको उल्टो पनि, अनुमति सूचीभित्र) | हो | +| `check:model-lifecycle` | हातैले मर्मत गरिने तीनवटा राउटिङ तालिकाहरू चेक-इन गरिएको जीवनचक्र स्न्यापसट (#11503) सँग सुसंगत रहन्छन्: `FITNESS_TABLE` (`taskFitness.ts`) ले `REGISTRY` ले राउट गर्न सक्ने कुनै पनि अवकाशप्राप्त id लाई स्कोर गर्दैन; प्रत्येक `BUILT_IN_ALIASES` लक्ष्य `REGISTRY` मा उपस्थित र अवकाशप्राप्त-id स्न्यापसटमा अनुपस्थित हुन्छ; `REGISTRY` मा अझै रहेका प्रत्येक अवकाशप्राप्त id लाई फर्वार्ड गरिएको वा `allowedRetiredInCatalog` मा सूचीबद्ध गरिएको हुन्छ; र कुनै पनि `DEFAULT_DEGRADATION_MAP` स्रोत वा लक्ष्य उक्त स्न्यापसटमा अवकाशप्राप्त देखिँदैन। यसले कुनै मोडेल हाल प्रत्यक्ष अपस्ट्रिमद्वारा उपलब्ध गराइएको छ भन्ने प्रमाणित गर्दैन। अफलाइन — `config/quality/model-lifecycle.json` सँग तुलना गर्छ, जसलाई `npm run quality:refresh-model-lifecycle` (नेटवर्क; CI मा जडान नगरिएको) मार्फत हातैले ताजा गरिन्छ। `allowedRetiredInCatalog` क्रमशः घटाउँदै लैजाने र्याचेट हो: ट्र्याकिङ इश्युसहित मात्र प्रविष्टि थप्नुहोस्। | हो | +| `check:fetch-targets` | क्लाइन्ट-साइड `src/` मा रहेको प्रत्येक `fetch("/api/...")` वास्तविक `route.ts` मा रिजोल्भ हुन्छ | हो | +| `check:deps` | रिपोजिटरीको प्रत्येक `package.json` मा रहेका सबै `npm install` गर्न मिल्ने निर्भरताहरू `dependency-allowlist.json` मा छन्; नयाँ पिन नगरिएका वा स्लपस्क्वाट गरिएका प्याकेजहरू चिन्ह लगाइन्छन् | हो | +| `audit:deps` | `npm audit` (रुट + electron) — कुनै उच्च/गम्भीर एडभाइजरी छैनन् (osv `check:vuln-ratchet` सँग ओभरल्याप हुन्छ; युक्तिसङ्गतीकरण ब्याकलग हेर्नुहोस्) | हो | +| `check:lockfile` | `package-lock.json` को अखण्डता — https रजिस्ट्री, अखण्डता ह्यासहरू, कुनै होस्ट ओभरराइड छैन | हो | +| `check:licenses` | उत्पादन निर्भरताहरूका लागि SPDX इजाजतपत्र अनुमति-सूची | हो | +| `check:tracked-artifacts` | कुनै बिल्ड आर्टिफ्याक्ट / कमिट गरिएका `node_modules` सिमलिङ्कहरू छैनन् (husky pre-commit मा पनि चल्छ; pre-push लाई जानाजानी हल्का राखिएको छ — #6716) | हो | +| `check:ai-attribution` | PR कमिटहरू, शीर्षक वा मुख्य सामग्रीमा कुनै AI/bot `Co-Authored-By` ट्रेलर वा AI-उत्पादन फुटर छैन — कडा नियम #16 (`quality.yml` को PR→`release/**` का लागि fast-gates लूपमा — इभेन्ट पेलोड पढ्छ, PR बाहिर कुनै कार्य गर्दैन — र `ci.yml` lint मा PR→`main` का लागि PR-मात्र चरण; साथै husky `commit-msg` हुक; मानव सह-लेखकहरूलाई अनुमति छ; #14436) | +| `check:vitest-exclusions` | प्रत्येक Vitest बहिष्करणले ट्र्याकिङ समस्या उल्लेख गर्छ र `config/quality/vitest-exclusions.json` मा देखा पर्छ (#13204) | हो | +| `check:file-size` | कुनै पनि स्रोत फाइलले प्रत्येक एक्सटेन्सनको सीमा नाघ्दैन (र्याचेट: `frozen` सूचीमा स्थिर गरिएका ठूला फाइलहरू) | हो | +| `check:error-helper` | executors/handlers का त्रुटि प्रतिक्रियाहरूले `buildErrorBody()` / `sanitizeErrorMessage()` प्रयोग गर्छन् (कडा नियम #12) | हो | +| `check:migration-numbering` | Migration SQL फाइलहरू क्रमिक रूपमा नम्बर गरिएका छन्, कुनै खाली क्रम वा दोहोरिएका नम्बरहरू छैनन् | हो | +| `check:public-creds` | `publicCreds.ts` बाहिर कुनै पनि प्रत्यक्ष OAuth `client_id`/`client_secret` वा Firebase Web कुञ्जीहरू छैनन् (कडा नियम #11) | हो | +| `check:db-rules` | `src/lib/db/` मोड्युलहरू बाहिर कुनै पनि कच्चा SQL छैन; `localDb.ts` बाट कुनै पनि ब्यारेल-इम्पोर्ट छैन (कडा नियमहरू #2/#5) | हो | +| `check:known-symbols` | आफ्ना डिस्प्याच तालिकाहरूमा दर्ता गरिएका प्रदायक एक्जिक्युटरहरू, राउटिङ रणनीतिहरू र अनुवादकहरू डिस्कमा रहेका फाइलहरूसँग मेल खान्छन् — कुनै पनि अनाथ वा अघोषित सिम्बलहरू छैनन् | हो | +| `check:route-guard-membership` | चाइल्ड प्रोसेस सुरु गर्ने प्रत्येक रुटलाई `isLocalOnlyPath()` द्वारा वर्गीकृत गरिएको छ (कडा नियमहरू #15/#17) | हो | +| `check:test-discovery` | रिपोजिटरीमा रहेको प्रत्येक `*.test.ts` / `*.spec.ts` फाइल कम्तीमा एउटा टेस्ट रनरद्वारा सङ्कलन गरिन्छ (र्याचेट: `test-discovery-baseline.json` मा रहेको अनाथ सूची घट्न मात्र सक्छ) | हो | +| `check:agent-skills-sync` | उत्पन्न गरिएका agent-skills आर्टिफ्याक्टहरू तिनको स्रोत क्याटलगसँग मेल खान्छन् (कुनै विचलन छैन) | +| `check:provider-asset-provenance` | प्रदायकका लोगो/एसेटहरूमा अभिलेख गरिएको उत्पत्ति प्रविष्टि हुन्छ | +| `lint:json` | JSON कन्फिग फाइलहरू पार्स हुन्छन् र repo का lint नियमहरू पूरा गर्छन् | +| `typecheck:core` | त्रुटिविनाको TypeScript कम्पाइलेसन (सल्लाहात्मक चेतावनीहरू मात्र) | हो | +| `typecheck:noimplicit:core` | कडा `noImplicitAny` — भविष्य-उन्मुख; पहिलेबाट रहेका धेरै call site हरूलाई अझै annotation आवश्यक छ | **सल्लाहात्मक** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` मा सीमित `tsc` (#7033) — `typecheck:core` को चयनित 27-फाइल allowlist मा कुनै पनि dashboard TSX समावेश छैन, र `next build` ले पनि यसलाई कहिल्यै type-check गर्दैन (`next.config.mjs` ले `ignoreBuildErrors: true` सेट गर्छ), त्यसैले त्यहाँका orphaned-identifier regression हरू (#6625/#6909) CI का लागि अदृश्य थिए। स्थिर गरिएको प्रति-फाइल/प्रति-TS-code सङ्ख्या baseline (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` कै जस्तो stale-enforcement ढाँचा) सँग diff गरिन्छ — baseline मा रहेको सङ्ख्याभन्दा बढीका नयाँ त्रुटिहरूले मात्र gate असफल गराउँछन्; पहिलेबाट रहेको त्रुटि समाधान हुँदा `--update` प्रयोग गरेर क्रमशः घटाउनुहोस्। | हो | ### Job: `quality-gate` `test-coverage` पछि चल्छ। असफल भएमा merge रोक्छ। -| स्क्रिप्ट | प्रमाणीकरण गर्छ | अवरोधक | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | `quality-metrics.json` उत्सर्जन गर्छ (ESLint चेतावनी सङ्ख्या, मर्ज गरिएको shard रिपोर्टबाट coverage) | हो (ratchet भन्दा अगाडि) | -| `quality:ratchet` | `quality-baseline.json` को प्रत्येक metric पछाडि परेको छैन (ESLint चेतावनीहरू ≤ baseline; coverage ≥ baseline) | हो | -| `check:duplication` | कोड दोहोरोपन (jscpd@4) ले `quality-baseline.json` को baseline नाघ्दैन | हो | -| `check:complexity` | फाइल-स्तरीय cyclomatic complexity ले सीमा नाघ्दैन (मुख्य ESLint `complexity` + `max-lines-per-function`) | हो | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — छुट्टै ESLint pass; CI ले दुवैलाई एउटै `check:complexity-ratchets` चरणका रूपमा मर्ज गरेर चलाउँछ | हो | -| `check:dead-code` | प्रयोग नगरिएका exports / files को ratchet (knip) baseline को तुलनामा पछाडि पर्दैन | हो | -| `check:compression-budget` | Compression benchmark budget — प्रति-engine token-savings का न्यूनतम सीमाहरू पछाडि पर्नु हुँदैन | हो | -| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) पछाडि पर्दैन; यसले धेरै हदसम्म `typecheck:noimplicit:core` लाई समेट्छ | हो | -| `check:codeql-ratchet` | खुला CodeQL alert सङ्ख्या पछाडि पर्दैन (`gh api` मार्फत पढ्छ; token बिना सुचारु रूपमा skip गर्छ) — refresh cadence र manual trigger का लागि: तलको "CodeQL ratchet" हेर्नुहोस् | हो | - -### कार्य: `quality-extended` - -सम्पूर्ण कार्य परामर्शात्मक हो (`continue-on-error: true`)। npm-आधारित ratchets वास्तविक रूपमा -चल्छन्; बाह्य scanners हरू `gh release download` मार्फत स्थापना हुन्छन् र binary अझै अनुपस्थित हुँदा +| स्क्रिप्ट | प्रमाणीकरण गर्छ | अवरोधक | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `quality:collect` | `quality-metrics.json` उत्सर्जन गर्छ (ESLint चेतावनी सङ्ख्या, मर्ज गरिएको shard रिपोर्टबाट coverage) | हो (ratchet भन्दा अघिल्लो) | +| `quality:ratchet` | `quality-baseline.json` मा भएको प्रत्येक metric खस्किएको छैन (ESLint चेतावनीहरू ≤ baseline; coverage ≥ baseline) | हो | +| `check:duplication` | कोड दोहोरोपन (jscpd@4) ले `quality-baseline.json` को baseline नाघ्दैन | हो | +| `check:complexity` | फाइल-स्तरीय cyclomatic complexity ले सीमा नाघ्दैन (core ESLint `complexity` + `max-lines-per-function`) | हो | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — छुट्टै ESLint pass; CI ले दुवैलाई एकल `check:complexity-ratchets` चरणका रूपमा मर्ज गरेर चलाउँछ | हो | +| `check:dead-code` | प्रयोग नगरिएका exports / files ratchet (knip) baseline को तुलनामा खस्किँदैन | हो | +| `check:compression-budget` | Compression benchmark budget — प्रति-engine token-savings का न्यूनतम सीमाहरू खस्किनु हुँदैन | हो | +| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) खस्किँदैन; यसले धेरै हदसम्म `typecheck:noimplicit:core` लाई समेट्छ | हो | +| `check:codeql-ratchet` | खुला CodeQL alert सङ्ख्या खस्किँदैन (`gh api` मार्फत पढ्छ; token नभए सहज रूपमा skip गर्छ) — refresh cadence र manual trigger: तलको "CodeQL ratchet" हेर्नुहोस् | हो | + +### Job: `quality-extended` + +सम्पूर्ण job सल्लाहात्मक हो (`continue-on-error: true`)। npm-आधारित ratchets वास्तवमै +चल्छन्; बाह्य scanners `gh release download` मार्फत install हुन्छन् र binary अझै अनुपस्थित हुँदा आफैँ skip हुन्छन् (exit 0)। -| स्क्रिप्ट | प्रमाणीकरण गर्छ | अवरोधक | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| `check:circular-deps` | कुनै circular dependencies छैनन् (dpdm) | **परामर्शात्मक** | -| `check:bundle-size` | Bundle size ले सीमा नाघ्दैन | **परामर्शात्मक** | -| `check:secrets` | Secret scanning (gitleaks) — binary अनुपस्थित भए skip गर्छ | **परामर्शात्मक** | -| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) पछाडि पर्दैनन् — binary अनुपस्थित भए skip गर्छ | **परामर्शात्मक** | -| `check:workflows` | Workflow lint (actionlint + zizmor); अनुपस्थित/बिग्रिएका scanners, अमान्य reports वा अनुपस्थित ratchet baseline भए INCOMPLETE का रूपमा असफल हुन्छ। मान्य findings ले चयन गरिएको strict/advisory/ratchet policy पालना गर्छन् | कार्यान्वयन आवश्यक; CI मा zizmor ratchet अवरोधक | -| `check:openapi-breaking` | आधार शाखाको तुलनामा सार्वजनिक API contract (`openapi.yaml`) मा breaking changes (oasdiff) — `openapiBreaking=N` उत्सर्जन गर्छ; oasdiff अनुपस्थित भए वा base spec समाधान गर्न नसकिए skip गर्छ | **परामर्शात्मक** | - -### कार्य: `docs-sync-strict` - -`main` तर्फको प्रत्येक PR मा चल्छ। असफल भए merge हुनबाट रोक्छ। - -| स्क्रिप्ट | प्रमाणीकरण गर्ने विषय | अवरोधक | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | तलका ६ वटा उप-गेटलाई क्रमिक रूपमा चलाउने मेटा-गेट | हो | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt संस्करणको एकरूपता | हो | -| ↳ `check:docs-counts` | गद्यमा भएका सङ्ख्याहरू (प्रदायक सङ्ख्या, माइग्रेसन सङ्ख्या आदि) वास्तविक सङ्ख्याको र्याचेट सीमाभित्र छन् | हो | -| ↳ `check:env-doc-sync` | `.env.example` मा भएको प्रत्येक env var कागजातको तालिकामा अभिलेखित छ, र यसको उल्टो पनि सत्य छ | हो | -| ↳ `check:deprecated-versions` | कागजातमा बहिष्कृत संस्करण स्ट्रिङहरू छैनन् | हो | -| ↳ `check:doc-links` | कागजातमा भएका आन्तरिक markdown लिङ्कहरू वास्तविक फाइलहरूमा समाधान हुन्छन् (`[text]`/`(path)` ढाँचा) | हो | -| ↳ `check:fabricated-docs` | कागजातमा उल्लेख गरिएका रुट, env vars, CLI कमान्ड, hook नाम र फाइल पाथहरू कोडबेसमा अवस्थित छन्। `--strict` मार्फत कडा गेट; फ्ल्यागबिना सफ्ट-फेल। | हो (CI मा `--strict` मार्फत) | -| `check:cli-i18n` | CLI कमान्ड स्ट्रिङहरू सबै i18n locale फाइलहरूमा उपस्थित छन् | हो | -| `check:openapi-coverage` | OpenAPI spec ले वास्तविक रुटहरूको कम्तीमा र्याचेट गरिएको न्यूनतम सीमा समेट्छ | हो | -| `check:openapi-security-tiers` | `openapi.yaml` मा भएका सुरक्षा तहका एनोटेसनहरू `routeGuard.ts` का वर्गीकरणहरूसँग एकरूप छन् | **सल्लाहमूलक** | -| `check:openapi-routes` | `openapi.yaml` को प्रत्येक पाथ वास्तविक `route.ts` मा समाधान हुन्छ (भ्रमजन्य विवरण-विरोधी) | हो | -| `check:docs-symbols` | `docs/**/*.md` मा भएको प्रत्येक `/api/...` सन्दर्भ वास्तविक `route.ts` मा समाधान हुन्छ (भ्रमजन्य विवरण-विरोधी) | हो | -| `i18n translation drift` | i18n locale फाइलहरूमा अनुवाद नगरिएका key हरू — चेतावनी मात्र | **सल्लाहमूलक** | +| स्क्रिप्ट | प्रमाणीकरण गर्छ | अवरोधक | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `check:circular-deps` | कुनै circular dependencies छैनन् (dpdm) | **सल्लाहात्मक** | +| `check:bundle-size` | Bundle size ले सीमा नाघ्दैन | **सल्लाहात्मक** | +| `check:secrets` | Secret scanning (gitleaks) — binary अनुपस्थित भए skip गर्छ | **सल्लाहात्मक** | +| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) खस्किँदैनन् — binary अनुपस्थित भए skip गर्छ | **सल्लाहात्मक** | +| `check:workflows` | Workflow lint (actionlint + zizmor); हराएका/बिग्रिएका scanners, अमान्य reports वा हराएको ratchet baseline भए INCOMPLETE का रूपमा असफल हुन्छ। मान्य findings ले चयन गरिएको strict/advisory/ratchet policy पालना गर्छन् | कार्यान्वयन आवश्यक; CI मा zizmor ratchet अवरोधक | +| `check:openapi-breaking` | आधार branch को तुलनामा सार्वजनिक API contract (`openapi.yaml`) मा भएका breaking changes (oasdiff) — `openapiBreaking=N` उत्सर्जन गर्छ; oasdiff अनुपस्थित भए वा आधार spec resolve गर्न नसकिए skip गर्छ | **सल्लाहात्मक** | + +### Job: `docs-sync-strict` + +`main` तर्फको प्रत्येक PR मा चल्छ। असफल भए merge रोक्छ। + +| स्क्रिप्ट | प्रमाणीकरण | अवरोधक | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `check:docs-all` | तलका ६ उप-गेटहरू क्रमिक रूपमा चलाउने मेटा-गेट | हो | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt संस्करणको एकरूपता | हो | +| ↳ `check:docs-counts` | गद्यमा भएका सङ्ख्याहरू (प्रदायक सङ्ख्या, माइग्रेसन सङ्ख्या आदि) वास्तविक सङ्ख्याहरूको र्याचेट विन्डोभित्र छन् | हो | +| ↳ `check:env-doc-sync` | `.env.example` मा भएको प्रत्येक env var कागजातको तालिकामा अभिलेखित छ, र यसको उल्टो पनि सत्य छ | हो | +| ↳ `check:deprecated-versions` | कागजातमा कुनै बहिष्कृत संस्करण स्ट्रिङ छैन | हो | +| ↳ `check:doc-links` | कागजातभित्रका आन्तरिक markdown लिङ्कहरू वास्तविक फाइलहरूमा समाधान हुन्छन् (`[text]`/`(path)` ढाँचा) | हो | +| ↳ `check:fabricated-docs` | कागजातमा उल्लेख गरिएका रुट, env vars, CLI आदेश, हुक नाम र फाइल पथहरू कोडबेसमा अवस्थित छन्। `--strict` मार्फत हार्ड गेट; फ्ल्यागबिना सफ्ट-फेल। | हो (CI मा `--strict` मार्फत) | +| `check:cli-i18n` | CLI आदेशका स्ट्रिङहरू सबै i18n लोकेल फाइलमा उपस्थित छन् | हो | +| `check:openapi-coverage` | OpenAPI स्पेकले वास्तविक रुटहरूको कम्तीमा र्याचेट गरिएको न्यूनतम सीमा समेट्छ | हो | +| `check:openapi-security-tiers` | `openapi.yaml` मा भएका सुरक्षा तहका एनोटेसनहरू `routeGuard.ts` का वर्गीकरणहरूसँग एकरूप छन् | **परामर्शात्मक** | +| `check:openapi-routes` | `openapi.yaml` को प्रत्येक पथ वास्तविक `route.ts` मा समाधान हुन्छ (भ्रमित सिर्जना-विरोधी) | हो | +| `check:docs-symbols` | `docs/**/*.md` मा भएको प्रत्येक `/api/...` सन्दर्भ वास्तविक `route.ts` मा समाधान हुन्छ (भ्रमित सिर्जना-विरोधी) | हो | +| `i18n translation drift` | i18n लोकेल फाइलहरूमा अनुवाद नगरिएका कुञ्जीहरू — चेतावनी मात्र | **परामर्शात्मक** | ### कार्य: `i18n-ui-coverage` -| स्क्रिप्ट | प्रमाणीकरण गर्ने विषय | अवरोधक | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (इनलाइन) | UI i18n key कभरेज ≥ 65% छ | हो | -| `check-ui-value-drift` (इनलाइन) | पुनर्लेखन गरिएको अङ्ग्रेजी **मान** ले कुनै पुरानो अनुवाद बाँकी राख्दैन | हो | -| `check-new-key-coverage` (इनलाइन) | **नयाँ** अङ्ग्रेजी key प्रत्येक locale मा अनुवाद गरिएको छ — `__MISSING__:` मार्कर अस्वीकार गरिन्छ | हो | -| `check-translation-ratio` | प्रति locale वास्तविक-अनुवाद अनुपात (allowlist बाहिरका अङ्ग्रेजीसँग समान / placeholder / हराएका leaf हरू) `config/quality/i18n-translation-baseline.json` + slack भन्दा बढी हुनु हुँदैन | **सल्लाहमूलक** | +| स्क्रिप्ट | प्रमाणीकरण | अवरोधक | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `check-ui-keys-coverage` (इनलाइन) | UI i18n कुञ्जी कभरेज ≥ 65% छ | हो | +| `check-ui-value-drift` (इनलाइन) | पुनर्लेखन गरिएको अङ्ग्रेजी **मान** ले कुनै पुरानो अनुवाद बाँकी राख्दैन | हो | +| `check-new-key-coverage` (इनलाइन) | एउटा **नयाँ** अङ्ग्रेजी कुञ्जी प्रत्येक लोकेलमा अनुवाद गरिएको छ — `__MISSING__:` मार्कर अस्वीकार गरिन्छ | हो | +| `check-translation-ratio` | प्रत्येक लोकेलको वास्तविक-अनुवाद अनुपात (अनुमति सूचीबाहिरका अङ्ग्रेजीसँग समान / प्लेसहोल्डर / छुटेका पातहरू) `config/quality/i18n-translation-baseline.json` + छुटभन्दा बढी हुनु हुँदैन | **परामर्शात्मक** | -`fetch-depth: 0` आवश्यक पर्छ — value-drift गेटले `en.json` लाई merge base सँग diff गर्छ। +`fetch-depth: 0` आवश्यक पर्छ — मान-ड्रिफ्ट गेटले मर्ज बेससँग `en.json` को diff गर्छ। #### `check-ui-value-drift` — पुरानो-अनुवाद गेट -अन्य गेटहरूले संरचनात्मक रूपमा देख्न नसक्ने एउटा i18n regression यसले समात्छ: अङ्ग्रेजी मान -पुनर्लेखन गरिन्छ र _अघिल्लो_ अङ्ग्रेजीबाट व्युत्पन्न अनुवादहरू यथावत् रहन्छन्, जसले गर्दा -गैर-अङ्ग्रेजी प्रयोगकर्ताहरूले आत्मविश्वासपूर्ण शैलीमा लेखिएको तर अहिले गलत भइसकेको पाठ पढिरहन्छन्। +यसले एउटा यस्तो i18n रिग्रेसन समात्छ जुन अन्य गेटहरूले संरचनात्मक रूपमा देख्न सक्दैनन्: कुनै अङ्ग्रेजी मान +पुनर्लेखन गरिन्छ र _अघिल्लो_ अङ्ग्रेजीबाट व्युत्पन्न अनुवादहरू यथावत् रहन्छन्, जसका कारण +गैर-अङ्ग्रेजी प्रयोगकर्ताहरूले आत्मविश्वासपूर्ण भाषामा लेखिएको तर अहिले गलत प्रतिलिपि पढिरहन्छन्। -यो समस्या वास्तवमै जारी गरिएको थियो। Antigravity लगइन helper थपिँदा (#5203) -`oauthModal.googleOAuthWarning` पुनर्लेखन गरिएको थियो; **४३ मध्ये ३९ locale** मा अपरेटरहरूलाई -"पूरा URL प्रतिलिपि गरेर तल टाँस्नुहोस्" भन्ने पाठ कायम रह्यो — त्यो प्रदायकका लागि पूरा हुनै नसक्ने प्रक्रिया। -यो #8463 सम्म ध्यानमा आएन, किनभने: +यो समस्या वास्तवमै रिलिज भएको थियो। Antigravity लगइन सहायक आएपछि (#5203) +`oauthModal.googleOAuthWarning` पुनर्लेखन गरिएको थियो; **४३ मध्ये ३९ लोकेलहरूमा** सञ्चालकहरूलाई "पूरै URL प्रतिलिपि गरेर तल टाँस्नुहोस्" भन्ने पाठ यथावत् रह्यो — त्यो प्रदायकका लागि पूरा हुनै नसक्ने प्रवाह। यो +#8463 सम्म ध्यानमा आएन, किनभने: -- `sync-ui-keys` ले **अनुपस्थित** key हरू मात्र backfill गर्छ, **पुराना** key हरू कहिल्यै गर्दैन; -- `check-ui-keys-coverage` ले key को _उपस्थिति_ गणना गर्छ, त्यसैले पुरानो अनुवाद पनि समेटिएको मानिन्छ; -- `check-translation-drift` ले `docs/i18n//**.md` का कागजात mirror हरू ट्र्याक गर्छ — - यसले `src/i18n/messages/*.json` कहिल्यै पढ्दैन। 2026-09 को पुनः-सिङ्कदेखि `docs-sync-strict` कार्यमा अवरोधक: - मुख्य कागजात सम्पादन गर्नुहोस् → `npm run i18n:run -- --files=` (खण्ड-स्तरीय, कम खर्चिलो)। +- `sync-ui-keys` ले केवल **अनुपस्थित** कुञ्जीहरू ब्याकफिल गर्छ, **पुराना** भएकाहरूलाई कहिल्यै गर्दैन; +- `check-ui-keys-coverage` ले कुञ्जीको _उपस्थिति_ गन्छ, त्यसैले पुरानो अनुवाद पनि समेटिएको मानिन्छ; +- `check-translation-drift` ले `docs/i18n//**.md` का कागजात मिररहरू ट्र्याक गर्छ — + यसले `src/i18n/messages/*.json` कहिल्यै पढ्दैन। 2026-09 पुनः-सिङ्कदेखि कार्य `docs-sync-strict` मा अवरोधक: मुख्य कागजात सम्पादन गर्नुहोस् → `npm run i18n:run -- --files=` (खण्ड-स्तरीय, सस्तो)। -**Diff-सचेत, आधाररेखामा निर्भर नरहेको।** यसले merge base मा रहेको `en.json` लाई +**Diff-aware हो, baseline-backed होइन।** यसले merge base मा रहेको `en.json` लाई working tree सँग तुलना गर्छ; अंग्रेजी मान परिवर्तन भएको प्रत्येक key का लागि, अझै पनि -नछोइएको अनुवाद राख्ने कुनै पनि locale पुरानो मानिन्छ। यसले जानाजानी **पहिलेदेखिको ऋणलाई स्थिर राख्छ** — -लामो समयदेखि रहेको अनुवाद कुन पुरानो अंग्रेजीबाट आएको हो भनेर diff ले देखाउन सक्दैन, त्यसैले gate ले -हालको परिवर्तनले छोएका कुराहरूलाई मात्र जाँच्छ। यसको विकल्प (प्रति-key hash आधाररेखा) का लागि -करिब 600 KB को generated file चाहिन्थ्यो, जुन सबैभन्दा ठूलो विद्यमान आधाररेखाभन्दा 3× ठूलो हो र प्रत्येक i18n PR मा परिवर्तन भइरहन्थ्यो। +नछोइएको अनुवाद भएको कुनै पनि locale बासी मानिन्छ। यसले जानाजानी **पहिलेदेखिको ऋणलाई स्थिर राख्छ** — diff ले +लामो समयदेखि रहेको अनुवाद कुन पुरानो अंग्रेजीबाट आएको हो भनेर देखाउन सक्दैन, त्यसैले gate ले +हालको परिवर्तनले छोएका कुराहरूलाई मात्र मूल्याङ्कन गर्छ। यसको विकल्प (प्रत्येक key का लागि hash baseline) का लागि +करिब 600 KB को generated file आवश्यक पर्थ्यो, जुन सबैभन्दा ठूलो विद्यमान baseline भन्दा 3× ठूलो हो र प्रत्येक i18n PR मा फेरबदल हुन्थ्यो। यसलाई पूरा गर्ने दुई तरिका छन्: 1. प्रभावित अनुवादहरू अद्यावधिक गर्नुहोस्, वा -2. तिनलाई `__MISSING__:` मा सेट गर्नुहोस् — त्यसपछि runtime ले सच्याइएको अंग्रेजी - (`src/i18n/request.ts::deepMergeFallback`, #7258) प्रदान गर्छ र उक्त key अनुवादका लागि पङ्क्तिबद्ध हुन्छ। +2. तिनलाई `__MISSING__:` मा सेट गर्नुहोस् — त्यसपछि runtime ले सच्याइएको अंग्रेजी उपलब्ध गराउँछ + (`src/i18n/request.ts::deepMergeFallback`, #7258) र key अनुवादका लागि लामबद्ध हुन्छ। -यदि string को **अर्थ** परिवर्तन भएको हो भने, **key को नाम परिवर्तन गर्नुलाई** प्राथमिकता दिनुहोस्: नयाँ key ले -पुरानो अनुवाद उत्तराधिकारमा पाउन सक्दैन। #8463 ले प्रयोग गरेको ढाँचा यही हो। +यदि string को **अर्थ** परिवर्तन भएको छ भने, **key को नाम परिवर्तन गर्नुलाई** प्राथमिकता दिनुहोस्: नयाँ key ले +बासी अनुवाद उत्तराधिकारमा लिन सक्दैन। #8463 ले यही ढाँचा प्रयोग गरेको थियो। ```bash npm run i18n:check-value-drift # कडा (CI ले चलाउने) @@ -232,48 +230,48 @@ npm run i18n:check-value-drift:warn # रिपोर्ट मात्र BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -आधार catalog पढ्न नसकिँदा (base ref बिनाको shallow -clone), `check-openapi-breaking` को व्यवहारअनुरूप `SKIP reason=base-unresolved` सहित 0 मा exit हुन्छ। +base catalog पढ्न नसकिँदा (base ref बिनाको shallow +clone), `check-openapi-breaking` कै व्यवहारअनुसार `SKIP reason=base-unresolved` सहित 0 मा निस्कन्छ। ### Job: `i18n` -पूर्ण i18n प्रमाणीकरण matrix (प्रति locale एउटा job)। सम्पूर्ण job परामर्शात्मक हो। +पूर्ण i18n प्रमाणीकरण matrix (प्रत्येक locale का लागि एउटा job)। सम्पूर्ण job परामर्शात्मक हो। -| Script | प्रमाणीकरण गर्ने कुरा | अवरोध गर्ने | -| ------------------------------- | ----------------------------- | ------------------------------------------------------------ | -| `validate_translation.py quick` | प्रति locale अनुवादको पूर्णता | **परामर्शात्मक** (सम्पूर्ण job मा `continue-on-error: true`) | +| Script | प्रमाणीकरण गर्ने कुरा | अवरोधक | +| ------------------------------- | --------------------------------- | ------------------------------------------------------------ | +| `validate_translation.py quick` | प्रत्येक locale को अनुवाद पूर्णता | **परामर्शात्मक** (सम्पूर्ण job मा `continue-on-error: true`) | ### Job: `pr-test-policy` pull request हरूमा मात्र चल्छ। -| Script | प्रमाणीकरण गर्ने कुरा | अवरोध गर्ने | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, वा `bin/` मा production code परिवर्तन गर्ने PR हरूले test समावेश वा अद्यावधिक गर्नुपर्छ (Hard Rule #8) | हो | -| `check:test-masking` | परिवर्तन गरिएका test file हरूले कुल assert सङ्ख्या घटाउँदैनन् वा `assert.ok(true)` जस्ता स्वतःसिद्ध कथन थप्दैनन् | हो | -| `check:pr-evidence` | PR body ले परिवर्तनका लागि test/VPS प्रमाण उल्लेख गर्छ (PR prose लाई grep गरेर Hard Rule #18 यान्त्रिकीकरण गर्छ — नाजुक, Backlog हेर्नुहोस्) | हो | +| Script | प्रमाणीकरण गर्ने कुरा | अवरोधक | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, वा `bin/` मा production code परिवर्तन गर्ने PR हरूले test समावेश वा अद्यावधिक गर्नुपर्छ (कडा नियम #8) | हो | +| `check:test-masking` | परिवर्तन गरिएका test file हरूले कुल assert सङ्ख्या घटाउँदैनन् वा `assert.ok(true)` जस्ता tautology थप्दैनन् | हो | +| `check:pr-evidence` | PR body ले परिवर्तनका लागि test/VPS प्रमाण उद्धृत गर्छ (PR prose लाई grep गरेर कडा नियम #18 लाई यान्त्रिक बनाउँछ — कमजोर छ, Backlog हेर्नुहोस्) | हो | ### Job: `test-vitest` `build` पछि चल्छ। असफल भएमा merge रोक्छ। -| Suite | प्रमाणीकरण गर्ने कुरा | अवरोध गर्ने | -| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | हो | -| `test:vitest:ui` | UI component test हरू — vitest runner | **अवरोध गर्ने** — पहिलेदेखिका failure हरू `vitest.config.ts` मा स्पष्ट रूपमा बहिष्कृत छन्; नयाँ failure ले job असफल गराउँछन् | +| Suite | प्रमाणीकरण गर्ने कुरा | अवरोधक | +| ---------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | हो | +| `test:vitest:ui` | UI component test हरू — vitest runner | **अवरोधक** — पहिलेदेखिका failure हरूलाई `vitest.config.ts` मा स्पष्ट रूपमा बाहिर राखिएको छ; नयाँ failure ले job असफल बनाउँछन् | ### रात्रिकालीन workflow हरू (तालिकाबद्ध, परामर्शात्मक) -यी cron schedule मा (र `workflow_dispatch` मार्फत) चल्छन्, PR हरूमा कहिल्यै चल्दैनन्। सबै परामर्शात्मक हुन्। +यी cron तालिकामा (र `workflow_dispatch` मार्फत) चल्छन्, PR हरूमा कहिल्यै चल्दैनन्। सबै परामर्शात्मक हुन्। -| Workflow | प्रमाणीकरण गर्ने कुरा | अवरोध गर्ने | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | random seed + उच्च run count सहितका fast-check property test हरू | **परामर्शात्मक** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **परामर्शात्मक** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probe हरू (provider secret नभएमा छोडिन्छ) | **परामर्शात्मक** | -| `nightly-schemathesis` | `docs/openapi.yaml` प्रयोग गरी live OmniRoute विरुद्ध OpenAPI contract fuzzing (schemathesis) — spec उल्लङ्घन / सम्हाल्न नसकिएका 500 हरू उजागर गर्छ (चरण 8 B.4) | **परामर्शात्मक** | -| `nightly-mutation` | द्रुत unit lane मा Stryker mutation-testing score — जीवित रहने mutant हरूले कमजोर assert उजागर गर्छन् | **परामर्शात्मक** | -| `nightly-compat` | समर्थित `engines.node` range हरूमा Node engine compatibility matrix | **परामर्शात्मक** | +| Workflow | प्रमाणीकरण गर्ने कुरा | अवरोधक | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `nightly-property` | random seed + उच्च run count सहितका fast-check property test हरू | **परामर्शात्मक** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **परामर्शात्मक** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probe हरू (provider secret नभएमा छोडिन्छ) | **परामर्शात्मक** | +| `nightly-schemathesis` | `docs/openapi.yaml` प्रयोग गरी live OmniRoute विरुद्ध OpenAPI contract fuzzing (schemathesis) — spec उल्लङ्घन / ह्यान्डल नगरिएका 500 हरू देखाउँछ (चरण 8 B.4) | **परामर्शात्मक** | +| `nightly-mutation` | द्रुत unit lane मा Stryker mutation-testing score — बाँचेका mutant हरूले कमजोर assert देखाउँछन् | **परामर्शात्मक** | +| `nightly-compat` | समर्थित `engines.node` range हरूमा Node engine compatibility matrix | **परामर्शात्मक** | --- @@ -535,43 +533,44 @@ CI गेटहरूभन्दा बाहिर, OmniRoute ले **ऐच --- -## युक्तिसंगतीकरण ब्याकलग (ROI समीक्षा — चरण 9 लहर 3) +## युक्तिसङ्गतीकरण ब्याकलग (ROI समीक्षा — चरण 9 लहर 3) यो सूचीलाई 2026-06-17 मा `ci.yml` सँग मिलान गरिएको थियो (अघिल्लो संस्करणमा `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` छुटेका थिए)। मिलान गरिएको सेटको ROI समीक्षाले -निम्न युक्तिसंगतीकरणका उम्मेदवारहरू पहिचान गर्यो। **मर्जहरू यान्त्रिक CI -परिवर्तनहरू हुन्; फ्लिप/हटाउने निर्णयहरू अपरेटरका लागि आरक्षित नीतिगत निर्णय हुन्।** तलका कुनै पनि कुरा -अहिलेसम्म लागू गरिएको छैन। +`check:codeql-ratchet`, `check:pr-evidence` छुटेका थिए)। मिलान गरिएको सेटको ROI +समीक्षाले निम्न युक्तिसङ्गतीकरणका उम्मेदवारहरू पहिचान गर्यो। **मर्जहरू यान्त्रिक CI +परिवर्तनहरू हुन्; फ्लिप/हटाउने कार्यहरू अपरेटरका लागि आरक्षित नीतिगत निर्णयहरू हुन्।** +तलका कुनै पनि कुरा अहिलेसम्म लागू गरिएको छैन। -**माथि कागजातबद्ध नगरिएका थप विषयहरू** (परामर्शात्मक, न्यून सङ्केत): `docs-lint` job -(markdownlint + Vale, सम्पूर्ण job मा `continue-on-error`) र छुट्टाछुट्टै scanner workflow हरू +**माथि दस्तावेजीकरण नगरिएका थप कुराहरू** (परामर्शात्मक, न्यून सङ्केत): `docs-lint` जब +(markdownlint + Vale, सम्पूर्ण जबमा `continue-on-error`) र छुट्टाछुट्टै स्क्यानर वर्कफ्लोहरू `semgrep.yml` / `codeql.yml` / `scorecard.yml`। `semgrepFindings: 0` -`quality-baseline.json` मा छ तर `ci.yml` मा अवरोधकारी ratchet सँग जोडिएको छैन — यो metric +`quality-baseline.json` मा छ तर `ci.yml` मा कुनै अवरोधक र्याचेटसँग जोडिएको छैन — यो मेट्रिक हाल अनाथ छ। -### मर्ज / डिडुप्लिकेसन (यान्त्रिक, कम जोखिम) +### मर्ज / दोहोरोपन हटाउने (यान्त्रिक, कम जोखिम) -प्रत्येक उम्मेदवारलाई 2026-06-17 को प्रत्यक्ष gate अवस्थाविरुद्ध मान्य गरिएको थियो (विश्वास गर तर प्रमाणीकरण पनि गर); -धेरै "स्पष्ट" मर्जहरूले वास्तवमा प्राविधिक ऋण लुकाएका रहेछन् र ती **सिधै प्रतिस्थापन गर्न मिल्ने** छैनन्। +प्रत्येक उम्मेदवारलाई 2026-06-17 को प्रत्यक्ष गेट अवस्थासँग प्रमाणीकरण गरिएको थियो +(विश्वास गर, तर पुष्टि पनि गर); धेरै "स्पष्ट" देखिने मर्जहरूले ऋण लुकाएका रहेछन् र ती +**सफा रूपमा सीधै प्रतिस्थापन गर्न मिल्ने** छैनन्। -- **`check:docs-sync` दुई पटक चल्छ** — `lint` job मा छुट्टै र फेरि `check:docs-all` (`docs-sync-strict`) भित्र तथा husky pre-commit hook मा। ✅ **सम्पन्न** — छुट्टै `lint` invocation हटाइयो। -- **CVE scanning** — ❌ **सिधै मर्ज गर्न मिल्दैन।** `audit:deps` कुनै पनि उच्च/गम्भीर CVE मा कडाइका साथ विफल हुन्छ; `check:vuln-ratchet` (osv) baseline को तुलनामा _प्रतिगमन_ हुँदा मात्र विफल हुन्छ (हाल 1 MODERATE)। अर्थगत व्यवहार फरक छन् — `audit:deps` हटाउँदा निरपेक्ष उच्च/गम्भीर gate हराउँछ। दुवै राख्नुहोस्। -- **Cycle detection** — ❌ **सिधै मर्ज गर्न मिल्दैन।** `check:circular-deps` (dpdm) ले **91 cycles** रिपोर्ट गर्छ (त्यसैले यो परामर्शात्मक छ); पहिले तिनलाई समाधान नगरी यसलाई अवरोधकारी बनाउन सकिँदैन, र यसको दायरा हरियो, चयनित `check:cycles` भन्दा फराकिलो छ। `check:cycles` लाई अवरोधकारी नै राख्नुहोस्; 91 वटा dpdm cycle समाधान गर्नु यसको आफ्नै backlog हो। -- **Complexity** — ✅ **सम्पन्न** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): एउटा ESLint walk, ruleId अनुसार गणना गरिएकाले cyclomatic+max-lines र cognitive baseline हरू स्वतन्त्र रहन्छन्; स्थानीय `--update` का लागि छुट्टाछुट्टै `check:complexity` / `check:cognitive-complexity` कायम छन्। -- **`/api` anti-hallucination** — ✅ **सम्पन्न** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` को एउटै FS inventory, openapi-routes + docs-symbols ले अझै स्वतन्त्र रूपमा रिपोर्ट गर्छन्; स्थानीय run का लागि छुट्टाछुट्टै जाँचहरू कायम छन्। -- **`check:node-runtime` 11 वटा job मा चल्छ** — ⚠️ **न्यून ROI।** प्रत्येक छुट्टै runner हो र जाँच <1s लाग्छ; सस्तो per-job guard गुमाउने तुलनामा कुल बचत ~10s मात्र हुन्छ। परिवर्तनको झन्झट लायक छैन। -- **CI lint मा `typecheck:noimplicit:core`** — ✅ **lint job बाट हटाइयो** (परामर्शात्मक `continue-on-error` थियो); अवरोधकारी type surface `typecheck:core` + `check:type-coverage` हो। स्थानीय script कायम राखियो। +- **`check:docs-sync` दुई पटक चल्छ** — `lint` जबमा छुट्टै र फेरि `check:docs-all` (`docs-sync-strict`) तथा husky pre-commit हुकभित्र। ✅ **सम्पन्न** — छुट्टै `lint` आह्वान हटाइयो। +- **CVE स्क्यानिङ** — ❌ **सफा मर्ज होइन।** `audit:deps` ले कुनै पनि उच्च/गम्भीर CVE मा कडा रूपमा असफल गराउँछ; `check:vuln-ratchet` (osv) भने आधाररेखाको तुलनामा _पश्चगमन_ भएमा मात्र असफल हुन्छ (हाल 1 MODERATE)। अर्थविज्ञान फरक छन् — `audit:deps` हटाउँदा निरपेक्ष उच्च/गम्भीर गेट हराउनेछ। दुवै राख्नुहोस्। +- **चक्र पत्ता लगाउने** — ✅ **सम्पन्न** (#15159 G-01/G-02)। यहाँको पुरानो पाठले `check:cycles` लाई "हरियो, छनोट गरिएको" गेट भनेको थियो र `check:circular-deps` (dpdm) ले 91 चक्र रिपोर्ट गरेको कारण यसलाई अवरोधक राख्नुपर्ने औचित्य दिएको थियो। त्यो हरियो अवस्था **झूटो हरियो** थियो: `check:cycles` ले 5 उपनिर्देशिका (450 फाइल) स्क्यान गर्थ्यो, स्थिर `import|export … from` सँग मात्र मिलान गर्थ्यो, र प्रत्येक `@/` तथा `@omniroute/open-sse/` स्पेसिफायर हटाउँथ्यो, त्यसैले यसले रिपोजिटरीमा हाबी भएका dynamic-import + alias चक्रहरू देख्न सक्दैनथ्यो। सुधार गरियो: गेटले अब `src` + `open-sse` (5023 फाइल) मा खोज्छ, TypeScript AST बाट स्पेसिफायरहरू सङ्कलन गर्छ (त्यसैले `import("…")` गणना हुन्छ र type-position `typeof import("…")` हुँदैन), र tsconfig `paths` समाधान गर्छ। यसले 0 होइन, **14** चक्र फेला पार्छ। पहिलेदेखि रहेका 14 चक्रलाई गेट PR मा सुधार्न नसकिने भएकाले, `check:cycles` अब **र्याचेट** हो (`--ratchet`, `quality-baseline.json` मा सीमा `metrics.cycles.value = 14`, `direction: down`) — यसले कुनै पनि _पश्चगमन_ रोक्छ र सङ्ख्या घट्न मात्र सक्छ। CI ले `npm run check:cycles:ratchet` चलाउँछ। क्रमिक न्यूनीकरण **A-01** सँगै अघि बढ्छ। `check:circular-deps` (dpdm) व्यापक दोस्रो रायका रूपमा परामर्शात्मक नै रहन्छ। +- **जटिलता** — ✅ **सम्पन्न** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): एउटै ESLint भ्रमण, ruleId अनुसार गणना गरिन्छ ताकि cyclomatic+max-lines र cognitive आधाररेखाहरू स्वतन्त्र रहून्; छुट्टाछुट्टै `check:complexity` / `check:cognitive-complexity` स्थानीय `--update` का लागि कायम छन्। +- **`/api` भ्रम-निरोध** — ✅ **सम्पन्न** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` को एउटै FS सूचीकरण, openapi-routes + docs-symbols ले अझै पनि स्वतन्त्र रूपमा रिपोर्ट गर्छन्; छुट्टाछुट्टै जाँचहरू स्थानीय रनका लागि कायम छन्। +- **`check:node-runtime` 11 जबमा चल्छ** — ⚠️ **न्यून ROI।** प्रत्येक छुट्टै रनर हो र जाँच <1s को छ; सस्तो प्रति-जब सुरक्षा गुमाउनुको सट्टा कुल बचत ~10s मात्र हुन्छ। यस्तो फेरबदल गर्न लायक छैन। +- **CI lint मा `typecheck:noimplicit:core`** — ✅ **lint जबबाट हटाइयो** (परामर्शात्मक `continue-on-error` थियो); अवरोधक type surface `typecheck:core` + `check:type-coverage` हो। स्थानीय स्क्रिप्ट कायम राखिएको छ। ### फ्लिप / निर्णय (अपरेटर नीति) -- `check:openapi-security-tiers` (परामर्शात्मक) — ❌ **सफा रूपमा फ्लिप गर्न मिल्दैन।** यो 0 सहित बाहिरिन्छ तर `LOCAL_ONLY_API_PREFIXES` अन्तर्गतका धेरै `traffic-inspector` route मा `x-loopback-only: true` annotation नभएको चेतावनी दिन्छ। यसलाई लागू गर्न पहिले `openapi.yaml` मा ती annotation थप्नुपर्छ। -- `typecheck:noimplicit:core` (परामर्शात्मक) — अवरोधकारी `check:type-coverage` ratchet ले यसलाई धेरै हदसम्म समेट्छ। यसलाई ratchet मा फ्लिप गर्नुहोस् वा दोहोरिएको दोस्रो `tsc` pass हटाउनुहोस्। -- `test:vitest:ui` (अहिले **अवरोधकारी**) — पहिलेबाट रहेका विफलताहरू `vitest.config.ts` मा `// #8618` tracking comment सहित स्पष्ट रूपमा बहिष्कृत गरिएका छन्; नयाँ विफलताले job विफल बनाउँछ। -- `check:secrets` (gitleaks, कागजातबद्ध 3 वटा false-positive मा स्थिर गरिएको अवरोधकारी ratchet) — 0 मा पुग्न ती 3 वटालाई allowlist गर्नुहोस्, वा परामर्शात्मकमा घटाउनुहोस्। यो GitHub को native secret-scanning + `check:public-creds` सँग दोहोरिन्छ। -- `check:pr-evidence` (अवरोधकारी, PR-body को गद्यमा grep गर्छ) — false-positive को उच्च जोखिम; हटाउँदा कडा नियम #18 को कार्यान्वयन कमजोर हुन्छ, त्यसैले यो वास्तविक नीतिगत निर्णय हो। -- `semgrep` (परामर्शात्मक standalone) — OWASP family हरूका लागि CodeQL सँग दोहोरिन्छ; यसको baseline लाई ratchet सँग जोड्नुहोस् वा हटाउनुहोस्। +- `check:openapi-security-tiers` (परामर्शात्मक) — ❌ **सफा रूपमा फ्लिप गर्न मिल्दैन।** यो 0 सहित बाहिरिन्छ तर `LOCAL_ONLY_API_PREFIXES` अन्तर्गतका धेरै `traffic-inspector` रुटहरूमा `x-loopback-only: true` एनोटेसन नभएको चेतावनी दिन्छ। यसलाई लागू गराउन पहिले `openapi.yaml` मा ती एनोटेसनहरू थप्नुपर्छ। +- `typecheck:noimplicit:core` (परामर्शात्मक) — अवरोधक `check:type-coverage` र्याचेटले यसको अधिकांश भाग समेट्छ। यसलाई र्याचेटमा फ्लिप गर्नुहोस् वा अनावश्यक दोस्रो `tsc` पास हटाउनुहोस्। +- `test:vitest:ui` (अहिले **अवरोधक**) — पहिलेदेखिका असफलताहरूलाई `vitest.config.ts` मा `// #8618` ट्र्याकिङ टिप्पणीहरूसहित स्पष्ट रूपमा बहिष्कार गरिएको छ; नयाँ असफलताले जब असफल गराउँछन्। +- `check:secrets` (gitleaks, दस्तावेजीकृत 3 false-positive मा स्थिर गरिएको अवरोधक र्याचेट) — 0 मा पुग्न ती 3 वटालाई allowlist गर्नुहोस्, वा परामर्शात्मकमा घटुवा गर्नुहोस्। GitHub को नेटिभ secret-scanning + `check:public-creds` सँग दोहोरिन्छ। +- `check:pr-evidence` (अवरोधक, PR-body गद्यमा grep गर्छ) — false-positive को उच्च जोखिम; हटाइएमा Hard Rule #18 को कार्यान्वयन कमजोर हुन्छ, त्यसैले यो वास्तविक नीतिगत निर्णय हो। +- `semgrep` (परामर्शात्मक छुट्टै वर्कफ्लो) — OWASP परिवारहरूका लागि CodeQL सँग दोहोरिन्छ; यसको आधाररेखालाई र्याचेटसँग जोड्नुहोस् वा हटाउनुहोस्। --- diff --git a/docs/i18n/nl/CONTRIBUTING.md b/docs/i18n/nl/CONTRIBUTING.md index 70a931b6949..a947dc06ac8 100644 --- a/docs/i18n/nl/CONTRIBUTING.md +++ b/docs/i18n/nl/CONTRIBUTING.md @@ -394,15 +394,15 @@ Schrijf unittests in `tests/unit/` die minimaal het volgende afdekken: - [ ] Build slaagt (`npm run build`) - [ ] TypeScript-typen toegevoegd voor nieuwe openbare functies en interfaces - [ ] Geen hardgecodeerde geheimen of terugvalwaarden -- [ ] Openbare upstream-referenties ingesloten via `resolvePublicCred()` (zie [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nooit als literals +- [ ] Openbare upstream-inloggegevens ingesloten via `resolvePublicCred()` (zie [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nooit als letterlijke waarden - [ ] Foutreacties worden verwerkt via `buildErrorBody()` / `sanitizeErrorMessage()` — geen onbewerkte stacktraces in responsbody's (zie [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shellopdrachten (`exec` / `spawn`) geven runtimewaarden door via `env`, niet via tekenreeksinterpolatie +- [ ] Shell-opdrachten (`exec` / `spawn`) geven runtimewaarden door via `env`, niet via tekenreeksinterpolatie - [ ] Alle invoer gevalideerd met Zod-schema's -- [ ] Changelog**fragment** toegevoegd onder `changelog.d/{features|fixes|maintenance}/-.md` voor gebruikersgerichte wijzigingen (zie [`changelog.d/README.md`](./changelog.d/README.md)) — bewerk `CHANGELOG.md` **niet** rechtstreeks; fragmenten worden bij een release samengevoegd en veroorzaken nooit conflicten tussen pull requests +- [ ] **Fragment** voor de changelog toegevoegd onder `changelog.d/{features|fixes|maintenance}/-.md` voor gebruikersgerichte wijzigingen (zie [`changelog.d/README.md`](./changelog.d/README.md)) — bewerk `CHANGELOG.md` **niet** rechtstreeks; fragmenten worden bij een release samengevoegd en veroorzaken nooit conflicten tussen pull requests - [ ] Documentatie bijgewerkt (indien van toepassing) -- [ ] Geen nieuwe CodeQL- / Secret-Scanning-waarschuwingen geopend, of elke waarschuwing is afgewezen met een technische onderbouwing die verwijst naar het relevante document in `docs/security/` -- [ ] Routes die onderliggende processen starten (`/api/mcp/`, `/api/cli-tools/runtime/`) geclassificeerd als `isLocalOnlyPath()` in `src/server/authz/routeGuard.ts` — zie [Harde regel #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Geen `Co-Authored-By`-trailers in commitberichten — commits mogen uitsluitend onder de Git-identiteit van de eigenaar van de repository verschijnen (Harde regel #16) +- [ ] Geen nieuwe CodeQL- of Secret-Scanning-meldingen geopend, of elke melding afgewezen met een technische onderbouwing die verwijst naar het relevante document in `docs/security/` +- [ ] Routes die onderliggende processen starten (`/api/mcp/`, `/api/cli-tools/runtime/`) geclassificeerd als `isLocalOnlyPath()` in `src/server/authz/routeGuard.ts` — zie [harde regel #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Geen AI-/bottrailers met `Co-authored-by` in commitberichten (harde regel #16) — menselijke medewerkers van wie werk wordt hergebruikt, worden vermeld met standaardtrailers in de vorm `Co-authored-by: Name ` --- diff --git a/docs/i18n/nl/docs/architecture/QUALITY_GATES.md b/docs/i18n/nl/docs/architecture/QUALITY_GATES.md index 62862aa0233..8dde4fa56d6 100644 --- a/docs/i18n/nl/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/nl/docs/architecture/QUALITY_GATES.md @@ -19,210 +19,214 @@ replicatieplanning van hetzelfde systeem het ### Toelating van kandidaten -De workflows CI en Quality Gates produceren elk een stabiel oordeel: `Gate / CI` en -`Gate / Quality`. Hun versiegebonden toelatingsbeleid somt elke upstream-job op -als vereist of adviserend. Een toepasselijke vereiste job moet slagen: ontbrekende, -geannuleerde, overgeslagen, in behandeling zijnde en onbekende resultaten kunnen geen PASS vaststellen. Een geldige -classificatie als alleen documentatie of alleen catalogus kan een code-lane niet-toepasselijk maken; -een concept-PR is geen geaccepteerde kandidaat. Een `hotfix`-label stelt niet vrij van bewijs. - -Beide workflows dekken PR's en pushes naar main-/release-branches, handmatige dispatches en -merge-group-events. Pushes, dispatches en merge groups voeren de volledige selectie uit. Forks -en merge groups gebruiken gehoste runners voor jobs die anders zelfgehoste -runners selecteren; vóór de uitrol moet voldoende gehoste capaciteit worden geverifieerd. +De workflows CI en Quality Gates geven elk een stabiel oordeel af: `Gate / CI` en +`Gate / Quality`. Hun geversioneerde toelatingsbeleid vermeldt elke upstream-job +als verplicht of adviserend. Een toepasselijke verplichte job moet slagen: ontbrekende, +geannuleerde, overgeslagen, wachtende en onbekende resultaten kunnen geen PASS aantonen. +Een geldige classificatie als alleen-documentatie of alleen-catalogus kan een code-lane +niet-toepasselijk maken; een concept-PR is geen geaccepteerde kandidaat. Een `hotfix`-label +stelt een kandidaat niet vrij van het leveren van bewijs. + +Beide workflows ondersteunen PR's en pushes naar main/release-branches, handmatige dispatches +en merge-group-events. Bij push, dispatch en merge-group wordt de volledige selectie uitgevoerd. +Forks en merge-groepen gebruiken hosted runners voor jobs die anders self-hosted runners +selecteren; vóór de uitrol moet worden geverifieerd dat er voldoende hosted capaciteit is. Elk JSON-ontvangstbewijs identificeert de uitgecheckte SHA, workflow-run en poging. -De CLI weigert een mismatch tussen de checkout-SHA en de event-SHA. Workflowtests koppelen beleidslidmaatschap -aan de `needs`-lijst van de beoordelingsjob, zodat een nieuwe of verwijderde lane niet ongemerkt kan verdwijnen. -De ontvangstbewijzen dekken hun eigen workflow, niet publicatie, implementatie of de interne werking -van een bestaande adviserende scanner. Het activeren van beide controlenamen in branchregels is een -afzonderlijke administratieve wijziging; het toevoegen van deze jobs beschermt op zichzelf geen branch. +De CLI weigert een verschil tussen de SHA van de checkout en die van het event. Workflowtests +koppelen beleidslidmaatschap aan de `needs`-lijst van de beoordelingsjob, zodat een nieuwe of +verwijderde lane niet ongemerkt kan verdwijnen. De ontvangstbewijzen dekken hun eigen workflow, +niet publicatie, implementatie of de interne werking van een bestaande adviserende scanner. +Het activeren van beide controlenamen in branchregels is een afzonderlijke administratieve +wijziging; het toevoegen van deze jobs beschermt op zichzelf geen branch. ### Inventaris van statische scans -De versiegebonden inventaris van npm-aliassen en het lidmaatschap van statische scans bevinden zich in +De geversioneerde inventaris van npm-aliassen en het lidmaatschap van statische scans staan in `config/quality/gate-manifest.json`. Voer `npm run check:gate-manifest` uit om -scriptnamen en exacte commando's te valideren aan de hand van `package.json`; toevoegingen, verwijderingen en -afwijkingen in commando's laten zowel de lokale hook als de wijzigingsclassificatiejobs in CI mislukken. -Een alias is geen workflowjob, matrixinstantie of testcase: deze aantallen mogen -niet als onderling uitwisselbaar worden gepresenteerd. +scriptnamen en exacte opdrachten te valideren aan de hand van `package.json`; toevoegingen, +verwijderingen en opdrachtafwijkingen laten zowel de lokale hook als de +wijzigingsclassificatiejobs in CI mislukken. Een alias is geen workflowjob, matrixinstantie of +testcase: deze aantallen mogen niet als onderling uitwisselbaar worden gepresenteerd. Gebruik `npm run quality:scan -- --list` of `npm run quality:scan:fast -- --list` -om de geselecteerde aliassen te inspecteren zonder ze uit te voeren. De runner roept het +om de geselecteerde aliassen te bekijken zonder ze uit te voeren. De runner roept het npm-entrypoint aan, zodat de runtime ervan (inclusief Bun waar geconfigureerd) behouden blijft. -Het manifest registreert aliassen buiten die profielen als afzonderlijk aangeroepen, en -onderhoudscommando's zijn verboden in alleen-lezen-scanprofielen. +Het manifest registreert aliassen buiten deze profielen als afzonderlijk aangeroepen, en +onderhoudsopdrachten zijn verboden in alleen-lezen-scanprofielen. -Deze profielen dekken alleen de statische scan. Ze certificeren geen producttests, +Deze profielen dekken uitsluitend de statische scan. Ze certificeren geen producttests, dekking, packaging, externe controles of de volledige releaseacceptatie van een kandidaat. Workflowtoelating gebruikt het gekoppelde `config/quality/admission-policy.json` en `scripts/quality/admission-verdict.mjs`. Release-observer-profielen blijven afzonderlijk; -inspecteer hun toepasselijke controles en ontvangstbewijzen onafhankelijk. De tekstuele -inventaris hieronder is een referentie, geen bewijs dat een gate daadwerkelijk is uitgevoerd. +controleer hun toepasselijke controles en ontvangstbewijzen onafhankelijk. De tekstuele +inventaris hieronder is een naslagwerk, geen bewijs dat een gate daadwerkelijk is uitgevoerd. Scripts bevinden zich onder `scripts/check/` (beleidsgates) en `scripts/quality/` (ratchet-engine). De bron van waarheid voor CI is `.github/workflows/ci.yml`. ### Snel pad voor release-PR's (`quality.yml`) -`.github/workflows/quality.yml` vult CI aan voor PR's naar main-/release-branches, pushes naar beveiligde branches, -dispatches en merge groups. PR's gebruiken snelle controles met padfilters. De permanent -uitgeschakelde dubbele build is verwijderd; de echte build-/package-/opstartcontroles blijven in CI. - -| Job | Bereik | Blokkerend | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `Docs Gates (fast-path)` | Documentatie-/code-PR's; API-documentatiereferenties en alle documentatie | Ja | -| `Fast Quality Gates` | Code-PR's; statische controles, typecontrole, typecontrole van het dashboard, beïnvloede unittests | Ja | -| `Forgotten sibling tests` | Code-PR's; gewijzigde modules getraceerd naar statische gebruikers en kandidaat-siblingtests; barrel- en dynamic-import-paden worden gerapporteerd als adviserende diagnostiek, met uitzonderingen op basis van een allowlist waarnaar wordt verwezen | **Adviserend** | -| `Vitest (fast-path)` | Code-PR's; snelle Vitest-suite | Ja | -| `Unit Tests fast-path` | Code-PR's; unittest-suite met 4 shards | Ja | -| `No new ESLint warnings` | Code-PR's; onderdrukkingsbewuste lintbewaking | Ja, inclusief forks | -| `Merge integrity (changelog + generated skills)` | Niet-concept-PR's; synchronisatie van de changelog en gegenereerde skills | Ja, inclusief forks | +`.github/workflows/quality.yml` vult CI aan voor PR's naar main/release, pushes naar beveiligde +branches, dispatches en merge-groepen. PR's gebruiken snelle, op paden gefilterde controles. De +permanent uitgeschakelde dubbele build is verwijderd; de echte controles voor build, packaging +en opstarten blijven in CI. + +| Job | Bereik | Blokkerend | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `Docs Gates (fast-path)` | Documentatie-/code-PR's; API-documentatiereferenties en docs-all | Ja | +| `Fast Quality Gates` | Code-PR's; statische controles, typecheck, dashboard-typecheck, beïnvloede unittests | Ja | +| `Forgotten sibling tests` | Code-PR's; gewijzigde modules getraceerd naar statische consumers en kandidaat-siblingtests; barrel- en dynamic-import-paden worden gerapporteerd als adviserende diagnostiek, met allowlist-uitzonderingen waarnaar wordt verwezen | **Adviserend** | +| `Vitest (fast-path)` | Code-PR's; snelle vitest-suite | Ja | +| `Unit Tests fast-path` | Code-PR's; unitsuite met 4 shards | Ja | +| `No new ESLint warnings` | Code-PR's; onderdrukkingsbewuste lint-bewaking | Ja, inclusief forks | +| `Merge integrity (changelog + generated skills)` | Niet-concept-PR's; synchronisatie van changelog en gegenereerde skills | Ja, inclusief forks | #### Rapport over vergeten siblingtests `npm run check:forgotten-sibling-tests` hergebruikt de importresolver achter de test-impactmap. -Voor elke gewijzigde productiemodule rapporteert het deterministische -`gewijzigde module/symbool -> statische gebruiker -> kandidaat-siblingtest`-ketens wanneer de kandidaat- -test ontbreekt in de diff van de pull request. De Markdown-samenvatting en het JSON-resultaat worden bewaard als -het workflowartefact `forgotten-sibling-tests` voor kalibratie vóór een eventuele blokkerende uitrol. +Voor elke gewijzigde productiemodule rapporteert het deterministische ketens van +`gewijzigde module/symbool -> statische consumer -> kandidaat-siblingtest` wanneer de kandidaat- +test ontbreekt in de diff van de pull request. De Markdown-samenvatting en het JSON-resultaat +worden bewaard als het workflowartefact `forgotten-sibling-tests` voor kalibratie voordat een +blokkerende uitrol plaatsvindt. Barrel-re-exports en dynamische imports dienen uitsluitend als resolutiediagnostiek; ze leiden nooit tot een blokkerende bevinding. Beoordeelde uitzonderingen staan in -`config/quality/forgotten-sibling-allowlist.json`. Elke vermelding moet de consumerende test en de kandidaat-test -benoemen, een specifieke motivering geven en naar een GitHub-issue of pull request verwijzen. Ongeldige vermeldingen worden -standaard geweigerd. Uitzonderingen kunnen een verwijderde kandidaat-test of een diff die `.skip`/`.todo` toevoegt niet onderdrukken; -het verzwakken van assertions en andere vormen van maskering blijven de verantwoordelijkheid van de onafhankelijk blokkerende +`config/quality/forgotten-sibling-allowlist.json`. Elke vermelding moet de consumer en kandidaat- +test benoemen, een specifieke onderbouwing geven en naar een GitHub-issue of pull request linken. Ongeldige vermeldingen worden +standaard geweigerd. Uitzonderingen kunnen een verwijderde kandidaattest of een diff die `.skip`/`.todo` toevoegt niet onderdrukken; +het afzwakken van assertions en andere maskering vallen onder de onafhankelijk blokkerende `check:test-masking`-gate. ### Job: `lint` Wordt uitgevoerd bij elke PR naar `main`. Blokkeert samenvoegen bij een fout. -| Script (`npm run ...`) | Valideert | Blokkerend | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | De Node.js-versie valt binnen het ondersteunde bereik | Ja | -| `check:cycles` | Circulaire imports — alle modules in `src/` + `open-sse/` | Ja | -| `check:route-validation:t06` | Zod-schema's aanwezig op alle routes (Tier 6-beleid) | Ja | -| `check:any-budget:t11` | Het aantal `@ts-expect-error // any` overschrijdt het budget niet (Tier 11-catraca) | Ja | -| `check:provider-consistency` | Elke provider in `providers.ts` heeft een overeenkomstige vermelding in `providerRegistry.ts` (en omgekeerd, binnen de allowlist) | Ja | -| `check:model-lifecycle` | De drie handmatig onderhouden routeringstabellen blijven consistent met de ingecheckte levenscyclussnapshot (#11503): `FITNESS_TABLE` (`taskFitness.ts`) kent geen score toe aan een uitgefaseerde id die door `REGISTRY` kan worden gerouteerd; elk doel van `BUILT_IN_ALIASES` is aanwezig in `REGISTRY` en afwezig in de snapshot met uitgefaseerde id's; elke uitgefaseerde id die nog in `REGISTRY` staat, wordt doorgestuurd of vermeld in `allowedRetiredInCatalog`; en geen enkele bron of doel van `DEFAULT_DEGRADATION_MAP` staat in die snapshot als uitgefaseerd. Dit bewijst niet dat een model momenteel door een actieve upstream wordt aangeboden. Offline — vergelijkt met `config/quality/model-lifecycle.json`, handmatig vernieuwd met `npm run quality:refresh-model-lifecycle` (netwerk; niet in CI geïntegreerd). `allowedRetiredInCatalog` is een afbouwmechanisme: voeg alleen een vermelding toe als er een tracking-issue is. | Ja | -| `check:fetch-targets` | Elke `fetch("/api/...")` in `src/` aan de clientzijde wordt herleid tot een bestaand `route.ts` | Ja | -| `check:deps` | Alle via `npm install` installeerbare afhankelijkheden in elk `package.json` in de repository staan in `dependency-allowlist.json`; nieuwe niet-vastgezette pakketten of pakketten met een naam die lijkt op die van een bestaand pakket worden gemarkeerd | Ja | -| `audit:deps` | `npm audit` (root + electron) — geen waarschuwingen met hoge/kritieke ernst (overlapt met osv `check:vuln-ratchet`; zie Rationalisatiebacklog) | Ja | -| `check:lockfile` | Integriteit van `package-lock.json` — https-register, integriteitshashes, geen hostoverschrijvingen | Ja | -| `check:licenses` | SPDX-licentietoegestane lijst voor productieafhankelijkheden | Ja | -| `check:tracked-artifacts` | Geen buildartefacten / vastgelegde `node_modules`-symbolische koppelingen (wordt ook uitgevoerd in de husky-pre-commithaak; pre-push is bewust lichtgewicht — #6716) | Ja | -| `check:ai-attribution` | Geen AI/bot-`Co-Authored-By`-trailer of AI-generatievoettekst in PR-commits, titel of hoofdtekst — Harde regel #16 (in de snelle-controlelus van `quality.yml` voor PR→`release/**` — leest de eventpayload, doet niets buiten PR's — en een stap die alleen voor PR's geldt in de linttaak van `ci.yml` voor PR→`main`; ook de husky-`commit-msg`-haak; menselijke co-auteurs toegestaan; #14436) | -| `check:vitest-exclusions` | Elke Vitest-uitsluiting vermeldt een trackingissue en komt voor in `config/quality/vitest-exclusions.json` (#13204) | Ja | -| `check:file-size` | Geen bronbestand overschrijdt de limiet per extensie (ratelmechanisme: bevroren grote bestanden in de `frozen`-lijst) | Ja | -| `check:error-helper` | Foutreacties in executors/handlers gebruiken `buildErrorBody()` / `sanitizeErrorMessage()` (Harde regel #12) | Ja | -| `check:migration-numbering` | Migratie-SQL-bestanden zijn opeenvolgend genummerd, zonder hiaten of duplicaten | Ja | -| `check:public-creds` | Geen letterlijke OAuth-`client_id`/`client_secret`-waarden of Firebase Web-sleutels buiten `publicCreds.ts` (Harde regel #11) | Ja | -| `check:db-rules` | Geen onbewerkte SQL buiten modules in `src/lib/db/`; geen barrel-imports vanuit `localDb.ts` (Harde regels #2/#5) | Ja | -| `check:known-symbols` | Provider-executors, routeringsstrategieën en vertalers die in hun dispatch-tabellen zijn geregistreerd, komen overeen met de bestanden op schijf — geen verweesde of niet-gedeclareerde symbolen | Ja | -| `check:route-guard-membership` | Elke route die een onderliggend proces start, is geclassificeerd door `isLocalOnlyPath()` (Harde regels #15/#17) | Ja | -| `check:test-discovery` | Elk `*.test.ts`- / `*.spec.ts`-bestand in de repo wordt door ten minste één testrunner verzameld (ratchet: de lijst met verweesde bestanden in `test-discovery-baseline.json` kan alleen maar krimpen) | Ja | -| `check:agent-skills-sync` | Gegenereerde agent-skills-artefacten komen overeen met hun broncatalogus (geen afwijkingen) | -| `check:provider-asset-provenance` | Logo's/assets van providers hebben een vastgelegde herkomstregistratie | -| `lint:json` | JSON-configuratiebestanden kunnen worden geparseerd en voldoen aan de lintregels van de repo | -| `typecheck:core` | TypeScript-compilatie zonder fouten (alleen adviserende waarschuwingen) | Ja | -| `typecheck:noimplicit:core` | Strikte `noImplicitAny` — toekomstgericht; veel bestaande aanroeplocaties moeten nog van annotaties worden voorzien | **Adviserend** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` beperkt tot `src/app/(dashboard)/**` (#7033) — de samengestelde allowlist van 27 bestanden van `typecheck:core` bevat geen enkele dashboard-TSX en `next build` voert er evenmin typecontrole op uit (`next.config.mjs` stelt `ignoreBuildErrors: true` in), waardoor regressies met verweesde identifiers daar (#6625/#6909) onzichtbaar waren voor CI. Vergelijkt met een bevroren basislijn voor aantallen per bestand/per TS-code (`config/quality/dashboard-typecheck-baseline.json`, hetzelfde patroon voor afdwinging van veroudering als `check:known-symbols`) — alleen NIEUWE fouten boven op het aantal in de basislijn laten de controle mislukken; stel de basislijn naar beneden bij met `--update` wanneer een bestaande fout is opgelost. | Ja | - -### Taak: `quality-gate` - -Wordt uitgevoerd na `test-coverage`. Blokkeert het samenvoegen bij een fout. - -| Script | Valideert | Blokkerend | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `quality:collect` | Genereert `quality-metrics.json` (aantal ESLint-waarschuwingen, dekking uit samengevoegd shardrapport) | Ja (voorafgaand aan ratchet) | -| `quality:ratchet` | Geen enkele metriek in `quality-baseline.json` is achteruitgegaan (ESLint-waarschuwingen ≤ baseline; dekking ≥ baseline) | Ja | -| `check:duplication` | Codeduplicatie (jscpd@4) overschrijdt de baseline in `quality-baseline.json` niet | Ja | -| `check:complexity` | Cyclomatische complexiteit op bestandsniveau overschrijdt de limiet niet (ESLint-kernregels `complexity` + `max-lines-per-function`) | Ja | -| `check:cognitive-complexity` | Ratchet voor cognitieve complexiteit (`eslint-plugin-sonarjs`) — afzonderlijke ESLint-run; CI voert beide samengevoegd uit als de ene stap `check:complexity-ratchets` | Ja | -| `check:dead-code` | Ratchet voor ongebruikte exports/bestanden (knip) gaat niet achteruit ten opzichte van de baseline | Ja | -| `check:compression-budget` | Budget voor compressiebenchmark — minimale tokenbesparing per engine mag niet achteruitgaan | Ja | -| `check:type-coverage` | Ratchet voor percentage getypeerde code (`type-coverage`) gaat niet achteruit; vervangt grotendeels `typecheck:noimplicit:core` | Ja | -| `check:codeql-ratchet` | Het aantal openstaande CodeQL-meldingen gaat niet achteruit (uitgelezen via `gh api`; gecontroleerd overslaan zonder token) — vernieuwingsfrequentie en handmatige trigger: zie "CodeQL-ratchet" hieronder | Ja | - -### Taak: `quality-extended` - -De volledige taak is adviserend (`continue-on-error: true`). De op npm gebaseerde ratchets worden +| Script (`npm run ...`) | Valideert | Blokkerend | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | De Node.js-versie valt binnen het ondersteunde bereik | Ja | +| `check:cycles` | Cyclische imports in heel `src/` + `open-sse/` (AST-gebaseerd, tsconfig-`paths` opgelost). Zonder extra opties = adviserend, toont de cycli. `check:cycles:ratchet` (wat CI uitvoert) blokkeert wanneer het aantal het `metrics.cycles`-plafond in `quality-baseline.json` overschrijdt — momenteel 14, `direction: down`, dus dit kan alleen dalen (#15159 G-01/G-02) | Ja (ratchet) | +| `check:route-validation:t06` | Zod-schema's aanwezig op alle routes (Tier 6-beleid) | Ja | +| `check:any-budget:t11` | Het aantal `@ts-expect-error // any` overschrijdt het budget niet (Tier 11-ratel) | Ja | +| `check:provider-consistency` | Elke provider in `providers.ts` heeft een overeenkomstige vermelding in `providerRegistry.ts` (en omgekeerd, binnen de allowlist) | Ja | +| `check:model-lifecycle` | De drie handmatig onderhouden routeringstabellen blijven consistent met de ingecheckte levenscyclussnapshot (#11503): `FITNESS_TABLE` (`taskFitness.ts`) kent geen score toe aan een uitgefaseerde id die door `REGISTRY` kan worden gerouteerd; elk doel van `BUILT_IN_ALIASES` is aanwezig in `REGISTRY` en afwezig in de snapshot met uitgefaseerde id's; elke uitgefaseerde id die nog in `REGISTRY` staat, wordt doorgestuurd of vermeld in `allowedRetiredInCatalog`; en geen enkele bron of bestemming van `DEFAULT_DEGRADATION_MAP` wordt in die snapshot als uitgefaseerd aangemerkt. Dit bewijst niet dat een model momenteel door een actieve upstream wordt aangeboden. Offline — vergelijkt met `config/quality/model-lifecycle.json`, handmatig bijgewerkt met `npm run quality:refresh-model-lifecycle` (netwerk; niet geïntegreerd in CI). `allowedRetiredInCatalog` is een afbouwratel: voeg alleen een vermelding toe met een tracking-issue. | Ja | +| `check:fetch-targets` | Elke `fetch("/api/...")` in de client-side `src/` verwijst naar een echte `route.ts` | Ja | +| `check:deps` | Alle via `npm install` installeerbare afhankelijkheden in elke `package.json` in de repo staan in `dependency-allowlist.json`; nieuwe niet-vastgezette of slopsquatted pakketten worden gemarkeerd | Ja | +| `audit:deps` | `npm audit` (root + electron) — geen waarschuwingen met hoge/kritieke ernst (overlapt met OSV-`check:vuln-ratchet`; zie Rationalisatiebacklog) | Ja | +| `check:lockfile` | Integriteit van `package-lock.json` — https-register, integriteitshashes, geen hostoverschrijvingen | Ja | +| `check:licenses` | SPDX-licentie-toestaanlijst voor productieafhankelijkheden | Ja | +| `check:tracked-artifacts` | Geen buildartefacten / vastgelegde `node_modules`-symbolische koppelingen (wordt ook uitgevoerd in husky pre-commit; pre-push is opzettelijk lichtgewicht — #6716) | Ja | +| `check:ai-attribution` | Geen AI-/bot-`Co-Authored-By`-trailer of door AI gegenereerde voettekst in PR-commits, -titel of -tekst — Harde regel #16 (in de snelle-controlelus van `quality.yml` voor PR→`release/**` — leest de eventpayload, no-op buiten PR's — en een uitsluitend voor PR's bestemde stap in de linttaak van `ci.yml` voor PR→`main`; tevens de husky-`commit-msg`-hook; menselijke co-auteurs zijn toegestaan; #14436) | +| `check:vitest-exclusions` | Elke Vitest-uitsluiting vermeldt een trackingissue en komt voor in `config/quality/vitest-exclusions.json` (#13204) | Ja | +| `check:file-size` | Geen bronbestand overschrijdt de limiet per extensie (ratchet: bevroren grote bestanden in de lijst `frozen`) | Ja | +| `check:error-helper` | Foutresponsen in uitvoerders/handlers gebruiken `buildErrorBody()` / `sanitizeErrorMessage()` (Harde regel #12) | Ja | +| `check:migration-numbering` | Migratie-SQL-bestanden zijn opeenvolgend genummerd, zonder hiaten of duplicaten | Ja | +| `check:public-creds` | Geen letterlijke OAuth-`client_id`/`client_secret` of Firebase-websleutels buiten `publicCreds.ts` (Harde regel #11) | Ja | +| `check:db-rules` | Geen ruwe SQL buiten modules in `src/lib/db/`; geen barrel-imports uit `localDb.ts` (Harde regels #2/#5) | Ja | +| `check:known-symbols` | Provider-executors, routeringsstrategieën en translators die in hun dispatch-tabellen zijn geregistreerd, komen overeen met de bestanden op schijf — geen verweesde of niet-gedeclareerde symbolen | Ja | +| `check:route-guard-membership` | Elke route die een onderliggend proces start, is geclassificeerd door `isLocalOnlyPath()` (Harde regels #15/#17) | Ja | +| `check:test-discovery` | Elk `*.test.ts`- / `*.spec.ts`-bestand in de repo wordt door ten minste één test-runner verzameld (ratchet: de lijst met verweesde bestanden in `test-discovery-baseline.json` kan alleen kleiner worden) | Ja | +| `check:agent-skills-sync` | Gegenereerde agent-skills-artefacten komen overeen met hun broncatalogus (geen afwijkingen) | +| `check:provider-asset-provenance` | Providerlogo's/-assets hebben een vastgelegde herkomstvermelding | +| `lint:json` | JSON-configuratiebestanden worden correct geparseerd en voldoen aan de lintregels van de repo | +| `typecheck:core` | TypeScript-compilatie zonder fouten (alleen adviserende waarschuwingen) | Ja | +| `typecheck:noimplicit:core` | Strikte `noImplicitAny` — toekomstgericht; veel reeds bestaande aanroepen hebben nog annotaties nodig | **Adviserend** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` beperkt tot `src/app/(dashboard)/**` (#7033) — de samengestelde allowlist van 27 bestanden van `typecheck:core` bevat geen dashboard-TSX, en `next build` voert hiervoor evenmin typecontrole uit (`next.config.mjs` stelt `ignoreBuildErrors: true` in), waardoor regressies met verweesde identifiers daar (#6625/#6909) onzichtbaar waren voor CI. Verschillen worden vergeleken met een bevroren baseline van aantallen per bestand/per TS-code (`config/quality/dashboard-typecheck-baseline.json`, hetzelfde patroon voor afdwinging bij veroudering als `check:known-symbols`) — alleen NIEUWE fouten boven het aantal in de baseline laten de gate mislukken; verlaag de baseline stapsgewijs met `--update` wanneer een reeds bestaande fout is opgelost. | Ja | + +### Job: `quality-gate` + +Wordt uitgevoerd na `test-coverage`. Blokkeert samenvoegen bij mislukking. + +| Script | Valideert | Blokkerend | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `quality:collect` | Genereert `quality-metrics.json` (aantal ESLint-waarschuwingen, dekking uit samengevoegd shardrapport) | Ja (voorafgaand aan ratchet) | +| `quality:ratchet` | Geen enkele metriek in `quality-baseline.json`` is verslechterd (ESLint-waarschuwingen ≤ baseline; dekking ≥ baseline) | Ja | +| `check:duplication` | Codeduplicatie (jscpd@4) overschrijdt de baseline in `quality-baseline.json` niet | Ja | +| `check:complexity` | Cyclomatische complexiteit op bestandsniveau overschrijdt de limiet niet (ESLint-core `complexity` + `max-lines-per-function`) | Ja | +| `check:cognitive-complexity` | Ratchet voor cognitieve complexiteit (`eslint-plugin-sonarjs`) — afzonderlijke ESLint-uitvoering; CI voert beide samengevoegd uit als de enkele stap `check:complexity-ratchets` | Ja | +| `check:dead-code` | Ratchet voor ongebruikte exports/bestanden (knip) verslechtert niet ten opzichte van de baseline | Ja | +| `check:compression-budget` | Budget voor compressiebenchmarks — minimale tokenbesparingen per engine mogen niet verslechteren | Ja | +| `check:type-coverage` | Ratchet voor het percentage getypeerde code (`type-coverage`) verslechtert niet; omvat grotendeels `typecheck:noimplicit:core` | Ja | +| `check:codeql-ratchet` | Aantal openstaande CodeQL-waarschuwingen verslechtert niet (uitgelezen via `gh api`; wordt zonder token probleemloos overgeslagen) — voor vernieuwingsfrequentie en handmatige trigger: zie 'CodeQL-ratchet' hieronder | Ja | + +### Job: `quality-extended` + +De volledige job is adviserend (`continue-on-error: true`). De op npm gebaseerde ratchets worden daadwerkelijk uitgevoerd; de externe scanners worden geïnstalleerd via `gh release download` en slaan zichzelf over (exit 0) wanneer een binair bestand nog steeds ontbreekt. -| Script | Valideert | Blokkerend | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -| `check:circular-deps` | Geen circulaire afhankelijkheden (dpdm) | **Adviserend** | -| `check:bundle-size` | Bundelgrootte overschrijdt de limiet niet | **Adviserend** | -| `check:secrets` | Scannen op geheimen (gitleaks) — wordt overgeslagen als het binaire bestand ontbreekt | **Adviserend** | -| `check:vuln-ratchet` | Kwetsbaarheden in afhankelijkheden (osv-scanner) gaan niet achteruit — wordt overgeslagen als het binaire bestand ontbreekt | **Adviserend** | -| `check:workflows` | Workflowlinting (actionlint + zizmor); ontbrekende/defecte scanners, ongeldige rapporten of een ontbrekende ratchetbaseline leiden tot INCOMPLETE. Geldige bevindingen volgen het geselecteerde strikte/adviserende/ratchetbeleid | Uitvoering vereist; zizmor-ratchet blokkerend in CI | -| `check:openapi-breaking` | Brekende wijzigingen in het openbare API-contract (`openapi.yaml`) ten opzichte van de basisbranch (oasdiff) — genereert `openapiBreaking=N`; wordt overgeslagen als oasdiff ontbreekt of de basisspecificatie niet kan worden omgezet | **Adviserend** | - -### Taak: `docs-sync-strict` - -Wordt uitgevoerd bij elke PR naar `main`. Blokkeert samenvoegen bij een fout. - -| Script | Valideert | Blokkerend | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `check:docs-all` | Metacontrole die de 6 onderstaande deelcontroles achtereenvolgens uitvoert | Ja | -| ↳ `check:docs-sync` | Versieconsistentie van CHANGELOG / OpenAPI / llm.txt | Ja | -| ↳ `check:docs-counts` | Aantallen in prozatekst (aantal providers, aantal migraties enz.) vallen binnen het ratchetvenster van de werkelijke aantallen | Ja | -| ↳ `check:env-doc-sync` | Elke omgevingsvariabele in `.env.example` is gedocumenteerd in een documentatietabel, en omgekeerd | Ja | -| ↳ `check:deprecated-versions` | Geen verouderde versietekenreeksen in de documentatie | Ja | -| ↳ `check:doc-links` | Interne markdownlinks in de documentatie verwijzen naar bestaande bestanden (`[text]`/`(path)`-vorm) | Ja | -| ↳ `check:fabricated-docs` | Routes, omgevingsvariabelen, CLI-opdrachten, hooknamen en bestandspaden die in de documentatie worden genoemd, bestaan in de codebase. Harde controle via `--strict`; zachte fout zonder vlag. | Ja (via `--strict` in CI) | -| `check:cli-i18n` | CLI-opdrachttekenreeksen zijn aanwezig in alle i18n-localebestanden | Ja | -| `check:openapi-coverage` | De OpenAPI-specificatie dekt ten minste een met een ratchet vastgelegde ondergrens van de werkelijke routes | Ja | -| `check:openapi-security-tiers` | Beveiligingsniveauannotaties in `openapi.yaml` komen overeen met de classificaties in `routeGuard.ts` | **Adviserend** | -| `check:openapi-routes` | Elk pad in `openapi.yaml` verwijst naar een bestaande `route.ts` (anti-hallucinatie) | Ja | -| `check:docs-symbols` | Elke `/api/...`-verwijzing in `docs/**/*.md` verwijst naar een bestaande `route.ts` (anti-hallucinatie) | Ja | -| `i18n translation drift` | Onvertaalde sleutels in i18n-localebestanden — alleen waarschuwen | **Adviserend** | +| Script | Valideert | Blokkerend | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| `check:circular-deps` | Geen circulaire afhankelijkheden (dpdm) | **Adviserend** | +| `check:bundle-size` | Bundelgrootte overschrijdt de limiet niet | **Adviserend** | +| `check:secrets` | Scannen op geheimen (gitleaks) — wordt overgeslagen als het binaire bestand ontbreekt | **Adviserend** | +| `check:vuln-ratchet` | Kwetsbaarheden in afhankelijkheden (osv-scanner) verslechteren niet — wordt overgeslagen als het binaire bestand ontbreekt | **Adviserend** | +| `check:workflows` | Workflow-linting (actionlint + zizmor); ontbrekende/defecte scanners, ongeldige rapporten of een ontbrekende ratchetbaseline leiden tot INCOMPLETE. Geldige bevindingen volgen het geselecteerde strikte/adviserende/ratchetbeleid | Uitvoering vereist; zizmor-ratchet blokkeert in CI | +| `check:openapi-breaking` | Incompatibele wijzigingen in het openbare API-contract (`openapi.yaml`) ten opzichte van de basisbranch (oasdiff) — genereert `openapiBreaking=N`; wordt overgeslagen als oasdiff ontbreekt of de basisspecificatie niet kan worden verwerkt | **Adviserend** | + +### Job: `docs-sync-strict` + +Wordt uitgevoerd bij elke PR naar `main`. Blokkeert samenvoegen bij fouten. + +| Script | Valideert | Blokkerend | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `check:docs-all` | Metapoort die de 6 onderstaande subpoorten achtereenvolgens uitvoert | Ja | +| ↳ `check:docs-sync` | Versieconsistentie tussen CHANGELOG / OpenAPI / llm.txt | Ja | +| ↳ `check:docs-counts` | Aantallen in lopende tekst (aantal providers, aantal migraties enz.) vallen binnen het aanscherpingsvenster van de werkelijke aantallen | Ja | +| ↳ `check:env-doc-sync` | Elke omgevingsvariabele in `.env.example` is gedocumenteerd in een documentatietabel en omgekeerd | Ja | +| ↳ `check:deprecated-versions` | Geen verouderde versietekenreeksen in de documentatie | Ja | +| ↳ `check:doc-links` | Interne markdown-links in de documentatie verwijzen naar bestaande bestanden (`[tekst]`/`(pad)`-vorm) | Ja | +| ↳ `check:fabricated-docs` | Routes, omgevingsvariabelen, CLI-opdrachten, hooknamen en bestandspaden die in de documentatie worden genoemd, bestaan in de codebase. Harde poort via `--strict`; zonder vlag slechts een waarschuwing. | Ja (via `--strict` in CI) | +| `check:cli-i18n` | CLI-opdrachttekenreeksen zijn aanwezig in alle i18n-localebestanden | Ja | +| `check:openapi-coverage` | De OpenAPI-specificatie dekt ten minste een stapsgewijs aangescherpte ondergrens van de werkelijke routes | Ja | +| `check:openapi-security-tiers` | Beveiligingsniveau-annotaties in `openapi.yaml` zijn consistent met de classificaties in `routeGuard.ts` | **Adviserend** | +| `check:openapi-routes` | Elk pad in `openapi.yaml` verwijst naar een bestaande `route.ts` (anti-hallucinatie) | Ja | +| `check:docs-symbols` | Elke `/api/...`-verwijzing in `docs/**/*.md` verwijst naar een bestaande `route.ts` (anti-hallucinatie) | Ja | +| `i18n translation drift` | Onvertaalde sleutels in i18n-localebestanden — alleen waarschuwen | **Adviserend** | ### Taak: `i18n-ui-coverage` -| Script | Valideert | Blokkerend | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (inline) | De dekking van UI-i18n-sleutels is ≥ 65% | Ja | -| `check-ui-value-drift` (inline) | Een herschreven Engelse **waarde** laat geen verouderde vertaling achter | Ja | -| `check-new-key-coverage` (inline) | Een **nieuwe** Engelse sleutel is in elke locale vertaald — een `__MISSING__:`-markering wordt afgewezen | Ja | -| `check-translation-ratio` | De verhouding van echte vertalingen per locale (bladen die identiek zijn aan het Engels / placeholders bevatten / ontbreken en buiten de toelatingslijst vallen) mag `config/quality/i18n-translation-baseline.json` + marge niet overschrijden | **Adviserend** | +| Script | Valideert | Blokkerend | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (inline) | De dekking van i18n-sleutels in de UI is ≥ 65% | Ja | +| `check-ui-value-drift` (inline) | Een herschreven Engelse **waarde** laat geen verouderde vertaling achter | Ja | +| `check-new-key-coverage` (inline) | Een **nieuwe** Engelse sleutel is in elke locale vertaald — een `__MISSING__:`-markering wordt afgewezen | Ja | +| `check-translation-ratio` | De verhouding echte vertalingen per locale (bladen die identiek zijn aan het Engels, placeholders bevatten of ontbreken en niet op de uitzonderingslijst staan) mag `config/quality/i18n-translation-baseline.json` + marge niet overschrijden | **Adviserend** | -Vereist `fetch-depth: 0` — de waardeafwijkingscontrole vergelijkt `en.json` met de merge-base. +Vereist `fetch-depth: 0` — de waardeafwijkingspoort vergelijkt `en.json` met de samenvoegbasis. -#### `check-ui-value-drift` — controle op verouderde vertalingen +#### `check-ui-value-drift` — poort voor verouderde vertalingen -Detecteert de ene i18n-regressie die de andere controles structureel niet kunnen zien: een Engelse waarde -wordt herschreven en de vertalingen die van het _vorige_ Engels zijn afgeleid, blijven staan, waardoor -niet-Engelstalige gebruikers zelfverzekerd geformuleerde, maar inmiddels onjuiste tekst blijven lezen. +Detecteert de ene i18n-regressie die de andere poorten structureel niet kunnen zien: een Engelse waarde +wordt herschreven terwijl de vertalingen die van de _vorige_ Engelse tekst zijn afgeleid, behouden blijven, waardoor +niet-Engelstalige gebruikers overtuigend geformuleerde, maar inmiddels onjuiste tekst blijven lezen. -Dit is daadwerkelijk in productie terechtgekomen. `oauthModal.googleOAuthWarning` werd herschreven toen de Antigravity- -aanmeldhulp werd toegevoegd (#5203); **39 van de 43 locales** behielden tekst die operators vertelde om "de +Dit is daadwerkelijk in productie uitgebracht. `oauthModal.googleOAuthWarning` werd herschreven toen de Antigravity- +inloghelper werd toegevoegd (#5203); **39 van de 43 locales** behielden tekst die operators opdroeg om "de volledige URL te kopiëren en hieronder te plakken" — een proces dat voor die provider niet kan worden voltooid. Dit bleef onopgemerkt tot #8463, omdat: -- `sync-ui-keys` alleen sleutels aanvult die **afwezig** zijn, nooit sleutels die **verouderd** zijn; +- `sync-ui-keys` alleen sleutels aanvult die **ontbreken**, nooit sleutels die **verouderd** zijn; - `check-ui-keys-coverage` de _aanwezigheid_ van sleutels telt, waardoor een verouderde vertaling als gedekt wordt beschouwd; -- `check-translation-drift` de documentatiespiegels in `docs/i18n//**.md` volgt — +- `check-translation-drift` de documentatiespiegels in `docs/i18n//**.md` bijhoudt — deze controle leest nooit `src/i18n/messages/*.json`. Blokkerend in taak `docs-sync-strict` sinds de - hersynchronisatie van 2026-09: bewerk een kerndocument → `npm run i18n:run -- --files=` (op sectieniveau, goedkoop). + hersynchronisatie van 2026-09: bewerk een kerndocument → `npm run i18n:run -- --files=` (per sectie, snel). **Diff-bewust, niet ondersteund door een baseline.** Dit vergelijkt `en.json` op de merge-base met de -werkboom; voor elke sleutel waarvan de Engelse waarde is gewijzigd, is elke locale die nog -een ongewijzigde vertaling bevat verouderd. Dit **bevriest bewust bestaande achterstand** — een diff -kan niet onthullen van welke oude Engelse tekst een al lang bestaande vertaling afkomstig is, dus de controle beoordeelt -alleen wat door de huidige wijziging wordt geraakt. Het alternatief (een baseline met een hash per sleutel) zou +working tree; voor elke sleutel waarvan de Engelse waarde is gewijzigd, is elke locale die nog een +ongewijzigde vertaling bevat verouderd. Hiermee wordt bewust **bestaande achterstand bevroren** — een diff +kan niet aantonen van welke oude Engelse tekst een reeds lang bestaande vertaling afkomstig is, dus de gate beoordeelt +alleen wat door de huidige wijziging wordt geraakt. Het alternatief (een hashbaseline per sleutel) zou een gegenereerd bestand van ~600 KB vereisen, 3× zo groot als de grootste bestaande baseline, dat bij elke i18n-PR wijzigt. -Er zijn twee manieren om eraan te voldoen: +Er zijn twee manieren om hieraan te voldoen: 1. werk de betreffende vertalingen bij, of -2. stel ze in op `__MISSING__:` — de runtime levert dan de gecorrigeerde Engelse tekst - (`src/i18n/request.ts::deepMergeFallback`, #7258) en zet de sleutel in de wachtrij voor vertaling. +2. stel ze in op `__MISSING__:` — de runtime levert dan de gecorrigeerde Engelse tekst + (`src/i18n/request.ts::deepMergeFallback`, #7258) en de sleutel wordt in de wachtrij voor vertaling geplaatst. -Als de **betekenis** van de tekenreeks is gewijzigd, geef dan de voorkeur aan **het hernoemen van de sleutel**: een nieuwe sleutel kan geen +Als de **betekenis** van de tekenreeks is gewijzigd, geef dan bij voorkeur **de sleutel een nieuwe naam**: een nieuwe sleutel kan geen verouderde vertaling overnemen. Dat is het patroon dat in #8463 is gebruikt. ```bash @@ -231,48 +235,48 @@ npm run i18n:check-value-drift:warn # alleen rapporteren BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Eindigt met code 0 en `SKIP reason=base-unresolved` wanneer de basiscatalogus niet kan worden gelezen (ondiepe -clone zonder de basisreferentie), overeenkomstig `check-openapi-breaking`. +Sluit af met 0 en `SKIP reason=base-unresolved` wanneer de basiscatalogus niet kan worden gelezen (ondiepe +clone zonder de base-ref), naar analogie van `check-openapi-breaking`. -### Taak: `i18n` +### Job: `i18n` -Volledige i18n-validatiematrix (één taak per locale). De volledige taak is adviserend. +Volledige i18n-validatiematrix (één job per locale). De volledige job is adviserend. -| Script | Valideert | Blokkerend | -| ------------------------------- | --------------------------------------- | ----------------------------------------------------------------- | -| `validate_translation.py quick` | Volledigheid van vertalingen per locale | **Adviserend** (`continue-on-error: true` voor de volledige taak) | +| Script | Valideert | Blokkerend | +| ------------------------------- | --------------------------------------- | ---------------------------------------------------------------- | +| `validate_translation.py quick` | Volledigheid van vertalingen per locale | **Adviserend** (`continue-on-error: true` voor de volledige job) | -### Taak: `pr-test-policy` +### Job: `pr-test-policy` Wordt alleen uitgevoerd voor pull requests. -| Script | Valideert | Blokkerend | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PR's die productiecode in `src/`, `open-sse/`, `electron/` of `bin/` wijzigen, moeten tests toevoegen of bijwerken (Harde regel #8) | Ja | -| `check:test-masking` | Gewijzigde testbestanden verlagen het nettoaantal asserts niet en voegen geen `assert.ok(true)`-tautologieën toe | Ja | -| `check:pr-evidence` | De PR-beschrijving vermeldt bewijs van tests/VPS voor de wijziging (automatiseert Harde regel #18 door PR-tekst te doorzoeken — kwetsbaar, zie Backlog) | Ja | +| Script | Valideert | Blokkerend | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | +| `check:pr-test-policy` | PR's die productiecode wijzigen in `src/`, `open-sse/`, `electron/` of `bin/`, moeten tests toevoegen of bijwerken (harde regel #8) | Ja | +| `check:test-masking` | Gewijzigde testbestanden verlagen het nettoaantal assertions niet en voegen geen `assert.ok(true)`-tautologieën toe | Ja | +| `check:pr-evidence` | De PR-beschrijving vermeldt test-/VPS-bewijs voor de wijziging (automatiseert harde regel #18 door de PR-tekst te doorzoeken — kwetsbaar, zie Backlog) | Ja | -### Taak: `test-vitest` +### Job: `test-vitest` -Wordt uitgevoerd na `build`. Blokkeert samenvoegen bij fouten. +Wordt uitgevoerd na `build`. Blokkeert samenvoegen bij een fout. -| Suite | Valideert | Blokkerend | -| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-server (110 tools), autoCombo, cache — vitest-runner | Ja | -| `test:vitest:ui` | UI-componenttests — vitest-runner | **Blokkerend** — reeds bestaande fouten zijn expliciet uitgesloten in `vitest.config.ts`; nieuwe fouten laten de taak mislukken | +| Suite | Valideert | Blokkerend | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP-server (110 tools), autoCombo, cache — vitest-runner | Ja | +| `test:vitest:ui` | UI-componenttests — vitest-runner | **Blokkerend** — reeds bestaande fouten zijn expliciet uitgesloten in `vitest.config.ts`; nieuwe fouten laten de job mislukken | ### Nachtelijke workflows (gepland, adviserend) Deze worden volgens een cron-schema uitgevoerd (en via `workflow_dispatch`), nooit voor PR's. Ze zijn allemaal adviserend. -| Workflow | Valideert | Blokkerend | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | fast-check-eigenschapstests met een willekeurige seed en een hoog aantal uitvoeringen | **Adviserend** | -| `nightly-resilience` | controle op heapgroei, chaos-foutinjectie, k6-belastings-/duurtest | **Adviserend** | -| `nightly-llm-security` | promptfoo-injectiebeveiliging (blokkeermodus) + garak-probes (overgeslagen zonder providergeheim) | **Adviserend** | -| `nightly-schemathesis` | OpenAPI-contractfuzzing (schemathesis) tegen een actieve OmniRoute met `docs/openapi.yaml` — brengt specificatieschendingen / niet-afgehandelde 500-fouten aan het licht (Fase 8 B.4) | **Adviserend** | -| `nightly-mutation` | Stryker-mutatie-testscore voor de snelle unit-lane — overlevende mutanten brengen zwakke asserts aan het licht | **Adviserend** | -| `nightly-compat` | Compatibiliteitsmatrix voor de Node-engine voor de ondersteunde `engines.node`-bereiken | **Adviserend** | +| Workflow | Valideert | Blokkerend | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | fast-check-propertytests met een willekeurige seed en een hoog aantal runs | **Adviserend** | +| `nightly-resilience` | gate voor heapgroei, chaos-foutinjectie, k6-load-/soaktests | **Adviserend** | +| `nightly-llm-security` | promptfoo-injectiebeveiliging (blokkeermodus) + garak-probes (overgeslagen zonder providersecret) | **Adviserend** | +| `nightly-schemathesis` | OpenAPI-contractfuzzing (schemathesis) tegen een live OmniRoute met `docs/openapi.yaml` — brengt specificatieschendingen/onafgehandelde 500-fouten aan het licht (fase 8 B.4) | **Adviserend** | +| `nightly-mutation` | Stryker-mutatietestscore voor de snelle unit-lane — overlevende mutanten leggen zwakke assertions bloot | **Adviserend** | +| `nightly-compat` | Compatibiliteitsmatrix voor de Node-engine over de ondersteunde `engines.node`-bereiken | **Adviserend** | --- @@ -543,37 +547,37 @@ Deze inventaris is op 2026-06-17 afgestemd op `ci.yml` (in de vorige versie ontb `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Een ROI-beoordeling van de afgestemde set -bracht de volgende kandidaten voor rationalisatie aan het licht. **De samenvoegingen zijn mechanische CI- -wijzigingen; de omzettingen/verwijderingen zijn beleidsbeslissingen die aan de operator zijn voorbehouden.** Niets hieronder +heeft de volgende kandidaten voor rationalisatie opgeleverd. **De samenvoegingen zijn mechanische CI- +wijzigingen; de omschakelingen/verwijderingen zijn beleidsbeslissingen die aan de operator zijn voorbehouden.** Niets hieronder is al toegepast. -**Hierboven ook niet gedocumenteerd** (adviserend, zwak signaal): de `docs-lint`-job -(markdownlint + Vale, de volledige job met `continue-on-error`) en de zelfstandige scannerworkflows +**Hierboven eveneens niet gedocumenteerd** (adviserend, weinig signaal): de `docs-lint`-job +(markdownlint + Vale, volledige job met `continue-on-error`) en de zelfstandige scannerworkflows `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` staat in `quality-baseline.json`, maar is niet gekoppeld aan een blokkerende ratchet in `ci.yml` — de metriek is momenteel verweesd. ### Samenvoegen / dedupliceren (mechanisch, lager risico) -Elke kandidaat is op 2026-06-17 gevalideerd tegen de actuele status van de gates (vertrouw, maar verifieer); -verschillende „voor de hand liggende” samenvoegingen bleken verborgen technische schuld te bevatten en zijn **geen** directe vervangingen. +Elke kandidaat is op 2026-06-17 gevalideerd aan de hand van de actuele gatestatus (vertrouwen-maar-verifiëren); +verscheidene „voor de hand liggende” samenvoegingen bleken verborgen achterstand te bevatten en zijn **geen** probleemloze vervangingen. - **`check:docs-sync` wordt tweemaal uitgevoerd** — zelfstandig in de `lint`-job en opnieuw binnen `check:docs-all` (`docs-sync-strict`) en de husky-pre-commithook. ✅ **VOLTOOID** — zelfstandige aanroep in `lint` verwijderd. -- **CVE-scanning** — ❌ **GEEN zuivere samenvoeging.** `audit:deps` faalt hard bij elke CVE met hoge/kritieke ernst; `check:vuln-ratchet` (osv) faalt alleen bij een _regressie_ ten opzichte van de baseline (momenteel 1 MODERATE). Verschillende semantiek — door `audit:deps` te verwijderen zou de absolute gate voor hoge/kritieke ernst verloren gaan. Behoud beide. -- **Cyclusdetectie** — ❌ **GEEN zuivere samenvoeging.** `check:circular-deps` (dpdm) rapporteert **91 cycli** (daarom is deze adviserend); deze kan niet blokkerend worden gemaakt zonder ze eerst op te lossen en heeft een breder bereik dan de groene, zorgvuldig samengestelde `check:cycles`. Behoud `check:cycles` als blokkerend; het oplossen van de 91 dpdm-cycli vormt een afzonderlijke backlog. -- **Complexiteit** — ✅ **VOLTOOID** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): één ESLint-scan, telt per ruleId zodat de baselines voor cyclomatische complexiteit + maximaal aantal regels en cognitieve complexiteit onafhankelijk blijven; afzonderlijke `check:complexity` / `check:cognitive-complexity` blijven behouden voor lokale `--update`. -- **`/api`-antihallucinatie** — ✅ **VOLTOOID** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): één bestandssysteeminventarisatie van `src/app/api`; openapi-routes + docs-symbols blijven onafhankelijk rapporteren; afzonderlijke controles blijven behouden voor lokale uitvoeringen. -- **`check:node-runtime` wordt in 11 jobs uitgevoerd** — ⚠️ **lage ROI.** Elke job gebruikt een afzonderlijke runner en de controle duurt <1 s; totale besparing ~10 s, tegenover het verlies van een goedkope beveiliging per job. De verstoring niet waard. -- **`typecheck:noimplicit:core` bij CI-linting** — ✅ **verwijderd uit de lint-job** (was adviserend met `continue-on-error`); het blokkerende type-oppervlak bestaat uit `typecheck:core` + `check:type-coverage`. Lokaal script behouden. - -### Omzetten / beslissen (operatorbeleid) - -- `check:openapi-security-tiers` (adviserend) — ❌ **NIET zonder meer om te zetten.** Deze eindigt met 0, maar waarschuwt dat meerdere `traffic-inspector`-routes onder `LOCAL_ONLY_API_PREFIXES` de annotatie `x-loopback-only: true` missen. Handhaving vereist dat die annotaties eerst aan `openapi.yaml` worden toegevoegd. -- `typecheck:noimplicit:core` (adviserend) — grotendeels afgedekt door de blokkerende `check:type-coverage`-ratchet. Zet deze om naar een ratchet of verwijder de redundante tweede `tsc`-doorgang. -- `test:vitest:ui` (nu **blokkerend**) — reeds bestaande fouten zijn expliciet uitgesloten in `vitest.config.ts` met `// #8618`-trackingopmerkingen; nieuwe fouten laten de job mislukken. -- `check:secrets` (gitleaks, blokkerende ratchet bevroren op 3 gedocumenteerde fout-positieven) — voeg de 3 toe aan de allowlist om 0 te bereiken, of degradeer deze naar adviserend. Overlapt met de ingebouwde secret-scanning van GitHub + `check:public-creds`. -- `check:pr-evidence` (blokkerend, doorzoekt de prozatekst van PR-beschrijvingen) — hoog risico op fout-positieven; verwijdering verzwakt de handhaving van Hard Rule #18, dus dit is een echte beleidsbeslissing. -- `semgrep` (zelfstandig, adviserend) — overlapt met CodeQL voor de OWASP-categorieën; koppel de baseline aan een ratchet of verwijder deze. +- **CVE-scanning** — ❌ **GEEN probleemloze samenvoeging.** `audit:deps` faalt hard bij elke hoge/kritieke CVE; `check:vuln-ratchet` (osv) faalt alleen bij een _regressie_ ten opzichte van de baseline (momenteel 1 MODERATE). Verschillende semantieken — door `audit:deps` te verwijderen zou de absolute gate voor hoge/kritieke kwetsbaarheden verloren gaan. Beide behouden. +- **Cyclusdetectie** — ✅ **VOLTOOID** (#15159 G-01/G-02). De oude tekst noemde `check:cycles` de „groene, gecureerde” gate en rechtvaardigde het blokkerend houden ervan omdat `check:circular-deps` (dpdm) 91 cycli rapporteerde. Dat groen was **vals groen**: `check:cycles` scande 5 submappen (450 bestanden), herkende alleen statische `import|export … from` en negeerde elke `@/`- en `@omniroute/open-sse/`-specifier, waardoor de door dynamische imports en aliassen gedomineerde cycli in de repo niet zichtbaar waren. Opgelost: de gate doorloopt nu `src` + `open-sse` (5023 bestanden), verzamelt specifiers uit de TypeScript-AST (waardoor `import("…")` meetelt en `typeof import("…")` in een typepositie niet) en verwerkt de `paths` uit tsconfig. De gate vindt **14** cycli, niet 0. Omdat 14 bestaande cycli niet in een gate-PR kunnen worden opgelost, is `check:cycles` nu een **ratchet** (`--ratchet`, plafond `metrics.cycles.value = 14` in `quality-baseline.json`, `direction: down`) — deze blokkeert elke _regressie_ en het aantal kan alleen dalen. CI voert `npm run check:cycles:ratchet` uit. De afbouw loopt mee met **A-01**. `check:circular-deps` (dpdm) blijft adviserend als bredere second opinion. +- **Complexiteit** — ✅ **VOLTOOID** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): één ESLint-doorloop, tellingen per ruleId zodat de cyclomatische+max-lines- en cognitieve baselines onafhankelijk blijven; de afzonderlijke `check:complexity` / `check:cognitive-complexity` blijven beschikbaar voor lokaal gebruik met `--update`. +- **`/api`-anti-hallucinatie** — ✅ **VOLTOOID** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): één FS-inventarisatie van `src/app/api`; openapi-routes + docs-symbols blijven onafhankelijk rapporteren; de afzonderlijke controles blijven beschikbaar voor lokale uitvoeringen. +- **`check:node-runtime` wordt in 11 jobs uitgevoerd** — ⚠️ **lage ROI.** Elke job gebruikt een afzonderlijke runner en de controle duurt <1s; totale besparing ~10s, ten koste van een goedkope beveiliging per job. De verstoring niet waard. +- **`typecheck:noimplicit:core` in CI-lint** — ✅ **verwijderd uit de lint-job** (was adviserend met `continue-on-error`); het blokkerende typeoppervlak bestaat uit `typecheck:core` + `check:type-coverage`. Lokaal script behouden. + +### Omschakelen / beslissen (operatorbeleid) + +- `check:openapi-security-tiers` (adviserend) — ❌ **NIET probleemloos omschakelbaar.** Deze eindigt met 0, maar waarschuwt dat meerdere `traffic-inspector`-routes onder `LOCAL_ONLY_API_PREFIXES` de annotatie `x-loopback-only: true` missen. Afdwinging vereist dat die annotaties eerst aan `openapi.yaml` worden toegevoegd. +- `typecheck:noimplicit:core` (adviserend) — grotendeels afgedekt door de blokkerende `check:type-coverage`-ratchet. Schakel om naar een ratchet of verwijder de redundante tweede `tsc`-doorloop. +- `test:vitest:ui` (nu **blokkerend**) — bestaande fouten zijn expliciet uitgesloten in `vitest.config.ts` met `// #8618`-trackingopmerkingen; nieuwe fouten laten de job mislukken. +- `check:secrets` (gitleaks, blokkerende ratchet vastgezet op 3 gedocumenteerde foutpositieven) — zet de 3 op de allowlist om 0 te bereiken, of degradeer de controle tot adviserend. Overlapt met de ingebouwde secret-scanning van GitHub + `check:public-creds`. +- `check:pr-evidence` (blokkerend, doorzoekt de prozatekst van de PR-body met grep) — hoog risico op foutpositieven; verwijdering verzwakt de handhaving van Hard Rule #18, dus dit is een echte beleidsbeslissing. +- `semgrep` (zelfstandig adviserend) — overlapt met CodeQL voor de OWASP-categorieën; koppel de baseline aan een ratchet of verwijder de controle. --- diff --git a/docs/i18n/no/CONTRIBUTING.md b/docs/i18n/no/CONTRIBUTING.md index acb7c3f1d5d..5d64ec9a1f3 100644 --- a/docs/i18n/no/CONTRIBUTING.md +++ b/docs/i18n/no/CONTRIBUTING.md @@ -391,18 +391,18 @@ Skriv enhetstester i `tests/unit/` som minst dekker: - [ ] Tester består (`npm test`) - [ ] Linting består (`npm run lint`) -- [ ] Bygging lykkes (`npm run build`) +- [ ] Bygging fullføres (`npm run build`) - [ ] TypeScript-typer er lagt til for nye offentlige funksjoner og grensesnitt - [ ] Ingen hardkodede hemmeligheter eller reserveverdier -- [ ] Offentlig tilgjengelig oppstrømslegitimasjon er innebygd via `resolvePublicCred()` (se [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), aldri som literalverdier -- [ ] Feilsvar går gjennom `buildErrorBody()` / `sanitizeErrorMessage()` — ingen rå stakkspor i svarinnholdet (se [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Offentlig tilgjengelig påloggingsinformasjon for oppstrømstjenester bygges inn via `resolvePublicCred()` (se [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), aldri som litteraler +- [ ] Feilsvar går gjennom `buildErrorBody()` / `sanitizeErrorMessage()` — ingen rå stakksporinger i svarinnhold (se [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Skallkommandoer (`exec` / `spawn`) sender kjøretidsverdier via `env`, ikke via strenginterpolasjon - [ ] Alle inndata valideres med Zod-skjemaer -- [ ] Et **fragment** til endringsloggen er lagt til under `changelog.d/{features|fixes|maintenance}/-.md` for endringer som er synlige for brukerne (se [`changelog.d/README.md`](./changelog.d/README.md)) — **ikke** rediger `CHANGELOG.md` direkte; fragmentene samles ved utgivelse og skaper aldri konflikter mellom pull requests +- [ ] En **fragmentfil** for endringsloggen er lagt til under `changelog.d/{features|fixes|maintenance}/-.md` for brukersynlige endringer (se [`changelog.d/README.md`](./changelog.d/README.md)) — rediger **ikke** `CHANGELOG.md` direkte; fragmentene samles ved utgivelse og skaper aldri konflikter mellom pull request-er - [ ] Dokumentasjonen er oppdatert (hvis aktuelt) -- [ ] Ingen nye CodeQL-varsler eller varsler fra Secret-Scanning er åpnet, eller hvert varsel er avvist med en teknisk begrunnelse som henviser til det relevante dokumentet under `docs/security/` +- [ ] Ingen nye CodeQL-/Secret-Scanning-varsler er opprettet, eller hvert varsel er avvist med en teknisk begrunnelse som henviser til det relevante dokumentet under `docs/security/` - [ ] Ruter som starter underprosesser (`/api/mcp/`, `/api/cli-tools/runtime/`), er klassifisert som `isLocalOnlyPath()` i `src/server/authz/routeGuard.ts` — se [ufravikelig regel nr. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Ingen `Co-Authored-By`-trailere i commit-meldinger — commits må utelukkende vises under repository-eierens Git-identitet (ufravikelig regel nr. 16) +- [ ] Ingen AI-/bot-`Co-authored-by`-trailere i commit-meldinger (ufravikelig regel nr. 16) — menneskelige samarbeidspartnere hvis arbeid gjenbrukes, krediteres med standardtrailere av typen `Co-authored-by: Name ` --- diff --git a/docs/i18n/no/docs/architecture/QUALITY_GATES.md b/docs/i18n/no/docs/architecture/QUALITY_GATES.md index 29f38bb6ed0..aed0cf3d29e 100644 --- a/docs/i18n/no/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/no/docs/architecture/QUALITY_GATES.md @@ -15,37 +15,37 @@ replikeringsplanen for det samme systemet, se --- -## Portoversikt og kjøringsprofiler +## Portvaktoversikt og kjøringsprofiler ### Kandidatgodkjenning -Arbeidsflytene for CI og kvalitetsporter avgir hver sin stabile avgjørelse: `Gate / CI` og +Arbeidsflytene for CI og kvalitetsporter avgir hver sin stabile konklusjon: `Gate / CI` og `Gate / Quality`. Den versjonerte godkjenningspolicyen deres angir hver oppstrømsjobb -som obligatorisk eller rådgivende. En gjeldende obligatorisk jobb må lykkes: manglende, +som obligatorisk eller veiledende. En aktuell obligatorisk jobb må lykkes: manglende, avbrutte, hoppede over, ventende og ukjente resultater kan ikke fastslå PASS. En gyldig -klassifisering som bare gjelder dokumentasjon eller katalogen, kan gjøre et kodespor irrelevant; -en PR merket som utkast er ikke en godkjent kandidat. En `hotfix`-etikett fritar ikke fra dokumentasjonskrav. +klassifisering som kun dokumentasjon eller kun katalog kan gjøre et kodespor uaktuelt; +en PR som er et utkast, er ikke en godkjent kandidat. En `hotfix`-etikett fritar ikke fra dokumentasjonskrav. -Begge arbeidsflytene dekker PR-er og push til main/release-grener, manuell oppstart og -merge-group-hendelser. Push, dispatch og merge-group kjører hele utvalget. Forker +Begge arbeidsflytene dekker PR-er og push til main-/release-grener, manuell kjøring og +merge-group-hendelser. Push, manuell kjøring og merge-group kjører hele utvalget. Forker og merge groups bruker driftede kjørere for jobber som ellers velger selvdriftede kjørere; tilstrekkelig driftet kapasitet må verifiseres før utrulling. -Hver JSON-kvittering identifiserer SHA-en som er sjekket ut, arbeidsflytkjøringen og forsøket. -CLI-verktøyet avviser avvik mellom SHA-en for checkout og hendelsen. Arbeidsflyttester knytter policymedlemskap -til avgjørelsesjobbens `needs`-liste, slik at et nytt eller fjernet spor ikke kan forsvinne ubemerket. -Kvitteringene dekker sin egen arbeidsflyt, ikke publisering, distribusjon eller det interne -i en eksisterende rådgivende skanner. Aktivering av begge kontrollnavnene i grenreglene er en -separat administrativ endring; å legge til disse jobbene beskytter ikke i seg selv en gren. +Hver JSON-kvittering identifiserer utsjekket SHA, arbeidsflytkjøring og forsøk. +CLI-en avviser manglende samsvar mellom SHA for utsjekking og hendelse. Arbeidsflyttester knytter policymedlemskap +til konklusjonsjobbens `needs`-liste, slik at et nytt eller fjernet spor ikke kan forsvinne ubemerket. +Kvitteringene dekker deres egen arbeidsflyt, ikke publisering, utrulling eller den interne virkemåten +til en eksisterende veiledende skanner. Aktivering av begge kontrollnavnene i grenreglene er en +separat administrativ endring; det å legge til disse jobbene beskytter ikke i seg selv en gren. ### Oversikt over statisk skanning -Den versjonerte oversikten over npm-aliaser og medlemskapet i statisk skanning finnes i +Den versjonerte oversikten over npm-aliaser og medlemskapet i den statiske skanningen ligger i `config/quality/gate-manifest.json`. Kjør `npm run check:gate-manifest` for å validere skriptnavn og eksakte kommandoer mot `package.json`; tillegg, fjerninger og -kommandoavvik gjør at både den lokale hooken og jobbene for endringsklassifisering i CI feiler. -Et alias er ikke en arbeidsflytjobb, matriseinstans eller testtilfelle: disse antallene må -ikke fremstilles som om de er innbyrdes utskiftbare. +kommandoavvik fører til feil både i den lokale hooken og jobbene for endringsklassifisering i CI. +Et alias er ikke en arbeidsflytjobb, matriseinstans eller testsak: disse antallene må +ikke fremstilles som om de er utskiftbare. Bruk `npm run quality:scan -- --list` eller `npm run quality:scan:fast -- --list` for å inspisere de valgte aliasene uten å kjøre dem. Kjøreren starter @@ -54,176 +54,177 @@ Manifestet registrerer aliaser utenfor disse profilene som separat startet, og vedlikeholdskommandoer er forbudt i skrivebeskyttede skanneprofiler. Disse profilene dekker bare den statiske skanningen. De sertifiserer ikke produkttester, -dekning, pakking, eksterne kontroller eller en kandidats fullstendige utgivelsesgodkjenning. -Godkjenning i arbeidsflyten bruker den tilknyttede `config/quality/admission-policy.json` og -`scripts/quality/admission-verdict.mjs`. Profiler for utgivelsesobservatører forblir separate; -inspiser de gjeldende kontrollene og kvitteringene deres uavhengig. Prosaoversikten +dekning, pakking, eksterne kontroller eller en kandidats fullstendige release-godkjenning. +Arbeidsflytens godkjenning bruker den tilknyttede `config/quality/admission-policy.json` og +`scripts/quality/admission-verdict.mjs`. Profiler for release-observatører forblir separate; +inspiser de aktuelle kontrollene og kvitteringene deres uavhengig. Prosaoversikten nedenfor er en referanse, ikke et bevis på at en port faktisk ble kjørt. -Skript finnes under `scripts/check/` (policyporter) og `scripts/quality/` (ratchet-motor). -Kilden til sannhet for CI er `.github/workflows/ci.yml`. +Skript ligger under `scripts/check/` (policyporter) og `scripts/quality/` (ratchet-motor). +CI-kilden til sannhet er `.github/workflows/ci.yml`. -### Hurtigspor for utgivelses-PR (`quality.yml`) +### Hurtigspor for release-PR-er (`quality.yml`) -`.github/workflows/quality.yml` utfyller CI for PR-er mot main/release, push til beskyttede grener, -dispatch og merge groups. PR-er bruker hurtigkontroller filtrert etter filsti. Den permanent -deaktiverte dupliserte bygningen ble fjernet; de reelle kontrollene for bygging/pakking/oppstart forblir i CI. +`.github/workflows/quality.yml` supplerer CI for PR-er mot main-/release-grener, push til beskyttede grener, +manuell kjøring og merge groups. PR-er bruker hurtigkontroller filtrert etter sti. Den permanent +deaktiverte duplikatbyggingen ble fjernet; de virkelige kontrollene for bygging/pakking/oppstart forblir i CI. -| Job | Omfang | Blokkerende | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| `Docs Gates (fast-path)` | Dokumentasjons-/kode-PR-er; referanser i API-dokumentasjon og all dokumentasjon | Ja | -| `Fast Quality Gates` | Kode-PR-er; statiske kontroller, typekontroll, typekontroll av kontrollpanel, berørte enhetstester | Ja | -| `Forgotten sibling tests` | Kode-PR-er; endrede moduler spores til statiske konsumenter og aktuelle søstertester; barrel- og dynamic-import-stier rapporteres som rådgivende diagnostikk, med refererte unntak i tillatelseslisten | **Rådgivende** | -| `Vitest (fast-path)` | Kode-PR-er; rask Vitest-testsamling | Ja | -| `Unit Tests fast-path` | Kode-PR-er; enhetstestsamling med 4 shards | Ja | -| `No new ESLint warnings` | Kode-PR-er; undertrykkelsesbevisst lint-vakt | Ja, inkludert forker | -| `Merge integrity (changelog + generated skills)` | PR-er som ikke er utkast; synkronisering av endringslogg og genererte ferdigheter | Ja, inkludert forker | +| Jobb | Omfang | Blokkerende | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | Dokumentasjons-/kode-PR-er; referanser i API-dokumentasjon og all dokumentasjon | Ja | +| `Fast Quality Gates` | Kode-PR-er; statiske kontroller, typekontroll, typekontroll av dashbord, berørte enhetstester | Ja | +| `Forgotten sibling tests` | Kode-PR-er; endrede moduler spores til statiske konsumenter og aktuelle søstertester; barrel- og dynamiske importstier rapporteres som veiledende diagnostikk, med refererte unntak i tillatelseslisten | **Veiledende** | +| `Vitest (fast-path)` | Kode-PR-er; rask Vitest-testpakke | Ja | +| `Unit Tests fast-path` | Kode-PR-er; enhetstestpakke med 4 sharder | Ja | +| `No new ESLint warnings` | Kode-PR-er; undertrykkelsesbevisst lint-vakt | Ja, inkludert forker | +| `Merge integrity (changelog + generated skills)` | PR-er som ikke er utkast; synkronisering av endringslogg og genererte ferdigheter | Ja, inkludert forker | #### Rapport om glemte søstertester -`npm run check:forgotten-sibling-tests` gjenbruker importløseren bak kartet over testpåvirkning. -For hver endrede produksjonsmodul rapporterer det deterministiske kjeder av typen -`changed module/symbol -> static consumer -> candidate sibling test` når den aktuelle -testen mangler i diffen for pull requesten. Markdown-sammendraget og JSON-resultatet beholdes som +`npm run check:forgotten-sibling-tests` gjenbruker importresolveren bak kartet over testpåvirkning. +For hver endrede produksjonsmodul rapporterer den deterministiske +`changed module/symbol -> static consumer -> candidate sibling test`-kjeder når den aktuelle +testen ikke finnes i pull-request-diffen. Markdown-sammendraget og JSON-resultatet beholdes som arbeidsflytartefaktet `forgotten-sibling-tests` for kalibrering før eventuell blokkerende utrulling. -Barrel-reeksporter og dynamiske importer er kun oppløsningsdiagnostikk; de oppretter aldri et +Barrel-gjeneksporter og dynamiske importer er kun oppløsningsdiagnostikk; de oppretter aldri et blokkerende funn. Gjennomgåtte unntak ligger i `config/quality/forgotten-sibling-allowlist.json`. Hver oppføring må angi konsumenten og den aktuelle -testen, gi en spesifikk begrunnelse og lenke til en GitHub-sak eller pull request. Feilformaterte oppføringer -avvises. Unntak kan ikke skjule en slettet aktuell test eller en diff som legger til `.skip`/`.todo`; -svekkelse av asserter og annen maskering håndteres fortsatt av den uavhengig blokkerende +testen, oppgi en spesifikk begrunnelse og lenke til en GitHub-sak eller pull request. Feilformaterte oppføringer +avvises. Unntak kan ikke undertrykke en slettet aktuell test eller en diff som legger til `.skip`/`.todo`; +svekkelse av assertions og annen maskering håndteres fortsatt av den uavhengig blokkerende `check:test-masking`-porten. ### Jobb: `lint` -Kjøres på hver PR til `main`. Blokkerer sammenslåing ved feil. - -| Skript (`npm run ...`) | Validerer | Blokkerende | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Node.js-versjonen er innenfor det støttede området | Ja | -| `check:cycles` | Sirkulære importer — alle moduler i `src/` + `open-sse/` | Ja | -| `check:route-validation:t06` | Zod-skjemaer finnes på alle ruter (retningslinjer for nivå 6) | Ja | -| `check:any-budget:t11` | Antallet `@ts-expect-error // any` overskrider ikke budsjettet (nivå 11-sperre) | Ja | -| `check:provider-consistency` | Hver leverandør i `providers.ts` har en tilsvarende oppføring i `providerRegistry.ts` (og omvendt, innenfor tillatelseslisten) | Ja | -| `check:model-lifecycle` | De tre manuelt vedlikeholdte rutingtabellene forblir konsistente med det innsjekkede livssyklusøyeblikksbildet (#11503): `FITNESS_TABLE` (`taskFitness.ts`) gir ingen utfaset ID en poengsum som `REGISTRY` kan rute; hvert mål i `BUILT_IN_ALIASES` finnes i `REGISTRY` og er fraværende i øyeblikksbildet over utfasede ID-er; hver utfaset ID som fortsatt finnes i `REGISTRY`, videresendes eller er oppført i `allowedRetiredInCatalog`; og ingen kilde eller mål i `DEFAULT_DEGRADATION_MAP` er markert som utfaset i dette øyeblikksbildet. Dette beviser ikke at en modell for øyeblikket betjenes av en aktiv oppstrømstjeneste. Frakoblet — sammenligner med `config/quality/model-lifecycle.json`, som oppdateres manuelt med `npm run quality:refresh-model-lifecycle` (krever nettverk; ikke koblet til CI). `allowedRetiredInCatalog` er en nedtrappingssperre: legg bare til en oppføring med en sporingssak. | Ja | -| `check:fetch-targets` | Hver `fetch("/api/...")` i `src/` på klientsiden peker til en faktisk `route.ts` | Ja | -| `check:deps` | Alle avhengigheter som kan installeres med `npm install`, på tvers av alle `package.json` i repositoriet, finnes i `dependency-allowlist.json`; nye pakker uten fastlåst versjon eller pakker utsatt for slopsquatting flagges | Ja | -| `audit:deps` | `npm audit` (rot + electron) — ingen varsler med høy eller kritisk alvorlighetsgrad (overlapper med osv `check:vuln-ratchet`; se rasjonaliseringslisten) | Ja | -| `check:lockfile` | Integriteten til `package-lock.json` — https-register, integritetshasher, ingen overstyringer av vert | Ja | -| `check:licenses` | Tillatt SPDX-lisensliste for produksjonsavhengigheter | Ja | -| `check:tracked-artifacts` | Ingen byggartefakter / innsendte `node_modules`-symbolske lenker (kjøres også i husky pre-commit; pre-push er med hensikt lettvektig — #6716) | Ja | -| `check:ai-attribution` | Ingen AI-/bot-generert `Co-Authored-By`-ettertekst eller AI-genereringsbunntekst i PR-committer, tittel eller brødtekst — hard regel #16 (i hurtigkontrollsløyfen i `quality.yml` for PR→`release/**` — leser hendelsesnyttelasten, gjør ingenting utenfor PR-er — og et trinn kun for PR-er i `ci.yml`-linting for PR→`main`; også husky-kroken `commit-msg`; menneskelige medforfattere er tillatt; #14436) | -| `check:vitest-exclusions` | Hvert Vitest-unntak angir en sporingssak og finnes i `config/quality/vitest-exclusions.json` (#13204) | Ja | -| `check:file-size` | Ingen kildefil overskrider grensen per filtype (skralle: fryste store filer i `frozen`-listen) | Ja | -| `check:error-helper` | Feilsvar i eksekverere/behandlere bruker `buildErrorBody()` / `sanitizeErrorMessage()` (hard regel #12) | Ja | -| `check:migration-numbering` | SQL-filer for migrering er nummerert sekvensielt, uten hull eller duplikater | Ja | -| `check:public-creds` | Ingen bokstavelige OAuth-verdier for `client_id`/`client_secret` eller Firebase Web-nøkler utenfor `publicCreds.ts` (ufravikelig regel nr. 11) | Ja | -| `check:db-rules` | Ingen rå SQL utenfor moduler i `src/lib/db/`; ingen samleimporter fra `localDb.ts` (ufravikelige regler nr. 2/5) | Ja | -| `check:known-symbols` | Leverandøreksekverere, rutingsstrategier og oversettere som er registrert i sine rutingtabeller, samsvarer med filene på disken — ingen foreldreløse eller udeklarerte symboler | Ja | -| `check:route-guard-membership` | Hver rute som starter en underprosess, er klassifisert av `isLocalOnlyPath()` (ufravikelige regler nr. 15/17) | Ja | -| `check:test-discovery` | Hver `*.test.ts`- / `*.spec.ts`-fil i repositoriet samles inn av minst én testkjører (sperrehake: listen over foreldreløse filer i `test-discovery-baseline.json` kan bare krympe) | Ja | -| `check:agent-skills-sync` | Genererte agent-skills-artefakter samsvarer med kildekatalogen (ingen avvik) | -| `check:provider-asset-provenance` | Leverandørlogoer/-ressurser har en registrert oppførsel om opphav | -| `lint:json` | JSON-konfigurasjonsfiler kan tolkes og oppfyller repoets lint-regler | -| `typecheck:core` | TypeScript-kompilering uten feil (kun rådgivende advarsler) | Ja | -| `typecheck:noimplicit:core` | Streng `noImplicitAny` — fremoverskuende; mange eksisterende kallsteder trenger fortsatt annotasjoner | **Rådgivende** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` avgrenset til `src/app/(dashboard)/**` (#7033) — den kuraterte tillatelseslisten med 27 filer i `typecheck:core` inkluderer ingen dashboard-TSX-filer, og `next build` typekontrollerer dem heller aldri (`next.config.mjs` angir `ignoreBuildErrors: true`), så regresjoner med foreldreløse identifikatorer der (#6625/#6909) var usynlige for CI. Sammenligner med en frosset grunnlinje for antall per fil/per TS-kode (`config/quality/dashboard-typecheck-baseline.json`, samme håndhevingsmønster for foreldede oppføringer som `check:known-symbols`) — bare NYE feil utover antallet i grunnlinjen gjør at kontrollen mislykkes; reduser grunnlinjen trinnvis med `--update` når en eksisterende feil er rettet. | Ja | +Kjøres for hver PR til `main`. Blokkerer sammenslåing ved feil. + +| Skript (`npm run ...`) | Validerer | Blokkerende | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | Node.js-versjonen er innenfor det støttede intervallet | Ja | +| `check:cycles` | Sirkulære importer på tvers av hele `src/` + `open-sse/` (AST-basert, `paths` fra tsconfig løses). Uten argumenter = rådgivende, viser syklusene. `check:cycles:ratchet` (det CI kjører) blokkerer når antallet overstiger `metrics.cycles`-grensen i `quality-baseline.json` — for øyeblikket 14, `direction: down`, slik at den bare kan reduseres (#15159 G-01/G-02) | Ja (ratchet) | +| `check:route-validation:t06` | Zod-skjemaer finnes på alle ruter (nivå 6-policy) | Ja | +| `check:any-budget:t11` | Antallet `@ts-expect-error // any` overstiger ikke budsjettet (nivå 11-catraca) | Ja | +| `check:provider-consistency` | Hver leverandør i `providers.ts` har en tilsvarende oppføring i `providerRegistry.ts` (og omvendt, innenfor tillatelseslisten) | Ja | +| `check:model-lifecycle` | De tre manuelt vedlikeholdte rutingtabellene forblir konsistente med det innsjekkede livssyklusøyeblikksbildet (#11503): `FITNESS_TABLE` (`taskFitness.ts`) vurderer ingen utfaset id som `REGISTRY` kan rute; hvert mål i `BUILT_IN_ALIASES` finnes i `REGISTRY` og er fraværende i øyeblikksbildet over utfasede id-er; hver utfaset id som fortsatt finnes i `REGISTRY`, videresendes eller er oppført i `allowedRetiredInCatalog`; og ingen kilde eller noe mål i `DEFAULT_DEGRADATION_MAP` vises som utfaset i dette øyeblikksbildet. Dette beviser ikke at en modell for øyeblikket betjenes av en aktiv oppstrømstjeneste. Frakoblet — sammenligner mot `config/quality/model-lifecycle.json`, som oppdateres manuelt med `npm run quality:refresh-model-lifecycle` (nettverk; ikke koblet til CI). `allowedRetiredInCatalog` er en gradvis innstrammingsmekanisme: legg bare til en oppføring med en sporingssak. | Ja | +| `check:fetch-targets` | Hver `fetch("/api/...")` i klientsidens `src/` peker til en faktisk `route.ts` | Ja | +| `check:deps` | Alle avhengigheter som kan installeres med `npm install`, på tvers av hver `package.json` i repositoriet, finnes i `dependency-allowlist.json`; nye ikke-fastlåste pakker eller pakker med navn som kan forveksles med andre, flagges | Ja | +| `audit:deps` | `npm audit` (rot + electron) — ingen varsler med høy/kritisk alvorlighetsgrad (overlapper med osv `check:vuln-ratchet`; se rasjonaliseringsetterslepet) | Ja | +| `check:lockfile` | Integriteten til `package-lock.json` — https-register, integritetshasher, ingen overstyringer av vert | Ja | +| `check:licenses` | SPDX-lisenstillatelsesliste for produksjonsavhengigheter | Ja | +| `check:tracked-artifacts` | Ingen byggartefakter / innsendte `node_modules`-symbolske lenker (kjøres også i husky pre-commit; pre-push er med hensikt lettvektig — #6716) | Ja | +| `check:ai-attribution` | Ingen AI-/bot-generert `Co-Authored-By`-ettertekst eller AI-genereringsbunntekst i PR-commits, tittel eller brødtekst — absolutt regel #16 (i `quality.yml`-løkken med hurtigkontroller for PR→`release/**` — leser hendelsesnyttelasten, gjør ingenting utenfor PR-er — og et trinn kun for PR-er i `ci.yml`-lintingen for PR→`main`; også husky-`commit-msg`-hooken; menneskelige medforfattere er tillatt; #14436) | +| `check:vitest-exclusions` | Hvert Vitest-unntak navngir en sporingssak og finnes i `config/quality/vitest-exclusions.json` (#13204) | Ja | +| `check:file-size` | Ingen kildefil overskrider grensen per filtype (skralle: fryste store filer i `frozen`-listen) | Ja | +| `check:error-helper` | Feilsvar i eksekverere/behandlere bruker `buildErrorBody()` / `sanitizeErrorMessage()` (absolutt regel #12) | Ja | +| `check:migration-numbering` | SQL-migreringsfiler er nummerert sekvensielt, uten hull eller duplikater | Ja | +| `check:public-creds` | Ingen bokstavelige OAuth-verdier for `client_id`/`client_secret` eller Firebase Web-nøkler utenfor `publicCreds.ts` (ufravikelig regel nr. 11) | Ja | +| `check:db-rules` | Ingen rå SQL utenfor modulene i `src/lib/db/`; ingen barrel-importer fra `localDb.ts` (ufravikelige regler nr. 2/5) | Ja | +| `check:known-symbols` | Leverandørutførere, rutingsstrategier og oversettere som er registrert i sine dispatch-tabeller, samsvarer med filene på disken – ingen foreldreløse eller udeklarerte symboler | Ja | +| `check:route-guard-membership` | Hver rute som starter en underprosess, er klassifisert av `isLocalOnlyPath()` (ufravikelige regler nr. 15/17) | Ja | +| `check:test-discovery` | Hver `*.test.ts`- / `*.spec.ts`-fil i repoet samles inn av minst én testkjører (ratchet: listen over foreldreløse filer i `test-discovery-baseline.json` kan bare krympe) | Ja | +| `check:agent-skills-sync` | Genererte agent-skills-artefakter samsvarer med kildekatalogen (ingen avvik) | +| `check:provider-asset-provenance` | Leverandørlogoer/-ressurser har en registrert oppførsel om opphav | +| `lint:json` | JSON-konfigurasjonsfiler kan analyseres og oppfyller repoets lint-regler | +| `typecheck:core` | TypeScript-kompilering uten feil (kun veiledende advarsler) | Ja | +| `typecheck:noimplicit:core` | Streng `noImplicitAny` — fremoverskuende; mange eksisterende kallesteder trenger fortsatt annotasjoner | **Veiledende** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` avgrenset til `src/app/(dashboard)/**` (#7033) — den kuraterte tillatelseslisten med 27 filer i `typecheck:core` inkluderer ingen TSX-filer fra kontrollpanelet, og `next build` typesjekker dem heller aldri (`next.config.mjs` angir `ignoreBuildErrors: true`), så regresjoner med foreldreløse identifikatorer der (#6625/#6909) var usynlige for CI. Sammenligner med en fryst grunnlinje for antall per fil/per TS-kode (`config/quality/dashboard-typecheck-baseline.json`, samme mønster for håndheving av foreldede oppføringer som `check:known-symbols`) — bare NYE feil utover grunnlinjeantallet gjør at kontrollen mislykkes; reduser grunnlinjen med `--update` når en eksisterende feil er rettet. | Ja | ### Jobb: `quality-gate` -Kjører etter `test-coverage`. Blokkerer sammenslåing ved feil. +Kjøres etter `test-coverage`. Blokkerer sammenslåing ved feil. -| Skript | Validerer | Blokkerende | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `quality:collect` | Genererer `quality-metrics.json` (antall ESLint-advarsler, dekning fra sammenslått delrapport) | Ja (oppstrøms for terskelkontrollen) | -| `quality:ratchet` | Ingen måleverdi i `quality-baseline.json` har blitt dårligere (ESLint-advarsler ≤ referanseverdi; dekning ≥ referanseverdi) | Ja | -| `check:duplication` | Kodeduplisering (jscpd@4) overskrider ikke referanseverdien i `quality-baseline.json` | Ja | -| `check:complexity` | Syklomatisk kompleksitet på filnivå overskrider ikke grensen (ESLint-kjernereglene `complexity` + `max-lines-per-function`) | Ja | -| `check:cognitive-complexity` | Terskelkontroll for kognitiv kompleksitet (`eslint-plugin-sonarjs`) — separat ESLint-kjøring; CI kjører begge samlet som ett enkelt `check:complexity-ratchets`-trinn | Ja | -| `check:dead-code` | Terskelkontroll for ubrukte eksporter/filer (knip) blir ikke dårligere enn referanseverdien | Ja | -| `check:compression-budget` | Budsjett for komprimeringsreferansemåling — minimumskravene til tokenbesparelse per motor må ikke bli dårligere | Ja | -| `check:type-coverage` | Terskelkontrollen for prosentandel typet kode (`type-coverage`) blir ikke dårligere; erstatter i stor grad `typecheck:noimplicit:core` | Ja | -| `check:codeql-ratchet` | Antallet åpne CodeQL-varsler blir ikke dårligere (leses via `gh api`; hopper kontrollert over uten token) — oppdateringsfrekvens og manuell utløsning: se «CodeQL-terskelkontroll» nedenfor | Ja | +| Skript | Validerer | Blokkerende | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `quality:collect` | Genererer `quality-metrics.json` (antall ESLint-advarsler, dekning fra sammenslått shard-rapport) | Ja (før ratchet-kontrollen) | +| `quality:ratchet` | Ingen metrikker i `quality-baseline.json` har gått tilbake (ESLint-advarsler ≤ referanseverdien; dekning ≥ referanseverdien) | Ja | +| `check:duplication` | Kodeduplisering (jscpd@4) overskrider ikke referanseverdien i `quality-baseline.json` | Ja | +| `check:complexity` | Syklomatisk kompleksitet på filnivå overskrider ikke grensen (ESLint-kjernereglene `complexity` + `max-lines-per-function`) | Ja | +| `check:cognitive-complexity` | Ratchet-kontroll for kognitiv kompleksitet (`eslint-plugin-sonarjs`) — separat ESLint-kjøring; CI kjører begge samlet som ett enkelt `check:complexity-ratchets`-trinn | Ja | +| `check:dead-code` | Ratchet-kontroll for ubrukte eksporter/filer (knip) har ikke gått tilbake sammenlignet med referanseverdien | Ja | +| `check:compression-budget` | Budsjett for komprimeringsmåling — minimumskravene til tokenbesparelse per motor må ikke gå tilbake | Ja | +| `check:type-coverage` | Ratchet-kontrollen for prosentvis typet kode (`type-coverage`) har ikke gått tilbake; erstatter i stor grad `typecheck:noimplicit:core` | Ja | +| `check:codeql-ratchet` | Antallet åpne CodeQL-varsler har ikke gått tilbake (leses via `gh api`; hoppes over uten feil hvis token mangler) — oppdateringsfrekvens og manuell utløsning: se «CodeQL ratchet» nedenfor | Ja | ### Jobb: `quality-extended` -Hele jobben er rådgivende (`continue-on-error: true`). De npm-baserte terskelkontrollene kjøres -reelt; de eksterne skannerne installeres via `gh release download` og hopper over seg selv (avslutningskode 0) +Hele jobben er rådgivende (`continue-on-error: true`). De npm-baserte ratchet-kontrollene kjøres på +ordentlig; de eksterne skannerne installeres via `gh release download` og hopper over seg selv (exit 0) når en binærfil fortsatt mangler. -| Skript | Validerer | Blokkerende | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -| `check:circular-deps` | Ingen sirkulære avhengigheter (dpdm) | **Rådgivende** | -| `check:bundle-size` | Pakkestørrelsen overskrider ikke grensen | **Rådgivende** | -| `check:secrets` | Skanning etter hemmeligheter (gitleaks) — hoppes over hvis binærfilen mangler | **Rådgivende** | -| `check:vuln-ratchet` | Sårbarheter i avhengigheter (osv-scanner) blir ikke verre — hoppes over hvis binærfilen mangler | **Rådgivende** | -| `check:workflows` | Linting av arbeidsflyter (actionlint + zizmor); manglende/ødelagte skannere, ugyldige rapporter eller manglende referanseverdi for terskelkontrollen gir statusen INCOMPLETE. Gyldige funn følger den valgte strenge, rådgivende eller terskelbaserte policyen | Kjøring kreves; zizmor-terskelkontrollen er blokkerende i CI | -| `check:openapi-breaking` | Inkompatible endringer i den offentlige API-kontrakten (`openapi.yaml`) sammenlignet med basisgrenen (oasdiff) — genererer `openapiBreaking=N`; hoppes over hvis oasdiff mangler eller basisspesifikasjonen ikke kan løses | **Rådgivende** | +| Skript | Validerer | Blokkerende | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:circular-deps` | Ingen sirkulære avhengigheter (dpdm) | **Rådgivende** | +| `check:bundle-size` | Pakkestørrelsen overskrider ikke grensen | **Rådgivende** | +| `check:secrets` | Skanning etter hemmeligheter (gitleaks) — hoppes over hvis binærfilen mangler | **Rådgivende** | +| `check:vuln-ratchet` | Sårbarheter i avhengigheter (osv-scanner) går ikke tilbake — hoppes over hvis binærfilen mangler | **Rådgivende** | +| `check:workflows` | Linting av arbeidsflyter (actionlint + zizmor); manglende/defekte skannere, ugyldige rapporter eller manglende ratchet-referanseverdi gir feilen INCOMPLETE. Gyldige funn følger den valgte strenge/rådgivende/ratchet-policyen | Kjøring påkrevd; zizmor-ratchet blokkerer i CI | +| `check:openapi-breaking` | Bakoverinkompatible endringer i den offentlige API-kontrakten (`openapi.yaml`) sammenlignet med basisgrenen (oasdiff) — genererer `openapiBreaking=N`; hoppes over hvis oasdiff mangler eller basisspesifikasjonen ikke kan løses | **Rådgivende** | ### Jobb: `docs-sync-strict` Kjøres for hver PR til `main`. Blokkerer sammenslåing ved feil. -| Skript | Validerer | Blokkerende | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `check:docs-all` | Metakontroll som kjører de seks delkontrollene nedenfor sekvensielt | Ja | -| ↳ `check:docs-sync` | Versjonssamsvar mellom CHANGELOG / OpenAPI / llm.txt | Ja | -| ↳ `check:docs-counts` | Antall i brødteksten (antall leverandører, antall migreringer osv.) er innenfor sperrevinduet til de faktiske antallene | Ja | -| ↳ `check:env-doc-sync` | Hver miljøvariabel i `.env.example` er dokumentert i en dokumentasjonstabell, og omvendt | Ja | -| ↳ `check:deprecated-versions` | Ingen avviklede versjonsstrenger i dokumentasjonen | Ja | -| ↳ `check:doc-links` | Interne Markdown-lenker i dokumentasjonen peker til faktiske filer (`[text]`/`(path)`-format) | Ja | -| ↳ `check:fabricated-docs` | Ruter, miljøvariabler, CLI-kommandoer, hook-navn og filstier som er omtalt i dokumentasjonen, finnes i kodebasen. Hard kontroll via `--strict`; myk feil uten flagget. | Ja (via `--strict` i CI) | -| `check:cli-i18n` | CLI-kommandostrenger finnes i alle i18n-språkfiler | Ja | -| `check:openapi-coverage` | OpenAPI-spesifikasjonen dekker minst en gradvis økende nedre grense for faktiske ruter | Ja | -| `check:openapi-security-tiers` | Sikkerhetsnivåmerknader i `openapi.yaml` samsvarer med klassifiseringene i `routeGuard.ts` | **Veiledende** | -| `check:openapi-routes` | Hver sti i `openapi.yaml` peker til en faktisk `route.ts` (motvirker hallusinasjoner) | Ja | -| `check:docs-symbols` | Hver `/api/...`-referanse i `docs/**/*.md` peker til en faktisk `route.ts` (motvirker hallusinasjoner) | Ja | -| `i18n translation drift` | Uoversatte nøkler i i18n-språkfiler — kun advarsel | **Veiledende** | +| Skript | Validerer | Blokkerende | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `check:docs-all` | Metakontroll som kjører de seks delkontrollene nedenfor sekvensielt | Ja | +| ↳ `check:docs-sync` | Versjonssamsvar mellom CHANGELOG / OpenAPI / llm.txt | Ja | +| ↳ `check:docs-counts` | Antall i prosa (antall leverandører, antall migreringer osv.) er innenfor sperrevinduet til de faktiske antallene | Ja | +| ↳ `check:env-doc-sync` | Hver miljøvariabel i `.env.example` er dokumentert i en dokumentasjonstabell, og omvendt | Ja | +| ↳ `check:deprecated-versions` | Ingen utdaterte versjonsstrenger i dokumentasjonen | Ja | +| ↳ `check:doc-links` | Interne markdown-lenker i dokumentasjonen peker til faktiske filer (`[tekst]`/`(sti)`-format) | Ja | +| ↳ `check:fabricated-docs` | Ruter, miljøvariabler, CLI-kommandoer, hook-navn og filstier som er nevnt i dokumentasjonen, finnes i kodebasen. Hard kontroll via `--strict`; myk feil uten flagget. | Ja (via `--strict` i CI) | +| `check:cli-i18n` | CLI-kommandostrenger finnes i alle i18n-lokalitetsfiler | Ja | +| `check:openapi-coverage` | OpenAPI-spesifikasjonen dekker minst en gradvis økende nedre grense for faktiske ruter | Ja | +| `check:openapi-security-tiers` | Sikkerhetsnivåannotasjoner i `openapi.yaml` samsvarer med klassifiseringene i `routeGuard.ts` | **Rådgivende** | +| `check:openapi-routes` | Hver sti i `openapi.yaml` peker til en faktisk `route.ts` (motvirker hallusinasjoner) | Ja | +| `check:docs-symbols` | Hver `/api/...`-referanse i `docs/**/*.md` peker til en faktisk `route.ts` (motvirker hallusinasjoner) | Ja | +| `i18n translation drift` | Uoversatte nøkler i i18n-lokalitetsfiler — kun advarsel | **Rådgivende** | ### Jobb: `i18n-ui-coverage` -| Skript | Validerer | Blokkerende | -| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | -| `check-ui-keys-coverage` (internt) | Dekningen av i18n-nøkler i brukergrensesnittet er ≥ 65 % | Ja | -| `check-ui-value-drift` (internt) | En omskrevet engelsk **verdi** etterlater ingen foreldet oversettelse | Ja | -| `check-new-key-coverage` (internt) | En **ny** engelsk nøkkel er oversatt i alle språk — en `__MISSING__:`-markør avvises | Ja | -| `check-translation-ratio` | Andelen reelle oversettelser per språk (blader utenfor tillatelseslisten som er identiske med engelsk / plassholdere / mangler) må ikke overstige `config/quality/i18n-translation-baseline.json` + slingringsmonn | **Veiledende** | +| Skript | Validerer | Blokkerende | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (internt) | Dekningen av UI i18n-nøkler er ≥ 65 % | Ja | +| `check-ui-value-drift` (internt) | En omskrevet engelsk **verdi** etterlater ingen utdatert oversettelse | Ja | +| `check-new-key-coverage` (internt) | En **ny** engelsk nøkkel er oversatt i alle lokaliteter — en `__MISSING__:`-markør avvises | Ja | +| `check-translation-ratio` | Andelen reelle oversettelser per lokalitet (blader utenfor tillatelseslisten som er identiske med engelsk / plassholdere / mangler) må ikke overstige `config/quality/i18n-translation-baseline.json` + slingringsmonn | **Rådgivende** | -Krever `fetch-depth: 0` — kontrollen for verdiavvik sammenligner `en.json` med sammenslåingsbasen. +Krever `fetch-depth: 0` — kontrollen for verdiavvik sammenligner `en.json` med flettingsbasen. -#### `check-ui-value-drift` — kontroll for foreldede oversettelser +#### `check-ui-value-drift` — kontroll for utdaterte oversettelser -Fanger opp den ene i18n-regresjonen som de andre kontrollene strukturelt sett ikke kan oppdage: En engelsk verdi -skrives om, mens oversettelsene som er basert på den _forrige_ engelske teksten, blir stående, slik at -ikke-engelskspråklige brukere fortsetter å lese en selvsikkert formulert tekst som nå er feil. +Fanger opp den ene i18n-regresjonen som de andre kontrollene strukturelt ikke kan oppdage: En engelsk verdi +skrives om, mens oversettelsene som er avledet fra den _forrige_ engelske teksten, blir stående, slik at +ikke-engelske brukere fortsetter å lese selvsikkert formulert, men nå feilaktig tekst. -Dette ble faktisk levert. `oauthModal.googleOAuthWarning` ble skrevet om da innloggingshjelperen for Antigravity -ble lagt til (#5203); **39 av 43 språk** beholdt tekst som ba operatører om å «kopiere hele -URL-en og lime den inn nedenfor» — en flyt som ikke kan fullføres for denne leverandøren. Det gikk -ubemerket hen frem til #8463 fordi: +Dette skjedde faktisk i produksjon. `oauthModal.googleOAuthWarning` ble skrevet om da Antigravity- +innloggingshjelperen ble innført (#5203); **39 av 43 lokaliteter** beholdt tekst som ba operatører om å «kopiere +hele URL-en og lime den inn nedenfor» — en flyt som ikke kan fullføres for denne leverandøren. Det +ble ikke oppdaget før #8463 fordi: -- `sync-ui-keys` fyller bare inn nøkler som **mangler**, aldri nøkler som er **foreldet**; -- `check-ui-keys-coverage` teller om nøkkelen er _til stede_, så en foreldet oversettelse regnes som dekket; -- `check-translation-drift` sporer dokumentasjonsspeilene `docs/i18n//**.md` — +- `sync-ui-keys` fyller bare inn nøkler som **mangler**, aldri nøkler som er **utdaterte**; +- `check-ui-keys-coverage` teller _tilstedeværelsen_ av nøkler, så en utdatert oversettelse regnes som dekket; +- `check-translation-drift` sporer dokumentasjonsspeilene i `docs/i18n//**.md` — den leser aldri `src/i18n/messages/*.json`. Blokkerende i jobben `docs-sync-strict` siden - 2026-09-resynkroniseringen: rediger et kjernedokument → `npm run i18n:run -- --files=` (på seksjonsnivå, rimelig). + resynkroniseringen i 2026-09: rediger et kjernedokument → `npm run i18n:run -- --files=` (på seksjonsnivå, rimelig). **Diff-bevisst, ikke støttet av en grunnlinje.** Den sammenligner `en.json` ved flettebasen med -arbeidstreet. For hver nøkkel der den engelske verdien er endret, regnes alle språkversjoner som -fortsatt har en urørt oversettelse, som utdaterte. Dette **fryser bevisst eksisterende gjeld** — en diff -kan ikke avsløre hvilken gammel engelsk tekst en langvarig oversettelse kom fra, så kontrollen vurderer -bare det den gjeldende endringen berører. Alternativet (en hash-grunnlinje per nøkkel) ville kreve -en generert fil på ~600 KB, 3× større enn den største eksisterende grunnlinjen, med endringer i hver i18n-PR. +arbeidstreet. For hver nøkkel der den engelske verdien er endret, er alle språkversjoner som +fortsatt har en urørt oversettelse, utdaterte. Dette **fryser eksisterende gjeld** med hensikt +— en diff kan ikke avdekke hvilken gammel engelsk tekst en langvarig oversettelse kom fra, +så kontrollen vurderer bare det den gjeldende endringen berører. Alternativet (en grunnlinje +med hash per nøkkel) ville kreve en generert fil på ~600 KB, 3× større enn den største +eksisterende grunnlinjen, med endringer for hver i18n-PR. Det finnes to måter å oppfylle kravet på: 1. oppdater de berørte oversettelsene, eller -2. sett dem til `__MISSING__:` — ved kjøring leveres da den korrigerte engelske teksten - (`src/i18n/request.ts::deepMergeFallback`, #7258), og nøkkelen legges i oversettelseskøen. +2. sett dem til `__MISSING__:` — ved kjøring vises da den korrigerte engelske + teksten (`src/i18n/request.ts::deepMergeFallback`, #7258), og nøkkelen legges i kø for oversettelse. -Hvis strengens **betydning** er endret, bør du helst **gi nøkkelen et nytt navn**: En ny nøkkel kan ikke arve -en utdatert oversettelse. Det er mønsteret som ble brukt i #8463. +Hvis strengens **betydning** er endret, bør du **gi nøkkelen et nytt navn**: En ny nøkkel kan +ikke arve en utdatert oversettelse. Det var mønsteret som ble brukt i #8463. ```bash npm run i18n:check-value-drift # streng (det CI kjører) @@ -231,48 +232,48 @@ npm run i18n:check-value-drift:warn # bare rapportering BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Avsluttes med kode 0 og `SKIP reason=base-unresolved` når basiskatalogen ikke kan leses (grunn -kloning uten basereferansen), i tråd med `check-openapi-breaking`. +Avslutter med 0 og `SKIP reason=base-unresolved` når basiskatalogen ikke kan leses (grunn +kloning uten basereferansen), på samme måte som `check-openapi-breaking`. ### Jobb: `i18n` Full valideringsmatrise for i18n (én jobb per språkversjon). Hele jobben er rådgivende. -| Skript | Validerer | Blokkerende | -| ------------------------------- | ------------------------------------ | ---------------------------------------------------------- | -| `validate_translation.py quick` | Fullstendighet for hver språkversjon | **Rådgivende** (`continue-on-error: true` for hele jobben) | +| Skript | Validerer | Blokkerende | +| ------------------------------- | -------------------------------------------- | ---------------------------------------------------------- | +| `validate_translation.py quick` | Oversettelsesfullstendighet per språkversjon | **Rådgivende** (`continue-on-error: true` for hele jobben) | ### Jobb: `pr-test-policy` Kjøres bare for pull requests. -| Skript | Validerer | Blokkerende | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | PR-er som endrer produksjonskode i `src/`, `open-sse/`, `electron/` eller `bin/`, må inkludere eller oppdatere tester (fast regel nr. 8) | Ja | -| `check:test-masking` | Endrede testfiler reduserer ikke nettoantallet av assert-uttrykk eller legger til `assert.ok(true)`-tautologier | Ja | -| `check:pr-evidence` | PR-beskrivelsen viser til test-/VPS-dokumentasjon for endringen (automatiserer fast regel nr. 18 ved å søke i PR-teksten — skjørt, se restlisten) | Ja | +| Skript | Validerer | Blokkerende | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| `check:pr-test-policy` | PR-er som endrer produksjonskode i `src/`, `open-sse/`, `electron/` eller `bin/`, må inkludere eller oppdatere tester (Hard regel #8) | Ja | +| `check:test-masking` | Endrede testfiler reduserer ikke nettoantallet av assert-uttrykk eller legger til `assert.ok(true)`-tautologier | Ja | +| `check:pr-evidence` | PR-teksten viser til test-/VPS-dokumentasjon for endringen (mekaniserer Hard regel #18 ved å søke gjennom PR-teksten — skjørt, se Backlog) | Ja | ### Jobb: `test-vitest` Kjøres etter `build`. Blokkerer fletting ved feil. -| Testpakke | Validerer | Blokkerende | -| ---------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-server (110 verktøy), autoCombo, hurtigbuffer — vitest-kjører | Ja | -| `test:vitest:ui` | Tester av UI-komponenter — vitest-kjører | **Blokkerende** — eksisterende feil er uttrykkelig ekskludert i `vitest.config.ts`; nye feil fører til at jobben mislykkes | +| Testpakke | Validerer | Blokkerende | +| ---------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP-server (110 verktøy), autoCombo, hurtigbuffer — vitest-testkjører | Ja | +| `test:vitest:ui` | Tester av UI-komponenter — vitest-testkjører | **Blokkerende** — eksisterende feil er uttrykkelig ekskludert i `vitest.config.ts`; nye feil gjør at jobben feiler | ### Nattlige arbeidsflyter (planlagte, rådgivende) -Disse kjøres etter en cron-plan (og med `workflow_dispatch`), aldri for PR-er. Alle er rådgivende. +Disse kjører etter en cron-plan (og `workflow_dispatch`), aldri for PR-er. Alle er rådgivende. | Arbeidsflyt | Validerer | Blokkerende | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | -| `nightly-property` | fast-check-egenskapstester med et tilfeldig starttall og et høyt antall kjøringer | **Rådgivende** | -| `nightly-resilience` | kontroll av heap-vekst, kaotisk feilinjeksjon, k6-belastnings-/utholdenhetstest | **Rådgivende** | +| `nightly-property` | fast-check-egenskapstester med et tilfeldig seed og et høyt antall kjøringer | **Rådgivende** | +| `nightly-resilience` | kontroll av heap-vekst, kaosbasert feilinjeksjon, k6-belastnings-/utholdenhetstest | **Rådgivende** | | `nightly-llm-security` | promptfoo-injeksjonsvern (blokkeringsmodus) + garak-prober (hoppes over uten en leverandørhemmelighet) | **Rådgivende** | -| `nightly-schemathesis` | fuzzing av OpenAPI-kontrakten (schemathesis) mot en kjørende OmniRoute ved bruk av `docs/openapi.yaml` — avdekker spesifikasjonsbrudd / uhåndterte 500-feil (Fase 8 B.4) | **Rådgivende** | -| `nightly-mutation` | Stryker-poengsum for mutasjonstesting i den raske enhetstestbanen — overlevende mutanter avdekker svake assert-uttrykk | **Rådgivende** | -| `nightly-compat` | Kompatibilitetsmatrise for Node-motoren på tvers av de støttede `engines.node`-intervallene | **Rådgivende** | +| `nightly-schemathesis` | OpenAPI-kontraktsfuzzing (schemathesis) mot en kjørende OmniRoute ved bruk av `docs/openapi.yaml` — avdekker brudd på spesifikasjonen / uhåndterte 500-feil (Fase 8 B.4) | **Rådgivende** | +| `nightly-mutation` | Stryker-mutasjonstestingspoeng for det raske enhetstestsporet — overlevende mutanter avdekker svake assert-uttrykk | **Rådgivende** | +| `nightly-compat` | kompatibilitetsmatrise for Node-motoren på tvers av de støttede `engines.node`-intervallene | **Rådgivende** | --- @@ -535,43 +536,44 @@ tilkoblingsfeil og avbryter aldri økter. --- -## Rasjonaliseringsrestanse (ROI-gjennomgang — fase 9 bølge 3) +## Rasjonaliseringsrestanse (ROI-gjennomgang — Fase 9 Onda 3) Denne oversikten ble avstemt mot `ci.yml` 2026-06-17 (den forrige versjonen utelot `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). En ROI-gjennomgang av det avstemte settet identifiserte følgende kandidater for rasjonalisering. **Sammenslåingene er mekaniske -CI-endringer; omgjøringene/fjerningene er policybeslutninger som er forbeholdt operatøren.** Ingenting nedenfor -er tatt i bruk ennå. +CI-endringer; endringene/fjerningene er policybeslutninger som er forbeholdt operatøren.** +Ingenting nedenfor er tatt i bruk ennå. -**Også udokumentert ovenfor** (rådgivende, svakt signal): `docs-lint`-jobben -(markdownlint + Vale, hele jobben har `continue-on-error`) og de frittstående skannerarbeidsflytene -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` finnes i -`quality-baseline.json`, men er ikke koblet til en blokkerende ratchet i `ci.yml` — måleverdien er -for øyeblikket foreldreløs. +**Også udokumentert ovenfor** (rådgivende, lav signalverdi): `docs-lint`-jobben +(markdownlint + Vale, hele jobben har `continue-on-error`) og de frittstående +skannerarbeidsflytene `semgrep.yml` / `codeql.yml` / `scorecard.yml`. +`semgrepFindings: 0` finnes i `quality-baseline.json`, men er ikke koblet til en +blokkerende skrallemekanisme i `ci.yml` — måleverdien er for øyeblikket foreldreløs. ### Slå sammen / dedupliser (mekanisk, lavere risiko) -Hver kandidat ble validert mot den aktive gate-tilstanden 2026-06-17 (stol på, men verifiser); -flere «åpenbare» sammenslåinger viste seg å skjule teknisk gjeld og er **ikke** problemfrie direkteerstatninger. +Hver kandidat ble validert mot den aktive porttilstanden 2026-06-17 +(stol på, men verifiser); flere «åpenbare» sammenslåinger viste seg å skjule gjeld og er +**ikke** rene direkteerstatninger. -- **`check:docs-sync` kjøres to ganger** — frittstående i `lint`-jobben og på nytt i `check:docs-all` (`docs-sync-strict`) og husky pre-commit-hooken. ✅ **FERDIG** — den frittstående `lint`-kjøringen er fjernet. -- **CVE-skanning** — ❌ **IKKE en problemfri sammenslåing.** `audit:deps` feiler kategorisk ved enhver CVE med høy/kritisk alvorlighetsgrad; `check:vuln-ratchet` (osv) feiler bare ved en _regresjon_ mot referanseverdien (for øyeblikket 1 MODERATE). Ulik semantikk — fjerning av `audit:deps` ville fjerne den absolutte gaten for høy/kritisk alvorlighetsgrad. Behold begge. -- **Syklusdeteksjon** — ❌ **IKKE en problemfri sammenslåing.** `check:circular-deps` (dpdm) rapporterer **91 sykluser** (det er derfor den er rådgivende); den kan ikke gjøres blokkerende før de er løst, og den har et bredere omfang enn den grønne, kuraterte `check:cycles`. Behold `check:cycles` som blokkerende; håndtering av de 91 dpdm-syklusene er en egen restanse. -- **Kompleksitet** — ✅ **FERDIG** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): én ESLint-gjennomgang, teller etter ruleId slik at referanseverdiene for syklomatisk kompleksitet+max-lines og kognitiv kompleksitet forblir uavhengige; de individuelle `check:complexity` / `check:cognitive-complexity` beholdes for lokal `--update`. -- **`/api`-antihallusinasjon** — ✅ **FERDIG** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): én FS-oversikt over `src/app/api`, openapi-routes + docs-symbols rapporterer fortsatt uavhengig; de individuelle kontrollene beholdes for lokale kjøringer. -- **`check:node-runtime` kjøres i 11 jobber** — ⚠️ **lav ROI.** Hver av dem bruker en separat runner, og kontrollen tar <1s; total besparelse er ~10s, mot å miste en rimelig beskyttelse per jobb. Ikke verdt omarbeidingen. -- **`typecheck:noimplicit:core` i CI-lint** — ✅ **fjernet fra lint-jobben** (var rådgivende med `continue-on-error`); den blokkerende typeoverflaten er `typecheck:core` + `check:type-coverage`. Lokalt skript er beholdt. +- **`check:docs-sync` kjøres to ganger** — frittstående i `lint`-jobben og på nytt i `check:docs-all` (`docs-sync-strict`) samt i husky sin pre-commit-hook. ✅ **FERDIG** — den frittstående `lint`-kjøringen er fjernet. +- **CVE-skanning** — ❌ **IKKE en ren sammenslåing.** `audit:deps` feiler ubetinget ved enhver CVE med høy/kritisk alvorlighetsgrad; `check:vuln-ratchet` (osv) feiler bare ved en _regresjon_ sammenlignet med grunnlinjen (for øyeblikket 1 MODERATE). Ulik semantikk — fjerning av `audit:deps` ville medføre tap av den absolutte porten for høy/kritisk alvorlighetsgrad. Behold begge. +- **Syklusdeteksjon** — ✅ **FERDIG** (#15159 G-01/G-02). Den gamle teksten her omtalte `check:cycles` som «den grønne, kuraterte» porten og begrunnet at den skulle forbli blokkerende fordi `check:circular-deps` (dpdm) rapporterte 91 sykluser. Det grønne resultatet var en **falsk grønnstatus**: `check:cycles` skannet 5 underkataloger (450 filer), samsvarte bare med statisk `import|export … from` og forkastet hver `@/`- og `@omniroute/open-sse/`-spesifikator, slik at den ikke kunne se syklusene med dynamisk import og aliaser som dominerte repoet. Rettet: Porten går nå gjennom `src` + `open-sse` (5023 filer), samler spesifikatorer fra TypeScript-AST-en (slik at `import("…")` telles, mens `typeof import("…")` i typeposisjon ikke gjør det) og løser opp tsconfig-`paths`. Den finner **14** sykluser, ikke 0. Fordi 14 eksisterende sykluser ikke kan rettes i en port-PR, er `check:cycles` nå en **skrallemekanisme** (`--ratchet`, tak `metrics.cycles.value = 14` i `quality-baseline.json`, `direction: down`) — den blokkerer enhver _regresjon_, og antallet kan bare synke. CI kjører `npm run check:cycles:ratchet`. Nedbyggingen følger **A-01**. `check:circular-deps` (dpdm) forblir rådgivende som en bredere tilleggsvurdering. +- **Kompleksitet** — ✅ **FERDIG** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): én ESLint-gjennomgang, telling etter ruleId slik at grunnlinjene for syklomatisk kompleksitet + maks antall linjer og kognitiv kompleksitet forblir uavhengige; de individuelle `check:complexity` / `check:cognitive-complexity` beholdes for lokal `--update`. +- **Antihallusinasjon for `/api`** — ✅ **FERDIG** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): én FS-oversikt over `src/app/api`; openapi-routes + docs-symbols rapporterer fortsatt uavhengig; de individuelle kontrollene beholdes for lokale kjøringer. +- **`check:node-runtime` kjøres i 11 jobber** — ⚠️ **lav ROI.** Hver kjører på en separat runner, og kontrollen tar <1s; total besparelse er ~10s, mot tapet av en rimelig kontroll per jobb. Ikke verdt endringsstøyen. +- **`typecheck:noimplicit:core` i CI-lint** — ✅ **fjernet fra lint-jobben** (var rådgivende med `continue-on-error`); den blokkerende typeoverflaten er `typecheck:core` + `check:type-coverage`. Det lokale skriptet er beholdt. ### Endre / avgjør (operatørpolicy) -- `check:openapi-security-tiers` (rådgivende) — ❌ **KAN IKKE problemfritt gjøres blokkerende.** Den avslutter med 0, men advarer om at flere `traffic-inspector`-ruter under `LOCAL_ONLY_API_PREFIXES` mangler annotasjonen `x-loopback-only: true`. Håndheving krever at disse annotasjonene først legges til i `openapi.yaml`. -- `typecheck:noimplicit:core` (rådgivende) — i stor grad innlemmet i den blokkerende `check:type-coverage`-ratcheten. Gjør den om til en ratchet, eller fjern den overflødige andre `tsc`-gjennomgangen. -- `test:vitest:ui` (nå **blokkerende**) — eksisterende feil er uttrykkelig ekskludert i `vitest.config.ts` med sporingskommentarene `// #8618`; nye feil gjør at jobben feiler. -- `check:secrets` (gitleaks, blokkerende ratchet fryst ved 3 dokumenterte falske positiver) — legg de 3 til i tillatelseslisten for å nå 0, eller nedgrader den til rådgivende. Overlapper med GitHubs innebygde hemmelighetsskanning + `check:public-creds`. -- `check:pr-evidence` (blokkerende, søker med grep i prosateksten i PR-beskrivelsen) — høy risiko for falske positiver; fjerning svekker håndhevingen av Hard Rule #18, så dette er en reell policyavgjørelse. -- `semgrep` (rådgivende, frittstående) — overlapper med CodeQL for OWASP-familiene; koble referanseverdien til en ratchet, eller fjern den. +- `check:openapi-security-tiers` (rådgivende) — ❌ **KAN IKKE endres uten videre.** Den avsluttes med 0, men advarer om at flere `traffic-inspector`-ruter under `LOCAL_ONLY_API_PREFIXES` mangler annotasjonen `x-loopback-only: true`. Håndheving krever at disse annotasjonene først legges til i `openapi.yaml`. +- `typecheck:noimplicit:core` (rådgivende) — i stor grad erstattet av den blokkerende `check:type-coverage`-skrallemekanismen. Endre den til en skrallemekanisme, eller fjern den overflødige andre `tsc`-kjøringen. +- `test:vitest:ui` (nå **blokkerende**) — eksisterende feil er eksplisitt ekskludert i `vitest.config.ts` med `// #8618`-sporingskommentarer; nye feil får jobben til å feile. +- `check:secrets` (gitleaks, blokkerende skrallemekanisme fryst ved 3 dokumenterte falske positiver) — tillat de 3 gjennom en allowlist for å nå 0, eller nedgrader til rådgivende. Overlapper med GitHubs innebygde hemmelighetsskanning + `check:public-creds`. +- `check:pr-evidence` (blokkerende, søker med grep i PR-beskrivelsens prosa) — høy risiko for falske positiver; fjerning svekker håndhevingen av Hard Rule #18, så dette er en reell policyavgjørelse. +- `semgrep` (rådgivende, frittstående) — overlapper CodeQL for OWASP-familiene; koble grunnlinjen til en skrallemekanisme, eller fjern den. --- diff --git a/docs/i18n/or/CONTRIBUTING.md b/docs/i18n/or/CONTRIBUTING.md index 9405c7c248f..f1967573043 100644 --- a/docs/i18n/or/CONTRIBUTING.md +++ b/docs/i18n/or/CONTRIBUTING.md @@ -397,22 +397,22 @@ docs/ --- -## ପୁଲ୍ ରିକ୍ୱେଷ୍ଟ୍ ଯାଞ୍ଚତାଲିକା - -- [ ] ପରୀକ୍ଷାଗୁଡ଼ିକ ସଫଳ ହୁଏ (`npm test`) -- [ ] ଲିଣ୍ଟିଂ ସଫଳ ହୁଏ (`npm run lint`) -- [ ] ବିଲ୍ଡ୍ ସଫଳ ହୁଏ (`npm run build`) -- [ ] ନୂତନ ସାର୍ବଜନୀନ ଫଙ୍କସନ୍ ଏବଂ ଇଣ୍ଟରଫେସ୍ଗୁଡ଼ିକ ପାଇଁ TypeScript ପ୍ରକାର ଯୋଡ଼ାଯାଇଛି -- [ ] କୌଣସି ହାର୍ଡକୋଡ୍ କରାଯାଇଥିବା ଗୁପ୍ତ ତଥ୍ୟ କିମ୍ବା ଫଲ୍ବ୍ୟାକ୍ ମୂଲ୍ୟ ନାହିଁ -- [ ] ସାର୍ବଜନୀନ ଅପ୍ଷ୍ଟ୍ରିମ୍ ପରିଚୟପତ୍ରଗୁଡ଼ିକ `resolvePublicCred()` ମାଧ୍ୟମରେ ଏମ୍ବେଡ୍ କରାଯାଇଛି ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ଦେଖନ୍ତୁ), କେବେବି ଲିଟେରାଲ୍ ଭାବେ ନୁହେଁ -- [ ] ତ୍ରୁଟି ପ୍ରତିକ୍ରିୟାଗୁଡ଼ିକ `buildErrorBody()` / `sanitizeErrorMessage()` ମାଧ୍ୟମରେ ଯାଏ — ପ୍ରତିକ୍ରିୟା ବଡିଗୁଡ଼ିକରେ କୌଣସି କଞ୍ଚା ଷ୍ଟାକ୍ ଟ୍ରେସ୍ ନାହିଁ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ଦେଖନ୍ତୁ) -- [ ] ଶେଲ୍ କମାଣ୍ଡ୍ଗୁଡ଼ିକ (`exec` / `spawn`) ଷ୍ଟ୍ରିଙ୍ଗ୍ ଇଣ୍ଟରପୋଲେସନ୍ ମାଧ୍ୟମରେ ନୁହେଁ, `env` ମାଧ୍ୟମରେ ରନ୍ଟାଇମ୍ ମୂଲ୍ୟଗୁଡ଼ିକ ପାସ୍ କରେ -- [ ] ସମସ୍ତ ଇନ୍ପୁଟ୍ Zod ସ୍କିମାଗୁଡ଼ିକ ସହିତ ବୈଧତା ଯାଞ୍ଚ କରାଯାଇଛି -- [ ] ବ୍ୟବହାରକାରୀଙ୍କୁ ପ୍ରଭାବିତ କରୁଥିବା ପରିବର୍ତ୍ତନ ପାଇଁ `changelog.d/{features|fixes|maintenance}/-.md` ଅଧୀନରେ Changelog **ଖଣ୍ଡ** ଯୋଡ଼ାଯାଇଛି ([`changelog.d/README.md`](./changelog.d/README.md) ଦେଖନ୍ତୁ) — `CHANGELOG.md`କୁ ସିଧାସଳଖ ସମ୍ପାଦନା **କରନ୍ତୁ ନାହିଁ**; ଖଣ୍ଡଗୁଡ଼ିକ ରିଲିଜ୍ ସମୟରେ ଏକତ୍ରିତ କରାଯାଏ ଏବଂ PRଗୁଡ଼ିକ ମଧ୍ୟରେ କେବେବି ବିବାଦ ସୃଷ୍ଟି କରେ ନାହିଁ -- [ ] ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ଅଦ୍ୟତନ କରାଯାଇଛି (ଯଦି ପ୍ରଯୁଜ୍ୟ) +## ପୁଲ୍ ରିକ୍ୱେଷ୍ଟ ଯାଞ୍ଚତାଲିକା + +- [ ] ପରୀକ୍ଷଣଗୁଡ଼ିକ ସଫଳ ହୋଇଛି (`npm test`) +- [ ] ଲିଣ୍ଟିଂ ସଫଳ ହୋଇଛି (`npm run lint`) +- [ ] ବିଲ୍ଡ ସଫଳ ହୋଇଛି (`npm run build`) +- [ ] ନୂତନ ସାର୍ବଜନୀନ ଫଙ୍କସନ୍ ଏବଂ ଇଣ୍ଟରଫେସ୍ଗୁଡ଼ିକ ପାଇଁ TypeScript ଟାଇପ୍ ଯୋଡ଼ାଯାଇଛି +- [ ] କୌଣସି ହାର୍ଡକୋଡ୍ କରାଯାଇଥିବା ସିକ୍ରେଟ୍ କିମ୍ବା ଫଲ୍ବ୍ୟାକ୍ ମୂଲ୍ୟ ନାହିଁ +- [ ] ସାର୍ବଜନୀନ ଅପ୍ଷ୍ଟ୍ରିମ୍ କ୍ରେଡେନ୍ସିଆଲ୍ଗୁଡ଼ିକୁ `resolvePublicCred()` ମାଧ୍ୟମରେ ଏମ୍ବେଡ୍ କରାଯାଇଛି ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ଦେଖନ୍ତୁ), କେବେବି ଲିଟେରାଲ୍ ଭାବରେ ନୁହେଁ +- [ ] ତ୍ରୁଟି ପ୍ରତିକ୍ରିୟାଗୁଡ଼ିକ `buildErrorBody()` / `sanitizeErrorMessage()` ମାଧ୍ୟମରେ ରୁଟ୍ ହୋଇଛି — ପ୍ରତିକ୍ରିୟା ବଡିରେ କୌଣସି ଅପରିବର୍ତ୍ତିତ ଷ୍ଟାକ୍ ଟ୍ରେସ୍ ନାହିଁ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ଦେଖନ୍ତୁ) +- [ ] ସେଲ୍ କମାଣ୍ଡଗୁଡ଼ିକ (`exec` / `spawn`) ଷ୍ଟ୍ରିଙ୍ଗ୍ ଇଣ୍ଟରପୋଲେସନ୍ ମାଧ୍ୟମରେ ନୁହେଁ, `env` ମାଧ୍ୟମରେ ରନ୍ଟାଇମ୍ ମୂଲ୍ୟ ପାସ୍ କରନ୍ତି +- [ ] ସମସ୍ତ ଇନ୍ପୁଟ୍କୁ Zod ସ୍କିମା ସହିତ ବୈଧୀକରଣ କରାଯାଇଛି +- [ ] ବ୍ୟବହାରକାରୀଙ୍କୁ ପ୍ରଭାବିତ କରୁଥିବା ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ପାଇଁ `changelog.d/{features|fixes|maintenance}/-.md` ଅଧୀନରେ ଚେଞ୍ଜଲଗ୍ **ଫ୍ରାଗ୍ମେଣ୍ଟ୍** ଯୋଡ଼ାଯାଇଛି ([`changelog.d/README.md`](./changelog.d/README.md) ଦେଖନ୍ତୁ) — `CHANGELOG.md`କୁ ସିଧାସଳଖ ସମ୍ପାଦନା କରନ୍ତୁ **ନାହିଁ**; ରିଲିଜ୍ ସମୟରେ ଫ୍ରାଗ୍ମେଣ୍ଟ୍ଗୁଡ଼ିକୁ ଏକତ୍ର କରାଯାଏ ଏବଂ PRଗୁଡ଼ିକ ମଧ୍ୟରେ କେବେବି ଦ୍ୱନ୍ଦ୍ୱ ସୃଷ୍ଟି ହୁଏ ନାହିଁ +- [ ] ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ଅପଡେଟ୍ କରାଯାଇଛି (ଯଦି ପ୍ରଯୁଜ୍ୟ) - [ ] କୌଣସି ନୂତନ CodeQL / Secret-Scanning ସତର୍କତା ଖୋଲାଯାଇନାହିଁ, କିମ୍ବା ପ୍ରତ୍ୟେକଟିକୁ ସମ୍ପର୍କିତ `docs/security/` ଡକ୍ୟୁମେଣ୍ଟ୍ ଉଲ୍ଲେଖ କରୁଥିବା ବୈଷୟିକ ଯଥାର୍ଥତା ସହିତ ଖାରଜ କରାଯାଇଛି -- [ ] ଚାଇଲ୍ଡ୍ ପ୍ରୋସେସ୍ ଆରମ୍ଭ କରୁଥିବା ରୁଟ୍ଗୁଡ଼ିକ (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts`ରେ `isLocalOnlyPath()` ଭାବେ ଶ୍ରେଣୀଭୁକ୍ତ କରାଯାଇଛି — [କଠୋର ନିୟମ #15](docs/security/ROUTE_GUARD_TIERS.md) ଦେଖନ୍ତୁ -- [ ] କମିଟ୍ ସନ୍ଦେଶଗୁଡ଼ିକରେ କୌଣସି `Co-Authored-By` ଟ୍ରେଲର୍ ନାହିଁ — କମିଟ୍ଗୁଡ଼ିକ କେବଳ ରିପୋଜିଟୋରି ମାଲିକଙ୍କ Git ପରିଚୟ ଅଧୀନରେ ଦେଖାଯିବା ଆବଶ୍ୟକ (କଠୋର ନିୟମ #16) +- [ ] ଚାଇଲ୍ଡ ପ୍ରୋସେସ୍ ସ୍ପନ୍ କରୁଥିବା ରୁଟ୍ଗୁଡ଼ିକ (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts`ରେ `isLocalOnlyPath()` ଭାବରେ ବର୍ଗୀକୃତ ହୋଇଛି — [କଠୋର ନିୟମ #15](docs/security/ROUTE_GUARD_TIERS.md) ଦେଖନ୍ତୁ +- [ ] କମିଟ୍ ବାର୍ତ୍ତାଗୁଡ଼ିକରେ କୌଣସି AI/ବଟ୍ `Co-authored-by` ଟ୍ରେଲର୍ ନାହିଁ (କଠୋର ନିୟମ #16) — ଯେଉଁ ମାନବ ସହଯୋଗୀଙ୍କ କାର୍ଯ୍ୟ ପୁନଃବ୍ୟବହୃତ ହୋଇଛି, ସେମାନଙ୍କୁ ମାନକ `Co-authored-by: Name ` ଟ୍ରେଲର୍ ସହିତ ଶ୍ରେୟ ଦିଆଯାଇଛି --- diff --git a/docs/i18n/or/docs/architecture/QUALITY_GATES.md b/docs/i18n/or/docs/architecture/QUALITY_GATES.md index 56e3a7b0d83..12e9f60ed29 100644 --- a/docs/i18n/or/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/or/docs/architecture/QUALITY_GATES.md @@ -15,254 +15,260 @@ --- -## ଗେଟ୍ ଇନଭେଣ୍ଟୋରୀ ଏବଂ ନିଷ୍ପାଦନ ପ୍ରୋଫାଇଲ୍ +## ଗେଟ୍ ଇନଭେଣ୍ଟରି ଏବଂ ଏକ୍ସିକ୍ୟୁସନ୍ ପ୍ରୋଫାଇଲ୍ -### ପ୍ରାର୍ଥୀ ଗ୍ରହଣ +### ପ୍ରାର୍ଥୀ ଅନୁମୋଦନ -CI ଏବଂ Quality Gates ୱାର୍କଫ୍ଲୋ ପ୍ରତ୍ୟେକ ଏକ ସ୍ଥିର ରାୟ ପ୍ରଦାନ କରେ: `Gate / CI` ଏବଂ -`Gate / Quality`। ସେମାନଙ୍କର ସଂସ୍କରଣଭିତ୍ତିକ ଗ୍ରହଣ ନୀତି ପ୍ରତ୍ୟେକ ଅପ୍ଷ୍ଟ୍ରିମ୍ ଜବ୍କୁ -ଆବଶ୍ୟକ କିମ୍ବା ପରାମର୍ଶମୂଳକ ଭାବେ ତାଲିକାଭୁକ୍ତ କରେ। ଏକ ପ୍ରଯୋଜ୍ୟ ଆବଶ୍ୟକ ଜବ୍ ନିଶ୍ଚିତ ଭାବେ ସଫଳ ହେବା ଉଚିତ: ଅନୁପସ୍ଥିତ, -ବାତିଲ ହୋଇଥିବା, ଏଡ଼ାଇ ଦିଆଯାଇଥିବା, ବିଚାରାଧୀନ ଏବଂ ଅଜଣା ଫଳାଫଳ PASS ପ୍ରତିଷ୍ଠା କରିପାରିବ ନାହିଁ। ଏକ ବୈଧ -କେବଳ-ଡକ୍ସ କିମ୍ବା କେବଳ-କ୍ୟାଟାଲଗ୍ ବର୍ଗୀକରଣ କୌଣସି କୋଡ୍ ଲେନ୍କୁ ଅପ୍ରଯୋଜ୍ୟ କରିପାରେ; +CI ଏବଂ Quality Gates ୱର୍କଫ୍ଲୋଗୁଡ଼ିକ ପ୍ରତ୍ୟେକ ଏକ ସ୍ଥିର ନିଷ୍ପତ୍ତି ପ୍ରଦାନ କରେ: `Gate / CI` ଏବଂ +`Gate / Quality`। ସେମାନଙ୍କର ସଂସ୍କରଣଭିତ୍ତିକ ଅନୁମୋଦନ ନୀତି ପ୍ରତ୍ୟେକ ଅପ୍ଷ୍ଟ୍ରିମ୍ ଜବ୍କୁ +ଆବଶ୍ୟକ କିମ୍ବା ପରାମର୍ଶମୂଳକ ଭାବେ ତାଲିକାଭୁକ୍ତ କରେ। ଏକ ପ୍ରଯୁଜ୍ୟ ଆବଶ୍ୟକ ଜବ୍ ନିଶ୍ଚିତ ଭାବେ ସଫଳ ହେବା ଆବଶ୍ୟକ: ଅନୁପସ୍ଥିତ, +ବାତିଲ ହୋଇଥିବା, ଏଡ଼ାଇ ଦିଆଯାଇଥିବା, ବିଚାରାଧୀନ ଏବଂ ଅଜଣା ଫଳାଫଳ PASS ସ୍ଥାପନ କରିପାରିବ ନାହିଁ। ଏକ ବୈଧ +କେବଳ-ଡକ୍ସ କିମ୍ବା କେବଳ-କ୍ୟାଟାଲଗ୍ ବର୍ଗୀକରଣ ଏକ କୋଡ୍ ଲେନ୍କୁ ଅପ୍ରଯୁଜ୍ୟ କରିପାରେ; ଏକ ଡ୍ରାଫ୍ଟ PR ଗ୍ରହଣୀୟ ପ୍ରାର୍ଥୀ ନୁହେଁ। ଏକ `hotfix` ଲେବଲ୍ ପ୍ରମାଣର ଆବଶ୍ୟକତାକୁ ଛାଡ଼ କରେ ନାହିଁ। -ଉଭୟ ୱାର୍କଫ୍ଲୋ PR ଏବଂ main/release ବ୍ରାଞ୍ଚଗୁଡ଼ିକୁ ପୁଶ୍, ମାନୁଆଲ୍ ଡିସ୍ପ୍ୟାଚ୍ ଏବଂ -ମର୍ଜ୍-ଗ୍ରୁପ୍ ଇଭେଣ୍ଟଗୁଡ଼ିକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ। ପୁଶ୍, ଡିସ୍ପ୍ୟାଚ୍ ଏବଂ ମର୍ଜ୍-ଗ୍ରୁପ୍ ସମ୍ପୂର୍ଣ୍ଣ ଚୟନକୁ ଚଲାଏ। ଫୋର୍କ୍ଗୁଡ଼ିକ -ଏବଂ ମର୍ଜ୍ ଗ୍ରୁପ୍ଗୁଡ଼ିକ ସେହି ଜବ୍ଗୁଡ଼ିକ ପାଇଁ ହୋଷ୍ଟେଡ୍ ରନର୍ ବ୍ୟବହାର କରନ୍ତି, ଯେଉଁଗୁଡ଼ିକ ଅନ୍ୟଥା ସେଲ୍ଫ-ହୋଷ୍ଟେଡ୍ -ରନର୍ ଚୟନ କରିଥାନ୍ତେ; ରୋଲ୍ଆଉଟ୍ ପୂର୍ବରୁ ପର୍ଯ୍ୟାପ୍ତ ହୋଷ୍ଟେଡ୍ କ୍ଷମତା ଯାଞ୍ଚ କରିବା ଆବଶ୍ୟକ। +ଉଭୟ ୱର୍କଫ୍ଲୋ PR ଏବଂ main/release ବ୍ରାଞ୍ଚଗୁଡ଼ିକୁ ପୁସ୍, ମାନୁଆଲ୍ ଡିସ୍ପାଚ୍ ଏବଂ +ମର୍ଜ୍-ଗ୍ରୁପ୍ ଇଭେଣ୍ଟଗୁଡ଼ିକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ। ପୁସ୍, ଡିସ୍ପାଚ୍ ଏବଂ ମର୍ଜ୍-ଗ୍ରୁପ୍ ସମ୍ପୂର୍ଣ୍ଣ ଚୟନ ଚଲାଏ। ଫୋର୍କ୍ +ଏବଂ ମର୍ଜ୍ ଗ୍ରୁପ୍ଗୁଡ଼ିକ ସେହି ଜବ୍ଗୁଡ଼ିକ ପାଇଁ ହୋଷ୍ଟେଡ୍ ରନର୍ ବ୍ୟବହାର କରନ୍ତି, ଯେଉଁଗୁଡ଼ିକ ଅନ୍ୟଥା ସେଲ୍ଫ୍-ହୋଷ୍ଟେଡ୍ +ରନର୍ ଚୟନ କରିଥାନ୍ତେ; ରୋଲ୍ଆଉଟ୍ ପୂର୍ବରୁ ପର୍ଯ୍ୟାପ୍ତ ହୋଷ୍ଟେଡ୍ କ୍ଷମତା ଯାଞ୍ଚ କରାଯିବା ଆବଶ୍ୟକ। -ପ୍ରତ୍ୟେକ JSON ରସିଦ ଚେକ୍ଆଉଟ୍ ହୋଇଥିବା SHA, ୱାର୍କଫ୍ଲୋ ରନ୍ ଏବଂ ପ୍ରୟାସକୁ ଚିହ୍ନଟ କରେ। -CLI ଏକ ଚେକ୍ଆଉଟ୍/ଇଭେଣ୍ଟ SHA ଅମେଳକୁ ପ୍ରତ୍ୟାଖ୍ୟାନ କରେ। ୱାର୍କଫ୍ଲୋ ପରୀକ୍ଷାଗୁଡ଼ିକ ନୀତି ସଦସ୍ୟତାକୁ -ରାୟ ଜବ୍ର `needs` ତାଲିକା ସହିତ ବାନ୍ଧିଥାଏ, ଯାହାଦ୍ୱାରା ଏକ ନୂତନ କିମ୍ବା ଅପସାରିତ ଲେନ୍ ନିରବରେ ଅଦୃଶ୍ୟ ହୋଇପାରିବ ନାହିଁ। -ରସିଦଗୁଡ଼ିକ ସେମାନଙ୍କ ନିଜସ୍ୱ ୱାର୍କଫ୍ଲୋକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ, ପ୍ରକାଶନ, ଡିପ୍ଲୟମେଣ୍ଟ କିମ୍ବା -କୌଣସି ବିଦ୍ୟମାନ ପରାମର୍ଶମୂଳକ ସ୍କାନର୍ର ଆଭ୍ୟନ୍ତରୀଣ କାର୍ଯ୍ୟକୁ ନୁହେଁ। ବ୍ରାଞ୍ଚ ନିୟମଗୁଡ଼ିକରେ ଉଭୟ ଚେକ୍ ନାମକୁ ସକ୍ରିୟ କରିବା -ଏକ ପୃଥକ ପ୍ରଶାସନିକ ପରିବର୍ତ୍ତନ; ଏହି ଜବ୍ଗୁଡ଼ିକୁ ଯୋଡ଼ିବା ନିଜେ କୌଣସି ବ୍ରାଞ୍ଚକୁ ସୁରକ୍ଷିତ କରେ ନାହିଁ। +ପ୍ରତ୍ୟେକ JSON ରସିଦ ଚେକ୍ଆଉଟ୍ ହୋଇଥିବା SHA, ୱର୍କଫ୍ଲୋ ରନ୍ ଏବଂ ପ୍ରୟାସକୁ ଚିହ୍ନଟ କରେ। +CLI ଏକ ଚେକ୍ଆଉଟ୍/ଇଭେଣ୍ଟ SHA ଅମେଳକୁ ପ୍ରତ୍ୟାଖ୍ୟାନ କରେ। ୱର୍କଫ୍ଲୋ ପରୀକ୍ଷାଗୁଡ଼ିକ ନୀତିର ସଦସ୍ୟତାକୁ +ନିଷ୍ପତ୍ତି ଜବ୍ର `needs` ତାଲିକା ସହିତ ବାନ୍ଧି ରଖେ, ଯାହାଦ୍ୱାରା ଏକ ନୂଆ କିମ୍ବା ଅପସାରିତ ଲେନ୍ ନିରବରେ ଅଦୃଶ୍ୟ ହୋଇପାରିବ ନାହିଁ। +ରସିଦଗୁଡ଼ିକ ସେମାନଙ୍କର ନିଜ ୱର୍କଫ୍ଲୋକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ, ପ୍ରକାଶନ, ଡିପ୍ଲୟମେଣ୍ଟ କିମ୍ବା +ଏକ ବିଦ୍ୟମାନ ପରାମର୍ଶମୂଳକ ସ୍କାନର୍ର ଆଭ୍ୟନ୍ତରୀଣ ଅଂଶକୁ ନୁହେଁ। ବ୍ରାଞ୍ଚ ନିୟମରେ ଉଭୟ ଚେକ୍ ନାମକୁ ସକ୍ରିୟ କରିବା +ଏକ ପୃଥକ ପ୍ରଶାସନିକ ପରିବର୍ତ୍ତନ; ଏହି ଜବ୍ଗୁଡ଼ିକୁ ଯୋଡ଼ିବା ନିଜେ ନିଜେ ଏକ ବ୍ରାଞ୍ଚକୁ ସୁରକ୍ଷିତ କରେ ନାହିଁ। -### ଷ୍ଟାଟିକ୍ ସ୍କାନ୍ ଇନଭେଣ୍ଟୋରୀ +### ଷ୍ଟାଟିକ୍ ସ୍କାନ୍ ଇନଭେଣ୍ଟରି -ସଂସ୍କରଣଭିତ୍ତିକ npm-ଆଲିଆସ୍ ଇନଭେଣ୍ଟୋରୀ ଏବଂ ଷ୍ଟାଟିକ୍-ସ୍କାନ୍ ସଦସ୍ୟତା -`config/quality/gate-manifest.json`ରେ ରହିଛି। `package.json` ସହିତ ସ୍କ୍ରିପ୍ଟ ନାମ ଏବଂ ସଠିକ୍ କମାଣ୍ଡଗୁଡ଼ିକୁ -ଯାଞ୍ଚ କରିବା ପାଇଁ `npm run check:gate-manifest` ଚଲାନ୍ତୁ; ଯୋଗ, ଅପସାରଣ ଏବଂ -କମାଣ୍ଡ ବିଚ୍ୟୁତି ଉଭୟ ସ୍ଥାନୀୟ ହୁକ୍ ଏବଂ CIର ପରିବର୍ତ୍ତନ-ବର୍ଗୀକରଣ ଜବ୍ଗୁଡ଼ିକୁ ବିଫଳ କରେ। -ଏକ ଆଲିଆସ୍ କୌଣସି ୱାର୍କଫ୍ଲୋ ଜବ୍, ମ୍ୟାଟ୍ରିକ୍ସ ଇନ୍ଷ୍ଟାନ୍ସ କିମ୍ବା ପରୀକ୍ଷଣ କେସ୍ ନୁହେଁ: ଏହି ଗଣନାଗୁଡ଼ିକୁ -ପରସ୍ପର ବଦଳଯୋଗ୍ୟ ଭାବେ ଉପସ୍ଥାପନ କରାଯିବା ଉଚିତ ନୁହେଁ। +ସଂସ୍କରଣଭିତ୍ତିକ npm-ଆଲିଆସ୍ ଇନଭେଣ୍ଟରି ଏବଂ ଷ୍ଟାଟିକ୍-ସ୍କାନ୍ ସଦସ୍ୟତା +`config/quality/gate-manifest.json`ରେ ରହିଛି। ସ୍କ୍ରିପ୍ଟ ନାମ ଏବଂ ସଠିକ୍ କମାଣ୍ଡଗୁଡ଼ିକୁ +`package.json` ସହିତ ଯାଞ୍ଚ କରିବା ପାଇଁ `npm run check:gate-manifest` ଚଲାନ୍ତୁ; ଯୋଗ, ଅପସାରଣ ଏବଂ +କମାଣ୍ଡର ବିଚ୍ୟୁତି ଉଭୟ ଲୋକାଲ୍ ହୁକ୍ ଏବଂ CIର ପରିବର୍ତ୍ତନ-ବର୍ଗୀକରଣ ଜବ୍ଗୁଡ଼ିକୁ ବିଫଳ କରେ। +ଏକ ଆଲିଆସ୍ କୌଣସି ୱର୍କଫ୍ଲୋ ଜବ୍, ମ୍ୟାଟ୍ରିକ୍ସ ଇନ୍ଷ୍ଟାନ୍ସ କିମ୍ବା ପରୀକ୍ଷଣ କେସ୍ ନୁହେଁ: ଏହି ଗଣନାଗୁଡ଼ିକୁ +ପରସ୍ପର ବିନିମୟଯୋଗ୍ୟ ଭାବେ ଉପସ୍ଥାପନ କରାଯିବା ଉଚିତ ନୁହେଁ। -ଚୟନିତ ଆଲିଆସ୍ଗୁଡ଼ିକୁ ନିଷ୍ପାଦନ ନକରି ନିରୀକ୍ଷଣ କରିବା ପାଇଁ `npm run quality:scan -- --list` କିମ୍ବା `npm run quality:scan:fast -- --list` -ବ୍ୟବହାର କରନ୍ତୁ। ରନର୍ npm ଏଣ୍ଟ୍ରିପଏଣ୍ଟକୁ ଆହ୍ୱାନ କରେ, ତେଣୁ ଏହାର ରନ୍ଟାଇମ୍ (ଯେଉଁଠାରେ ବିନ୍ୟାସିତ ଅଛି ସେଠାରେ Bun ସମେତ) ସଂରକ୍ଷିତ ରହେ। -ମ୍ୟାନିଫେଷ୍ଟ ସେହି ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକ ବାହାରର ଆଲିଆସ୍ଗୁଡ଼ିକୁ ପୃଥକ ଭାବେ ଆହ୍ୱାନ କରାଯାଇଥିବା ଭାବେ ରେକର୍ଡ କରେ, ଏବଂ -ରିଡ୍-ଅନ୍ଲି ସ୍କାନ୍ ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକରେ ରକ୍ଷଣାବେକ୍ଷଣ କମାଣ୍ଡ ନିଷିଦ୍ଧ। +ଚୟନିତ ଆଲିଆସ୍ଗୁଡ଼ିକୁ ନିଷ୍ପାଦନ ନ କରି ନିରୀକ୍ଷଣ କରିବା ପାଇଁ `npm run quality:scan -- --list` କିମ୍ବା `npm run quality:scan:fast -- --list` +ବ୍ୟବହାର କରନ୍ତୁ। ରନର୍ npm ଏଣ୍ଟ୍ରିପଏଣ୍ଟକୁ ଆହ୍ୱାନ କରେ, ତେଣୁ ଏହାର ରନ୍ଟାଇମ୍ (ଯେଉଁଠାରେ ବିନ୍ୟାସିତ, ସେଠାରେ Bun ସମେତ) ସଂରକ୍ଷିତ ରହେ। +ମ୍ୟାନିଫେଷ୍ଟ ସେହି ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକର ବାହାରେ ଥିବା ଆଲିଆସ୍ଗୁଡ଼ିକୁ ପୃଥକ ଭାବେ ଆହ୍ୱାନ କରାଯାଇଥିବା ଭାବେ ରେକର୍ଡ କରେ, ଏବଂ +କେବଳ-ପଠନ ସ୍କାନ୍ ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକରେ ରକ୍ଷଣାବେକ୍ଷଣ କମାଣ୍ଡ ନିଷିଦ୍ଧ। -ଏହି ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକ କେବଳ ଷ୍ଟାଟିକ୍ ସ୍କାନ୍କୁ ଅନ୍ତର୍ଭୁକ୍ତ କରନ୍ତି। ସେଗୁଡ଼ିକ ପ୍ରଡକ୍ଟ ପରୀକ୍ଷା, -କଭରେଜ୍, ପ୍ୟାକେଜିଂ, ବାହ୍ୟ ଚେକ୍ କିମ୍ବା କୌଣସି ପ୍ରାର୍ଥୀର ସମ୍ପୂର୍ଣ୍ଣ ରିଲିଜ୍ ଗ୍ରହଣକୁ ପ୍ରମାଣିତ କରନ୍ତି ନାହିଁ। -ୱାର୍କଫ୍ଲୋ ଗ୍ରହଣ ଲିଙ୍କ୍ ହୋଇଥିବା `config/quality/admission-policy.json` ଏବଂ -`scripts/quality/admission-verdict.mjs` ବ୍ୟବହାର କରେ। ରିଲିଜ୍-ଅବଜର୍ଭର୍ ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକ ପୃଥକ ରହେ; -ସେମାନଙ୍କର ପ୍ରଯୋଜ୍ୟ ଚେକ୍ ଏବଂ ରସିଦଗୁଡ଼ିକୁ ସ୍ୱାଧୀନ ଭାବେ ନିରୀକ୍ଷଣ କରନ୍ତୁ। ନିମ୍ନରେ ଥିବା ଗଦ୍ୟ -ଇନଭେଣ୍ଟୋରୀ ଏକ ସନ୍ଦର୍ଭ, କୌଣସି ଗେଟ୍ ପ୍ରକୃତରେ ଚାଲିଥିବାର ପ୍ରମାଣ ନୁହେଁ। +ଏହି ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକ କେବଳ ଷ୍ଟାଟିକ୍ ସ୍କାନ୍କୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ। ସେଗୁଡ଼ିକ ପ୍ରଡକ୍ଟ ପରୀକ୍ଷା, +କଭରେଜ୍, ପ୍ୟାକେଜିଂ, ବାହ୍ୟ ଚେକ୍ କିମ୍ବା ଏକ ପ୍ରାର୍ଥୀର ସମ୍ପୂର୍ଣ୍ଣ ରିଲିଜ୍ ଗ୍ରହଣୀୟତାକୁ ପ୍ରମାଣିତ କରେ ନାହିଁ। +ୱର୍କଫ୍ଲୋ ଅନୁମୋଦନ ଲିଙ୍କ୍ ହୋଇଥିବା `config/quality/admission-policy.json` ଏବଂ +`scripts/quality/admission-verdict.mjs` ବ୍ୟବହାର କରେ। ରିଲିଜ୍-ପର୍ଯ୍ୟବେକ୍ଷକ ପ୍ରୋଫାଇଲ୍ଗୁଡ଼ିକ ପୃଥକ ରହେ; +ସେମାନଙ୍କର ପ୍ରଯୁଜ୍ୟ ଚେକ୍ ଏବଂ ରସିଦଗୁଡ଼ିକୁ ସ୍ୱାଧୀନ ଭାବେ ନିରୀକ୍ଷଣ କରନ୍ତୁ। ନିମ୍ନରେ ଥିବା ଗଦ୍ୟ +ଇନଭେଣ୍ଟରି ଏକ ସନ୍ଦର୍ଭ, କୌଣସି ଗେଟ୍ ପ୍ରକୃତରେ ଚାଲିଥିବାର ପ୍ରମାଣ ନୁହେଁ। -ସ୍କ୍ରିପ୍ଟଗୁଡ଼ିକ `scripts/check/` (ନୀତି ଗେଟ୍ଗୁଡ଼ିକ) ଏବଂ `scripts/quality/` (ରାଚେଟ୍ ଇଞ୍ଜିନ୍) ଅଧୀନରେ ରହିଛି। -CIର ପ୍ରାମାଣିକ ଉତ୍ସ ହେଉଛି `.github/workflows/ci.yml`। +ସ୍କ୍ରିପ୍ଟଗୁଡ଼ିକ `scripts/check/` (ନୀତି ଗେଟ୍) ଏବଂ `scripts/quality/` (ରାଚେଟ୍ ଇଞ୍ଜିନ୍) ଅଧୀନରେ ରହିଛି। +CIର ପ୍ରମାଣିକ ଉତ୍ସ ହେଉଛି `.github/workflows/ci.yml`। -### ରିଲିଜ୍ PR ଫାଷ୍ଟ-ପାଥ୍ (`quality.yml`) +### ରିଲିଜ୍ PR ଦ୍ରୁତ ପଥ (`quality.yml`) -`.github/workflows/quality.yml` main/release PRଗୁଡ଼ିକ, ସୁରକ୍ଷିତ-ବ୍ରାଞ୍ଚ -ପୁଶ୍, ଡିସ୍ପ୍ୟାଚ୍ ଏବଂ ମର୍ଜ୍ ଗ୍ରୁପ୍ଗୁଡ଼ିକରେ CIକୁ ପରିପୂରକ କରେ। PRଗୁଡ଼ିକ ପାଥ୍-ଫିଲ୍ଟର୍ ହୋଇଥିବା ଦ୍ରୁତ ଚେକ୍ ବ୍ୟବହାର କରନ୍ତି। ସ୍ଥାୟୀ ଭାବେ -ଅକ୍ଷମ କରାଯାଇଥିବା ଡୁପ୍ଲିକେଟ୍ ବିଲ୍ଡକୁ ଅପସାରଣ କରାଯାଇଛି; ପ୍ରକୃତ ବିଲ୍ଡ/ପ୍ୟାକେଜ୍/ବୁଟ୍ ଚେକ୍ଗୁଡ଼ିକ CIରେ ରହିଛି। +`.github/workflows/quality.yml` main/release PR, ସୁରକ୍ଷିତ-ବ୍ରାଞ୍ଚ +ପୁସ୍, ଡିସ୍ପାଚ୍ ଏବଂ ମର୍ଜ୍ ଗ୍ରୁପ୍ଗୁଡ଼ିକରେ CIକୁ ପରିପୂରକ କରେ। PRଗୁଡ଼ିକ ପଥ-ଫିଲ୍ଟର୍ ହୋଇଥିବା ଦ୍ରୁତ ଚେକ୍ ବ୍ୟବହାର କରନ୍ତି। ସ୍ଥାୟୀ ଭାବେ +ଅକ୍ଷମ ହୋଇଥିବା ଡୁପ୍ଲିକେଟ୍ ବିଲ୍ଡକୁ ଅପସାରଣ କରାଯାଇଛି; ପ୍ରକୃତ ବିଲ୍ଡ/ପ୍ୟାକେଜ୍/ବୁଟ୍ ଚେକ୍ଗୁଡ଼ିକ CIରେ ରହିଛି। | ଜବ୍ | ପରିସର | ବ୍ଲକିଂ | | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `Docs Gates (fast-path)` | ଡକ୍ସ/କୋଡ୍ PRଗୁଡ଼ିକ; API ଡକ୍ସ ରେଫ୍ ଏବଂ docs-all | ହଁ | -| `Fast Quality Gates` | କୋଡ୍ PRଗୁଡ଼ିକ; ଷ୍ଟାଟିକ୍ ଚେକ୍, ଟାଇପ୍ଚେକ୍, ଡ୍ୟାସ୍ବୋର୍ଡ ଟାଇପ୍ଚେକ୍, ପ୍ରଭାବିତ ୟୁନିଟ୍ ପରୀକ୍ଷା | ହଁ | -| `Forgotten sibling tests` | କୋଡ୍ PRଗୁଡ଼ିକ; ପରିବର୍ତ୍ତିତ ମଡ୍ୟୁଲ୍ଗୁଡ଼ିକୁ ଷ୍ଟାଟିକ୍ ଉପଭୋକ୍ତା ଏବଂ ପ୍ରାର୍ଥୀ ସିବ୍ଲିଂ ପରୀକ୍ଷା ପର୍ଯ୍ୟନ୍ତ ଟ୍ରେସ୍ କରାଯାଏ; ବ୍ୟାରେଲ୍ ଏବଂ ଡାଇନାମିକ୍-ଇମ୍ପୋର୍ଟ ପାଥ୍ଗୁଡ଼ିକୁ ସନ୍ଦର୍ଭିତ ଅଲାଉଲିଷ୍ଟ ବ୍ୟତିକ୍ରମ ସହିତ ପରାମର୍ଶମୂଳକ ନିଦାନ ଭାବେ ରିପୋର୍ଟ କରାଯାଏ | **ପରାମର୍ଶମୂଳକ** | -| `Vitest (fast-path)` | କୋଡ୍ PRଗୁଡ଼ିକ; ଦ୍ରୁତ vitest ସୁଇଟ୍ | ହଁ | -| `Unit Tests fast-path` | କୋଡ୍ PRଗୁଡ଼ିକ; 4-ଶାର୍ଡ ୟୁନିଟ୍ ସୁଇଟ୍ | ହଁ | -| `No new ESLint warnings` | କୋଡ୍ PRଗୁଡ଼ିକ; ସପ୍ରେସନ୍-ସଚେତନ ଲିଣ୍ଟ୍ ଗାର୍ଡ | ହଁ, ଫୋର୍କ୍ ସମେତ | -| `Merge integrity (changelog + generated skills)` | ଅଣ-ଡ୍ରାଫ୍ଟ PRଗୁଡ଼ିକ; ଚେଞ୍ଜଲଗ୍ ଏବଂ ଜେନେରେଟେଡ୍ ସ୍କିଲ୍ ସିଙ୍କ୍ | ହଁ, ଫୋର୍କ୍ ସମେତ | +| `Docs Gates (fast-path)` | ଡକ୍ସ/କୋଡ୍ PR; API ଡକ୍ସ ରେଫରେନ୍ସ ଏବଂ docs-all | ହଁ | +| `Fast Quality Gates` | କୋଡ୍ PR; ଷ୍ଟାଟିକ୍ ଚେକ୍, ଟାଇପ୍ଚେକ୍, ଡ୍ୟାସ୍ବୋର୍ଡ ଟାଇପ୍ଚେକ୍, ପ୍ରଭାବିତ ୟୁନିଟ୍ ପରୀକ୍ଷା | ହଁ | +| `Forgotten sibling tests` | କୋଡ୍ PR; ପରିବର୍ତ୍ତିତ ମଡ୍ୟୁଲ୍ଗୁଡ଼ିକୁ ଷ୍ଟାଟିକ୍ ଉପଭୋକ୍ତା ଏବଂ ପ୍ରାର୍ଥୀ ସିବ୍ଲିଂ ପରୀକ୍ଷା ପର୍ଯ୍ୟନ୍ତ ଟ୍ରେସ୍ କରାଯାଏ; ବ୍ୟାରେଲ୍ ଏବଂ ଡାଇନାମିକ୍-ଇମ୍ପୋର୍ଟ ପଥଗୁଡ଼ିକୁ ସନ୍ଦର୍ଭିତ ଅଲାଉଲିଷ୍ଟ ବ୍ୟତିକ୍ରମ ସହିତ ପରାମର୍ଶମୂଳକ ଡାଇଗ୍ନୋଷ୍ଟିକ୍ ଭାବେ ରିପୋର୍ଟ କରାଯାଏ | **ପରାମର୍ଶମୂଳକ** | +| `Vitest (fast-path)` | କୋଡ୍ PR; ଦ୍ରୁତ vitest ସୁଇଟ୍ | ହଁ | +| `Unit Tests fast-path` | କୋଡ୍ PR; 4-ଶାର୍ଡ ୟୁନିଟ୍ ସୁଇଟ୍ | ହଁ | +| `No new ESLint warnings` | କୋଡ୍ PR; ସପ୍ରେସନ୍-ସଚେତନ lint ଗାର୍ଡ | ହଁ, ଫୋର୍କ୍ ସମେତ | +| `Merge integrity (changelog + generated skills)` | ଅଣ-ଡ୍ରାଫ୍ଟ PR; ଚେଞ୍ଜଲଗ୍ ଏବଂ ଜେନେରେଟେଡ୍ ସ୍କିଲ୍ ସିଙ୍କ୍ | ହଁ, ଫୋର୍କ୍ ସମେତ | #### ଭୁଲିଯାଇଥିବା ସିବ୍ଲିଂ ପରୀକ୍ଷା ରିପୋର୍ଟ `npm run check:forgotten-sibling-tests` ପରୀକ୍ଷା-ପ୍ରଭାବ ମ୍ୟାପ୍ ପଛରେ ଥିବା ଇମ୍ପୋର୍ଟ ରିଜଲ୍ଭର୍କୁ ପୁନଃବ୍ୟବହାର କରେ। -ପ୍ରତ୍ୟେକ ପରିବର୍ତ୍ତିତ ପ୍ରଡକ୍ସନ୍ ମଡ୍ୟୁଲ୍ ପାଇଁ, ଯେତେବେଳେ ପ୍ରାର୍ଥୀ -ପରୀକ୍ଷାଟି ପୁଲ୍-ରିକ୍ୱେଷ୍ଟ ଡିଫ୍ରେ ଅନୁପସ୍ଥିତ ଥାଏ, ଏହା ନିର୍ଦ୍ଧାରିତ -`changed module/symbol -> static consumer -> candidate sibling test` ଶୃଙ୍ଖଳଗୁଡ଼ିକୁ ରିପୋର୍ଟ କରେ। କୌଣସି ବ୍ଲକିଂ ରୋଲ୍ଆଉଟ୍ ପୂର୍ବରୁ କ୍ୟାଲିବ୍ରେସନ୍ ପାଇଁ Markdown ସାରାଂଶ ଏବଂ JSON ଫଳାଫଳକୁ -`forgotten-sibling-tests` ୱାର୍କଫ୍ଲୋ ଆର୍ଟିଫ୍ୟାକ୍ଟ ଭାବେ ରଖାଯାଏ। - -Barrel re-export ଏବଂ dynamic import କେବଳ resolution diagnostic ଅଟେ; ସେଗୁଡ଼ିକ କେବେ ମଧ୍ୟ -blocking finding ସୃଷ୍ଟି କରେ ନାହିଁ। ସମୀକ୍ଷା କରାଯାଇଥିବା exceptionଗୁଡ଼ିକ -`config/quality/forgotten-sibling-allowlist.json`ରେ ରହିଥାଏ। ପ୍ରତ୍ୟେକ entryରେ consumer ଏବଂ candidate -testର ନାମ, ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ ଯୁକ୍ତି, ଏବଂ GitHub issue କିମ୍ବା pull requestର link ରହିବା ଆବଶ୍ୟକ। ବିକୃତ entryଗୁଡ଼ିକ -fail closed ହୁଏ। Exceptionଗୁଡ଼ିକ ଏକ ବିଲୋପ ହୋଇଥିବା candidate test କିମ୍ବା `.skip`/`.todo` ଯୋଡ଼ୁଥିବା diffକୁ suppress କରିପାରିବ ନାହିଁ; -assertion ଦୁର୍ବଳୀକରଣ ଏବଂ ଅନ୍ୟ masking ସ୍ୱାଧୀନ ଭାବେ blocking କରୁଥିବା -`check:test-masking` gateର ଅଧୀନରେ ରହେ। - -### Job: `lint` - -`main` ପାଇଁ ପ୍ରତ୍ୟେକ PRରେ ଚାଲେ। ବିଫଳ ହେଲେ mergeକୁ block କରେ। - -| Script (`npm run ...`) | ଯାହାକୁ validate କରେ | Blocking | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | Node.js version ସମର୍ଥିତ range ମଧ୍ୟରେ ଅଛି | ହଁ | -| `check:cycles` | Circular import — ସମସ୍ତ `src/` + `open-sse/` module | ହଁ | -| `check:route-validation:t06` | ସମସ୍ତ routeରେ Zod schema ଉପସ୍ଥିତ ଅଛି (Tier 6 policy) | ହଁ | -| `check:any-budget:t11` | `@ts-expect-error // any` ସଂଖ୍ୟା budget ଅତିକ୍ରମ କରେ ନାହିଁ (Tier 11 catraca) | ହଁ | -| `check:provider-consistency` | `providers.ts`ର ପ୍ରତ୍ୟେକ ପ୍ରଦାନକାରୀ ପାଇଁ `providerRegistry.ts`ରେ ଏକ ମେଳ ଖାଉଥିବା ଏଣ୍ଟ୍ରି ଅଛି (ଏବଂ ଏହାର ବିପରୀତଟି ମଧ୍ୟ, ଅନୁମତି-ତାଲିକା ମଧ୍ୟରେ) | ହଁ | -| `check:model-lifecycle` | ହାତରେ ରକ୍ଷଣାବେକ୍ଷଣ କରାଯାଉଥିବା ତିନୋଟି ରାଉଟିଂ ଟେବୁଲ୍ ଚେକ୍-ଇନ୍ ହୋଇଥିବା ଜୀବନଚକ୍ର ସ୍ନାପସଟ୍ (#11503) ସହ ସୁସଙ୍ଗତ ରହେ: `FITNESS_TABLE` (`taskFitness.ts`) ଏପରି କୌଣସି ଅବସରପ୍ରାପ୍ତ idକୁ ସ୍କୋର୍ କରେ ନାହିଁ ଯାହାକୁ `REGISTRY` ରାଉଟ୍ କରିପାରେ; ପ୍ରତ୍ୟେକ `BUILT_IN_ALIASES` ଲକ୍ଷ୍ୟ `REGISTRY`ରେ ଉପସ୍ଥିତ ଏବଂ ଅବସରପ୍ରାପ୍ତ-id ସ୍ନାପସଟ୍ରେ ଅନୁପସ୍ଥିତ; `REGISTRY`ରେ ଏବେ ମଧ୍ୟ ଥିବା ପ୍ରତ୍ୟେକ ଅବସରପ୍ରାପ୍ତ idକୁ ଫରୱାର୍ଡ କରାଯାଇଛି କିମ୍ବା `allowedRetiredInCatalog`ରେ ତାଲିକାଭୁକ୍ତ କରାଯାଇଛି; ଏବଂ ସେହି ସ୍ନାପସଟ୍ରେ କୌଣସି `DEFAULT_DEGRADATION_MAP` ଉତ୍ସ କିମ୍ବା ଲକ୍ଷ୍ୟ ଅବସରପ୍ରାପ୍ତ ଭାବେ ଦେଖାଯାଏ ନାହିଁ। ଏହା ପ୍ରମାଣ କରେ ନାହିଁ ଯେ କୌଣସି ମଡେଲ୍ ବର୍ତ୍ତମାନ ଏକ ସକ୍ରିୟ ଅପ୍ଷ୍ଟ୍ରିମ୍ ଦ୍ୱାରା ପରିବେଷିତ ହେଉଛି। ଅଫ୍ଲାଇନ୍ — `config/quality/model-lifecycle.json` ସହ ତୁଳନା କରେ, ଯାହାକୁ `npm run quality:refresh-model-lifecycle` ବ୍ୟବହାର କରି ହାତରେ ସତେଜ କରାଯାଏ (ନେଟୱର୍କ; CI ସହ ସଂଯୁକ୍ତ ନୁହେଁ)। `allowedRetiredInCatalog` ହେଉଛି ଏକ କ୍ରମଶଃ-ହ୍ରାସ ରାଚେଟ୍: କେବଳ ଏକ ଟ୍ରାକିଂ ଇସ୍ୟୁ ସହିତ ଏଣ୍ଟ୍ରି ଯୋଡ଼ନ୍ତୁ। | ହଁ | -| `check:fetch-targets` | କ୍ଲାଏଣ୍ଟ-ପାର୍ଶ୍ୱ `src/`ର ପ୍ରତ୍ୟେକ `fetch("/api/...")` ଏକ ପ୍ରକୃତ `route.ts`କୁ ସମାଧାନ ହୁଏ | ହଁ | -| `check:deps` | ରେପୋର ପ୍ରତ୍ୟେକ `package.json`ରେ ଥିବା ସମସ୍ତ `npm install`-ଯୋଗ୍ୟ ନିର୍ଭରଶୀଳତା `dependency-allowlist.json`ରେ ଅଛି; ନୂଆ ଅପିନ୍ ହୋଇଥିବା କିମ୍ବା ସ୍ଲପସ୍କ୍ୱାଟ୍ ହୋଇଥିବା ପ୍ୟାକେଜ୍ଗୁଡ଼ିକୁ ଚିହ୍ନିତ କରାଯାଏ | ହଁ | -| `audit:deps` | `npm audit` (ରୁଟ୍ + electron) — କୌଣସି ଉଚ୍ଚ/ଗୁରୁତର ପରାମର୍ଶ ନାହିଁ (osv `check:vuln-ratchet` ସହ ଓଭରଲାପ୍ କରେ; ଯୁକ୍ତିସଙ୍ଗତକରଣ ବ୍ୟାକଲଗ୍ ଦେଖନ୍ତୁ) | ହଁ | -| `check:lockfile` | `package-lock.json`ର ଅଖଣ୍ଡତା — https ରେଜିଷ୍ଟ୍ରି, ଅଖଣ୍ଡତା ହ୍ୟାସ୍, କୌଣସି ହୋଷ୍ଟ ଓଭରରାଇଡ୍ ନାହିଁ | ହଁ | -| `check:licenses` | ପ୍ରଡକ୍ସନ୍ ଡିପେଣ୍ଡେନ୍ସିଗୁଡ଼ିକ ପାଇଁ SPDX ଲାଇସେନ୍ସ ଅନୁମୋଦିତ ତାଲିକା | ହଁ | -| `check:tracked-artifacts` | କୌଣସି ବିଲ୍ଡ ଆର୍ଟିଫ୍ୟାକ୍ଟ / କମିଟ୍ ହୋଇଥିବା `node_modules` ସିମ୍ଲିଙ୍କ୍ ନାହିଁ (husky pre-commitରେ ମଧ୍ୟ ଚାଲେ; pre-pushକୁ ଉଦ୍ଦେଶ୍ୟମୂଳକ ଭାବେ ହାଲୁକା ରଖାଯାଇଛି — #6716) | ହଁ | -| `check:ai-attribution` | PR କମିଟ୍, ଶୀର୍ଷକ କିମ୍ବା ବଡିରେ କୌଣସି AI/ବଟ୍ `Co-Authored-By` ଟ୍ରେଲର୍ କିମ୍ବା AI-ଜେନେରେସନ୍ ଫୁଟର୍ ନାହିଁ — କଠୋର ନିୟମ #16 (`quality.yml`ର PR→`release/**` ପାଇଁ fast-gates ଲୁପ୍ରେ — ଇଭେଣ୍ଟ ପେଲୋଡ୍ ପଢ଼େ, PR ନଥିଲେ କୌଣସି କାର୍ଯ୍ୟ କରେନାହିଁ — ଏବଂ `ci.yml` lintରେ PR→`main` ପାଇଁ ଏକ କେବଳ-PR ଷ୍ଟେପ୍; husky `commit-msg` ହୁକ୍ରେ ମଧ୍ୟ; ମାନବ ସହ-ଲେଖକଙ୍କୁ ଅନୁମତି ଅଛି; #14436) | -| `check:vitest-exclusions` | ପ୍ରତ୍ୟେକ Vitest ବାଦକରଣ ଏକ ଟ୍ରାକିଂ ଇସ୍ୟୁକୁ ଉଲ୍ଲେଖ କରେ ଏବଂ `config/quality/vitest-exclusions.json`ରେ ଉପସ୍ଥିତ ଥାଏ (#13204) | ହଁ | -| `check:file-size` | କୌଣସି ସୋର୍ସ ଫାଇଲ୍ ପ୍ରତି-ଏକ୍ସଟେନ୍ସନ୍ ସୀମା ଅତିକ୍ରମ କରେନାହିଁ (ର୍ୟାଚେଟ୍: `frozen` ତାଲିକାରେ ଫ୍ରିଜ୍ କରାଯାଇଥିବା ବଡ଼ ଫାଇଲ୍ଗୁଡ଼ିକ) | ହଁ | -| `check:error-helper` | ଏକ୍ସିକ୍ୟୁଟର୍/ହ୍ୟାଣ୍ଡଲର୍ଗୁଡ଼ିକରେ ତ୍ରୁଟି ପ୍ରତିକ୍ରିୟା `buildErrorBody()` / `sanitizeErrorMessage()` ବ୍ୟବହାର କରେ (କଠୋର ନିୟମ #12) | ହଁ | -| `check:migration-numbering` | Migration SQL ଫାଇଲ୍ଗୁଡ଼ିକ କୌଣସି ଅନୁକ୍ରମ ଅନ୍ତର କିମ୍ବା ପୁନରାବୃତ୍ତି ବିନା କ୍ରମାନୁସାରେ ସଂଖ୍ୟାୟିତ ହୋଇଛି | ହଁ | -| `check:public-creds` | `publicCreds.ts` ବାହାରେ କୌଣସି ସ୍ପଷ୍ଟ OAuth `client_id`/`client_secret` କିମ୍ବା Firebase Web କୀ ନାହିଁ (କଠୋର ନିୟମ #11) | ହଁ | -| `check:db-rules` | `src/lib/db/` ମଡ୍ୟୁଲ୍ଗୁଡ଼ିକ ବାହାରେ କୌଣସି ର’ SQL ନାହିଁ; `localDb.ts` ରୁ କୌଣସି barrel-import ନାହିଁ (କଠୋର ନିୟମ #2/#5) | ହଁ | -| `check:known-symbols` | ସେମାନଙ୍କ dispatch ଟେବୁଲ୍ରେ ପଞ୍ଜୀକୃତ provider executor, routing strategy ଏବଂ translatorଗୁଡ଼ିକ ଡିସ୍କରେ ଥିବା ଫାଇଲ୍ଗୁଡ଼ିକ ସହ ମେଳ ଖାଆନ୍ତି — କୌଣସି ଅନାଥ କିମ୍ବା ଅଘୋଷିତ symbol ନାହିଁ | ହଁ | -| `check:route-guard-membership` | child process ସୃଷ୍ଟି କରୁଥିବା ପ୍ରତ୍ୟେକ routeକୁ `isLocalOnlyPath()` ଦ୍ୱାରା ଶ୍ରେଣୀଭୁକ୍ତ କରାଯାଇଛି (କଠୋର ନିୟମ #15/#17) | ହଁ | -| `check:test-discovery` | repoରେ ଥିବା ପ୍ରତ୍ୟେକ `*.test.ts` / `*.spec.ts` ଫାଇଲ୍ ଅତି କମରେ ଗୋଟିଏ test runner ଦ୍ୱାରା ସଂଗୃହୀତ ହୁଏ (ratchet: `test-discovery-baseline.json`ରେ ଥିବା ଅନାଥ ତାଲିକା କେବଳ ସଙ୍କୁଚିତ ହୋଇପାରିବ) | ହଁ | -| `check:agent-skills-sync` | ସୃଷ୍ଟି କରାଯାଇଥିବା agent-skills ଆର୍ଟିଫ୍ୟାକ୍ଟଗୁଡ଼ିକ ସେମାନଙ୍କର ଉତ୍ସ କ୍ୟାଟାଲଗ୍ ସହିତ ମେଳ ଖାଉଛି (କୌଣସି ବିଚ୍ୟୁତି ନାହିଁ) | -| `check:provider-asset-provenance` | ପ୍ରଦାତାଙ୍କ ଲୋଗୋ/ଆସେଟ୍ଗୁଡ଼ିକରେ ଏକ ରେକର୍ଡ କରାଯାଇଥିବା ଉତ୍ପତ୍ତି ଏଣ୍ଟ୍ରି ରହିଛି | -| `lint:json` | JSON କନଫିଗ୍ ଫାଇଲ୍ଗୁଡ଼ିକ ପାର୍ସ ହୁଏ ଏବଂ ରିପୋଜିଟୋରିର ଲିଣ୍ଟ ନିୟମଗୁଡ଼ିକ ପୂରଣ କରେ | -| `typecheck:core` | ତ୍ରୁଟି ବିନା TypeScript କମ୍ପାଇଲେସନ୍ (କେବଳ ପରାମର୍ଶମୂଳକ ଚେତାବନୀ) | ହଁ | -| `typecheck:noimplicit:core` | କଠୋର `noImplicitAny` — ଭବିଷ୍ୟତମୁଖୀ; ପୂର୍ବରୁ ଥିବା ଅନେକ କଲ୍ ସାଇଟ୍ରେ ଏବେ ମଧ୍ୟ ଆନୋଟେସନ୍ ଆବଶ୍ୟକ | **ପରାମର୍ଶମୂଳକ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, `src/app/(dashboard)/**` ମଧ୍ୟରେ ସୀମିତ (#7033) — `typecheck:core`ର ସୁନିର୍ବାଚିତ 27-ଫାଇଲ୍ ଅନୁମୋଦିତ ତାଲିକାରେ କୌଣସି ଡ୍ୟାସ୍ବୋର୍ଡ TSX ଅନ୍ତର୍ଭୁକ୍ତ ନାହିଁ, ଏବଂ `next build` ମଧ୍ୟ ଏହାକୁ କେବେ ଟାଇପ୍-ଚେକ୍ କରେ ନାହିଁ (`next.config.mjs`ରେ `ignoreBuildErrors: true` ସେଟ୍ କରାଯାଇଛି), ତେଣୁ ସେଠାରେ ଥିବା ଅନାଥ-ପରିଚାୟକ ରିଗ୍ରେସନ୍ଗୁଡ଼ିକ (#6625/#6909) CI ପାଇଁ ଅଦୃଶ୍ୟ ଥିଲା। ଏକ ସ୍ଥିରୀକୃତ ପ୍ରତି-ଫାଇଲ୍/ପ୍ରତି-TS-କୋଡ୍ ଗଣନା ବେସ୍ଲାଇନ୍ (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ପରି ସମାନ ଅଚଳତା-ପ୍ରବର୍ତ୍ତନ ପ୍ରଣାଳୀ) ସହିତ ତଫାତ୍ ତୁଳନା କରେ — ବେସ୍ଲାଇନ୍ ଗଣନାଠାରୁ ଅଧିକ କେବଳ ନୂତନ ତ୍ରୁଟିଗୁଡ଼ିକ ଗେଟ୍କୁ ବିଫଳ କରେ; ପୂର୍ବରୁ ଥିବା ତ୍ରୁଟି ସମାଧାନ ହେଲେ `--update` ସହିତ ବେସ୍ଲାଇନ୍ କମାନ୍ତୁ। | ହଁ | +ପ୍ରତ୍ୟେକ ପରିବର୍ତ୍ତିତ ପ୍ରଡକ୍ସନ୍ ମଡ୍ୟୁଲ୍ ପାଇଁ, ପ୍ରାର୍ଥୀ +ପରୀକ୍ଷାଟି ପୁଲ୍-ରିକ୍ୱେଷ୍ଟ ଡିଫ୍ରେ ଅନୁପସ୍ଥିତ ଥିବାବେଳେ, ଏହା ନିର୍ଦ୍ଧାରିତ +`changed module/symbol -> static consumer -> candidate sibling test` ଶୃଙ୍ଖଳଗୁଡ଼ିକୁ ରିପୋର୍ଟ କରେ। ଯେକୌଣସି ବ୍ଲକିଂ ରୋଲ୍ଆଉଟ୍ ପୂର୍ବରୁ କ୍ୟାଲିବ୍ରେସନ୍ ପାଇଁ +Markdown ସାରାଂଶ ଏବଂ JSON ଫଳାଫଳକୁ `forgotten-sibling-tests` ୱର୍କଫ୍ଲୋ ଆର୍ଟିଫ୍ୟାକ୍ଟ ଭାବେ ସଂରକ୍ଷିତ ରଖାଯାଏ। + +ବ୍ୟାରେଲ୍ ପୁନଃ-ରପ୍ତାନି ଏବଂ ଡାଇନାମିକ୍ ଇମ୍ପୋର୍ଟଗୁଡ଼ିକ କେବଳ ରିଜୋଲ୍ୟୁସନ୍ ଡାଇଗ୍ନୋଷ୍ଟିକ୍; ସେଗୁଡ଼ିକ କେବେ ମଧ୍ୟ +ବ୍ଲକିଂ ଫାଇଣ୍ଡିଂ ସୃଷ୍ଟି କରନ୍ତି ନାହିଁ। ସମୀକ୍ଷା କରାଯାଇଥିବା ବ୍ୟତିକ୍ରମଗୁଡ଼ିକ +`config/quality/forgotten-sibling-allowlist.json`ରେ ରହେ। ପ୍ରତ୍ୟେକ ଏଣ୍ଟ୍ରିରେ ଉପଭୋକ୍ତା ଏବଂ ପ୍ରାର୍ଥୀ +ଟେଷ୍ଟର ନାମ, ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ ଯୁକ୍ତି, ଏବଂ ଏକ GitHub ଇସ୍ୟୁ କିମ୍ବା ପୁଲ୍ ରିକ୍ୱେଷ୍ଟର ଲିଙ୍କ ଦେବା ଆବଶ୍ୟକ। ତ୍ରୁଟିପୂର୍ଣ୍ଣ ଏଣ୍ଟ୍ରିଗୁଡ଼ିକ +ବନ୍ଦ ଅବସ୍ଥାରେ ବିଫଳ ହୁଏ। ବ୍ୟତିକ୍ରମଗୁଡ଼ିକ ଏକ ବିଲୋପିତ ପ୍ରାର୍ଥୀ ଟେଷ୍ଟ କିମ୍ବା `.skip`/`.todo` ଯୋଡ଼ୁଥିବା ଏକ diffକୁ ଦମନ କରିପାରିବ ନାହିଁ; +ଆସର୍ସନ୍ ଦୁର୍ବଳୀକରଣ ଏବଂ ଅନ୍ୟ ମାସ୍କିଂ ସ୍ୱାଧୀନ ଭାବେ ବ୍ଲକ୍ କରୁଥିବା +`check:test-masking` ଗେଟ୍ର ଅଧୀନରେ ରହେ। + +### ଜବ୍: `lint` + +`main` ପ୍ରତି ଥିବା ପ୍ରତ୍ୟେକ PRରେ ଚାଲେ। ବିଫଳ ହେଲେ ମର୍ଜ୍କୁ ବ୍ଲକ୍ କରେ। + +| ସ୍କ୍ରିପ୍ଟ (`npm run ...`) | ଯାହାକୁ ବୈଧ କରେ | ବ୍ଲକିଂ | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------- | +| `check:node-runtime` | Node.js ସଂସ୍କରଣ ସମର୍ଥିତ ପରିସର ମଧ୍ୟରେ ଅଛି | ହଁ | +| `check:cycles` | ସମଗ୍ର `src/` + `open-sse/`ରେ ସର୍କୁଲାର୍ ଇମ୍ପୋର୍ଟଗୁଡ଼ିକ (AST-ଆଧାରିତ, tsconfig `paths` ରିଜଲ୍ଭ୍ କରାଯାଇଛି)। Bare = ପରାମର୍ଶମୂଳକ, ସାଇକେଲ୍ଗୁଡ଼ିକୁ ତାଲିକାଭୁକ୍ତ କରେ। `check:cycles:ratchet` (ଯାହାକୁ CI ଚଲାଏ) `quality-baseline.json`ରେ ଥିବା `metrics.cycles` ସର୍ବୋଚ୍ଚ ସୀମାଠାରୁ ଗଣନା ଅଧିକ ହେଲେ ବ୍ଲକ୍ କରେ — ବର୍ତ୍ତମାନ 14, `direction: down`, ତେଣୁ ଏହା କେବଳ କମିପାରିବ (#15159 G-01/G-02) | ହଁ (ରାଚେଟ୍) | +| `check:route-validation:t06` | ସମସ୍ତ ରୁଟ୍ରେ Zod ସ୍କିମା ଉପସ୍ଥିତ ଅଛି (ଟିୟର୍ 6 ନୀତି) | ହଁ | +| `check:any-budget:t11` | `@ts-expect-error // any` ଗଣନା ବଜେଟ୍ ଅତିକ୍ରମ କରେ ନାହିଁ (ଟିୟର୍ 11 catraca) | ହଁ | +| `check:provider-consistency` | `providers.ts` ର ପ୍ରତ୍ୟେକ provider ପାଇଁ `providerRegistry.ts` ରେ ଏକ ମେଳ ଖାଉଥିବା entry ଅଛି (ଏବଂ ଏହାର ବିପରୀତଟି ମଧ୍ୟ, allowlist ମଧ୍ୟରେ) | ହଁ | +| `check:model-lifecycle` | ହାତରେ ରକ୍ଷଣାବେକ୍ଷଣ କରାଯାଉଥିବା ତିନୋଟି routing table, checked-in lifecycle snapshot (#11503) ସହ ସୁସଙ୍ଗତ ରହେ: `FITNESS_TABLE` (`taskFitness.ts`) ଏପରି କୌଣସି ଅବସରପ୍ରାପ୍ତ id କୁ score କରେ ନାହିଁ ଯାହାକୁ `REGISTRY` route କରିପାରେ; ପ୍ରତ୍ୟେକ `BUILT_IN_ALIASES` target `REGISTRY` ରେ ଉପସ୍ଥିତ ଏବଂ ଅବସରପ୍ରାପ୍ତ-id snapshot ରେ ଅନୁପସ୍ଥିତ; `REGISTRY` ରେ ଏପର୍ଯ୍ୟନ୍ତ ଥିବା ପ୍ରତ୍ୟେକ ଅବସରପ୍ରାପ୍ତ id କୁ forward କରାଯାଇଛି କିମ୍ବା `allowedRetiredInCatalog` ରେ ତାଲିକାଭୁକ୍ତ କରାଯାଇଛି; ଏବଂ କୌଣସି `DEFAULT_DEGRADATION_MAP` source କିମ୍ବା target ସେହି snapshot ରେ ଅବସରପ୍ରାପ୍ତ ଭାବେ ଦେଖାଯାଏ ନାହିଁ। ଏହା କୌଣସି model ବର୍ତ୍ତମାନ ଏକ ସକ୍ରିୟ upstream ଦ୍ୱାରା ପରିବେଶିତ ହେଉଛି ବୋଲି ପ୍ରମାଣ କରେ ନାହିଁ। Offline — `config/quality/model-lifecycle.json` ସହ ତୁଳନା କରେ, ଯାହାକୁ `npm run quality:refresh-model-lifecycle` (network; CI ସହ ସଂଯୁକ୍ତ ନୁହେଁ) ଦ୍ୱାରା ହାତରେ refresh କରାଯାଏ। `allowedRetiredInCatalog` ଏକ burn-down ratchet: କେବଳ ଏକ tracking issue ସହିତ ଏକ entry ଯୋଡ଼ନ୍ତୁ। | ହଁ | +| `check:fetch-targets` | client-side `src/` ରେ ଥିବା ପ୍ରତ୍ୟେକ `fetch("/api/...")` ଏକ ପ୍ରକୃତ `route.ts` କୁ resolve ହୁଏ | ହଁ | +| `check:deps` | repo ର ପ୍ରତ୍ୟେକ `package.json` ରେ ଥିବା ସମସ୍ତ `npm install`-ଯୋଗ୍ୟ dep `dependency-allowlist.json` ରେ ଅଛି; ନୂତନ unpinned କିମ୍ବା slopsquatted package ଗୁଡ଼ିକୁ flag କରାଯାଏ | ହଁ | +| `audit:deps` | `npm audit` (root + electron) — କୌଣସି high/critical advisory ନାହିଁ (osv `check:vuln-ratchet` ସହ overlap କରେ; Rationalization Backlog ଦେଖନ୍ତୁ) | ହଁ | +| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hash, କୌଣସି host override ନାହିଁ | ହଁ | +| `check:licenses` | ପ୍ରଡକ୍ସନ୍ ନିର୍ଭରତାଗୁଡ଼ିକ ପାଇଁ SPDX ଲାଇସେନ୍ସ ଅନୁମୋଦିତ ତାଲିକା | ହଁ | +| `check:tracked-artifacts` | କୌଣସି ବିଲ୍ଡ ଆର୍ଟିଫ୍ୟାକ୍ଟ / କମିଟ୍ କରାଯାଇଥିବା `node_modules` ସିମ୍ଲିଙ୍କ୍ ନାହିଁ (husky pre-commitରେ ମଧ୍ୟ ଚାଲେ; pre-pushକୁ ଉଦ୍ଦେଶ୍ୟମୂଳକ ଭାବେ ହାଲୁକା ରଖାଯାଇଛି — #6716) | ହଁ | +| `check:ai-attribution` | PR କମିଟ୍, ଶୀର୍ଷକ କିମ୍ବା ବିବରଣୀରେ କୌଣସି AI/bot `Co-Authored-By` ଟ୍ରେଲର୍ କିମ୍ବା AI-ଜେନେରେସନ୍ ଫୁଟର୍ ନାହିଁ — କଠୋର ନିୟମ #16 (`quality.yml`ର PR→`release/**` ପାଇଁ fast-gates ଲୁପ୍ରେ — ଇଭେଣ୍ଟ ପେଲୋଡ୍ ପଢ଼େ, PR ବ୍ୟତୀତ ଅନ୍ୟ ସ୍ଥାନରେ କୌଣସି କାର୍ଯ୍ୟ କରେ ନାହିଁ — ଏବଂ `ci.yml` lintରେ PR→`main` ପାଇଁ କେବଳ-PR ପଦକ୍ଷେପ; husky `commit-msg` ହୁକ୍ରେ ମଧ୍ୟ; ମାନବ ସହ-ଲେଖକମାନେ ଅନୁମୋଦିତ; #14436) | +| `check:vitest-exclusions` | ପ୍ରତ୍ୟେକ Vitest ବହିଷ୍କରଣ ଏକ ଟ୍ରାକିଂ ଇସ୍ୟୁ ଉଲ୍ଲେଖ କରେ ଏବଂ `config/quality/vitest-exclusions.json`ରେ ଦେଖାଯାଏ (#13204) | ହଁ | +| `check:file-size` | କୌଣସି ସୋର୍ସ ଫାଇଲ୍ ପ୍ରତି-ଏକ୍ସଟେନ୍ସନ୍ ସୀମା ଅତିକ୍ରମ କରେ ନାହିଁ (ରାଚେଟ୍: `frozen` ତାଲିକାରେ ଫ୍ରିଜ୍ କରାଯାଇଥିବା ବଡ଼ ଫାଇଲ୍ଗୁଡ଼ିକ) | ହଁ | +| `check:error-helper` | ଏକ୍ସିକ୍ୟୁଟର୍/ହ୍ୟାଣ୍ଡଲର୍ଗୁଡ଼ିକରେ ତ୍ରୁଟି ପ୍ରତିକ୍ରିୟା `buildErrorBody()` / `sanitizeErrorMessage()` ବ୍ୟବହାର କରେ (କଠୋର ନିୟମ #12) | ହଁ | +| `check:migration-numbering` | Migration SQL ଫାଇଲଗୁଡ଼ିକ କୌଣସି କ୍ରମିକ ସଂଖ୍ୟାର ଅଭାବ କିମ୍ବା ପୁନରାବୃତ୍ତି ବିନା କ୍ରମାନୁସାରେ ସଂଖ୍ୟାଙ୍କିତ ହୋଇଛି | ହଁ | +| `check:public-creds` | `publicCreds.ts` ବାହାରେ କୌଣସି ସ୍ପଷ୍ଟ OAuth `client_id`/`client_secret` କିମ୍ବା Firebase Web କୀ ନାହିଁ (କଠୋର ନିୟମ #11) | ହଁ | +| `check:db-rules` | `src/lib/db/` ମଡ୍ୟୁଲଗୁଡ଼ିକ ବାହାରେ କୌଣସି କଞ୍ଚା SQL ନାହିଁ; `localDb.ts` ରୁ କୌଣସି ବ୍ୟାରେଲ୍ ଇମ୍ପୋର୍ଟ ନାହିଁ (କଠୋର ନିୟମ #2/#5) | ହଁ | +| `check:known-symbols` | ସେମାନଙ୍କ ଡିସ୍ପାଚ୍ ଟେବୁଲରେ ପଞ୍ଜୀକୃତ ପ୍ରଦାତା ନିଷ୍ପାଦକ, ରାଉଟିଂ କୌଶଳ ଏବଂ ଅନୁବାଦକଗୁଡ଼ିକ ଡିସ୍କରେ ଥିବା ଫାଇଲଗୁଡ଼ିକ ସହ ମେଳ ଖାଆନ୍ତି — କୌଣସି ଅନାଥ କିମ୍ବା ଅଘୋଷିତ ସଙ୍କେତ ନାହିଁ | ହଁ | +| `check:route-guard-membership` | ଚାଇଲ୍ଡ ପ୍ରୋସେସ୍ ଆରମ୍ଭ କରୁଥିବା ପ୍ରତ୍ୟେକ ରୁଟ୍ `isLocalOnlyPath()` ଦ୍ୱାରା ବର୍ଗୀକୃତ ହୋଇଛି (କଠୋର ନିୟମ #15/#17) | ହଁ | +| `check:test-discovery` | ରିପୋରେ ଥିବା ପ୍ରତ୍ୟେକ `*.test.ts` / `*.spec.ts` ଫାଇଲ୍ ଅତି କମରେ ଗୋଟିଏ ଟେଷ୍ଟ ରନର୍ ଦ୍ୱାରା ସଂଗୃହୀତ ହୁଏ (ରାଚେଟ୍: `test-discovery-baseline.json` ରେ ଥିବା ଅନାଥ ତାଲିକା କେବଳ ସଙ୍କୁଚିତ ହୋଇପାରିବ) | ହଁ | +| `check:agent-skills-sync` | ସୃଷ୍ଟି ହୋଇଥିବା agent-skills ଆର୍ଟିଫ୍ୟାକ୍ଟଗୁଡ଼ିକ ସେମାନଙ୍କର ଉତ୍ସ କ୍ୟାଟାଲଗ୍ ସହ ମେଳ ଖାଉଛି (କୌଣସି ବିଚ୍ୟୁତି ନାହିଁ) | +| `check:provider-asset-provenance` | ପ୍ରଦାତାଙ୍କ ଲୋଗୋ/ଆସେଟ୍ଗୁଡ଼ିକର ଏକ ରେକର୍ଡ କରାଯାଇଥିବା ଉତ୍ପତ୍ତି-ସୂଚନା ଏଣ୍ଟ୍ରି ରହିଛି | +| `lint:json` | JSON କନଫିଗ୍ ଫାଇଲ୍ଗୁଡ଼ିକ ପାର୍ସ ହୁଏ ଏବଂ ରିପୋଜିଟୋରିର ଲିଣ୍ଟ ନିୟମଗୁଡ଼ିକ ପୂରଣ କରେ | +| `typecheck:core` | ତ୍ରୁଟି ବିନା TypeScript କମ୍ପାଇଲେସନ୍ (କେବଳ ପରାମର୍ଶମୂଳକ ଚେତାବନୀ) | ହଁ | +| `typecheck:noimplicit:core` | କଠୋର `noImplicitAny` — ଭବିଷ୍ୟତମୁଖୀ; ପୂର୍ବରୁ ଥିବା ଅନେକ କଲ୍ ସାଇଟ୍ରେ ଏବେ ମଧ୍ୟ ଆନୋଟେସନ୍ ଆବଶ୍ୟକ | **ପରାମର୍ଶମୂଳକ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` ପର୍ଯ୍ୟନ୍ତ ସୀମିତ `tsc` (#7033) — `typecheck:core`ର ସୁନିର୍ଦ୍ଧାରିତ 27-ଫାଇଲ୍ ଅନୁମତି-ତାଲିକାରେ କୌଣସି ଡ୍ୟାସ୍ବୋର୍ଡ TSX ଅନ୍ତର୍ଭୁକ୍ତ ନାହିଁ, ଏବଂ `next build` ମଧ୍ୟ ଏହାର ପ୍ରକାର ଯାଞ୍ଚ କରେ ନାହିଁ (`next.config.mjs`ରେ `ignoreBuildErrors: true` ସେଟ୍ କରାଯାଇଛି), ତେଣୁ ସେଠାରେ ଥିବା ଅନାଥ-ଆଇଡେଣ୍ଟିଫାୟର୍ ରିଗ୍ରେସନ୍ଗୁଡ଼ିକ (#6625/#6909) CI ପାଇଁ ଅଦୃଶ୍ୟ ଥିଲା। ଏକ ସ୍ଥିର କରାଯାଇଥିବା ପ୍ରତି-ଫାଇଲ୍/ପ୍ରତି-TS-କୋଡ୍ ଗଣନା ବେସ୍ଲାଇନ୍ (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ପରି ସମାନ ପୁରୁଣା-ସ୍ଥିତି ପ୍ରବର୍ତ୍ତନ ଢାଞ୍ଚା) ସହ ପାର୍ଥକ୍ୟ ଯାଞ୍ଚ କରେ — ବେସ୍ଲାଇନ୍ ଗଣନାଠାରୁ ଅଧିକ କେବଳ ନୂତନ ତ୍ରୁଟିଗୁଡ଼ିକ ଗେଟ୍କୁ ବିଫଳ କରେ; ପୂର୍ବରୁ ଥିବା କୌଣସି ତ୍ରୁଟି ସମାଧାନ ହେଲେ `--update` ସହିତ ବେସ୍ଲାଇନ୍କୁ କ୍ରମେ କମାନ୍ତୁ। | ହଁ | ### ଜବ୍: `quality-gate` `test-coverage` ପରେ ଚାଲେ। ବିଫଳ ହେଲେ ମର୍ଜ୍କୁ ଅବରୋଧ କରେ। -| ସ୍କ୍ରିପ୍ଟ | ଯାହାକୁ ବୈଧ କରେ | ଅବରୋଧକ | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | -| `quality:collect` | `quality-metrics.json` ନିର୍ଗତ କରେ (ESLint ଚେତାବନୀ ସଂଖ୍ୟା, ମିଶ୍ରିତ shard ରିପୋର୍ଟରୁ coverage) | ହଁ (ratchetର upstream) | -| `quality:ratchet` | `quality-baseline.json`ର ପ୍ରତ୍ୟେକ metricର ଅବନତି ହୋଇନାହିଁ (ESLint ଚେତାବନୀ ≤ baseline; coverage ≥ baseline) | ହଁ | -| `check:duplication` | କୋଡ୍ ନକଲ (jscpd@4) `quality-baseline.json`ର baselineକୁ ଅତିକ୍ରମ କରେ ନାହିଁ | ହଁ | -| `check:complexity` | ଫାଇଲ୍-ସ୍ତରୀୟ cyclomatic complexity ନିର୍ଦ୍ଧାରିତ ସୀମାକୁ ଅତିକ୍ରମ କରେ ନାହିଁ (ମୂଳ ESLint `complexity` + `max-lines-per-function`) | ହଁ | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — ପୃଥକ ESLint pass; CI ଉଭୟକୁ ଏକକ `check:complexity-ratchets` ପଦକ୍ଷେପ ଭାବେ ମିଶାଇ ଚଲାଏ | ହଁ | -| `check:dead-code` | ଅବ୍ୟବହୃତ exports / files ratchet (knip)ର baseline ତୁଳନାରେ ଅବନତି ହୁଏ ନାହିଁ | ହଁ | -| `check:compression-budget` | Compression benchmark budget — ପ୍ରତ୍ୟେକ engineର token-savings floorsର ଅବନତି ହେବା ଉଚିତ ନୁହେଁ | ହଁ | -| `check:type-coverage` | Percent-typed ratchet (`type-coverage`)ର ଅବନତି ହୁଏ ନାହିଁ; ଏହା ମୁଖ୍ୟତଃ `typecheck:noimplicit:core`କୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ | ହଁ | -| `check:codeql-ratchet` | ଖୋଲା CodeQL alert ସଂଖ୍ୟାର ଅବନତି ହୁଏ ନାହିଁ (`gh api` ମାଧ୍ୟମରେ ପଢ଼େ; token ବିନା ସୁରକ୍ଷିତ ଭାବେ skip କରେ) — refresh cadence ଏବଂ manual trigger: ତଳେ "CodeQL ratchet" ଦେଖନ୍ତୁ | ହଁ | - -### Job: `quality-extended` - -ସମ୍ପୂର୍ଣ୍ଣ jobଟି ପରାମର୍ଶମୂଳକ (`continue-on-error: true`)। npm-ଆଧାରିତ ratchets ବାସ୍ତବରେ -ଚାଲେ; external scannersଗୁଡ଼ିକ `gh release download` ମାଧ୍ୟମରେ install ହୁଅନ୍ତି ଏବଂ କୌଣସି binary ଏପର୍ଯ୍ୟନ୍ତ ଅନୁପସ୍ଥିତ -ଥିଲେ ନିଜେ skip କରନ୍ତି (exit 0)। - -| ସ୍କ୍ରିପ୍ଟ | ଯାହାକୁ ବୈଧ କରେ | ଅବରୋଧକ | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:circular-deps` | କୌଣସି circular dependencies ନାହିଁ (dpdm) | **ପରାମର୍ଶମୂଳକ** | -| `check:bundle-size` | Bundle size ନିର୍ଦ୍ଧାରିତ ସୀମାକୁ ଅତିକ୍ରମ କରେ ନାହିଁ | **ପରାମର୍ଶମୂଳକ** | -| `check:secrets` | Secret scanning (gitleaks) — binary ଅନୁପସ୍ଥିତ ଥିଲେ skip କରେ | **ପରାମର୍ଶମୂଳକ** | -| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner)ର ଅବନତି ହୁଏ ନାହିଁ — binary ଅନୁପସ୍ଥିତ ଥିଲେ skip କରେ | **ପରାମର୍ଶମୂଳକ** | -| `check:workflows` | Workflow lint (actionlint + zizmor); ଅନୁପସ୍ଥିତ/ତ୍ରୁଟିପୂର୍ଣ୍ଣ scanners, ଅବୈଧ reports କିମ୍ବା ଅନୁପସ୍ଥିତ ratchet baseline, INCOMPLETE ଭାବେ ବିଫଳ ହୁଏ। ବୈଧ findings ଚୟନିତ strict/advisory/ratchet policy ଅନୁସରଣ କରେ | Execution ଆବଶ୍ୟକ; CIରେ zizmor ratchet ଅବରୋଧକ | -| `check:openapi-breaking` | ସାର୍ବଜନୀନ API contract (`openapi.yaml`)ରେ base branch ତୁଳନାରେ breaking changes (oasdiff) — `openapiBreaking=N` ନିର୍ଗତ କରେ; oasdiff ଅନୁପସ୍ଥିତ କିମ୍ବା base spec ସମାଧାନଯୋଗ୍ୟ ନହେଲେ skip କରେ | **ପରାମର୍ଶମୂଳକ** | - -### Job: `docs-sync-strict` - -`main`କୁ ଯାଉଥିବା ପ୍ରତ୍ୟେକ PRରେ ଚାଲେ। ବିଫଳ ହେଲେ mergeକୁ ଅବରୋଧ କରେ। - -| ସ୍କ୍ରିପ୍ଟ | ଯାଞ୍ଚ କରେ | ଅବରୋଧକ | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | -| `check:docs-all` | ନିମ୍ନର 6ଟି ଉପ-ଗେଟ୍କୁ କ୍ରମାନୁସାରେ ଚଲାଉଥିବା ମେଟା-ଗେଟ୍ | ହଁ | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ସଂସ୍କରଣ ସୁସଙ୍ଗତତା | ହଁ | -| ↳ `check:docs-counts` | ଗଦ୍ୟରେ ଥିବା ସଂଖ୍ୟାଗୁଡ଼ିକ (ପ୍ରଦାନକାରୀ ସଂଖ୍ୟା, ମାଇଗ୍ରେସନ୍ ସଂଖ୍ୟା ଇତ୍ୟାଦି) ପ୍ରକୃତ ସଂଖ୍ୟାର ରାଚେଟ୍ ସୀମା ମଧ୍ୟରେ ଅଛି | ହଁ | -| ↳ `check:env-doc-sync` | `.env.example`ର ପ୍ରତ୍ୟେକ ପରିବେଶ ଭେରିଏବଲ୍ ଏକ ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ଟେବୁଲ୍ରେ ଲିପିବଦ୍ଧ ଅଛି, ଏବଂ ତାହାର ବିପରୀତଟି ମଧ୍ୟ ସତ୍ୟ | ହଁ | -| ↳ `check:deprecated-versions` | ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକରେ କୌଣସି ଅବମୂଲ୍ୟାୟିତ ସଂସ୍କରଣ ଷ୍ଟ୍ରିଙ୍ଗ୍ ନାହିଁ | ହଁ | -| ↳ `check:doc-links` | ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକର ଆଭ୍ୟନ୍ତରୀଣ ମାର୍କଡାଉନ୍ ଲିଙ୍କ୍ଗୁଡ଼ିକ ପ୍ରକୃତ ଫାଇଲ୍କୁ ରିଜଲ୍ଭ ହୁଏ (`[text]`/`(path)` ରୂପ) | ହଁ | -| ↳ `check:fabricated-docs` | ଡକ୍ୟୁମେଣ୍ଟରେ ଉଲ୍ଲେଖିତ ରୁଟ୍, ପରିବେଶ ଭେରିଏବଲ୍, CLI କମାଣ୍ଡ, ହୁକ୍ ନାମ ଏବଂ ଫାଇଲ୍ ପଥଗୁଡ଼ିକ କୋଡ୍ବେସ୍ରେ ଅଛି। `--strict` ମାଧ୍ୟମରେ କଠୋର ଗେଟ୍; ଫ୍ଲାଗ୍ ବିନା ସଫ୍ଟ-ଫେଲ୍। | ହଁ (CIରେ `--strict` ମାଧ୍ୟମରେ) | -| `check:cli-i18n` | CLI କମାଣ୍ଡ ଷ୍ଟ୍ରିଙ୍ଗ୍ଗୁଡ଼ିକ ସମସ୍ତ i18n ଲୋକେଲ୍ ଫାଇଲ୍ରେ ଉପସ୍ଥିତ | ହଁ | -| `check:openapi-coverage` | OpenAPI ସ୍ପେକ୍ ପ୍ରକୃତ ରୁଟ୍ଗୁଡ଼ିକର ଅତି କମରେ ଏକ ରାଚେଟ୍-ନିର୍ଦ୍ଧାରିତ ସର୍ବନିମ୍ନ ସୀମାକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ | ହଁ | -| `check:openapi-security-tiers` | `openapi.yaml`ରେ ଥିବା ସୁରକ୍ଷା ସ୍ତର ଆନୋଟେସନ୍ଗୁଡ଼ିକ `routeGuard.ts` ବର୍ଗୀକରଣ ସହିତ ସୁସଙ୍ଗତ | **ପରାମର୍ଶମୂଳକ** | -| `check:openapi-routes` | `openapi.yaml`ର ପ୍ରତ୍ୟେକ ପଥ ଏକ ପ୍ରକୃତ `route.ts`କୁ ରିଜଲ୍ଭ ହୁଏ (କଳ୍ପନା-ବିରୋଧୀ) | ହଁ | -| `check:docs-symbols` | `docs/**/*.md`ର ପ୍ରତ୍ୟେକ `/api/...` ସନ୍ଦର୍ଭ ଏକ ପ୍ରକୃତ `route.ts`କୁ ରିଜଲ୍ଭ ହୁଏ (କଳ୍ପନା-ବିରୋଧୀ) | ହଁ | -| `i18n translation drift` | i18n ଲୋକେଲ୍ ଫାଇଲ୍ଗୁଡ଼ିକରେ ଅନୁବାଦ ହୋଇନଥିବା କୀ — କେବଳ ଚେତାବନୀ | **ପରାମର୍ଶମୂଳକ** | - -### କାର୍ଯ୍ୟ: `i18n-ui-coverage` - -| ସ୍କ୍ରିପ୍ଟ | ଯାଞ୍ଚ କରେ | ଅବରୋଧକ | -| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | -| `check-ui-keys-coverage` (ଇନ୍ଲାଇନ୍) | UI i18n କୀ କଭରେଜ୍ ≥ 65% | ହଁ | -| `check-ui-value-drift` (ଇନ୍ଲାଇନ୍) | ପୁନର୍ଲିଖିତ ଇଂରାଜୀ **ମୂଲ୍ୟ** ପଛରେ କୌଣସି ଅଚଳ ଅନୁବାଦ ଛାଡ଼େ ନାହିଁ | ହଁ | -| `check-new-key-coverage` (ଇନ୍ଲାଇନ୍) | ଏକ **ନୂତନ** ଇଂରାଜୀ କୀ ପ୍ରତ୍ୟେକ ଲୋକେଲ୍ରେ ଅନୁବାଦିତ — ଏକ `__MISSING__:` ମାର୍କର୍ ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଯାଏ | ହଁ | -| `check-translation-ratio` | ପ୍ରତି ଲୋକେଲ୍ର ପ୍ରକୃତ-ଅନୁବାଦ ଅନୁପାତ (ଅନୁମୋଦିତ ତାଲିକା ବାହାରେ ଇଂରାଜୀ ସହ ସମାନ / ପ୍ଲେସହୋଲ୍ଡର୍ / ଅନୁପସ୍ଥିତ ଲିଫ୍) `config/quality/i18n-translation-baseline.json` + ଅତିରିକ୍ତ ସୀମାକୁ ଅତିକ୍ରମ କରିବା ଉଚିତ୍ ନୁହେଁ | **ପରାମର୍ଶମୂଳକ** | - -`fetch-depth: 0` ଆବଶ୍ୟକ — ମୂଲ୍ୟ-ଡ୍ରିଫ୍ଟ ଗେଟ୍ ମର୍ଜ୍ ବେସ୍ ସହିତ `en.json`ର ଡିଫ୍ କରେ। - -#### `check-ui-value-drift` — ଅଚଳ-ଅନୁବାଦ ଗେଟ୍ - -ଏହା ସେହି ଗୋଟିଏ i18n ରିଗ୍ରେସନ୍କୁ ଧରେ ଯାହାକୁ ଅନ୍ୟ ଗେଟ୍ଗୁଡ଼ିକ ଗଠନାତ୍ମକ ଭାବେ ଦେଖିପାରନ୍ତି ନାହିଁ: ଏକ ଇଂରାଜୀ ମୂଲ୍ୟ -ପୁନର୍ଲିଖିତ ହୁଏ ଏବଂ _ପୂର୍ବବର୍ତ୍ତୀ_ ଇଂରାଜୀରୁ ଉତ୍ପନ୍ନ ଅନୁବାଦଗୁଡ଼ିକ ପଛରେ ରହିଯାଏ, ତେଣୁ -ଅଣ-ଇଂରାଜୀ ବ୍ୟବହାରକାରୀମାନେ ଆତ୍ମବିଶ୍ୱାସୀ ଭାଷାରେ ଲିଖିତ, କିନ୍ତୁ ବର୍ତ୍ତମାନ ଭୁଲ୍ ଥିବା ପାଠ୍ୟ ପଢ଼ିବା ଜାରି ରଖନ୍ତି। - -ଏହା ପ୍ରକୃତରେ ରିଲିଜ୍ ହୋଇଥିଲା। Antigravity ଲଗ୍ଇନ୍ ସହାୟକ ଆସିବା ସମୟରେ (#5203) -`oauthModal.googleOAuthWarning` ପୁନର୍ଲିଖିତ ହୋଇଥିଲା; **43ଟି ଲୋକେଲ୍ରୁ 39ଟି**ରେ ଅପରେଟର୍ମାନଙ୍କୁ "ସମ୍ପୂର୍ଣ୍ଣ URL କପି କରି ତଳେ ପେଷ୍ଟ କରନ୍ତୁ" ବୋଲି କହୁଥିବା ପାଠ୍ୟ ରହିଯାଇଥିଲା — ଏକ ଏପରି ପ୍ରବାହ ଯାହା ସେହି ପ୍ରଦାନକାରୀ ପାଇଁ ସମ୍ପୂର୍ଣ୍ଣ ହୋଇପାରେ ନାହିଁ। ଏହା -#8463 ପର୍ଯ୍ୟନ୍ତ ଅଲକ୍ଷିତ ରହିଲା, କାରଣ: - -- `sync-ui-keys` କେବଳ **ଅନୁପସ୍ଥିତ** କୀଗୁଡ଼ିକୁ ବ୍ୟାକ୍ଫିଲ୍ କରେ, **ଅଚଳ** କୀଗୁଡ଼ିକୁ କେବେ ନୁହେଁ; -- `check-ui-keys-coverage` କୀର _ଉପସ୍ଥିତି_ ଗଣନା କରେ, ତେଣୁ ଏକ ଅଚଳ ଅନୁବାଦକୁ କଭର୍ ହୋଇଛି ବୋଲି ଗଣାଯାଏ; -- `check-translation-drift` `docs/i18n//**.md` ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ପ୍ରତିରୂପଗୁଡ଼ିକୁ ଟ୍ରାକ୍ କରେ — - ଏହା କେବେବି `src/i18n/messages/*.json` ପଢ଼େ ନାହିଁ। 2026-09 ପୁନଃ-ସିଙ୍କ୍ ପରଠାରୁ `docs-sync-strict` କାର୍ଯ୍ୟରେ ଅବରୋଧକ: ଏକ ମୁଖ୍ୟ ଡକ୍ୟୁମେଣ୍ଟ ସମ୍ପାଦନା କରନ୍ତୁ → `npm run i18n:run -- --files=` (ବିଭାଗ-ସ୍ତରୀୟ, କମ୍ ଖର୍ଚ୍ଚସାଧ୍ୟ)। - -**Diff-ସଚେତନ, baseline-ସମର୍ଥିତ ନୁହେଁ।** ଏହା merge base-ର `en.json`କୁ working tree ସହିତ ତୁଳନା କରେ; ଯେଉଁ ପ୍ରତ୍ୟେକ key-ର ଇଂରାଜୀ value ପରିବର୍ତ୍ତିତ ହୋଇଛି, ସେଥିପାଇଁ ଏପର୍ଯ୍ୟନ୍ତ ଅପରିବର୍ତ୍ତିତ translation ଧାରଣ କରିଥିବା ଯେକୌଣସି locale ପୁରୁଣା ହୋଇଯାଇଛି। ଏହା ଉଦ୍ଦେଶ୍ୟମୂଳକ ଭାବେ **ପୂର୍ବରୁ ଥିବା ବକେୟା କାମକୁ ସ୍ଥିର କରିଦିଏ** — ଦୀର୍ଘଦିନ ଧରି ଥିବା କୌଣସି translation କେଉଁ ପୁରୁଣା ଇଂରାଜୀରୁ ଆସିଛି, ଏକ diff ତାହା ପ୍ରକାଶ କରିପାରେ ନାହିଁ; ତେଣୁ gate କେବଳ ବର୍ତ୍ତମାନର ପରିବର୍ତ୍ତନ ଯାହାକୁ ସ୍ପର୍ଶ କରେ, ତାହାର ହିଁ ବିଚାର କରେ। ବିକଳ୍ପଟି (ପ୍ରତି-key hash baseline) ପାଇଁ ଏକ ~600 KB generated file ଆବଶ୍ୟକ ହେବ, ଯାହା ସବୁଠାରୁ ବଡ଼ ବର୍ତ୍ତମାନର baseline-ର 3×, ଏବଂ ପ୍ରତ୍ୟେକ i18n PR-ରେ ବାରମ୍ବାର ବଦଳିବ। +| ସ୍କ୍ରିପ୍ଟ | ଯାଞ୍ଚ କରେ | ଅବରୋଧକ | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `quality:collect` | `quality-metrics.json` ନିର୍ଗତ କରେ (ESLint ଚେତାବନୀ ସଂଖ୍ୟା, ମିଶ୍ରିତ shard ରିପୋର୍ଟରୁ coverage) | ହଁ (ratchet-ର upstream) | +| `quality:ratchet` | `quality-baseline.json`-ର ପ୍ରତ୍ୟେକ metric-ର ଅବନତି ହୋଇନାହିଁ (ESLint ଚେତାବନୀ ≤ baseline; coverage ≥ baseline) | ହଁ | +| `check:duplication` | କୋଡ୍ ନକଲ (jscpd@4) `quality-baseline.json`-ର baseline ଅତିକ୍ରମ କରେ ନାହିଁ | ହଁ | +| `check:complexity` | ଫାଇଲ୍-ସ୍ତରୀୟ cyclomatic complexity ସର୍ବାଧିକ ସୀମା ଅତିକ୍ରମ କରେ ନାହିଁ (ମୂଳ ESLint `complexity` + `max-lines-per-function`) | ହଁ | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — ପୃଥକ ESLint pass; CI ଉଭୟକୁ ଏକକ `check:complexity-ratchets` ପଦକ୍ଷେପ ଭାବେ ମିଶ୍ରିତ ଭାବରେ ଚଲାଏ | ହଁ | +| `check:dead-code` | ଅବ୍ୟବହୃତ exports / files ratchet (knip) baseline ତୁଳନାରେ ଅବନତି କରେ ନାହିଁ | ହଁ | +| `check:compression-budget` | Compression benchmark budget — ପ୍ରତି-engine token-savings-ର ନିମ୍ନସୀମାର ଅବନତି ହେବା ଉଚିତ୍ ନୁହେଁ | ହଁ | +| `check:type-coverage` | ଶତକଡ଼ା-typed ratchet (`type-coverage`) ଅବନତି କରେ ନାହିଁ; ବହୁମାତ୍ରାରେ `typecheck:noimplicit:core`-କୁ ଅନ୍ତର୍ଭୁକ୍ତ କରେ | ହଁ | +| `check:codeql-ratchet` | ଖୋଲା CodeQL alert ସଂଖ୍ୟାର ଅବନତି ହୁଏ ନାହିଁ (`gh api` ମାଧ୍ୟମରେ ପଢ଼େ; token ବିନା ସୁରକ୍ଷିତ ଭାବେ ଏଡ଼ାଇଯାଏ) — refresh cadence ଏବଂ manual trigger: ନିମ୍ନରେ "CodeQL ratchet" ଦେଖନ୍ତୁ | ହଁ | + +### କାର୍ଯ୍ୟ: `quality-extended` + +ସମ୍ପୂର୍ଣ୍ଣ କାର୍ଯ୍ୟଟି ପରାମର୍ଶମୂଳକ (`continue-on-error: true`)। npm-ଆଧାରିତ ratchet-ଗୁଡ଼ିକ +ପ୍ରକୃତରେ ଚାଲେ; ବାହ୍ୟ scanner-ଗୁଡ଼ିକ `gh release download` ମାଧ୍ୟମରେ install ହୁଅନ୍ତି ଏବଂ +binary ତଥାପି ଅନୁପସ୍ଥିତ ଥିଲେ ସ୍ୱୟଂ-ଏଡ଼ାଇଯାଆନ୍ତି (exit 0)। + +| ସ୍କ୍ରିପ୍ଟ | ଯାଞ୍ଚ କରେ | ଅବରୋଧକ | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `check:circular-deps` | କୌଣସି circular dependency ନାହିଁ (dpdm) | **ପରାମର୍ଶମୂଳକ** | +| `check:bundle-size` | Bundle size ସର୍ବାଧିକ ସୀମା ଅତିକ୍ରମ କରେ ନାହିଁ | **ପରାମର୍ଶମୂଳକ** | +| `check:secrets` | Secret scanning (gitleaks) — binary ଅନୁପସ୍ଥିତ ଥିଲେ ଏଡ଼ାଇଯାଏ | **ପରାମର୍ଶମୂଳକ** | +| `check:vuln-ratchet` | Dependency vulnerability-ଗୁଡ଼ିକର (osv-scanner) ଅବନତି ହୁଏ ନାହିଁ — binary ଅନୁପସ୍ଥିତ ଥିଲେ ଏଡ଼ାଇଯାଏ | **ପରାମର୍ଶମୂଳକ** | +| `check:workflows` | Workflow lint (actionlint + zizmor); scanner ଅନୁପସ୍ଥିତ/ତ୍ରୁଟିପୂର୍ଣ୍ଣ ହେଲେ, report ଅବୈଧ ହେଲେ କିମ୍ବା ratchet baseline ଅନୁପସ୍ଥିତ ଥିଲେ INCOMPLETE ଭାବେ ବିଫଳ ହୁଏ। ବୈଧ finding-ଗୁଡ଼ିକ ଚୟନିତ strict/advisory/ratchet policy ଅନୁସରଣ କରେ | Execution ଆବଶ୍ୟକ; CI-ରେ zizmor ratchet ଅବରୋଧକ | +| `check:openapi-breaking` | ସାର୍ବଜନୀନ API contract (`openapi.yaml`)-ରେ base branch ତୁଳନାରେ breaking change (oasdiff) — `openapiBreaking=N` ନିର୍ଗତ କରେ; oasdiff ଅନୁପସ୍ଥିତ ହେଲେ କିମ୍ବା base spec resolve ହୋଇନପାରିଲେ ଏଡ଼ାଇଯାଏ | **ପରାମର୍ଶମୂଳକ** | + +### କାର୍ଯ୍ୟ: `docs-sync-strict` + +`main`-କୁ ଯାଉଥିବା ପ୍ରତ୍ୟେକ PR-ରେ ଚାଲେ। ବିଫଳ ହେଲେ merge-କୁ ଅବରୋଧ କରେ। + +| ସ୍କ୍ରିପ୍ଟ | ଯାହାକୁ ବୈଧ କରେ | ଅବରୋଧକ | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `check:docs-all` | ନିମ୍ନରେ ଥିବା 6ଟି ଉପ-ଗେଟ୍କୁ କ୍ରମାନୁସାରେ ଚଲାଉଥିବା ମେଟା-ଗେଟ୍ | ହଁ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ସଂସ୍କରଣ ସାମଞ୍ଜସ୍ୟ | ହଁ | +| ↳ `check:docs-counts` | ଗଦ୍ୟରେ ଥିବା ଗଣନାଗୁଡ଼ିକ (ପ୍ରଦାତା ସଂଖ୍ୟା, ମାଇଗ୍ରେସନ୍ ସଂଖ୍ୟା ଇତ୍ୟାଦି) ବାସ୍ତବ ଗଣନାର ରାଚେଟ୍ ୱିଣ୍ଡୋ ମଧ୍ୟରେ ଅଛି କି ନାହିଁ | ହଁ | +| ↳ `check:env-doc-sync` | `.env.example`ର ପ୍ରତ୍ୟେକ env var ଏକ ଡକ୍ସ ଟେବୁଲ୍ରେ ଦଲିଲଭୁକ୍ତ ହୋଇଛି କି ନାହିଁ, ଏବଂ ଏହାର ବିପରୀତଟି ମଧ୍ୟ | ହଁ | +| ↳ `check:deprecated-versions` | ଡକ୍ସରେ କୌଣସି ଅପ୍ରଚଳିତ ସଂସ୍କରଣ ଷ୍ଟ୍ରିଙ୍ଗ୍ ନାହିଁ କି ନାହିଁ | ହଁ | +| ↳ `check:doc-links` | ଡକ୍ସର ଆଭ୍ୟନ୍ତରୀଣ markdown ଲିଙ୍କ୍ଗୁଡ଼ିକ ବାସ୍ତବ ଫାଇଲ୍କୁ ରିଜଲ୍ଭ ହୁଏ କି ନାହିଁ (`[text]`/`(path)` ଫର୍ମ) | ହଁ | +| ↳ `check:fabricated-docs` | ଡକ୍ସରେ ଉଲ୍ଲେଖିତ ରୁଟ୍, env var, CLI କମାଣ୍ଡ୍, ହୁକ୍ ନାମ ଏବଂ ଫାଇଲ୍ ପଥ କୋଡ୍ବେସ୍ରେ ଅଛି କି ନାହିଁ। `--strict` ମାଧ୍ୟମରେ ହାର୍ଡ ଗେଟ୍; ଫ୍ଲାଗ୍ ବିନା ସଫ୍ଟ-ଫେଲ୍। | ହଁ (CIରେ `--strict` ମାଧ୍ୟମରେ) | +| `check:cli-i18n` | CLI କମାଣ୍ଡ୍ ଷ୍ଟ୍ରିଙ୍ଗ୍ଗୁଡ଼ିକ ସମସ୍ତ i18n ଲୋକେଲ୍ ଫାଇଲ୍ରେ ଅଛି କି ନାହିଁ | ହଁ | +| `check:openapi-coverage` | OpenAPI ସ୍ପେକ୍ ବାସ୍ତବ ରୁଟ୍ଗୁଡ଼ିକର ଅତିକମରେ ଏକ ରାଚେଟ୍ କରାଯାଇଥିବା ନ୍ୟୂନତମ ସୀମାକୁ ଆବୃତ କରେ କି ନାହିଁ | ହଁ | +| `check:openapi-security-tiers` | `openapi.yaml`ର ସୁରକ୍ଷା ସ୍ତର ଆନୋଟେସନ୍ଗୁଡ଼ିକ `routeGuard.ts`ର ବର୍ଗୀକରଣ ସହ ସାମଞ୍ଜସ୍ୟପୂର୍ଣ୍ଣ କି ନାହିଁ | **ପରାମର୍ଶମୂଳକ** | +| `check:openapi-routes` | `openapi.yaml`ର ପ୍ରତ୍ୟେକ ପଥ ବାସ୍ତବ `route.ts`କୁ ରିଜଲ୍ଭ ହୁଏ କି ନାହିଁ (କଳ୍ପିତ ତଥ୍ୟ-ବିରୋଧୀ) | ହଁ | +| `check:docs-symbols` | `docs/**/*.md`ର ପ୍ରତ୍ୟେକ `/api/...` ରେଫରେନ୍ସ ବାସ୍ତବ `route.ts`କୁ ରିଜଲ୍ଭ ହୁଏ କି ନାହିଁ (କଳ୍ପିତ ତଥ୍ୟ-ବିରୋଧୀ) | ହଁ | +| `i18n translation drift` | i18n ଲୋକେଲ୍ ଫାଇଲ୍ଗୁଡ଼ିକରେ ଅନୁବାଦ ହୋଇନଥିବା କୀ — କେବଳ ଚେତାବନୀ | **ପରାମର୍ଶମୂଳକ** | + +### ଜବ୍: `i18n-ui-coverage` + +| ସ୍କ୍ରିପ୍ଟ | ଯାହାକୁ ବୈଧ କରେ | ଅବରୋଧକ | +| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (ଇନ୍ଲାଇନ୍) | UI i18n କୀ କଭରେଜ୍ ≥ 65% କି ନାହିଁ | ହଁ | +| `check-ui-value-drift` (ଇନ୍ଲାଇନ୍) | ପୁନଃଲିଖିତ ଇଂରାଜୀ **ମୂଲ୍ୟ** ପଛରେ କୌଣସି ପୁରୁଣା ଅନୁବାଦ ଛାଡ଼େ ନାହିଁ କି ନାହିଁ | ହଁ | +| `check-new-key-coverage` (ଇନ୍ଲାଇନ୍) | ଏକ **ନୂଆ** ଇଂରାଜୀ କୀ ପ୍ରତ୍ୟେକ ଲୋକେଲ୍ରେ ଅନୁବାଦିତ ହୋଇଛି କି ନାହିଁ — ଏକ `__MISSING__:` ମାର୍କର୍ ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଯାଏ | ହଁ | +| `check-translation-ratio` | ପ୍ରତ୍ୟେକ ଲୋକେଲ୍ ପାଇଁ ବାସ୍ତବ-ଅନୁବାଦ ଅନୁପାତ (ଅନୁମୋଦିତ ତାଲିକା ବାହାରେ ଇଂରାଜୀ ସହ ସମାନ / ପ୍ଲେସ୍ହୋଲ୍ଡର୍ / ଅନୁପସ୍ଥିତ ଲିଫ୍) `config/quality/i18n-translation-baseline.json` + ଅତିରିକ୍ତ ସୀମାକୁ ଅତିକ୍ରମ କରିବା ଉଚିତ୍ ନୁହେଁ | **ପରାମର୍ଶମୂଳକ** | + +`fetch-depth: 0` ଆବଶ୍ୟକ — value-drift ଗେଟ୍ ମର୍ଜ୍ ବେସ୍ ସହିତ `en.json`ର ପାର୍ଥକ୍ୟ ଯାଞ୍ଚ କରେ। + +#### `check-ui-value-drift` — ପୁରୁଣା-ଅନୁବାଦ ଗେଟ୍ + +ଏହା ସେହି ଏକମାତ୍ର i18n ରିଗ୍ରେସନ୍କୁ ଧରେ ଯାହାକୁ ଅନ୍ୟ ଗେଟ୍ଗୁଡ଼ିକ ଗଠନାତ୍ମକ ଭାବେ ଦେଖିପାରନ୍ତି ନାହିଁ: ଏକ ଇଂରାଜୀ ମୂଲ୍ୟ +ପୁନଃଲିଖିତ ହୁଏ ଏବଂ _ପୂର୍ବବର୍ତ୍ତୀ_ ଇଂରାଜୀରୁ ତିଆରି ହୋଇଥିବା ଅନୁବାଦଗୁଡ଼ିକ ପଛରେ ରହିଯାଏ, ଫଳରେ +ଅଣ-ଇଂରାଜୀ ବ୍ୟବହାରକାରୀମାନେ ଆତ୍ମବିଶ୍ୱାସପୂର୍ଣ୍ଣ ଶୈଳୀରେ ଲିଖିତ, କିନ୍ତୁ ବର୍ତ୍ତମାନ ଭୁଲ୍ ଥିବା ପାଠ୍ୟ ପଢ଼ିଚାଲନ୍ତି। + +ଏହା ପ୍ରକୃତରେ ରିଲିଜ୍ ହୋଇଥିଲା। Antigravity +ଲଗଇନ୍ ହେଲ୍ପର୍ ଆସିବାବେଳେ (#5203) `oauthModal.googleOAuthWarning` ପୁନଃଲିଖିତ ହୋଇଥିଲା; **43ଟି ଲୋକେଲ୍ରୁ 39ଟିରେ** ଅପରେଟର୍ମାନଙ୍କୁ "ସମ୍ପୂର୍ଣ୍ଣ URL କପି କରି ତଳେ ପେଷ୍ଟ କରନ୍ତୁ" ବୋଲି କହୁଥିବା ପାଠ୍ୟ ରହିଯାଇଥିଲା — ଏକ ଏପରି ପ୍ରବାହ ଯାହା ସେହି ପ୍ରଦାତା ପାଇଁ ସମ୍ପୂର୍ଣ୍ଣ ହୋଇପାରେ ନାହିଁ। ଏହି କାରଣଗୁଡ଼ିକ ଯୋଗୁଁ #8463 ପର୍ଯ୍ୟନ୍ତ ଏହା ଧରାପଡ଼ିନଥିଲା: + +- `sync-ui-keys` କେବଳ **ଅନୁପସ୍ଥିତ** କୀଗୁଡ଼ିକୁ ବ୍ୟାକ୍ଫିଲ୍ କରେ, **ପୁରୁଣା** କୀଗୁଡ଼ିକୁ କେବେ ନୁହେଁ; +- `check-ui-keys-coverage` କୀର _ଉପସ୍ଥିତି_ ଗଣନା କରେ, ତେଣୁ ଏକ ପୁରୁଣା ଅନୁବାଦ କଭର୍ ହୋଇଥିବା ଭାବେ ସ୍କୋର୍ କରେ; +- `check-translation-drift` `docs/i18n//**.md` ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ମିରର୍ଗୁଡ଼ିକୁ ଟ୍ରାକ୍ କରେ — + ଏହା କେବେବି `src/i18n/messages/*.json` ପଢ଼େ ନାହିଁ। 2026-09 ପୁନଃ-ସିଙ୍କ୍ ପରଠାରୁ ଜବ୍ `docs-sync-strict`ରେ ଅବରୋଧକ: ଏକ ମୁଖ୍ୟ ଡକ୍ ସମ୍ପାଦନା କରନ୍ତୁ → `npm run i18n:run -- --files=` (ବିଭାଗ-ସ୍ତରୀୟ, କମ୍ ଖର୍ଚ୍ଚସାଧ୍ୟ)। + +**ଡିଫ୍-ସଚେତନ, ବେସ୍ଲାଇନ୍-ସମର୍ଥିତ ନୁହେଁ।** ଏହା ମର୍ଜ୍ ବେସ୍ରେ ଥିବା `en.json`କୁ +ୱର୍କିଂ ଟ୍ରି ସହିତ ତୁଳନା କରେ; ଯେଉଁ ପ୍ରତ୍ୟେକ କୀର ଇଂରାଜୀ ମୂଲ୍ୟ ପରିବର୍ତ୍ତିତ ହୋଇଛି, ସେଥିପାଇଁ ଏବେ ମଧ୍ୟ +ଅପରିବର୍ତ୍ତିତ ଅନୁବାଦ ଧାରଣ କରିଥିବା ଯେକୌଣସି ଲୋକେଲ୍ ପୁରୁଣା ହୋଇଯାଇଛି। ଏହା ଉଦ୍ଦେଶ୍ୟମୂଳକ ଭାବେ **ପୂର୍ବରୁ ଥିବା ଋଣକୁ ସ୍ଥିର ରଖେ** — ଦୀର୍ଘ ସମୟ ଧରି ଥିବା ଏକ ଅନୁବାଦ କେଉଁ ପୁରୁଣା ଇଂରାଜୀରୁ ଆସିଥିଲା, ତାହା ଏକ ଡିଫ୍ +ପ୍ରକାଶ କରିପାରିବ ନାହିଁ, ତେଣୁ ଗେଟ୍ କେବଳ ବର୍ତ୍ତମାନର ପରିବର୍ତ୍ତନ ଯାହାକୁ ସ୍ପର୍ଶ କରେ ତାହାକୁ ବିଚାର କରେ। +ବିକଳ୍ପଟି (ପ୍ରତି-କୀ ହ୍ୟାଶ୍ ବେସ୍ଲାଇନ୍) ପାଇଁ ପ୍ରାୟ 600 KBର ଏକ ଜେନେରେଟ୍ ହୋଇଥିବା ଫାଇଲ୍ ଆବଶ୍ୟକ ହେବ, +ଯାହା ସବୁଠାରୁ ବଡ଼ ବର୍ତ୍ତମାନର ବେସ୍ଲାଇନ୍ର 3×, ଏବଂ ପ୍ରତ୍ୟେକ i18n PRରେ ପରିବର୍ତ୍ତିତ ହେବ। ଏହାକୁ ସନ୍ତୁଷ୍ଟ କରିବାର ଦୁଇଟି ଉପାୟ: -1. ପ୍ରଭାବିତ translationଗୁଡ଼ିକୁ update କରନ୍ତୁ, କିମ୍ବା -2. ସେଗୁଡ଼ିକୁ `__MISSING__:` ଭାବେ set କରନ୍ତୁ — ତା’ପରେ runtime ସଂଶୋଧିତ ଇଂରାଜୀ ପରିବେଷଣ କରେ - (`src/i18n/request.ts::deepMergeFallback`, #7258) ଏବଂ keyଟି translation ପାଇଁ queueରେ ଯୋଡ଼ାଯାଏ। +1. ପ୍ରଭାବିତ ଅନୁବାଦଗୁଡ଼ିକୁ ଅପଡେଟ୍ କରନ୍ତୁ, କିମ୍ବା +2. ସେଗୁଡ଼ିକୁ `__MISSING__:` ଭାବେ ସେଟ୍ କରନ୍ତୁ — ତାହାପରେ ରନ୍ଟାଇମ୍ ସଂଶୋଧିତ ଇଂରାଜୀ ପ୍ରଦାନ କରେ + (`src/i18n/request.ts::deepMergeFallback`, #7258) ଏବଂ କୀଟି ଅନୁବାଦ ପାଇଁ ଧାଡ଼ିରେ ଯୋଡ଼ାଯାଏ। -ଯଦି stringଟିର **ଅର୍ଥ** ପରିବର୍ତ୍ତିତ ହୋଇଛି, ତେବେ **keyଟିକୁ rename କରିବାକୁ** ପ୍ରାଧାନ୍ୟ ଦିଅନ୍ତୁ: ଏକ ନୂଆ key ପୁରୁଣା translation ଉତ୍ତରାଧିକାରରେ ପାଇପାରିବ ନାହିଁ। #8463ରେ ଏହି pattern ବ୍ୟବହୃତ ହୋଇଥିଲା। +ଯଦି ଷ୍ଟ୍ରିଙ୍ଗ୍ର **ଅର୍ଥ** ପରିବର୍ତ୍ତିତ ହୋଇଛି, ତେବେ **କୀର ନାମ ପରିବର୍ତ୍ତନ କରିବାକୁ** ପ୍ରାଧାନ୍ୟ ଦିଅନ୍ତୁ: ଏକ ନୂଆ କୀ +ପୁରୁଣା ଅନୁବାଦ ଉତ୍ତରାଧିକାରରେ ପାଇପାରିବ ନାହିଁ। #8463ରେ ଏହି ପ୍ୟାଟର୍ନ ବ୍ୟବହାର କରାଯାଇଥିଲା। ```bash npm run i18n:check-value-drift # କଠୋର (CI ଯାହା ଚଲାଏ) -npm run i18n:check-value-drift:warn # କେବଳ report +npm run i18n:check-value-drift:warn # କେବଳ ରିପୋର୍ଟ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -base catalog ପଢ଼ାଯାଇ ନପାରିଲେ (base ref ବିନା shallow clone), `check-openapi-breaking`କୁ ଅନୁସରଣ କରି `SKIP reason=base-unresolved` ସହିତ 0ରେ exit କରେ। +ବେସ୍ କ୍ୟାଟାଲଗ୍ ପଢ଼ାଯାଇ ପାରିନଥିଲେ (ବେସ୍ ref ବିନା ଶ୍ୟାଲୋ +କ୍ଲୋନ୍), `check-openapi-breaking`କୁ ଅନୁସରଣ କରି, `SKIP reason=base-unresolved` ସହିତ 0ରେ ପ୍ରସ୍ଥାନ କରେ। -### Job: `i18n` +### ଜବ୍: `i18n` -ସମ୍ପୂର୍ଣ୍ଣ i18n validation matrix (ପ୍ରତ୍ୟେକ locale ପାଇଁ ଗୋଟିଏ job)। ସମଗ୍ର jobଟି ପରାମର୍ଶମୂଳକ। +ସମ୍ପୂର୍ଣ୍ଣ i18n ବୈଧତା ଯାଞ୍ଚ ମ୍ୟାଟ୍ରିକ୍ସ (ପ୍ରତ୍ୟେକ ଲୋକେଲ୍ ପାଇଁ ଗୋଟିଏ ଜବ୍)। ସମଗ୍ର ଜବ୍ଟି ପରାମର୍ଶମୂଳକ। -| Script | କ’ଣ validate କରେ | ବାଧ୍ୟକାରୀ | +| ସ୍କ୍ରିପ୍ଟ | ଯାହାକୁ ବୈଧ କରେ | ବ୍ଲକିଂ | | ------------------------------- | ----------------------------------------- | ------------------------------------------------------- | -| `validate_translation.py quick` | ପ୍ରତ୍ୟେକ localeର translation ସମ୍ପୂର୍ଣ୍ଣତା | **ପରାମର୍ଶମୂଳକ** (ସମଗ୍ର jobରେ `continue-on-error: true`) | +| `validate_translation.py quick` | ପ୍ରତ୍ୟେକ ଲୋକେଲ୍ ପାଇଁ ଅନୁବାଦର ସମ୍ପୂର୍ଣ୍ଣତା | **ପରାମର୍ଶମୂଳକ** (ସମଗ୍ର ଜବ୍ରେ `continue-on-error: true`) | -### Job: `pr-test-policy` +### ଜବ୍: `pr-test-policy` -କେବଳ pull requestଗୁଡ଼ିକରେ ଚାଲେ। +କେବଳ ପୁଲ୍ ରିକ୍ୱେଷ୍ଟଗୁଡ଼ିକରେ ଚାଲେ। -| Script | କ’ଣ validate କରେ | ବାଧ୍ୟକାରୀ | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, କିମ୍ବା `bin/`ର production code ପରିବର୍ତ୍ତନ କରୁଥିବା PRଗୁଡ଼ିକ test ଅନ୍ତର୍ଭୁକ୍ତ କିମ୍ବା update କରିବା ଆବଶ୍ୟକ (କଠୋର ନିୟମ #8) | ହଁ | -| `check:test-masking` | ପରିବର୍ତ୍ତିତ test fileଗୁଡ଼ିକ ମୋଟ assert ସଂଖ୍ୟା କମାନ୍ତି ନାହିଁ କିମ୍ବା `assert.ok(true)` tautology ଯୋଡ଼ନ୍ତି ନାହିଁ | ହଁ | -| `check:pr-evidence` | PR bodyରେ ପରିବର୍ତ୍ତନ ପାଇଁ test/VPS ପ୍ରମାଣ ଉଲ୍ଲେଖ ହୋଇଛି (PR ଗଦ୍ୟକୁ grep କରି କଠୋର ନିୟମ #18କୁ ସ୍ୱୟଂଚାଳିତ କରେ — ଭଙ୍ଗୁର, Backlog ଦେଖନ୍ତୁ) | ହଁ | +| ସ୍କ୍ରିପ୍ଟ | ଯାହାକୁ ବୈଧ କରେ | ବ୍ଲକିଂ | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, କିମ୍ବା `bin/`ରେ ପ୍ରଡକ୍ସନ୍ କୋଡ୍ ପରିବର୍ତ୍ତନ କରୁଥିବା PRଗୁଡ଼ିକ ନିଶ୍ଚିତ ଭାବେ ଟେଷ୍ଟ ସାମିଲ କିମ୍ବା ଅପଡେଟ୍ କରିବା ଆବଶ୍ୟକ (କଠୋର ନିୟମ #8) | ହଁ | +| `check:test-masking` | ପରିବର୍ତ୍ତିତ ଟେଷ୍ଟ ଫାଇଲ୍ଗୁଡ଼ିକ ସମୁଦାୟ ଆସର୍ଟ ଗଣନା କମାନ୍ତି ନାହିଁ କିମ୍ବା `assert.ok(true)` ଟଟୋଲୋଜି ଯୋଡ଼ନ୍ତି ନାହିଁ | ହଁ | +| `check:pr-evidence` | PR ବଡିରେ ପରିବର୍ତ୍ତନ ପାଇଁ ଟେଷ୍ଟ/VPS ପ୍ରମାଣ ଉଲ୍ଲେଖ ଅଛି (PR ଗଦ୍ୟକୁ grep କରି କଠୋର ନିୟମ #18କୁ ସ୍ୱୟଂଚାଳିତ କରେ — ଭଙ୍ଗୁର, Backlog ଦେଖନ୍ତୁ) | ହଁ | -### Job: `test-vitest` +### ଜବ୍: `test-vitest` -`build` ପରେ ଚାଲେ। ବିଫଳ ହେଲେ mergeକୁ ଅବରୋଧ କରେ। +`build` ପରେ ଚାଲେ। ବିଫଳ ହେଲେ ମର୍ଜ୍କୁ ଅବରୋଧ କରେ। -| Suite | କ’ଣ validate କରେ | ବାଧ୍ୟକାରୀ | -| ---------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110ଟି tool), autoCombo, cache — vitest runner | ହଁ | -| `test:vitest:ui` | UI component test — vitest runner | **ବାଧ୍ୟକାରୀ** — ପୂର୍ବରୁ ଥିବା failureଗୁଡ଼ିକୁ `vitest.config.ts`ରେ ସ୍ପଷ୍ଟ ଭାବେ ବାଦ ଦିଆଯାଇଛି; ନୂଆ failure jobଟିକୁ ବିଫଳ କରେ | +| ସୁଇଟ୍ | ଯାହାକୁ ବୈଧ କରେ | ବ୍ଲକିଂ | +| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP ସର୍ଭର୍ (110ଟି ଟୁଲ୍), autoCombo, କ୍ୟାଶ୍ — vitest ରନର୍ | ହଁ | +| `test:vitest:ui` | UI କମ୍ପୋନେଣ୍ଟ ଟେଷ୍ଟ — vitest ରନର୍ | **ବ୍ଲକିଂ** — ପୂର୍ବରୁ ଥିବା ବିଫଳତାଗୁଡ଼ିକୁ `vitest.config.ts`ରେ ସ୍ପଷ୍ଟ ଭାବେ ବାଦ ଦିଆଯାଇଛି; ନୂଆ ବିଫଳତା ଜବ୍କୁ ବିଫଳ କରେ | -### ରାତ୍ରିକାଳୀନ workflow (ନିର୍ଦ୍ଧାରିତ, ପରାମର୍ଶମୂଳକ) +### ରାତ୍ରିକାଳୀନ ୱର୍କଫ୍ଲୋଗୁଡ଼ିକ (ନିର୍ଦ୍ଧାରିତ, ପରାମର୍ଶମୂଳକ) -ଏଗୁଡ଼ିକ cron scheduleରେ (ଏବଂ `workflow_dispatch`ରେ) ଚାଲେ, PRରେ କେବେ ମଧ୍ୟ ନୁହେଁ। ସମସ୍ତେ ପରାମର୍ଶମୂଳକ। +ଏଗୁଡ଼ିକ ଏକ cron ସୂଚୀରେ (ଏବଂ `workflow_dispatch`ରେ) ଚାଲେ, PRଗୁଡ଼ିକରେ କେବେ ମଧ୍ୟ ନୁହେଁ। ସମସ୍ତେ ପରାମର୍ଶମୂଳକ। -| Workflow | କ’ଣ validate କରେ | ବାଧ୍ୟକାରୀ | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | random seed + ଉଚ୍ଚ run count ସହିତ fast-check property test | **ପରାମର୍ଶମୂଳକ** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **ପରାମର୍ଶମୂଳକ** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probe (provider secret ବିନା skip କରାଯାଏ) | **ପରାମର୍ଶମୂଳକ** | -| `nightly-schemathesis` | `docs/openapi.yaml` ବ୍ୟବହାର କରି ଏକ live OmniRoute ବିରୁଦ୍ଧରେ OpenAPI contract fuzzing (schemathesis) — spec ଉଲ୍ଲଂଘନ / unhandled 500କୁ ପ୍ରକାଶ କରେ (ପର୍ଯ୍ୟାୟ 8 B.4) | **ପରାମର୍ଶମୂଳକ** | -| `nightly-mutation` | fast unit lane ଉପରେ Stryker mutation-testing score — ବଞ୍ଚିରହିଥିବା mutantଗୁଡ଼ିକ ଦୁର୍ବଳ assertକୁ ପ୍ରକାଶ କରନ୍ତି | **ପରାମର୍ଶମୂଳକ** | -| `nightly-compat` | ସମର୍ଥିତ `engines.node` rangeଗୁଡ଼ିକରେ Node engine compatibility matrix | **ପରାମର୍ଶମୂଳକ** | +| ୱର୍କଫ୍ଲୋ | ଯାହାକୁ ବୈଧ କରେ | ବ୍ଲକିଂ | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `nightly-property` | ଏକ ଯାଦୃଚ୍ଛିକ ସିଡ୍ + ଅଧିକ ରନ୍ ଗଣନା ସହିତ fast-check ପ୍ରୋପର୍ଟି ଟେଷ୍ଟ | **ପରାମର୍ଶମୂଳକ** | +| `nightly-resilience` | ହିପ୍-ବୃଦ୍ଧି ଗେଟ୍, କ୍ୟାଓସ୍ ଫଲ୍ଟ-ଇଞ୍ଜେକ୍ସନ୍, k6 ଲୋଡ୍/ସୋକ୍ | **ପରାମର୍ଶମୂଳକ** | +| `nightly-llm-security` | promptfoo ଇଞ୍ଜେକ୍ସନ୍ ଗାର୍ଡ୍ (ବ୍ଲକ୍ ମୋଡ୍) + garak ପ୍ରୋବ୍ଗୁଡ଼ିକ (ପ୍ରଦାତା ସିକ୍ରେଟ୍ ବିନା ଏଡ଼ାଇ ଦିଆଯାଏ) | **ପରାମର୍ଶମୂଳକ** | +| `nightly-schemathesis` | `docs/openapi.yaml` ବ୍ୟବହାର କରି ଏକ ସକ୍ରିୟ OmniRoute ବିରୁଦ୍ଧରେ OpenAPI କଣ୍ଟ୍ରାକ୍ଟ ଫଜିଂ (schemathesis) — ସ୍ପେକ୍ ଉଲ୍ଲଂଘନ / ଅଣନିୟନ୍ତ୍ରିତ 500ଗୁଡ଼ିକୁ ପ୍ରକାଶ କରେ (Fase 8 B.4) | **ପରାମର୍ଶମୂଳକ** | +| `nightly-mutation` | ଦ୍ରୁତ ୟୁନିଟ୍ ଲେନ୍ରେ Stryker ମ୍ୟୁଟେସନ୍-ଟେଷ୍ଟିଂ ସ୍କୋର୍ — ବଞ୍ଚି ରହିଥିବା ମ୍ୟୁଟାଣ୍ଟଗୁଡ଼ିକ ଦୁର୍ବଳ ଆସର୍ଟଗୁଡ଼ିକୁ ପ୍ରକାଶ କରେ | **ପରାମର୍ଶମୂଳକ** | +| `nightly-compat` | ସମର୍ଥିତ `engines.node` ରେଞ୍ଜଗୁଡ଼ିକରେ Node ଇଞ୍ଜିନ୍ ସୁସଙ୍ଗତତା ମ୍ୟାଟ୍ରିକ୍ସ | **ପରାମର୍ଶମୂଳକ** | --- @@ -523,41 +529,41 @@ CI ଗେଟ୍ଗୁଡ଼ିକ ବ୍ୟତୀତ, OmniRoute ଏକ **ଇଚ ## ଯୁକ୍ତିସଙ୍ଗତକରଣ ବ୍ୟାକଲଗ୍ (ROI ସମୀକ୍ଷା — ପର୍ଯ୍ୟାୟ 9 ତରଙ୍ଗ 3) -ଏହି ଇନଭେଣ୍ଟରିକୁ 2026-06-17 ରେ `ci.yml` ସହିତ ମେଳ କରାଯାଇଥିଲା (ପୂର୍ବ ସଂସ୍କରଣରେ +ଏହି ଇନ୍ଭେଣ୍ଟରୀକୁ 2026-06-17 ରେ `ci.yml` ସହିତ ମେଳ କରାଯାଇଥିଲା (ପୂର୍ବ ସଂସ୍କରଣରେ `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence` ବାଦ ପଡ଼ିଥିଲା)। ମେଳ କରାଯାଇଥିବା ସେଟ୍ର ଏକ ROI ସମୀକ୍ଷା ନିମ୍ନଲିଖିତ ଯୁକ୍ତିସଙ୍ଗତକରଣ ପ୍ରାର୍ଥୀଗୁଡ଼ିକୁ ଚିହ୍ନଟ କରିଛି। **ମର୍ଜଗୁଡ଼ିକ ଯାନ୍ତ୍ରିକ CI -ପରିବର୍ତ୍ତନ; ଫ୍ଲିପ୍/ଡ୍ରପ୍ଗୁଡ଼ିକ ଅପରେଟରଙ୍କ ପାଇଁ ସଂରକ୍ଷିତ ନୀତିଗତ ନିଷ୍ପତ୍ତି।** ନିମ୍ନରେ ଥିବା କିଛି ମଧ୍ୟ +ପରିବର୍ତ୍ତନ; ଫ୍ଲିପ୍/ବାଦ ଦେବା ହେଉଛି ଅପରେଟରଙ୍କ ପାଇଁ ସଂରକ୍ଷିତ ନୀତିଗତ ନିଷ୍ପତ୍ତି।** ନିମ୍ନରେ ଥିବା କୌଣସି ବିଷୟ ଏପର୍ଯ୍ୟନ୍ତ ପ୍ରୟୋଗ କରାଯାଇନାହିଁ। -**ଉପରେ ଏହା ମଧ୍ୟ ଦସ୍ତାବିଜଭୁକ୍ତ ହୋଇନାହିଁ** (ପରାମର୍ଶମୂଳକ, ଦୁର୍ବଳ ସଙ୍କେତ): `docs-lint` ଜବ୍ +**ଉପରେ ଆହୁରି ଅଲିଖିତ ଥିବା ବିଷୟ** (ପରାମର୍ଶମୂଳକ, ନିମ୍ନ ସଙ୍କେତ): `docs-lint` ଜବ୍ (markdownlint + Vale, ସମଗ୍ର ଜବ୍ରେ `continue-on-error`) ଏବଂ ସ୍ୱତନ୍ତ୍ର ସ୍କାନର୍ ୱର୍କଫ୍ଲୋଗୁଡ଼ିକ `semgrep.yml` / `codeql.yml` / `scorecard.yml`। `semgrepFindings: 0` -`quality-baseline.json` ଭିତରେ ଅଛି, କିନ୍ତୁ `ci.yml` ରେ ଏହାକୁ କୌଣସି ବ୍ଲକିଂ ରାଚେଟ୍ ସହ ଯୋଡ଼ାଯାଇନାହିଁ — ମେଟ୍ରିକ୍ଟି +`quality-baseline.json` ରେ ଅଛି, କିନ୍ତୁ `ci.yml` ରେ ଏହାକୁ କୌଣସି ବ୍ଲକିଂ ରାଚେଟ୍ ସହିତ ସଂଯୋଗ କରାଯାଇନାହିଁ — ମେଟ୍ରିକ୍ଟି ବର୍ତ୍ତମାନ ଅନାଥ ଅବସ୍ଥାରେ ଅଛି। -### ମର୍ଜ୍ / ଡିଡୁପ୍ଲିକେସନ୍ (ଯାନ୍ତ୍ରିକ, କମ୍ ବିପଦ) +### ମର୍ଜ / ଡିଡ୍ୟୁପ୍ (ଯାନ୍ତ୍ରିକ, କମ୍ ବିପଦ) -ପ୍ରତ୍ୟେକ ପ୍ରାର୍ଥୀକୁ 2026-06-17 ର ଲାଇଭ୍ ଗେଟ୍ ସ୍ଥିତି ସହିତ ଯାଞ୍ଚ କରାଯାଇଥିଲା (ବିଶ୍ୱାସ କରନ୍ତୁ, କିନ୍ତୁ ଯାଞ୍ଚ ମଧ୍ୟ କରନ୍ତୁ); -ଅନେକ "ସ୍ପଷ୍ଟ" ମର୍ଜ୍ ପ୍ରକୃତରେ ଲୁକ୍କାୟିତ ଋଣ ଲୁଚାଇଥିବା ଜଣାପଡ଼ିଲା ଏବଂ ସେଗୁଡ଼ିକ **ସିଧାସଳଖ ପ୍ରତିସ୍ଥାପନଯୋଗ୍ୟ ନୁହେଁ**। +ପ୍ରତ୍ୟେକ ପ୍ରାର୍ଥୀକୁ 2026-06-17 ରେ ସକ୍ରିୟ ଗେଟ୍ ସ୍ଥିତି ସହିତ ଯାଞ୍ଚ କରାଯାଇଥିଲା (ବିଶ୍ୱାସ କରନ୍ତୁ, କିନ୍ତୁ ଯାଞ୍ଚ ମଧ୍ୟ କରନ୍ତୁ); +ଅନେକ "ସ୍ପଷ୍ଟ" ମର୍ଜ ଋଣ ଲୁଚାଇ ରଖିଥିବା ଜଣାପଡ଼ିଲା ଏବଂ ସେଗୁଡ଼ିକ **ସିଧାସଳଖ ପ୍ରତିସ୍ଥାପନଯୋଗ୍ୟ ନୁହେଁ**। -- **`check:docs-sync` ଦୁଇଥର ଚାଲେ** — `lint` ଜବ୍ରେ ସ୍ୱତନ୍ତ୍ର ଭାବରେ ଏବଂ ପୁନର୍ବାର `check:docs-all` (`docs-sync-strict`) ଓ husky pre-commit hook ଭିତରେ। ✅ **ସମ୍ପୂର୍ଣ୍ଣ** — ସ୍ୱତନ୍ତ୍ର `lint` ଆହ୍ୱାନ ଅପସାରିତ। -- **CVE ସ୍କାନିଂ** — ❌ **ଏହା ଏକ ସହଜ ମର୍ଜ୍ ନୁହେଁ।** `audit:deps` ଯେକୌଣସି high/critical CVE ରେ ହାର୍ଡ-ଫେଲ୍ କରେ; `check:vuln-ratchet` (osv) କେବଳ ବେସଲାଇନ୍ ତୁଳନାରେ ଏକ _ରିଗ୍ରେସନ୍_ ହେଲେ ବିଫଳ ହୁଏ (ବର୍ତ୍ତମାନ 1 MODERATE)। ଅର୍ଥବିଧି ଭିନ୍ନ — `audit:deps` ବାଦ ଦେଲେ ପରମ high/critical ଗେଟ୍ ହରାଇଯିବ। ଉଭୟକୁ ରଖନ୍ତୁ। -- **ସାଇକଲ୍ ଚିହ୍ନଟ** — ❌ **ଏହା ଏକ ସହଜ ମର୍ଜ୍ ନୁହେଁ।** `check:circular-deps` (dpdm) **91ଟି ସାଇକଲ୍** ରିପୋର୍ଟ କରେ (ସେଥିପାଇଁ ଏହା ପରାମର୍ଶମୂଳକ); ପ୍ରଥମେ ସେଗୁଡ଼ିକର ସମାଧାନ ନକରି ଏହାକୁ ବ୍ଲକିଂକୁ ଉନ୍ନୀତ କରାଯାଇପାରିବ ନାହିଁ, ଏବଂ ସବୁଜ, ସୁପରିଚାଳିତ `check:cycles` ତୁଳନାରେ ଏହାର ପରିସର ଅଧିକ ବ୍ୟାପକ। `check:cycles` କୁ ବ୍ଲକିଂ ଭାବେ ରଖନ୍ତୁ; 91ଟି dpdm ସାଇକଲ୍ର ସମାଧାନ ଏକ ପୃଥକ ବ୍ୟାକଲଗ୍। -- **ଜଟିଳତା** — ✅ **ସମ୍ପୂର୍ଣ୍ଣ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ଗୋଟିଏ ESLint ୱାକ୍, ruleId ଅନୁସାରେ ଗଣନା କରେ ଯାହାଦ୍ୱାରା cyclomatic+max-lines ଏବଂ cognitive ବେସଲାଇନ୍ଗୁଡ଼ିକ ସ୍ୱାଧୀନ ରହେ; ବ୍ୟକ୍ତିଗତ `check:complexity` / `check:cognitive-complexity` ସ୍ଥାନୀୟ `--update` ପାଇଁ ରହିଛି। -- **`/api` ଆଣ୍ଟି-ହାଲୁସିନେସନ୍** — ✅ **ସମ୍ପୂର୍ଣ୍ଣ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ର ଗୋଟିଏ FS ଇନଭେଣ୍ଟରି, openapi-routes + docs-symbols ଏବେ ମଧ୍ୟ ସ୍ୱାଧୀନ ଭାବେ ରିପୋର୍ଟ କରେ; ବ୍ୟକ୍ତିଗତଗୁଡ଼ିକ ସ୍ଥାନୀୟ ରନ୍ ପାଇଁ ରହିଛି। -- **`check:node-runtime` 11ଟି ଜବ୍ରେ ଚାଲେ** — ⚠️ **କମ୍ ROI।** ପ୍ରତ୍ୟେକଟି ଏକ ପୃଥକ ରନର୍ ଏବଂ ଯାଞ୍ଚଟି <1s; ମୋଟ ସଞ୍ଚୟ ~10s, କିନ୍ତୁ ଏହା ବଦଳରେ ଏକ ସସ୍ତା ପ୍ରତି-ଜବ୍ ସୁରକ୍ଷା ହରାଇବ। ପରିବର୍ତ୍ତନଜନିତ ଅସ୍ଥିରତା ପାଇଁ ଏହା ଯୋଗ୍ୟ ନୁହେଁ। -- **CI lint ରେ `typecheck:noimplicit:core`** — ✅ **lint ଜବ୍ରୁ ଅପସାରିତ** (ଏହା ପରାମର୍ଶମୂଳକ `continue-on-error` ଥିଲା); ବ୍ଲକିଂ ଟାଇପ୍ ସର୍ଫେସ୍ ହେଉଛି `typecheck:core` + `check:type-coverage`। ସ୍ଥାନୀୟ ସ୍କ୍ରିପ୍ଟ ରଖାଯାଇଛି। +- **`check:docs-sync` ଦୁଇଥର ଚାଲେ** — `lint` ଜବ୍ରେ ସ୍ୱତନ୍ତ୍ର ଭାବେ ଏବଂ ପୁଣି `check:docs-all` (`docs-sync-strict`) ଭିତରେ ଓ husky pre-commit hook ରେ। ✅ **ସମ୍ପୂର୍ଣ୍ଣ** — ସ୍ୱତନ୍ତ୍ର `lint` ଆହ୍ୱାନ ହଟାଯାଇଛି। +- **CVE ସ୍କାନିଂ** — ❌ **ଏକ ସ୍ୱଚ୍ଛ ମର୍ଜ ନୁହେଁ।** ଯେକୌଣସି high/critical CVE ଥିଲେ `audit:deps` ନିଶ୍ଚିତ ଭାବେ ବିଫଳ ହୁଏ; `check:vuln-ratchet` (osv) କେବଳ ବେସ୍ଲାଇନ୍ ତୁଳନାରେ ଏକ _ଅବନତି_ ହେଲେ ବିଫଳ ହୁଏ (ବର୍ତ୍ତମାନ 1 MODERATE)। ଅର୍ଥବିଜ୍ଞାନ ଭିନ୍ନ — `audit:deps` ବାଦ ଦେଲେ ସମ୍ପୂର୍ଣ୍ଣ high/critical ଗେଟ୍ ହରାଇଯିବ। ଉଭୟକୁ ରଖନ୍ତୁ। +- **ଚକ୍ର ଚିହ୍ନଟ** — ✅ **ସମ୍ପୂର୍ଣ୍ଣ** (#15159 G-01/G-02)। ଏଠାରେ ଥିବା ପୁରୁଣା ପାଠ୍ୟ `check:cycles` କୁ "ସବୁଜ, ସୁବ୍ୟବସ୍ଥିତ" ଗେଟ୍ ବୋଲି କହିଥିଲା ଏବଂ `check:circular-deps` (dpdm) 91ଟି ଚକ୍ର ରିପୋର୍ଟ କରିଥିବାରୁ ଏହାକୁ ବ୍ଲକିଂ ଭାବେ ରଖିବା ଯୁକ୍ତିସଙ୍ଗତ ବୋଲି ଦର୍ଶାଇଥିଲା। ସେହି ସବୁଜ ସ୍ଥିତି ଏକ **ଭୁଲ ସବୁଜ** ଥିଲା: `check:cycles` 5ଟି ସବ୍ଡିରେକ୍ଟୋରୀ (450ଟି ଫାଇଲ୍) ସ୍କାନ୍ କରୁଥିଲା, କେବଳ ସ୍ଥିର `import|export … from` ସହିତ ମେଳ କରୁଥିଲା, ଏବଂ ପ୍ରତ୍ୟେକ `@/` ଓ `@omniroute/open-sse/` ସ୍ପେସିଫାୟର୍କୁ ବାଦ ଦେଉଥିଲା, ତେଣୁ ରିପୋଜିଟୋରୀରେ ପ୍ରାଧାନ୍ୟ ରଖିଥିବା ଡାଇନାମିକ୍-import + alias ଚକ୍ରଗୁଡ଼ିକୁ ଏହା ଦେଖିପାରୁ ନଥିଲା। ସମାଧାନ କରାଯାଇଛି: ଗେଟ୍ଟି ବର୍ତ୍ତମାନ `src` + `open-sse` (5023ଟି ଫାଇଲ୍) ପରିକ୍ରମା କରେ, TypeScript AST ରୁ ସ୍ପେସିଫାୟର୍ଗୁଡ଼ିକ ସଂଗ୍ରହ କରେ (ଫଳରେ `import("…")` ଗଣାଯାଏ ଏବଂ type-position `typeof import("…")` ଗଣାଯାଏ ନାହିଁ), ଏବଂ tsconfig `paths` ସମାଧାନ କରେ। ଏହା 0 ନୁହେଁ, **14**ଟି ଚକ୍ର ଚିହ୍ନଟ କରେ। ଏକ ଗେଟ୍ PR ରେ ପୂର୍ବରୁ ଥିବା 14ଟି ଚକ୍ର ସମାଧାନ କରାଯାଇପାରିବ ନାହିଁ ବୋଲି, `check:cycles` ବର୍ତ୍ତମାନ ଏକ **ରାଚେଟ୍** (`--ratchet`, `quality-baseline.json` ରେ ସୀମା `metrics.cycles.value = 14`, `direction: down`) — ଏହା ଯେକୌଣସି _ଅବନତି_କୁ ଅବରୋଧ କରେ ଏବଂ ଗଣନା କେବଳ କମିପାରେ। CI `npm run check:cycles:ratchet` ଚଲାଏ। କ୍ରମଶଃ ହ୍ରାସ **A-01** ସହିତ ଚାଲିବ। ବ୍ୟାପକ ଦ୍ୱିତୀୟ ମତାମତ ଭାବେ `check:circular-deps` (dpdm) ପରାମର୍ଶମୂଳକ ରହିବ। +- **ଜଟିଳତା** — ✅ **ସମ୍ପୂର୍ଣ୍ଣ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ଗୋଟିଏ ESLint ପରିକ୍ରମା, ruleId ଅନୁଯାୟୀ ଗଣନା କରେ ଯାହାଦ୍ୱାରା cyclomatic+max-lines ଏବଂ cognitive ବେସ୍ଲାଇନ୍ଗୁଡ଼ିକ ସ୍ୱାଧୀନ ରହେ; ସ୍ଥାନୀୟ `--update` ପାଇଁ ବ୍ୟକ୍ତିଗତ `check:complexity` / `check:cognitive-complexity` ରହିବ। +- **`/api` ଭ୍ରମବିରୋଧୀ ବ୍ୟବସ୍ଥା** — ✅ **ସମ୍ପୂର୍ଣ୍ଣ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ର ଗୋଟିଏ FS ଇନ୍ଭେଣ୍ଟରୀ, openapi-routes + docs-symbols ଏବେ ମଧ୍ୟ ସ୍ୱାଧୀନ ଭାବେ ରିପୋର୍ଟ କରେ; ସ୍ଥାନୀୟ ଚାଳନା ପାଇଁ ବ୍ୟକ୍ତିଗତଗୁଡ଼ିକ ରହିବ। +- **`check:node-runtime` 11ଟି ଜବ୍ରେ ଚାଲେ** — ⚠️ **କମ୍ ROI।** ପ୍ରତ୍ୟେକଟି ଏକ ପୃଥକ ରନର୍ ଏବଂ ଯାଞ୍ଚଟି <1s; ମୋଟ ସଞ୍ଚୟ ~10s, କିନ୍ତୁ ଏହା ବଦଳରେ ପ୍ରତି-ଜବ୍ର ଏକ ଶସ୍ତା ସୁରକ୍ଷା ବ୍ୟବସ୍ଥା ହରାଇବାକୁ ପଡ଼ିବ। ଏହି ପରିବର୍ତ୍ତନଜନିତ ଅସ୍ଥିରତା ଯୋଗ୍ୟ ନୁହେଁ। +- **CI lint ରେ `typecheck:noimplicit:core`** — ✅ **lint ଜବ୍ରୁ ହଟାଯାଇଛି** (ପୂର୍ବରୁ ପରାମର୍ଶମୂଳକ `continue-on-error` ଥିଲା); ବ୍ଲକିଂ ଟାଇପ୍ ସର୍ଫେସ୍ ହେଉଛି `typecheck:core` + `check:type-coverage`। ସ୍ଥାନୀୟ ସ୍କ୍ରିପ୍ଟ ରଖାଯାଇଛି। -### ଫ୍ଲିପ୍ / ନିଷ୍ପତ୍ତି (ଅପରେଟର ନୀତି) +### ଫ୍ଲିପ୍ / ନିଷ୍ପତ୍ତି ନିଅନ୍ତୁ (ଅପରେଟର୍ ନୀତି) -- `check:openapi-security-tiers` (ପରାମର୍ଶମୂଳକ) — ❌ **ସହଜରେ ଫ୍ଲିପ୍ କରାଯାଇପାରିବ ନାହିଁ।** ଏହା 0 ସହିତ ପ୍ରସ୍ଥାନ କରେ, କିନ୍ତୁ ସତର୍କ କରେ ଯେ `LOCAL_ONLY_API_PREFIXES` ଅଧୀନରେ ଥିବା ଅନେକ `traffic-inspector` ରୁଟ୍ରେ `x-loopback-only: true` ଟିପ୍ପଣୀ ନାହିଁ। ଏହାକୁ ବାଧ୍ୟତାମୂଳକ କରିବା ପାଇଁ ପ୍ରଥମେ `openapi.yaml` ରେ ସେହି ଟିପ୍ପଣୀଗୁଡ଼ିକ ଯୋଡ଼ିବା ଆବଶ୍ୟକ। -- `typecheck:noimplicit:core` (ପରାମର୍ଶମୂଳକ) — ବ୍ଲକିଂ `check:type-coverage` ରାଚେଟ୍ ଦ୍ୱାରା ମୁଖ୍ୟତଃ ଅନ୍ତର୍ଭୁକ୍ତ। ଏହାକୁ ଏକ ରାଚେଟ୍କୁ ଫ୍ଲିପ୍ କରନ୍ତୁ କିମ୍ବା ଅନାବଶ୍ୟକ ଦ୍ୱିତୀୟ `tsc` ପାସ୍କୁ ବାଦ ଦିଅନ୍ତୁ। +- `check:openapi-security-tiers` (ପରାମର୍ଶମୂଳକ) — ❌ **ସ୍ୱଚ୍ଛ ଭାବେ ଫ୍ଲିପ୍ କରାଯାଇପାରିବ ନାହିଁ।** ଏହା 0 ସହିତ ପ୍ରସ୍ଥାନ କରେ, କିନ୍ତୁ ସତର୍କ କରେ ଯେ `LOCAL_ONLY_API_PREFIXES` ଅଧୀନରେ ଥିବା ଅନେକ `traffic-inspector` ରୁଟ୍ରେ `x-loopback-only: true` ଟୀକା ନାହିଁ। ଏହାକୁ ବାଧ୍ୟତାମୂଳକ କରିବା ପାଇଁ ପ୍ରଥମେ `openapi.yaml` ରେ ସେହି ଟୀକାଗୁଡ଼ିକ ଯୋଡ଼ିବା ଆବଶ୍ୟକ। +- `typecheck:noimplicit:core` (ପରାମର୍ଶମୂଳକ) — ବ୍ଲକିଂ `check:type-coverage` ରାଚେଟ୍ ଦ୍ୱାରା ମୁଖ୍ୟତଃ ଅନ୍ତର୍ଭୁକ୍ତ। ଏହାକୁ ରାଚେଟ୍ରେ ଫ୍ଲିପ୍ କରନ୍ତୁ କିମ୍ବା ଅନାବଶ୍ୟକ ଦ୍ୱିତୀୟ `tsc` ପାସ୍କୁ ବାଦ ଦିଅନ୍ତୁ। - `test:vitest:ui` (ବର୍ତ୍ତମାନ **ବ୍ଲକିଂ**) — ପୂର୍ବରୁ ଥିବା ବିଫଳତାଗୁଡ଼ିକୁ `vitest.config.ts` ରେ `// #8618` ଟ୍ରାକିଂ ମନ୍ତବ୍ୟ ସହିତ ସ୍ପଷ୍ଟ ଭାବେ ବାଦ ଦିଆଯାଇଛି; ନୂତନ ବିଫଳତା ଜବ୍କୁ ବିଫଳ କରେ। -- `check:secrets` (gitleaks, 3ଟି ଦସ୍ତାବିଜଭୁକ୍ତ ମିଥ୍ୟା-ପଜିଟିଭ୍ରେ ଫ୍ରିଜ୍ ହୋଇଥିବା ବ୍ଲକିଂ ରାଚେଟ୍) — 0 ରେ ପହଞ୍ଚିବା ପାଇଁ ସେହି 3ଟିକୁ allowlist କରନ୍ତୁ, କିମ୍ବା ପରାମର୍ଶମୂଳକ ସ୍ତରକୁ ଅବନମିତ କରନ୍ତୁ। GitHub ର ନେଟିଭ୍ secret-scanning + `check:public-creds` ସହିତ ଏହା ଆଂଶିକ ଭାବେ ଓଭରଲାପ୍ କରେ। -- `check:pr-evidence` (ବ୍ଲକିଂ, PR-body ଗଦ୍ୟରେ grep କରେ) — ମିଥ୍ୟା-ପଜିଟିଭ୍ର ଉଚ୍ଚ ବିପଦ; ଏହାକୁ ବାଦ ଦେଲେ Hard Rule #18 ର ପ୍ରବର୍ତ୍ତନ ଦୁର୍ବଳ ହୁଏ, ତେଣୁ ଏହା ଏକ ପ୍ରକୃତ ନୀତିଗତ ନିଷ୍ପତ୍ତି। -- `semgrep` (ପରାମର୍ଶମୂଳକ ସ୍ୱତନ୍ତ୍ର) — OWASP ପରିବାରଗୁଡ଼ିକ ପାଇଁ CodeQL ସହିତ ଓଭରଲାପ୍ କରେ; ଏହାର ବେସଲାଇନ୍କୁ ଏକ ରାଚେଟ୍ ସହ ଯୋଡ଼ନ୍ତୁ କିମ୍ବା ବାଦ ଦିଅନ୍ତୁ। +- `check:secrets` (gitleaks, 3ଟି ଡକ୍ୟୁମେଣ୍ଟେଡ୍ false-positive ରେ ସ୍ଥିରୀକୃତ ବ୍ଲକିଂ ରାଚେଟ୍) — 0 ରେ ପହଞ୍ଚିବା ପାଇଁ ସେହି 3ଟିକୁ allowlist କରନ୍ତୁ, କିମ୍ବା ପରାମର୍ଶମୂଳକ ସ୍ତରକୁ ଅବନମିତ କରନ୍ତୁ। GitHub ର ନେଟିଭ୍ secret-scanning + `check:public-creds` ସହିତ ଏହାର ଆଂଶିକ ପୁନରାବୃତ୍ତି ଅଛି। +- `check:pr-evidence` (ବ୍ଲକିଂ, PR-body ଗଦ୍ୟକୁ grep କରେ) — false-positive ହେବାର ଉଚ୍ଚ ବିପଦ; ବାଦ ଦିଆଗଲେ Hard Rule #18 ର ପ୍ରବର୍ତ୍ତନ ଦୁର୍ବଳ ହୁଏ, ତେଣୁ ଏହା ଏକ ପ୍ରକୃତ ନୀତିଗତ ନିଷ୍ପତ୍ତି। +- `semgrep` (ପରାମର୍ଶମୂଳକ ସ୍ୱତନ୍ତ୍ର) — OWASP ପରିବାରଗୁଡ଼ିକ ପାଇଁ CodeQL ସହିତ ପୁନରାବୃତ୍ତି ଅଛି; ଏହାର ବେସ୍ଲାଇନ୍କୁ ଏକ ରାଚେଟ୍ ସହିତ ସଂଯୋଗ କରନ୍ତୁ କିମ୍ବା ବାଦ ଦିଅନ୍ତୁ। --- diff --git a/docs/i18n/pa/CONTRIBUTING.md b/docs/i18n/pa/CONTRIBUTING.md index ff65e320f21..23856cd3f3b 100644 --- a/docs/i18n/pa/CONTRIBUTING.md +++ b/docs/i18n/pa/CONTRIBUTING.md @@ -392,22 +392,22 @@ docs/ --- -## ਪੁੱਲ ਰਿਕਵੈਸਟ ਚੈੱਕਲਿਸਟ +## ਪੁੱਲ ਰਿਕਵੇਸਟ ਚੈੱਕਲਿਸਟ - [ ] ਟੈਸਟ ਪਾਸ ਹੁੰਦੇ ਹਨ (`npm test`) - [ ] ਲਿੰਟਿੰਗ ਪਾਸ ਹੁੰਦੀ ਹੈ (`npm run lint`) - [ ] ਬਿਲਡ ਸਫਲ ਹੁੰਦਾ ਹੈ (`npm run build`) -- [ ] ਨਵੇਂ ਜਨਤਕ ਫੰਕਸ਼ਨਾਂ ਅਤੇ ਇੰਟਰਫੇਸਾਂ ਲਈ TypeScript ਟਾਈਪ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ ਹਨ -- [ ] ਕੋਈ ਹਾਰਡਕੋਡ ਕੀਤਾ ਸੀਕ੍ਰੇਟ ਜਾਂ ਫਾਲਬੈਕ ਮੁੱਲ ਨਹੀਂ ਹੈ -- [ ] ਜਨਤਕ ਅੱਪਸਟ੍ਰੀਮ ਕ੍ਰੈਡੈਂਸ਼ੀਅਲ `resolvePublicCred()` ਰਾਹੀਂ ਏਮਬੈੱਡ ਕੀਤੇ ਗਏ ਹਨ ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ਵੇਖੋ), ਕਦੇ ਵੀ ਲਿਟਰਲ ਵਜੋਂ ਨਹੀਂ -- [ ] ਤਰੁੱਟੀ ਜਵਾਬ `buildErrorBody()` / `sanitizeErrorMessage()` ਰਾਹੀਂ ਜਾਂਦੇ ਹਨ — ਜਵਾਬ ਬਾਡੀਆਂ ਵਿੱਚ ਕੋਈ ਕੱਚਾ ਸਟੈਕ ਟਰੇਸ ਨਹੀਂ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ਵੇਖੋ) -- [ ] ਸ਼ੈੱਲ ਕਮਾਂਡਾਂ (`exec` / `spawn`) ਰਨਟਾਈਮ ਮੁੱਲਾਂ ਨੂੰ ਸਟਰਿੰਗ ਇੰਟਰਪੋਲੇਸ਼ਨ ਰਾਹੀਂ ਨਹੀਂ, ਸਗੋਂ `env` ਰਾਹੀਂ ਪਾਸ ਕਰਦੀਆਂ ਹਨ +- [ ] ਨਵੇਂ ਪਬਲਿਕ ਫੰਕਸ਼ਨਾਂ ਅਤੇ ਇੰਟਰਫੇਸਾਂ ਲਈ TypeScript ਟਾਈਪਾਂ ਜੋੜੀਆਂ ਗਈਆਂ ਹਨ +- [ ] ਕੋਈ ਹਾਰਡਕੋਡ ਕੀਤੇ ਸੀਕ੍ਰੇਟ ਜਾਂ ਫਾਲਬੈਕ ਮੁੱਲ ਨਹੀਂ ਹਨ +- [ ] ਪਬਲਿਕ ਅੱਪਸਟ੍ਰੀਮ ਕ੍ਰੈਡੈਂਸ਼ਲ `resolvePublicCred()` ਰਾਹੀਂ ਐਂਬੈੱਡ ਕੀਤੇ ਗਏ ਹਨ ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ਵੇਖੋ), ਕਦੇ ਵੀ ਲਿਟਰਲ ਵਜੋਂ ਨਹੀਂ +- [ ] ਗਲਤੀ ਜਵਾਬ `buildErrorBody()` / `sanitizeErrorMessage()` ਰਾਹੀਂ ਭੇਜੇ ਜਾਂਦੇ ਹਨ — ਜਵਾਬ ਬਾਡੀਆਂ ਵਿੱਚ ਕੋਈ ਕੱਚਾ ਸਟੈਕ ਟ੍ਰੇਸ ਨਹੀਂ ਹੈ ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ਵੇਖੋ) +- [ ] ਸ਼ੈੱਲ ਕਮਾਂਡਾਂ (`exec` / `spawn`) ਰਨਟਾਈਮ ਮੁੱਲ ਸਟ੍ਰਿੰਗ ਇੰਟਰਪੋਲੇਸ਼ਨ ਰਾਹੀਂ ਨਹੀਂ, ਸਗੋਂ `env` ਰਾਹੀਂ ਪਾਸ ਕਰਦੀਆਂ ਹਨ - [ ] ਸਾਰੇ ਇਨਪੁੱਟ Zod ਸਕੀਮਿਆਂ ਨਾਲ ਪ੍ਰਮਾਣਿਤ ਕੀਤੇ ਗਏ ਹਨ -- [ ] ਉਪਭੋਗਤਾ-ਸਾਹਮਣੇ ਵਾਲੀਆਂ ਤਬਦੀਲੀਆਂ ਲਈ `changelog.d/{features|fixes|maintenance}/-.md` ਅਧੀਨ ਚੇਂਜਲੌਗ **ਫ੍ਰੈਗਮੈਂਟ** ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ ([`changelog.d/README.md`](./changelog.d/README.md) ਵੇਖੋ) — `CHANGELOG.md` ਨੂੰ ਸਿੱਧਾ ਸੰਪਾਦਿਤ **ਨਾ** ਕਰੋ; ਫ੍ਰੈਗਮੈਂਟ ਰਿਲੀਜ਼ ਵੇਲੇ ਇਕੱਠੇ ਕੀਤੇ ਜਾਂਦੇ ਹਨ ਅਤੇ PRs ਵਿਚਕਾਰ ਕਦੇ ਟਕਰਾਅ ਨਹੀਂ ਕਰਦੇ +- [ ] ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰਨ ਵਾਲੀਆਂ ਤਬਦੀਲੀਆਂ ਲਈ `changelog.d/{features|fixes|maintenance}/-.md` ਅਧੀਨ ਚੇਂਜਲੌਗ **ਫ੍ਰੈਗਮੈਂਟ** ਜੋੜਿਆ ਗਿਆ ਹੈ ([`changelog.d/README.md`](./changelog.d/README.md) ਵੇਖੋ) — `CHANGELOG.md` ਨੂੰ ਸਿੱਧੇ ਤੌਰ 'ਤੇ ਸੰਪਾਦਿਤ **ਨਾ** ਕਰੋ; ਫ੍ਰੈਗਮੈਂਟ ਰਿਲੀਜ਼ ਸਮੇਂ ਇਕੱਠੇ ਕੀਤੇ ਜਾਂਦੇ ਹਨ ਅਤੇ PRs ਵਿਚਕਾਰ ਕਦੇ ਟਕਰਾਅ ਨਹੀਂ ਕਰਦੇ - [ ] ਦਸਤਾਵੇਜ਼ ਅੱਪਡੇਟ ਕੀਤੇ ਗਏ ਹਨ (ਜੇ ਲਾਗੂ ਹੋਵੇ) -- [ ] ਕੋਈ ਨਵੀਂ CodeQL / Secret-Scanning ਚੇਤਾਵਨੀ ਨਹੀਂ ਖੋਲ੍ਹੀ ਗਈ, ਜਾਂ ਹਰੇਕ ਨੂੰ ਸੰਬੰਧਿਤ `docs/security/` ਦਸਤਾਵੇਜ਼ ਦਾ ਹਵਾਲਾ ਦਿੰਦੇ ਤਕਨੀਕੀ ਜਾਇਜ਼ੇ ਨਾਲ ਖਾਰਜ ਕੀਤਾ ਗਿਆ ਹੈ -- [ ] ਚਾਈਲਡ ਪ੍ਰੋਸੈਸ ਸ਼ੁਰੂ ਕਰਨ ਵਾਲੇ ਰੂਟ (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` ਵਿੱਚ `isLocalOnlyPath()` ਵਜੋਂ ਵਰਗੀਕ੍ਰਿਤ ਹਨ — [ਸਖ਼ਤ ਨਿਯਮ #15](docs/security/ROUTE_GUARD_TIERS.md) ਵੇਖੋ -- [ ] ਕਮਿਟ ਸੁਨੇਹਿਆਂ ਵਿੱਚ ਕੋਈ `Co-Authored-By` ਟ੍ਰੇਲਰ ਨਹੀਂ — ਕਮਿਟ ਸਿਰਫ਼ ਰਿਪੋਜ਼ਟਰੀ ਮਾਲਕ ਦੀ Git ਪਛਾਣ ਹੇਠ ਦਿਖਾਈ ਦੇਣੇ ਚਾਹੀਦੇ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #16) +- [ ] ਕੋਈ ਨਵੀਂ CodeQL / Secret-Scanning ਚੇਤਾਵਨੀ ਨਹੀਂ ਖੋਲ੍ਹੀ ਗਈ, ਜਾਂ ਹਰ ਇੱਕ ਨੂੰ ਸੰਬੰਧਿਤ `docs/security/` ਦਸਤਾਵੇਜ਼ ਦਾ ਹਵਾਲਾ ਦਿੰਦੇ ਤਕਨੀਕੀ ਤਰਕ ਨਾਲ ਖਾਰਜ ਕੀਤਾ ਗਿਆ ਹੈ +- [ ] ਚਾਈਲਡ ਪ੍ਰੋਸੈਸ ਸ਼ੁਰੂ ਕਰਨ ਵਾਲੇ ਰੂਟ (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` ਵਿੱਚ `isLocalOnlyPath()` ਵਜੋਂ ਵਰਗੀਕ੍ਰਿਤ ਕੀਤੇ ਗਏ ਹਨ — [ਸਖ਼ਤ ਨਿਯਮ #15](docs/security/ROUTE_GUARD_TIERS.md) ਵੇਖੋ +- [ ] ਕਮਿਟ ਸੁਨੇਹਿਆਂ ਵਿੱਚ ਕੋਈ AI/ਬੌਟ `Co-authored-by` ਟ੍ਰੇਲਰ ਨਹੀਂ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #16) — ਜਿਨ੍ਹਾਂ ਮਨੁੱਖੀ ਸਹਿਯੋਗੀਆਂ ਦੇ ਕੰਮ ਦੀ ਮੁੜ ਵਰਤੋਂ ਕੀਤੀ ਗਈ ਹੈ, ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਆਰੀ `Co-authored-by: Name ` ਟ੍ਰੇਲਰਾਂ ਨਾਲ ਸਿਹਰਾ ਦਿੱਤਾ ਗਿਆ ਹੈ --- diff --git a/docs/i18n/pa/docs/architecture/QUALITY_GATES.md b/docs/i18n/pa/docs/architecture/QUALITY_GATES.md index 1072775968b..71bc0a9dc04 100644 --- a/docs/i18n/pa/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/pa/docs/architecture/QUALITY_GATES.md @@ -17,213 +17,207 @@ ## ਗੇਟ ਇਨਵੈਂਟਰੀ ਅਤੇ ਐਗਜ਼ਿਕਿਊਸ਼ਨ ਪ੍ਰੋਫ਼ਾਈਲ -### ਉਮੀਦਵਾਰ ਦਾਖਲਾ +### ਉਮੀਦਵਾਰ ਦੀ ਸਵੀਕ੍ਰਿਤੀ CI ਅਤੇ Quality Gates ਵਰਕਫ਼ਲੋ ਹਰ ਇੱਕ ਸਥਿਰ ਫ਼ੈਸਲਾ ਜਾਰੀ ਕਰਦੇ ਹਨ: `Gate / CI` ਅਤੇ -`Gate / Quality`। ਉਨ੍ਹਾਂ ਦੀ ਵਰਜ਼ਨ-ਨਿਯੰਤਰਿਤ ਦਾਖਲਾ ਨੀਤੀ ਹਰ ਅੱਪਸਟ੍ਰੀਮ ਜੌਬ ਨੂੰ -ਲਾਜ਼ਮੀ ਜਾਂ ਸਲਾਹਕਾਰੀ ਵਜੋਂ ਸੂਚੀਬੱਧ ਕਰਦੀ ਹੈ। ਲਾਗੂ ਹੋਣ ਵਾਲੀ ਲਾਜ਼ਮੀ ਜੌਬ ਦਾ ਸਫਲ ਹੋਣਾ -ਜ਼ਰੂਰੀ ਹੈ: ਗੁੰਮ, ਰੱਦ, ਛੱਡੇ ਗਏ, ਬਕਾਇਆ ਅਤੇ ਅਣਜਾਣ ਨਤੀਜੇ PASS ਸਥਾਪਤ ਨਹੀਂ ਕਰ ਸਕਦੇ। -ਇੱਕ ਵੈਧ ਸਿਰਫ਼-ਡੌਕਸ ਜਾਂ ਸਿਰਫ਼-ਕੈਟਾਲੌਗ ਵਰਗੀਕਰਨ ਕੋਡ ਲੇਨ ਨੂੰ ਗੈਰ-ਲਾਗੂ ਬਣਾ ਸਕਦਾ ਹੈ; -ਡਰਾਫਟ PR ਨੂੰ ਸਵੀਕਾਰਿਆ ਉਮੀਦਵਾਰ ਨਹੀਂ ਮੰਨਿਆ ਜਾਂਦਾ। `hotfix` ਲੇਬਲ ਸਬੂਤ ਦੀ ਲੋੜ ਨੂੰ -ਮੁਆਫ਼ ਨਹੀਂ ਕਰਦਾ। - -ਦੋਵੇਂ ਵਰਕਫ਼ਲੋ PRs ਅਤੇ main/release ਬ੍ਰਾਂਚਾਂ ਵੱਲ ਪੁਸ਼, ਮੈਨੁਅਲ ਡਿਸਪੈਚ ਅਤੇ -ਮਰਜ-ਗਰੁੱਪ ਇਵੈਂਟਾਂ ਨੂੰ ਕਵਰ ਕਰਦੇ ਹਨ। ਪੁਸ਼, ਡਿਸਪੈਚ ਅਤੇ ਮਰਜ-ਗਰੁੱਪ ਪੂਰੀ ਚੋਣ ਚਲਾਉਂਦੇ ਹਨ। -ਫੋਰਕ ਅਤੇ ਮਰਜ ਗਰੁੱਪ ਉਹਨਾਂ ਜੌਬਾਂ ਲਈ ਹੋਸਟਡ ਰਨਰ ਵਰਤਦੇ ਹਨ ਜੋ ਨਹੀਂ ਤਾਂ ਸੈਲਫ਼-ਹੋਸਟਡ -ਰਨਰ ਚੁਣਦੀਆਂ; ਰੋਲਆਉਟ ਤੋਂ ਪਹਿਲਾਂ ਲੋੜੀਂਦੀ ਹੋਸਟਡ ਸਮਰੱਥਾ ਦੀ ਪੁਸ਼ਟੀ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ। - -ਹਰ JSON ਰਸੀਦ ਚੈੱਕ-ਆਉਟ ਕੀਤੇ SHA, ਵਰਕਫ਼ਲੋ ਰਨ ਅਤੇ ਕੋਸ਼ਿਸ਼ ਦੀ ਪਛਾਣ ਕਰਦੀ ਹੈ। -CLI ਚੈੱਕਆਉਟ/ਇਵੈਂਟ SHA ਬੇਮੇਲ ਨੂੰ ਰੱਦ ਕਰਦਾ ਹੈ। ਵਰਕਫ਼ਲੋ ਟੈਸਟ ਨੀਤੀ ਮੈਂਬਰਸ਼ਿਪ ਨੂੰ -ਫ਼ੈਸਲਾ ਜੌਬ ਦੀ `needs` ਸੂਚੀ ਨਾਲ ਬੰਨ੍ਹਦੇ ਹਨ, ਤਾਂ ਜੋ ਕੋਈ ਨਵੀਂ ਜਾਂ ਹਟਾਈ ਗਈ ਲੇਨ -ਚੁੱਪਚਾਪ ਗਾਇਬ ਨਾ ਹੋ ਸਕੇ। ਰਸੀਦਾਂ ਆਪਣੇ ਵਰਕਫ਼ਲੋ ਨੂੰ ਕਵਰ ਕਰਦੀਆਂ ਹਨ, ਪ੍ਰਕਾਸ਼ਨ, -ਡਿਪਲੌਇਮੈਂਟ ਜਾਂ ਕਿਸੇ ਮੌਜੂਦਾ ਸਲਾਹਕਾਰੀ ਸਕੈਨਰ ਦੇ ਅੰਦਰੂਨੀ ਹਿੱਸਿਆਂ ਨੂੰ ਨਹੀਂ। ਬ੍ਰਾਂਚ -ਨਿਯਮਾਂ ਵਿੱਚ ਦੋਵੇਂ ਚੈੱਕ ਨਾਮ ਸਰਗਰਮ ਕਰਨਾ ਇੱਕ ਵੱਖਰਾ ਪ੍ਰਸ਼ਾਸਕੀ ਬਦਲਾਅ ਹੈ; ਇਹ ਜੌਬਾਂ -ਜੋੜਨਾ ਆਪਣੇ ਆਪ ਕਿਸੇ ਬ੍ਰਾਂਚ ਦੀ ਸੁਰੱਖਿਆ ਨਹੀਂ ਕਰਦਾ। +`Gate / Quality`। ਉਨ੍ਹਾਂ ਦੀ ਵਰਜਨਬੱਧ ਸਵੀਕ੍ਰਿਤੀ ਨੀਤੀ ਹਰੇਕ ਅੱਪਸਟ੍ਰੀਮ ਜੌਬ ਨੂੰ +ਲਾਜ਼ਮੀ ਜਾਂ ਸਲਾਹਕਾਰੀ ਵਜੋਂ ਸੂਚੀਬੱਧ ਕਰਦੀ ਹੈ। ਲਾਗੂ ਹੋਣ ਵਾਲਾ ਲਾਜ਼ਮੀ ਜੌਬ ਸਫਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ: +ਗੈਰਹਾਜ਼ਰ, ਰੱਦ, ਛੱਡੇ ਗਏ, ਬਕਾਇਆ ਅਤੇ ਅਣਜਾਣ ਨਤੀਜੇ PASS ਸਥਾਪਤ ਨਹੀਂ ਕਰ ਸਕਦੇ। ਇੱਕ ਵੈਧ +ਕੇਵਲ-ਦਸਤਾਵੇਜ਼ ਜਾਂ ਕੇਵਲ-ਕੈਟਾਲੌਗ ਵਰਗੀਕਰਨ ਕਿਸੇ ਕੋਡ ਲੇਨ ਨੂੰ ਗੈਰ-ਲਾਗੂ ਬਣਾ ਸਕਦਾ ਹੈ; +ਡਰਾਫਟ PR ਸਵੀਕਾਰਿਆ ਉਮੀਦਵਾਰ ਨਹੀਂ ਹੈ। `hotfix` ਲੇਬਲ ਸਬੂਤ ਦੀ ਲੋੜ ਨੂੰ ਮੁਆਫ਼ ਨਹੀਂ ਕਰਦਾ। + +ਦੋਵੇਂ ਵਰਕਫ਼ਲੋ PRs ਅਤੇ main/release ਬ੍ਰਾਂਚਾਂ ਵੱਲ ਪੁਸ਼, ਮੈਨੂਅਲ ਡਿਸਪੈਚ ਅਤੇ +merge-group ਇਵੈਂਟਾਂ ਨੂੰ ਕਵਰ ਕਰਦੇ ਹਨ। Push, dispatch ਅਤੇ merge-group ਪੂਰੀ ਚੋਣ ਚਲਾਉਂਦੇ ਹਨ। Forks +ਅਤੇ merge groups ਉਹਨਾਂ ਜੌਬਾਂ ਲਈ hosted runners ਵਰਤਦੇ ਹਨ ਜੋ ਹੋਰਥਾਂ self-hosted +runners ਚੁਣਦੇ ਹਨ; ਰੋਲਆਉਟ ਤੋਂ ਪਹਿਲਾਂ hosted ਸਮਰੱਥਾ ਦੀ ਯਥੇਸ਼ਟਤਾ ਦੀ ਪੁਸ਼ਟੀ ਕੀਤੀ ਜਾਣੀ ਚਾਹੀਦੀ ਹੈ। + +ਹਰੇਕ JSON ਰਸੀਦ ਚੈੱਕ-ਆਉਟ ਕੀਤੇ SHA, ਵਰਕਫ਼ਲੋ ਰਨ ਅਤੇ ਕੋਸ਼ਿਸ਼ ਦੀ ਪਛਾਣ ਕਰਦੀ ਹੈ। +CLI, checkout/event SHA ਦੇ ਬੇਮੇਲ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰਦਾ ਹੈ। ਵਰਕਫ਼ਲੋ ਟੈਸਟ ਨੀਤੀ ਮੈਂਬਰਸ਼ਿਪ ਨੂੰ +ਫ਼ੈਸਲਾ ਜੌਬ ਦੀ `needs` ਸੂਚੀ ਨਾਲ ਜੋੜਦੇ ਹਨ, ਤਾਂ ਜੋ ਕੋਈ ਨਵੀਂ ਜਾਂ ਹਟਾਈ ਗਈ ਲੇਨ ਚੁੱਪਚਾਪ ਗਾਇਬ ਨਾ ਹੋ ਸਕੇ। +ਰਸੀਦਾਂ ਆਪਣੇ ਵਰਕਫ਼ਲੋ ਨੂੰ ਕਵਰ ਕਰਦੀਆਂ ਹਨ, ਪ੍ਰਕਾਸ਼ਨ, ਡਿਪਲੌਇਮੈਂਟ ਜਾਂ ਕਿਸੇ ਮੌਜੂਦਾ +ਸਲਾਹਕਾਰੀ ਸਕੈਨਰ ਦੇ ਅੰਦਰੂਨੀ ਹਿੱਸਿਆਂ ਨੂੰ ਨਹੀਂ। ਬ੍ਰਾਂਚ ਨਿਯਮਾਂ ਵਿੱਚ ਦੋਵੇਂ ਚੈੱਕ ਨਾਮ ਸਰਗਰਮ ਕਰਨਾ ਇੱਕ +ਵੱਖਰਾ ਪ੍ਰਸ਼ਾਸਕੀ ਬਦਲਾਅ ਹੈ; ਇਹ ਜੌਬ ਸ਼ਾਮਲ ਕਰਨ ਨਾਲ ਆਪਣੇ ਆਪ ਕੋਈ ਬ੍ਰਾਂਚ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹੁੰਦੀ। ### ਸਟੈਟਿਕ ਸਕੈਨ ਇਨਵੈਂਟਰੀ -ਵਰਜ਼ਨ-ਨਿਯੰਤਰਿਤ npm-ਐਲਿਅਸ ਇਨਵੈਂਟਰੀ ਅਤੇ ਸਟੈਟਿਕ-ਸਕੈਨ ਮੈਂਬਰਸ਼ਿਪ -`config/quality/gate-manifest.json` ਵਿੱਚ ਮੌਜੂਦ ਹਨ। ਸਕ੍ਰਿਪਟ ਨਾਮਾਂ ਅਤੇ ਸਟੀਕ ਕਮਾਂਡਾਂ -ਨੂੰ `package.json` ਨਾਲ ਮਿਲਾ ਕੇ ਪ੍ਰਮਾਣਿਤ ਕਰਨ ਲਈ `npm run check:gate-manifest` ਚਲਾਓ; -ਜੋੜ, ਹਟਾਉਣ ਅਤੇ ਕਮਾਂਡ ਵਿੱਚ ਤਬਦੀਲੀ ਸਥਾਨਕ ਹੁੱਕ ਅਤੇ CI ਵਿੱਚ ਬਦਲਾਅ-ਵਰਗੀਕਰਨ ਜੌਬਾਂ -ਦੋਵਾਂ ਨੂੰ ਅਸਫਲ ਕਰ ਦਿੰਦੇ ਹਨ। ਇੱਕ ਐਲਿਅਸ ਕੋਈ ਵਰਕਫ਼ਲੋ ਜੌਬ, ਮੈਟ੍ਰਿਕਸ ਇੰਸਟੈਂਸ ਜਾਂ -ਟੈਸਟ ਕੇਸ ਨਹੀਂ ਹੁੰਦਾ: ਇਨ੍ਹਾਂ ਗਿਣਤੀਆਂ ਨੂੰ ਆਪਸ ਵਿੱਚ ਬਦਲਣਯੋਗ ਵਜੋਂ ਪੇਸ਼ ਨਹੀਂ ਕੀਤਾ -ਜਾਣਾ ਚਾਹੀਦਾ। - -ਚੁਣੇ ਹੋਏ ਐਲਿਅਸਾਂ ਨੂੰ ਚਲਾਏ ਬਿਨਾਂ ਦੇਖਣ ਲਈ `npm run quality:scan -- --list` ਜਾਂ -`npm run quality:scan:fast -- --list` ਵਰਤੋ। ਰਨਰ npm ਐਂਟਰੀਪੌਇੰਟ ਨੂੰ ਇਨਵੋਕ ਕਰਦਾ -ਹੈ, ਇਸ ਲਈ ਇਸ ਦਾ ਰਨਟਾਈਮ (ਜਿੱਥੇ ਸੰਰਚਿਤ ਹੋਵੇ ਉੱਥੇ Bun ਸਮੇਤ) ਬਰਕਰਾਰ ਰਹਿੰਦਾ ਹੈ। -ਮੈਨੀਫੈਸਟ ਉਨ੍ਹਾਂ ਪ੍ਰੋਫ਼ਾਈਲਾਂ ਤੋਂ ਬਾਹਰਲੇ ਐਲਿਅਸਾਂ ਨੂੰ ਵੱਖਰੇ ਤੌਰ 'ਤੇ ਇਨਵੋਕ ਕੀਤੇ ਵਜੋਂ -ਦਰਜ ਕਰਦਾ ਹੈ, ਅਤੇ ਰੀਡ-ਓਨਲੀ ਸਕੈਨ ਪ੍ਰੋਫ਼ਾਈਲਾਂ ਵਿੱਚ ਰੱਖ-ਰਖਾਅ ਕਮਾਂਡਾਂ ਦੀ ਮਨਾਹੀ ਹੈ। - -ਇਹ ਪ੍ਰੋਫ਼ਾਈਲ ਸਿਰਫ਼ ਸਟੈਟਿਕ ਸਕੈਨ ਨੂੰ ਕਵਰ ਕਰਦੇ ਹਨ। ਇਹ ਪ੍ਰੋਡਕਟ ਟੈਸਟਾਂ, ਕਵਰੇਜ, -ਪੈਕੇਜਿੰਗ, ਬਾਹਰੀ ਚੈੱਕਾਂ ਜਾਂ ਕਿਸੇ ਉਮੀਦਵਾਰ ਦੀ ਪੂਰੀ ਰਿਲੀਜ਼ ਸਵੀਕ੍ਰਿਤੀ ਨੂੰ ਪ੍ਰਮਾਣਿਤ -ਨਹੀਂ ਕਰਦੇ। ਵਰਕਫ਼ਲੋ ਦਾਖਲਾ ਲਿੰਕ ਕੀਤੇ `config/quality/admission-policy.json` ਅਤੇ -`scripts/quality/admission-verdict.mjs` ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਰਿਲੀਜ਼-ਆਬਜ਼ਰਵਰ ਪ੍ਰੋਫ਼ਾਈਲ -ਵੱਖਰੇ ਰਹਿੰਦੇ ਹਨ; ਉਨ੍ਹਾਂ ਦੇ ਲਾਗੂ ਚੈੱਕਾਂ ਅਤੇ ਰਸੀਦਾਂ ਦੀ ਸੁਤੰਤਰ ਤੌਰ 'ਤੇ ਜਾਂਚ ਕਰੋ। -ਹੇਠਾਂ ਦਿੱਤੀ ਵਾਰਤਕ ਇਨਵੈਂਟਰੀ ਇੱਕ ਹਵਾਲਾ ਹੈ, ਇਸ ਗੱਲ ਦਾ ਸਬੂਤ ਨਹੀਂ ਕਿ ਗੇਟ ਅਸਲ ਵਿੱਚ -ਚੱਲਿਆ ਸੀ। - -ਸਕ੍ਰਿਪਟਾਂ `scripts/check/` (ਨੀਤੀ ਗੇਟ) ਅਤੇ `scripts/quality/` (ਰੈਚਿਟ ਇੰਜਣ) ਦੇ -ਅਧੀਨ ਮੌਜੂਦ ਹਨ। CI ਲਈ ਸੱਚਾਈ ਦਾ ਸਰੋਤ `.github/workflows/ci.yml` ਹੈ। - -### ਰਿਲੀਜ਼ PR ਫਾਸਟ-ਪਾਥ (`quality.yml`) - -`.github/workflows/quality.yml` main/release PRs, ਸੁਰੱਖਿਅਤ-ਬ੍ਰਾਂਚ ਪੁਸ਼ਾਂ, ਡਿਸਪੈਚ -ਅਤੇ ਮਰਜ ਗਰੁੱਪਾਂ 'ਤੇ CI ਦੀ ਪੂਰਤੀ ਕਰਦਾ ਹੈ। PRs ਪਾਥ-ਫਿਲਟਰ ਕੀਤੇ ਤੇਜ਼ ਚੈੱਕ ਵਰਤਦੇ ਹਨ। -ਸਥਾਈ ਤੌਰ 'ਤੇ ਅਸਮਰੱਥ ਕੀਤੀ ਡੁਪਲੀਕੇਟ ਬਿਲਡ ਹਟਾ ਦਿੱਤੀ ਗਈ ਸੀ; ਅਸਲ -ਬਿਲਡ/ਪੈਕੇਜ/ਬੂਟ ਚੈੱਕ CI ਵਿੱਚ ਬਰਕਰਾਰ ਹਨ। - -| ਜੌਬ | ਦਾਇਰਾ | ਬਲੌਕਿੰਗ | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | ਡੌਕਸ/ਕੋਡ PRs; API ਡੌਕਸ ਹਵਾਲੇ ਅਤੇ docs-all | ਹਾਂ | -| `Fast Quality Gates` | ਕੋਡ PRs; ਸਟੈਟਿਕ ਚੈੱਕ, ਟਾਈਪਚੈੱਕ, ਡੈਸ਼ਬੋਰਡ ਟਾਈਪਚੈੱਕ, ਪ੍ਰਭਾਵਿਤ ਯੂਨਿਟ ਟੈਸਟ | ਹਾਂ | -| `Forgotten sibling tests` | ਕੋਡ PRs; ਬਦਲੇ ਮੌਡਿਊਲਾਂ ਤੋਂ ਸਟੈਟਿਕ ਉਪਭੋਗਤਾਵਾਂ ਅਤੇ ਸੰਭਾਵੀ ਸਿਬਲਿੰਗ ਟੈਸਟਾਂ ਤੱਕ ਟਰੇਸ; ਬੈਰਲ ਅਤੇ ਡਾਇਨਾਮਿਕ-ਇੰਪੋਰਟ ਪਾਥਾਂ ਨੂੰ ਸਲਾਹਕਾਰੀ ਡਾਇਗਨੌਸਟਿਕਸ ਵਜੋਂ ਰਿਪੋਰਟ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਹਵਾਲਾ ਦਿੱਤੇ ਅਲਾਊਲਿਸਟ ਅਪਵਾਦਾਂ ਸਮੇਤ | **ਸਲਾਹਕਾਰੀ** | -| `Vitest (fast-path)` | ਕੋਡ PRs; ਤੇਜ਼ vitest ਸੂਟ | ਹਾਂ | -| `Unit Tests fast-path` | ਕੋਡ PRs; 4-ਸ਼ਾਰਡ ਯੂਨਿਟ ਸੂਟ | ਹਾਂ | -| `No new ESLint warnings` | ਕੋਡ PRs; ਸਪ੍ਰੈਸ਼ਨ-ਅਵੇਅਰ ਲਿੰਟ ਗਾਰਡ | ਹਾਂ, ਫੋਰਕਾਂ ਸਮੇਤ | -| `Merge integrity (changelog + generated skills)` | ਗੈਰ-ਡਰਾਫਟ PRs; ਚੇਂਜਲੌਗ ਅਤੇ ਜਨਰੇਟ ਕੀਤੇ ਸਕਿੱਲਾਂ ਦਾ ਸਿੰਕ | ਹਾਂ, ਫੋਰਕਾਂ ਸਮੇਤ | - -#### ਭੁੱਲੇ ਹੋਏ ਸਿਬਲਿੰਗ ਟੈਸਟਾਂ ਦੀ ਰਿਪੋਰਟ - -`npm run check:forgotten-sibling-tests` ਟੈਸਟ-ਇੰਪੈਕਟ ਮੈਪ ਦੇ ਪਿੱਛੇ ਵਰਤੇ ਜਾਣ ਵਾਲੇ -ਇੰਪੋਰਟ ਰਿਜ਼ੌਲਵਰ ਨੂੰ ਮੁੜ ਵਰਤਦਾ ਹੈ। ਹਰੇਕ ਬਦਲੇ ਹੋਏ ਪ੍ਰੋਡਕਸ਼ਨ ਮੌਡਿਊਲ ਲਈ, ਜਦੋਂ -ਸੰਭਾਵੀ ਟੈਸਟ ਪੁੱਲ-ਰਿਕਵੈਸਟ ਡਿਫ਼ ਵਿੱਚ ਮੌਜੂਦ ਨਹੀਂ ਹੁੰਦਾ, ਇਹ ਨਿਰਧਾਰਤ -`changed module/symbol -> static consumer -> candidate sibling test` ਚੇਨਾਂ ਦੀ -ਰਿਪੋਰਟ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਵੀ ਬਲੌਕਿੰਗ ਰੋਲਆਉਟ ਤੋਂ ਪਹਿਲਾਂ ਕੈਲੀਬ੍ਰੇਸ਼ਨ ਲਈ Markdown ਸੰਖੇਪ -ਅਤੇ JSON ਨਤੀਜੇ ਨੂੰ `forgotten-sibling-tests` ਵਰਕਫ਼ਲੋ ਆਰਟੀਫੈਕਟ ਵਜੋਂ ਸੰਭਾਲਿਆ ਜਾਂਦਾ ਹੈ। - -Barrel re-exports ਅਤੇ dynamic imports ਕੇਵਲ resolution diagnostics ਹਨ; ਇਹ ਕਦੇ ਵੀ ਕੋਈ -ਰੋਕਣ ਵਾਲੀ finding ਨਹੀਂ ਬਣਾਉਂਦੇ। ਸਮੀਖਿਆ ਕੀਤੇ exceptions -`config/quality/forgotten-sibling-allowlist.json` ਵਿੱਚ ਮੌਜੂਦ ਹਨ। ਹਰੇਕ entry ਵਿੱਚ consumer ਅਤੇ candidate -test ਦਾ ਨਾਮ, ਇੱਕ ਵਿਸ਼ੇਸ਼ ਤਰਕ, ਅਤੇ ਕਿਸੇ GitHub issue ਜਾਂ pull request ਦਾ link ਹੋਣਾ ਲਾਜ਼ਮੀ ਹੈ। ਗਲਤ ਢੰਗ ਨਾਲ ਬਣੀਆਂ entries -ਬੰਦ-ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਅਸਫਲ ਹੁੰਦੀਆਂ ਹਨ। Exceptions ਕਿਸੇ ਮਿਟਾਏ ਗਏ candidate test ਜਾਂ `.skip`/`.todo` ਜੋੜਨ ਵਾਲੇ diff ਨੂੰ suppress ਨਹੀਂ ਕਰ ਸਕਦੇ; -assertion ਨੂੰ ਕਮਜ਼ੋਰ ਕਰਨਾ ਅਤੇ ਹੋਰ masking ਸੁਤੰਤਰ ਤੌਰ 'ਤੇ ਰੋਕ ਲਗਾਉਣ ਵਾਲੇ -`check:test-masking` gate ਦੇ ਅਧੀਨ ਰਹਿੰਦੇ ਹਨ। +ਵਰਜਨਬੱਧ npm-alias ਇਨਵੈਂਟਰੀ ਅਤੇ static-scan ਮੈਂਬਰਸ਼ਿਪ +`config/quality/gate-manifest.json` ਵਿੱਚ ਮੌਜੂਦ ਹਨ। ਸਕ੍ਰਿਪਟ ਨਾਮਾਂ ਅਤੇ ਸਟੀਕ ਕਮਾਂਡਾਂ ਨੂੰ +`package.json` ਨਾਲ ਮਿਲਾ ਕੇ ਪ੍ਰਮਾਣਿਤ ਕਰਨ ਲਈ `npm run check:gate-manifest` ਚਲਾਓ; ਜੋੜ, ਹਟਾਉਣ ਅਤੇ +ਕਮਾਂਡ ਡ੍ਰਿਫ਼ਟ ਦੋਵਾਂ—ਲੋਕਲ ਹੁੱਕ ਅਤੇ CI ਵਿੱਚ ਬਦਲਾਅ-ਵਰਗੀਕਰਨ ਜੌਬਾਂ—ਨੂੰ ਅਸਫਲ ਕਰ ਦਿੰਦੇ ਹਨ। +ਕੋਈ alias, workflow job, matrix instance ਜਾਂ test case ਨਹੀਂ ਹੁੰਦਾ: ਇਹ ਗਿਣਤੀਆਂ +ਆਪਸ ਵਿੱਚ ਬਦਲਣਯੋਗ ਵਜੋਂ ਪੇਸ਼ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾਣੀਆਂ ਚਾਹੀਦੀਆਂ। + +ਚੁਣੇ ਹੋਏ aliases ਨੂੰ ਚਲਾਏ ਬਿਨਾਂ ਦੇਖਣ ਲਈ `npm run quality:scan -- --list` ਜਾਂ +`npm run quality:scan:fast -- --list` ਵਰਤੋ। Runner, npm entrypoint ਨੂੰ ਚਲਾਉਂਦਾ ਹੈ, +ਇਸ ਲਈ ਇਸ ਦਾ runtime—ਸੰਰਚਿਤ ਹੋਣ ਦੀ ਸਥਿਤੀ ਵਿੱਚ Bun ਸਮੇਤ—ਬਰਕਰਾਰ ਰਹਿੰਦਾ ਹੈ। +Manifest ਉਹਨਾਂ ਪ੍ਰੋਫ਼ਾਈਲਾਂ ਤੋਂ ਬਾਹਰਲੇ aliases ਨੂੰ ਵੱਖਰੇ ਤੌਰ 'ਤੇ ਚਲਾਏ ਗਏ ਵਜੋਂ ਦਰਜ ਕਰਦਾ ਹੈ, ਅਤੇ +read-only scan ਪ੍ਰੋਫ਼ਾਈਲਾਂ ਵਿੱਚ maintenance commands ਵਰਜਿਤ ਹਨ। + +ਇਹ ਪ੍ਰੋਫ਼ਾਈਲ ਕੇਵਲ static scan ਨੂੰ ਕਵਰ ਕਰਦੇ ਹਨ। ਇਹ product tests, +coverage, packaging, external checks ਜਾਂ ਕਿਸੇ ਉਮੀਦਵਾਰ ਦੀ ਪੂਰੀ release acceptance ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਨਹੀਂ ਕਰਦੇ। +Workflow admission, ਲਿੰਕ ਕੀਤੇ `config/quality/admission-policy.json` ਅਤੇ +`scripts/quality/admission-verdict.mjs` ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ। Release-observer ਪ੍ਰੋਫ਼ਾਈਲ ਵੱਖਰੇ ਰਹਿੰਦੇ ਹਨ; +ਉਨ੍ਹਾਂ ਦੇ ਲਾਗੂ ਚੈੱਕਾਂ ਅਤੇ ਰਸੀਦਾਂ ਦੀ ਸੁਤੰਤਰ ਤੌਰ 'ਤੇ ਜਾਂਚ ਕਰੋ। ਹੇਠਾਂ ਦਿੱਤੀ ਵਿਆਖਿਆਤਮਕ +ਇਨਵੈਂਟਰੀ ਇੱਕ ਹਵਾਲਾ ਹੈ, ਇਸ ਗੱਲ ਦਾ ਸਬੂਤ ਨਹੀਂ ਕਿ ਕੋਈ ਗੇਟ ਵਾਸਤਵ ਵਿੱਚ ਚੱਲਿਆ ਸੀ। + +ਸਕ੍ਰਿਪਟਾਂ `scripts/check/` (ਨੀਤੀ ਗੇਟ) ਅਤੇ `scripts/quality/` (ratchet engine) ਦੇ ਅਧੀਨ ਮੌਜੂਦ ਹਨ। +CI ਲਈ ਸੱਚਾਈ ਦਾ ਸਰੋਤ `.github/workflows/ci.yml` ਹੈ। + +### Release PR ਫਾਸਟ-ਪਾਥ (`quality.yml`) + +`.github/workflows/quality.yml`, main/release PRs, protected-branch +pushes, dispatch ਅਤੇ merge groups ਉੱਤੇ CI ਦੀ ਪੂਰਤੀ ਕਰਦਾ ਹੈ। PRs path-filtered ਤੇਜ਼ ਚੈੱਕ ਵਰਤਦੇ ਹਨ। ਸਥਾਈ ਤੌਰ 'ਤੇ +ਅਸਮਰੱਥ ਕੀਤਾ ਡੁਪਲੀਕੇਟ build ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਸੀ; ਅਸਲ build/package/boot ਚੈੱਕ CI ਵਿੱਚ ਮੌਜੂਦ ਰਹਿੰਦੇ ਹਨ। + +| ਜੌਬ | ਦਾਇਰਾ | ਬਲੌਕ ਕਰਨ ਵਾਲਾ | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `Docs Gates (fast-path)` | Docs/code PRs; API docs refs ਅਤੇ docs-all | ਹਾਂ | +| `Fast Quality Gates` | Code PRs; static checks, typecheck, dashboard typecheck, ਪ੍ਰਭਾਵਿਤ unit tests | ਹਾਂ | +| `Forgotten sibling tests` | Code PRs; ਬਦਲੇ ਹੋਏ modules ਤੋਂ static consumers ਅਤੇ candidate sibling tests ਤੱਕ ਟ੍ਰੇਸ; barrel ਅਤੇ dynamic-import paths ਨੂੰ allowlist ਦੇ ਹਵਾਲੇ ਵਾਲੇ ਅਪਵਾਦਾਂ ਸਮੇਤ ਸਲਾਹਕਾਰੀ diagnostics ਵਜੋਂ ਰਿਪੋਰਟ ਕੀਤਾ ਜਾਂਦਾ ਹੈ | **ਸਲਾਹਕਾਰੀ** | +| `Vitest (fast-path)` | Code PRs; ਤੇਜ਼ vitest suite | ਹਾਂ | +| `Unit Tests fast-path` | Code PRs; 4-shard unit suite | ਹਾਂ | +| `No new ESLint warnings` | Code PRs; suppressions-aware lint guard | ਹਾਂ, forks ਸਮੇਤ | +| `Merge integrity (changelog + generated skills)` | Non-draft PRs; changelog ਅਤੇ generated skill sync | ਹਾਂ, forks ਸਮੇਤ | + +#### ਭੁੱਲੇ ਹੋਏ sibling tests ਦੀ ਰਿਪੋਰਟ + +`npm run check:forgotten-sibling-tests`, test-impact map ਦੇ ਪਿੱਛੇ ਮੌਜੂਦ import resolver ਨੂੰ ਮੁੜ ਵਰਤਦਾ ਹੈ। +ਹਰੇਕ ਬਦਲੇ ਹੋਏ production module ਲਈ, ਜਦੋਂ candidate +test, pull-request diff ਵਿੱਚ ਗੈਰਹਾਜ਼ਰ ਹੋਵੇ, ਇਹ ਨਿਰਧਾਰਿਤ +`changed module/symbol -> static consumer -> candidate sibling test` ਲੜੀਆਂ ਰਿਪੋਰਟ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਵੀ blocking rollout ਤੋਂ ਪਹਿਲਾਂ calibration ਲਈ +Markdown ਸਾਰਾਂਸ਼ ਅਤੇ JSON ਨਤੀਜੇ ਨੂੰ `forgotten-sibling-tests` workflow artifact ਵਜੋਂ ਸੰਭਾਲਿਆ ਜਾਂਦਾ ਹੈ। + +Barrel ਰੀ-ਐਕਸਪੋਰਟ ਅਤੇ ਡਾਇਨਾਮਿਕ ਇੰਪੋਰਟ ਸਿਰਫ਼ resolution diagnostics ਹਨ; ਇਹ ਕਦੇ ਵੀ +ਕੋਈ blocking finding ਨਹੀਂ ਬਣਾਉਂਦੇ। ਸਮੀਖਿਆ ਕੀਤੀਆਂ exceptions +`config/quality/forgotten-sibling-allowlist.json` ਵਿੱਚ ਮੌਜੂਦ ਹਨ। ਹਰ entry ਵਿੱਚ consumer ਅਤੇ candidate +ਟੈਸਟ ਦਾ ਨਾਮ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਇੱਕ ਖਾਸ ਤਰਕ ਦਿੱਤਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਅਤੇ GitHub issue ਜਾਂ pull request ਦਾ ਲਿੰਕ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ। ਗਲਤ-ਰੂਪ ਵਾਲੀਆਂ entries +fail closed ਹੁੰਦੀਆਂ ਹਨ। Exceptions ਮਿਟਾਏ ਗਏ candidate ਟੈਸਟ ਜਾਂ `.skip`/`.todo` ਜੋੜਨ ਵਾਲੇ diff ਨੂੰ suppress ਨਹੀਂ ਕਰ ਸਕਦੀਆਂ; +assertion weakening ਅਤੇ ਹੋਰ masking ਦੀ ਜ਼ਿੰਮੇਵਾਰੀ ਸੁਤੰਤਰ ਤੌਰ 'ਤੇ blocking +`check:test-masking` gate ਕੋਲ ਰਹਿੰਦੀ ਹੈ। ### Job: `lint` -`main` ਲਈ ਹਰ PR ਉੱਤੇ ਚੱਲਦਾ ਹੈ। ਅਸਫਲਤਾ ਹੋਣ 'ਤੇ merge ਨੂੰ ਰੋਕਦਾ ਹੈ। - -| Script (`npm run ...`) | ਪ੍ਰਮਾਣਿਤ ਕਰਦਾ ਹੈ | ਰੋਕਣ ਵਾਲਾ | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `check:node-runtime` | Node.js ਦਾ version ਸਮਰਥਿਤ range ਦੇ ਅੰਦਰ ਹੈ | ਹਾਂ | -| `check:cycles` | Circular imports — ਸਾਰੇ `src/` + `open-sse/` modules | ਹਾਂ | -| `check:route-validation:t06` | ਸਾਰੇ routes ਉੱਤੇ Zod schemas ਮੌਜੂਦ ਹਨ (Tier 6 policy) | ਹਾਂ | -| `check:any-budget:t11` | `@ts-expect-error // any` ਦੀ ਗਿਣਤੀ budget ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ (Tier 11 catraca) | ਹਾਂ | -| `check:provider-consistency` | `providers.ts` ਵਿੱਚ ਹਰ provider ਲਈ `providerRegistry.ts` ਵਿੱਚ ਇੱਕ ਮੇਲ ਖਾਂਦੀ ਐਂਟਰੀ ਮੌਜੂਦ ਹੈ (ਅਤੇ ਇਸਦੇ ਉਲਟ ਵੀ, allowlist ਦੇ ਅੰਦਰ) | ਹਾਂ | -| `check:model-lifecycle` | ਹੱਥੀਂ ਸੰਭਾਲੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਤਿੰਨ routing tables, checked-in lifecycle snapshot (#11503) ਨਾਲ ਇਕਸਾਰ ਰਹਿੰਦੀਆਂ ਹਨ: `FITNESS_TABLE` (`taskFitness.ts`) ਕਿਸੇ ਵੀ ਅਜਿਹੀ retired id ਨੂੰ ਸਕੋਰ ਨਹੀਂ ਕਰਦੀ ਜਿਸ ਨੂੰ `REGISTRY` route ਕਰ ਸਕਦੀ ਹੈ; ਹਰ `BUILT_IN_ALIASES` target `REGISTRY` ਵਿੱਚ ਮੌਜੂਦ ਹੈ ਅਤੇ retired-id snapshot ਵਿੱਚ ਗੈਰਹਾਜ਼ਰ ਹੈ; `REGISTRY` ਵਿੱਚ ਅਜੇ ਵੀ ਮੌਜੂਦ ਹਰ retired id ਨੂੰ forward ਕੀਤਾ ਗਿਆ ਹੈ ਜਾਂ `allowedRetiredInCatalog` ਵਿੱਚ ਸੂਚੀਬੱਧ ਕੀਤਾ ਗਿਆ ਹੈ; ਅਤੇ ਕੋਈ ਵੀ `DEFAULT_DEGRADATION_MAP` source ਜਾਂ target ਉਸ snapshot ਵਿੱਚ retired ਵਜੋਂ ਨਹੀਂ ਦਿਸਦਾ। ਇਹ ਸਾਬਤ ਨਹੀਂ ਕਰਦਾ ਕਿ ਕੋਈ model ਇਸ ਵੇਲੇ live upstream ਵੱਲੋਂ serve ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ। Offline — `config/quality/model-lifecycle.json` ਨਾਲ ਤੁਲਨਾ ਕਰਦਾ ਹੈ, ਜਿਸਨੂੰ `npm run quality:refresh-model-lifecycle` ਨਾਲ ਹੱਥੀਂ refresh ਕੀਤਾ ਜਾਂਦਾ ਹੈ (network; CI ਨਾਲ ਜੋੜਿਆ ਨਹੀਂ ਗਿਆ)। `allowedRetiredInCatalog` ਇੱਕ burn-down ratchet ਹੈ: ਕੋਈ ਐਂਟਰੀ ਸਿਰਫ਼ tracking issue ਦੇ ਨਾਲ ਹੀ ਸ਼ਾਮਲ ਕਰੋ। | ਹਾਂ | -| `check:fetch-targets` | client-side `src/` ਵਿੱਚ ਹਰ `fetch("/api/...")` ਇੱਕ ਅਸਲ `route.ts` ਵੱਲ resolve ਹੁੰਦਾ ਹੈ | ਹਾਂ | -| `check:deps` | repo ਵਿੱਚ ਹਰ `package.json` ਦੇ ਸਾਰੇ `npm install`-ਯੋਗ deps `dependency-allowlist.json` ਵਿੱਚ ਹਨ; ਨਵੇਂ unpinned ਜਾਂ slopsquatted packages ਨੂੰ flag ਕੀਤਾ ਜਾਂਦਾ ਹੈ | ਹਾਂ | -| `audit:deps` | `npm audit` (root + electron) — ਕੋਈ high/critical advisory ਨਹੀਂ (`check:vuln-ratchet` osv ਨਾਲ overlap ਕਰਦਾ ਹੈ; Rationalization Backlog ਵੇਖੋ) | ਹਾਂ | -| `check:lockfile` | `package-lock.json` ਦੀ integrity — https registry, integrity hashes, ਕੋਈ host override ਨਹੀਂ | ਹਾਂ | -| `check:licenses` | ਉਤਪਾਦਨ ਨਿਰਭਰਤਾਵਾਂ ਲਈ SPDX ਲਾਇਸੈਂਸ ਮਨਜ਼ੂਰਸ਼ੁਦਾ-ਸੂਚੀ | ਹਾਂ | -| `check:tracked-artifacts` | ਕੋਈ ਬਿਲਡ ਆਰਟੀਫੈਕਟ / ਕਮਿਟ ਕੀਤੇ `node_modules` ਸਿੰਬੋਲਿਕ ਲਿੰਕ ਨਹੀਂ (husky pre-commit ਵਿੱਚ ਵੀ ਚੱਲਦਾ ਹੈ; pre-push ਜਾਣਬੁੱਝ ਕੇ ਹਲਕਾ ਰੱਖਿਆ ਗਿਆ ਹੈ — #6716) | ਹਾਂ | -| `check:ai-attribution` | PR ਕਮਿਟਾਂ, ਸਿਰਲੇਖ ਜਾਂ ਮੁੱਖ ਸਮੱਗਰੀ ਵਿੱਚ ਕੋਈ AI/bot `Co-Authored-By` ਟ੍ਰੇਲਰ ਜਾਂ AI-ਜਨਰੇਸ਼ਨ ਫੁੱਟਰ ਨਹੀਂ — ਸਖ਼ਤ ਨਿਯਮ #16 (`quality.yml` ਦੇ PR→`release/**` ਲਈ fast-gates ਲੂਪ ਵਿੱਚ — ਇਵੈਂਟ ਪੇਲੋਡ ਪੜ੍ਹਦਾ ਹੈ, PR ਨਾ ਹੋਣ 'ਤੇ ਕੁਝ ਨਹੀਂ ਕਰਦਾ — ਅਤੇ `ci.yml` lint ਵਿੱਚ PR→`main` ਲਈ ਕੇਵਲ-PR ਪੜਾਅ; ਨਾਲ ਹੀ husky `commit-msg` ਹੁੱਕ; ਮਨੁੱਖੀ ਸਹਿ-ਲੇਖਕ ਮਨਜ਼ੂਰ ਹਨ; #14436) | -| `check:vitest-exclusions` | ਹਰ Vitest ਅਪਵਾਦ ਵਿੱਚ ਇੱਕ ਟ੍ਰੈਕਿੰਗ ਇਸ਼ੂ ਦਾ ਨਾਮ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਅਤੇ ਉਹ `config/quality/vitest-exclusions.json` ਵਿੱਚ ਮੌਜੂਦ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ (#13204) | ਹਾਂ | -| `check:file-size` | ਕੋਈ ਵੀ ਸਰੋਤ ਫ਼ਾਈਲ ਪ੍ਰਤੀ-ਐਕਸਟੈਂਸ਼ਨ ਸੀਮਾ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੁੰਦੀ (ਰੈਚਟ: `frozen` ਸੂਚੀ ਵਿੱਚ ਫ੍ਰੀਜ਼ ਕੀਤੀਆਂ ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ) | ਹਾਂ | -| `check:error-helper` | ਐਗਜ਼ਿਕਿਊਟਰਾਂ/ਹੈਂਡਲਰਾਂ ਵਿੱਚ ਤਰੁੱਟੀ ਜਵਾਬ `buildErrorBody()` / `sanitizeErrorMessage()` ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #12) | ਹਾਂ | -| `check:migration-numbering` | Migration SQL ਫਾਈਲਾਂ ਨੂੰ ਬਿਨਾਂ ਕਿਸੇ ਖਾਲੀ ਥਾਂ ਜਾਂ ਡੁਪਲੀਕੇਟ ਦੇ ਕ੍ਰਮਵਾਰ ਨੰਬਰ ਦਿੱਤੇ ਗਏ ਹਨ | ਹਾਂ | -| `check:public-creds` | `publicCreds.ts` ਤੋਂ ਬਾਹਰ ਕੋਈ ਵੀ ਸਿੱਧਾ ਲਿਖਿਆ OAuth `client_id`/`client_secret` ਜਾਂ Firebase Web ਕੁੰਜੀਆਂ ਨਹੀਂ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #11) | ਹਾਂ | -| `check:db-rules` | `src/lib/db/` ਮੋਡੀਊਲਾਂ ਤੋਂ ਬਾਹਰ ਕੋਈ ਕੱਚਾ SQL ਨਹੀਂ ਹੈ; `localDb.ts` ਤੋਂ ਕੋਈ barrel-imports ਨਹੀਂ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #2/#5) | ਹਾਂ | -| `check:known-symbols` | ਆਪਣੀਆਂ dispatch ਟੇਬਲਾਂ ਵਿੱਚ ਰਜਿਸਟਰ ਕੀਤੇ provider executors, routing strategies ਅਤੇ translators ਡਿਸਕ ਉੱਤੇ ਮੌਜੂਦ ਫਾਈਲਾਂ ਨਾਲ ਮੇਲ ਖਾਂਦੇ ਹਨ—ਕੋਈ ਅਨਾਥ ਜਾਂ ਅਣ-ਐਲਾਨੇ symbols ਨਹੀਂ ਹਨ | ਹਾਂ | -| `check:route-guard-membership` | child process ਸ਼ੁਰੂ ਕਰਨ ਵਾਲਾ ਹਰੇਕ route, `isLocalOnlyPath()` ਦੁਆਰਾ ਵਰਗੀਕ੍ਰਿਤ ਹੈ (ਸਖ਼ਤ ਨਿਯਮ #15/#17) | ਹਾਂ | -| `check:test-discovery` | ਰਿਪੋ ਵਿੱਚ ਹਰੇਕ `*.test.ts` / `*.spec.ts` ਫਾਈਲ ਨੂੰ ਘੱਟੋ-ਘੱਟ ਇੱਕ test runner ਦੁਆਰਾ ਇਕੱਠਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ (ratchet: `test-discovery-baseline.json` ਵਿੱਚ orphan ਸੂਚੀ ਸਿਰਫ਼ ਛੋਟੀ ਹੋ ਸਕਦੀ ਹੈ) | ਹਾਂ | -| `check:agent-skills-sync` | ਬਣਾਏ ਗਏ agent-skills ਆਰਟੀਫੈਕਟ ਆਪਣੇ ਸਰੋਤ ਕੈਟਾਲਾਗ ਨਾਲ ਮੇਲ ਖਾਂਦੇ ਹਨ (ਕੋਈ ਅੰਤਰ ਨਹੀਂ) | -| `check:provider-asset-provenance` | ਪ੍ਰਦਾਤਾ ਦੇ ਲੋਗੋ/ਐਸੈੱਟਾਂ ਲਈ ਦਰਜ ਕੀਤਾ ਗਿਆ ਮੂਲ-ਸਰੋਤ ਰਿਕਾਰਡ ਮੌਜੂਦ ਹੈ | -| `lint:json` | JSON ਕਨਫਿਗ ਫਾਈਲਾਂ ਸਹੀ ਢੰਗ ਨਾਲ ਪਾਰਸ ਹੁੰਦੀਆਂ ਹਨ ਅਤੇ ਰਿਪੋ ਦੇ lint ਨਿਯਮਾਂ ਦੀ ਪਾਲਣਾ ਕਰਦੀਆਂ ਹਨ | -| `typecheck:core` | ਬਿਨਾਂ ਤਰੁੱਟੀਆਂ ਦੇ TypeScript ਕੰਪਾਇਲੇਸ਼ਨ (ਕੇਵਲ ਸਲਾਹਕਾਰੀ ਚੇਤਾਵਨੀਆਂ) | ਹਾਂ | -| `typecheck:noimplicit:core` | ਸਖ਼ਤ `noImplicitAny` — ਭਵਿੱਖ-ਕੇਂਦਰਿਤ; ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਕਈ ਕਾਲ ਸਾਈਟਾਂ ਨੂੰ ਹਾਲੇ ਵੀ ਐਨੋਟੇਸ਼ਨਾਂ ਦੀ ਲੋੜ ਹੈ | **ਸਲਾਹਕਾਰੀ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ਨੂੰ `src/app/(dashboard)/**` ਤੱਕ ਸੀਮਿਤ ਕੀਤਾ ਗਿਆ ਹੈ (#7033) — `typecheck:core` ਦੀ ਸੋਚ-ਸਮਝ ਕੇ ਚੁਣੀ 27-ਫਾਈਲਾਂ ਵਾਲੀ allowlist ਵਿੱਚ ਕੋਈ ਵੀ dashboard TSX ਸ਼ਾਮਲ ਨਹੀਂ ਹੈ, ਅਤੇ `next build` ਵੀ ਕਦੇ ਇਸ ਦੀ type-checking ਨਹੀਂ ਕਰਦਾ (`next.config.mjs` ਵਿੱਚ `ignoreBuildErrors: true` ਸੈੱਟ ਹੈ), ਇਸ ਲਈ ਉੱਥੇ orphaned-identifier ਰਿਗ੍ਰੈਸ਼ਨ (#6625/#6909) CI ਲਈ ਅਦਿੱਖ ਸਨ। ਇੱਕ ਸਥਿਰ ਕੀਤੀ ਪ੍ਰਤੀ-ਫਾਈਲ/ਪ੍ਰਤੀ-TS-code ਗਿਣਤੀ ਬੇਸਲਾਈਨ (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ਵਰਗਾ ਹੀ stale-enforcement ਪੈਟਰਨ) ਦੇ ਮੁਕਾਬਲੇ ਅੰਤਰ ਜਾਂਚੇ ਜਾਂਦੇ ਹਨ — ਬੇਸਲਾਈਨ ਕੀਤੀ ਗਿਣਤੀ ਤੋਂ ਵੱਧ ਕੇਵਲ ਨਵੀਆਂ ਤਰੁੱਟੀਆਂ ਹੀ ਗੇਟ ਨੂੰ ਅਸਫਲ ਕਰਦੀਆਂ ਹਨ; ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਤਰੁੱਟੀ ਠੀਕ ਹੋਣ 'ਤੇ `--update` ਨਾਲ ਬੇਸਲਾਈਨ ਘਟਾਓ। | ਹਾਂ | - -### ਜੌਬ: `quality-gate` +`main` ਲਈ ਹਰ PR ਉੱਤੇ ਚੱਲਦਾ ਹੈ। ਅਸਫਲ ਹੋਣ 'ਤੇ merge ਨੂੰ ਰੋਕਦਾ ਹੈ। -`test-coverage` ਤੋਂ ਬਾਅਦ ਚੱਲਦੀ ਹੈ। ਅਸਫਲਤਾ ਹੋਣ 'ਤੇ ਮਰਜ ਨੂੰ ਰੋਕਦੀ ਹੈ। - -| ਸਕ੍ਰਿਪਟ | ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਰੋਕਣ ਵਾਲੀ | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | `quality-metrics.json` ਬਣਾਉਂਦੀ ਹੈ (ESLint ਚੇਤਾਵਨੀਆਂ ਦੀ ਗਿਣਤੀ, ਮਿਲਾਈ ਗਈ shard ਰਿਪੋਰਟ ਤੋਂ coverage) | ਹਾਂ (ratchet ਤੋਂ ਪਹਿਲਾਂ) | -| `quality:ratchet` | `quality-baseline.json` ਵਿੱਚ ਹਰ metric ਪਿੱਛੇ ਨਹੀਂ ਗਈ ਹੈ (ESLint ਚੇਤਾਵਨੀਆਂ ≤ baseline; coverage ≥ baseline) | ਹਾਂ | -| `check:duplication` | ਕੋਡ ਦੀ duplication (jscpd@4), `quality-baseline.json` ਵਿੱਚ baseline ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ | ਹਾਂ | -| `check:complexity` | ਫ਼ਾਈਲ-ਪੱਧਰੀ cyclomatic complexity ਨਿਰਧਾਰਤ ਸੀਮਾ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ (ਮੁੱਖ ESLint `complexity` + `max-lines-per-function`) | ਹਾਂ | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — ਵੱਖਰਾ ESLint ਪਾਸ; CI ਦੋਵਾਂ ਨੂੰ ਇਕੱਲੇ `check:complexity-ratchets` ਪੜਾਅ ਵਜੋਂ ਮਿਲਾ ਕੇ ਚਲਾਉਂਦਾ ਹੈ | ਹਾਂ | -| `check:dead-code` | ਨਾ ਵਰਤੇ ਗਏ exports / ਫ਼ਾਈਲਾਂ ਦਾ ratchet (knip), baseline ਦੇ ਮੁਕਾਬਲੇ ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦਾ | ਹਾਂ | -| `check:compression-budget` | Compression benchmark ਬਜਟ — ਹਰ engine ਲਈ token-savings ਦੀਆਂ ਘੱਟੋ-ਘੱਟ ਹੱਦਾਂ ਪਿੱਛੇ ਨਹੀਂ ਜਾਣੀਆਂ ਚਾਹੀਦੀਆਂ | ਹਾਂ | -| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦਾ; ਵੱਡੇ ਪੱਧਰ 'ਤੇ `typecheck:noimplicit:core` ਨੂੰ ਆਪਣੇ ਅਧੀਨ ਲੈਂਦਾ ਹੈ | ਹਾਂ | -| `check:codeql-ratchet` | ਖੁੱਲ੍ਹੀਆਂ CodeQL ਚੇਤਾਵਨੀਆਂ ਦੀ ਗਿਣਤੀ ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦੀ (`gh api` ਰਾਹੀਂ ਪੜ੍ਹਦਾ ਹੈ; token ਤੋਂ ਬਿਨਾਂ ਸੁਚੱਜੇ ਢੰਗ ਨਾਲ ਛੱਡ ਦਿੰਦਾ ਹੈ) — refresh cadence ਅਤੇ manual trigger: ਹੇਠਾਂ "CodeQL ratchet" ਵੇਖੋ | ਹਾਂ | - -### Job: `quality-extended` - -ਪੂਰਾ job ਸਲਾਹਕਾਰੀ ਹੈ (`continue-on-error: true`)। npm-ਅਧਾਰਿਤ ratchets ਅਸਲ ਵਿੱਚ -ਚੱਲਦੇ ਹਨ; ਬਾਹਰੀ scanners `gh release download` ਰਾਹੀਂ install ਹੁੰਦੇ ਹਨ ਅਤੇ ਜਦੋਂ -binary ਹਾਲੇ ਵੀ ਮੌਜੂਦ ਨਾ ਹੋਵੇ ਤਾਂ ਆਪਣੇ ਆਪ ਛੱਡ ਦਿੰਦੇ ਹਨ (exit 0)। - -| ਸਕ੍ਰਿਪਟ | ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਰੋਕਣ ਵਾਲੀ | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -| `check:circular-deps` | ਕੋਈ circular dependencies ਨਹੀਂ ਹਨ (dpdm) | **ਸਲਾਹਕਾਰੀ** | -| `check:bundle-size` | Bundle ਦਾ ਆਕਾਰ ਨਿਰਧਾਰਤ ਸੀਮਾ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ | **ਸਲਾਹਕਾਰੀ** | -| `check:secrets` | Secret scanning (gitleaks) — binary ਮੌਜੂਦ ਨਾ ਹੋਣ 'ਤੇ ਛੱਡ ਦਿੰਦੀ ਹੈ | **ਸਲਾਹਕਾਰੀ** | -| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦੀਆਂ — binary ਮੌਜੂਦ ਨਾ ਹੋਣ 'ਤੇ ਛੱਡ ਦਿੰਦੀ ਹੈ | **ਸਲਾਹਕਾਰੀ** | -| `check:workflows` | Workflow lint (actionlint + zizmor); ਗੁੰਮ/ਖ਼ਰਾਬ scanners, ਅਵੈਧ reports ਜਾਂ ਗੁੰਮ ratchet baseline ਨੂੰ INCOMPLETE ਵਜੋਂ ਅਸਫਲ ਕਰਦੇ ਹਨ। ਵੈਧ findings ਚੁਣੀ ਗਈ strict/advisory/ratchet policy ਦੀ ਪਾਲਣਾ ਕਰਦੀਆਂ ਹਨ | ਕਾਰਵਾਈ ਲਾਜ਼ਮੀ; CI ਵਿੱਚ zizmor ratchet ਰੋਕਣ ਵਾਲਾ ਹੈ | -| `check:openapi-breaking` | ਮੂਲ branch ਦੇ ਮੁਕਾਬਲੇ ਜਨਤਕ API contract (`openapi.yaml`) ਵਿੱਚ breaking changes (oasdiff) — `openapiBreaking=N` ਜਾਰੀ ਕਰਦਾ ਹੈ; oasdiff ਮੌਜੂਦ ਨਾ ਹੋਣ ਜਾਂ ਮੂਲ spec resolve ਨਾ ਹੋਣ 'ਤੇ ਛੱਡ ਦਿੰਦਾ ਹੈ | **ਸਲਾਹਕਾਰੀ** | - -### Job: `docs-sync-strict` +| Script (`npm run ...`) | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦਾ ਹੈ | Blocking | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `check:node-runtime` | Node.js version ਸਮਰਥਿਤ range ਦੇ ਅੰਦਰ ਹੈ | ਹਾਂ | +| `check:cycles` | ਪੂਰੇ `src/` + `open-sse/` ਵਿੱਚ circular imports (AST-ਅਧਾਰਿਤ, tsconfig `paths` resolve ਕੀਤੇ ਹੋਏ)। Bare = advisory, cycles ਦੀ ਸੂਚੀ ਦਿੰਦਾ ਹੈ। `check:cycles:ratchet` (ਜੋ CI ਚਲਾਉਂਦਾ ਹੈ) ਉਸ ਵੇਲੇ block ਕਰਦਾ ਹੈ ਜਦੋਂ ਗਿਣਤੀ `quality-baseline.json` ਵਿੱਚ `metrics.cycles` ceiling ਤੋਂ ਵੱਧ ਜਾਂਦੀ ਹੈ — ਇਸ ਵੇਲੇ 14, `direction: down`, ਇਸ ਲਈ ਇਹ ਸਿਰਫ਼ ਘਟ ਸਕਦੀ ਹੈ (#15159 G-01/G-02) | ਹਾਂ (ratchet) | +| `check:route-validation:t06` | ਸਾਰੇ routes ਉੱਤੇ Zod schemas ਮੌਜੂਦ ਹਨ (Tier 6 policy) | ਹਾਂ | +| `check:any-budget:t11` | `@ts-expect-error // any` ਦੀ ਗਿਣਤੀ budget ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ (Tier 11 catraca) | ਹਾਂ | +| `check:provider-consistency` | `providers.ts` ਵਿੱਚ ਹਰ ਪ੍ਰੋਵਾਈਡਰ ਦੀ `providerRegistry.ts` ਵਿੱਚ ਇੱਕ ਮੇਲ ਖਾਂਦੀ ਐਂਟਰੀ ਹੈ (ਅਤੇ allowlist ਦੇ ਅੰਦਰ ਇਸਦੇ ਉਲਟ ਵੀ) | ਹਾਂ | +| `check:model-lifecycle` | ਹੱਥੀਂ ਸੰਭਾਲੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਤਿੰਨ ਰਾਊਟਿੰਗ ਟੇਬਲਾਂ ਚੈੱਕ-ਇਨ ਕੀਤੇ ਲਾਈਫਸਾਈਕਲ ਸਨੈਪਸ਼ਾਟ (#11503) ਨਾਲ ਇਕਸਾਰ ਰਹਿੰਦੀਆਂ ਹਨ: `FITNESS_TABLE` (`taskFitness.ts`) ਕਿਸੇ ਅਜਿਹੀ ਰਿਟਾਇਰਡ id ਨੂੰ ਸਕੋਰ ਨਹੀਂ ਕਰਦੀ ਜਿਸਨੂੰ `REGISTRY` ਰਾਊਟ ਕਰ ਸਕਦੀ ਹੈ; ਹਰ `BUILT_IN_ALIASES` ਟਾਰਗੇਟ `REGISTRY` ਵਿੱਚ ਮੌਜੂਦ ਅਤੇ ਰਿਟਾਇਰਡ-id ਸਨੈਪਸ਼ਾਟ ਤੋਂ ਗੈਰਹਾਜ਼ਰ ਹੈ; `REGISTRY` ਵਿੱਚ ਅਜੇ ਵੀ ਮੌਜੂਦ ਹਰ ਰਿਟਾਇਰਡ id ਨੂੰ ਫਾਰਵਰਡ ਕੀਤਾ ਗਿਆ ਹੈ ਜਾਂ `allowedRetiredInCatalog` ਵਿੱਚ ਸੂਚੀਬੱਧ ਕੀਤਾ ਗਿਆ ਹੈ; ਅਤੇ ਕੋਈ ਵੀ `DEFAULT_DEGRADATION_MAP` ਸਰੋਤ ਜਾਂ ਟਾਰਗੇਟ ਉਸ ਸਨੈਪਸ਼ਾਟ ਵਿੱਚ ਰਿਟਾਇਰਡ ਵਜੋਂ ਨਹੀਂ ਦਿਸਦਾ। ਇਹ ਸਾਬਤ ਨਹੀਂ ਕਰਦਾ ਕਿ ਕੋਈ ਮਾਡਲ ਇਸ ਵੇਲੇ ਕਿਸੇ ਲਾਈਵ ਅੱਪਸਟ੍ਰੀਮ ਵੱਲੋਂ ਸਰਵ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ। ਆਫਲਾਈਨ — `config/quality/model-lifecycle.json` ਨਾਲ ਤੁਲਨਾ ਕਰਦਾ ਹੈ, ਜਿਸਨੂੰ `npm run quality:refresh-model-lifecycle` (ਨੈੱਟਵਰਕ; CI ਨਾਲ ਜੋੜਿਆ ਨਹੀਂ ਗਿਆ) ਰਾਹੀਂ ਹੱਥੀਂ ਰਿਫ੍ਰੈਸ਼ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। `allowedRetiredInCatalog` ਇੱਕ ਬਰਨ-ਡਾਊਨ ਰੈਚਟ ਹੈ: ਕੋਈ ਐਂਟਰੀ ਸਿਰਫ਼ ਟ੍ਰੈਕਿੰਗ ਇਸ਼ੂ ਦੇ ਨਾਲ ਹੀ ਸ਼ਾਮਲ ਕਰੋ। | ਹਾਂ | +| `check:fetch-targets` | ਕਲਾਇੰਟ-ਸਾਈਡ `src/` ਵਿੱਚ ਹਰ `fetch("/api/...")` ਇੱਕ ਅਸਲ `route.ts` ਤੱਕ ਰਿਜ਼ਾਲਵ ਹੁੰਦਾ ਹੈ | ਹਾਂ | +| `check:deps` | ਰਿਪੋ ਵਿੱਚ ਹਰ `package.json` ਦੀਆਂ ਸਾਰੀਆਂ `npm install`-ਯੋਗ ਡਿਪੈਂਡੈਂਸੀਆਂ `dependency-allowlist.json` ਵਿੱਚ ਹਨ; ਨਵੇਂ ਅਨਪਿੰਨ ਜਾਂ slopsquatted ਪੈਕੇਜ ਫਲੈਗ ਕੀਤੇ ਜਾਂਦੇ ਹਨ | ਹਾਂ | +| `audit:deps` | `npm audit` (ਰੂਟ + electron) — ਕੋਈ ਉੱਚ/ਨਾਜ਼ੁਕ ਐਡਵਾਈਜ਼ਰੀ ਨਹੀਂ (osv `check:vuln-ratchet` ਨਾਲ ਓਵਰਲੈਪ ਕਰਦਾ ਹੈ; Rationalization Backlog ਵੇਖੋ) | ਹਾਂ | +| `check:lockfile` | `package-lock.json` ਦੀ ਅਖੰਡਤਾ — https ਰਜਿਸਟਰੀ, ਅਖੰਡਤਾ ਹੈਸ਼, ਕੋਈ ਹੋਸਟ ਓਵਰਰਾਈਡ ਨਹੀਂ | ਹਾਂ | +| `check:licenses` | ਪ੍ਰੋਡਕਸ਼ਨ ਡਿਪੈਂਡੈਂਸੀਜ਼ ਲਈ SPDX ਲਾਇਸੈਂਸ ਅਨੁਮਤੀ-ਸੂਚੀ | ਹਾਂ | +| `check:tracked-artifacts` | ਕੋਈ ਬਿਲਡ ਆਰਟੀਫੈਕਟ / ਕਮਿਟ ਕੀਤੇ `node_modules` ਸਿਮਲਿੰਕ ਨਹੀਂ (husky pre-commit ਵਿੱਚ ਵੀ ਚੱਲਦਾ ਹੈ; pre-push ਨੂੰ ਜਾਣ-ਬੁੱਝ ਕੇ ਹਲਕਾ ਰੱਖਿਆ ਗਿਆ ਹੈ — #6716) | ਹਾਂ | +| `check:ai-attribution` | PR ਕਮਿਟਾਂ, ਸਿਰਲੇਖ ਜਾਂ ਮੁੱਖ ਭਾਗ ਵਿੱਚ ਕੋਈ AI/bot `Co-Authored-By` ਟ੍ਰੇਲਰ ਜਾਂ AI-ਜਨਰੇਸ਼ਨ ਫੁੱਟਰ ਨਹੀਂ — ਸਖ਼ਤ ਨਿਯਮ #16 (`quality.yml` ਦੇ PR→`release/**` ਲਈ fast-gates ਲੂਪ ਵਿੱਚ — ਇਵੈਂਟ ਪੇਲੋਡ ਪੜ੍ਹਦਾ ਹੈ, PR ਨਾ ਹੋਣ 'ਤੇ ਕੋਈ ਕਾਰਵਾਈ ਨਹੀਂ ਕਰਦਾ — ਅਤੇ PR→`main` ਲਈ `ci.yml` lint ਵਿੱਚ ਸਿਰਫ਼-PR ਪੜਾਅ; husky `commit-msg` ਹੁੱਕ ਵੀ; ਮਨੁੱਖੀ ਸਹਿ-ਲੇਖਕਾਂ ਦੀ ਆਗਿਆ ਹੈ; #14436) | +| `check:vitest-exclusions` | ਹਰ Vitest ਅਪਵਾਦ ਇੱਕ ਟ੍ਰੈਕਿੰਗ ਇਸ਼ੂ ਦਾ ਨਾਮ ਦਿੰਦਾ ਹੈ ਅਤੇ `config/quality/vitest-exclusions.json` ਵਿੱਚ ਮੌਜੂਦ ਹੁੰਦਾ ਹੈ (#13204) | ਹਾਂ | +| `check:file-size` | ਕੋਈ ਵੀ ਸਰੋਤ ਫ਼ਾਈਲ ਪ੍ਰਤੀ-ਐਕਸਟੈਂਸ਼ਨ ਸੀਮਾ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੁੰਦੀ (ਰੈਚਟ: `frozen` ਸੂਚੀ ਵਿੱਚ ਫ੍ਰੀਜ਼ ਕੀਤੀਆਂ ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ) | ਹਾਂ | +| `check:error-helper` | executors/handlers ਵਿੱਚ ਗਲਤੀ ਜਵਾਬ `buildErrorBody()` / `sanitizeErrorMessage()` ਵਰਤਦੇ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #12) | ਹਾਂ | +| `check:migration-numbering` | Migration SQL ਫਾਈਲਾਂ ਨੂੰ ਬਿਨਾਂ ਕਿਸੇ ਖਾਲੀ ਥਾਂ ਜਾਂ ਦੁਹਰਾਅ ਦੇ ਲੜੀਵਾਰ ਨੰਬਰ ਦਿੱਤੇ ਗਏ ਹਨ | ਹਾਂ | +| `check:public-creds` | `publicCreds.ts` ਤੋਂ ਬਾਹਰ ਕੋਈ ਵੀ ਸ਼ਾਬਦਿਕ OAuth `client_id`/`client_secret` ਜਾਂ Firebase Web ਕੁੰਜੀਆਂ ਨਹੀਂ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #11) | ਹਾਂ | +| `check:db-rules` | `src/lib/db/` ਮੋਡੀਊਲਾਂ ਤੋਂ ਬਾਹਰ ਕੋਈ ਕੱਚਾ SQL ਨਹੀਂ; `localDb.ts` ਤੋਂ ਕੋਈ ਬੈਰਲ-ਇੰਪੋਰਟ ਨਹੀਂ (ਸਖ਼ਤ ਨਿਯਮ #2/#5) | ਹਾਂ | +| `check:known-symbols` | ਆਪਣੀਆਂ ਡਿਸਪੈਚ ਟੇਬਲਾਂ ਵਿੱਚ ਰਜਿਸਟਰ ਕੀਤੇ ਪ੍ਰੋਵਾਈਡਰ ਐਗਜ਼ੀਕਿਊਟਰ, ਰਾਊਟਿੰਗ ਰਣਨੀਤੀਆਂ ਅਤੇ ਅਨੁਵਾਦਕ ਡਿਸਕ ਉੱਤੇ ਮੌਜੂਦ ਫਾਈਲਾਂ ਨਾਲ ਮੇਲ ਖਾਂਦੇ ਹਨ — ਕੋਈ ਅਨਾਥ ਜਾਂ ਅਘੋਸ਼ਿਤ ਸਿੰਬਲ ਨਹੀਂ | ਹਾਂ | +| `check:route-guard-membership` | ਚਾਈਲਡ ਪ੍ਰੋਸੈੱਸ ਸ਼ੁਰੂ ਕਰਨ ਵਾਲੇ ਹਰ ਰੂਟ ਨੂੰ `isLocalOnlyPath()` ਦੁਆਰਾ ਵਰਗੀਕ੍ਰਿਤ ਕੀਤਾ ਗਿਆ ਹੈ (ਸਖ਼ਤ ਨਿਯਮ #15/#17) | ਹਾਂ | +| `check:test-discovery` | ਰੈਪੋ ਵਿੱਚ ਹਰ `*.test.ts` / `*.spec.ts` ਫਾਈਲ ਨੂੰ ਘੱਟੋ-ਘੱਟ ਇੱਕ ਟੈਸਟ ਰਨਰ ਦੁਆਰਾ ਇਕੱਠਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ (ਰੈਚਟ: `test-discovery-baseline.json` ਵਿੱਚ ਅਨਾਥ ਸੂਚੀ ਸਿਰਫ਼ ਘੱਟ ਸਕਦੀ ਹੈ) | ਹਾਂ | +| `check:agent-skills-sync` | ਬਣਾਏ ਗਏ agent-skills ਆਰਟੀਫੈਕਟ ਆਪਣੇ ਸਰੋਤ ਕੈਟਾਲਾਗ ਨਾਲ ਮੇਲ ਖਾਂਦੇ ਹਨ (ਕੋਈ ਅੰਤਰ ਨਹੀਂ) | +| `check:provider-asset-provenance` | ਪ੍ਰਦਾਤਾ ਦੇ ਲੋਗੋ/ਐਸੈੱਟਾਂ ਨਾਲ ਦਰਜ ਕੀਤਾ ਗਿਆ ਸਰੋਤ-ਵੇਰਵਾ ਜੁੜਿਆ ਹੁੰਦਾ ਹੈ | +| `lint:json` | JSON ਸੰਰਚਨਾ ਫ਼ਾਈਲਾਂ ਪਾਰਸ ਹੁੰਦੀਆਂ ਹਨ ਅਤੇ ਰਿਪੋਜ਼ਟਰੀ ਦੇ lint ਨਿਯਮਾਂ ਨੂੰ ਪੂਰਾ ਕਰਦੀਆਂ ਹਨ | +| `typecheck:core` | ਬਿਨਾਂ ਗਲਤੀਆਂ ਦੇ TypeScript ਕੰਪਾਇਲੇਸ਼ਨ (ਸਿਰਫ਼ ਸਲਾਹਕਾਰੀ ਚੇਤਾਵਨੀਆਂ) | ਹਾਂ | +| `typecheck:noimplicit:core` | ਸਖ਼ਤ `noImplicitAny` — ਭਵਿੱਖ-ਕੇਂਦਰਿਤ; ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਕਈ ਕਾਲ ਸਾਈਟਾਂ ਨੂੰ ਹਾਲੇ ਵੀ ਐਨੋਟੇਸ਼ਨਾਂ ਦੀ ਲੋੜ ਹੈ | **ਸਲਾਹਕਾਰੀ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ਦਾ ਦਾਇਰਾ `src/app/(dashboard)/**` ਤੱਕ ਸੀਮਿਤ ਹੈ (#7033) — `typecheck:core` ਦੀ ਚੁਣੀ ਹੋਈ 27-ਫ਼ਾਈਲਾਂ ਦੀ ਮਨਜ਼ੂਰ-ਸੂਚੀ ਵਿੱਚ ਕੋਈ ਵੀ ਡੈਸ਼ਬੋਰਡ TSX ਸ਼ਾਮਲ ਨਹੀਂ ਹੈ, ਅਤੇ `next build` ਵੀ ਕਦੇ ਇਸ ਦੀ ਟਾਈਪ-ਜਾਂਚ ਨਹੀਂ ਕਰਦਾ (`next.config.mjs` ਵਿੱਚ `ignoreBuildErrors: true` ਸੈੱਟ ਹੈ), ਇਸ ਲਈ ਉੱਥੇ orphaned-identifier ਰਿਗ੍ਰੈਸ਼ਨ (#6625/#6909) CI ਨੂੰ ਦਿਖਾਈ ਨਹੀਂ ਦਿੰਦੇ ਸਨ। ਇੱਕ ਸਥਿਰ ਕੀਤੀ ਪ੍ਰਤੀ-ਫ਼ਾਈਲ/ਪ੍ਰਤੀ-TS-ਕੋਡ ਗਿਣਤੀ ਬੇਸਲਾਈਨ (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ਵਾਂਗ ਹੀ stale-enforcement ਪੈਟਰਨ) ਨਾਲ ਅੰਤਰਾਂ ਦੀ ਤੁਲਨਾ ਕੀਤੀ ਜਾਂਦੀ ਹੈ — ਬੇਸਲਾਈਨ ਕੀਤੀ ਗਿਣਤੀ ਤੋਂ ਵੱਧ ਸਿਰਫ਼ ਨਵੀਆਂ ਗਲਤੀਆਂ ਹੀ ਗੇਟ ਨੂੰ ਅਸਫਲ ਕਰਦੀਆਂ ਹਨ; ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਗਲਤੀ ਠੀਕ ਹੋਣ 'ਤੇ `--update` ਨਾਲ ਬੇਸਲਾਈਨ ਘਟਾਓ। | ਹਾਂ | -`main` ਲਈ ਹਰ PR ਉੱਤੇ ਚੱਲਦਾ ਹੈ। ਅਸਫਲ ਹੋਣ 'ਤੇ merge ਨੂੰ ਰੋਕਦਾ ਹੈ। +### ਜੌਬ: `quality-gate` -| ਸਕ੍ਰਿਪਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਬਲੌਕਿੰਗ | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| `check:docs-all` | ਮੈਟਾ-ਗੇਟ ਜੋ ਹੇਠਾਂ ਦਿੱਤੇ 6 ਸਬ-ਗੇਟਾਂ ਨੂੰ ਕ੍ਰਮਵਾਰ ਚਲਾਉਂਦਾ ਹੈ | ਹਾਂ | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ਵਰਜਨ ਇਕਸਾਰਤਾ | ਹਾਂ | -| ↳ `check:docs-counts` | ਗੱਦ ਵਿੱਚ ਦਿੱਤੀਆਂ ਗਿਣਤੀਆਂ (ਪ੍ਰਦਾਤਾ ਗਿਣਤੀ, ਮਾਈਗ੍ਰੇਸ਼ਨ ਗਿਣਤੀ, ਆਦਿ) ਅਸਲ ਗਿਣਤੀਆਂ ਦੀ ਰੈਚਿਟ ਵਿੰਡੋ ਦੇ ਅੰਦਰ ਹਨ | ਹਾਂ | -| ↳ `check:env-doc-sync` | `.env.example` ਵਿੱਚ ਹਰ env var ਕਿਸੇ ਦਸਤਾਵੇਜ਼ੀ ਸਾਰਣੀ ਵਿੱਚ ਦਰਜ ਹੈ, ਅਤੇ ਇਸਦੇ ਉਲਟ ਵੀ | ਹਾਂ | -| ↳ `check:deprecated-versions` | ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਕੋਈ ਬਰਖ਼ਾਸਤ ਵਰਜਨ ਸਟਰਿੰਗ ਨਹੀਂ ਹੈ | ਹਾਂ | -| ↳ `check:doc-links` | ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਅੰਦਰੂਨੀ markdown ਲਿੰਕ ਅਸਲ ਫ਼ਾਈਲਾਂ ਵੱਲ ਜਾਂਦੇ ਹਨ (`[text]`/`(path)` ਰੂਪ) | ਹਾਂ | -| ↳ `check:fabricated-docs` | ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਦਰਸਾਏ ਰੂਟ, env vars, CLI ਕਮਾਂਡਾਂ, ਹੁੱਕ ਨਾਮ ਅਤੇ ਫ਼ਾਈਲ ਪਾਥ ਕੋਡਬੇਸ ਵਿੱਚ ਮੌਜੂਦ ਹਨ। `--strict` ਰਾਹੀਂ ਹਾਰਡ ਗੇਟ; ਫਲੈਗ ਤੋਂ ਬਿਨਾਂ ਸੌਫਟ-ਫੇਲ। | ਹਾਂ (CI ਵਿੱਚ `--strict` ਰਾਹੀਂ) | -| `check:cli-i18n` | CLI ਕਮਾਂਡ ਸਟਰਿੰਗਾਂ ਸਾਰੀਆਂ i18n ਲੋਕੇਲ ਫ਼ਾਈਲਾਂ ਵਿੱਚ ਮੌਜੂਦ ਹਨ | ਹਾਂ | -| `check:openapi-coverage` | OpenAPI ਸਪੈਕ ਅਸਲ ਰੂਟਾਂ ਦੀ ਘੱਟੋ-ਘੱਟ ਰੈਚਿਟ ਕੀਤੀ ਹੱਦ ਨੂੰ ਕਵਰ ਕਰਦਾ ਹੈ | ਹਾਂ | -| `check:openapi-security-tiers` | `openapi.yaml` ਵਿੱਚ ਸੁਰੱਖਿਆ ਟੀਅਰ ਐਨੋਟੇਸ਼ਨ `routeGuard.ts` ਵਰਗੀਕਰਨਾਂ ਨਾਲ ਇਕਸਾਰ ਹਨ | **ਸਲਾਹਕਾਰੀ** | -| `check:openapi-routes` | `openapi.yaml` ਵਿੱਚ ਹਰ ਪਾਥ ਕਿਸੇ ਅਸਲ `route.ts` ਵੱਲ ਜਾਂਦਾ ਹੈ (ਭਰਮ-ਰੋਕੂ) | ਹਾਂ | -| `check:docs-symbols` | `docs/**/*.md` ਵਿੱਚ ਹਰ `/api/...` ਹਵਾਲਾ ਕਿਸੇ ਅਸਲ `route.ts` ਵੱਲ ਜਾਂਦਾ ਹੈ (ਭਰਮ-ਰੋਕੂ) | ਹਾਂ | -| `i18n translation drift` | i18n ਲੋਕੇਲ ਫ਼ਾਈਲਾਂ ਵਿੱਚ ਅਨੁਵਾਦ ਨਾ ਕੀਤੀਆਂ ਕੁੰਜੀਆਂ — ਸਿਰਫ਼ ਚੇਤਾਵਨੀ | **ਸਲਾਹਕਾਰੀ** | +`test-coverage` ਤੋਂ ਬਾਅਦ ਚੱਲਦੀ ਹੈ। ਅਸਫਲ ਹੋਣ 'ਤੇ ਮਰਜ ਨੂੰ ਰੋਕਦੀ ਹੈ। + +| ਸਕ੍ਰਿਪਟ | ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਰੋਕਣ ਵਾਲੀ | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ | +| `quality:collect` | `quality-metrics.json` ਉਤਪੰਨ ਕਰਦੀ ਹੈ (ESLint ਚੇਤਾਵਨੀਆਂ ਦੀ ਗਿਣਤੀ, ਮਿਲਾਈ ਗਈ shard ਰਿਪੋਰਟ ਤੋਂ coverage) | ਹਾਂ (ratchet ਤੋਂ ਪਹਿਲਾਂ) | +| `quality:ratchet` | `quality-baseline.json` ਵਿੱਚ ਹਰੇਕ metric ਪਿੱਛੇ ਨਹੀਂ ਗਈ ਹੈ (ESLint ਚੇਤਾਵਨੀਆਂ ≤ baseline; coverage ≥ baseline) | ਹਾਂ | +| `check:duplication` | Code duplication (jscpd@4), `quality-baseline.json` ਵਿੱਚ baseline ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ | ਹਾਂ | +| `check:complexity` | ਫ਼ਾਈਲ-ਪੱਧਰੀ cyclomatic complexity ਨਿਰਧਾਰਤ ਸੀਮਾ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ (ਮੁੱਖ ESLint `complexity` + `max-lines-per-function`) | ਹਾਂ | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — ਵੱਖਰਾ ESLint pass; CI ਦੋਵਾਂ ਨੂੰ ਇੱਕੋ `check:complexity-ratchets` ਪੜਾਅ ਵਜੋਂ ਮਿਲਾ ਕੇ ਚਲਾਉਂਦਾ ਹੈ | ਹਾਂ | +| `check:dead-code` | ਨਾ ਵਰਤੇ ਗਏ exports / files ਦਾ ratchet (knip), baseline ਦੇ ਮੁਕਾਬਲੇ ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦਾ | ਹਾਂ | +| `check:compression-budget` | Compression benchmark budget — ਪ੍ਰਤੀ-engine token-savings ਦੀਆਂ ਘੱਟੋ-ਘੱਟ ਹੱਦਾਂ ਪਿੱਛੇ ਨਹੀਂ ਜਾਣੀਆਂ ਚਾਹੀਦੀਆਂ | ਹਾਂ | +| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦਾ; ਵੱਡੇ ਪੱਧਰ 'ਤੇ `typecheck:noimplicit:core` ਨੂੰ ਸਮੇਟਦਾ ਹੈ | ਹਾਂ | +| `check:codeql-ratchet` | ਖੁੱਲ੍ਹੀਆਂ CodeQL ਚੇਤਾਵਨੀਆਂ ਦੀ ਗਿਣਤੀ ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦੀ (`gh api` ਰਾਹੀਂ ਪੜ੍ਹਦਾ ਹੈ; token ਤੋਂ ਬਿਨਾਂ ਸੁਚੱਜੇ ਢੰਗ ਨਾਲ ਛੱਡ ਦਿੰਦਾ ਹੈ) — refresh cadence ਅਤੇ ਹੱਥੀਂ trigger ਲਈ: ਹੇਠਾਂ "CodeQL ratchet" ਵੇਖੋ | ਹਾਂ | + +### ਜੌਬ: `quality-extended` + +ਪੂਰੀ ਜੌਬ ਸਲਾਹਕਾਰੀ ਹੈ (`continue-on-error: true`)। npm-ਅਧਾਰਿਤ ratchets ਅਸਲ ਵਿੱਚ +ਚੱਲਦੇ ਹਨ; ਬਾਹਰੀ scanners `gh release download` ਰਾਹੀਂ install ਹੁੰਦੇ ਹਨ ਅਤੇ ਜਦੋਂ ਕੋਈ +binary ਅਜੇ ਵੀ ਮੌਜੂਦ ਨਾ ਹੋਵੇ ਤਾਂ ਆਪਣੇ ਆਪ ਛੱਡ ਦਿੰਦੇ ਹਨ (exit 0)। + +| ਸਕ੍ਰਿਪਟ | ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਰੋਕਣ ਵਾਲੀ | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| `check:circular-deps` | ਕੋਈ circular dependencies ਨਹੀਂ (dpdm) | **ਸਲਾਹਕਾਰੀ** | +| `check:bundle-size` | Bundle size ਨਿਰਧਾਰਤ ਸੀਮਾ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੈ | **ਸਲਾਹਕਾਰੀ** | +| `check:secrets` | Secret scanning (gitleaks) — binary ਮੌਜੂਦ ਨਾ ਹੋਣ 'ਤੇ ਛੱਡ ਦਿੰਦੀ ਹੈ | **ਸਲਾਹਕਾਰੀ** | +| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) ਪਿੱਛੇ ਨਹੀਂ ਜਾਂਦੀਆਂ — binary ਮੌਜੂਦ ਨਾ ਹੋਣ 'ਤੇ ਛੱਡ ਦਿੰਦੀ ਹੈ | **ਸਲਾਹਕਾਰੀ** | +| `check:workflows` | Workflow lint (actionlint + zizmor); ਗੁੰਮ/ਖ਼ਰਾਬ scanners, ਅਵੈਧ reports ਜਾਂ ਗੁੰਮ ratchet baseline ਨੂੰ INCOMPLETE ਮੰਨ ਕੇ ਅਸਫਲ ਕਰਦੇ ਹਨ। ਵੈਧ findings ਚੁਣੀ ਗਈ strict/advisory/ratchet policy ਦੀ ਪਾਲਣਾ ਕਰਦੀਆਂ ਹਨ | ਚਲਾਉਣਾ ਲਾਜ਼ਮੀ; CI ਵਿੱਚ zizmor ratchet ਰੋਕਣ ਵਾਲਾ ਹੈ | +| `check:openapi-breaking` | ਮੁੱਢਲੀ branch ਦੇ ਮੁਕਾਬਲੇ ਜਨਤਕ API contract (`openapi.yaml`) ਵਿੱਚ breaking changes (oasdiff) — `openapiBreaking=N` ਉਤਪੰਨ ਕਰਦੀ ਹੈ; oasdiff ਮੌਜੂਦ ਨਾ ਹੋਣ ਜਾਂ ਮੁੱਢਲੀ spec ਹੱਲ ਨਾ ਹੋ ਸਕਣ 'ਤੇ ਛੱਡ ਦਿੰਦੀ ਹੈ | **ਸਲਾਹਕਾਰੀ** | + +### ਜੌਬ: `docs-sync-strict` + +`main` ਲਈ ਹਰੇਕ PR ਉੱਤੇ ਚੱਲਦੀ ਹੈ। ਅਸਫਲ ਹੋਣ 'ਤੇ merge ਨੂੰ ਰੋਕਦੀ ਹੈ। + +| ਸਕ੍ਰਿਪਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਰੋਕਣ ਵਾਲੀ | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `check:docs-all` | ਮੈਟਾ-ਗੇਟ ਜੋ ਹੇਠਾਂ ਦਿੱਤੇ 6 ਉਪ-ਗੇਟਾਂ ਨੂੰ ਕ੍ਰਮਵਾਰ ਚਲਾਉਂਦਾ ਹੈ | ਹਾਂ | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt ਸੰਸਕਰਣ ਇਕਸਾਰਤਾ | ਹਾਂ | +| ↳ `check:docs-counts` | ਗੱਥ ਵਿੱਚ ਦਿੱਤੀਆਂ ਗਿਣਤੀਆਂ (ਪ੍ਰਦਾਤਾ ਗਿਣਤੀ, ਮਾਈਗ੍ਰੇਸ਼ਨ ਗਿਣਤੀ ਆਦਿ) ਅਸਲ ਗਿਣਤੀਆਂ ਦੀ ਰੈਚਟ ਸੀਮਾ ਦੇ ਅੰਦਰ ਹਨ | ਹਾਂ | +| ↳ `check:env-doc-sync` | `.env.example` ਵਿੱਚ ਮੌਜੂਦ ਹਰ env var ਨੂੰ ਦਸਤਾਵੇਜ਼ਾਂ ਦੀ ਇੱਕ ਸਾਰਣੀ ਵਿੱਚ ਦਰਜ ਕੀਤਾ ਗਿਆ ਹੈ, ਅਤੇ ਇਸਦੇ ਉਲਟ ਵੀ | ਹਾਂ | +| ↳ `check:deprecated-versions` | ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਕੋਈ ਵੀ ਬਰਖ਼ਾਸਤ ਸੰਸਕਰਣ ਸਤਰ ਨਹੀਂ ਹੈ | ਹਾਂ | +| ↳ `check:doc-links` | ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਅੰਦਰੂਨੀ markdown ਲਿੰਕ ਅਸਲ ਫ਼ਾਈਲਾਂ ਵੱਲ ਜਾਂਦੇ ਹਨ (`[text]`/`(path)` ਰੂਪ) | ਹਾਂ | +| ↳ `check:fabricated-docs` | ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਦਰਸਾਏ ਗਏ ਰੂਟ, env vars, CLI ਕਮਾਂਡਾਂ, ਹੁੱਕ ਨਾਮ ਅਤੇ ਫ਼ਾਈਲ ਪਾਥ ਕੋਡਬੇਸ ਵਿੱਚ ਮੌਜੂਦ ਹਨ। `--strict` ਰਾਹੀਂ ਹਾਰਡ ਗੇਟ; ਫ਼ਲੈਗ ਤੋਂ ਬਿਨਾਂ ਸੌਫ਼ਟ-ਫੇਲ। | ਹਾਂ (CI ਵਿੱਚ `--strict` ਰਾਹੀਂ) | +| `check:cli-i18n` | CLI ਕਮਾਂਡ ਸਤਰਾਂ ਸਾਰੀਆਂ i18n ਲੋਕੇਲ ਫ਼ਾਈਲਾਂ ਵਿੱਚ ਮੌਜੂਦ ਹਨ | ਹਾਂ | +| `check:openapi-coverage` | OpenAPI ਵਿਸ਼ੇਸ਼ਤਾ ਅਸਲ ਰੂਟਾਂ ਦੀ ਘੱਟੋ-ਘੱਟ ਰੈਚਟ ਕੀਤੀ ਹੇਠਲੀ ਸੀਮਾ ਨੂੰ ਕਵਰ ਕਰਦੀ ਹੈ | ਹਾਂ | +| `check:openapi-security-tiers` | `openapi.yaml` ਵਿੱਚ ਸੁਰੱਖਿਆ ਟੀਅਰ ਐਨੋਟੇਸ਼ਨ `routeGuard.ts` ਵਰਗੀਕਰਨਾਂ ਨਾਲ ਇਕਸਾਰ ਹਨ | **ਸਲਾਹਕਾਰੀ** | +| `check:openapi-routes` | `openapi.yaml` ਵਿੱਚ ਹਰ ਪਾਥ ਇੱਕ ਅਸਲ `route.ts` ਵੱਲ ਜਾਂਦਾ ਹੈ (ਭਰਮ-ਰੋਕੂ) | ਹਾਂ | +| `check:docs-symbols` | `docs/**/*.md` ਵਿੱਚ ਹਰ `/api/...` ਹਵਾਲਾ ਇੱਕ ਅਸਲ `route.ts` ਵੱਲ ਜਾਂਦਾ ਹੈ (ਭਰਮ-ਰੋਕੂ) | ਹਾਂ | +| `i18n translation drift` | i18n ਲੋਕੇਲ ਫ਼ਾਈਲਾਂ ਵਿੱਚ ਅਨੁਵਾਦ ਨਾ ਕੀਤੀਆਂ ਕੁੰਜੀਆਂ — ਸਿਰਫ਼ ਚੇਤਾਵਨੀ | **ਸਲਾਹਕਾਰੀ** | ### ਜੌਬ: `i18n-ui-coverage` -| ਸਕ੍ਰਿਪਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਬਲੌਕਿੰਗ | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | -| `check-ui-keys-coverage` (ਇਨਲਾਈਨ) | UI i18n ਕੁੰਜੀ ਕਵਰੇਜ ≥ 65% ਹੈ | ਹਾਂ | -| `check-ui-value-drift` (ਇਨਲਾਈਨ) | ਮੁੜ ਲਿਖਿਆ ਗਿਆ ਅੰਗਰੇਜ਼ੀ **ਮੁੱਲ** ਕੋਈ ਪੁਰਾਣਾ ਅਨੁਵਾਦ ਪਿੱਛੇ ਨਹੀਂ ਛੱਡਦਾ | ਹਾਂ | -| `check-new-key-coverage` (ਇਨਲਾਈਨ) | ਇੱਕ **ਨਵੀਂ** ਅੰਗਰੇਜ਼ੀ ਕੁੰਜੀ ਹਰ ਲੋਕੇਲ ਵਿੱਚ ਅਨੁਵਾਦ ਕੀਤੀ ਗਈ ਹੈ — ਇੱਕ `__MISSING__:` ਮਾਰਕਰ ਅਸਵੀਕਾਰ ਕੀਤਾ ਜਾਂਦਾ ਹੈ | ਹਾਂ | -| `check-translation-ratio` | ਪ੍ਰਤੀ ਲੋਕੇਲ ਅਸਲ-ਅਨੁਵਾਦ ਅਨੁਪਾਤ (ਅੰਗਰੇਜ਼ੀ ਦੇ ਸਮਾਨ / ਪਲੇਸਹੋਲਡਰ / ਮਨਜ਼ੂਰਸ਼ੁਦਾ ਸੂਚੀ ਤੋਂ ਬਾਹਰ ਗੁੰਮ ਐਂਟਰੀਆਂ) `config/quality/i18n-translation-baseline.json` + ਛੋਟ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ | **ਸਲਾਹਕਾਰੀ** | +| ਸਕ੍ਰਿਪਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਰੋਕਣ ਵਾਲੀ | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `check-ui-keys-coverage` (ਇਨਲਾਈਨ) | UI i18n ਕੁੰਜੀ ਕਵਰੇਜ ≥ 65% ਹੈ | ਹਾਂ | +| `check-ui-value-drift` (ਇਨਲਾਈਨ) | ਮੁੜ ਲਿਖੇ ਗਏ ਅੰਗਰੇਜ਼ੀ **ਮੁੱਲ** ਤੋਂ ਬਾਅਦ ਕੋਈ ਪੁਰਾਣਾ ਅਨੁਵਾਦ ਬਾਕੀ ਨਹੀਂ ਰਹਿੰਦਾ | ਹਾਂ | +| `check-new-key-coverage` (ਇਨਲਾਈਨ) | ਇੱਕ **ਨਵੀਂ** ਅੰਗਰੇਜ਼ੀ ਕੁੰਜੀ ਦਾ ਹਰ ਲੋਕੇਲ ਵਿੱਚ ਅਨੁਵਾਦ ਕੀਤਾ ਗਿਆ ਹੈ — ਇੱਕ `__MISSING__:` ਮਾਰਕਰ ਅਸਵੀਕਾਰ ਕੀਤਾ ਜਾਂਦਾ ਹੈ | ਹਾਂ | +| `check-translation-ratio` | ਹਰ ਲੋਕੇਲ ਲਈ ਅਸਲ-ਅਨੁਵਾਦ ਅਨੁਪਾਤ (ਅੰਗਰੇਜ਼ੀ ਨਾਲ ਇੱਕੋ ਜਿਹੇ / ਪਲੇਸਹੋਲਡਰ / ਮਨਜ਼ੂਰ-ਸੂਚੀ ਤੋਂ ਬਾਹਰ ਗੁੰਮ ਪੱਤੇ) `config/quality/i18n-translation-baseline.json` + ਢਿੱਲ ਤੋਂ ਵੱਧ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ | **ਸਲਾਹਕਾਰੀ** | -`fetch-depth: 0` ਦੀ ਲੋੜ ਹੈ — ਵੈਲਿਊ-ਡ੍ਰਿਫਟ ਗੇਟ ਮਰਜ ਬੇਸ ਦੇ ਮੁਕਾਬਲੇ `en.json` ਦਾ diff ਕਰਦਾ ਹੈ। +`fetch-depth: 0` ਦੀ ਲੋੜ ਹੈ — ਮੁੱਲ-ਡ੍ਰਿਫਟ ਗੇਟ `en.json` ਦੀ merge base ਨਾਲ ਤੁਲਨਾ ਕਰਦਾ ਹੈ। #### `check-ui-value-drift` — ਪੁਰਾਣੇ-ਅਨੁਵਾਦ ਦਾ ਗੇਟ -ਇਹ ਉਸ ਇੱਕ i18n ਰਿਗ੍ਰੈਸ਼ਨ ਨੂੰ ਫੜਦਾ ਹੈ ਜਿਸਨੂੰ ਹੋਰ ਗੇਟ ਸੰਰਚਨਾਤਮਕ ਤੌਰ 'ਤੇ ਨਹੀਂ ਦੇਖ ਸਕਦੇ: ਇੱਕ ਅੰਗਰੇਜ਼ੀ ਮੁੱਲ -ਮੁੜ ਲਿਖਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ _ਪਿਛਲੇ_ ਅੰਗਰੇਜ਼ੀ ਮੁੱਲ ਤੋਂ ਬਣੇ ਅਨੁਵਾਦ ਉੱਥੇ ਹੀ ਰਹਿ ਜਾਂਦੇ ਹਨ, ਜਿਸ ਕਾਰਨ -ਗੈਰ-ਅੰਗਰੇਜ਼ੀ ਵਰਤੋਂਕਾਰ ਭਰੋਸੇ ਨਾਲ ਲਿਖੀ ਹੋਈ, ਪਰ ਹੁਣ ਗਲਤ ਕਾਪੀ ਪੜ੍ਹਦੇ ਰਹਿੰਦੇ ਹਨ। +ਇਹ ਉਸ ਇੱਕ i18n ਰਿਗ੍ਰੈਸ਼ਨ ਨੂੰ ਫੜਦਾ ਹੈ ਜਿਸਨੂੰ ਹੋਰ ਗੇਟ ਸੰਰਚਨਾਤਮਕ ਤੌਰ 'ਤੇ ਨਹੀਂ ਦੇਖ ਸਕਦੇ: ਕਿਸੇ ਅੰਗਰੇਜ਼ੀ ਮੁੱਲ ਨੂੰ +ਮੁੜ ਲਿਖਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ _ਪਿਛਲੀ_ ਅੰਗਰੇਜ਼ੀ ਤੋਂ ਬਣੇ ਅਨੁਵਾਦ ਪਿੱਛੇ ਹੀ ਰਹਿ ਜਾਂਦੇ ਹਨ, ਇਸ ਲਈ +ਗ਼ੈਰ-ਅੰਗਰੇਜ਼ੀ ਵਰਤੋਂਕਾਰ ਭਰੋਸੇ ਨਾਲ ਲਿਖੀ, ਪਰ ਹੁਣ ਗ਼ਲਤ, ਸਮੱਗਰੀ ਪੜ੍ਹਦੇ ਰਹਿੰਦੇ ਹਨ। -ਇਹ ਅਸਲ ਵਿੱਚ ਰਿਲੀਜ਼ ਹੋਇਆ ਸੀ। ਜਦੋਂ Antigravity ਲੌਗਇਨ ਸਹਾਇਕ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ (#5203), ਤਾਂ `oauthModal.googleOAuthWarning` -ਨੂੰ ਮੁੜ ਲਿਖਿਆ ਗਿਆ ਸੀ; **43 ਵਿੱਚੋਂ 39 ਲੋਕੇਲਾਂ** ਵਿੱਚ ਆਪਰੇਟਰਾਂ ਨੂੰ "ਪੂਰਾ URL ਕਾਪੀ ਕਰੋ -ਅਤੇ ਇਸਨੂੰ ਹੇਠਾਂ ਪੇਸਟ ਕਰੋ" ਦੱਸਣ ਵਾਲਾ ਟੈਕਸਟ ਹੀ ਰਿਹਾ — ਇੱਕ ਅਜਿਹਾ ਪ੍ਰਵਾਹ ਜੋ ਉਸ ਪ੍ਰਦਾਤਾ ਲਈ ਪੂਰਾ ਨਹੀਂ ਹੋ ਸਕਦਾ। ਇਸਦਾ -#8463 ਤੱਕ ਪਤਾ ਨਹੀਂ ਲੱਗਿਆ ਕਿਉਂਕਿ: +ਇਹ ਅਸਲ ਵਿੱਚ ਰਿਲੀਜ਼ ਹੋਇਆ ਸੀ। ਜਦੋਂ Antigravity +ਲੌਗਇਨ ਸਹਾਇਕ ਸ਼ਾਮਲ ਹੋਇਆ (#5203), ਤਾਂ `oauthModal.googleOAuthWarning` ਨੂੰ ਮੁੜ ਲਿਖਿਆ ਗਿਆ ਸੀ; **43 ਵਿੱਚੋਂ 39 ਲੋਕੇਲਾਂ** ਵਿੱਚ ਉਹੀ ਲਿਖਤ ਰਹੀ ਜੋ ਓਪਰੇਟਰਾਂ ਨੂੰ "ਪੂਰਾ +URL ਕਾਪੀ ਕਰਕੇ ਹੇਠਾਂ ਪੇਸਟ ਕਰੋ" ਕਹਿੰਦੀ ਸੀ — ਇੱਕ ਅਜਿਹਾ ਪ੍ਰਵਾਹ ਜੋ ਉਸ ਪ੍ਰਦਾਤਾ ਲਈ ਪੂਰਾ ਨਹੀਂ ਹੋ ਸਕਦਾ। ਇਹ +#8463 ਤੱਕ ਅਣਦੇਖਿਆ ਰਿਹਾ ਕਿਉਂਕਿ: -- `sync-ui-keys` ਸਿਰਫ਼ ਉਹਨਾਂ ਕੁੰਜੀਆਂ ਨੂੰ ਬੈਕਫ਼ਿਲ ਕਰਦਾ ਹੈ ਜੋ **ਗੈਰਹਾਜ਼ਰ** ਹਨ, ਉਹਨਾਂ ਨੂੰ ਕਦੇ ਨਹੀਂ ਜੋ **ਪੁਰਾਣੀਆਂ** ਹਨ; -- `check-ui-keys-coverage` ਕੁੰਜੀ ਦੀ _ਮੌਜੂਦਗੀ_ ਗਿਣਦਾ ਹੈ, ਇਸ ਲਈ ਪੁਰਾਣਾ ਅਨੁਵਾਦ ਕਵਰ ਕੀਤਾ ਹੋਇਆ ਮੰਨਿਆ ਜਾਂਦਾ ਹੈ; +- `sync-ui-keys` ਸਿਰਫ਼ ਉਹਨਾਂ ਕੁੰਜੀਆਂ ਨੂੰ ਬੈਕਫ਼ਿਲ ਕਰਦਾ ਹੈ ਜੋ **ਗੈਰ-ਮੌਜੂਦ** ਹਨ, **ਪੁਰਾਣੀਆਂ** ਕੁੰਜੀਆਂ ਨੂੰ ਕਦੇ ਨਹੀਂ; +- `check-ui-keys-coverage` ਕੁੰਜੀ ਦੀ _ਮੌਜੂਦਗੀ_ ਗਿਣਦਾ ਹੈ, ਇਸ ਲਈ ਇੱਕ ਪੁਰਾਣਾ ਅਨੁਵਾਦ ਵੀ ਕਵਰ ਕੀਤਾ ਹੋਇਆ ਮੰਨਿਆ ਜਾਂਦਾ ਹੈ; - `check-translation-drift` `docs/i18n//**.md` ਦਸਤਾਵੇਜ਼ੀ ਮਿਰਰਾਂ ਨੂੰ ਟ੍ਰੈਕ ਕਰਦਾ ਹੈ — - ਇਹ ਕਦੇ ਵੀ `src/i18n/messages/*.json` ਨਹੀਂ ਪੜ੍ਹਦਾ। 2026-09 ਮੁੜ-ਸਿੰਕ ਤੋਂ ਬਾਅਦ ਜੌਬ `docs-sync-strict` ਵਿੱਚ ਬਲੌਕਿੰਗ: - ਇੱਕ ਮੁੱਖ ਦਸਤਾਵੇਜ਼ ਸੋਧੋ → `npm run i18n:run -- --files=` (ਸੈਕਸ਼ਨ-ਪੱਧਰੀ, ਘੱਟ ਖ਼ਰਚੀਲਾ)। + ਇਹ ਕਦੇ ਵੀ `src/i18n/messages/*.json` ਨਹੀਂ ਪੜ੍ਹਦਾ। 2026-09 ਦੀ ਮੁੜ-ਸਿੰਕ ਤੋਂ ਬਾਅਦ ਜੌਬ `docs-sync-strict` ਵਿੱਚ ਰੋਕਣ ਵਾਲਾ: + ਮੁੱਖ ਦਸਤਾਵੇਜ਼ ਸੋਧੋ → `npm run i18n:run -- --files=` (ਸੈਕਸ਼ਨ-ਪੱਧਰੀ, ਘੱਟ-ਖ਼ਰਚੀਲਾ)। -**ਡਿਫ਼-ਸਚੇਤ, ਬੇਸਲਾਈਨ-ਸਮਰਥਿਤ ਨਹੀਂ।** ਇਹ ਮਰਜ ਬੇਸ ਉੱਤੇ ਮੌਜੂਦ `en.json` ਦੀ ਵਰਕਿੰਗ ਟ੍ਰੀ ਨਾਲ ਤੁਲਨਾ ਕਰਦਾ ਹੈ; ਹਰ ਉਸ ਕੁੰਜੀ ਲਈ ਜਿਸਦਾ ਅੰਗਰੇਜ਼ੀ ਮੁੱਲ ਬਦਲਿਆ ਹੈ, ਕੋਈ ਵੀ ਲੋਕੇਲ ਜਿਸ ਵਿੱਚ ਅਜੇ ਵੀ ਨਾ-ਬਦਲਿਆ ਅਨੁਵਾਦ ਹੈ, ਪੁਰਾਣਾ ਮੰਨਿਆ ਜਾਂਦਾ ਹੈ। ਇਹ ਜਾਣ-ਬੁੱਝ ਕੇ **ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਕਰਜ਼ੇ ਨੂੰ ਫ੍ਰੀਜ਼ ਕਰਦਾ ਹੈ** — ਕੋਈ ਡਿਫ਼ ਇਹ ਨਹੀਂ ਦੱਸ ਸਕਦਾ ਕਿ ਲੰਬੇ ਸਮੇਂ ਤੋਂ ਮੌਜੂਦ ਅਨੁਵਾਦ ਕਿਸ ਪੁਰਾਣੇ ਅੰਗਰੇਜ਼ੀ ਪਾਠ ਤੋਂ ਆਇਆ ਸੀ, ਇਸ ਲਈ ਗੇਟ ਸਿਰਫ਼ ਉਸੇ ਨੂੰ ਜਾਂਚਦਾ ਹੈ ਜਿਸਨੂੰ ਮੌਜੂਦਾ ਤਬਦੀਲੀ ਛੂੰਹਦੀ ਹੈ। ਵਿਕਲਪ (ਹਰ ਕੁੰਜੀ ਲਈ ਹੈਸ਼ ਬੇਸਲਾਈਨ) ਲਈ ਲਗਭਗ 600 KB ਦੀ ਜਨਰੇਟ ਕੀਤੀ ਫ਼ਾਈਲ ਦੀ ਲੋੜ ਪਵੇਗੀ, ਜੋ ਮੌਜੂਦਾ ਸਭ ਤੋਂ ਵੱਡੀ ਬੇਸਲਾਈਨ ਤੋਂ 3× ਵੱਡੀ ਹੋਵੇਗੀ ਅਤੇ ਹਰ i18n PR ਉੱਤੇ ਬਦਲੇਗੀ। +**Diff-ਅਵੇਅਰ, ਬੇਸਲਾਈਨ-ਬੈਕਡ ਨਹੀਂ।** ਇਹ ਮਰਜ ਬੇਸ ਉੱਤੇ ਮੌਜੂਦ `en.json` ਦੀ ਵਰਕਿੰਗ ਟ੍ਰੀ ਨਾਲ ਤੁਲਨਾ ਕਰਦਾ ਹੈ; ਹਰ ਉਸ ਕੁੰਜੀ ਲਈ ਜਿਸਦਾ ਅੰਗਰੇਜ਼ੀ ਮੁੱਲ ਬਦਲਿਆ ਹੈ, ਕੋਈ ਵੀ ਲੋਕੇਲ ਜਿਸ ਵਿੱਚ ਹਾਲੇ ਵੀ ਨਾ-ਛੋਹਿਆ ਅਨੁਵਾਦ ਮੌਜੂਦ ਹੈ, ਪੁਰਾਣਾ ਮੰਨਿਆ ਜਾਂਦਾ ਹੈ। ਇਹ ਜਾਣ-ਬੁੱਝ ਕੇ **ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਕਰਜ਼ੇ ਨੂੰ ਫ੍ਰੀਜ਼ ਕਰਦਾ ਹੈ** — ਕੋਈ diff ਇਹ ਨਹੀਂ ਦੱਸ ਸਕਦਾ ਕਿ ਲੰਬੇ ਸਮੇਂ ਤੋਂ ਮੌਜੂਦ ਅਨੁਵਾਦ ਕਿਸ ਪੁਰਾਣੇ ਅੰਗਰੇਜ਼ੀ ਪਾਠ ਤੋਂ ਆਇਆ ਸੀ, ਇਸ ਲਈ ਗੇਟ ਸਿਰਫ਼ ਉਸੇ ਨੂੰ ਪਰਖਦਾ ਹੈ ਜਿਸਨੂੰ ਮੌਜੂਦਾ ਤਬਦੀਲੀ ਛੂਹਦੀ ਹੈ। ਵਿਕਲਪ (ਹਰ ਕੁੰਜੀ ਲਈ ਹੈਸ਼ ਬੇਸਲਾਈਨ) ਲਈ ~600 KB ਦੀ ਜਨਰੇਟ ਕੀਤੀ ਫ਼ਾਈਲ ਦੀ ਲੋੜ ਪਵੇਗੀ, ਜੋ ਸਭ ਤੋਂ ਵੱਡੀ ਮੌਜੂਦਾ ਬੇਸਲਾਈਨ ਤੋਂ 3× ਵੱਡੀ ਹੋਵੇਗੀ ਅਤੇ ਹਰ i18n PR ਉੱਤੇ ਬਦਲੇਗੀ। ਇਸਨੂੰ ਸੰਤੁਸ਼ਟ ਕਰਨ ਦੇ ਦੋ ਤਰੀਕੇ ਹਨ: 1. ਪ੍ਰਭਾਵਿਤ ਅਨੁਵਾਦਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ, ਜਾਂ -2. ਉਨ੍ਹਾਂ ਨੂੰ `__MISSING__:` ਉੱਤੇ ਸੈੱਟ ਕਰੋ — ਫਿਰ ਰਨਟਾਈਮ ਸੁਧਾਰਿਆ ਹੋਇਆ ਅੰਗਰੇਜ਼ੀ ਪਾਠ ਦਿੰਦਾ ਹੈ - (`src/i18n/request.ts::deepMergeFallback`, #7258) ਅਤੇ ਕੁੰਜੀ ਅਨੁਵਾਦ ਲਈ ਕਤਾਰ ਵਿੱਚ ਚਲੀ ਜਾਂਦੀ ਹੈ। +2. ਉਹਨਾਂ ਨੂੰ `__MISSING__:` ਉੱਤੇ ਸੈੱਟ ਕਰੋ — ਫਿਰ ਰਨਟਾਈਮ ਸੋਧਿਆ ਹੋਇਆ ਅੰਗਰੇਜ਼ੀ ਪਾਠ ਸਰਵ ਕਰਦਾ ਹੈ + (`src/i18n/request.ts::deepMergeFallback`, #7258) ਅਤੇ ਕੁੰਜੀ ਅਨੁਵਾਦ ਲਈ ਕਤਾਰਬੱਧ ਹੋ ਜਾਂਦੀ ਹੈ। -ਜੇ ਸਤਰ ਦਾ **ਅਰਥ** ਬਦਲ ਗਿਆ ਹੈ, ਤਾਂ **ਕੁੰਜੀ ਦਾ ਨਾਮ ਬਦਲਣ** ਨੂੰ ਤਰਜੀਹ ਦਿਓ: ਨਵੀਂ ਕੁੰਜੀ ਕਿਸੇ ਪੁਰਾਣੇ ਅਨੁਵਾਦ ਨੂੰ ਵਿਰਾਸਤ ਵਿੱਚ ਨਹੀਂ ਲੈ ਸਕਦੀ। #8463 ਵਿੱਚ ਇਹੀ ਪੈਟਰਨ ਵਰਤਿਆ ਗਿਆ ਸੀ। +ਜੇ ਸਤਰ ਦਾ **ਅਰਥ** ਬਦਲਿਆ ਹੈ, ਤਾਂ **ਕੁੰਜੀ ਦਾ ਨਾਮ ਬਦਲਣ** ਨੂੰ ਤਰਜੀਹ ਦਿਓ: ਨਵੀਂ ਕੁੰਜੀ ਕਿਸੇ ਪੁਰਾਣੇ ਅਨੁਵਾਦ ਨੂੰ ਵਿਰਾਸਤ ਵਿੱਚ ਨਹੀਂ ਲੈ ਸਕਦੀ। #8463 ਵਿੱਚ ਇਹੀ ਪੈਟਰਨ ਵਰਤਿਆ ਗਿਆ ਸੀ। ```bash npm run i18n:check-value-drift # ਸਖ਼ਤ (ਜੋ CI ਚਲਾਉਂਦਾ ਹੈ) @@ -231,47 +225,47 @@ npm run i18n:check-value-drift:warn # ਸਿਰਫ਼ ਰਿਪੋਰਟ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -ਜਦੋਂ ਬੇਸ ਕੈਟਾਲਾਗ ਪੜ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ (ਬੇਸ ਰੈਫ਼ ਤੋਂ ਬਿਨਾਂ ਸ਼ੈਲੋ ਕਲੋਨ), ਤਾਂ `SKIP reason=base-unresolved` ਨਾਲ 0 ਉੱਤੇ ਐਗਜ਼ਿਟ ਕਰਦਾ ਹੈ, ਜੋ `check-openapi-breaking` ਦੇ ਵਿਹਾਰ ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ। +ਜਦੋਂ ਬੇਸ ਕੈਟਾਲਾਗ ਪੜ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ (ਬੇਸ ref ਤੋਂ ਬਿਨਾਂ shallow clone), ਤਾਂ `check-openapi-breaking` ਦੇ ਵਿਹਾਰ ਦੀ ਨਕਲ ਕਰਦਿਆਂ ਇਹ `SKIP reason=base-unresolved` ਨਾਲ 0 ਐਗਜ਼ਿਟ ਕਰਦਾ ਹੈ। ### ਜੌਬ: `i18n` -ਪੂਰਾ i18n ਪ੍ਰਮਾਣਿਕਤਾ ਮੈਟ੍ਰਿਕਸ (ਹਰ ਲੋਕੇਲ ਲਈ ਇੱਕ ਜੌਬ)। ਪੂਰੀ ਜੌਬ ਸਲਾਹਕਾਰੀ ਹੈ। +ਪੂਰਾ i18n ਵੈਲੀਡੇਸ਼ਨ ਮੈਟ੍ਰਿਕਸ (ਹਰ ਲੋਕੇਲ ਲਈ ਇੱਕ ਜੌਬ)। ਪੂਰੀ ਜੌਬ ਸਲਾਹਕਾਰੀ ਹੈ। -| ਸਕ੍ਰਿਪਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਬਲੌਕਿੰਗ | +| ਸਕ੍ਰਿਪਟ | ਕੀ ਵੈਲੀਡੇਟ ਕਰਦੀ ਹੈ | ਬਲੌਕਿੰਗ | | ------------------------------- | ---------------------------- | ------------------------------------------------------ | | `validate_translation.py quick` | ਹਰ ਲੋਕੇਲ ਲਈ ਅਨੁਵਾਦ ਦੀ ਪੂਰਨਤਾ | **ਸਲਾਹਕਾਰੀ** (ਪੂਰੀ ਜੌਬ ਉੱਤੇ `continue-on-error: true`) | ### ਜੌਬ: `pr-test-policy` -ਸਿਰਫ਼ ਪੁੱਲ ਰਿਕਵੈਸਟਾਂ ਉੱਤੇ ਚੱਲਦੀ ਹੈ। +ਸਿਰਫ਼ ਪੁੱਲ ਰਿਕਵੇਸਟਾਂ ਉੱਤੇ ਚੱਲਦੀ ਹੈ। -| ਸਕ੍ਰਿਪਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦੀ ਹੈ | ਬਲੌਕਿੰਗ | +| ਸਕ੍ਰਿਪਟ | ਕੀ ਵੈਲੀਡੇਟ ਕਰਦੀ ਹੈ | ਬਲੌਕਿੰਗ | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, ਜਾਂ `bin/` ਵਿੱਚ ਪ੍ਰੋਡਕਸ਼ਨ ਕੋਡ ਬਦਲਣ ਵਾਲੀਆਂ PRs ਵਿੱਚ ਟੈਸਟ ਸ਼ਾਮਲ ਜਾਂ ਅੱਪਡੇਟ ਹੋਣੇ ਲਾਜ਼ਮੀ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #8) | ਹਾਂ | -| `check:test-masking` | ਬਦਲੀਆਂ ਹੋਈਆਂ ਟੈਸਟ ਫ਼ਾਈਲਾਂ ਕੁੱਲ assert ਗਿਣਤੀ ਨੂੰ ਘਟਾਉਂਦੀਆਂ ਜਾਂ `assert.ok(true)` ਵਰਗੀਆਂ ਸਵੈ-ਸਪਸ਼ਟ ਸੱਚਾਈਆਂ ਨਹੀਂ ਜੋੜਦੀਆਂ | ਹਾਂ | -| `check:pr-evidence` | PR ਦਾ ਮੁੱਖ ਭਾਗ ਤਬਦੀਲੀ ਲਈ ਟੈਸਟ/VPS ਸਬੂਤ ਦਾ ਹਵਾਲਾ ਦਿੰਦਾ ਹੈ (PR ਦੇ ਗੱਦ ਨੂੰ grep ਕਰਕੇ ਸਖ਼ਤ ਨਿਯਮ #18 ਨੂੰ ਮਸ਼ੀਨੀ ਬਣਾਉਂਦਾ ਹੈ — ਨਾਜ਼ੁਕ, Backlog ਵੇਖੋ) | ਹਾਂ | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, ਜਾਂ `bin/` ਵਿੱਚ ਪ੍ਰੋਡਕਸ਼ਨ ਕੋਡ ਬਦਲਣ ਵਾਲੀਆਂ PRs ਵਿੱਚ ਟੈਸਟ ਸ਼ਾਮਲ ਜਾਂ ਅੱਪਡੇਟ ਕੀਤੇ ਹੋਣੇ ਲਾਜ਼ਮੀ ਹਨ (ਸਖ਼ਤ ਨਿਯਮ #8) | ਹਾਂ | +| `check:test-masking` | ਬਦਲੀਆਂ ਹੋਈਆਂ ਟੈਸਟ ਫ਼ਾਈਲਾਂ ਕੁੱਲ assert ਗਿਣਤੀ ਨੂੰ ਘਟਾਉਂਦੀਆਂ ਜਾਂ `assert.ok(true)` ਵਰਗੀਆਂ ਸਵੈ-ਸਿੱਧੀਆਂ ਸ਼ਰਤਾਂ ਨਹੀਂ ਜੋੜਦੀਆਂ | ਹਾਂ | +| `check:pr-evidence` | PR ਬਾਡੀ ਵਿੱਚ ਤਬਦੀਲੀ ਲਈ ਟੈਸਟ/VPS ਸਬੂਤ ਦਾ ਹਵਾਲਾ ਹੋਵੇ (PR ਲਿਖਤ ਨੂੰ grep ਕਰਕੇ ਸਖ਼ਤ ਨਿਯਮ #18 ਨੂੰ ਮਸ਼ੀਨੀ ਰੂਪ ਦਿੰਦਾ ਹੈ — ਨਾਜ਼ੁਕ ਹੈ, Backlog ਵੇਖੋ) | ਹਾਂ | ### ਜੌਬ: `test-vitest` -`build` ਤੋਂ ਬਾਅਦ ਚੱਲਦੀ ਹੈ। ਅਸਫਲ ਹੋਣ ਉੱਤੇ ਮਰਜ ਨੂੰ ਰੋਕਦੀ ਹੈ। +`build` ਤੋਂ ਬਾਅਦ ਚੱਲਦੀ ਹੈ। ਅਸਫਲ ਹੋਣ ਉੱਤੇ ਮਰਜ ਨੂੰ ਬਲੌਕ ਕਰਦੀ ਹੈ। -| ਸੂਟ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦਾ ਹੈ | ਬਲੌਕਿੰਗ | -| ---------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP ਸਰਵਰ (110 ਟੂਲ), autoCombo, ਕੈਸ਼ — vitest ਰਨਰ | ਹਾਂ | -| `test:vitest:ui` | UI ਕੰਪੋਨੈਂਟ ਟੈਸਟ — vitest ਰਨਰ | **ਬਲੌਕਿੰਗ** — ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਅਸਫਲਤਾਵਾਂ ਨੂੰ `vitest.config.ts` ਵਿੱਚ ਸਪਸ਼ਟ ਤੌਰ ਉੱਤੇ ਬਾਹਰ ਰੱਖਿਆ ਗਿਆ ਹੈ; ਨਵੀਆਂ ਅਸਫਲਤਾਵਾਂ ਜੌਬ ਨੂੰ ਅਸਫਲ ਕਰ ਦਿੰਦੀਆਂ ਹਨ | +| ਸੂਟ | ਕੀ ਵੈਲੀਡੇਟ ਕਰਦਾ ਹੈ | ਬਲੌਕਿੰਗ | +| ---------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP ਸਰਵਰ (110 ਟੂਲ), autoCombo, ਕੈਸ਼ — vitest ਰਨਰ | ਹਾਂ | +| `test:vitest:ui` | UI ਕੰਪੋਨੈਂਟ ਟੈਸਟ — vitest ਰਨਰ | **ਬਲੌਕਿੰਗ** — ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਅਸਫਲਤਾਵਾਂ ਨੂੰ `vitest.config.ts` ਵਿੱਚ ਸਪਸ਼ਟ ਤੌਰ ਉੱਤੇ ਬਾਹਰ ਰੱਖਿਆ ਗਿਆ ਹੈ; ਨਵੀਆਂ ਅਸਫਲਤਾਵਾਂ ਜੌਬ ਨੂੰ ਅਸਫਲ ਕਰਦੀਆਂ ਹਨ | -### ਰਾਤਰੀ ਵਰਕਫ਼ਲੋ (ਨਿਯਤ, ਸਲਾਹਕਾਰੀ) +### ਰਾਤਰੀ ਵਰਕਫ਼ਲੋ (ਨਿਰਧਾਰਤ, ਸਲਾਹਕਾਰੀ) ਇਹ cron ਸ਼ਡਿਊਲ ਉੱਤੇ (ਅਤੇ `workflow_dispatch` ਰਾਹੀਂ) ਚੱਲਦੇ ਹਨ, PRs ਉੱਤੇ ਕਦੇ ਨਹੀਂ। ਸਾਰੇ ਸਲਾਹਕਾਰੀ ਹਨ। -| ਵਰਕਫ਼ਲੋ | ਕੀ ਪ੍ਰਮਾਣਿਤ ਕਰਦਾ ਹੈ | ਬਲੌਕਿੰਗ | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `nightly-property` | ਇੱਕ ਰੈਂਡਮ ਸੀਡ ਅਤੇ ਵੱਡੀ ਰਨ ਗਿਣਤੀ ਨਾਲ fast-check ਪ੍ਰਾਪਰਟੀ ਟੈਸਟ | **ਸਲਾਹਕਾਰੀ** | -| `nightly-resilience` | ਹੀਪ-ਵਾਧਾ ਗੇਟ, ਕਾਓਸ ਫ਼ਾਲਟ-ਇੰਜੈਕਸ਼ਨ, k6 ਲੋਡ/ਸੋਕ | **ਸਲਾਹਕਾਰੀ** | -| `nightly-llm-security` | promptfoo ਇੰਜੈਕਸ਼ਨ ਗਾਰਡ (ਬਲੌਕ ਮੋਡ) + garak ਪ੍ਰੋਬ (ਪ੍ਰੋਵਾਈਡਰ ਸੀਕ੍ਰੇਟ ਤੋਂ ਬਿਨਾਂ ਛੱਡੇ ਜਾਂਦੇ ਹਨ) | **ਸਲਾਹਕਾਰੀ** | -| `nightly-schemathesis` | `docs/openapi.yaml` ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਲਾਈਵ OmniRoute ਵਿਰੁੱਧ OpenAPI ਕਾਂਟ੍ਰੈਕਟ ਫ਼ਜ਼ਿੰਗ (schemathesis) — ਸਪੈਕ ਉਲੰਘਣਾਵਾਂ / ਨਾ-ਸੰਭਾਲੀਆਂ 500 ਗਲਤੀਆਂ ਨੂੰ ਸਾਹਮਣੇ ਲਿਆਉਂਦੀ ਹੈ (ਪੜਾਅ 8 B.4) | **ਸਲਾਹਕਾਰੀ** | -| `nightly-mutation` | ਤੇਜ਼ ਯੂਨਿਟ ਲੇਨ ਉੱਤੇ Stryker ਮਿਊਟੇਸ਼ਨ-ਟੈਸਟਿੰਗ ਸਕੋਰ — ਬਚੇ ਹੋਏ ਮਿਊਟੈਂਟ ਕਮਜ਼ੋਰ asserts ਨੂੰ ਸਾਹਮਣੇ ਲਿਆਉਂਦੇ ਹਨ | **ਸਲਾਹਕਾਰੀ** | -| `nightly-compat` | ਸਮਰਥਿਤ `engines.node` ਰੇਂਜਾਂ ਵਿੱਚ Node ਇੰਜਣ ਅਨੁਕੂਲਤਾ ਮੈਟ੍ਰਿਕਸ | **ਸਲਾਹਕਾਰੀ** | +| ਵਰਕਫ਼ਲੋ | ਕੀ ਵੈਲੀਡੇਟ ਕਰਦਾ ਹੈ | ਬਲੌਕਿੰਗ | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | ਬੇਤਰਤੀਬ seed + ਉੱਚ run count ਨਾਲ fast-check ਪ੍ਰਾਪਰਟੀ ਟੈਸਟ | **ਸਲਾਹਕਾਰੀ** | +| `nightly-resilience` | heap-growth ਗੇਟ, chaos fault-injection, k6 load/soak | **ਸਲਾਹਕਾਰੀ** | +| `nightly-llm-security` | promptfoo injection ਗਾਰਡ (block ਮੋਡ) + garak probes (ਪ੍ਰੋਵਾਈਡਰ ਸੀਕ੍ਰੇਟ ਤੋਂ ਬਿਨਾਂ ਛੱਡੇ ਜਾਂਦੇ ਹਨ) | **ਸਲਾਹਕਾਰੀ** | +| `nightly-schemathesis` | `docs/openapi.yaml` ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਲਾਈਵ OmniRoute ਦੇ ਵਿਰੁੱਧ OpenAPI ਕੰਟ੍ਰੈਕਟ ਫਜ਼ਿੰਗ (schemathesis) — ਸਪੈੱਕ ਉਲੰਘਣਾਵਾਂ / ਨਾ-ਸੰਭਾਲੀਆਂ 500 ਗਲਤੀਆਂ ਸਾਹਮਣੇ ਲਿਆਉਂਦੀ ਹੈ (Fase 8 B.4) | **ਸਲਾਹਕਾਰੀ** | +| `nightly-mutation` | ਤੇਜ਼ ਯੂਨਿਟ ਲੇਨ ਉੱਤੇ Stryker ਮਿਊਟੇਸ਼ਨ-ਟੈਸਟਿੰਗ ਸਕੋਰ — ਬਚੇ ਰਹਿਣ ਵਾਲੇ mutants ਕਮਜ਼ੋਰ asserts ਨੂੰ ਸਾਹਮਣੇ ਲਿਆਉਂਦੇ ਹਨ | **ਸਲਾਹਕਾਰੀ** | +| `nightly-compat` | ਸਮਰਥਿਤ `engines.node` ਰੇਂਜਾਂ ਵਿੱਚ Node ਇੰਜਣ ਅਨੁਕੂਲਤਾ ਮੈਟ੍ਰਿਕਸ | **ਸਲਾਹਕਾਰੀ** | --- @@ -535,43 +529,43 @@ CI ਗੇਟਾਂ ਤੋਂ ਇਲਾਵਾ, OmniRoute ਇੱਕ **ਚੋਣਵ --- -## ਤਰਕਸੰਗਤੀਕਰਨ ਬੈਕਲੌਗ (ROI ਸਮੀਖਿਆ — ਪੜਾਅ 9 ਲਹਿਰ 3) +## ਤਰਕਸੰਗਤੀਕਰਨ ਬੈਕਲਾਗ (ROI ਸਮੀਖਿਆ — ਪੜਾਅ 9 ਲਹਿਰ 3) -ਇਸ ਸੂਚੀ ਦਾ 2026-06-17 ਨੂੰ `ci.yml` ਨਾਲ ਮਿਲਾਣ ਕੀਤਾ ਗਿਆ ਸੀ (ਪਿਛਲੇ ਸੰਸਕਰਣ ਵਿੱਚ +ਇਸ ਸੂਚੀ ਦਾ 2026-06-17 ਨੂੰ `ci.yml` ਨਾਲ ਮਿਲਾਨ ਕੀਤਾ ਗਿਆ ਸੀ (ਪਿਛਲੇ ਸੰਸਕਰਣ ਵਿੱਚ `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` ਸ਼ਾਮਲ ਨਹੀਂ ਸਨ)। ਮਿਲਾਣ ਕੀਤੇ ਸੈੱਟ ਦੀ ROI ਸਮੀਖਿਆ ਨੇ -ਹੇਠਾਂ ਦਿੱਤੇ ਤਰਕਸੰਗਤੀਕਰਨ ਉਮੀਦਵਾਰਾਂ ਦੀ ਪਛਾਣ ਕੀਤੀ। **ਮਰਜ ਮਕੈਨੀਕਲ CI -ਤਬਦੀਲੀਆਂ ਹਨ; ਫਲਿੱਪ/ਹਟਾਉਣ ਨੀਤੀਗਤ ਫ਼ੈਸਲੇ ਹਨ ਜੋ ਆਪਰੇਟਰ ਲਈ ਰਾਖਵੇਂ ਹਨ।** ਹੇਠਾਂ ਦਿੱਤੀ ਕੋਈ ਵੀ ਚੀਜ਼ -ਅਜੇ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਗਈ। +`check:codeql-ratchet`, `check:pr-evidence` ਸ਼ਾਮਲ ਨਹੀਂ ਸਨ)। ਮਿਲਾਨ ਕੀਤੇ ਸੈੱਟ ਦੀ ROI ਸਮੀਖਿਆ +ਨੇ ਹੇਠ ਲਿਖੇ ਤਰਕਸੰਗਤੀਕਰਨ ਉਮੀਦਵਾਰਾਂ ਦੀ ਪਛਾਣ ਕੀਤੀ। **ਮਰਜ ਮਕੈਨੀਕਲ CI +ਬਦਲਾਅ ਹਨ; ਫਲਿਪ/ਡ੍ਰਾਪ ਨੀਤੀਗਤ ਫੈਸਲੇ ਹਨ ਜੋ ਓਪਰੇਟਰ ਲਈ ਰਾਖਵੇਂ ਹਨ।** ਹੇਠਾਂ ਦਿੱਤਾ ਕੁਝ ਵੀ +ਹਾਲੇ ਲਾਗੂ ਨਹੀਂ ਕੀਤਾ ਗਿਆ। **ਉੱਪਰ ਇਹ ਵੀ ਦਸਤਾਵੇਜ਼ਬੱਧ ਨਹੀਂ ਹੈ** (ਸਲਾਹਕਾਰੀ, ਘੱਟ ਸੰਕੇਤ): `docs-lint` ਜੌਬ (markdownlint + Vale, ਪੂਰੀ ਜੌਬ `continue-on-error`) ਅਤੇ ਵੱਖਰੇ ਸਕੈਨਰ ਵਰਕਫ਼ਲੋ `semgrep.yml` / `codeql.yml` / `scorecard.yml`। `semgrepFindings: 0` -`quality-baseline.json` ਵਿੱਚ ਹੈ, ਪਰ `ci.yml` ਵਿੱਚ ਕਿਸੇ ਬਲੌਕਿੰਗ ਰੈਚਟ ਨਾਲ ਨਹੀਂ ਜੋੜਿਆ ਗਿਆ — ਇਹ ਮੈਟ੍ਰਿਕ +`quality-baseline.json` ਵਿੱਚ ਹੈ ਪਰ `ci.yml` ਵਿੱਚ ਕਿਸੇ ਬਲੌਕਿੰਗ ਰੈਚਿਟ ਨਾਲ ਜੋੜਿਆ ਨਹੀਂ ਗਿਆ — ਇਹ ਮੈਟ੍ਰਿਕ ਇਸ ਵੇਲੇ ਅਨਾਥ ਹੈ। -### ਮਰਜ / ਡੀਡੁਪਲੀਕੇਸ਼ਨ (ਮਕੈਨੀਕਲ, ਘੱਟ ਜੋਖਮ) +### ਮਰਜ / ਡੀਡੁਪ (ਮਕੈਨੀਕਲ, ਘੱਟ ਜੋਖਮ) -ਹਰੇਕ ਉਮੀਦਵਾਰ ਦੀ 2026-06-17 ਨੂੰ ਲਾਈਵ ਗੇਟ ਸਥਿਤੀ ਦੇ ਮੁਕਾਬਲੇ ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ ਸੀ (ਭਰੋਸਾ ਕਰੋ, ਪਰ ਤਸਦੀਕ ਵੀ ਕਰੋ); -ਕਈ "ਸਪਸ਼ਟ" ਮਰਜਾਂ ਦੇ ਪਿੱਛੇ ਅਸਲ ਵਿੱਚ ਕਰਜ਼ ਲੁਕਿਆ ਹੋਇਆ ਸੀ ਅਤੇ ਉਹ **ਸਿੱਧੇ ਬਦਲ ਵਜੋਂ ਸਾਫ਼ ਨਹੀਂ** ਹਨ। +ਹਰ ਉਮੀਦਵਾਰ ਨੂੰ 2026-06-17 ਨੂੰ ਲਾਈਵ ਗੇਟ ਸਥਿਤੀ ਦੇ ਮੁਕਾਬਲੇ ਪ੍ਰਮਾਣਿਤ ਕੀਤਾ ਗਿਆ ਸੀ (ਭਰੋਸਾ ਕਰੋ, ਪਰ ਤਸਦੀਕ ਵੀ ਕਰੋ); +ਕਈ "ਸਪਸ਼ਟ" ਮਰਜਾਂ ਦੇ ਪਿੱਛੇ ਕਰਜ਼ਾ ਲੁਕਿਆ ਹੋਇਆ ਨਿਕਲਿਆ ਅਤੇ ਉਹ **ਸਿੱਧੇ ਤੌਰ 'ਤੇ ਵਰਤਣਯੋਗ ਬਦਲ ਨਹੀਂ** ਹਨ। -- **`check:docs-sync` ਦੋ ਵਾਰ ਚੱਲਦਾ ਹੈ** — `lint` ਜੌਬ ਵਿੱਚ ਵੱਖਰੇ ਤੌਰ 'ਤੇ ਅਤੇ ਦੁਬਾਰਾ `check:docs-all` (`docs-sync-strict`) ਅਤੇ husky pre-commit ਹੁੱਕ ਦੇ ਅੰਦਰ। ✅ **ਮੁਕੰਮਲ** — ਵੱਖਰਾ `lint` ਸੱਦਾ ਹਟਾ ਦਿੱਤਾ ਗਿਆ। -- **CVE ਸਕੈਨਿੰਗ** — ❌ **ਸਾਫ਼ ਮਰਜ ਨਹੀਂ ਹੈ।** `audit:deps` ਕਿਸੇ ਵੀ high/critical CVE ਉੱਤੇ ਪੱਕੇ ਤੌਰ 'ਤੇ ਫੇਲ੍ਹ ਹੁੰਦਾ ਹੈ; `check:vuln-ratchet` (osv) ਸਿਰਫ਼ ਬੇਸਲਾਈਨ ਦੇ ਮੁਕਾਬਲੇ ਕਿਸੇ _ਰਿਗ੍ਰੈਸ਼ਨ_ ਉੱਤੇ ਫੇਲ੍ਹ ਹੁੰਦਾ ਹੈ (ਇਸ ਵੇਲੇ 1 MODERATE)। ਅਰਥ-ਵਿਹਾਰ ਵੱਖਰੇ ਹਨ — `audit:deps` ਨੂੰ ਹਟਾਉਣ ਨਾਲ ਪੂਰਨ high/critical ਗੇਟ ਗੁਆਚ ਜਾਵੇਗਾ। ਦੋਵੇਂ ਰੱਖੋ। -- **ਸਾਈਕਲ ਪਛਾਣ** — ❌ **ਸਾਫ਼ ਮਰਜ ਨਹੀਂ ਹੈ।** `check:circular-deps` (dpdm) **91 ਸਾਈਕਲਾਂ** ਦੀ ਰਿਪੋਰਟ ਕਰਦਾ ਹੈ (ਇਸੇ ਲਈ ਇਹ ਸਲਾਹਕਾਰੀ ਹੈ); ਪਹਿਲਾਂ ਉਨ੍ਹਾਂ ਨੂੰ ਹੱਲ ਕੀਤੇ ਬਿਨਾਂ ਇਸਨੂੰ ਬਲੌਕਿੰਗ ਨਹੀਂ ਬਣਾਇਆ ਜਾ ਸਕਦਾ, ਅਤੇ ਇਸਦਾ ਦਾਇਰਾ ਹਰੇ, ਚੁਣੇ ਹੋਏ `check:cycles` ਨਾਲੋਂ ਵੱਡਾ ਹੈ। `check:cycles` ਨੂੰ ਬਲੌਕਿੰਗ ਰੱਖੋ; 91 dpdm ਸਾਈਕਲਾਂ ਨੂੰ ਹੱਲ ਕਰਨਾ ਆਪਣਾ ਵੱਖਰਾ ਬੈਕਲੌਗ ਹੈ। -- **ਜਟਿਲਤਾ** — ✅ **ਮੁਕੰਮਲ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ਇੱਕ ESLint ਵਾਕ, ruleId ਮੁਤਾਬਕ ਗਿਣਤੀ ਕਰਦਾ ਹੈ ਤਾਂ ਜੋ cyclomatic+max-lines ਅਤੇ cognitive ਬੇਸਲਾਈਨਾਂ ਸੁਤੰਤਰ ਰਹਿਣ; ਵੱਖਰੇ `check:complexity` / `check:cognitive-complexity` ਸਥਾਨਕ `--update` ਲਈ ਕਾਇਮ ਹਨ। -- **`/api` ਭਰਮ-ਰੋਕਥਾਮ** — ✅ **ਮੁਕੰਮਲ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ਦੀ ਇੱਕ FS ਇਨਵੈਂਟਰੀ, openapi-routes + docs-symbols ਅਜੇ ਵੀ ਸੁਤੰਤਰ ਤੌਰ 'ਤੇ ਰਿਪੋਰਟ ਕਰਦੇ ਹਨ; ਵੱਖਰੇ ਚੈੱਕ ਸਥਾਨਕ ਰਨਾਂ ਲਈ ਕਾਇਮ ਹਨ। -- **`check:node-runtime` 11 ਜੌਬਾਂ ਵਿੱਚ ਚੱਲਦਾ ਹੈ** — ⚠️ **ਘੱਟ ROI।** ਹਰੇਕ ਇੱਕ ਵੱਖਰਾ ਰਨਰ ਹੈ ਅਤੇ ਚੈੱਕ <1s ਹੈ; ਕੁੱਲ ਬਚਤ ~10s ਹੈ, ਜਿਸਦੇ ਮੁਕਾਬਲੇ ਹਰ ਜੌਬ ਲਈ ਇੱਕ ਸਸਤਾ ਗਾਰਡ ਗੁਆਉਣਾ ਪਵੇਗਾ। ਤਬਦੀਲੀ ਦੀ ਝੰਝਟ ਦੇ ਯੋਗ ਨਹੀਂ। -- **CI lint ਉੱਤੇ `typecheck:noimplicit:core`** — ✅ **lint ਜੌਬ ਤੋਂ ਹਟਾਇਆ ਗਿਆ** (ਇਹ ਸਲਾਹਕਾਰੀ `continue-on-error` ਸੀ); ਬਲੌਕਿੰਗ ਟਾਈਪ ਸਤਹ `typecheck:core` + `check:type-coverage` ਹੈ। ਸਥਾਨਕ ਸਕ੍ਰਿਪਟ ਕਾਇਮ ਰੱਖੀ ਗਈ ਹੈ। +- **`check:docs-sync` ਦੋ ਵਾਰ ਚੱਲਦਾ ਹੈ** — `lint` ਜੌਬ ਵਿੱਚ ਵੱਖਰੇ ਤੌਰ 'ਤੇ ਅਤੇ ਮੁੜ `check:docs-all` (`docs-sync-strict`) ਅਤੇ husky pre-commit ਹੁੱਕ ਦੇ ਅੰਦਰ। ✅ **ਪੂਰਾ ਹੋਇਆ** — ਵੱਖਰਾ `lint` ਇਨਵੋਕੇਸ਼ਨ ਹਟਾਇਆ ਗਿਆ। +- **CVE ਸਕੈਨਿੰਗ** — ❌ **ਸਾਫ਼-ਸੁਥਰਾ ਮਰਜ ਨਹੀਂ ਹੈ।** `audit:deps` ਕਿਸੇ ਵੀ high/critical CVE 'ਤੇ ਹਾਰਡ-ਫੇਲ ਹੁੰਦਾ ਹੈ; `check:vuln-ratchet` (osv) ਸਿਰਫ਼ ਬੇਸਲਾਈਨ (ਇਸ ਵੇਲੇ 1 MODERATE) ਦੇ ਮੁਕਾਬਲੇ ਕਿਸੇ _ਰਿਗ੍ਰੈਸ਼ਨ_ 'ਤੇ ਫੇਲ ਹੁੰਦਾ ਹੈ। ਅਰਥ-ਵਿਹਾਰ ਵੱਖਰੇ ਹਨ — `audit:deps` ਨੂੰ ਹਟਾਉਣ ਨਾਲ ਪੂਰਨ high/critical ਗੇਟ ਖਤਮ ਹੋ ਜਾਵੇਗਾ। ਦੋਵੇਂ ਰੱਖੋ। +- **ਚੱਕਰ ਖੋਜ** — ✅ **ਪੂਰਾ ਹੋਇਆ** (#15159 G-01/G-02)। ਇੱਥੇ ਪੁਰਾਣੇ ਟੈਕਸਟ ਨੇ `check:cycles` ਨੂੰ "ਹਰਾ, ਸੰਭਾਲ ਕੇ ਚੁਣਿਆ" ਗੇਟ ਕਿਹਾ ਸੀ ਅਤੇ ਇਸਨੂੰ ਬਲੌਕਿੰਗ ਰੱਖਣ ਨੂੰ ਇਸ ਆਧਾਰ 'ਤੇ ਜਾਇਜ਼ ਠਹਿਰਾਇਆ ਸੀ ਕਿ `check:circular-deps` (dpdm) ਨੇ 91 ਚੱਕਰ ਰਿਪੋਰਟ ਕੀਤੇ ਸਨ। ਉਹ ਹਰਾ ਦਰਜਾ ਇੱਕ **ਗਲਤ ਹਰਾ ਸੰਕੇਤ** ਸੀ: `check:cycles` ਨੇ 5 ਸਬਡਾਇਰੈਕਟਰੀਆਂ (450 ਫ਼ਾਈਲਾਂ) ਸਕੈਨ ਕੀਤੀਆਂ, ਸਿਰਫ਼ ਸਥਿਰ `import|export … from` ਨਾਲ ਮੇਲ ਕੀਤਾ, ਅਤੇ ਹਰੇਕ `@/` ਅਤੇ `@omniroute/open-sse/` ਸਪੈਸੀਫਾਇਰ ਨੂੰ ਛੱਡ ਦਿੱਤਾ, ਇਸ ਲਈ ਇਹ ਉਹ dynamic-import + alias ਚੱਕਰ ਨਹੀਂ ਦੇਖ ਸਕਿਆ ਜੋ ਰਿਪੋ ਵਿੱਚ ਹਾਵੀ ਸਨ। ਠੀਕ ਕੀਤਾ ਗਿਆ: ਗੇਟ ਹੁਣ `src` + `open-sse` (5023 ਫ਼ਾਈਲਾਂ) ਵਿੱਚੋਂ ਲੰਘਦਾ ਹੈ, TypeScript AST ਤੋਂ ਸਪੈਸੀਫਾਇਰ ਇਕੱਠੇ ਕਰਦਾ ਹੈ (ਇਸ ਲਈ `import("…")` ਗਿਣਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ type-position `typeof import("…")` ਨਹੀਂ), ਅਤੇ tsconfig `paths` ਨੂੰ ਰਿਜ਼ੌਲਵ ਕਰਦਾ ਹੈ। ਇਹ 0 ਨਹੀਂ, ਸਗੋਂ **14** ਚੱਕਰ ਲੱਭਦਾ ਹੈ। ਕਿਉਂਕਿ ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ 14 ਚੱਕਰਾਂ ਨੂੰ ਗੇਟ PR ਵਿੱਚ ਠੀਕ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ, `check:cycles` ਹੁਣ ਇੱਕ **ਰੈਚਿਟ** ਹੈ (`--ratchet`, `quality-baseline.json` ਵਿੱਚ ਸੀਮਾ `metrics.cycles.value = 14`, `direction: down`) — ਇਹ ਕਿਸੇ ਵੀ _ਰਿਗ੍ਰੈਸ਼ਨ_ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ ਅਤੇ ਗਿਣਤੀ ਸਿਰਫ਼ ਘਟ ਸਕਦੀ ਹੈ। CI `npm run check:cycles:ratchet` ਚਲਾਉਂਦਾ ਹੈ। ਘਟਾਓ ਦਾ ਕੰਮ **A-01** ਦੇ ਨਾਲ ਚੱਲੇਗਾ। `check:circular-deps` (dpdm) ਵਿਆਪਕ ਦੂਜੀ ਰਾਏ ਵਜੋਂ ਸਲਾਹਕਾਰੀ ਰਹਿੰਦਾ ਹੈ। +- **ਜਟਿਲਤਾ** — ✅ **ਪੂਰਾ ਹੋਇਆ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ਇੱਕ ESLint ਵਾਕ, `ruleId` ਮੁਤਾਬਕ ਗਿਣਤੀ ਤਾਂ ਜੋ cyclomatic+max-lines ਅਤੇ cognitive ਬੇਸਲਾਈਨਾਂ ਸੁਤੰਤਰ ਰਹਿਣ; ਵੱਖਰੇ `check:complexity` / `check:cognitive-complexity` ਲੋਕਲ `--update` ਲਈ ਬਰਕਰਾਰ ਹਨ। +- **`/api` ਐਂਟੀ-ਹੈਲੂਸੀਨੇਸ਼ਨ** — ✅ **ਪੂਰਾ ਹੋਇਆ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` ਦੀ ਇੱਕ FS ਇਨਵੈਂਟਰੀ, openapi-routes + docs-symbols ਹਾਲੇ ਵੀ ਸੁਤੰਤਰ ਤੌਰ 'ਤੇ ਰਿਪੋਰਟ ਕਰਦੇ ਹਨ; ਵੱਖਰੇ ਚੈਕ ਲੋਕਲ ਰਨਾਂ ਲਈ ਬਰਕਰਾਰ ਹਨ। +- **`check:node-runtime` 11 ਜੌਬਾਂ ਵਿੱਚ ਚੱਲਦਾ ਹੈ** — ⚠️ **ਘੱਟ ROI।** ਹਰ ਇੱਕ ਵੱਖਰਾ ਰਨਰ ਹੈ ਅਤੇ ਚੈਕ <1s ਲੈਂਦਾ ਹੈ; ਇੱਕ ਸਸਤੇ ਪ੍ਰਤੀ-ਜੌਬ ਗਾਰਡ ਨੂੰ ਗੁਆਉਣ ਦੇ ਮੁਕਾਬਲੇ ਕੁੱਲ ਬਚਤ ~10s ਹੈ। ਇੰਨੀ ਉਥਲ-ਪੁਥਲ ਦੇ ਯੋਗ ਨਹੀਂ। +- **CI lint 'ਤੇ `typecheck:noimplicit:core`** — ✅ **lint ਜੌਬ ਤੋਂ ਹਟਾਇਆ ਗਿਆ** (ਇਹ ਸਲਾਹਕਾਰੀ `continue-on-error` ਸੀ); ਬਲੌਕਿੰਗ type ਸਤਹ `typecheck:core` + `check:type-coverage` ਹੈ। ਲੋਕਲ ਸਕ੍ਰਿਪਟ ਬਰਕਰਾਰ ਹੈ। -### ਫਲਿੱਪ / ਫ਼ੈਸਲਾ ਕਰੋ (ਆਪਰੇਟਰ ਨੀਤੀ) +### ਫਲਿਪ / ਫੈਸਲਾ ਕਰੋ (ਓਪਰੇਟਰ ਨੀਤੀ) -- `check:openapi-security-tiers` (ਸਲਾਹਕਾਰੀ) — ❌ **ਸਾਫ਼ ਤੌਰ 'ਤੇ ਫਲਿੱਪ ਕਰਨਯੋਗ ਨਹੀਂ।** ਇਹ 0 ਨਾਲ ਬੰਦ ਹੁੰਦਾ ਹੈ, ਪਰ ਚੇਤਾਵਨੀ ਦਿੰਦਾ ਹੈ ਕਿ `LOCAL_ONLY_API_PREFIXES` ਹੇਠ ਕਈ `traffic-inspector` ਰੂਟਾਂ ਵਿੱਚ `x-loopback-only: true` ਐਨੋਟੇਸ਼ਨ ਮੌਜੂਦ ਨਹੀਂ ਹੈ। ਇਸਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਪਹਿਲਾਂ ਉਹ ਐਨੋਟੇਸ਼ਨ `openapi.yaml` ਵਿੱਚ ਸ਼ਾਮਲ ਕਰਨੇ ਲਾਜ਼ਮੀ ਹਨ। -- `typecheck:noimplicit:core` (ਸਲਾਹਕਾਰੀ) — ਬਲੌਕਿੰਗ `check:type-coverage` ਰੈਚਟ ਵੱਲੋਂ ਕਾਫ਼ੀ ਹੱਦ ਤੱਕ ਸਮੇਟਿਆ ਗਿਆ ਹੈ। ਇਸਨੂੰ ਰੈਚਟ ਵਿੱਚ ਫਲਿੱਪ ਕਰੋ ਜਾਂ ਫ਼ਾਲਤੂ ਦੂਜਾ `tsc` ਪਾਸ ਹਟਾਓ। -- `test:vitest:ui` (ਹੁਣ **ਬਲੌਕਿੰਗ**) — ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਅਸਫਲਤਾਵਾਂ ਨੂੰ `vitest.config.ts` ਵਿੱਚ `// #8618` ਟ੍ਰੈਕਿੰਗ ਟਿੱਪਣੀਆਂ ਨਾਲ ਸਪਸ਼ਟ ਤੌਰ 'ਤੇ ਬਾਹਰ ਰੱਖਿਆ ਗਿਆ ਹੈ; ਨਵੀਆਂ ਅਸਫਲਤਾਵਾਂ ਜੌਬ ਨੂੰ ਫੇਲ੍ਹ ਕਰਦੀਆਂ ਹਨ। -- `check:secrets` (gitleaks, 3 ਦਸਤਾਵੇਜ਼ਬੱਧ ਗਲਤ-ਸਕਾਰਾਤਮਕਾਂ ਉੱਤੇ ਜਮਾਇਆ ਹੋਇਆ ਬਲੌਕਿੰਗ ਰੈਚਟ) — 0 ਤੱਕ ਪਹੁੰਚਣ ਲਈ ਉਨ੍ਹਾਂ 3 ਨੂੰ allowlist ਕਰੋ, ਜਾਂ ਇਸਨੂੰ ਸਲਾਹਕਾਰੀ ਦਰਜੇ ਤੱਕ ਘਟਾਓ। GitHub ਦੀ ਮੂਲ secret-scanning + `check:public-creds` ਨਾਲ ਓਵਰਲੈਪ ਕਰਦਾ ਹੈ। -- `check:pr-evidence` (ਬਲੌਕਿੰਗ, PR-body ਗੱਦ ਨੂੰ greps ਕਰਦਾ ਹੈ) — ਗਲਤ-ਸਕਾਰਾਤਮਕ ਦਾ ਉੱਚ ਜੋਖਮ; ਹਟਾਉਣ ਨਾਲ Hard Rule #18 ਦੀ ਲਾਗੂਅਤ ਕਮਜ਼ੋਰ ਹੁੰਦੀ ਹੈ, ਇਸ ਲਈ ਇਹ ਸੱਚਮੁੱਚ ਇੱਕ ਨੀਤੀਗਤ ਫ਼ੈਸਲਾ ਹੈ। -- `semgrep` (ਵੱਖਰਾ ਸਲਾਹਕਾਰੀ) — OWASP ਪਰਿਵਾਰਾਂ ਲਈ CodeQL ਨਾਲ ਓਵਰਲੈਪ ਕਰਦਾ ਹੈ; ਇਸਦੀ ਬੇਸਲਾਈਨ ਨੂੰ ਕਿਸੇ ਰੈਚਟ ਨਾਲ ਜੋੜੋ ਜਾਂ ਹਟਾਓ। +- `check:openapi-security-tiers` (ਸਲਾਹਕਾਰੀ) — ❌ **ਸਾਫ਼ ਤਰੀਕੇ ਨਾਲ ਫਲਿਪ ਕਰਨਯੋਗ ਨਹੀਂ।** ਇਹ 0 ਨਾਲ ਬਾਹਰ ਨਿਕਲਦਾ ਹੈ ਪਰ ਚੇਤਾਵਨੀ ਦਿੰਦਾ ਹੈ ਕਿ `LOCAL_ONLY_API_PREFIXES` ਹੇਠ ਕਈ `traffic-inspector` ਰੂਟਾਂ ਵਿੱਚ `x-loopback-only: true` ਐਨੋਟੇਸ਼ਨ ਮੌਜੂਦ ਨਹੀਂ ਹੈ। ਇਸਨੂੰ ਲਾਗੂ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਹ ਐਨੋਟੇਸ਼ਨਾਂ `openapi.yaml` ਵਿੱਚ ਜੋੜਨੀਆਂ ਪੈਣਗੀਆਂ। +- `typecheck:noimplicit:core` (ਸਲਾਹਕਾਰੀ) — ਬਲੌਕਿੰਗ `check:type-coverage` ਰੈਚਿਟ ਵੱਲੋਂ ਵੱਡੇ ਪੱਧਰ 'ਤੇ ਕਵਰ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਸਨੂੰ ਰੈਚਿਟ ਵਿੱਚ ਫਲਿਪ ਕਰੋ ਜਾਂ ਫ਼ਾਲਤੂ ਦੂਜਾ `tsc` ਪਾਸ ਹਟਾਓ। +- `test:vitest:ui` (ਹੁਣ **ਬਲੌਕਿੰਗ**) — ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਅਸਫਲਤਾਵਾਂ ਨੂੰ `vitest.config.ts` ਵਿੱਚ `// #8618` ਟ੍ਰੈਕਿੰਗ ਟਿੱਪਣੀਆਂ ਨਾਲ ਸਪਸ਼ਟ ਤੌਰ 'ਤੇ ਬਾਹਰ ਰੱਖਿਆ ਗਿਆ ਹੈ; ਨਵੀਆਂ ਅਸਫਲਤਾਵਾਂ ਜੌਬ ਨੂੰ ਫੇਲ ਕਰਦੀਆਂ ਹਨ। +- `check:secrets` (gitleaks, 3 ਦਸਤਾਵੇਜ਼ਬੱਧ false-positives 'ਤੇ ਜੰਮਿਆ ਬਲੌਕਿੰਗ ਰੈਚਿਟ) — 0 ਤੱਕ ਪਹੁੰਚਣ ਲਈ ਉਹਨਾਂ 3 ਨੂੰ allowlist ਕਰੋ, ਜਾਂ ਸਲਾਹਕਾਰੀ ਦਰਜੇ 'ਤੇ ਘਟਾਓ। ਇਹ GitHub ਦੀ ਮੂਲ secret-scanning + `check:public-creds` ਨਾਲ ਓਵਰਲੈਪ ਕਰਦਾ ਹੈ। +- `check:pr-evidence` (ਬਲੌਕਿੰਗ, PR-body ਗੱਥ ਨੂੰ grep ਕਰਦਾ ਹੈ) — false-positive ਦਾ ਉੱਚ ਜੋਖਮ; ਹਟਾਉਣ 'ਤੇ Hard Rule #18 ਦੀ ਲਾਗੂਕਰਨ ਸਮਰੱਥਾ ਕਮਜ਼ੋਰ ਹੁੰਦੀ ਹੈ, ਇਸ ਲਈ ਇਹ ਇੱਕ ਅਸਲ ਨੀਤੀਗਤ ਫੈਸਲਾ ਹੈ। +- `semgrep` (ਵੱਖਰਾ ਸਲਾਹਕਾਰੀ) — OWASP ਪਰਿਵਾਰਾਂ ਲਈ CodeQL ਨਾਲ ਓਵਰਲੈਪ ਕਰਦਾ ਹੈ; ਇਸਦੀ ਬੇਸਲਾਈਨ ਨੂੰ ਕਿਸੇ ਰੈਚਿਟ ਨਾਲ ਜੋੜੋ ਜਾਂ ਹਟਾਓ। --- diff --git a/docs/i18n/phi/CONTRIBUTING.md b/docs/i18n/phi/CONTRIBUTING.md index d48e3861963..01af88ee295 100644 --- a/docs/i18n/phi/CONTRIBUTING.md +++ b/docs/i18n/phi/CONTRIBUTING.md @@ -392,17 +392,17 @@ Sumulat ng mga unit test sa `tests/unit/` na sumasaklaw, bilang minimum, sa: - [ ] Pumapasa ang mga test (`npm test`) - [ ] Pumapasa ang linting (`npm run lint`) - [ ] Matagumpay ang build (`npm run build`) -- [ ] Naidagdag ang mga TypeScript type para sa mga bagong pampublikong function at interface -- [ ] Walang mga naka-hardcode na secret o fallback value -- [ ] Naka-embed ang mga pampublikong upstream credential sa pamamagitan ng `resolvePublicCred()` (tingnan ang [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), at hindi kailanman bilang mga literal -- [ ] Dumadaan ang mga tugon sa error sa `buildErrorBody()` / `sanitizeErrorMessage()` — walang mga raw stack trace sa mga response body (tingnan ang [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Ipinapasa ng mga shell command (`exec` / `spawn`) ang mga runtime value sa pamamagitan ng `env`, hindi sa pamamagitan ng string interpolation -- [ ] Na-validate ang lahat ng input gamit ang mga Zod schema -- [ ] Nagdagdag ng **fragment** ng changelog sa ilalim ng `changelog.d/{features|fixes|maintenance}/-.md` para sa mga pagbabagong nakikita ng user (tingnan ang [`changelog.d/README.md`](./changelog.d/README.md)) — **huwag** direktang i-edit ang `CHANGELOG.md`; pinagsasama-sama ang mga fragment sa oras ng release at hindi kailanman nagkakaroon ng conflict sa pagitan ng mga PR +- [ ] Nagdagdag ng mga TypeScript type para sa mga bagong pampublikong function at interface +- [ ] Walang naka-hardcode na mga secret o fallback value +- [ ] Ang mga pampublikong upstream credential ay naka-embed sa pamamagitan ng `resolvePublicCred()` (tingnan ang [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), at hindi kailanman bilang mga literal +- [ ] Ang mga error response ay dumaraan sa `buildErrorBody()` / `sanitizeErrorMessage()` — walang mga raw stack trace sa mga response body (tingnan ang [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Ang mga shell command (`exec` / `spawn`) ay nagpapasa ng mga runtime value sa pamamagitan ng `env`, hindi sa pamamagitan ng string interpolation +- [ ] Napatunayan ang bisa ng lahat ng input gamit ang mga Zod schema +- [ ] Nagdagdag ng **fragment** ng changelog sa ilalim ng `changelog.d/{features|fixes|maintenance}/-.md` para sa mga pagbabagong nakikita ng user (tingnan ang [`changelog.d/README.md`](./changelog.d/README.md)) — **huwag** direktang i-edit ang `CHANGELOG.md`; pinagsasama-sama ang mga fragment sa oras ng release at hindi kailanman nagkakasalungatan sa pagitan ng mga PR - [ ] Na-update ang dokumentasyon (kung naaangkop) -- [ ] Walang bagong nabuksang alerto mula sa CodeQL / Secret-Scanning, o na-dismiss ang bawat isa nang may teknikal na katwirang tumutukoy sa nauugnay na dokumento sa `docs/security/` +- [ ] Walang bagong nabuksang alerto mula sa CodeQL / Secret-Scanning, o ang bawat isa ay na-dismiss nang may teknikal na katwiran na tumutukoy sa nauugnay na dokumento sa `docs/security/` - [ ] Ang mga route na naglulunsad ng mga child process (`/api/mcp/`, `/api/cli-tools/runtime/`) ay inuri bilang `isLocalOnlyPath()` sa `src/server/authz/routeGuard.ts` — tingnan ang [Mahigpit na Panuntunan #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Walang mga trailer na `Co-Authored-By` sa mga commit message — dapat lumabas ang mga commit sa ilalim lamang ng Git identity ng may-ari ng repository (Mahigpit na Panuntunan #16) +- [ ] Walang mga AI/bot na `Co-authored-by` trailer sa mga commit message (Mahigpit na Panuntunan #16) — ang mga taong collaborator na muling ginamit ang gawa ay kinikilala gamit ang karaniwang `Co-authored-by: Name ` na mga trailer --- diff --git a/docs/i18n/phi/docs/architecture/QUALITY_GATES.md b/docs/i18n/phi/docs/architecture/QUALITY_GATES.md index 948731566eb..7426a3b938d 100644 --- a/docs/i18n/phi/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/phi/docs/architecture/QUALITY_GATES.md @@ -15,228 +15,231 @@ plano ng replikasyon ng parehong sistema, tingnan ang --- -## Imbentaryo ng mga gate at profile ng pagpapatupad +## Imbentaryo ng gate at mga profile ng pagpapatupad ### Pagtanggap ng kandidato -Ang mga workflow ng CI at Quality Gates ay parehong naglalabas ng matatag na hatol: `Gate / CI` at -`Gate / Quality`. Inililista ng naka-bersyong patakaran sa pagtanggap ng mga ito ang bawat upstream na job -bilang kinakailangan o advisory. Dapat magtagumpay ang isang naaangkop na kinakailangang job: ang mga resultang -nawawala, kinansela, nilaktawan, nakabinbin, at hindi alam ay hindi makapagtatatag ng PASS. Maaaring gawing -hindi naaangkop ang isang code lane ng wastong klasipikasyong docs-only o catalog-only; -ang isang draft na PR ay hindi tinatanggap na kandidato. Hindi inaalis ng label na `hotfix` ang pangangailangan sa ebidensya. +Ang mga workflow ng CI at Quality Gates ay parehong naglalabas ng matatag na pasya: `Gate / CI` at +`Gate / Quality`. Inililista ng kanilang may-bersyong patakaran sa pagtanggap ang bawat upstream job +bilang kinakailangan o advisory. Dapat magtagumpay ang isang naaangkop na kinakailangang job: ang mga +resultang nawawala, kinansela, nilaktawan, nakabinbin, at hindi alam ay hindi makapagtatatag ng PASS. Maaaring +gawing hindi naaangkop ang isang code lane ng wastong klasipikasyong docs-only o catalog-only; +ang draft na PR ay hindi tinatanggap na kandidato. Hindi inaalis ng label na `hotfix` ang pangangailangan sa ebidensya. -Saklaw ng parehong workflow ang mga PR at push sa mga main/release branch, manual dispatch, at -merge-group event. Isinasagawa ng push, dispatch, at merge-group ang buong seleksyon. Gumagamit ang mga fork -at merge group ng mga hosted runner para sa mga job na karaniwang pumipili ng mga self-hosted +Saklaw ng parehong workflow ang mga PR at push sa mga main/release branch, manu-manong dispatch, at +mga merge-group event. Isinasagawa ng push, dispatch, at merge-group ang buong seleksyon. Gumagamit ang mga fork +at merge group ng mga hosted runner para sa mga job na kung hindi ay pipili ng mga self-hosted runner; dapat beripikahin ang sapat na hosted capacity bago ang rollout. Tinutukoy ng bawat JSON receipt ang na-checkout na SHA, workflow run, at attempt. -Tinatanggihan ng CLI ang hindi pagtutugma ng checkout/event SHA. Itinatali ng mga workflow test ang pagiging miyembro sa patakaran -sa listahan ng `needs` ng verdict job upang hindi palihim na mawala ang bago o inalis na lane. +Tinatanggihan ng CLI ang hindi pagtutugma ng checkout/event SHA. Iniuugnay ng mga workflow test ang pagiging miyembro ng patakaran +sa listahan ng `needs` ng verdict job upang hindi tahimik na mawala ang isang bago o inalis na lane. Saklaw ng mga receipt ang sarili nilang workflow, hindi ang publication, deployment, o mga internal -ng isang umiiral na advisory scanner. Ang pag-activate sa parehong pangalan ng check sa mga panuntunan ng branch ay isang -hiwalay na administratibong pagbabago; ang pagdaragdag sa mga job na ito ay hindi kusang nagpoprotekta sa isang branch. +na bahagi ng isang umiiral na advisory scanner. Ang pag-activate sa parehong pangalan ng check sa mga branch rule ay isang +hiwalay na pagbabagong administratibo; hindi awtomatikong napoprotektahan ang isang branch sa pagdaragdag lamang ng mga job na ito. ### Imbentaryo ng static scan -Ang naka-bersyong imbentaryo ng npm-alias at pagiging miyembro sa static-scan ay nasa -`config/quality/gate-manifest.json`. Patakbuhin ang `npm run check:gate-manifest` upang patotohanan +Makikita sa `config/quality/gate-manifest.json` ang may-bersyong imbentaryo ng npm-alias at ang pagiging miyembro ng static-scan. +Patakbuhin ang `npm run check:gate-manifest` upang patunayan ang mga pangalan ng script at eksaktong command laban sa `package.json`; kapag may idinagdag, inalis, o -nagbago ang command, mabibigo ang parehong local hook at mga change-classification job sa CI. +nagbago sa command, mabibigo ang lokal na hook at ang mga change-classification job sa CI. Ang alias ay hindi workflow job, matrix instance, o test case: hindi dapat ipakita ang mga bilang na ito na para bang mapagpapalit ang mga ito. Gamitin ang `npm run quality:scan -- --list` o `npm run quality:scan:fast -- --list` -upang siyasatin ang mga napiling alias nang hindi isinasagawa ang mga ito. Ginagamit ng runner ang -npm entrypoint, kaya napapanatili ang runtime nito (kabilang ang Bun kung naka-configure). -Itinatala ng manifest ang mga alias sa labas ng mga profile na iyon bilang hiwalay na isinasagawa, at +upang suriin ang mga napiling alias nang hindi isinasagawa ang mga ito. Tinatawag ng runner ang +npm entrypoint, kaya napapanatili ang runtime nito (kabilang ang Bun kung saan naka-configure). +Itinatala ng manifest bilang hiwalay na tinatawag ang mga alias na wala sa mga profile na iyon, at ipinagbabawal ang mga maintenance command sa mga read-only na profile ng scan. -Static scan lamang ang saklaw ng mga profile na ito. Hindi nito sinesertipikahan ang mga product test, +Ang static scan lamang ang saklaw ng mga profile na ito. Hindi nila sinesertipika ang mga product test, coverage, packaging, external check, o buong pagtanggap sa release ng isang kandidato. -Ginagamit ng pagtanggap sa workflow ang naka-link na `config/quality/admission-policy.json` at -`scripts/quality/admission-verdict.mjs`. Nananatiling hiwalay ang mga profile ng release-observer; -siyasatin nang hiwalay ang mga naaangkop na check at receipt ng mga ito. Ang tekstuwal na -imbentaryo sa ibaba ay sanggunian, hindi patunay na talagang naisagawa ang isang gate. +Ginagamit ng workflow admission ang naka-link na `config/quality/admission-policy.json` at +`scripts/quality/admission-verdict.mjs`. Nananatiling hiwalay ang mga release-observer profile; +suriin nang hiwalay ang kanilang mga naaangkop na check at receipt. Ang tekstuwal na +imbentaryo sa ibaba ay sanggunian, hindi patunay na aktuwal na tumakbo ang isang gate. Matatagpuan ang mga script sa ilalim ng `scripts/check/` (mga policy gate) at `scripts/quality/` (ratchet engine). Ang pinagmumulan ng katotohanan para sa CI ay `.github/workflows/ci.yml`. -### Mabilis na landas ng Release PR (`quality.yml`) +### Mabilis na landas ng release PR (`quality.yml`) -Kinukumpleto ng `.github/workflows/quality.yml` ang CI sa mga main/release PR, push sa protected branch, -dispatch, at merge group. Gumagamit ang mga PR ng mga mabilis na check na sinala ayon sa path. Inalis ang permanenteng -naka-disable na duplicate build; nananatili sa CI ang mga tunay na check para sa build/package/boot. +Dinadagdagan ng `.github/workflows/quality.yml` ang CI sa mga main/release PR, push sa protected branch, +dispatch, at merge group. Gumagamit ang mga PR ng mga path-filtered na mabilis na check. Inalis ang permanenteng +naka-disable na dobleng build; nananatili sa CI ang mga tunay na check para sa build/package/boot. -| Job | Saklaw | Nakakaharang | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | -| `Docs Gates (fast-path)` | Mga PR ng docs/code; mga reference ng API docs at docs-all | Oo | -| `Fast Quality Gates` | Mga PR ng code; mga static check, typecheck, dashboard typecheck, at mga apektadong unit test | Oo | -| `Forgotten sibling tests` | Mga PR ng code; tinutunton ang mga nabagong module patungo sa mga static consumer at kandidatong sibling test; iniuulat bilang mga advisory diagnostic ang mga barrel at dynamic-import path, kasama ang mga naka-reference na pagbubukod sa allowlist | **Advisory** | -| `Vitest (fast-path)` | Mga PR ng code; mabilis na vitest suite | Oo | -| `Unit Tests fast-path` | Mga PR ng code; 4-shard na unit suite | Oo | -| `No new ESLint warnings` | Mga PR ng code; suppressions-aware na lint guard | Oo, kabilang ang mga fork | -| `Merge integrity (changelog + generated skills)` | Mga hindi draft na PR; changelog at pag-sync ng mga nabuong skill | Oo, kabilang ang mga fork | +| Job | Saklaw | Humaharang | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| `Docs Gates (fast-path)` | Mga docs/code PR; mga sanggunian sa API docs at docs-all | Oo | +| `Fast Quality Gates` | Mga code PR; mga static check, typecheck, dashboard typecheck, at mga apektadong unit test | Oo | +| `Forgotten sibling tests` | Mga code PR; sinusundan ang mga binagong module patungo sa mga static consumer at kandidatong sibling test; iniuulat ang mga barrel at dynamic-import path bilang mga advisory diagnostic, kasama ang mga binanggit na allowlist exception | **Advisory** | +| `Vitest (fast-path)` | Mga code PR; mabilis na vitest suite | Oo | +| `Unit Tests fast-path` | Mga code PR; 4-shard na unit suite | Oo | +| `No new ESLint warnings` | Mga code PR; suppression-aware na lint guard | Oo, kabilang ang mga fork | +| `Merge integrity (changelog + generated skills)` | Mga hindi draft na PR; pag-sync ng changelog at mga nabuong skill | Oo, kabilang ang mga fork | #### Ulat ng mga nakaligtaang sibling test -Muling ginagamit ng `npm run check:forgotten-sibling-tests` ang import resolver sa likod ng mapa ng epekto sa test. -Para sa bawat nabagong production module, nag-uulat ito ng mga deterministikong chain na -`changed module/symbol -> static consumer -> candidate sibling test` kapag wala ang kandidatong -test sa diff ng pull request. Pinananatili ang buod na Markdown at resultang JSON bilang -workflow artifact na `forgotten-sibling-tests` para sa calibration bago ang anumang blocking rollout. +Muling ginagamit ng `npm run check:forgotten-sibling-tests` ang import resolver sa likod ng test-impact map. +Para sa bawat binagong production module, nag-uulat ito ng mga deterministikong +`changed module/symbol -> static consumer -> candidate sibling test` chain kapag wala ang kandidatong +test sa diff ng pull request. Pinananatili ang Markdown summary at JSON result bilang +workflow artifact na `forgotten-sibling-tests` para sa pagkakalibrate bago ang anumang blocking rollout. Ang mga barrel re-export at dynamic import ay para lamang sa mga diagnostic ng resolution; hindi kailanman lumilikha ang mga ito ng -finding na nakaka-block. Ang mga nasuring exception ay nasa +finding na nakakaharang. Ang mga nasuring exception ay nasa `config/quality/forgotten-sibling-allowlist.json`. Dapat tukuyin ng bawat entry ang consumer at candidate -test, magbigay ng partikular na katwiran, at mag-link sa isang GitHub issue o pull request. Kapag malformed ang mga entry, -awtomatikong bina-block ang mga ito. Hindi maaaring i-suppress ng mga exception ang isang tinanggal na candidate test o isang diff na nagdaragdag ng `.skip`/`.todo`; -ang pagpapahina ng assertion at iba pang masking ay nananatiling saklaw ng hiwalay na blocking -gate na `check:test-masking`. +test, magbigay ng partikular na katwiran, at mag-link sa isang GitHub issue o pull request. Ang mga entry na mali ang pagkakabuo ay +awtomatikong ibinabagsak. Hindi maaaring pigilan ng mga exception ang isang na-delete na candidate test o isang diff na nagdaragdag ng `.skip`/`.todo`; +ang pagpapahina ng assertion at iba pang pagtatakip ay nananatiling saklaw ng hiwalay na nakakaharang na +`check:test-masking` gate. ### Job: `lint` -Tumatakbo sa bawat PR patungo sa `main`. Bina-block ang merge kapag nabigo. - -| Script (`npm run ...`) | Bine-validate | Nagba-block | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `check:node-runtime` | Ang bersyon ng Node.js ay nasa loob ng sinusuportahang saklaw | Oo | -| `check:cycles` | Mga circular import — lahat ng module sa `src/` + `open-sse/` | Oo | -| `check:route-validation:t06` | May mga Zod schema sa lahat ng route (patakaran ng Tier 6) | Oo | -| `check:any-budget:t11` | Hindi lumalampas sa budget ang bilang ng `@ts-expect-error // any` (Tier 11 catraca) | Oo | -| `check:provider-consistency` | Ang bawat provider sa `providers.ts` ay may katugmang entry sa `providerRegistry.ts` (at kabaliktaran, sa loob ng allowlist) | Oo | -| `check:model-lifecycle` | Nananatiling magkakatugma ang tatlong mano-manong pinapanatiling routing table sa naka-check-in na lifecycle snapshot (#11503): walang retired id na binibigyan ng score ng `FITNESS_TABLE` (`taskFitness.ts`) na maaaring i-route ng `REGISTRY`; naroroon sa `REGISTRY` at wala sa retired-id snapshot ang bawat target ng `BUILT_IN_ALIASES`; ang bawat retired id na nasa `REGISTRY` pa rin ay ipinapasa o nakalista sa `allowedRetiredInCatalog`; at walang source o target ng `DEFAULT_DEGRADATION_MAP` na lumalabas bilang retired sa snapshot na iyon. Hindi nito pinatutunayan na kasalukuyang sineserbisyuhan ng live upstream ang isang modelo. Offline — inihahambing sa `config/quality/model-lifecycle.json`, na mano-manong nire-refresh gamit ang `npm run quality:refresh-model-lifecycle` (network; hindi naka-wire sa CI). Ang `allowedRetiredInCatalog` ay isang burn-down ratchet: magdagdag lamang ng entry na may tracking issue. | Oo | -| `check:fetch-targets` | Ang bawat `fetch("/api/...")` sa client-side na `src/` ay tumutukoy sa isang totoong `route.ts` | Oo | -| `check:deps` | Ang lahat ng dependency na maaaring i-`npm install` mula sa bawat `package.json` sa repo ay nasa `dependency-allowlist.json`; bina-flag ang mga bagong package na hindi naka-pin o slopsquatted | Oo | -| `audit:deps` | `npm audit` (root + electron) — walang high/critical na advisory (nag-o-overlap sa osv `check:vuln-ratchet`; tingnan ang Rationalization Backlog) | Oo | -| `check:lockfile` | Integridad ng `package-lock.json` — https registry, mga integrity hash, walang host override | Oo | -| `check:licenses` | Allowlist ng lisensyang SPDX para sa mga dependency sa production | Oo | -| `check:tracked-artifacts` | Walang mga artifact ng build / naka-commit na mga symlink ng `node_modules` (tumatakbo rin sa husky pre-commit; sadyang magaan ang pre-push — #6716) | Oo | -| `check:ai-attribution` | Walang trailer na `Co-Authored-By` mula sa AI/bot o footer ng pagbuo ng AI sa mga commit, pamagat, o katawan ng PR — Mahigpit na Panuntunan #16 (sa fast-gates loop ng `quality.yml` para sa PR→`release/**` — binabasa ang event payload, walang ginagawa sa labas ng mga PR — at isang hakbang na para lamang sa PR sa lint ng `ci.yml` para sa PR→`main`; pati na rin ang husky hook na `commit-msg`; pinapayagan ang mga taong co-author; #14436) | -| `check:vitest-exclusions` | Ang bawat pagbubukod sa Vitest ay tumutukoy sa isang tracking issue at lumilitaw sa `config/quality/vitest-exclusions.json` (#13204) | Oo | -| `check:file-size` | Walang source file na lumalampas sa limitasyon para sa bawat extension (ratchet: ang malalaking file na hindi na maaaring lumaki ay nasa listahang `frozen`) | Oo | -| `check:error-helper` | Ginagamit ng mga tugon sa error sa mga executor/handler ang `buildErrorBody()` / `sanitizeErrorMessage()` (Mahigpit na Panuntunan #12) | Oo | -| `check:migration-numbering` | Ang mga Migration SQL file ay sunod-sunod ang pagnunumero, walang puwang o duplikado | Oo | -| `check:public-creds` | Walang literal na OAuth `client_id`/`client_secret` o mga Firebase Web key sa labas ng `publicCreds.ts` (Mahigpit na Panuntunan #11) | Oo | -| `check:db-rules` | Walang raw SQL sa labas ng mga module ng `src/lib/db/`; walang mga barrel import mula sa `localDb.ts` (Mahihigpit na Panuntunan #2/#5) | Oo | -| `check:known-symbols` | Ang mga provider executor, routing strategy, at translator na nakarehistro sa kani-kanilang mga dispatch table ay tumutugma sa mga file sa disk—walang mga ulila o hindi idineklarang simbolo | Oo | -| `check:route-guard-membership` | Ang bawat route na lumilikha ng child process ay inuuri ng `isLocalOnlyPath()` (Mahihigpit na Panuntunan #15/#17) | Oo | -| `check:test-discovery` | Ang bawat `*.test.ts` / `*.spec.ts` file sa repo ay kinokolekta ng kahit isang test runner (ratchet: maaari lamang lumiit ang listahan ng mga ulila sa `test-discovery-baseline.json`) | Oo | -| `check:agent-skills-sync` | Tumutugma ang mga nabuong agent-skills artifact sa kanilang source catalog (walang drift) | -| `check:provider-asset-provenance` | May nakatalang provenance entry ang mga logo/asset ng provider | -| `lint:json` | Napi-parse ang mga JSON config file at sumusunod ang mga ito sa mga lint rule ng repo | -| `typecheck:core` | Pag-compile ng TypeScript nang walang mga error (mga advisory warning lamang) | Oo | -| `typecheck:noimplicit:core` | Mahigpit na `noImplicitAny` — nakatuon sa hinaharap; kailangan pa rin ng mga annotation ang maraming dati nang call site | **Advisory** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` na nakatuon sa `src/app/(dashboard)/**` (#7033) — hindi kasama sa piniling 27-file allowlist ng `typecheck:core` ang anumang dashboard TSX, at hindi rin ito kailanman tine-type-check ng `next build` (itinatakda ng `next.config.mjs` ang `ignoreBuildErrors: true`), kaya hindi nakikita ng CI ang mga orphaned-identifier regression doon (#6625/#6909). Inihahambing sa isang naka-freeze na baseline ng bilang sa bawat file/bawat TS code (`config/quality/dashboard-typecheck-baseline.json`, kaparehong pattern ng stale-enforcement gaya ng `check:known-symbols`) — tanging mga BAGONG error na lampas sa naka-baseline na bilang ang magpapabagsak sa gate; unti-unting pababain gamit ang `--update` kapag naayos ang isang dati nang error. | Oo | +Tumatakbo sa bawat PR patungong `main`. Hinaharang ang merge kapag nabigo. + +| Script (`npm run ...`) | Bine-validate | Nakakaharang | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | +| `check:node-runtime` | Ang bersyon ng Node.js ay nasa loob ng suportadong saklaw | Oo | +| `check:cycles` | Mga circular import sa buong `src/` + `open-sse/` (nakabatay sa AST, ni-resolve ang `paths` ng tsconfig). Bare = advisory, inililista ang mga cycle. Hinaharang ng `check:cycles:ratchet` (ang pinapatakbo ng CI) kapag lumampas ang bilang sa limitasyong `metrics.cycles` sa `quality-baseline.json` — kasalukuyang 14, `direction: down`, kaya maaari lamang itong bumaba (#15159 G-01/G-02) | Oo (ratchet) | +| `check:route-validation:t06` | May mga Zod schema sa lahat ng route (patakaran ng Tier 6) | Oo | +| `check:any-budget:t11` | Ang bilang ng `@ts-expect-error // any` ay hindi lumalampas sa budget (Tier 11 catraca) | Oo | +| `check:provider-consistency` | Ang bawat provider sa `providers.ts` ay may katugmang entry sa `providerRegistry.ts` (at vice-versa, sa loob ng allowlist) | Oo | +| `check:model-lifecycle` | Ang tatlong routing table na mano-manong pinananatili ay nananatiling tugma sa naka-check-in na lifecycle snapshot (#11503): walang retired id na maaaring i-route ng `REGISTRY` ang binibigyan ng score ng `FITNESS_TABLE` (`taskFitness.ts`); ang bawat target ng `BUILT_IN_ALIASES` ay nasa `REGISTRY` at wala sa retired-id snapshot; ang bawat retired id na nasa `REGISTRY` pa rin ay naka-forward o nakalista sa `allowedRetiredInCatalog`; at walang source o target ng `DEFAULT_DEGRADATION_MAP` ang lumilitaw na retired sa snapshot na iyon. Hindi nito pinatutunayan na ang isang modelo ay kasalukuyang sineserbisyuhan ng isang live upstream. Offline — inihahambing sa `config/quality/model-lifecycle.json`, na mano-manong nire-refresh gamit ang `npm run quality:refresh-model-lifecycle` (network; hindi naka-wire sa CI). Ang `allowedRetiredInCatalog` ay isang burn-down ratchet: magdagdag lamang ng entry kung may tracking issue. | Oo | +| `check:fetch-targets` | Ang bawat `fetch("/api/...")` sa client-side na `src/` ay tumutukoy sa isang tunay na `route.ts` | Oo | +| `check:deps` | Ang lahat ng dependency na maaaring i-`npm install` mula sa bawat `package.json` sa repo ay nasa `dependency-allowlist.json`; mina-flag ang mga bagong package na hindi naka-pin o slopsquatted | Oo | +| `audit:deps` | `npm audit` (root + electron) — walang high/critical na advisory (nag-o-overlap sa osv `check:vuln-ratchet`; tingnan ang Backlog ng Rasyonalisasyon) | Oo | +| `check:lockfile` | Integridad ng `package-lock.json` — https registry, mga integrity hash, walang host override | Oo | +| `check:licenses` | Allowlist ng lisensyang SPDX para sa mga dependency sa production | Oo | +| `check:tracked-artifacts` | Walang mga artifact ng build / naka-commit na mga symlink ng `node_modules` (tumatakbo rin sa husky pre-commit; sadyang magaan ang pre-push — #6716) | Oo | +| `check:ai-attribution` | Walang trailer na AI/bot `Co-Authored-By` o footer ng pagbuo ng AI sa mga commit, pamagat, o katawan ng PR — Mahigpit na Panuntunan #16 (nasa fast-gates loop ng `quality.yml` para sa PR→`release/**` — binabasa ang event payload, walang ginagawa kapag hindi PR — at isang hakbang na para lamang sa PR sa lint ng `ci.yml` para sa PR→`main`; pati na rin ang husky hook na `commit-msg`; pinapayagan ang mga taong kapwa may-akda; #14436) | +| `check:vitest-exclusions` | Ang bawat pagbubukod sa Vitest ay nagbabanggit ng tracking issue at lumilitaw sa `config/quality/vitest-exclusions.json` (#13204) | Oo | +| `check:file-size` | Walang source file na lalampas sa limitasyon para sa bawat extension (ratchet: mga naka-freeze na malaking file sa listahang `frozen`) | Oo | +| `check:error-helper` | Gumagamit ang mga tugon sa error sa mga executor/handler ng `buildErrorBody()` / `sanitizeErrorMessage()` (Mahigpit na Panuntunan #12) | Oo | +| `check:migration-numbering` | Ang mga Migration SQL file ay sunod-sunod ang pagkakanumero, walang puwang o duplikado | Oo | +| `check:public-creds` | Walang literal na OAuth `client_id`/`client_secret` o mga Firebase Web key sa labas ng `publicCreds.ts` (Mahigpit na Panuntunan #11) | Oo | +| `check:db-rules` | Walang raw SQL sa labas ng mga module ng `src/lib/db/`; walang mga barrel import mula sa `localDb.ts` (Mahihigpit na Panuntunan #2/#5) | Oo | +| `check:known-symbols` | Ang mga provider executor, routing strategy, at translator na nakarehistro sa kani-kanilang dispatch table ay tumutugma sa mga file sa disk—walang nakahiwalay o hindi nakadeklarang mga symbol | Oo | +| `check:route-guard-membership` | Ang bawat route na lumilikha ng child process ay inuuri ng `isLocalOnlyPath()` (Mahihigpit na Panuntunan #15/#17) | Oo | +| `check:test-discovery` | Ang bawat `*.test.ts` / `*.spec.ts` file sa repo ay kinokolekta ng kahit isang test runner (ratchet: maaari lamang umikli ang listahan ng mga nakahiwalay na file sa `test-discovery-baseline.json`) | Oo | +| `check:agent-skills-sync` | Tumutugma ang mga nabuong artifact ng agent-skills sa kanilang source catalog (walang drift) | +| `check:provider-asset-provenance` | May nakatalang provenance entry ang mga logo/asset ng provider | +| `lint:json` | Nape-parse ang mga JSON config file at sumusunod ang mga ito sa mga panuntunan sa lint ng repo | +| `typecheck:core` | Pag-compile ng TypeScript nang walang mga error (mga advisory warning lamang) | Oo | +| `typecheck:noimplicit:core` | Mahigpit na `noImplicitAny` — nakatuon sa hinaharap; marami pa ring dati nang call site na nangangailangan ng mga annotation | **Advisory** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` na limitado sa `src/app/(dashboard)/**` (#7033) — hindi kasama sa piniling 27-file allowlist ng `typecheck:core` ang anumang dashboard TSX, at hindi rin ito kailanman tine-type-check ng `next build` (`next.config.mjs` ay nagtatakda ng `ignoreBuildErrors: true`), kaya hindi nakikita ng CI ang mga regression ng orphaned identifier doon (#6625/#6909). Inihahambing ang mga diff sa isang naka-freeze na baseline ng bilang ayon sa file/TS-code (`config/quality/dashboard-typecheck-baseline.json`, kaparehong pattern ng stale enforcement gaya ng `check:known-symbols`) — mga BAGONG error lamang na lampas sa naka-baseline na bilang ang nagpapabigo sa gate; unti-unting ibaba gamit ang `--update` kapag naayos ang dati nang error. | Oo | ### Job: `quality-gate` -Tumatakbo pagkatapos ng `test-coverage`. Hinaharangan ang pag-merge kapag nabigo. - -| Script | Bine-validate | Pagharang | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- | -| `quality:collect` | Gumagawa ng `quality-metrics.json` (bilang ng mga babala ng ESLint, coverage mula sa pinagsamang ulat ng shard) | Oo (bago ang ratchet) | -| `quality:ratchet` | Hindi umatras ang bawat metric sa `quality-baseline.json` (mga babala ng ESLint ≤ baseline; coverage ≥ baseline) | Oo | -| `check:duplication` | Hindi lumalampas ang pagdodoble ng code (jscpd@4) sa baseline sa `quality-baseline.json` | Oo | -| `check:complexity` | Hindi lumalampas sa cap ang cyclomatic complexity sa antas ng file (pangunahing ESLint `complexity` + `max-lines-per-function`) | Oo | -| `check:cognitive-complexity` | Ratchet ng cognitive complexity (`eslint-plugin-sonarjs`) — hiwalay na ESLint pass; parehong pinapatakbo ng CI bilang iisang hakbang na `check:complexity-ratchets` | Oo | -| `check:dead-code` | Hindi lumalala kumpara sa baseline ang ratchet ng mga hindi ginagamit na export / file (knip) | Oo | -| `check:compression-budget` | Budget ng compression benchmark — hindi dapat bumaba ang pinakamababang matitipid na token para sa bawat engine | Oo | -| `check:type-coverage` | Hindi bumababa ang percent-typed ratchet (`type-coverage`); higit na sinasaklaw nito ang `typecheck:noimplicit:core` | Oo | -| `check:codeql-ratchet` | Hindi dumarami ang mga bukas na alerto ng CodeQL (nagbabasa sa pamamagitan ng `gh api`; maayos na nilalaktawan kapag walang token) — iskedyul ng pag-refresh at manu-manong pag-trigger: tingnan ang "CodeQL ratchet" sa ibaba | Oo | - -### Job: `quality-extended` - -Ang buong job ay advisory (`continue-on-error: true`). Aktuwal na pinapatakbo ang mga ratchet na nakabatay sa npm; ini-install ang mga panlabas na scanner sa pamamagitan ng `gh release download` at kusang nilalaktawan (exit 0) kapag wala pa rin ang binary. - -| Script | Bine-validate | Pagharang | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `check:circular-deps` | Walang mga circular dependency (dpdm) | **Advisory** | -| `check:bundle-size` | Hindi lumalampas sa cap ang laki ng bundle | **Advisory** | -| `check:secrets` | Pag-scan ng mga lihim (gitleaks) — nilalaktawan kung wala ang binary | **Advisory** | -| `check:vuln-ratchet` | Hindi lumalala ang mga kahinaan ng dependency (osv-scanner) — nilalaktawan kung wala ang binary | **Advisory** | -| `check:workflows` | Pag-lint ng workflow (actionlint + zizmor); ang nawawala/sirang mga scanner, di-wastong ulat, o nawawalang baseline ng ratchet ay nabibigo bilang INCOMPLETE. Ang mga wastong natuklasan ay sumusunod sa napiling patakarang strict/advisory/ratchet | Kailangang maisagawa; humaharang sa CI ang zizmor ratchet | -| `check:openapi-breaking` | Mga breaking change sa pampublikong kontrata ng API (`openapi.yaml`) kumpara sa base branch (oasdiff) — gumagawa ng `openapiBreaking=N`; nilalaktawan kung wala ang oasdiff o hindi maresolba ang base spec | **Advisory** | - -### Job: `docs-sync-strict` - -Pinapatakbo sa bawat PR patungo sa `main`. Hinaharang ang pag-merge kapag nabigo. - -| Script | Bine-validate | Humaharang | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:docs-all` | Meta-gate na sunod-sunod na nagpapatakbo sa 6 na sub-gate sa ibaba | Oo | -| ↳ `check:docs-sync` | Pagkakatugma ng bersyon ng CHANGELOG / OpenAPI / llm.txt | Oo | -| ↳ `check:docs-counts` | Ang mga bilang sa teksto (bilang ng provider, bilang ng migration, atbp.) ay nasa loob ng ratchet window ng mga aktuwal na bilang | Oo | -| ↳ `check:env-doc-sync` | Ang bawat env var sa `.env.example` ay nakadokumento sa isang talahanayan ng docs, at gayundin sa kabaligtaran | Oo | -| ↳ `check:deprecated-versions` | Walang mga string ng hindi na suportadong bersyon sa docs | Oo | -| ↳ `check:doc-links` | Ang mga panloob na markdown link sa docs ay tumutukoy sa mga aktuwal na file (`[text]`/`(path)` na anyo) | Oo | -| ↳ `check:fabricated-docs` | Umiiral sa codebase ang mga route, env var, CLI command, pangalan ng hook, at file path na binanggit sa docs. Mahigpit na gate sa pamamagitan ng `--strict`; soft-fail kapag walang flag. | Oo (sa pamamagitan ng `--strict` sa CI) | -| `check:cli-i18n` | Makikita ang mga string ng CLI command sa lahat ng i18n locale file | Oo | -| `check:openapi-coverage` | Sinasaklaw ng OpenAPI spec ang hindi bababa sa isang ratcheted floor ng mga aktuwal na route | Oo | -| `check:openapi-security-tiers` | Ang mga anotasyon ng security tier sa `openapi.yaml` ay tugma sa mga klasipikasyon ng `routeGuard.ts` | **Payo lamang** | -| `check:openapi-routes` | Ang bawat path sa `openapi.yaml` ay tumutukoy sa isang aktuwal na `route.ts` (kontra-hallucination) | Oo | -| `check:docs-symbols` | Ang bawat `/api/...` na sanggunian sa `docs/**/*.md` ay tumutukoy sa isang aktuwal na `route.ts` (kontra-hallucination) | Oo | -| `i18n translation drift` | Mga hindi naisaling key sa mga i18n locale file — babala lamang | **Payo lamang** | +Tumatakbo pagkatapos ng `test-coverage`. Hinaharangan ang merge kapag nabigo. + +| Script | Bineberipika | Humaharang | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `quality:collect` | Gumagawa ng `quality-metrics.json` (bilang ng babala ng ESLint, coverage mula sa pinagsamang ulat ng shard) | Oo (nauuna sa ratchet) | +| `quality:ratchet` | Hindi bumaba ang bawat metric sa `quality-baseline.json` (mga babala ng ESLint ≤ baseline; coverage ≥ baseline) | Oo | +| `check:duplication` | Hindi lumalampas ang pagdodoble ng code (jscpd@4) sa baseline sa `quality-baseline.json` | Oo | +| `check:complexity` | Hindi lumalampas sa limitasyon ang cyclomatic complexity sa antas ng file (pangunahing ESLint `complexity` + `max-lines-per-function`) | Oo | +| `check:cognitive-complexity` | Ratchet ng cognitive complexity (`eslint-plugin-sonarjs`) — hiwalay na pagpapatakbo ng ESLint; parehong pinapatakbo ng CI nang pinagsama bilang iisang hakbang na `check:complexity-ratchets` | Oo | +| `check:dead-code` | Hindi bumaba kumpara sa baseline ang ratchet ng mga hindi ginagamit na export / file (knip) | Oo | +| `check:compression-budget` | Badyet para sa benchmark ng compression — hindi dapat bumaba ang pinakamababang token savings ng bawat engine | Oo | +| `check:type-coverage` | Hindi bumaba ang ratchet ng porsiyento ng may type (`type-coverage`); karaniwang sinasaklaw nito ang `typecheck:noimplicit:core` | Oo | +| `check:codeql-ratchet` | Hindi dumami ang mga bukas na alerto ng CodeQL (binabasa sa pamamagitan ng `gh api`; maayos na nilalaktawan kapag walang token) — para sa dalas ng pag-refresh at manu-manong pag-trigger: tingnan ang "CodeQL ratchet" sa ibaba | Oo | + +### Trabaho: `quality-extended` + +Ang buong trabaho ay nagbibigay-payo lamang (`continue-on-error: true`). Aktuwal na +tumatakbo ang mga ratchet na nakabatay sa npm; nag-i-install ang mga panlabas na scanner +sa pamamagitan ng `gh release download` at kusang lumalaktaw (exit 0) kapag wala pa rin +ang binary. + +| Script | Bineberipika | Humaharang | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `check:circular-deps` | Walang mga paikot na dependency (dpdm) | **Nagbibigay-payo** | +| `check:bundle-size` | Hindi lumalampas sa limitasyon ang laki ng bundle | **Nagbibigay-payo** | +| `check:secrets` | Pag-scan ng mga lihim (gitleaks) — nilalaktawan kung wala ang binary | **Nagbibigay-payo** | +| `check:vuln-ratchet` | Hindi dumami ang mga kahinaan sa dependency (osv-scanner) — nilalaktawan kung wala ang binary | **Nagbibigay-payo** | +| `check:workflows` | Pag-lint ng workflow (actionlint + zizmor); ang mga nawawala/sirang scanner, di-wastong ulat, o nawawalang ratchet baseline ay nabibigo bilang INCOMPLETE. Ang mga wastong natuklasan ay sumusunod sa napiling patakarang strict/advisory/ratchet | Kinakailangan ang pagpapatupad; humaharang sa CI ang zizmor ratchet | +| `check:openapi-breaking` | Mga breaking change sa pampublikong kontrata ng API (`openapi.yaml`) kumpara sa base branch (oasdiff) — gumagawa ng `openapiBreaking=N`; nilalaktawan kung wala ang oasdiff o hindi malutas ang base spec | **Nagbibigay-payo** | + +### Trabaho: `docs-sync-strict` + +Tumatakbo sa bawat PR patungo sa `main`. Hinaharang ang pag-merge kapag nabigo. + +| Script | Bineberipika | Humahadlang | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:docs-all` | Meta-gate na sunud-sunod na nagpapatakbo sa 6 na sub-gate sa ibaba | Oo | +| ↳ `check:docs-sync` | Pagkakatugma ng bersyon ng CHANGELOG / OpenAPI / llm.txt | Oo | +| ↳ `check:docs-counts` | Ang mga bilang sa teksto (bilang ng provider, bilang ng migration, atbp.) ay nasa loob ng ratchet window ng mga aktuwal na bilang | Oo | +| ↳ `check:env-doc-sync` | Nakadokumento sa isang talahanayan ng docs ang bawat env var sa `.env.example`, at gayundin sa kabilang direksyon | Oo | +| ↳ `check:deprecated-versions` | Walang mga string ng hindi na suportadong bersyon sa docs | Oo | +| ↳ `check:doc-links` | Ang mga internal na markdown link sa docs ay tumutukoy sa mga aktuwal na file (`[text]`/`(path)` na anyo) | Oo | +| ↳ `check:fabricated-docs` | Umiiral sa codebase ang mga route, env var, CLI command, pangalan ng hook, at path ng file na binanggit sa docs. Mahigpit na gate sa pamamagitan ng `--strict`; soft-fail kapag walang flag. | Oo (sa pamamagitan ng `--strict` sa CI) | +| `check:cli-i18n` | Makikita ang mga string ng CLI command sa lahat ng i18n locale file | Oo | +| `check:openapi-coverage` | Saklaw ng OpenAPI spec ang hindi bababa sa ratcheted floor ng mga aktuwal na route | Oo | +| `check:openapi-security-tiers` | Ang mga anotasyon ng security tier sa `openapi.yaml` ay naaayon sa mga klasipikasyon ng `routeGuard.ts` | **Payo lamang** | +| `check:openapi-routes` | Ang bawat path sa `openapi.yaml` ay tumutukoy sa isang aktuwal na `route.ts` (kontra-halusinasyon) | Oo | +| `check:docs-symbols` | Ang bawat sangguniang `/api/...` sa `docs/**/*.md` ay tumutukoy sa isang aktuwal na `route.ts` (kontra-halusinasyon) | Oo | +| `i18n translation drift` | Mga hindi naisaling key sa mga i18n locale file — babala lamang | **Payo lamang** | ### Job: `i18n-ui-coverage` -| Script | Bine-validate | Humaharang | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (inline) | Ang saklaw ng UI i18n key ay ≥ 65% | Oo | -| `check-ui-value-drift` (inline) | Kapag muling isinulat ang isang English na **value**, walang naiiwang lipas na salin | Oo | -| `check-new-key-coverage` (inline) | Ang isang **bagong** English key ay naisalin sa bawat locale — tatanggihan ang isang `__MISSING__:` marker | Oo | -| `check-translation-ratio` | Ang proporsyon ng aktuwal na salin bawat locale (mga leaf na kapareho ng English / placeholder / nawawala sa labas ng allowlist) ay hindi dapat lumampas sa `config/quality/i18n-translation-baseline.json` + slack | **Payo lamang** | +| Script | Bineberipika | Humahadlang | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (inline) | Ang saklaw ng UI i18n key ay ≥ 65% | Oo | +| `check-ui-value-drift` (inline) | Kapag muling isinulat ang isang English na **value**, walang naiiwang lipas na salin | Oo | +| `check-new-key-coverage` (inline) | Ang isang **bagong** English key ay naisalin sa bawat locale — tinatanggihan ang marker na `__MISSING__:` | Oo | +| `check-translation-ratio` | Ang ratio ng aktuwal na salin sa bawat locale (mga value na kapareho ng English / placeholder / nawawalang leaf sa labas ng allowlist) ay hindi dapat lumampas sa `config/quality/i18n-translation-baseline.json` + slack | **Payo lamang** | -Nangangailangan ng `fetch-depth: 0` — dini-diff ng value-drift gate ang `en.json` laban sa merge base. +Kailangan ng `fetch-depth: 0` — dini-diff ng value-drift gate ang `en.json` laban sa merge base. #### `check-ui-value-drift` — gate para sa lipas na salin -Nahuhuli nito ang isang i18n regression na hindi nakikita ng ibang mga gate sa estruktural na paraan: muling -isinusulat ang isang English value at naiiwan ang mga saling hinango mula sa _nakaraang_ English, kaya -patuloy na nakakabasa ang mga user na hindi gumagamit ng English ng tekstong may tiyak na pananalita ngunit mali na ngayon. +Nahuhuli nito ang isang i18n regression na hindi nakikita ng iba pang gate sa estruktural na paraan: muling +isinulat ang isang English na value at naiwan ang mga saling hinango sa _nakaraang_ English, kaya +patuloy na nagbabasa ang mga hindi English na user ng tekstong may kumpiyansang pananalita ngunit mali na ngayon. -Aktuwal itong na-release. Muling isinulat ang `oauthModal.googleOAuthWarning` nang idagdag ang Antigravity +Talagang nailabas ito. Muling isinulat ang `oauthModal.googleOAuthWarning` nang idagdag ang Antigravity login helper (#5203); **39 sa 43 locale** ang nanatiling may tekstong nagsasabi sa mga operator na "kopyahin ang buong URL at i-paste ito sa ibaba" — isang flow na hindi makukumpleto para sa provider na iyon. Hindi ito napansin hanggang #8463 dahil: -- nagba-backfill lamang ang `sync-ui-keys` ng mga key na **wala**, at hindi kailanman ng mga **lipas**; -- binibilang ng `check-ui-keys-coverage` ang _presensya_ ng key, kaya itinuturing na saklaw ang isang lipas na salin; -- sinusubaybayan ng `check-translation-drift` ang mga mirror ng dokumentasyong `docs/i18n//**.md` — - hindi nito kailanman binabasa ang `src/i18n/messages/*.json`. Humaharang sa job na `docs-sync-strict` mula noong - 2026-09 re-sync: mag-edit ng isang pangunahing doc → `npm run i18n:run -- --files=` (antas ng seksyon, mura). +- Nagba-backfill lamang ang `sync-ui-keys` ng mga key na **wala**, hindi kailanman ng mga **lipas**; +- Binibilang ng `check-ui-keys-coverage` ang _pagkakaroon_ ng key, kaya itinuturing na sakop ang isang lipas na salin; +- Sinusubaybayan ng `check-translation-drift` ang mga mirror ng dokumentasyong `docs/i18n//**.md` — + hindi nito kailanman binabasa ang `src/i18n/messages/*.json`. Humahadlang sa job na `docs-sync-strict` mula noong + 2026-09 na muling pag-sync: mag-edit ng pangunahing doc → `npm run i18n:run -- --files=` (antas-seksyon, mabilis). -**May kamalayan sa diff, hindi nakabatay sa baseline.** Inihahambing nito ang `en.json` sa merge base laban sa -working tree; para sa bawat key na nagbago ang English value, lipas na ang anumang locale na mayroon pa ring -hindi nabagong salin. Sinasadya nitong **i-freeze ang dati nang pagkakautang** — hindi maihahayag ng isang diff -kung sa aling lumang English nagmula ang isang matagal nang salin, kaya ang gate ay humuhusga +**Nakabatay sa diff, hindi sa baseline.** Inihahambing nito ang `en.json` sa merge base laban sa +working tree; para sa bawat key na nagbago ang English na value, stale ang anumang locale na mayroon +pa ring hindi nabagong salin. Sadya nitong **pinananatili ang dati nang utang** — hindi maipapakita ng diff +kung sa aling lumang English nagmula ang isang matagal nang salin, kaya ang gate ay humahatol lamang sa mga naaapektuhan ng kasalukuyang pagbabago. Ang alternatibo (isang per-key hash baseline) ay mangangailangan -ng ~600 KB na generated file, 3× ng pinakamalaking kasalukuyang baseline, na mababago sa bawat i18n PR. +ng ~600 KB na generated file, 3× ng pinakamalaking kasalukuyang baseline, na magbabago sa bawat i18n PR. Dalawang paraan upang matugunan ito: 1. i-update ang mga apektadong salin, o -2. itakda ang mga ito sa `__MISSING__:` — ihahatid pagkatapos ng runtime ang itinamang English - (`src/i18n/request.ts::deepMergeFallback`, #7258) at ipipila ang key para sa pagsasalin. +2. itakda ang mga ito sa `__MISSING__:` — pagkatapos ay ihahatid ng runtime ang itinamang English + (`src/i18n/request.ts::deepMergeFallback`, #7258) at ilalagay sa pila ang key para sa pagsasalin. Kung nagbago ang **kahulugan** ng string, mas mainam na **palitan ang pangalan ng key**: hindi maaaring magmana -ng lipas na salin ang isang bagong key. Iyan ang pattern na ginamit ng #8463. +ng stale na salin ang isang bagong key. Iyon ang pattern na ginamit ng #8463. ```bash -npm run i18n:check-value-drift # mahigpit (ang pinapatakbo ng CI) +npm run i18n:check-value-drift # mahigpit (ito ang pinapatakbo ng CI) npm run i18n:check-value-drift:warn # ulat lamang BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Nagtatapos nang may 0 at `SKIP reason=base-unresolved` kapag hindi mabasa ang base catalog (shallow -clone na walang base ref), gaya ng `check-openapi-breaking`. +Nag-e-exit nang 0 na may `SKIP reason=base-unresolved` kapag hindi mabasa ang base catalog (shallow +clone na walang base ref), katulad ng `check-openapi-breaking`. ### Job: `i18n` Kumpletong i18n validation matrix (isang job bawat locale). Advisory ang buong job. -| Script | Bine-validate | Pagba-block | +| Script | Bine-validate | Pag-block | | ------------------------------- | ----------------------------------- | ----------------------------------------------------- | | `validate_translation.py quick` | Pagkakumpleto ng salin bawat locale | **Advisory** (`continue-on-error: true` sa buong job) | @@ -244,33 +247,33 @@ Kumpletong i18n validation matrix (isang job bawat locale). Advisory ang buong j Tumatakbo lamang sa mga pull request. -| Script | Bine-validate | Pagba-block | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | Ang mga PR na nagbabago ng production code sa `src/`, `open-sse/`, `electron/`, o `bin/` ay dapat magsama o mag-update ng mga test (Hard Rule #8) | Oo | -| `check:test-masking` | Hindi binabawasan ng mga binagong test file ang net assert count o nagdaragdag ng mga tautology na `assert.ok(true)` | Oo | -| `check:pr-evidence` | Binabanggit ng PR body ang ebidensya ng test/VPS para sa pagbabago (isinasagawa ang Hard Rule #18 sa pamamagitan ng pag-grep sa prose ng PR — marupok, tingnan ang Backlog) | Oo | +| Script | Bine-validate | Pag-block | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | +| `check:pr-test-policy` | Ang mga PR na nagbabago ng production code sa `src/`, `open-sse/`, `electron/`, o `bin/` ay dapat magsama o mag-update ng mga test (Mahigpit na Panuntunan #8) | Oo | +| `check:test-masking` | Hindi binabawasan ng mga binagong test file ang net assert count o nagdaragdag ng mga tautology na `assert.ok(true)` | Oo | +| `check:pr-evidence` | Nagbabanggit ang PR body ng test/VPS evidence para sa pagbabago (ginagawang mekanikal ang Mahigpit na Panuntunan #18 sa pamamagitan ng pag-grep sa prose ng PR — marupok, tingnan ang Backlog) | Oo | ### Job: `test-vitest` -Tumatakbo pagkatapos ng `build`. Hinaharangan ang pag-merge kapag nabigo. +Tumatakbo pagkatapos ng `build`. Hinaharangan ang merge kapag nabigo. -| Suite | Bine-validate | Pagba-block | -| ---------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 tool), autoCombo, cache — vitest runner | Oo | -| `test:vitest:ui` | Mga test ng UI component — vitest runner | **Blocking** — tahasang ibinukod sa `vitest.config.ts` ang dati nang mga kabiguan; pinabibigo ng mga bagong kabiguan ang job | +| Suite | Bine-validate | Pag-block | +| ---------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 tool), autoCombo, cache — vitest runner | Oo | +| `test:vitest:ui` | Mga UI component test — vitest runner | **Nagba-block** — tahasang hindi isinasama sa `vitest.config.ts` ang mga dati nang failure; pinababagsak ng mga bagong failure ang job | ### Mga nightly workflow (naka-iskedyul, advisory) -Tumatakbo ang mga ito ayon sa cron schedule (at `workflow_dispatch`), at hindi kailanman sa mga PR. Advisory ang lahat ng ito. +Tumatakbo ang mga ito ayon sa cron schedule (at `workflow_dispatch`), hindi kailanman sa mga PR. Advisory ang lahat. -| Workflow | Bine-validate | Pagba-block | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `nightly-property` | Mga fast-check property test na may random seed + mataas na run count | **Advisory** | -| `nightly-resilience` | Heap-growth gate, chaos fault-injection, k6 load/soak | **Advisory** | -| `nightly-llm-security` | Promptfoo injection guard (block mode) + garak probe (nilalaktawan kapag walang provider secret) | **Advisory** | -| `nightly-schemathesis` | OpenAPI contract fuzzing (schemathesis) laban sa live na OmniRoute gamit ang `docs/openapi.yaml` — inilalantad ang mga paglabag sa spec / hindi nahawakang 500 (Fase 8 B.4) | **Advisory** | -| `nightly-mutation` | Stryker mutation-testing score sa mabilis na unit lane — inilalantad ng mga surviving mutant ang mahihinang assert | **Advisory** | -| `nightly-compat` | Node engine compatibility matrix sa lahat ng sinusuportahang saklaw ng `engines.node` | **Advisory** | +| Workflow | Bine-validate | Pag-block | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | Mga fast-check property test na may random seed + mataas na run count | **Advisory** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **Advisory** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + mga garak probe (nilalaktawan kapag walang provider secret) | **Advisory** | +| `nightly-schemathesis` | OpenAPI contract fuzzing (schemathesis) laban sa live na OmniRoute gamit ang `docs/openapi.yaml` — inilalantad ang mga paglabag sa spec / mga hindi nahawakang 500 (Yugto 8 B.4) | **Advisory** | +| `nightly-mutation` | Stryker mutation-testing score sa mabilis na unit lane — inilalantad ng mga nakaligtas na mutant ang mahihinang assert | **Advisory** | +| `nightly-compat` | Node engine compatibility matrix sa lahat ng sinusuportahang range ng `engines.node` | **Advisory** | --- @@ -535,43 +538,43 @@ connection error at hindi kailanman nakasisira ng mga session. --- -## Backlog ng Rasyonalisasyon (pagsusuri ng ROI — Yugto 9 Alon 3) +## Backlog ng Rasyonalisasyon (pagsusuri ng ROI — Fase 9 Onda 3) -Itinugma ang imbentaryong ito sa `ci.yml` noong 2026-06-17 (hindi naisama sa naunang bersyon ang +Itinugma ang imbentaryong ito sa `ci.yml` noong 2026-06-17 (hindi naisama sa nakaraang bersyon ang `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Natukoy sa pagsusuri ng ROI ng pinagkatugmang hanay -ang mga sumusunod na kandidato para sa rasyonalisasyon. **Ang mga pagsasanib ay mekanikal na -pagbabago sa CI; ang mga paglipat/pag-aalis ay mga desisyon sa patakaran na nakalaan sa operator.** Wala pa -sa mga nasa ibaba ang inilalapat. +`check:codeql-ratchet`, `check:pr-evidence`). Natukoy sa pagsusuri ng ROI sa itinugmang hanay +ang mga sumusunod na kandidato para sa rasyonalisasyon. **Ang mga pagsasanib ay mga mekanikal na +pagbabago sa CI; ang mga paglipat/pag-aalis ay mga desisyon sa patakaran na nakalaan para sa operator.** Wala pa +sa mga nasa ibaba ang nailalapat. **Hindi rin nakadokumento sa itaas** (advisory, mahinang signal): ang `docs-lint` job -(markdownlint + Vale, ang buong job ay `continue-on-error`) at ang mga standalone na scanner workflow na +(markdownlint + Vale, buong job ay `continue-on-error`) at ang mga nakahiwalay na scanner workflow na `semgrep.yml` / `codeql.yml` / `scorecard.yml`. Nasa -`quality-baseline.json` ang `semgrepFindings: 0` ngunit hindi ito nakakabit sa isang blocking ratchet sa `ci.yml` — kasalukuyang -ulila ang metric na ito. - -### Pagsasama / pag-aalis ng duplikasyon (mekanikal, mas mababang panganib) - -Sinuri ang bawat kandidato laban sa aktuwal na estado ng gate noong 2026-06-17 (magtiwala ngunit tiyakin); -lumabas na may itinatagong utang ang ilang "halatang" pagsasama at **hindi** maaaring direktang ipalit nang maayos. - -- **Dalawang beses tumatakbo ang `check:docs-sync`** — standalone sa `lint` job at muli sa loob ng `check:docs-all` (`docs-sync-strict`) at sa husky pre-commit hook. ✅ **TAPOS NA** — inalis ang standalone na invocation sa `lint`. -- **Pag-scan ng CVE** — ❌ **HINDI maayos na pagsasama.** Agad na nabibigo ang `audit:deps` sa anumang high/critical na CVE; nabibigo lamang ang `check:vuln-ratchet` (osv) kapag may _paglala_ kumpara sa baseline (kasalukuyang 1 MODERATE). Magkaiba ang semantics — mawawala ang absolute high/critical gate kapag inalis ang `audit:deps`. Panatilihin ang dalawa. -- **Pagtukoy ng cycle** — ❌ **HINDI maayos na pagsasama.** Nag-uulat ang `check:circular-deps` (dpdm) ng **91 cycle** (ito ang dahilan kung bakit advisory ito); hindi ito maaaring gawing blocking nang hindi muna nireresolba ang mga iyon, at mas malawak ang saklaw nito kaysa sa maayos at piniling `check:cycles`. Panatilihing blocking ang `check:cycles`; hiwalay na backlog ang paglutas sa 91 dpdm cycle. -- **Complexity** — ✅ **TAPOS NA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): isang ESLint walk, binibilang ayon sa ruleId upang manatiling magkahiwalay ang cyclomatic+max-lines at cognitive baseline; nananatili ang indibidwal na `check:complexity` / `check:cognitive-complexity` para sa lokal na `--update`. -- **Anti-hallucination ng `/api`** — ✅ **TAPOS NA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): isang FS inventory ng `src/app/api`, patuloy na magkahiwalay na nag-uulat ang openapi-routes + docs-symbols; nananatili ang mga indibidwal na check para sa mga lokal na pagpapatakbo. -- **Tumatakbo ang `check:node-runtime` sa 11 job** — ⚠️ **mababang ROI.** Bawat isa ay hiwalay na runner at <1s ang check; kabuuang matitipid ay ~10s, kapalit ng pagkawala ng isang murang guard sa bawat job. Hindi sulit ang pagbabago. -- **`typecheck:noimplicit:core` sa CI lint** — ✅ **inalis sa lint job** (dati itong advisory na `continue-on-error`); ang blocking na type surface ay `typecheck:core` + `check:type-coverage`. Pinanatili ang lokal na script. - -### Ilipat / pagpasyahan (patakaran ng operator) - -- `check:openapi-security-tiers` (advisory) — ❌ **HINDI maaaring ilipat nang maayos.** Nag-e-exit ito nang 0 ngunit nagbababala na walang annotation na `x-loopback-only: true` ang ilang `traffic-inspector` route sa ilalim ng `LOCAL_ONLY_API_PREFIXES`. Kailangang idagdag muna ang mga annotation na iyon sa `openapi.yaml` bago ito ipatupad. -- `typecheck:noimplicit:core` (advisory) — malaking bahagi nito ay nasasaklaw na ng blocking na `check:type-coverage` ratchet. Ilipat sa isang ratchet o alisin ang redundant na ikalawang `tsc` pass. -- `test:vitest:ui` (ngayon ay **blocking**) — tahasang hindi isinasama sa `vitest.config.ts` ang mga dati nang failure gamit ang mga tracking comment na `// #8618`; magpapabigo sa job ang mga bagong failure. -- `check:secrets` (gitleaks, blocking ratchet na nakapirmi sa 3 dokumentadong false-positive) — ilagay sa allowlist ang 3 upang maging 0, o ibaba sa advisory. Nag-o-overlap sa native secret-scanning ng GitHub + `check:public-creds`. -- `check:pr-evidence` (blocking, nagge-grep ng prose sa PR body) — mataas ang panganib ng false-positive; hihina ang pagpapatupad ng Hard Rule #18 kapag inalis, kaya tunay itong desisyon sa patakaran. -- `semgrep` (advisory standalone) — nag-o-overlap sa CodeQL para sa mga OWASP family; ikabit ang baseline nito sa isang ratchet o alisin. +`quality-baseline.json` ang `semgrepFindings: 0` ngunit hindi ito nakakabit sa isang blocking ratchet sa `ci.yml` — ang metric ay +kasalukuyang walang kaugnay na pagpapatupad. + +### Pagsasanib / pag-aalis ng duplikasyon (mekanikal, mas mababang panganib) + +Bawat kandidato ay pinatunayan laban sa aktuwal na estado ng gate noong 2026-06-17 (magtiwala ngunit magsuri); +lumabas na may nakatagong debt ang ilang "halatang" pagsasanib at ang mga ito ay **hindi** malinis na pamalit. + +- **Dalawang beses tumatakbo ang `check:docs-sync`** — nakahiwalay sa `lint` job at muli sa loob ng `check:docs-all` (`docs-sync-strict`) at sa husky pre-commit hook. ✅ **TAPOS NA** — inalis ang nakahiwalay na `lint` invocation. +- **Pag-scan ng CVE** — ❌ **HINDI malinis na pagsasanib.** Agad na nabibigo ang `audit:deps` sa anumang high/critical na CVE; nabibigo lamang ang `check:vuln-ratchet` (osv) kapag may _regression_ kumpara sa baseline (kasalukuyang 1 MODERATE). Magkaiba ang semantics — mawawala ang absolute high/critical gate kapag inalis ang `audit:deps`. Panatilihin ang dalawa. +- **Pagtukoy ng cycle** — ✅ **TAPOS NA** (#15159 G-01/G-02). Tinawag ng lumang teksto rito ang `check:cycles` na "ang green, curated" gate at binigyang-katwiran ang pagpapanatili rito bilang blocking dahil nag-ulat ang `check:circular-deps` (dpdm) ng 91 cycle. Ang pagiging green na iyon ay isang **false green**: nag-scan ang `check:cycles` ng 5 subdirectory (450 file), itinugma lamang ang static na `import|export … from`, at inalis ang bawat `@/` at `@omniroute/open-sse/` specifier, kaya hindi nito makita ang mga dynamic-import + alias cycle na nangingibabaw sa repo. Naayos na: nilalakbay na ngayon ng gate ang `src` + `open-sse` (5023 file), kinokolekta ang mga specifier mula sa TypeScript AST (kaya binibilang ang `import("…")` ngunit hindi ang type-position na `typeof import("…")`), at nire-resolve ang `paths` ng tsconfig. Nakakahanap ito ng **14** na cycle, hindi 0. Dahil hindi maaayos ang 14 na dati nang cycle sa isang gate PR, isa na ngayong **ratchet** ang `check:cycles` (`--ratchet`, ceiling na `metrics.cycles.value = 14` sa `quality-baseline.json`, `direction: down`) — bina-block nito ang anumang _regression_ at maaari lamang bumaba ang bilang. Pinapatakbo ng CI ang `npm run check:cycles:ratchet`. Kasabay ng **A-01** ang burn-down. Nananatiling advisory ang `check:circular-deps` (dpdm) bilang mas malawak na pangalawang opinyon. +- **Complexity** — ✅ **TAPOS NA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): isang ESLint walk, nagbibilang ayon sa ruleId upang manatiling magkahiwalay ang cyclomatic+max-lines at cognitive baseline; nananatili ang indibidwal na `check:complexity` / `check:cognitive-complexity` para sa lokal na `--update`. +- **`/api` anti-hallucination** — ✅ **TAPOS NA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): isang FS inventory ng `src/app/api`, patuloy na magkahiwalay ang pag-uulat ng openapi-routes + docs-symbols; nananatili ang mga indibidwal na check para sa mga lokal na pagpapatakbo. +- **Tumatakbo ang `check:node-runtime` sa 11 job** — ⚠️ **mababang ROI.** Hiwalay na runner ang bawat isa at <1s ang check; kabuuang matitipid ay ~10s, kapalit ng pagkawala ng murang guard sa bawat job. Hindi sulit ang pagbabago. +- **`typecheck:noimplicit:core` sa CI lint** — ✅ **inalis sa lint job** (dating advisory na `continue-on-error`); ang blocking type surface ay `typecheck:core` + `check:type-coverage`. Pinanatili ang lokal na script. + +### Ilipat / pagpasiyahan (patakaran ng operator) + +- `check:openapi-security-tiers` (advisory) — ❌ **HINDI malinis na maililipat.** Nag-e-exit ito nang 0 ngunit nagbababala na walang `x-loopback-only: true` annotation ang ilang `traffic-inspector` route sa ilalim ng `LOCAL_ONLY_API_PREFIXES`. Kailangang idagdag muna ang mga annotation na iyon sa `openapi.yaml` bago ito ipatupad. +- `typecheck:noimplicit:core` (advisory) — halos saklaw na ng blocking na `check:type-coverage` ratchet. Ilipat sa isang ratchet o alisin ang kalabisan na pangalawang `tsc` pass. +- `test:vitest:ui` (ngayon ay **blocking**) — tahasang ibinukod sa `vitest.config.ts` ang mga dati nang failure gamit ang `// #8618` tracking comment; pinababagsak ng mga bagong failure ang job. +- `check:secrets` (gitleaks, blocking ratchet na naka-freeze sa 3 nakadokumentong false-positive) — i-allowlist ang 3 upang umabot sa 0, o ibaba sa advisory. Nag-o-overlap sa native secret-scanning ng GitHub + `check:public-creds`. +- `check:pr-evidence` (blocking, nagge-grep ng prose sa PR body) — mataas ang panganib ng false-positive; pinahihina ang pagpapatupad ng Hard Rule #18 kapag inalis, kaya isa itong tunay na desisyon sa patakaran. +- `semgrep` (nakahiwalay na advisory) — nag-o-overlap sa CodeQL para sa mga OWASP family; ikabit ang baseline nito sa isang ratchet o alisin. --- diff --git a/docs/i18n/pl/CONTRIBUTING.md b/docs/i18n/pl/CONTRIBUTING.md index b13c8ed78db..212719ee0bf 100644 --- a/docs/i18n/pl/CONTRIBUTING.md +++ b/docs/i18n/pl/CONTRIBUTING.md @@ -399,22 +399,22 @@ Napisz testy jednostkowe w `tests/unit/`, obejmujące co najmniej: --- -## Lista kontrolna pull requestu +## Lista kontrolna Pull Requesta -- [ ] Testy przechodzą (`npm test`) -- [ ] Lintowanie przechodzi (`npm run lint`) +- [ ] Testy przechodzą pomyślnie (`npm test`) +- [ ] Lintowanie przechodzi pomyślnie (`npm run lint`) - [ ] Kompilacja kończy się powodzeniem (`npm run build`) - [ ] Dodano typy TypeScript dla nowych publicznych funkcji i interfejsów - [ ] Brak zakodowanych na stałe sekretów lub wartości zapasowych -- [ ] Publiczne dane uwierzytelniające dostawcy nadrzędnego osadzono za pomocą `resolvePublicCred()` (zobacz [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nigdy jako literały -- [ ] Odpowiedzi o błędach przechodzą przez `buildErrorBody()` / `sanitizeErrorMessage()` — brak nieprzetworzonych śladów stosu w treściach odpowiedzi (zobacz [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Polecenia powłoki (`exec` / `spawn`) przekazują wartości środowiska wykonawczego przez `env`, a nie przez interpolację ciągów znaków +- [ ] Publiczne dane uwierzytelniające usług nadrzędnych osadzono za pomocą `resolvePublicCred()` (zobacz [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nigdy jako literały +- [ ] Odpowiedzi błędów są przetwarzane przez `buildErrorBody()` / `sanitizeErrorMessage()` — brak surowych śladów stosu w treści odpowiedzi (zobacz [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Polecenia powłoki (`exec` / `spawn`) przekazują wartości czasu wykonywania przez `env`, a nie przez interpolację ciągów znaków - [ ] Wszystkie dane wejściowe są walidowane za pomocą schematów Zod -- [ ] Dodano **fragment** dziennika zmian w `changelog.d/{features|fixes|maintenance}/-.md` dla zmian widocznych dla użytkownika (zobacz [`changelog.d/README.md`](./changelog.d/README.md)) — **nie** edytuj bezpośrednio `CHANGELOG.md`; fragmenty są agregowane podczas wydania i nigdy nie powodują konfliktów między pull requestami -- [ ] Zaktualizowano dokumentację (jeśli dotyczy) -- [ ] Nie utworzono żadnych nowych alertów CodeQL / Secret-Scanning albo każdy z nich odrzucono z uzasadnieniem technicznym odwołującym się do odpowiedniego dokumentu w `docs/security/` -- [ ] Trasy uruchamiające procesy potomne (`/api/mcp/`, `/api/cli-tools/runtime/`) sklasyfikowano jako `isLocalOnlyPath()` w `src/server/authz/routeGuard.ts` — zobacz [Twarda reguła #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Brak wpisów końcowych `Co-Authored-By` w komunikatach commitów — commity muszą być przypisane wyłącznie do tożsamości Git właściciela repozytorium (Twarda reguła #16) +- [ ] Dla zmian widocznych dla użytkowników dodano **fragment** dziennika zmian w `changelog.d/{features|fixes|maintenance}/-.md` (zobacz [`changelog.d/README.md`](./changelog.d/README.md)) — **nie** edytuj bezpośrednio pliku `CHANGELOG.md`; fragmenty są agregowane podczas wydania i nigdy nie powodują konfliktów między Pull Requestami +- [ ] Dokumentacja została zaktualizowana (jeśli dotyczy) +- [ ] Nie utworzono nowych alertów CodeQL / Secret-Scanning lub każdy z nich został odrzucony z technicznym uzasadnieniem odwołującym się do odpowiedniego dokumentu w `docs/security/` +- [ ] Trasy uruchamiające procesy podrzędne (`/api/mcp/`, `/api/cli-tools/runtime/`) sklasyfikowano jako `isLocalOnlyPath()` w `src/server/authz/routeGuard.ts` — zobacz [Twarda reguła nr 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Brak stopek `Co-authored-by` dotyczących AI/botów w komunikatach commitów (Twarda reguła nr 16) — współpracownicy będący ludźmi, których praca została ponownie wykorzystana, są wymieniani za pomocą standardowych stopek `Co-authored-by: Name ` --- diff --git a/docs/i18n/pl/docs/architecture/QUALITY_GATES.md b/docs/i18n/pl/docs/architecture/QUALITY_GATES.md index 8f616859e34..f35f721183b 100644 --- a/docs/i18n/pl/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/pl/docs/architecture/QUALITY_GATES.md @@ -16,231 +16,240 @@ plan odtworzenia tego samego systemu zawiera --- -## Inwentarz bramek i profile wykonywania +## Wykaz bramek i profile wykonywania ### Dopuszczanie kandydatów -Przepływy pracy CI i Quality Gates generują po jednym stabilnym werdykcie: `Gate / CI` oraz -`Gate / Quality`. Ich wersjonowana polityka dopuszczania określa każde nadrzędne zadanie -jako wymagane lub doradcze. Każde mające zastosowanie zadanie wymagane musi zakończyć się powodzeniem: -brakujące, anulowane, pominięte, oczekujące i nieznane wyniki nie mogą ustanowić wyniku PASS. -Prawidłowa klasyfikacja docs-only lub catalog-only może sprawić, że ścieżka kodu nie będzie miała zastosowania; -wersja robocza PR nie jest akceptowanym kandydatem. Etykieta `hotfix` nie znosi wymogu przedstawienia dowodów. - -Oba przepływy pracy obejmują PR-y i wypchnięcia do gałęzi main/release, ręczne uruchomienia oraz -zdarzenia grup scalania. Wypchnięcia, ręczne uruchomienia i grupy scalania wykonują pełny zestaw. -Forki i grupy scalania używają hostowanych runnerów dla zadań, które w przeciwnym razie wybrałyby -runnery self-hosted; przed wdrożeniem należy zweryfikować wystarczającą pojemność infrastruktury hostowanej. - -Każde potwierdzenie JSON identyfikuje SHA pobranego kodu, uruchomienie przepływu pracy i próbę. -CLI odrzuca niezgodność SHA między pobranym kodem a zdarzeniem. Testy przepływu pracy wiążą członkostwo w polityce -z listą `needs` zadania werdyktu, dzięki czemu nowa lub usunięta ścieżka nie może zniknąć po cichu. -Potwierdzenia obejmują własny przepływ pracy, a nie publikację, wdrożenie ani wewnętrzne działanie -istniejącego skanera doradczego. Aktywacja obu nazw kontroli w regułach gałęzi jest -osobną zmianą administracyjną; samo dodanie tych zadań nie chroni gałęzi. - -### Inwentarz skanowania statycznego - -Wersjonowany inwentarz aliasów npm i członkostwo w skanowaniu statycznym znajdują się w +Przepływy pracy CI i Quality Gates emitują stabilne werdykty: `Gate / CI` oraz +`Gate / Quality`. Ich wersjonowana polityka dopuszczania określa każde zadanie nadrzędne +jako wymagane lub doradcze. Każde mające zastosowanie zadanie wymagane musi zakończyć się +powodzeniem: brakujące, anulowane, pominięte, oczekujące i nieznane wyniki nie mogą stanowić +podstawy do uznania statusu PASS. Prawidłowa klasyfikacja wyłącznie jako docs-only lub +catalog-only może sprawić, że ścieżka kodu nie będzie miała zastosowania; +wersja robocza PR nie jest akceptowanym kandydatem. Etykieta `hotfix` nie zwalnia +z obowiązku przedstawienia dowodów. + +Oba przepływy pracy obejmują PR-y i wypchnięcia do gałęzi main/release, uruchomienia +ręczne oraz zdarzenia grupy scalania. Wypchnięcia, uruchomienia ręczne i grupy scalania +wykonują pełny zestaw. Forki i grupy scalania używają hostowanych runnerów dla zadań, +które w innych przypadkach wybierają samodzielnie hostowane runnery; przed wdrożeniem +należy zweryfikować wystarczającą pojemność środowiska hostowanego. + +Każde pokwitowanie JSON identyfikuje pobrany SHA, uruchomienie przepływu pracy i próbę. +CLI odrzuca niezgodność SHA między pobranym kodem a zdarzeniem. Testy przepływu pracy +wiążą przynależność do polityki z listą `needs` zadania werdyktu, dzięki czemu nowa lub +usunięta ścieżka nie może niezauważenie zniknąć. Pokwitowania obejmują własny przepływ +pracy, a nie publikację, wdrożenie ani wewnętrzne działanie istniejącego skanera +doradczego. Aktywowanie obu nazw kontroli w regułach gałęzi jest osobną zmianą +administracyjną; samo dodanie tych zadań nie chroni gałęzi. + +### Wykaz skanowania statycznego + +Wersjonowany wykaz aliasów npm i przynależność do skanowania statycznego znajdują się w `config/quality/gate-manifest.json`. Uruchom `npm run check:gate-manifest`, aby zweryfikować -nazwy skryptów i dokładne polecenia względem `package.json`; dodania, usunięcia i -zmiany poleceń powodują niepowodzenie zarówno lokalnego hooka, jak i zadań klasyfikacji zmian w CI. -Alias nie jest zadaniem przepływu pracy, instancją macierzy ani przypadkiem testowym: tych wartości -nie wolno przedstawiać jako zamiennych. +nazwy skryptów i dokładne polecenia względem `package.json`; dodania, usunięcia i zmiany +poleceń powodują niepowodzenie zarówno lokalnego hooka, jak i zadań klasyfikacji zmian +w CI. Alias nie jest zadaniem przepływu pracy, instancją macierzy ani przypadkiem +testowym: tych liczebności nie wolno przedstawiać jako równoważnych. Użyj `npm run quality:scan -- --list` lub `npm run quality:scan:fast -- --list`, -aby sprawdzić wybrane aliasy bez ich wykonywania. Runner wywołuje -punkt wejścia npm, więc jego środowisko uruchomieniowe (w tym Bun, jeśli skonfigurowano) zostaje zachowane. -Manifest rejestruje aliasy spoza tych profili jako wywoływane osobno, a -polecenia konserwacyjne są zabronione w profilach skanowania tylko do odczytu. +aby sprawdzić wybrane aliasy bez ich wykonywania. Runner wywołuje punkt wejścia npm, +więc jego środowisko uruchomieniowe (w tym Bun, jeśli jest skonfigurowany) zostaje +zachowane. Manifest rejestruje aliasy spoza tych profili jako wywoływane oddzielnie, +a polecenia konserwacyjne są zabronione w profilach skanowania tylko do odczytu. Profile te obejmują wyłącznie skanowanie statyczne. Nie poświadczają testów produktu, -pokrycia, pakowania, kontroli zewnętrznych ani pełnego dopuszczenia kandydata do wydania. -Dopuszczanie w przepływie pracy korzysta z powiązanych plików `config/quality/admission-policy.json` oraz -`scripts/quality/admission-verdict.mjs`. Profile obserwatora wydań pozostają oddzielne; -ich mające zastosowanie kontrole i potwierdzenia należy sprawdzać niezależnie. Poniższy -inwentarz opisowy stanowi materiał referencyjny, a nie dowód faktycznego uruchomienia bramki. - -Skrypty znajdują się w `scripts/check/` (bramki polityk) i `scripts/quality/` (silnik mechanizmu zapadkowego). -Źródłem prawdy dla CI jest `.github/workflows/ci.yml`. - -### Szybka ścieżka PR-a wydania (`quality.yml`) - -`.github/workflows/quality.yml` uzupełnia CI dla PR-ów do gałęzi main/release, wypchnięć -do chronionych gałęzi, ręcznych uruchomień i grup scalania. PR-y korzystają z szybkich kontroli -filtrowanych według ścieżek. Trwale wyłączony zduplikowany build został usunięty; -rzeczywiste kontrole buildu, pakowania i uruchamiania pozostają w CI. - -| Zadanie | Zakres | Blokujące | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `Docs Gates (fast-path)` | PR-y dokumentacji/kodu; odwołania do dokumentacji API i docs-all | Tak | -| `Fast Quality Gates` | PR-y kodu; kontrole statyczne, typecheck, typecheck dashboardu, testy jednostkowe objęte zmianami | Tak | -| `Forgotten sibling tests` | PR-y kodu; śledzenie zmienionych modułów do konsumentów statycznych i potencjalnych testów równoległych; ścieżki barrel i dynamic-import są zgłaszane jako diagnostyka doradcza wraz z przywołanymi wyjątkami z listy dozwolonych | **Doradcze** | -| `Vitest (fast-path)` | PR-y kodu; szybki zestaw vitest | Tak | -| `Unit Tests fast-path` | PR-y kodu; 4-częściowy zestaw testów jednostkowych | Tak | -| `No new ESLint warnings` | PR-y kodu; kontrola lintowania uwzględniająca wyciszenia | Tak, w tym dla forków | -| `Merge integrity (changelog + generated skills)` | PR-y niebędące wersjami roboczymi; synchronizacja changelogu i wygenerowanych umiejętności | Tak, w tym dla forków | - -#### Raport zapomnianych testów równoległych - -`npm run check:forgotten-sibling-tests` ponownie wykorzystuje mechanizm rozpoznawania importów, na którym opiera się mapa wpływu testów. -Dla każdego zmienionego modułu produkcyjnego raportuje deterministyczne łańcuchy -`zmieniony moduł/symbol -> konsument statyczny -> potencjalny test równoległy`, gdy potencjalny -test nie występuje w różnicach pull requestu. Podsumowanie Markdown i wynik JSON są zachowywane jako -artefakt przepływu pracy `forgotten-sibling-tests` na potrzeby kalibracji przed ewentualnym wdrożeniem trybu blokującego. - -Reeksporty zbiorcze i importy dynamiczne służą wyłącznie do diagnostyki rozwiązywania zależności; nigdy nie powodują -wykrycia problemu blokującego. Zatwierdzone wyjątki znajdują się w pliku +pokrycia, pakowania, kontroli zewnętrznych ani pełnej akceptacji kandydata do wydania. +Dopuszczanie przez przepływ pracy korzysta z powiązanych plików +`config/quality/admission-policy.json` oraz +`scripts/quality/admission-verdict.mjs`. Profile obserwatora wydania pozostają +oddzielne; ich właściwe kontrole i pokwitowania należy sprawdzać niezależnie. Poniższy +wykaz opisowy stanowi materiał referencyjny, a nie dowód, że bramka faktycznie została +uruchomiona. + +Skrypty znajdują się w `scripts/check/` (bramki polityki) i `scripts/quality/` (silnik +mechanizmu zapadkowego). Źródłem prawdy dla CI jest `.github/workflows/ci.yml`. + +### Szybka ścieżka PR-ów wydania (`quality.yml`) + +`.github/workflows/quality.yml` uzupełnia CI dla PR-ów do gałęzi main/release, +wypchnięć do chronionych gałęzi, uruchomień ręcznych i grup scalania. PR-y używają +szybkich kontroli filtrowanych według ścieżek. Trwale wyłączony, zduplikowany proces +kompilacji został usunięty; rzeczywiste kontrole kompilacji, pakowania i uruchamiania +pozostają w CI. + +| Zadanie | Zakres | Blokujące | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `Docs Gates (fast-path)` | PR-y dokumentacji/kodu; odwołania do dokumentacji API i cała dokumentacja | Tak | +| `Fast Quality Gates` | PR-y kodu; kontrole statyczne, kontrola typów, kontrola typów panelu, testy jednostkowe objęte zmianami | Tak | +| `Forgotten sibling tests` | PR-y kodu; śledzenie zmienionych modułów do statycznych konsumentów i potencjalnych testów siostrzanych; ścieżki przez moduły zbiorcze i importy dynamiczne są raportowane jako diagnostyka doradcza, z odwołaniami do wyjątków na liście dozwolonych | **Doradcze** | +| `Vitest (fast-path)` | PR-y kodu; szybki zestaw vitest | Tak | +| `Unit Tests fast-path` | PR-y kodu; 4-częściowy zestaw testów jednostkowych | Tak | +| `No new ESLint warnings` | PR-y kodu; kontrola lintowania uwzględniająca wyciszenia | Tak, w tym dla forków | +| `Merge integrity (changelog + generated skills)` | PR-y inne niż wersje robocze; synchronizacja dziennika zmian i wygenerowanych umiejętności | Tak, w tym dla forków | + +#### Raport zapomnianych testów siostrzanych + +`npm run check:forgotten-sibling-tests` ponownie wykorzystuje mechanizm rozwiązywania +importów będący podstawą mapy wpływu testów. Dla każdego zmienionego modułu produkcyjnego +raportuje deterministyczne łańcuchy +`zmieniony moduł/symbol -> statyczny konsument -> potencjalny test siostrzany`, gdy +potencjalnego testu nie ma w różnicy zmian pull requestu. Podsumowanie Markdown i wynik +JSON są zachowywane jako artefakt przepływu pracy `forgotten-sibling-tests` na potrzeby +kalibracji przed wdrożeniem trybu blokującego. + +Re-eksporty zbiorcze i importy dynamiczne służą wyłącznie do diagnostyki rozwiązywania zależności; nigdy nie tworzą +ustalenia blokującego. Zweryfikowane wyjątki znajdują się w `config/quality/forgotten-sibling-allowlist.json`. Każdy wpis musi wskazywać test używający i test -kandydujący, zawierać konkretne uzasadnienie oraz łącze do zgłoszenia lub pull requestu w serwisie GitHub. Nieprawidłowo sformułowane wpisy są -domyślnie odrzucane. Wyjątki nie mogą ukrywać usuniętego testu kandydującego ani różnicy dodającej `.skip`/`.todo`; +kandydujący, podawać konkretne uzasadnienie oraz zawierać link do zgłoszenia GitHub lub pull requestu. Nieprawidłowo sformatowane wpisy są +domyślnie odrzucane. Wyjątki nie mogą ukrywać usuniętego testu kandydującego ani diffu dodającego `.skip`/`.todo`; osłabianie asercji i inne formy maskowania pozostają objęte niezależnie blokującą bramką `check:test-masking`. ### Zadanie: `lint` -Uruchamiane dla każdego PR-a do `main`. W przypadku niepowodzenia blokuje scalanie. - -| Skrypt (`npm run ...`) | Sprawdza | Blokuje | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `check:node-runtime` | Czy wersja Node.js mieści się w obsługiwanym zakresie | Tak | -| `check:cycles` | Importy cykliczne — wszystkie moduły w `src/` i `open-sse/` | Tak | -| `check:route-validation:t06` | Obecność schematów Zod we wszystkich trasach (zasady poziomu 6) | Tak | -| `check:any-budget:t11` | Czy liczba wystąpień `@ts-expect-error // any` nie przekracza limitu (bramka poziomu 11) | Tak | -| `check:provider-consistency` | Każdy dostawca w `providers.ts` ma odpowiadający mu wpis w `providerRegistry.ts` (i odwrotnie, w ramach listy dozwolonych) | Tak | -| `check:model-lifecycle` | Trzy ręcznie utrzymywane tabele routingu pozostają spójne z zapisaną w repozytorium migawką cyklu życia (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nie przyznaje punktów żadnemu wycofanemu identyfikatorowi, do którego `REGISTRY` może kierować; każdy cel `BUILT_IN_ALIASES` znajduje się w `REGISTRY` i nie występuje w migawce wycofanych identyfikatorów; każdy wycofany identyfikator nadal obecny w `REGISTRY` jest przekierowywany lub wymieniony w `allowedRetiredInCatalog`; a żadne źródło ani cel `DEFAULT_DEGRADATION_MAP` nie jest oznaczone jako wycofane w tej migawce. Nie dowodzi to, że model jest obecnie obsługiwany przez działającą usługę nadrzędną. W trybie offline — porównuje z `config/quality/model-lifecycle.json`, odświeżanym ręcznie za pomocą `npm run quality:refresh-model-lifecycle` (wymaga sieci; nie jest podłączone do CI). `allowedRetiredInCatalog` jest mechanizmem stopniowego ograniczania: wpis należy dodawać wyłącznie wraz ze zgłoszeniem śledzącym. | Tak | -| `check:fetch-targets` | Każde `fetch("/api/...")` w klienckim kodzie `src/` wskazuje na rzeczywisty plik `route.ts` | Tak | -| `check:deps` | Wszystkie zależności możliwe do zainstalowania za pomocą `npm install` ze wszystkich plików `package.json` w repozytorium znajdują się w `dependency-allowlist.json`; nowe nieprzypięte pakiety lub pakiety wykorzystujące literówki w nazwach są oznaczane | Tak | -| `audit:deps` | `npm audit` (katalog główny + electron) — brak ostrzeżeń o wysokim/krytycznym poziomie istotności (częściowo pokrywa się z `check:vuln-ratchet` systemu osv; zobacz Rejestr zadań racjonalizacyjnych) | Tak | -| `check:lockfile` | Integralność pliku `package-lock.json` — rejestr https, skróty integralności, brak nadpisań hosta | Tak | -| `check:licenses` | Lista dozwolonych licencji SPDX dla zależności produkcyjnych | Tak | -| `check:tracked-artifacts` | Brak artefaktów kompilacji / zatwierdzonych dowiązań symbolicznych `node_modules` (uruchamiane również przez husky przed zatwierdzeniem; kontrola przed wypchnięciem jest celowo uproszczona — #6716) | Tak | -| `check:ai-attribution` | Brak stopki `Co-Authored-By` wskazującej na AI/bota ani stopki dotyczącej generowania przez AI w commitach, tytule lub treści PR — reguła bezwzględna nr 16 (w pętli szybkich kontroli `quality.yml` dla PR→`release/**` — odczytuje dane zdarzenia, nie wykonuje żadnej operacji poza PR — oraz w kroku wykonywanym wyłącznie dla PR w kontroli lintowania `ci.yml` dla PR→`main`; także w hooku husky `commit-msg`; współautorzy będący ludźmi są dozwoleni; #14436) | -| `check:vitest-exclusions` | Każde wykluczenie Vitest wskazuje zgłoszenie śledzące i znajduje się w `config/quality/vitest-exclusions.json` (#13204) | Tak | -| `check:file-size` | Żaden plik źródłowy nie przekracza limitu określonego dla danego rozszerzenia (mechanizm zapadkowy: duże pliki zamrożone na liście `frozen`) | Tak | -| `check:error-helper` | Odpowiedzi o błędach w executorach/handlerach używają `buildErrorBody()` / `sanitizeErrorMessage()` (reguła bezwzględna nr 12) | Tak | -| `check:migration-numbering` | Pliki migracji SQL są numerowane sekwencyjnie, bez luk ani duplikatów | Tak | -| `check:public-creds` | Brak jawnie zapisanych wartości OAuth `client_id`/`client_secret` lub kluczy Firebase Web poza plikiem `publicCreds.ts` (Twarda reguła nr 11) | Tak | -| `check:db-rules` | Brak surowego SQL poza modułami `src/lib/db/`; brak importów zbiorczych z `localDb.ts` (Twarde reguły nr 2 i 5) | Tak | -| `check:known-symbols` | Wykonawcy dostawców, strategie routingu i translatory zarejestrowane w odpowiednich tabelach wysyłania są zgodne z plikami na dysku — bez osieroconych ani niezadeklarowanych symboli | Tak | -| `check:route-guard-membership` | Każda trasa uruchamiająca proces potomny jest sklasyfikowana przez `isLocalOnlyPath()` (Twarde reguły nr 15 i 17) | Tak | -| `check:test-discovery` | Każdy plik `*.test.ts` / `*.spec.ts` w repozytorium jest wykrywany przez co najmniej jeden mechanizm uruchamiania testów (mechanizm zapadkowy: lista osieroconych plików w `test-discovery-baseline.json` może się tylko skracać) | Tak | -| `check:agent-skills-sync` | Wygenerowane artefakty agent-skills są zgodne z katalogiem źródłowym (brak rozbieżności) | -| `check:provider-asset-provenance` | Logotypy/zasoby dostawców mają zarejestrowany wpis dotyczący pochodzenia | -| `lint:json` | Pliki konfiguracyjne JSON są poprawnie parsowane i spełniają reguły lintowania repozytorium | -| `typecheck:core` | Kompilacja TypeScript bez błędów (tylko ostrzeżenia doradcze) | Tak | -| `typecheck:noimplicit:core` | Rygorystyczne `noImplicitAny` — rozwiązanie przyszłościowe; wiele istniejących miejsc wywołań nadal wymaga adnotacji | **Doradcze** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ograniczone do `src/app/(dashboard)/**` (#7033) — opracowana lista dozwolonych 27 plików w `typecheck:core` nie obejmuje żadnych plików TSX panelu, a `next build` również nigdy nie sprawdza ich typów (`next.config.mjs` ustawia `ignoreBuildErrors: true`), przez co regresje związane z osieroconymi identyfikatorami (#6625/#6909) pozostawały niewidoczne dla CI. Różnice są porównywane z zamrożoną wartością bazową liczby błędów dla poszczególnych plików i kodów TS (`config/quality/dashboard-typecheck-baseline.json`, ten sam wzorzec wymuszania aktualności co w `check:known-symbols`) — tylko NOWE błędy wykraczające poza liczbę bazową powodują niepowodzenie bramki; po naprawieniu istniejącego wcześniej błędu należy obniżyć wartość bazową za pomocą `--update`. | Tak | +Uruchamiane dla każdego PR do `main`. W przypadku niepowodzenia blokuje scalenie. + +| Skrypt (`npm run ...`) | Sprawdza | Blokujący | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- | +| `check:node-runtime` | Wersja Node.js mieści się w obsługiwanym zakresie | Tak | +| `check:cycles` | Importy cykliczne w całych katalogach `src/` + `open-sse/` (na podstawie AST, z rozwiązanymi `paths` z tsconfig). Tryb podstawowy = informacyjny, wyświetla cykle. `check:cycles:ratchet` (uruchamiany przez CI) blokuje, gdy liczba przekracza limit `metrics.cycles` w `quality-baseline.json` — obecnie 14, `direction: down`, więc może wyłącznie maleć (#15159 G-01/G-02) | Tak (mechanizm zapadkowy) | +| `check:route-validation:t06` | Obecność schematów Zod we wszystkich trasach (zasady poziomu 6) | Tak | +| `check:any-budget:t11` | Liczba wystąpień `@ts-expect-error // any` nie przekracza budżetu (mechanizm zapadkowy poziomu 11) | Tak | +| `check:provider-consistency` | Każdy dostawca w `providers.ts` ma odpowiadający mu wpis w `providerRegistry.ts` (i odwrotnie, w obrębie listy dozwolonych) | Tak | +| `check:model-lifecycle` | Trzy ręcznie utrzymywane tabele routingu pozostają spójne z przechowywaną w repozytorium migawką cyklu życia (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nie przyznaje punktów żadnemu wycofanemu identyfikatorowi, do którego `REGISTRY` może kierować; każdy cel `BUILT_IN_ALIASES` znajduje się w `REGISTRY` i nie występuje w migawce wycofanych identyfikatorów; każdy wycofany identyfikator nadal obecny w `REGISTRY` jest przekierowywany lub wymieniony w `allowedRetiredInCatalog`; a żadne źródło ani cel `DEFAULT_DEGRADATION_MAP` nie jest oznaczone jako wycofane w tej migawce. Nie dowodzi to, że model jest obecnie obsługiwany przez działającą usługę nadrzędną. Tryb offline — porównuje z `config/quality/model-lifecycle.json`, odświeżanym ręcznie za pomocą `npm run quality:refresh-model-lifecycle` (wymaga sieci; nie jest podłączone do CI). `allowedRetiredInCatalog` to zapadka służąca do stopniowego zmniejszania liczby wpisów: wpis należy dodawać wyłącznie wraz ze zgłoszeniem śledzącym. | Tak | +| `check:fetch-targets` | Każde `fetch("/api/...")` w kodzie klienckim w `src/` wskazuje na rzeczywisty plik `route.ts` | Tak | +| `check:deps` | Wszystkie zależności możliwe do zainstalowania za pomocą `npm install` ze wszystkich plików `package.json` w repozytorium znajdują się w `dependency-allowlist.json`; nowe pakiety bez przypiętej wersji lub podszywające się pod inne są oznaczane | Tak | +| `audit:deps` | `npm audit` (katalog główny + Electron) — brak ostrzeżeń o wysokiej/krytycznej wadze (częściowo pokrywa się z OSV `check:vuln-ratchet`; zobacz Rejestr zadań racjonalizacyjnych) | Tak | +| `check:lockfile` | Integralność `package-lock.json` — rejestr HTTPS, skróty integralności, brak nadpisań hosta | Tak | +| `check:licenses` | Lista dozwolonych licencji SPDX dla zależności produkcyjnych | Tak | +| `check:tracked-artifacts` | Brak artefaktów kompilacji / zatwierdzonych dowiązań symbolicznych `node_modules` (uruchamiane również w husky pre-commit; pre-push jest celowo uproszczony — #6716) | Tak | +| `check:ai-attribution` | Brak stopki AI/bota `Co-Authored-By` ani stopki informującej o wygenerowaniu przez AI w commitach, tytule lub treści PR — Reguła bezwzględna #16 (w pętli szybkich kontroli `quality.yml` dla PR→`release/**` — odczytuje dane zdarzenia, nie wykonuje żadnych działań poza PR — oraz jako krok wykonywany tylko dla PR w zadaniu lint pliku `ci.yml` dla PR→`main`; także hook husky `commit-msg`; współautorzy będący ludźmi są dozwoleni; #14436) | +| `check:vitest-exclusions` | Każde wykluczenie Vitest wskazuje zgłoszenie śledzące i znajduje się w `config/quality/vitest-exclusions.json` (#13204) | Tak | +| `check:file-size` | Żaden plik źródłowy nie przekracza limitu dla danego rozszerzenia (mechanizm zapadkowy: duże pliki zamrożone na liście `frozen`) | Tak | +| `check:error-helper` | Odpowiedzi błędów w executorach/handlerach używają `buildErrorBody()` / `sanitizeErrorMessage()` (Reguła bezwzględna #12) | Tak | +| `check:migration-numbering` | Pliki migracji SQL są numerowane sekwencyjnie, bez luk ani duplikatów | Tak | +| `check:public-creds` | Brak wpisanych na stałe wartości OAuth `client_id`/`client_secret` ani kluczy Firebase Web poza `publicCreds.ts` (Twarda reguła nr 11) | Tak | +| `check:db-rules` | Brak surowego kodu SQL poza modułami `src/lib/db/`; brak importów zbiorczych z `localDb.ts` (Twarde reguły nr 2 i 5) | Tak | +| `check:known-symbols` | Wykonawcy dostawców, strategie routingu i translatory zarejestrowane w ich tabelach dyspozytorskich odpowiadają plikom na dysku — brak osieroconych lub niezadeklarowanych symboli | Tak | +| `check:route-guard-membership` | Każda trasa uruchamiająca proces potomny jest sklasyfikowana przez `isLocalOnlyPath()` (Twarde reguły nr 15 i 17) | Tak | +| `check:test-discovery` | Każdy plik `*.test.ts` / `*.spec.ts` w repozytorium jest wykrywany przez co najmniej jeden program uruchamiający testy (mechanizm zapadkowy: lista osieroconych plików w `test-discovery-baseline.json` może się tylko skracać) | Tak | +| `check:agent-skills-sync` | Wygenerowane artefakty umiejętności agentów są zgodne z katalogiem źródłowym (brak rozbieżności) | +| `check:provider-asset-provenance` | Logo/zasoby dostawców mają zarejestrowany wpis dotyczący pochodzenia | +| `lint:json` | Pliki konfiguracyjne JSON są poprawnie przetwarzane i spełniają reguły lintowania repozytorium | +| `typecheck:core` | Kompilacja TypeScript bez błędów (wyłącznie ostrzeżenia informacyjne) | Tak | +| `typecheck:noimplicit:core` | Ścisłe `noImplicitAny` — rozwiązanie przyszłościowe; wiele istniejących miejsc wywołań nadal wymaga adnotacji | **Informacyjne** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ograniczone do `src/app/(dashboard)/**` (#7033) — starannie dobrana lista 27 plików dozwolonych w `typecheck:core` nie obejmuje żadnych plików TSX panelu, a `next build` również nigdy nie sprawdza ich typów (`next.config.mjs` ustawia `ignoreBuildErrors: true`), dlatego regresje związane z osieroconymi identyfikatorami w tym miejscu (#6625/#6909) były niewidoczne dla CI. Różnice są porównywane z zamrożoną wartością bazową liczby błędów według pliku i kodu TS (`config/quality/dashboard-typecheck-baseline.json`, ten sam wzorzec wymuszania aktualności co w `check:known-symbols`) — tylko NOWE błędy przekraczające bazową liczbę powodują niepowodzenie kontroli; gdy istniejący wcześniej błąd zostanie naprawiony, obniż wartość bazową za pomocą `--update`. | Tak | ### Zadanie: `quality-gate` Uruchamiane po `test-coverage`. W przypadku niepowodzenia blokuje scalenie. -| Skrypt | Sprawdza | Blokujący | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `quality:collect` | Generuje `quality-metrics.json` (liczba ostrzeżeń ESLint, pokrycie z połączonego raportu fragmentów) | Tak (przed mechanizmem zapadki) | -| `quality:ratchet` | Żadna metryka w `quality-baseline.json` nie uległa pogorszeniu (ostrzeżenia ESLint ≤ poziom bazowy; pokrycie ≥ poziom bazowy) | Tak | -| `check:duplication` | Duplikacja kodu (jscpd@4) nie przekracza poziomu bazowego z `quality-baseline.json` | Tak | -| `check:complexity` | Złożoność cyklomatyczna na poziomie pliku nie przekracza limitu (reguły ESLint `complexity` + `max-lines-per-function`) | Tak | -| `check:cognitive-complexity` | Zapadka złożoności poznawczej (`eslint-plugin-sonarjs`) — oddzielny przebieg ESLint; CI uruchamia oba razem jako pojedynczy krok `check:complexity-ratchets` | Tak | -| `check:dead-code` | Zapadka nieużywanych eksportów / plików (knip) nie pogarsza się względem poziomu bazowego | Tak | -| `check:compression-budget` | Budżet testu wydajności kompresji — minimalne progi oszczędności tokenów dla poszczególnych silników nie mogą ulec pogorszeniu | Tak | -| `check:type-coverage` | Zapadka procentowego udziału typowanego kodu (`type-coverage`) nie pogarsza się; w dużej mierze zastępuje `typecheck:noimplicit:core` | Tak | -| `check:codeql-ratchet` | Liczba otwartych alertów CodeQL nie wzrasta (odczyt przez `gh api`; bezpieczne pominięcie bez tokenu) — częstotliwość odświeżania i ręczne uruchamianie: patrz „Zapadka CodeQL” poniżej | Tak | +| Skrypt | Sprawdza | Blokujący | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `quality:collect` | Generuje `quality-metrics.json` (liczba ostrzeżeń ESLint, pokrycie ze scalonego raportu fragmentów) | Tak (przed mechanizmem ratchet) | +| `quality:ratchet` | Żadna metryka w `quality-baseline.json` nie uległa pogorszeniu (ostrzeżenia ESLint ≤ wartość bazowa; pokrycie ≥ wartość bazowa) | Tak | +| `check:duplication` | Duplikacja kodu (jscpd@4) nie przekracza wartości bazowej w `quality-baseline.json` | Tak | +| `check:complexity` | Złożoność cyklomatyczna na poziomie pliku nie przekracza limitu (reguły podstawowe ESLint `complexity` + `max-lines-per-function`) | Tak | +| `check:cognitive-complexity` | Mechanizm ratchet dla złożoności poznawczej (`eslint-plugin-sonarjs`) — osobne uruchomienie ESLint; CI uruchamia oba w ramach jednego kroku `check:complexity-ratchets` | Tak | +| `check:dead-code` | Mechanizm ratchet dla nieużywanych eksportów/plików (knip) nie wykazuje regresji względem wartości bazowej | Tak | +| `check:compression-budget` | Budżet testu porównawczego kompresji — minimalne poziomy oszczędności tokenów dla poszczególnych silników nie mogą ulec pogorszeniu | Tak | +| `check:type-coverage` | Mechanizm ratchet dla odsetka kodu z typami (`type-coverage`) nie wykazuje regresji; w dużej mierze zastępuje `typecheck:noimplicit:core` | Tak | +| `check:codeql-ratchet` | Liczba otwartych alertów CodeQL nie wzrasta (odczyt przez `gh api`; pominięcie bez błędu przy braku tokenu) — częstotliwość odświeżania i ręczne uruchamianie: patrz „CodeQL ratchet” poniżej | Tak | ### Zadanie: `quality-extended` -Całe zadanie ma charakter doradczy (`continue-on-error: true`). Zapadki oparte na npm są -uruchamiane faktycznie; zewnętrzne skanery są instalowane za pomocą `gh release download` -i samoczynnie pomijają wykonanie (kod wyjścia 0), gdy plik binarny nadal jest niedostępny. +Całe zadanie ma charakter doradczy (`continue-on-error: true`). Mechanizmy ratchet oparte na npm są +faktycznie uruchamiane; zewnętrzne skanery są instalowane za pomocą `gh release download` i samoczynnie pomijają wykonanie (kod wyjścia 0), +jeśli plik binarny nadal nie jest dostępny. -| Skrypt | Sprawdza | Blokujący | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -| `check:circular-deps` | Brak cyklicznych zależności (dpdm) | **Doradczy** | -| `check:bundle-size` | Rozmiar pakietu nie przekracza limitu | **Doradczy** | -| `check:secrets` | Skanowanie pod kątem sekretów (gitleaks) — pomijane, jeśli brak pliku binarnego | **Doradczy** | -| `check:vuln-ratchet` | Podatności zależności (osv-scanner) nie ulegają pogorszeniu — pomijane, jeśli brak pliku binarnego | **Doradczy** | -| `check:workflows` | Lintowanie przepływów pracy (actionlint + zizmor); brakujące/uszkodzone skanery, nieprawidłowe raporty lub brak bazowego poziomu zapadki powodują status INCOMPLETE. Prawidłowe znaleziska podlegają wybranej polityce ścisłej/doradczej/zapadki | Wykonanie wymagane; zapadka zizmor blokuje w CI | -| `check:openapi-breaking` | Niezgodne wstecznie zmiany publicznego kontraktu API (`openapi.yaml`) względem gałęzi bazowej (oasdiff) — generuje `openapiBreaking=N`; pomijane, jeśli brak oasdiff lub nie można rozpoznać specyfikacji bazowej | **Doradczy** | +| Skrypt | Sprawdza | Blokujący | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `check:circular-deps` | Brak cyklicznych zależności (dpdm) | **Doradczy** | +| `check:bundle-size` | Rozmiar pakietu nie przekracza limitu | **Doradczy** | +| `check:secrets` | Skanowanie pod kątem sekretów (gitleaks) — pomijane w przypadku braku pliku binarnego | **Doradczy** | +| `check:vuln-ratchet` | Podatności zależności (osv-scanner) nie wykazują regresji — pomijane w przypadku braku pliku binarnego | **Doradczy** | +| `check:workflows` | Lintowanie przepływów pracy (actionlint + zizmor); brakujące/uszkodzone skanery, nieprawidłowe raporty lub brak bazowej wartości ratchet powodują stan INCOMPLETE. Prawidłowe wykrycia podlegają wybranej polityce ścisłej/doradczej/ratchet | Wykonanie wymagane; ratchet zizmor blokuje w CI | +| `check:openapi-breaking` | Zmiany niezgodne wstecznie w publicznym kontrakcie API (`openapi.yaml`) względem gałęzi bazowej (oasdiff) — generuje `openapiBreaking=N`; pomijane, jeśli brakuje oasdiff lub nie można rozpoznać specyfikacji bazowej | **Doradczy** | ### Zadanie: `docs-sync-strict` -Uruchamiane dla każdego PR do `main`. W przypadku niepowodzenia blokuje scalenie. - -| Skrypt | Sprawdza | Blokujący | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `check:docs-all` | Metabrama uruchamiająca kolejno 6 poniższych bram podrzędnych | Tak | -| ↳ `check:docs-sync` | Spójność wersji w CHANGELOG / OpenAPI / llm.txt | Tak | -| ↳ `check:docs-counts` | Liczby w treści (liczba dostawców, liczba migracji itp.) mieszczą się w przedziale zapadkowym względem rzeczywistych wartości | Tak | -| ↳ `check:env-doc-sync` | Każda zmienna środowiskowa z `.env.example` jest udokumentowana w tabeli dokumentacji i odwrotnie | Tak | -| ↳ `check:deprecated-versions` | Brak ciągów oznaczających przestarzałe wersje w dokumentacji | Tak | -| ↳ `check:doc-links` | Wewnętrzne linki markdown w dokumentacji wskazują na istniejące pliki (format `[tekst]`/`(ścieżka)`) | Tak | -| ↳ `check:fabricated-docs` | Trasy, zmienne środowiskowe, polecenia CLI, nazwy hooków i ścieżki plików przywołane w dokumentacji istnieją w bazie kodu. Brama twarda z `--strict`; bez tej flagi zgłasza błąd miękki. | Tak (przez `--strict` w CI) | -| `check:cli-i18n` | Ciągi poleceń CLI są obecne we wszystkich plikach ustawień regionalnych i18n | Tak | -| `check:openapi-coverage` | Specyfikacja OpenAPI obejmuje co najmniej ustalony zapadkowo minimalny odsetek rzeczywistych tras | Tak | -| `check:openapi-security-tiers` | Adnotacje poziomów bezpieczeństwa w `openapi.yaml` są spójne z klasyfikacjami w `routeGuard.ts` | **Doradczy** | -| `check:openapi-routes` | Każda ścieżka w `openapi.yaml` wskazuje na rzeczywisty plik `route.ts` (ochrona przed halucynacjami) | Tak | -| `check:docs-symbols` | Każde odwołanie `/api/...` w `docs/**/*.md` wskazuje na rzeczywisty plik `route.ts` (ochrona przed halucynacjami) | Tak | -| `i18n translation drift` | Nieprzetłumaczone klucze w plikach ustawień regionalnych i18n — tylko ostrzeżenie | **Doradczy** | +Uruchamiane dla każdego PR do `main`. W przypadku niepowodzenia blokuje scalanie. + +| Skrypt | Sprawdza | Blokujący | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `check:docs-all` | Metabramka, która kolejno uruchamia 6 poniższych podbramek | Tak | +| ↳ `check:docs-sync` | Spójność wersji w CHANGELOG / OpenAPI / llm.txt | Tak | +| ↳ `check:docs-counts` | Liczby w tekście (liczba dostawców, liczba migracji itp.) mieszczą się w przedziale wyznaczonym względem rzeczywistych wartości | Tak | +| ↳ `check:env-doc-sync` | Każda zmienna środowiskowa z `.env.example` jest udokumentowana w tabeli dokumentacji i odwrotnie | Tak | +| ↳ `check:deprecated-versions` | W dokumentacji nie występują ciągi znaków z wycofanymi wersjami | Tak | +| ↳ `check:doc-links` | Wewnętrzne linki markdown w dokumentacji wskazują na istniejące pliki (format `[tekst]`/`(ścieżka)`) | Tak | +| ↳ `check:fabricated-docs` | Trasy, zmienne środowiskowe, polecenia CLI, nazwy hooków i ścieżki plików przywołane w dokumentacji istnieją w bazie kodu. Bramka twarda z `--strict`; bez tej flagi błąd nie blokuje. | Tak (przez `--strict` w CI) | +| `check:cli-i18n` | Ciągi znaków poleceń CLI są obecne we wszystkich plikach lokalizacji i18n | Tak | +| `check:openapi-coverage` | Specyfikacja OpenAPI obejmuje co najmniej progową, stopniowo zwiększaną liczbę rzeczywistych tras | Tak | +| `check:openapi-security-tiers` | Adnotacje poziomów zabezpieczeń w `openapi.yaml` są zgodne z klasyfikacjami w `routeGuard.ts` | **Doradczy** | +| `check:openapi-routes` | Każda ścieżka w `openapi.yaml` odpowiada rzeczywistemu plikowi `route.ts` (zapobieganie halucynacjom) | Tak | +| `check:docs-symbols` | Każde odwołanie `/api/...` w `docs/**/*.md` odpowiada rzeczywistemu plikowi `route.ts` (zapobieganie halucynacjom) | Tak | +| `i18n translation drift` | Nieprzetłumaczone klucze w plikach lokalizacji i18n — tylko ostrzeżenie | **Doradczy** | ### Zadanie: `i18n-ui-coverage` -| Skrypt | Sprawdza | Blokujący | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `check-ui-keys-coverage` (inline) | Pokrycie kluczy i18n interfejsu użytkownika wynosi ≥ 65% | Tak | -| `check-ui-value-drift` (inline) | Zmiana angielskiej **wartości** nie pozostawia nieaktualnego tłumaczenia | Tak | -| `check-new-key-coverage` (inline) | **Nowy** angielski klucz jest przetłumaczony dla każdego ustawienia regionalnego — znacznik `__MISSING__:` jest odrzucany | Tak | -| `check-translation-ratio` | Współczynnik rzeczywistych tłumaczeń dla każdego ustawienia regionalnego (liście identyczne z angielskimi / zastępcze / brakujące, spoza listy dozwolonych wyjątków) nie może przekraczać `config/quality/i18n-translation-baseline.json` + margines | **Doradczy** | +| Skrypt | Sprawdza | Blokujący | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `check-ui-keys-coverage` (inline) | Pokrycie kluczy i18n interfejsu użytkownika wynosi ≥ 65% | Tak | +| `check-ui-value-drift` (inline) | Zmieniona angielska **wartość** nie pozostawia nieaktualnego tłumaczenia | Tak | +| `check-new-key-coverage` (inline) | **Nowy** angielski klucz jest przetłumaczony w każdej lokalizacji — znacznik `__MISSING__:` jest odrzucany | Tak | +| `check-translation-ratio` | Współczynnik rzeczywistych tłumaczeń dla każdej lokalizacji (wartości identyczne z angielskimi / symbole zastępcze / brakujące elementy spoza listy dozwolonych) nie może przekraczać `config/quality/i18n-translation-baseline.json` + marginesu | **Doradczy** | -Wymaga `fetch-depth: 0` — brama wykrywająca rozbieżności wartości porównuje `en.json` z bazą scalania. +Wymaga `fetch-depth: 0` — bramka wykrywająca rozbieżności wartości porównuje `en.json` z bazą scalania. -#### `check-ui-value-drift` — brama nieaktualnych tłumaczeń +#### `check-ui-value-drift` — bramka nieaktualnych tłumaczeń -Wykrywa ten jeden rodzaj regresji i18n, którego pozostałe bramy nie są w stanie rozpoznać strukturalnie: angielska wartość -zostaje zmieniona, a tłumaczenia utworzone na podstawie _poprzedniej_ wersji angielskiej pozostają bez zmian, przez co -użytkownicy nieanglojęzyczni nadal czytają sformułowaną w sposób budzący zaufanie, lecz obecnie błędną treść. +Wykrywa jedną regresję i18n, której pozostałe bramki z przyczyn strukturalnych nie są w stanie zauważyć: angielska wartość +zostaje zmieniona, a tłumaczenia utworzone na podstawie _poprzedniej_ angielskiej wersji pozostają niezmienione, przez co +użytkownicy nieanglojęzyczni nadal czytają sformułowany z pełnym przekonaniem, ale już nieprawidłowy tekst. -Taki błąd rzeczywiście trafił do wydania. Wartość `oauthModal.googleOAuthWarning` została zmieniona po dodaniu -pomocniczego mechanizmu logowania Antigravity (#5203); w **39 z 43 ustawień regionalnych** pozostał tekst nakazujący operatorom „skopiować -pełny adres URL i wkleić go poniżej” — jest to procedura, której nie da się ukończyć dla tego dostawcy. Problem -pozostał niezauważony aż do #8463, ponieważ: +Taka sytuacja rzeczywiście trafiła do wydania. `oauthModal.googleOAuthWarning` zmieniono po dodaniu pomocnika logowania +Antigravity (#5203); **39 z 43 lokalizacji** nadal zawierało tekst nakazujący operatorom „skopiować pełny adres URL +i wkleić go poniżej” — w przypadku tego dostawcy taki proces nie może się zakończyć. Problem pozostał +niezauważony aż do #8463, ponieważ: -- `sync-ui-keys` uzupełnia wyłącznie klucze, których **brakuje**, a nigdy te, które są **nieaktualne**; -- `check-ui-keys-coverage` zlicza _obecność_ kluczy, dlatego nieaktualne tłumaczenie jest uznawane za pokryte; +- `sync-ui-keys` uzupełnia tylko klucze, których **brakuje**, nigdy te, które są **nieaktualne**; +- `check-ui-keys-coverage` zlicza _obecność_ kluczy, więc nieaktualne tłumaczenie jest uznawane za pokryte; - `check-translation-drift` śledzi kopie dokumentacji `docs/i18n//**.md` — nigdy nie odczytuje `src/i18n/messages/*.json`. Blokuje w zadaniu `docs-sync-strict` od ponownej synchronizacji - 2026-09: po edycji głównego dokumentu uruchom `npm run i18n:run -- --files=` (na poziomie sekcji, niewielki koszt). + 2026-09: edytuj główny dokument → `npm run i18n:run -- --files=` (na poziomie sekcji, niewielki koszt). -**Uwzględnia różnice, nie opiera się na bazie odniesienia.** Porównuje plik `en.json` w punkcie wspólnego przodka z +**Uwzględnia różnice, nie opiera się na pliku bazowym.** Porównuje `en.json` w punkcie bazowym scalania z drzewem roboczym; dla każdego klucza, którego angielska wartość uległa zmianie, każde tłumaczenie nadal zawierające -niezmienioną wersję jest nieaktualne. Celowo **zamraża to istniejący dług** — różnica -nie pozwala ustalić, z której starej angielskiej wersji pochodzi istniejące od dawna tłumaczenie, dlatego mechanizm kontrolny ocenia -wyłącznie to, czego dotyczy bieżąca zmiana. Alternatywa (baza skrótów dla poszczególnych kluczy) wymagałaby -wygenerowanego pliku o rozmiarze ~600 KB, 3× większego niż największa istniejąca baza odniesienia, zmieniającego się przy każdym PR dotyczącym i18n. +niezmienioną wersję jest nieaktualne. To celowo **zamraża istniejący dług** — różnica +nie pozwala ustalić, z której starej angielskiej wersji pochodzi istniejące od dawna tłumaczenie, dlatego bramka ocenia +wyłącznie to, czego dotyczy bieżąca zmiana. Alternatywa (bazowy skrót dla każdego klucza) wymagałaby +wygenerowanego pliku o rozmiarze około 600 KB, 3× większego niż największy istniejący plik bazowy, zmieniającego się przy każdym PR dotyczącym i18n. -Można spełnić ten wymóg na dwa sposoby: +Można spełnić ten warunek na dwa sposoby: 1. zaktualizować tłumaczenia, których dotyczy zmiana, albo -2. ustawić ich wartość na `__MISSING__:` — środowisko uruchomieniowe zwróci wtedy poprawiony tekst angielski - (`src/i18n/request.ts::deepMergeFallback`, #7258), a klucz trafi do kolejki tłumaczeń. +2. ustawić ich wartość na `__MISSING__:` — środowisko uruchomieniowe wyświetli wtedy poprawiony tekst angielski + (`src/i18n/request.ts::deepMergeFallback`, #7258), a klucz zostanie dodany do kolejki tłumaczeń. -Jeśli zmieniło się **znaczenie** ciągu, zaleca się **zmianę nazwy klucza**: nowy klucz nie może odziedziczyć -nieaktualnego tłumaczenia. Ten wzorzec zastosowano w #8463. +Jeśli zmieniło się **znaczenie** ciągu, najlepiej **zmienić nazwę klucza**: nowy klucz nie może odziedziczyć +nieaktualnego tłumaczenia. Taki wzorzec zastosowano w #8463. ```bash -npm run i18n:check-value-drift # tryb rygorystyczny (uruchamiany przez CI) +npm run i18n:check-value-drift # tryb ścisły (uruchamiany przez CI) npm run i18n:check-value-drift:warn # tylko raport BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` Kończy działanie z kodem 0 i komunikatem `SKIP reason=base-unresolved`, gdy nie można odczytać katalogu bazowego (płytki -klon bez bazowego odwołania), analogicznie do `check-openapi-breaking`. +klon bez referencji bazowej), analogicznie do `check-openapi-breaking`. ### Zadanie: `i18n` -Pełna macierz walidacji i18n (jedno zadanie na ustawienia regionalne). Całe zadanie ma charakter informacyjny. +Pełna macierz walidacji i18n (jedno zadanie na język). Całe zadanie ma charakter informacyjny. -| Skrypt | Sprawdza | Blokowanie | +| Skrypt | Weryfikuje | Blokowanie | | ------------------------------- | ------------------------------------------ | --------------------------------------------------------------- | | `validate_translation.py quick` | Kompletność tłumaczenia dla każdego języka | **Informacyjne** (`continue-on-error: true` dla całego zadania) | @@ -248,32 +257,32 @@ Pełna macierz walidacji i18n (jedno zadanie na ustawienia regionalne). Całe za Uruchamiane wyłącznie dla pull requestów. -| Skrypt | Sprawdza | Blokowanie | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | -| `check:pr-test-policy` | PR-y zmieniające kod produkcyjny w `src/`, `open-sse/`, `electron/` lub `bin/` muszą zawierać lub aktualizować testy (Twarda reguła #8) | Tak | -| `check:test-masking` | Zmienione pliki testowe nie zmniejszają łącznej liczby asercji ani nie dodają tautologii `assert.ok(true)` | Tak | -| `check:pr-evidence` | Treść PR-a przytacza wyniki testów/VPS dotyczące zmiany (automatyzuje Twardą regułę #18 przez przeszukiwanie opisu PR-a — rozwiązanie kruche, patrz Backlog) | Tak | +| Skrypt | Weryfikuje | Blokowanie | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | PR-y zmieniające kod produkcyjny w `src/`, `open-sse/`, `electron/` lub `bin/` muszą zawierać nowe lub zaktualizowane testy (Twarda reguła #8) | Tak | +| `check:test-masking` | Zmienione pliki testowe nie zmniejszają łącznej liczby asercji ani nie dodają tautologii `assert.ok(true)` | Tak | +| `check:pr-evidence` | Opis PR-a przytacza dowody z testów/VPS dotyczące zmiany (automatyzuje Twardą regułę #18 przez przeszukiwanie treści PR-a — rozwiązanie kruche, patrz Zaległości) | Tak | ### Zadanie: `test-vitest` -Uruchamiane po `build`. W przypadku niepowodzenia blokuje scalenie. +Uruchamiane po `build`. Niepowodzenie blokuje scalenie. -| Zestaw | Sprawdza | Blokowanie | -| ---------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Serwer MCP (110 narzędzi), autoCombo, pamięć podręczna — runner vitest | Tak | -| `test:vitest:ui` | Testy komponentów interfejsu użytkownika — runner vitest | **Blokujące** — istniejące wcześniej niepowodzenia są jawnie wykluczone w `vitest.config.ts`; nowe niepowodzenia przerywają zadanie | +| Zestaw | Weryfikuje | Blokowanie | +| ---------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Serwer MCP (110 narzędzi), autoCombo, pamięć podręczna — runner vitest | Tak | +| `test:vitest:ui` | Testy komponentów interfejsu użytkownika — runner vitest | **Blokujące** — istniejące wcześniej błędy są jawnie wykluczone w `vitest.config.ts`; nowe błędy powodują niepowodzenie zadania | ### Nocne przepływy pracy (zaplanowane, informacyjne) Są uruchamiane zgodnie z harmonogramem cron (oraz przez `workflow_dispatch`), nigdy dla PR-ów. Wszystkie mają charakter informacyjny. -| Przepływ pracy | Sprawdza | Blokowanie | +| Przepływ pracy | Weryfikuje | Blokowanie | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | Testy właściwości fast-check z losowym ziarnem i dużą liczbą przebiegów | **Informacyjne** | -| `nightly-resilience` | Kontrola wzrostu sterty, wstrzykiwanie błędów metodą chaos engineering, testy obciążeniowe/długotrwałe k6 | **Informacyjne** | -| `nightly-llm-security` | Ochrona promptfoo przed wstrzyknięciami (tryb blokowania) + sondy garak (pomijane bez sekretu dostawcy) | **Informacyjne** | -| `nightly-schemathesis` | Fuzzing kontraktu OpenAPI (schemathesis) względem działającej instancji OmniRoute z użyciem `docs/openapi.yaml` — ujawnia naruszenia specyfikacji / nieobsłużone błędy 500 (Etap 8 B.4) | **Informacyjne** | -| `nightly-mutation` | Wynik testów mutacyjnych Stryker dla szybkiej ścieżki testów jednostkowych — przetrwałe mutanty ujawniają słabe asercje | **Informacyjne** | +| `nightly-property` | Testy właściwości fast-check z losowym ziarnem i dużą liczbą uruchomień | **Informacyjne** | +| `nightly-resilience` | Bramka wzrostu sterty, chaotyczne wstrzykiwanie błędów, testy obciążeniowe/długotrwałe k6 | **Informacyjne** | +| `nightly-llm-security` | Ochrona przed atakami typu prompt injection w promptfoo (tryb blokowania) i sondy garak (pomijane bez sekretu dostawcy) | **Informacyjne** | +| `nightly-schemathesis` | Fuzzing kontraktu OpenAPI (schemathesis) względem działającej instancji OmniRoute z użyciem `docs/openapi.yaml` — ujawnia naruszenia specyfikacji / nieobsłużone błędy 500 (Faza 8 B.4) | **Informacyjne** | +| `nightly-mutation` | Wynik testów mutacyjnych Stryker dla szybkiej ścieżki testów jednostkowych — mutanty, które przetrwały, ujawniają słabe asercje | **Informacyjne** | | `nightly-compat` | Macierz zgodności silnika Node dla obsługiwanych zakresów `engines.node` | **Informacyjne** | --- @@ -539,43 +548,43 @@ błąd połączenia i nigdy nie zakłóca sesji. --- -## Rejestr racjonalizacji (przegląd ROI — Etap 9, Fala 3) +## Rejestr racjonalizacji (przegląd ROI — etap 9, fala 3) -Ten wykaz uzgodniono z `ci.yml` w dniu 2026-06-17 (w poprzedniej wersji pominięto +Ten wykaz uzgodniono z `ci.yml` 2026-06-17 (w poprzedniej wersji pominięto `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Przegląd ROI uzgodnionego zestawu wskazał następujących kandydatów do racjonalizacji. **Scalenia są mechanicznymi zmianami -CI; przełączenia/usunięcia są decyzjami dotyczącymi zasad, zastrzeżonymi dla operatora.** Żadna +CI; przełączenia/usunięcia to decyzje dotyczące zasad, zastrzeżone dla operatora.** Żadna z poniższych zmian nie została jeszcze zastosowana. -**Pominięte również powyżej** (doradcze, słaby sygnał): zadanie `docs-lint` -(markdownlint + Vale, całe zadanie z `continue-on-error`) oraz samodzielne przepływy pracy skanerów +**Powyżej nie udokumentowano również** (tryb doradczy, słaby sygnał): zadania `docs-lint` +(markdownlint + Vale, całe zadanie z `continue-on-error`) oraz samodzielnych przepływów pracy skanerów `semgrep.yml` / `codeql.yml` / `scorecard.yml`. Wartość `semgrepFindings: 0` znajduje się w -`quality-baseline.json`, ale nie jest powiązana z blokującym mechanizmem zapadkowym w `ci.yml` — ta metryka +`quality-baseline.json`, ale nie jest podłączona do blokującej zapadki w `ci.yml` — ta metryka jest obecnie osierocona. ### Scalanie / deduplikacja (mechaniczne, niższe ryzyko) -Każdego kandydata zweryfikowano względem bieżącego stanu bramek w dniu 2026-06-17 (ufaj, ale sprawdzaj); -okazało się, że kilka „oczywistych” scaleń ukrywa dług i **nie** nadaje się do bezpośredniego zastosowania. +Każdego kandydata zweryfikowano względem bieżącego stanu bramek 2026-06-17 (ufaj, ale sprawdzaj); +okazało się, że kilka „oczywistych” scaleń ukrywa dług i **nie** stanowi bezproblemowych zamienników. -- **`check:docs-sync` uruchamia się dwukrotnie** — samodzielnie w zadaniu `lint` oraz ponownie wewnątrz `check:docs-all` (`docs-sync-strict`) i haka husky pre-commit. ✅ **GOTOWE** — usunięto samodzielne wywołanie w `lint`. -- **Skanowanie CVE** — ❌ **NIE jest to proste scalenie.** `audit:deps` kończy się twardym błędem przy każdej luce CVE o wysokiej/krytycznej wadze; `check:vuln-ratchet` (osv) kończy się błędem tylko w przypadku _regresji_ względem poziomu bazowego (obecnie 1 MODERATE). Odmienna semantyka — usunięcie `audit:deps` oznaczałoby utratę bezwzględnej bramki dla luk o wysokiej/krytycznej wadze. Zachować oba. -- **Wykrywanie cykli** — ❌ **NIE jest to proste scalenie.** `check:circular-deps` (dpdm) zgłasza **91 cykli** (dlatego ma charakter doradczy); nie można nadać mu statusu blokującego bez ich uprzedniego rozwiązania, a jego zakres jest szerszy niż w przypadku zielonego, starannie dobranego `check:cycles`. Zachować `check:cycles` jako blokujące; rozwiązanie 91 cykli dpdm stanowi osobną pozycję rejestru. -- **Złożoność** — ✅ **GOTOWE** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jedno przejście ESLint, zliczanie według ruleId, dzięki czemu bazowe wartości złożoności cyklomatycznej+max-lines oraz złożoności poznawczej pozostają niezależne; poszczególne `check:complexity` / `check:cognitive-complexity` pozostają dostępne do lokalnego użycia z `--update`. -- **Ochrona `/api` przed halucynacjami** — ✅ **GOTOWE** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jedna inwentaryzacja FS katalogu `src/app/api`, openapi-routes + docs-symbols nadal raportują niezależnie; poszczególne polecenia pozostają dostępne do lokalnych uruchomień. -- **`check:node-runtime` uruchamia się w 11 zadaniach** — ⚠️ **niski ROI.** Każde działa na osobnym runnerze, a kontrola trwa <1s; łączna oszczędność wyniosłaby ~10s kosztem utraty niedrogiej ochrony dla każdego zadania. Nie warto powodować zamieszania. -- **`typecheck:noimplicit:core` w lintowaniu CI** — ✅ **usunięto z zadania lint** (miało charakter doradczy z `continue-on-error`); blokujący zakres kontroli typów zapewniają `typecheck:core` + `check:type-coverage`. Zachowano skrypt lokalny. +- **`check:docs-sync` uruchamia się dwukrotnie** — samodzielnie w zadaniu `lint` oraz ponownie wewnątrz `check:docs-all` (`docs-sync-strict`) i w hooku pre-commit husky. ✅ **GOTOWE** — samodzielne wywołanie w `lint` zostało usunięte. +- **Skanowanie CVE** — ❌ **NIE jest to bezproblemowe scalenie.** `audit:deps` kończy się twardym błędem przy dowolnej luce CVE o wysokiej/krytycznej wadze; `check:vuln-ratchet` (osv) kończy się błędem tylko przy _regresji_ względem wartości bazowej (obecnie 1 MODERATE). Inna semantyka — usunięcie `audit:deps` oznaczałoby utratę bezwzględnej bramki dla luk o wysokiej/krytycznej wadze. Należy zachować oba. +- **Wykrywanie cykli** — ✅ **GOTOWE** (#15159 G-01/G-02). Poprzedni tekst określał `check:cycles` jako „zieloną, starannie dobraną” bramkę i uzasadniał utrzymanie jej w trybie blokującym tym, że `check:circular-deps` (dpdm) zgłaszało 91 cykli. Ten zielony wynik był **fałszywie pozytywny**: `check:cycles` skanował 5 podkatalogów (450 plików), dopasowywał tylko statyczne `import|export … from` i odrzucał każdy specyfikator `@/` oraz `@omniroute/open-sse/`, przez co nie mógł wykryć cykli dynamicznego importu i aliasów, które dominowały w repozytorium. Naprawiono: bramka przeszukuje teraz `src` + `open-sse` (5023 pliki), zbiera specyfikatory z AST TypeScriptu (dzięki czemu `import("…")` jest uwzględniany, a `typeof import("…")` w pozycji typu — nie) i rozwiązuje `paths` z tsconfig. Wykrywa **14** cykli, a nie 0. Ponieważ 14 istniejących wcześniej cykli nie można naprawić w PR-ze dotyczącym bramki, `check:cycles` działa teraz jako **zapadka** (`--ratchet`, limit `metrics.cycles.value = 14` w `quality-baseline.json`, `direction: down`) — blokuje każdą _regresję_, a liczba może wyłącznie maleć. CI uruchamia `npm run check:cycles:ratchet`. Redukcja długu odbywa się w ramach **A-01**. `check:circular-deps` (dpdm) pozostaje doradczą, szerszą drugą opinią. +- **Złożoność** — ✅ **GOTOWE** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jedno przejście ESLint, zliczanie według ruleId, dzięki czemu wartości bazowe dla złożoności cyklomatycznej + maksymalnej liczby wierszy oraz złożoności poznawczej pozostają niezależne; poszczególne `check:complexity` / `check:cognitive-complexity` pozostają dostępne dla lokalnego `--update`. +- **Ochrona `/api` przed halucynacjami** — ✅ **GOTOWE** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jeden wykaz FS katalogu `src/app/api`; openapi-routes + docs-symbols nadal raportują niezależnie; poszczególne polecenia pozostają dostępne do uruchamiania lokalnego. +- **`check:node-runtime` uruchamia się w 11 zadaniach** — ⚠️ **niski ROI.** Każde korzysta z osobnego runnera, a sprawdzenie trwa <1 s; łączna oszczędność wyniosłaby ~10 s, kosztem utraty taniego zabezpieczenia dla każdego zadania. Nie warto wprowadzać takiej zmiany. +- **`typecheck:noimplicit:core` w zadaniu lint CI** — ✅ **usunięto z zadania lint** (wcześniej działało doradczo z `continue-on-error`); blokującą powierzchnię typów zapewniają `typecheck:core` + `check:type-coverage`. Skrypt lokalny zachowano. ### Przełączenie / decyzja (zasady operatora) -- `check:openapi-security-tiers` (doradcze) — ❌ **NIE można go bezpośrednio przełączyć.** Kończy się kodem 0, ale ostrzega, że kilka tras `traffic-inspector` w ramach `LOCAL_ONLY_API_PREFIXES` nie ma adnotacji `x-loopback-only: true`. Wymuszenie tej kontroli wymaga najpierw dodania tych adnotacji do `openapi.yaml`. -- `typecheck:noimplicit:core` (doradcze) — w dużej mierze zastąpione przez blokujący mechanizm zapadkowy `check:type-coverage`. Przełączyć na mechanizm zapadkowy albo usunąć redundantne drugie przejście `tsc`. -- `test:vitest:ui` (obecnie **blokujące**) — wcześniej istniejące błędy są jawnie wykluczone w `vitest.config.ts` za pomocą komentarzy śledzących `// #8618`; nowe błędy powodują niepowodzenie zadania. -- `check:secrets` (gitleaks, blokujący mechanizm zapadkowy zamrożony na poziomie 3 udokumentowanych wyników fałszywie dodatnich) — dodać te 3 przypadki do listy dozwolonych, aby osiągnąć 0, albo obniżyć status do doradczego. Pokrywa się z natywnym skanowaniem sekretów GitHub + `check:public-creds`. -- `check:pr-evidence` (blokujące, przeszukuje tekst opisu PR) — wysokie ryzyko wyników fałszywie dodatnich; usunięcie osłabi egzekwowanie Twardej Reguły nr 18, więc jest to rzeczywista decyzja dotycząca zasad. -- `semgrep` (samodzielne, doradcze) — pokrywa się z CodeQL w zakresie kategorii OWASP; powiązać jego poziom bazowy z mechanizmem zapadkowym albo usunąć. +- `check:openapi-security-tiers` (doradcze) — ❌ **NIE można go bezproblemowo przełączyć.** Kończy działanie z kodem 0, ale ostrzega, że w kilku trasach `traffic-inspector` w ramach `LOCAL_ONLY_API_PREFIXES` brakuje adnotacji `x-loopback-only: true`. Wymuszenie tej kontroli wymaga najpierw dodania tych adnotacji do `openapi.yaml`. +- `typecheck:noimplicit:core` (doradcze) — w dużej mierze zastąpione przez blokującą zapadkę `check:type-coverage`. Należy przełączyć je na zapadkę albo usunąć nadmiarowe drugie przejście `tsc`. +- `test:vitest:ui` (obecnie **blokujące**) — istniejące wcześniej błędy są jawnie wykluczone w `vitest.config.ts` za pomocą komentarzy śledzących `// #8618`; nowe błędy powodują niepowodzenie zadania. +- `check:secrets` (gitleaks, blokująca zapadka zamrożona na 3 udokumentowanych wynikach fałszywie pozytywnych) — należy dodać te 3 przypadki do listy dozwolonych, aby osiągnąć 0, albo zdegradować kontrolę do trybu doradczego. Nakłada się na natywne skanowanie sekretów GitHub + `check:public-creds`. +- `check:pr-evidence` (blokujące, przeszukuje tekst opisu PR) — wysokie ryzyko wyników fałszywie pozytywnych; usunięcie osłabi egzekwowanie Hard Rule #18, więc jest to rzeczywista decyzja dotycząca zasad. +- `semgrep` (samodzielne, doradcze) — nakłada się na CodeQL w zakresie rodzin OWASP; należy podłączyć jego wartość bazową do zapadki albo go usunąć. --- diff --git a/docs/i18n/pt-BR/CONTRIBUTING.md b/docs/i18n/pt-BR/CONTRIBUTING.md index 2c37bbfdf4b..2295348707f 100644 --- a/docs/i18n/pt-BR/CONTRIBUTING.md +++ b/docs/i18n/pt-BR/CONTRIBUTING.md @@ -399,7 +399,7 @@ Escreva testes unitários em `tests/unit/` que cubram, no mínimo: --- -## Checklist da Pull Request +## Checklist do Pull Request - [ ] Os testes passam (`npm test`) - [ ] O lint passa (`npm run lint`) @@ -407,14 +407,14 @@ Escreva testes unitários em `tests/unit/` que cubram, no mínimo: - [ ] Tipos TypeScript adicionados para novas funções e interfaces públicas - [ ] Nenhum segredo ou valor de fallback codificado diretamente - [ ] Credenciais públicas upstream incorporadas por meio de `resolvePublicCred()` (consulte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nunca como literais -- [ ] As respostas de erro passam por `buildErrorBody()` / `sanitizeErrorMessage()` — nenhum stack trace bruto nos corpos das respostas (consulte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Respostas de erro passam por `buildErrorBody()` / `sanitizeErrorMessage()` — nenhum stack trace bruto nos corpos das respostas (consulte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Comandos de shell (`exec` / `spawn`) passam valores de runtime por meio de `env`, não por interpolação de strings - [ ] Todas as entradas são validadas com esquemas Zod - [ ] **Fragmento** do changelog adicionado em `changelog.d/{features|fixes|maintenance}/-.md` para alterações visíveis aos usuários (consulte [`changelog.d/README.md`](./changelog.d/README.md)) — **não** edite `CHANGELOG.md` diretamente; os fragmentos são agregados no momento do lançamento e nunca geram conflitos entre PRs - [ ] Documentação atualizada (se aplicável) -- [ ] Nenhum novo alerta do CodeQL / Secret-Scanning aberto, ou cada um foi descartado com uma justificativa técnica que faça referência ao documento relevante em `docs/security/` +- [ ] Nenhum novo alerta do CodeQL / Secret-Scanning foi aberto, ou cada alerta foi descartado com uma justificativa técnica que faça referência ao documento relevante em `docs/security/` - [ ] Rotas que iniciam processos filhos (`/api/mcp/`, `/api/cli-tools/runtime/`) classificadas como `isLocalOnlyPath()` em `src/server/authz/routeGuard.ts` — consulte a [Regra Rígida nº 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Nenhum trailer `Co-Authored-By` nas mensagens de commit — os commits devem aparecer exclusivamente sob a identidade Git do proprietário do repositório (Regra Rígida nº 16) +- [ ] Nenhum trailer `Co-authored-by` de IA/bot nas mensagens de commit (Regra Rígida nº 16) — colaboradores humanos cujo trabalho for reutilizado recebem crédito com trailers padrão `Co-authored-by: Name ` --- diff --git a/docs/i18n/pt-BR/docs/architecture/QUALITY_GATES.md b/docs/i18n/pt-BR/docs/architecture/QUALITY_GATES.md index 35a0c8333ce..464a90e944f 100644 --- a/docs/i18n/pt-BR/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/pt-BR/docs/architecture/QUALITY_GATES.md @@ -20,173 +20,166 @@ replicação independente de ferramentas do mesmo sistema, consulte o ### Admissão de candidatos Os workflows de CI e Quality Gates emitem, cada um, um veredito estável: `Gate / CI` e -`Gate / Quality`. A política de admissão versionada deles enumera cada job upstream -como obrigatório ou consultivo. Um job obrigatório aplicável deve ser bem-sucedido: -resultados ausentes, cancelados, ignorados, pendentes e desconhecidos não podem -estabelecer PASS. Uma classificação válida como somente documentação ou somente -catálogo pode tornar uma lane de código não aplicável; um PR em rascunho não é um -candidato aceito. Um rótulo `hotfix` não dispensa evidências. - -Ambos os workflows abrangem PRs e pushes para branches main/release, acionamento -manual e eventos de merge group. Push, acionamento e merge group executam a seleção -completa. Forks e merge groups usam runners hospedados para jobs que, de outra forma, -selecionariam runners auto-hospedados; deve-se verificar se há capacidade hospedada -suficiente antes da implantação. - -Cada comprovante JSON identifica o SHA do checkout, a execução do workflow e a tentativa. -A CLI rejeita uma incompatibilidade entre o SHA do checkout e o do evento. Os testes -de workflow vinculam a associação à política à lista `needs` do job de veredito, para -que uma lane nova ou removida não desapareça silenciosamente. Os comprovantes abrangem -seu próprio workflow, não a publicação, a implantação nem os detalhes internos de um -scanner consultivo existente. Ativar ambos os nomes de verificação nas regras da branch -é uma alteração administrativa separada; adicionar esses jobs não protege uma branch -por si só. - -### Inventário de varredura estática - -O inventário versionado de aliases npm e a associação à varredura estática ficam em +`Gate / Quality`. Sua política de admissão versionada enumera cada job upstream +como obrigatório ou consultivo. Um job obrigatório aplicável deve ser bem-sucedido: resultados +ausentes, cancelados, ignorados, pendentes e desconhecidos não podem estabelecer PASS. Uma +classificação válida de somente documentação ou somente catálogo pode tornar uma lane de código não aplicável; +um PR em rascunho não é um candidato aceito. Um label `hotfix` não dispensa evidências. + +Ambos os workflows abrangem PRs e pushes para branches main/release, acionamento manual e +eventos de merge group. Push, dispatch e merge group executam a seleção completa. Forks +e merge groups usam runners hospedados para jobs que, de outra forma, selecionariam runners +auto-hospedados; deve-se verificar se há capacidade hospedada suficiente antes da implantação. + +Cada recibo JSON identifica o SHA do checkout, a execução e a tentativa do workflow. +A CLI rejeita uma divergência entre o SHA do checkout e o do evento. Os testes do workflow vinculam a participação +na política à lista `needs` do job de veredito, para que uma lane nova ou removida não possa desaparecer silenciosamente. +Os recibos abrangem seu próprio workflow, não a publicação, a implantação nem os detalhes internos +de um scanner consultivo existente. Ativar ambos os nomes de checks nas regras de branch é uma +alteração administrativa separada; adicionar esses jobs não protege, por si só, uma branch. + +### Inventário da varredura estática + +O inventário versionado de aliases do npm e a composição da varredura estática ficam em `config/quality/gate-manifest.json`. Execute `npm run check:gate-manifest` para validar -os nomes dos scripts e os comandos exatos em relação ao `package.json`; adições, remoções -e divergências de comandos fazem falhar tanto o hook local quanto os jobs de classificação -de alterações na CI. Um alias não é um job de workflow, uma instância de matriz nem um -caso de teste: essas contagens não devem ser apresentadas como equivalentes. +os nomes dos scripts e os comandos exatos em relação ao `package.json`; adições, remoções e +alterações de comandos fazem falhar tanto o hook local quanto os jobs de classificação de alterações na CI. +Um alias não é um job de workflow, uma instância de matriz nem um caso de teste: essas contagens não devem +ser apresentadas como equivalentes. Use `npm run quality:scan -- --list` ou `npm run quality:scan:fast -- --list` para inspecionar os aliases selecionados sem executá-los. O runner invoca o -entrypoint npm, portanto seu runtime (incluindo Bun, quando configurado) é preservado. -O manifesto registra os aliases externos a esses perfis como invocados separadamente, -e comandos de manutenção são proibidos em perfis de varredura somente leitura. +ponto de entrada do npm, portanto seu runtime (incluindo Bun, quando configurado) é preservado. +O manifesto registra aliases fora desses perfis como invocados separadamente, e +comandos de manutenção são proibidos em perfis de varredura somente leitura. Esses perfis abrangem apenas a varredura estática. Eles não certificam testes do produto, -cobertura, empacotamento, verificações externas nem a aceitação completa de um candidato -para release. A admissão do workflow usa o `config/quality/admission-policy.json` -vinculado e `scripts/quality/admission-verdict.mjs`. Os perfis de observação de release -permanecem separados; inspecione suas verificações e seus comprovantes aplicáveis de -forma independente. O inventário descritivo abaixo é uma referência, não uma prova de -que um gate foi realmente executado. +cobertura, empacotamento, verificações externas nem a aceitação completa de um candidato para release. +A admissão do workflow usa `config/quality/admission-policy.json` e +`scripts/quality/admission-verdict.mjs` vinculados. Os perfis do observador de release permanecem separados; +inspecione suas verificações e seus recibos aplicáveis de forma independente. O inventário +descritivo abaixo é uma referência, não uma prova de que um gate foi realmente executado. Os scripts ficam em `scripts/check/` (gates de política) e `scripts/quality/` (mecanismo de ratchet). A fonte da verdade da CI é `.github/workflows/ci.yml`. -### Caminho rápido de PR de release (`quality.yml`) +### Caminho rápido para PRs de release (`quality.yml`) -`.github/workflows/quality.yml` complementa a CI em PRs de main/release, pushes para -branches protegidas, acionamentos e merge groups. Os PRs usam verificações rápidas -filtradas por caminho. O build duplicado, permanentemente desabilitado, foi removido; -as verificações reais de build/empacotamento/inicialização permanecem na CI. +`.github/workflows/quality.yml` complementa a CI em PRs de main/release, pushes para branches +protegidas, dispatch e merge groups. Os PRs usam verificações rápidas filtradas por caminho. O build +duplicado permanentemente desabilitado foi removido; as verificações reais de build/package/boot permanecem na CI. -| Job | Escopo | Bloqueante | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| `Docs Gates (fast-path)` | PRs de documentação/código; referências de documentação da API e docs-all | Sim | -| `Fast Quality Gates` | PRs de código; verificações estáticas, verificação de tipos, verificação de tipos do dashboard, testes unitários impactados | Sim | -| `Forgotten sibling tests` | PRs de código; módulos alterados rastreados até consumidores estáticos e testes irmãos candidatos; caminhos de barrel e importação dinâmica são relatados como diagnósticos consultivos, com exceções referenciadas na lista de permissões | **Consultivo** | -| `Vitest (fast-path)` | PRs de código; suíte rápida do vitest | Sim | -| `Unit Tests fast-path` | PRs de código; suíte unitária de 4 shards | Sim | -| `No new ESLint warnings` | PRs de código; proteção de lint ciente de supressões | Sim, incluindo forks | -| `Merge integrity (changelog + generated skills)` | PRs que não sejam rascunhos; sincronização do changelog e das skills geradas | Sim, incluindo forks | +| Job | Escopo | Bloqueante | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | PRs de documentação/código; referências da documentação da API e toda a documentação | Sim | +| `Fast Quality Gates` | PRs de código; verificações estáticas, typecheck, typecheck do dashboard e testes unitários impactados | Sim | +| `Forgotten sibling tests` | PRs de código; módulos alterados rastreados até consumidores estáticos e possíveis testes irmãos; caminhos por barrel e importação dinâmica são relatados como diagnósticos consultivos, com exceções referenciadas na allowlist | **Consultivo** | +| `Vitest (fast-path)` | PRs de código; suíte rápida do vitest | Sim | +| `Unit Tests fast-path` | PRs de código; suíte de testes unitários com 4 shards | Sim | +| `No new ESLint warnings` | PRs de código; proteção de lint com reconhecimento de supressões | Sim, incluindo forks | +| `Merge integrity (changelog + generated skills)` | PRs que não sejam rascunhos; sincronização do changelog e das skills geradas | Sim, incluindo forks | #### Relatório de testes irmãos esquecidos -`npm run check:forgotten-sibling-tests` reutiliza o resolvedor de imports por trás do -mapa de impacto de testes. Para cada módulo de produção alterado, ele relata cadeias -determinísticas `módulo/símbolo alterado -> consumidor estático -> teste irmão candidato` -quando o teste candidato está ausente do diff da pull request. O resumo em Markdown e -o resultado JSON são mantidos como o artefato de workflow `forgotten-sibling-tests` -para calibração antes de qualquer implantação bloqueante. +`npm run check:forgotten-sibling-tests` reutiliza o resolvedor de imports por trás do mapa de impacto dos testes. +Para cada módulo de produção alterado, ele relata cadeias determinísticas +`módulo/símbolo alterado -> consumidor estático -> possível teste irmão` quando o teste +em questão está ausente do diff do pull request. O resumo em Markdown e o resultado em JSON são mantidos como +o artefato de workflow `forgotten-sibling-tests` para calibração antes de qualquer implantação bloqueante. Reexportações de barrel e importações dinâmicas servem apenas como diagnósticos de resolução; elas nunca criam uma constatação bloqueante. As exceções revisadas ficam em `config/quality/forgotten-sibling-allowlist.json`. Cada entrada deve nomear o consumidor e o teste candidato, fornecer uma justificativa específica e incluir um link para uma issue ou um pull request do GitHub. Entradas malformadas -falham de forma fechada. As exceções não podem suprimir um teste candidato excluído nem um diff que adicione `.skip`/`.todo`; -o enfraquecimento de asserções e outros tipos de mascaramento continuam sob responsabilidade do gate +falham de forma restritiva. As exceções não podem suprimir um teste candidato excluído nem um diff que adicione `.skip`/`.todo`; +o enfraquecimento de asserções e outras formas de mascaramento continuam sob responsabilidade do gate `check:test-masking`, que é bloqueante de forma independente. ### Job: `lint` -É executado em todo PR para `main`. Bloqueia o merge em caso de falha. - -| Script (`npm run ...`) | Valida | Bloqueante | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | A versão do Node.js está dentro do intervalo compatível | Sim | -| `check:cycles` | Importações circulares — todos os módulos de `src/` + `open-sse/` | Sim | -| `check:route-validation:t06` | Schemas Zod presentes em todas as rotas (política do Tier 6) | Sim | -| `check:any-budget:t11` | A contagem de `@ts-expect-error // any` não excede o orçamento (catraca do Tier 11) | Sim | -| `check:provider-consistency` | Cada provedor em `providers.ts` possui uma entrada correspondente em `providerRegistry.ts` (e vice-versa, dentro da lista de permissões) | Sim | -| `check:model-lifecycle` | As três tabelas de roteamento mantidas manualmente permanecem consistentes com o snapshot de ciclo de vida versionado (#11503): `FITNESS_TABLE` (`taskFitness.ts`) não pontua nenhum id descontinuado que `REGISTRY` possa rotear; cada destino de `BUILT_IN_ALIASES` está presente em `REGISTRY` e ausente do snapshot de ids descontinuados; cada id descontinuado ainda presente em `REGISTRY` é encaminhado ou listado em `allowedRetiredInCatalog`; e nenhuma origem ou destino de `DEFAULT_DEGRADATION_MAP` aparece como descontinuado nesse snapshot. Isso não comprova que um modelo esteja sendo fornecido atualmente por um upstream ativo. Offline — compara com `config/quality/model-lifecycle.json`, atualizado manualmente com `npm run quality:refresh-model-lifecycle` (rede; não integrado à CI). `allowedRetiredInCatalog` é uma catraca de redução: adicione uma entrada somente com uma issue de acompanhamento. | Sim | -| `check:fetch-targets` | Cada `fetch("/api/...")` no `src/` do lado do cliente é resolvido para um `route.ts` real | Sim | -| `check:deps` | Todas as dependências instaláveis com `npm install` em cada `package.json` do repositório estão em `dependency-allowlist.json`; pacotes novos sem versão fixada ou com risco de slopsquatting são sinalizados | Sim | -| `audit:deps` | `npm audit` (raiz + electron) — nenhum alerta de gravidade alta/crítica (sobrepõe-se ao `check:vuln-ratchet` do osv; consulte a lista de pendências de racionalização) | Sim | -| `check:lockfile` | Integridade do `package-lock.json` — registro https, hashes de integridade, nenhuma substituição de host | Sim | -| `check:licenses` | Lista de permissões de licenças SPDX para dependências de produção | Sim | -| `check:tracked-artifacts` | Nenhum artefato de build / link simbólico de `node_modules` versionado (também é executado no pre-commit do husky; o pre-push é intencionalmente leve — #6716) | Sim | -| `check:ai-attribution` | Nenhum trailer `Co-Authored-By` de IA/bot ou rodapé de geração por IA nos commits, título ou corpo do PR — Regra Rígida nº 16 (no loop de verificações rápidas de `quality.yml` para PR→`release/**` — lê o payload do evento e não faz nada fora de PRs — e uma etapa exclusiva de PR no lint de `ci.yml` para PR→`main`; também no hook `commit-msg` do husky; coautores humanos são permitidos; #14436) | -| `check:vitest-exclusions` | Toda exclusão do Vitest menciona uma issue de acompanhamento e aparece em `config/quality/vitest-exclusions.json` (#13204) | Sim | -| `check:file-size` | Nenhum arquivo-fonte excede o limite por extensão (catraca: arquivos grandes congelados na lista `frozen`) | Sim | -| `check:error-helper` | As respostas de erro em executores/handlers usam `buildErrorBody()` / `sanitizeErrorMessage()` (Regra Rígida nº 12) | Sim | -| `check:migration-numbering` | Os arquivos SQL de migração são numerados sequencialmente, sem lacunas ou duplicatas | Sim | -| `check:public-creds` | Nenhum `client_id`/`client_secret` OAuth literal ou chave Web do Firebase fora de `publicCreds.ts` (Regra Rígida nº 11) | Sim | -| `check:db-rules` | Nenhum SQL bruto fora dos módulos de `src/lib/db/`; nenhuma importação agregadora de `localDb.ts` (Regras Rígidas nº 2/nº 5) | Sim | -| `check:known-symbols` | Os executores de provedores, as estratégias de roteamento e os tradutores registrados em suas tabelas de despacho correspondem aos arquivos no disco — sem símbolos órfãos ou não declarados | Sim | -| `check:route-guard-membership` | Toda rota que inicia um processo filho é classificada por `isLocalOnlyPath()` (Regras Rígidas nº 15/nº 17) | Sim | -| `check:test-discovery` | Todo arquivo `*.test.ts` / `*.spec.ts` no repositório é coletado por pelo menos um executor de testes (ratchet: a lista de órfãos em `test-discovery-baseline.json` só pode diminuir) | Sim | -| `check:agent-skills-sync` | Os artefatos gerados de agent-skills correspondem ao catálogo de origem (sem divergências) | -| `check:provider-asset-provenance` | Os logotipos/ativos de provedores possuem uma entrada de procedência registrada | -| `lint:json` | Os arquivos de configuração JSON são analisados corretamente e atendem às regras de lint do repositório | -| `typecheck:core` | Compilação do TypeScript sem erros (somente avisos consultivos) | Sim | -| `typecheck:noimplicit:core` | `noImplicitAny` estrito — voltado para o futuro; muitos locais de chamada preexistentes ainda precisam de anotações | **Consultivo** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limitado a `src/app/(dashboard)/**` (#7033) — a lista de permissões selecionada de 27 arquivos de `typecheck:core` não inclui nenhum TSX do dashboard, e `next build` também nunca faz a verificação de tipos dele (`next.config.mjs` define `ignoreBuildErrors: true`), portanto, regressões de identificadores órfãos nessa área (#6625/#6909) não eram detectadas pela CI. Compara com uma linha de base congelada da contagem por arquivo/por código TS (`config/quality/dashboard-typecheck-baseline.json`, o mesmo padrão de imposição de obsolescência de `check:known-symbols`) — somente erros NOVOS além da contagem registrada na linha de base fazem a verificação falhar; reduza gradualmente com `--update` quando um erro preexistente for corrigido. | Sim | +É executado em cada PR para `main`. Bloqueia o merge em caso de falha. + +| Script (`npm run ...`) | Valida | Bloqueante | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | A versão do Node.js está dentro do intervalo compatível | Sim | +| `check:cycles` | Importações circulares em todo o `src/` + `open-sse/` (baseado em AST, com `paths` do tsconfig resolvidos). A execução isolada é informativa e lista os ciclos. `check:cycles:ratchet` (o que a CI executa) bloqueia quando a contagem excede o limite máximo de `metrics.cycles` em `quality-baseline.json` — atualmente 14, `direction: down`, portanto só pode diminuir (#15159 G-01/G-02) | Sim (catraca) | +| `check:route-validation:t06` | Presença de schemas Zod em todas as rotas (política do Tier 6) | Sim | +| `check:any-budget:t11` | A contagem de `@ts-expect-error // any` não excede o orçamento (catraca do Tier 11) | Sim | +| `check:provider-consistency` | Cada provedor em `providers.ts` tem uma entrada correspondente em `providerRegistry.ts` (e vice-versa, dentro da lista de permissões) | Sim | +| `check:model-lifecycle` | As três tabelas de roteamento mantidas manualmente permanecem consistentes com o snapshot de ciclo de vida versionado (#11503): `FITNESS_TABLE` (`taskFitness.ts`) não pontua nenhum id descontinuado que `REGISTRY` possa rotear; cada destino de `BUILT_IN_ALIASES` está presente em `REGISTRY` e ausente do snapshot de ids descontinuados; cada id descontinuado ainda presente em `REGISTRY` é encaminhado ou listado em `allowedRetiredInCatalog`; e nenhuma origem ou destino de `DEFAULT_DEGRADATION_MAP` aparece como descontinuado nesse snapshot. Isso não comprova que um modelo esteja sendo disponibilizado atualmente por um upstream ativo. Offline — compara com `config/quality/model-lifecycle.json`, atualizado manualmente com `npm run quality:refresh-model-lifecycle` (rede; não integrado ao CI). `allowedRetiredInCatalog` é uma catraca de redução progressiva: adicione uma entrada somente com uma issue de acompanhamento. | Sim | +| `check:fetch-targets` | Cada `fetch("/api/...")` no `src/` do lado do cliente corresponde a um `route.ts` real | Sim | +| `check:deps` | Todas as dependências instaláveis com `npm install` em cada `package.json` do repositório estão em `dependency-allowlist.json`; pacotes novos sem versão fixada ou com nomes semelhantes a pacotes legítimos são sinalizados | Sim | +| `audit:deps` | `npm audit` (raiz + electron) — nenhum aviso de severidade alta/crítica (sobrepõe-se ao `check:vuln-ratchet` do osv; consulte o Backlog de Racionalização) | Sim | +| `check:lockfile` | Integridade de `package-lock.json` — registro https, hashes de integridade, nenhuma substituição de host | Sim | +| `check:licenses` | Lista de permissões de licenças SPDX para dependências de produção | Sim | +| `check:tracked-artifacts` | Nenhum artefato de build / link simbólico de `node_modules` versionado (também é executado no pre-commit do husky; o pre-push é intencionalmente leve — #6716) | Sim | +| `check:ai-attribution` | Nenhum trailer `Co-Authored-By` de IA/bot nem rodapé de geração por IA nos commits, no título ou no corpo do PR — Regra Rígida nº 16 (no loop de verificações rápidas de `quality.yml` para PR→`release/**` — lê o payload do evento e não realiza nenhuma operação fora de PRs — e em uma etapa exclusiva para PRs no lint de `ci.yml` para PR→`main`; também no hook `commit-msg` do husky; coautores humanos são permitidos; #14436) | +| `check:vitest-exclusions` | Toda exclusão do Vitest menciona uma issue de rastreamento e aparece em `config/quality/vitest-exclusions.json` (#13204) | Sim | +| `check:file-size` | Nenhum arquivo-fonte excede o limite por extensão (catraca: arquivos grandes congelados na lista `frozen`) | Sim | +| `check:error-helper` | As respostas de erro em executores/handlers usam `buildErrorBody()` / `sanitizeErrorMessage()` (Regra Rígida nº 12) | Sim | +| `check:migration-numbering` | Os arquivos SQL de migração são numerados sequencialmente, sem lacunas ou duplicatas | Sim | +| `check:public-creds` | Nenhum `client_id`/`client_secret` OAuth literal ou chave Web do Firebase fora de `publicCreds.ts` (Regra Rígida nº 11) | Sim | +| `check:db-rules` | Nenhum SQL bruto fora dos módulos de `src/lib/db/`; nenhuma importação de barril de `localDb.ts` (Regras Rígidas nº 2/nº 5) | Sim | +| `check:known-symbols` | Os executores de provedores, as estratégias de roteamento e os tradutores registrados em suas tabelas de despacho correspondem aos arquivos no disco — sem símbolos órfãos ou não declarados | Sim | +| `check:route-guard-membership` | Toda rota que inicia um processo filho é classificada por `isLocalOnlyPath()` (Regras Rígidas nº 15/nº 17) | Sim | +| `check:test-discovery` | Todo arquivo `*.test.ts` / `*.spec.ts` no repositório é coletado por pelo menos um executor de testes (ratchet: a lista de órfãos em `test-discovery-baseline.json` só pode diminuir) | Sim | +| `check:agent-skills-sync` | Os artefatos gerados de agent-skills correspondem ao catálogo de origem (sem divergências) | +| `check:provider-asset-provenance` | Os logotipos/ativos dos provedores possuem uma entrada de proveniência registrada | +| `lint:json` | Os arquivos de configuração JSON são analisados e atendem às regras de lint do repositório | +| `typecheck:core` | Compilação TypeScript sem erros (apenas avisos consultivos) | Sim | +| `typecheck:noimplicit:core` | `noImplicitAny` estrito — voltado para o futuro; muitos locais de chamada preexistentes ainda precisam de anotações | **Consultivo** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` restrito a `src/app/(dashboard)/**` (#7033) — a lista de permissões selecionada de 27 arquivos de `typecheck:core` não inclui nenhum TSX do dashboard, e `next build` também nunca faz a verificação de tipos deles (`next.config.mjs` define `ignoreBuildErrors: true`), portanto, regressões de identificadores órfãos nessa área (#6625/#6909) não eram detectadas pela CI. Compara com uma linha de base congelada de contagem por arquivo/por código TS (`config/quality/dashboard-typecheck-baseline.json`, o mesmo padrão de imposição contra desatualização usado por `check:known-symbols`) — somente erros NOVOS além da contagem da linha de base fazem o gate falhar; reduza-a progressivamente com `--update` quando um erro preexistente for corrigido. | Sim | ### Job: `quality-gate` -É executado após `test-coverage`. Bloqueia o merge em caso de falha. +É executado após `test-coverage`. Bloqueia a mesclagem em caso de falha. -| Script | Valida | Bloqueante | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `quality:collect` | Gera `quality-metrics.json` (contagem de avisos do ESLint, cobertura do relatório consolidado dos shards) | Sim (precede o ratchet) | -| `quality:ratchet` | Cada métrica em `quality-baseline.json` não regrediu (avisos do ESLint ≤ linha de base; cobertura ≥ linha de base) | Sim | -| `check:duplication` | A duplicação de código (jscpd@4) não excede a linha de base em `quality-baseline.json` | Sim | -| `check:complexity` | A complexidade ciclomática no nível do arquivo não excede o limite (regras `complexity` + `max-lines-per-function` do ESLint principal) | Sim | -| `check:cognitive-complexity` | Ratchet de complexidade cognitiva (`eslint-plugin-sonarjs`) — execução separada do ESLint; a CI executa ambos combinados na única etapa `check:complexity-ratchets` | Sim | -| `check:dead-code` | O ratchet de exportações/arquivos não utilizados (knip) não regride em relação à linha de base | Sim | -| `check:compression-budget` | Orçamento do benchmark de compactação — os limites mínimos de economia de tokens por mecanismo não devem regredir | Sim | -| `check:type-coverage` | O ratchet do percentual tipado (`type-coverage`) não regride; substitui em grande parte `typecheck:noimplicit:core` | Sim | -| `check:codeql-ratchet` | A contagem de alertas abertos do CodeQL não regride (lê via `gh api`; ignora normalmente sem token) — frequência de atualização e acionamento manual: veja "Ratchet do CodeQL" abaixo | Sim | +| Script | Valida | Bloqueante | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `quality:collect` | Gera `quality-metrics.json` (contagem de avisos do ESLint, cobertura proveniente do relatório consolidado dos shards) | Sim (precede o ratchet) | +| `quality:ratchet` | Cada métrica em `quality-baseline.json` não regrediu (avisos do ESLint ≤ baseline; cobertura ≥ baseline) | Sim | +| `check:duplication` | A duplicação de código (jscpd@4) não excede o baseline em `quality-baseline.json` | Sim | +| `check:complexity` | A complexidade ciclomática no nível de arquivo não excede o limite (regras `complexity` + `max-lines-per-function` do ESLint core) | Sim | +| `check:cognitive-complexity` | Ratchet de complexidade cognitiva (`eslint-plugin-sonarjs`) — execução separada do ESLint; a CI executa ambos de forma combinada na única etapa `check:complexity-ratchets` | Sim | +| `check:dead-code` | O ratchet de exports/arquivos não utilizados (knip) não regride em relação ao baseline | Sim | +| `check:compression-budget` | Orçamento do benchmark de compactação — os pisos de economia de tokens por engine não podem regredir | Sim | +| `check:type-coverage` | O ratchet de percentual tipado (`type-coverage`) não regride; substitui em grande parte `typecheck:noimplicit:core` | Sim | +| `check:codeql-ratchet` | A contagem de alertas abertos do CodeQL não regride (consulta via `gh api`; ignora de forma segura sem token) — frequência de atualização e acionamento manual: consulte "Ratchet do CodeQL" abaixo | Sim | ### Job: `quality-extended` -Todo o job é consultivo (`continue-on-error: true`). Os ratchets baseados em npm são executados -de fato; os scanners externos são instalados via `gh release download` e se ignoram automaticamente (exit 0) +O job inteiro é consultivo (`continue-on-error: true`). Os ratchets baseados em npm são executados +de fato; os scanners externos são instalados via `gh release download` e se autoignoram (exit 0) quando um binário ainda está ausente. -| Script | Valida | Bloqueante | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `check:circular-deps` | Nenhuma dependência circular (dpdm) | **Consultivo** | -| `check:bundle-size` | O tamanho do bundle não excede o limite | **Consultivo** | -| `check:secrets` | Varredura de segredos (gitleaks) — ignorada se o binário estiver ausente | **Consultivo** | -| `check:vuln-ratchet` | As vulnerabilidades de dependências (osv-scanner) não regridem — ignorado se o binário estiver ausente | **Consultivo** | -| `check:workflows` | Lint de workflows (actionlint + zizmor); scanners ausentes/com falha, relatórios inválidos ou linha de base do ratchet ausente falham como INCOMPLETE. Achados válidos seguem a política estrita/consultiva/de ratchet selecionada | Execução obrigatória; ratchet do zizmor bloqueante na CI | -| `check:openapi-breaking` | Alterações incompatíveis no contrato da API pública (`openapi.yaml`) em relação à branch base (oasdiff) — gera `openapiBreaking=N`; ignorado se o oasdiff estiver ausente ou se a especificação base não puder ser resolvida | **Consultivo** | +| Script | Valida | Bloqueante | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `check:circular-deps` | Nenhuma dependência circular (dpdm) | **Consultivo** | +| `check:bundle-size` | O tamanho do bundle não excede o limite | **Consultivo** | +| `check:secrets` | Varredura de segredos (gitleaks) — ignora se o binário estiver ausente | **Consultivo** | +| `check:vuln-ratchet` | As vulnerabilidades de dependências (osv-scanner) não regridem — ignora se o binário estiver ausente | **Consultivo** | +| `check:workflows` | Lint de workflows (actionlint + zizmor); scanners ausentes/com falha, relatórios inválidos ou ausência do baseline do ratchet resultam em INCOMPLETE. Achados válidos seguem a política strict/advisory/ratchet selecionada | Execução obrigatória; ratchet do zizmor bloqueante na CI | +| `check:openapi-breaking` | Alterações incompatíveis no contrato da API pública (`openapi.yaml`) em relação à branch base (oasdiff) — gera `openapiBreaking=N`; ignora se o oasdiff estiver ausente ou se a especificação base não puder ser resolvida | **Consultivo** | ### Job: `docs-sync-strict` É executado em cada PR para `main`. Bloqueia o merge em caso de falha. -| Script | Valida | Bloqueante | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | Metagate que executa sequencialmente os 6 subgates abaixo | Sim | -| ↳ `check:docs-sync` | Consistência de versões entre CHANGELOG / OpenAPI / llm.txt | Sim | -| ↳ `check:docs-counts` | As contagens no texto (quantidade de provedores, quantidade de migrações etc.) estão dentro da janela progressiva das contagens reais | Sim | -| ↳ `check:env-doc-sync` | Cada variável de ambiente em `.env.example` está documentada em uma tabela da documentação e vice-versa | Sim | -| ↳ `check:deprecated-versions` | Não há strings de versões obsoletas na documentação | Sim | -| ↳ `check:doc-links` | Os links markdown internos na documentação apontam para arquivos reais (formato `[texto]`/`(caminho)`) | Sim | -| ↳ `check:fabricated-docs` | Rotas, variáveis de ambiente, comandos da CLI, nomes de hooks e caminhos de arquivos citados na documentação existem na base de código. Gate rígido via `--strict`; falha não bloqueante sem a flag. | Sim (via `--strict` na CI) | -| `check:cli-i18n` | As strings de comandos da CLI estão presentes em todos os arquivos de localidades i18n | Sim | -| `check:openapi-coverage` | A especificação OpenAPI cobre pelo menos um limite mínimo progressivo de rotas reais | Sim | -| `check:openapi-security-tiers` | As anotações de níveis de segurança em `openapi.yaml` são consistentes com as classificações de `routeGuard.ts` | **Consultivo** | -| `check:openapi-routes` | Cada caminho em `openapi.yaml` corresponde a um `route.ts` real (antialucinação) | Sim | -| `check:docs-symbols` | Cada referência a `/api/...` em `docs/**/*.md` corresponde a um `route.ts` real (antialucinação) | Sim | -| `i18n translation drift` | Chaves não traduzidas nos arquivos de localidades i18n — apenas alerta | **Consultivo** | +| Script | Valida | Bloqueante | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | Metaverificação que executa sequencialmente as 6 subverificações abaixo | Sim | +| ↳ `check:docs-sync` | Consistência de versões entre CHANGELOG / OpenAPI / llm.txt | Sim | +| ↳ `check:docs-counts` | As contagens no texto (quantidade de provedores, quantidade de migrações etc.) estão dentro da janela progressiva das contagens reais | Sim | +| ↳ `check:env-doc-sync` | Cada variável de ambiente em `.env.example` está documentada em uma tabela da documentação e vice-versa | Sim | +| ↳ `check:deprecated-versions` | Não há strings de versões obsoletas na documentação | Sim | +| ↳ `check:doc-links` | Links markdown internos na documentação apontam para arquivos reais (formato `[texto]`/`(caminho)`) | Sim | +| ↳ `check:fabricated-docs` | Rotas, variáveis de ambiente, comandos da CLI, nomes de hooks e caminhos de arquivos citados na documentação existem na base de código. Verificação rígida via `--strict`; falha não bloqueante sem a flag. | Sim (via `--strict` na CI) | +| `check:cli-i18n` | As strings de comandos da CLI estão presentes em todos os arquivos de localidades i18n | Sim | +| `check:openapi-coverage` | A especificação OpenAPI cobre pelo menos um limite mínimo progressivo das rotas reais | Sim | +| `check:openapi-security-tiers` | As anotações de níveis de segurança em `openapi.yaml` são consistentes com as classificações de `routeGuard.ts` | **Consultivo** | +| `check:openapi-routes` | Cada caminho em `openapi.yaml` corresponde a um `route.ts` real (antialucinação) | Sim | +| `check:docs-symbols` | Cada referência a `/api/...` em `docs/**/*.md` corresponde a um `route.ts` real (antialucinação) | Sim | +| `i18n translation drift` | Chaves não traduzidas nos arquivos de localidades i18n — apenas aviso | **Consultivo** | ### Job: `i18n-ui-coverage` @@ -195,90 +188,92 @@ quando um binário ainda está ausente. | `check-ui-keys-coverage` (inline) | A cobertura de chaves i18n da UI é ≥ 65% | Sim | | `check-ui-value-drift` (inline) | Um **valor** em inglês reescrito não deixa para trás nenhuma tradução desatualizada | Sim | | `check-new-key-coverage` (inline) | Uma **nova** chave em inglês está traduzida em todas as localidades — um marcador `__MISSING__:` é rejeitado | Sim | -| `check-translation-ratio` | A proporção de traduções reais por localidade (entradas idênticas ao inglês / placeholders / ausentes fora da lista de permissões) não deve exceder `config/quality/i18n-translation-baseline.json` + margem | **Consultivo** | +| `check-translation-ratio` | A proporção de traduções reais por localidade (valores idênticos ao inglês / placeholders / ausências fora da lista de permissões) não deve exceder `config/quality/i18n-translation-baseline.json` + margem | **Consultivo** | -Requer `fetch-depth: 0` — o gate de divergência de valores compara `en.json` com a base do merge. +Requer `fetch-depth: 0` — a verificação de divergência de valores compara `en.json` com a base de mesclagem. -#### `check-ui-value-drift` — gate de traduções desatualizadas +#### `check-ui-value-drift` — verificação de traduções desatualizadas -Detecta a única regressão de i18n que os outros gates não conseguem identificar estruturalmente: um valor em inglês +Detecta a única regressão de i18n que as outras verificações não conseguem identificar estruturalmente: um valor em inglês é reescrito e as traduções derivadas do inglês _anterior_ permanecem, fazendo com que -usuários que não falam inglês continuem lendo um texto assertivo, mas agora incorreto. +usuários que não falam inglês continuem lendo um texto formulado de maneira assertiva, mas agora incorreto. -Isso realmente chegou à produção. `oauthModal.googleOAuthWarning` foi reescrito quando o assistente de login -do Antigravity foi lançado (#5203); **39 de 43 localidades** mantiveram o texto instruindo os operadores a "copiar a +Isso realmente chegou à produção. `oauthModal.googleOAuthWarning` foi reescrito quando o auxiliar de login +Antigravity foi introduzido (#5203); **39 de 43 localidades** mantiveram o texto instruindo os operadores a "copiar a URL completa e colá-la abaixo" — um fluxo que não pode ser concluído para esse provedor. Isso passou despercebido até #8463 porque: -- `sync-ui-keys` apenas preenche chaves que estão **ausentes**, nunca as que estão **desatualizadas**; -- `check-ui-keys-coverage` contabiliza a _presença_ das chaves, portanto uma tradução desatualizada é considerada coberta; +- `sync-ui-keys` só preenche chaves que estão **ausentes**, nunca as que estão **desatualizadas**; +- `check-ui-keys-coverage` contabiliza a _presença_ da chave, portanto uma tradução desatualizada conta como coberta; - `check-translation-drift` monitora os espelhos da documentação em `docs/i18n//**.md` — ele nunca lê `src/i18n/messages/*.json`. Bloqueante no job `docs-sync-strict` desde a - ressincronização de 2026-09: edite um documento principal → `npm run i18n:run -- --files=` (por seção, econômico). + ressincronização de 2026-09: edite um documento principal → `npm run i18n:run -- --files=` (por seção, de baixo custo). -**Ciente do diff, sem depender de uma baseline.** Compara o `en.json` na base do merge com a -árvore de trabalho; para cada chave cujo valor em inglês foi alterado, qualquer localidade que ainda contenha uma -tradução intacta está desatualizada. Isso deliberadamente **congela a dívida preexistente** — um diff -não pode revelar de qual texto antigo em inglês veio uma tradução existente há muito tempo; portanto, a validação considera -apenas o que a alteração atual afeta. A alternativa (uma baseline de hashes por chave) exigiria -um arquivo gerado de aproximadamente 600 KB, 3× maior que a maior baseline existente, com alterações em todo PR de i18n. +**Ciente de diff, sem respaldo de baseline.** Ele compara o `en.json` na base do merge com a +árvore de trabalho; para cada chave cujo valor em inglês foi alterado, qualquer localidade +que ainda contenha uma tradução não modificada está desatualizada. Isso deliberadamente +**congela a dívida preexistente** — um diff não consegue revelar de qual versão antiga em +inglês veio uma tradução de longa data, portanto o gate avalia apenas o que a alteração +atual afeta. A alternativa (uma baseline de hash por chave) custaria um arquivo gerado de +~600 KB, 3× maior que a maior baseline existente, com alterações em todo PR de i18n. -Há duas maneiras de satisfazer a validação: +Há duas maneiras de satisfazê-lo: 1. atualizar as traduções afetadas; ou -2. defini-las como `__MISSING__:` — em seguida, o runtime fornece o texto corrigido em inglês - (`src/i18n/request.ts::deepMergeFallback`, #7258), e a chave entra na fila de tradução. +2. defini-las como `__MISSING__:` — o runtime então fornece o texto + corrigido em inglês (`src/i18n/request.ts::deepMergeFallback`, #7258), e a chave entra + na fila para tradução. -Se o **significado** da string tiver mudado, prefira **renomear a chave**: uma nova chave não pode herdar -uma tradução desatualizada. Esse foi o padrão usado em #8463. +Se o **significado** da string mudou, prefira **renomear a chave**: uma nova chave não pode +herdar uma tradução desatualizada. Esse foi o padrão usado no #8463. ```bash npm run i18n:check-value-drift # estrito (o que a CI executa) -npm run i18n:check-value-drift:warn # apenas relata +npm run i18n:check-value-drift:warn # apenas gera relatório BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Encerra com código 0 e `SKIP reason=base-unresolved` quando o catálogo-base não pode ser lido (clone -raso sem a ref da base), seguindo o comportamento de `check-openapi-breaking`. +Encerra com código 0 e `SKIP reason=base-unresolved` quando o catálogo-base não pode ser +lido (clone superficial sem a referência-base), espelhando `check-openapi-breaking`. ### Job: `i18n` Matriz completa de validação de i18n (um job por localidade). O job inteiro é consultivo. -| Script | Valida | Bloqueante | -| ------------------------------- | ------------------------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | Completude da tradução por localidade | **Consultivo** (`continue-on-error: true` no job inteiro) | +| Script | Valida | Bloqueante | +| ------------------------------- | ------------------------------------- | ------------------------------------------------------ | +| `validate_translation.py quick` | Completude da tradução por localidade | **Consultivo** (`continue-on-error: true` no job todo) | ### Job: `pr-test-policy` -Executado somente em pull requests. +Executado apenas em pull requests. -| Script | Valida | Bloqueante | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PRs que alteram código de produção em `src/`, `open-sse/`, `electron/` ou `bin/` devem incluir ou atualizar testes (Regra Rígida nº 8) | Sim | -| `check:test-masking` | Arquivos de teste alterados não reduzem a contagem líquida de asserções nem adicionam tautologias `assert.ok(true)` | Sim | -| `check:pr-evidence` | O corpo do PR cita evidências de testes/VPS para a alteração (automatiza a Regra Rígida nº 18 procurando padrões no texto do PR — frágil; consulte o Backlog) | Sim | +| Script | Valida | Bloqueante | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | PRs que alteram código de produção em `src/`, `open-sse/`, `electron/` ou `bin/` devem incluir ou atualizar testes (Regra Rígida nº 8) | Sim | +| `check:test-masking` | Arquivos de teste alterados não reduzem a contagem líquida de asserções nem adicionam tautologias `assert.ok(true)` | Sim | +| `check:pr-evidence` | O corpo do PR cita evidências de teste/VPS para a alteração (automatiza a Regra Rígida nº 18 examinando o texto do PR — frágil, consulte as Pendências) | Sim | ### Job: `test-vitest` Executado após `build`. Bloqueia o merge em caso de falha. -| Suíte | Valida | Bloqueante | -| ---------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Servidor MCP (110 ferramentas), autoCombo, cache — executor vitest | Sim | -| `test:vitest:ui` | Testes de componentes da UI — executor vitest | **Bloqueante** — falhas preexistentes são explicitamente excluídas em `vitest.config.ts`; novas falhas fazem o job falhar | +| Suíte | Valida | Bloqueante | +| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Servidor MCP (110 ferramentas), autoCombo, cache — runner vitest | Sim | +| `test:vitest:ui` | Testes de componentes de UI — runner vitest | **Bloqueante** — falhas preexistentes são explicitamente excluídas em `vitest.config.ts`; novas falhas fazem o job falhar | ### Workflows noturnos (agendados, consultivos) -São executados por agendamento cron (e `workflow_dispatch`), nunca em PRs. Todos são consultivos. +São executados em um cronograma cron (e por `workflow_dispatch`), nunca em PRs. Todos são consultivos. | Workflow | Valida | Bloqueante | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | `nightly-property` | Testes baseados em propriedades com fast-check, usando uma seed aleatória e uma alta contagem de execuções | **Consultivo** | -| `nightly-resilience` | Validação de crescimento do heap, injeção caótica de falhas, testes de carga/prolongados com k6 | **Consultivo** | +| `nightly-resilience` | Gate de crescimento de heap, injeção de falhas caóticas, testes de carga/soak com k6 | **Consultivo** | | `nightly-llm-security` | Proteção contra injeção do promptfoo (modo de bloqueio) + sondas do garak (ignoradas sem um segredo de provedor) | **Consultivo** | -| `nightly-schemathesis` | Fuzzing de contrato OpenAPI (schemathesis) contra uma instância ativa do OmniRoute usando `docs/openapi.yaml` — revela violações da especificação/erros 500 não tratados (Fase 8 B.4) | **Consultivo** | -| `nightly-mutation` | Pontuação de testes de mutação do Stryker sobre a via rápida de testes unitários — mutantes sobreviventes revelam asserções fracas | **Consultivo** | +| `nightly-schemathesis` | Fuzzing do contrato OpenAPI (schemathesis) contra uma instância ativa do OmniRoute usando `docs/openapi.yaml` — revela violações da especificação/erros 500 não tratados (Fase 8 B.4) | **Consultivo** | +| `nightly-mutation` | Pontuação de testes de mutação do Stryker na faixa rápida de testes unitários — mutantes sobreviventes revelam asserções fracas | **Consultivo** | | `nightly-compat` | Matriz de compatibilidade do mecanismo Node entre os intervalos compatíveis de `engines.node` | **Consultivo** | --- @@ -556,31 +551,31 @@ operador.** Nada abaixo foi aplicado ainda. **Também não documentados acima** (consultivos, baixo sinal): o job `docs-lint` (markdownlint + Vale, com `continue-on-error` no job inteiro) e os workflows independentes de análise `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` está em -`quality-baseline.json`, mas não está conectado a uma catraca bloqueante em `ci.yml` — a +`quality-baseline.json`, mas não está conectado a um ratchet bloqueante em `ci.yml` — a métrica está atualmente órfã. -### Consolidação / desduplicação (mecânica, menor risco) +### Consolidação / deduplicação (mecânica, menor risco) Cada candidato foi validado em relação ao estado real dos gates em 2026-06-17 (confiar, mas verificar); várias consolidações "óbvias" acabaram ocultando dívida e -**não** são substituições diretas seguras. +**não** são substituições diretas e seguras. -- **`check:docs-sync` é executado duas vezes** — de forma independente no job `lint` e novamente dentro de `check:docs-all` (`docs-sync-strict`) e no hook de pre-commit do husky. ✅ **CONCLUÍDO** — a invocação independente em `lint` foi removida. -- **Análise de CVEs** — ❌ **NÃO é uma consolidação segura.** `audit:deps` falha de forma bloqueante diante de qualquer CVE de severidade alta/crítica; `check:vuln-ratchet` (osv) só falha em caso de _regressão_ em relação à baseline (atualmente 1 MODERATE). Semânticas diferentes — remover `audit:deps` eliminaria o gate absoluto para severidades alta/crítica. Manter ambos. -- **Detecção de ciclos** — ❌ **NÃO é uma consolidação segura.** `check:circular-deps` (dpdm) relata **91 ciclos** (por isso é consultivo); ele não pode ser promovido a bloqueante sem primeiro resolvê-los e tem um escopo mais amplo do que o `check:cycles`, que está verde e é criteriosamente selecionado. Manter `check:cycles` como bloqueante; resolver os 91 ciclos do dpdm constitui um backlog próprio. -- **Complexidade** — ✅ **CONCLUÍDO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): uma única varredura do ESLint, com contagens por ruleId para que as baselines de complexidade ciclomática+máximo de linhas e de complexidade cognitiva permaneçam independentes; os comandos individuais `check:complexity` / `check:cognitive-complexity` permanecem disponíveis para `--update` local. -- **Antialucinação de `/api`** — ✅ **CONCLUÍDO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): um único inventário do sistema de arquivos de `src/app/api`; openapi-routes + docs-symbols continuam relatando resultados de forma independente; os comandos individuais permanecem disponíveis para execuções locais. -- **`check:node-runtime` é executado em 11 jobs** — ⚠️ **baixo ROI.** Cada um está em um runner separado e a verificação leva <1s; economia total de ~10s, ao custo de perder uma proteção barata por job. Não vale a perturbação. -- **`typecheck:noimplicit:core` no lint da CI** — ✅ **removido do job lint** (era consultivo com `continue-on-error`); a superfície de tipos bloqueante é `typecheck:core` + `check:type-coverage`. Script local mantido. +- **`check:docs-sync` é executado duas vezes** — de forma independente no job `lint` e novamente dentro de `check:docs-all` (`docs-sync-strict`) e do hook de pre-commit do husky. ✅ **CONCLUÍDO** — a execução independente em `lint` foi removida. +- **Varredura de CVEs** — ❌ **NÃO é uma consolidação segura.** `audit:deps` falha obrigatoriamente diante de qualquer CVE de severidade alta/crítica; `check:vuln-ratchet` (osv) só falha em uma _regressão_ em relação à baseline (atualmente 1 MODERATE). Semânticas diferentes — remover `audit:deps` eliminaria o gate absoluto para severidades alta/crítica. Manter ambos. +- **Detecção de ciclos** — ✅ **CONCLUÍDO** (#15159 G-01/G-02). O texto anterior chamava `check:cycles` de gate "verde e curado" e justificava mantê-lo bloqueante porque `check:circular-deps` (dpdm) relatava 91 ciclos. Esse resultado verde era um **falso positivo de sucesso**: `check:cycles` analisava 5 subdiretórios (450 arquivos), identificava somente `import|export … from` estáticos e descartava todos os especificadores `@/` e `@omniroute/open-sse/`, portanto não conseguia enxergar os ciclos de importação dinâmica + alias que predominavam no repositório. Corrigido: agora o gate percorre `src` + `open-sse` (5023 arquivos), coleta especificadores da AST do TypeScript (assim, `import("…")` conta e `typeof import("…")` em posição de tipo não conta) e resolve `paths` do tsconfig. Ele encontra **14** ciclos, não 0. Como 14 ciclos preexistentes não podem ser corrigidos em um PR de gate, `check:cycles` agora é um **ratchet** (`--ratchet`, teto `metrics.cycles.value = 14` em `quality-baseline.json`, `direction: down`) — ele bloqueia qualquer _regressão_ e a contagem só pode diminuir. A CI executa `npm run check:cycles:ratchet`. A redução gradual acompanha a **A-01**. `check:circular-deps` (dpdm) permanece consultivo como uma segunda opinião mais abrangente. +- **Complexidade** — ✅ **CONCLUÍDO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): uma única varredura do ESLint, com contagens por ruleId para que as baselines ciclomática+max-lines e cognitiva permaneçam independentes; `check:complexity` / `check:cognitive-complexity` individuais permanecem para uso local com `--update`. +- **Antialucinação de `/api`** — ✅ **CONCLUÍDO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): um único inventário do sistema de arquivos de `src/app/api`; openapi-routes + docs-symbols ainda geram relatórios independentes; os comandos individuais permanecem para execuções locais. +- **`check:node-runtime` é executado em 11 jobs** — ⚠️ **baixo ROI.** Cada um usa um runner separado e a verificação leva <1s; economia total de ~10s, em troca da perda de uma proteção barata por job. Não vale o retrabalho. +- **`typecheck:noimplicit:core` no lint da CI** — ✅ **removido do job lint** (era consultivo com `continue-on-error`); a superfície de tipos bloqueante é `typecheck:core` + `check:type-coverage`. O script local foi mantido. ### Alterar status / decidir (política do operador) -- `check:openapi-security-tiers` (consultivo) — ❌ **NÃO pode se tornar bloqueante diretamente.** Ele encerra com código 0, mas alerta que várias rotas de `traffic-inspector` sob `LOCAL_ONLY_API_PREFIXES` não têm a anotação `x-loopback-only: true`. Aplicá-lo de forma bloqueante exige primeiro adicionar essas anotações a `openapi.yaml`. -- `typecheck:noimplicit:core` (consultivo) — amplamente contemplado pela catraca bloqueante `check:type-coverage`. Converter em catraca ou remover a segunda passagem redundante do `tsc`. -- `test:vitest:ui` (agora **bloqueante**) — falhas preexistentes são explicitamente excluídas em `vitest.config.ts` com comentários de acompanhamento `// #8618`; novas falhas fazem o job falhar. -- `check:secrets` (gitleaks, catraca bloqueante congelada em 3 falsos positivos documentados) — adicionar os 3 à lista de permissões para chegar a 0 ou rebaixar para consultivo. Sobrepõe-se à análise nativa de segredos do GitHub + `check:public-creds`. -- `check:pr-evidence` (bloqueante, procura padrões no texto descritivo do corpo do PR) — alto risco de falsos positivos; sua remoção enfraquece a aplicação da Hard Rule #18, portanto esta é uma verdadeira decisão de política. -- `semgrep` (workflow independente consultivo) — sobrepõe-se ao CodeQL para as famílias do OWASP; conectar sua baseline a uma catraca ou remover. +- `check:openapi-security-tiers` (consultivo) — ❌ **NÃO pode ser tornado bloqueante de forma segura.** Ele encerra com código 0, mas alerta que várias rotas de `traffic-inspector` sob `LOCAL_ONLY_API_PREFIXES` não possuem a anotação `x-loopback-only: true`. Torná-lo obrigatório exige primeiro adicionar essas anotações a `openapi.yaml`. +- `typecheck:noimplicit:core` (consultivo) — amplamente substituído pelo ratchet bloqueante `check:type-coverage`. Transformar em ratchet ou remover a segunda execução redundante de `tsc`. +- `test:vitest:ui` (agora **bloqueante**) — falhas preexistentes são explicitamente excluídas em `vitest.config.ts` com comentários de rastreamento `// #8618`; novas falhas fazem o job falhar. +- `check:secrets` (gitleaks, ratchet bloqueante congelado em 3 falsos positivos documentados) — adicionar os 3 à lista de permissões para chegar a 0 ou rebaixar para consultivo. Sobrepõe-se à verificação nativa de segredos do GitHub + `check:public-creds`. +- `check:pr-evidence` (bloqueante, usa grep no texto do corpo do PR) — alto risco de falsos positivos; removê-lo enfraquece a aplicação da Hard Rule #18, portanto esta é uma decisão de política legítima. +- `semgrep` (workflow independente consultivo) — sobrepõe-se ao CodeQL para as famílias OWASP; conectar sua baseline a um ratchet ou remover. --- diff --git a/docs/i18n/pt/CONTRIBUTING.md b/docs/i18n/pt/CONTRIBUTING.md index a9677ebe162..c24b27988d0 100644 --- a/docs/i18n/pt/CONTRIBUTING.md +++ b/docs/i18n/pt/CONTRIBUTING.md @@ -390,19 +390,19 @@ Escreva testes unitários em `tests/unit/` que abranjam, no mínimo: ## Lista de verificação do Pull Request - [ ] Os testes passam (`npm test`) -- [ ] A análise de lint passa (`npm run lint`) -- [ ] A compilação é concluída com sucesso (`npm run build`) -- [ ] Tipos TypeScript adicionados para novas funções e interfaces públicas -- [ ] Sem segredos codificados diretamente ou valores de recurso -- [ ] Credenciais públicas de upstream incorporadas através de `resolvePublicCred()` (consulte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nunca como literais -- [ ] As respostas de erro são encaminhadas através de `buildErrorBody()` / `sanitizeErrorMessage()` — sem stack traces em bruto nos corpos das respostas (consulte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Os comandos shell (`exec` / `spawn`) passam valores de runtime através de `env`, não através de interpolação de strings +- [ ] A verificação de lint passa (`npm run lint`) +- [ ] A compilação é concluída com êxito (`npm run build`) +- [ ] Foram adicionados tipos TypeScript para novas funções e interfaces públicas +- [ ] Não existem segredos ou valores de recurso codificados diretamente +- [ ] As credenciais públicas de upstream são incorporadas através de `resolvePublicCred()` (consulte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nunca como literais +- [ ] As respostas de erro são encaminhadas através de `buildErrorBody()` / `sanitizeErrorMessage()` — sem rastreios de pilha em bruto nos corpos das respostas (consulte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Os comandos de shell (`exec` / `spawn`) transmitem valores de tempo de execução através de `env`, não através de interpolação de strings - [ ] Todas as entradas são validadas com esquemas Zod -- [ ] **Fragmento** de changelog adicionado em `changelog.d/{features|fixes|maintenance}/-.md` para alterações visíveis ao utilizador (consulte [`changelog.d/README.md`](./changelog.d/README.md)) — **não** edite `CHANGELOG.md` diretamente; os fragmentos são agregados no momento do lançamento e nunca entram em conflito entre PRs -- [ ] Documentação atualizada (se aplicável) -- [ ] Nenhum novo alerta do CodeQL / Secret-Scanning aberto, ou cada alerta foi dispensado com uma justificação técnica que referencia o documento relevante em `docs/security/` -- [ ] Rotas que iniciam processos-filho (`/api/mcp/`, `/api/cli-tools/runtime/`) classificadas como `isLocalOnlyPath()` em `src/server/authz/routeGuard.ts` — consulte a [Regra Rígida n.º 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Sem trailers `Co-Authored-By` nas mensagens de commit — os commits devem aparecer exclusivamente sob a identidade Git do proprietário do repositório (Regra Rígida n.º 16) +- [ ] Foi adicionado um **fragmento** de registo de alterações em `changelog.d/{features|fixes|maintenance}/-.md` para alterações visíveis para o utilizador (consulte [`changelog.d/README.md`](./changelog.d/README.md)) — **não** edite `CHANGELOG.md` diretamente; os fragmentos são agregados aquando do lançamento e nunca entram em conflito entre PRs +- [ ] A documentação foi atualizada (se aplicável) +- [ ] Não foram abertos novos alertas do CodeQL / Secret-Scanning, ou cada um foi dispensado com uma justificação técnica que referencia o documento relevante em `docs/security/` +- [ ] As rotas que iniciam processos filhos (`/api/mcp/`, `/api/cli-tools/runtime/`) estão classificadas como `isLocalOnlyPath()` em `src/server/authz/routeGuard.ts` — consulte a [Regra Rígida n.º 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Não existem trailers `Co-authored-by` de IA/bots nas mensagens de commit (Regra Rígida n.º 16) — os colaboradores humanos cujo trabalho é reutilizado são creditados com trailers padrão `Co-authored-by: Name ` --- diff --git a/docs/i18n/pt/docs/architecture/QUALITY_GATES.md b/docs/i18n/pt/docs/architecture/QUALITY_GATES.md index 28403759dc2..51eb1043fbd 100644 --- a/docs/i18n/pt/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/pt/docs/architecture/QUALITY_GATES.md @@ -20,210 +20,214 @@ replicação independente de ferramentas do mesmo sistema, consulte o ### Admissão de candidatos Os workflows CI e Quality Gates emitem, cada um, um veredicto estável: `Gate / CI` e -`Gate / Quality`. A respetiva política de admissão com controlo de versões enumera todos os jobs a montante -como obrigatórios ou consultivos. Um job obrigatório aplicável tem de ser concluído com êxito: resultados -em falta, cancelados, ignorados, pendentes e desconhecidos não permitem estabelecer PASS. Uma classificação -válida como apenas documentação ou apenas catálogo pode tornar uma via de código não aplicável; -um PR de rascunho não é um candidato aceite. Uma etiqueta `hotfix` não dispensa a apresentação de provas. - -Ambos os workflows abrangem PRs e pushes para branches main/release, execução manual e -eventos de grupos de merge. Pushes, execuções manuais e grupos de merge executam a seleção completa. Forks -e grupos de merge utilizam runners alojados para jobs que, de outra forma, selecionariam runners autoalojados; -é necessário verificar se existe capacidade alojada suficiente antes da implementação. - -Cada recibo JSON identifica o SHA obtido no checkout, a execução do workflow e a tentativa. -A CLI rejeita uma divergência entre o SHA do checkout e o do evento. Os testes do workflow associam a pertença à política -à lista `needs` do job de veredicto, para que uma via nova ou removida não possa desaparecer silenciosamente. -Os recibos abrangem o respetivo workflow, não a publicação, a implementação nem os componentes internos -de um scanner consultivo existente. A ativação de ambos os nomes de verificação nas regras de branches é uma -alteração administrativa separada; a adição destes jobs não protege, por si só, uma branch. +`Gate / Quality`. A respetiva política de admissão versionada enumera todos os jobs +a montante como obrigatórios ou consultivos. Um job obrigatório aplicável tem de ser +bem-sucedido: resultados em falta, cancelados, ignorados, pendentes e desconhecidos +não permitem estabelecer PASS. Uma classificação válida apenas de documentação ou +apenas de catálogo pode tornar uma lane de código não aplicável; um PR em rascunho +não é um candidato aceite. Uma etiqueta `hotfix` não dispensa evidências. + +Ambos os workflows abrangem PRs e pushes para branches main/release, acionamento manual e +eventos de merge group. Push, dispatch e merge group executam a seleção completa. Os forks +e merge groups utilizam runners alojados para jobs que, de outro modo, selecionariam runners +autoalojados; é necessário verificar se existe capacidade alojada suficiente antes da implementação. + +Cada recibo JSON identifica o SHA que foi objeto de checkout, a execução do workflow e a tentativa. +A CLI rejeita uma divergência entre o SHA do checkout e o SHA do evento. Os testes do workflow +associam a pertença à política à lista `needs` do job de veredicto, para que uma lane nova ou +removida não possa desaparecer silenciosamente. Os recibos abrangem o próprio workflow, não a +publicação, a implementação nem o funcionamento interno de um scanner consultivo existente. A +ativação de ambos os nomes de checks nas regras de branch é uma alteração administrativa separada; +a adição destes jobs não protege, por si só, uma branch. ### Inventário de análise estática -O inventário de aliases npm com controlo de versões e a pertença à análise estática encontram-se em +O inventário versionado de aliases npm e a composição da análise estática encontram-se em `config/quality/gate-manifest.json`. Execute `npm run check:gate-manifest` para validar -os nomes dos scripts e os comandos exatos face a `package.json`; adições, remoções e -alterações de comandos fazem falhar tanto o hook local como os jobs de classificação de alterações no CI. -Um alias não é um job de workflow, uma instância de matriz nem um caso de teste: estas contagens não devem -ser apresentadas como equivalentes. +os nomes dos scripts e os comandos exatos em relação a `package.json`; adições, remoções e +alterações aos comandos fazem falhar tanto o hook local como os jobs de classificação de +alterações no CI. Um alias não é um job de workflow, uma instância de matriz nem um caso de teste: +estas contagens não devem ser apresentadas como equivalentes. Utilize `npm run quality:scan -- --list` ou `npm run quality:scan:fast -- --list` para inspecionar os aliases selecionados sem os executar. O runner invoca o -ponto de entrada npm, pelo que o respetivo ambiente de execução (incluindo Bun, quando configurado) é preservado. -O manifesto regista os aliases fora destes perfis como invocados separadamente, e -os comandos de manutenção são proibidos em perfis de análise só de leitura. +ponto de entrada npm, pelo que o respetivo runtime (incluindo Bun, quando configurado) é preservado. +O manifesto regista os aliases fora desses perfis como invocados separadamente, e +os comandos de manutenção são proibidos em perfis de análise apenas de leitura. Estes perfis abrangem apenas a análise estática. Não certificam testes do produto, -cobertura, empacotamento, verificações externas nem a aceitação integral de uma versão candidata. -A admissão pelo workflow utiliza os ficheiros associados `config/quality/admission-policy.json` e -`scripts/quality/admission-verdict.mjs`. Os perfis de observação de versões permanecem separados; -inspecione de forma independente as respetivas verificações e recibos aplicáveis. O inventário -descritivo abaixo é uma referência, não uma prova de que um gate foi efetivamente executado. +cobertura, empacotamento, checks externos nem a aceitação completa de lançamento de um candidato. +A admissão do workflow utiliza `config/quality/admission-policy.json` e +`scripts/quality/admission-verdict.mjs` associados. Os perfis release-observer permanecem separados; +inspecione os respetivos checks e recibos aplicáveis de forma independente. O inventário +descritivo abaixo é uma referência, não uma prova de que um gate tenha sido efetivamente executado. -Os scripts encontram-se em `scripts/check/` (gates de políticas) e `scripts/quality/` (motor de ratchet). -A fonte fidedigna do CI é `.github/workflows/ci.yml`. +Os scripts encontram-se em `scripts/check/` (gates de política) e `scripts/quality/` (motor de ratchet). +A fonte de verdade do CI é `.github/workflows/ci.yml`. -### Via rápida de PRs de versão (`quality.yml`) +### Via rápida de PRs de lançamento (`quality.yml`) `.github/workflows/quality.yml` complementa o CI em PRs de main/release, pushes para branches -protegidas, execuções manuais e grupos de merge. Os PRs utilizam verificações rápidas filtradas por caminhos. A compilação -duplicada permanentemente desativada foi removida; as verificações reais de compilação/empacotamento/arranque permanecem no CI. - -| Job | Âmbito | Bloqueante | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| `Docs Gates (fast-path)` | PRs de documentação/código; referências da documentação da API e toda a documentação | Sim | -| `Fast Quality Gates` | PRs de código; verificações estáticas, verificação de tipos, verificação de tipos do dashboard, testes unitários afetados | Sim | -| `Forgotten sibling tests` | PRs de código; módulos alterados rastreados até consumidores estáticos e testes irmãos candidatos; caminhos de barrels e imports dinâmicos são reportados como diagnósticos consultivos, com exceções referenciadas na lista de permissões | **Consultivo** | -| `Vitest (fast-path)` | PRs de código; conjunto rápido de testes vitest | Sim | -| `Unit Tests fast-path` | PRs de código; conjunto de testes unitários com 4 shards | Sim | -| `No new ESLint warnings` | PRs de código; proteção de lint com conhecimento de supressões | Sim, incluindo forks | -| `Merge integrity (changelog + generated skills)` | PRs que não sejam rascunhos; sincronização do changelog e das competências geradas | Sim, incluindo forks | +protegidas, dispatch e merge groups. Os PRs utilizam checks rápidos filtrados por caminhos. A compilação +duplicada permanentemente desativada foi removida; os checks reais de compilação/empacotamento/arranque permanecem no CI. + +| Job | Âmbito | Bloqueante | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | PRs de documentação/código; referências da documentação da API e docs-all | Sim | +| `Fast Quality Gates` | PRs de código; checks estáticos, verificação de tipos, verificação de tipos do dashboard, testes unitários afetados | Sim | +| `Forgotten sibling tests` | PRs de código; módulos alterados rastreados até consumidores estáticos e testes irmãos candidatos; caminhos de barrels e imports dinâmicos são comunicados como diagnósticos consultivos, com exceções referenciadas da lista de permissões | **Consultivo** | +| `Vitest (fast-path)` | PRs de código; conjunto rápido do vitest | Sim | +| `Unit Tests fast-path` | PRs de código; conjunto de testes unitários com 4 shards | Sim | +| `No new ESLint warnings` | PRs de código; proteção de lint ciente de supressões | Sim, incluindo forks | +| `Merge integrity (changelog + generated skills)` | PRs que não sejam rascunhos; sincronização do changelog e das skills geradas | Sim, incluindo forks | #### Relatório de testes irmãos esquecidos `npm run check:forgotten-sibling-tests` reutiliza o resolvedor de imports subjacente ao mapa de impacto dos testes. -Para cada módulo de produção alterado, reporta cadeias determinísticas -`módulo/símbolo alterado -> consumidor estático -> teste irmão candidato` quando o teste -candidato não está presente no diff do pull request. O resumo em Markdown e o resultado JSON são mantidos como +Para cada módulo de produção alterado, comunica cadeias determinísticas +`módulo/símbolo alterado -> consumidor estático -> teste irmão candidato` quando o teste candidato +não está presente no diff do pull request. O resumo Markdown e o resultado JSON são mantidos como o artefacto de workflow `forgotten-sibling-tests` para calibração antes de qualquer implementação bloqueante. -As reexportações de barrel e as importações dinâmicas servem apenas como diagnósticos de resolução; nunca criam uma -ocorrência bloqueante. As exceções revistas encontram-se em +As reexportações barrel e as importações dinâmicas servem apenas para diagnóstico de resolução; nunca criam uma +ocorrência bloqueadora. As exceções revistas encontram-se em `config/quality/forgotten-sibling-allowlist.json`. Cada entrada tem de indicar o consumidor e o teste -candidato, apresentar uma justificação específica e incluir uma ligação para uma issue ou pull request do GitHub. As entradas malformadas -falham de forma fechada. As exceções não podem suprimir um teste candidato eliminado nem um diff que adicione `.skip`/`.todo`; -o enfraquecimento de asserções e outras formas de ocultação continuam a ser da responsabilidade do gate bloqueante independente +candidato, apresentar uma justificação específica e incluir uma ligação para um issue ou pull request do GitHub. As entradas malformadas +falham de forma restritiva. As exceções não podem suprimir um teste candidato eliminado nem um diff que adicione `.skip`/`.todo`; +o enfraquecimento de asserções e outras formas de dissimulação continuam a ser responsabilidade da barreira bloqueadora independente `check:test-masking`. -### Tarefa: `lint` - -É executada em todos os PR para `main`. Bloqueia a integração em caso de falha. - -| Script (`npm run ...`) | Valida | Bloqueante | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | A versão do Node.js encontra-se dentro do intervalo suportado | Sim | -| `check:cycles` | Importações circulares — todos os módulos de `src/` + `open-sse/` | Sim | -| `check:route-validation:t06` | Esquemas Zod presentes em todas as rotas (política do Nível 6) | Sim | -| `check:any-budget:t11` | A contagem de `@ts-expect-error // any` não excede o limite (torniquete do Nível 11) | Sim | -| `check:provider-consistency` | Cada fornecedor em `providers.ts` tem uma entrada correspondente em `providerRegistry.ts` (e vice-versa, dentro da lista de permissões) | Sim | -| `check:model-lifecycle` | As três tabelas de encaminhamento mantidas manualmente permanecem consistentes com o instantâneo do ciclo de vida incluído no repositório (#11503): `FITNESS_TABLE` (`taskFitness.ts`) não atribui pontuação a nenhum id descontinuado que `REGISTRY` possa encaminhar; todos os destinos de `BUILT_IN_ALIASES` estão presentes em `REGISTRY` e ausentes do instantâneo de ids descontinuados; todos os ids descontinuados ainda presentes em `REGISTRY` são reencaminhados ou indicados em `allowedRetiredInCatalog`; e nenhuma origem ou destino de `DEFAULT_DEGRADATION_MAP` aparece como descontinuado nesse instantâneo. Isto não comprova que um modelo esteja atualmente a ser servido por um upstream ativo. Offline — compara com `config/quality/model-lifecycle.json`, atualizado manualmente com `npm run quality:refresh-model-lifecycle` (rede; não integrado no CI). `allowedRetiredInCatalog` é um mecanismo de redução progressiva: adicione uma entrada apenas com uma issue de acompanhamento. | Sim | -| `check:fetch-targets` | Cada `fetch("/api/...")` no `src/` do lado do cliente corresponde a um `route.ts` real | Sim | -| `check:deps` | Todas as dependências instaláveis com `npm install` em todos os ficheiros `package.json` do repositório constam de `dependency-allowlist.json`; pacotes novos sem versão fixa ou resultantes de slopsquatting são sinalizados | Sim | -| `audit:deps` | `npm audit` (raiz + electron) — sem avisos de gravidade alta/crítica (sobrepõe-se ao `check:vuln-ratchet` do osv; consulte a Lista de Tarefas de Racionalização) | Sim | -| `check:lockfile` | Integridade de `package-lock.json` — registo https, hashes de integridade, sem substituições de anfitrião | Sim | -| `check:licenses` | Lista de permissões de licenças SPDX para dependências de produção | Sim | -| `check:tracked-artifacts` | Sem artefactos de compilação / ligações simbólicas de `node_modules` com controlo de versões (também é executado no pre-commit do husky; o pre-push é intencionalmente leve — #6716) | Sim | -| `check:ai-attribution` | Sem rodapé `Co-Authored-By` de IA/bot nem rodapé de geração por IA nos commits, título ou corpo do PR — Regra Rígida #16 (no ciclo de verificações rápidas de `quality.yml` para PR→`release/**` — lê o payload do evento, não executa qualquer operação fora de PRs — e num passo exclusivo de PRs no lint de `ci.yml` para PR→`main`; também no hook `commit-msg` do husky; coautores humanos permitidos; #14436) | -| `check:vitest-exclusions` | Cada exclusão do Vitest indica um issue de acompanhamento e consta em `config/quality/vitest-exclusions.json` (#13204) | Sim | -| `check:file-size` | Nenhum ficheiro de código-fonte excede o limite por extensão (ratchet: ficheiros grandes congelados na lista `frozen`) | Sim | -| `check:error-helper` | As respostas de erro em executores/handlers utilizam `buildErrorBody()` / `sanitizeErrorMessage()` (Regra Rígida #12) | Sim | -| `check:migration-numbering` | Os ficheiros SQL de migração são numerados sequencialmente, sem lacunas nem duplicados | Sim | -| `check:public-creds` | Não existem valores literais de OAuth `client_id`/`client_secret` nem chaves Web do Firebase fora de `publicCreds.ts` (Regra Rígida n.º 11) | Sim | -| `check:db-rules` | Não existe SQL em bruto fora dos módulos de `src/lib/db/`; não existem importações agregadas de `localDb.ts` (Regras Rígidas n.º 2/n.º 5) | Sim | -| `check:known-symbols` | Os executores de fornecedores, as estratégias de encaminhamento e os tradutores registados nas respetivas tabelas de expedição correspondem aos ficheiros no disco — sem símbolos órfãos ou não declarados | Sim | -| `check:route-guard-membership` | Todas as rotas que iniciam um processo subordinado são classificadas por `isLocalOnlyPath()` (Regras Rígidas n.º 15/n.º 17) | Sim | -| `check:test-discovery` | Todos os ficheiros `*.test.ts` / `*.spec.ts` no repositório são recolhidos por, pelo menos, um executor de testes (mecanismo de retenção: a lista de órfãos em `test-discovery-baseline.json` apenas pode diminuir) | Sim | -| `check:agent-skills-sync` | Os artefactos agent-skills gerados correspondem ao respetivo catálogo de origem (sem divergências) | -| `check:provider-asset-provenance` | Os logótipos/recursos dos fornecedores têm uma entrada de proveniência registada | -| `lint:json` | Os ficheiros de configuração JSON são analisados corretamente e cumprem as regras de lint do repositório | -| `typecheck:core` | Compilação TypeScript sem erros (apenas avisos informativos) | Sim | -| `typecheck:noimplicit:core` | `noImplicitAny` estrito — orientado para o futuro; muitos locais de chamada preexistentes ainda necessitam de anotações | **Informativo** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limitado a `src/app/(dashboard)/**` (#7033) — a lista de permissões selecionada de 27 ficheiros de `typecheck:core` não inclui qualquer TSX do dashboard, e `next build` também nunca efetua a verificação de tipos (`next.config.mjs` define `ignoreBuildErrors: true`), pelo que as regressões de identificadores órfãos aí existentes (#6625/#6909) eram invisíveis para o CI. Compara com uma linha de base fixa de contagens por ficheiro/por código TS (`config/quality/dashboard-typecheck-baseline.json`, seguindo o mesmo padrão de imposição de obsolescência de `check:known-symbols`) — apenas NOVOS erros além da contagem da linha de base fazem com que a verificação falhe; reduza progressivamente com `--update` quando um erro preexistente for corrigido. | Sim | +### Job: `lint` + +É executado em cada PR para `main`. Bloqueia a integração em caso de falha. + +| Script (`npm run ...`) | Valida | Bloqueador | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | A versão do Node.js encontra-se dentro do intervalo suportado | Sim | +| `check:cycles` | Importações circulares em todo o `src/` + `open-sse/` (baseado em AST, com `paths` do tsconfig resolvidos). A execução simples é informativa e lista os ciclos. `check:cycles:ratchet` (que é executado pelo CI) bloqueia quando a contagem excede o limite máximo de `metrics.cycles` em `quality-baseline.json` — atualmente 14, `direction: down`, pelo que só pode diminuir (#15159 G-01/G-02) | Sim (catraca) | +| `check:route-validation:t06` | Presença de esquemas Zod em todas as rotas (política de Nível 6) | Sim | +| `check:any-budget:t11` | A contagem de `@ts-expect-error // any` não excede o limite (catraca de Nível 11) | Sim | +| `check:provider-consistency` | Cada fornecedor em `providers.ts` tem uma entrada correspondente em `providerRegistry.ts` (e vice-versa, dentro da lista de permissões) | Sim | +| `check:model-lifecycle` | As três tabelas de encaminhamento mantidas manualmente permanecem consistentes com o instantâneo do ciclo de vida incluído no repositório (#11503): `FITNESS_TABLE` (`taskFitness.ts`) não pontua nenhum id descontinuado que `REGISTRY` consiga encaminhar; todos os destinos de `BUILT_IN_ALIASES` estão presentes em `REGISTRY` e ausentes do instantâneo de ids descontinuados; todos os ids descontinuados ainda presentes em `REGISTRY` são reencaminhados ou indicados em `allowedRetiredInCatalog`; e nenhuma origem ou destino de `DEFAULT_DEGRADATION_MAP` aparece como descontinuado nesse instantâneo. Isto não prova que um modelo esteja atualmente a ser disponibilizado por um serviço a montante ativo. Offline — compara com `config/quality/model-lifecycle.json`, atualizado manualmente com `npm run quality:refresh-model-lifecycle` (rede; não integrado no CI). `allowedRetiredInCatalog` é um mecanismo de redução progressiva: adicione uma entrada apenas com uma questão de acompanhamento. | Sim | +| `check:fetch-targets` | Cada `fetch("/api/...")` no diretório `src/` do lado do cliente corresponde a um `route.ts` real | Sim | +| `check:deps` | Todas as dependências instaláveis com `npm install`, em todos os ficheiros `package.json` do repositório, estão em `dependency-allowlist.json`; pacotes novos sem versão fixa ou com nomes semelhantes a outros pacotes são assinalados | Sim | +| `audit:deps` | `npm audit` (raiz + electron) — sem avisos de gravidade alta/crítica (sobrepõe-se ao `check:vuln-ratchet` do osv; consulte a Lista de Pendências de Racionalização) | Sim | +| `check:lockfile` | Integridade de `package-lock.json` — registo https, hashes de integridade, sem substituições de anfitrião | Sim | +| `check:licenses` | Lista de permissões de licenças SPDX para dependências de produção | Sim | +| `check:tracked-artifacts` | Sem artefactos de compilação / ligações simbólicas de `node_modules` submetidas (também é executado no pre-commit do husky; o pre-push é intencionalmente leve — #6716) | Sim | +| `check:ai-attribution` | Sem rodapé `Co-Authored-By` de IA/bot nem rodapé de geração por IA nos commits, no título ou no corpo do PR — Regra Rígida n.º 16 (no ciclo de verificações rápidas de `quality.yml` para PR→`release/**` — lê o payload do evento, não efetua nenhuma operação fora de PRs — e num passo exclusivo de PRs na análise estática de `ci.yml` para PR→`main`; também no hook `commit-msg` do husky; são permitidos coautores humanos; #14436) | +| `check:vitest-exclusions` | Cada exclusão do Vitest identifica um issue de acompanhamento e consta de `config/quality/vitest-exclusions.json` (#13204) | Sim | +| `check:file-size` | Nenhum ficheiro de código-fonte excede o limite por extensão (ratchet: ficheiros grandes congelados na lista `frozen`) | Sim | +| `check:error-helper` | As respostas de erro em executores/handlers utilizam `buildErrorBody()` / `sanitizeErrorMessage()` (Regra Rígida n.º 12) | Sim | +| `check:migration-numbering` | Os ficheiros SQL de migração são numerados sequencialmente, sem lacunas nem duplicados | Sim | +| `check:public-creds` | Não existem valores literais de OAuth `client_id`/`client_secret` nem chaves Web do Firebase fora de `publicCreds.ts` (Regra Rígida #11) | Sim | +| `check:db-rules` | Não existe SQL em bruto fora dos módulos de `src/lib/db/`; não existem importações de agregação a partir de `localDb.ts` (Regras Rígidas #2/#5) | Sim | +| `check:known-symbols` | Os executores de fornecedores, as estratégias de encaminhamento e os tradutores registados nas respetivas tabelas de despacho correspondem aos ficheiros no disco — sem símbolos órfãos ou não declarados | Sim | +| `check:route-guard-membership` | Todas as rotas que iniciam um processo subordinado estão classificadas por `isLocalOnlyPath()` (Regras Rígidas #15/#17) | Sim | +| `check:test-discovery` | Todos os ficheiros `*.test.ts` / `*.spec.ts` no repositório são recolhidos por, pelo menos, um executor de testes (catraca: a lista de órfãos em `test-discovery-baseline.json` apenas pode diminuir) | Sim | +| `check:agent-skills-sync` | Os artefactos agent-skills gerados correspondem ao respetivo catálogo de origem (sem divergências) | +| `check:provider-asset-provenance` | Os logótipos/recursos dos fornecedores têm uma entrada de proveniência registada | +| `lint:json` | Os ficheiros de configuração JSON são analisados corretamente e cumprem as regras de lint do repositório | +| `typecheck:core` | Compilação TypeScript sem erros (apenas avisos informativos) | Sim | +| `typecheck:noimplicit:core` | `noImplicitAny` estrito — orientado para o futuro; muitos locais de chamada preexistentes ainda necessitam de anotações | **Informativo** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` limitado a `src/app/(dashboard)/**` (#7033) — a lista restrita de 27 ficheiros permitidos de `typecheck:core` não inclui qualquer TSX do dashboard, e `next build` também nunca efetua a verificação de tipos desse código (`next.config.mjs` define `ignoreBuildErrors: true`), pelo que as regressões de identificadores órfãos nessa área (#6625/#6909) eram invisíveis para a CI. Compara com uma linha de base fixa de contagens por ficheiro/por código TS (`config/quality/dashboard-typecheck-baseline.json`, seguindo o mesmo padrão de imposição de dados obsoletos de `check:known-symbols`) — apenas erros NOVOS que excedam a contagem da linha de base fazem falhar a validação; reduza-a progressivamente com `--update` quando um erro preexistente for corrigido. | Sim | ### Tarefa: `quality-gate` É executada após `test-coverage`. Bloqueia a integração em caso de falha. -| Script | Valida | Bloqueante | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `quality:collect` | Gera `quality-metrics.json` (número de avisos do ESLint, cobertura do relatório combinado dos fragmentos) | Sim (a montante do ratchet) | -| `quality:ratchet` | Nenhuma métrica em `quality-baseline.json` regrediu (avisos do ESLint ≤ referência; cobertura ≥ referência) | Sim | -| `check:duplication` | A duplicação de código (jscpd@4) não excede a referência em `quality-baseline.json` | Sim | -| `check:complexity` | A complexidade ciclomática ao nível do ficheiro não excede o limite (`complexity` principal do ESLint + `max-lines-per-function`) | Sim | -| `check:cognitive-complexity` | Ratchet de complexidade cognitiva (`eslint-plugin-sonarjs`) — execução separada do ESLint; a CI executa ambos combinados no passo único `check:complexity-ratchets` | Sim | -| `check:dead-code` | O ratchet de exportações/ficheiros não utilizados (knip) não regride relativamente à referência | Sim | -| `check:compression-budget` | Orçamento do benchmark de compressão — os valores mínimos de poupança de tokens por motor não podem regredir | Sim | -| `check:type-coverage` | O ratchet da percentagem de código tipado (`type-coverage`) não regride; substitui em grande medida `typecheck:noimplicit:core` | Sim | -| `check:codeql-ratchet` | O número de alertas CodeQL abertos não regride (lido através de `gh api`; ignorado de forma segura sem token) — frequência de atualização e acionamento manual: consulte «Ratchet do CodeQL» abaixo | Sim | - -### Tarefa: `quality-extended` - -Toda a tarefa é consultiva (`continue-on-error: true`). Os ratchets baseados em npm são executados -efetivamente; os analisadores externos são instalados através de `gh release download` e ignoram-se automaticamente (código de saída 0) +| Script | Valida | Bloqueante | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `quality:collect` | Gera `quality-metrics.json` (número de avisos do ESLint, cobertura do relatório combinado dos fragmentos) | Sim (a montante do ratchet) | +| `quality:ratchet` | Nenhuma métrica em `quality-baseline.json` regrediu (avisos do ESLint ≤ linha de base; cobertura ≥ linha de base) | Sim | +| `check:duplication` | A duplicação de código (jscpd@4) não excede a linha de base em `quality-baseline.json` | Sim | +| `check:complexity` | A complexidade ciclomática ao nível do ficheiro não excede o limite (`complexity` do ESLint base + `max-lines-per-function`) | Sim | +| `check:cognitive-complexity` | Ratchet de complexidade cognitiva (`eslint-plugin-sonarjs`) — execução separada do ESLint; a CI executa ambos em conjunto como o único passo `check:complexity-ratchets` | Sim | +| `check:dead-code` | O ratchet de exportações/ficheiros não utilizados (knip) não regride face à linha de base | Sim | +| `check:compression-budget` | Orçamento do benchmark de compressão — os limites mínimos de poupança de tokens por motor não podem regredir | Sim | +| `check:type-coverage` | O ratchet da percentagem tipificada (`type-coverage`) não regride; substitui, em grande medida, `typecheck:noimplicit:core` | Sim | +| `check:codeql-ratchet` | O número de alertas CodeQL abertos não regride (lê através de `gh api`; omissão controlada sem token) — para a cadência de atualização e o acionamento manual: consulte "Ratchet do CodeQL" abaixo | Sim | + +### Job: `quality-extended` + +Todo o job é consultivo (`continue-on-error: true`). Os ratchets baseados em npm são executados +efetivamente; os analisadores externos são instalados através de `gh release download` e omitem-se automaticamente (exit 0) quando um binário continua ausente. -| Script | Valida | Bloqueante | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `check:circular-deps` | Ausência de dependências circulares (dpdm) | **Consultivo** | -| `check:bundle-size` | O tamanho do bundle não excede o limite | **Consultivo** | -| `check:secrets` | Análise de segredos (gitleaks) — ignorada se o binário estiver ausente | **Consultivo** | -| `check:vuln-ratchet` | As vulnerabilidades das dependências (osv-scanner) não regridem — ignorado se o binário estiver ausente | **Consultivo** | -| `check:workflows` | Validação de workflows (actionlint + zizmor); analisadores ausentes/com falhas, relatórios inválidos ou uma referência de ratchet ausente resultam em INCOMPLETE. As conclusões válidas seguem a política rigorosa/consultiva/de ratchet selecionada | Execução obrigatória; ratchet do zizmor bloqueante na CI | -| `check:openapi-breaking` | Alterações incompatíveis ao contrato da API pública (`openapi.yaml`) relativamente ao ramo base (oasdiff) — gera `openapiBreaking=N`; ignorado se o oasdiff estiver ausente ou se não for possível resolver a especificação base | **Consultivo** | - -### Tarefa: `docs-sync-strict` - -É executada em todos os PR para `main`. Bloqueia a integração em caso de falha. - -| Script | Valida | Bloqueante | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -| `check:docs-all` | Metaporta que executa sequencialmente as 6 subportas abaixo | Sim | -| ↳ `check:docs-sync` | Consistência das versões de CHANGELOG / OpenAPI / llm.txt | Sim | -| ↳ `check:docs-counts` | As contagens no texto (número de fornecedores, número de migrações, etc.) estão dentro da janela de progressão das contagens reais | Sim | -| ↳ `check:env-doc-sync` | Todas as variáveis de ambiente em `.env.example` estão documentadas numa tabela da documentação e vice-versa | Sim | -| ↳ `check:deprecated-versions` | Não existem cadeias de versões obsoletas na documentação | Sim | -| ↳ `check:doc-links` | As ligações internas de markdown na documentação remetem para ficheiros reais (formato `[text]`/`(path)`) | Sim | -| ↳ `check:fabricated-docs` | As rotas, variáveis de ambiente, comandos da CLI, nomes de hooks e caminhos de ficheiros citados na documentação existem na base de código. Porta rígida através de `--strict`; falha não bloqueante sem a opção. | Sim (através de `--strict` no CI) | -| `check:cli-i18n` | As cadeias dos comandos da CLI estão presentes em todos os ficheiros de idiomas i18n | Sim | -| `check:openapi-coverage` | A especificação OpenAPI abrange, no mínimo, um limite mínimo progressivo das rotas reais | Sim | -| `check:openapi-security-tiers` | As anotações dos níveis de segurança em `openapi.yaml` são consistentes com as classificações de `routeGuard.ts` | **Consultivo** | -| `check:openapi-routes` | Todos os caminhos em `openapi.yaml` correspondem a um `route.ts` real (antialucinação) | Sim | -| `check:docs-symbols` | Todas as referências `/api/...` em `docs/**/*.md` correspondem a um `route.ts` real (antialucinação) | Sim | -| `i18n translation drift` | Chaves não traduzidas nos ficheiros de idiomas i18n — apenas aviso | **Consultivo** | +| Script | Valida | Bloqueante | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | +| `check:circular-deps` | Ausência de dependências circulares (dpdm) | **Consultivo** | +| `check:bundle-size` | O tamanho do bundle não excede o limite | **Consultivo** | +| `check:secrets` | Análise de segredos (gitleaks) — omitida se o binário estiver ausente | **Consultivo** | +| `check:vuln-ratchet` | As vulnerabilidades das dependências (osv-scanner) não regridem — omitida se o binário estiver ausente | **Consultivo** | +| `check:workflows` | Lint de workflows (actionlint + zizmor); analisadores ausentes/com falhas, relatórios inválidos ou uma linha de base do ratchet em falta resultam em INCOMPLETE. As deteções válidas seguem a política estrita/consultiva/de ratchet selecionada | Execução obrigatória; ratchet do zizmor bloqueante na CI | +| `check:openapi-breaking` | Alterações incompatíveis ao contrato da API pública (`openapi.yaml`) face ao branch de base (oasdiff) — gera `openapiBreaking=N`; omitida se o oasdiff estiver ausente ou se a especificação de base não puder ser resolvida | **Consultivo** | + +### Job: `docs-sync-strict` + +É executado em todos os PR para `main`. Bloqueia a integração em caso de falha. + +| Script | Valida | Bloqueante | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `check:docs-all` | Metaverificação que executa sequencialmente as 6 subverificações abaixo | Sim | +| ↳ `check:docs-sync` | Consistência das versões entre CHANGELOG / OpenAPI / llm.txt | Sim | +| ↳ `check:docs-counts` | As contagens no texto (número de fornecedores, número de migrações, etc.) encontram-se dentro do intervalo de progressão das contagens reais | Sim | +| ↳ `check:env-doc-sync` | Todas as variáveis de ambiente em `.env.example` estão documentadas numa tabela da documentação e vice-versa | Sim | +| ↳ `check:deprecated-versions` | Não existem cadeias de versões obsoletas na documentação | Sim | +| ↳ `check:doc-links` | As ligações markdown internas na documentação correspondem a ficheiros reais (formato `[texto]`/`(caminho)`) | Sim | +| ↳ `check:fabricated-docs` | As rotas, variáveis de ambiente, comandos da CLI, nomes de hooks e caminhos de ficheiros mencionados na documentação existem na base de código. Verificação estrita através de `--strict`; falha não bloqueante sem a opção. | Sim (através de `--strict` no CI) | +| `check:cli-i18n` | As cadeias dos comandos da CLI estão presentes em todos os ficheiros de idiomas i18n | Sim | +| `check:openapi-coverage` | A especificação OpenAPI cobre, pelo menos, um limiar progressivo de rotas reais | Sim | +| `check:openapi-security-tiers` | As anotações dos níveis de segurança em `openapi.yaml` são consistentes com as classificações em `routeGuard.ts` | **Consultivo** | +| `check:openapi-routes` | Cada caminho em `openapi.yaml` corresponde a um `route.ts` real (antialucinação) | Sim | +| `check:docs-symbols` | Cada referência `/api/...` em `docs/**/*.md` corresponde a um `route.ts` real (antialucinação) | Sim | +| `i18n translation drift` | Chaves não traduzidas nos ficheiros de idiomas i18n — apenas aviso | **Consultivo** | ### Tarefa: `i18n-ui-coverage` -| Script | Valida | Bloqueante | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (inline) | A cobertura das chaves de i18n da IU é ≥ 65% | Sim | -| `check-ui-value-drift` (inline) | Um **valor** em inglês reescrito não deixa para trás nenhuma tradução desatualizada | Sim | -| `check-new-key-coverage` (inline) | Uma **nova** chave em inglês está traduzida em todos os idiomas — um marcador `__MISSING__:` é rejeitado | Sim | -| `check-translation-ratio` | O rácio de traduções reais por idioma (valores idênticos ao inglês / marcadores de posição / elementos em falta fora da lista de permissões) não pode exceder `config/quality/i18n-translation-baseline.json` + margem | **Consultivo** | +| Script | Valida | Bloqueante | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (inline) | A cobertura das chaves i18n da IU é ≥ 65% | Sim | +| `check-ui-value-drift` (inline) | Um **valor** em inglês reescrito não deixa para trás nenhuma tradução desatualizada | Sim | +| `check-new-key-coverage` (inline) | Uma **nova** chave em inglês está traduzida em todos os idiomas — um marcador `__MISSING__:` é rejeitado | Sim | +| `check-translation-ratio` | O rácio de traduções reais por idioma (elementos idênticos ao inglês / marcadores de posição / em falta fora da lista de permissões) não pode exceder `config/quality/i18n-translation-baseline.json` + margem | **Consultivo** | -Requer `fetch-depth: 0` — a porta de divergência de valores compara `en.json` com a base de integração. +Requer `fetch-depth: 0` — a verificação de divergência de valores compara `en.json` com a base de integração. -#### `check-ui-value-drift` — porta de traduções desatualizadas +#### `check-ui-value-drift` — verificação de traduções desatualizadas -Deteta a única regressão de i18n que as outras portas, estruturalmente, não conseguem identificar: um valor em inglês -é reescrito e as traduções derivadas do inglês _anterior_ permanecem, fazendo com que -os utilizadores que não falam inglês continuem a ler um texto formulado de forma convincente, mas agora incorreto. +Deteta a única regressão de i18n que as outras verificações não conseguem identificar +estruturalmente: um valor em inglês é reescrito e as traduções derivadas do inglês +_anterior_ permanecem, pelo que os utilizadores que não usam inglês continuam a ler um +texto apresentado com confiança, mas agora incorreto. -Isto chegou efetivamente à produção. `oauthModal.googleOAuthWarning` foi reescrito quando o auxiliar de início de sessão -do Antigravity foi introduzido (#5203); **39 de 43 idiomas** mantiveram o texto que instruía os operadores a «copiar o -URL completo e colá-lo abaixo» — um fluxo que não pode ser concluído para esse fornecedor. O problema -passou despercebido até ao #8463 porque: +Isto chegou efetivamente à produção. `oauthModal.googleOAuthWarning` foi reescrito quando +foi introduzido o auxiliar de início de sessão Antigravity (#5203); **39 de 43 idiomas** +mantiveram o texto que instruía os operadores a «copiar o URL completo e colá-lo abaixo» — +um fluxo que não pode ser concluído para esse fornecedor. O problema passou despercebido +até ao #8463 porque: - `sync-ui-keys` apenas preenche chaves que estão **ausentes**, nunca as que estão **desatualizadas**; -- `check-ui-keys-coverage` contabiliza a _presença_ das chaves, pelo que uma tradução desatualizada conta como abrangida; +- `check-ui-keys-coverage` contabiliza a _presença_ das chaves, pelo que uma tradução desatualizada conta como coberta; - `check-translation-drift` monitoriza os espelhos da documentação em `docs/i18n//**.md` — nunca lê `src/i18n/messages/*.json`. Bloqueante na tarefa `docs-sync-strict` desde a - ressincronização de 2026-09: editar um documento principal → `npm run i18n:run -- --files=` (ao nível da secção, pouco dispendioso). + ressincronização de 2026-09: editar um documento principal → `npm run i18n:run -- --files=` (ao nível da secção, rápido). -**Tem em conta o diff, não se baseia numa baseline.** Compara o `en.json` na base de integração com a +**Sensível ao diff, sem depender de uma baseline.** Compara o `en.json` na base de integração com a árvore de trabalho; para cada chave cujo valor em inglês tenha sido alterado, qualquer locale que ainda contenha uma -tradução inalterada está desatualizado. Isto **congela deliberadamente a dívida preexistente** — um diff -não permite determinar de que versão antiga do inglês veio uma tradução existente há muito tempo, pelo que o controlo avalia +tradução não alterada está desatualizado. Isto **congela deliberadamente a dívida preexistente** — um diff +não consegue revelar de que versão antiga do inglês surgiu uma tradução existente há muito tempo, pelo que a validação avalia apenas aquilo em que a alteração atual toca. A alternativa (uma baseline de hashes por chave) implicaria um ficheiro gerado de ~600 KB, 3× maior do que a maior baseline existente, alterado em cada PR de i18n. -Há duas formas de satisfazer este controlo: +Há duas formas de cumprir a validação: 1. atualizar as traduções afetadas, ou -2. defini-las como `__MISSING__:` — em seguida, o runtime apresenta o inglês corrigido - (`src/i18n/request.ts::deepMergeFallback`, #7258) e a chave fica em fila para tradução. +2. defini-las como `__MISSING__:` — em tempo de execução, é então apresentado o inglês corrigido + (`src/i18n/request.ts::deepMergeFallback`, #7258) e a chave entra na fila para tradução. -Se o **significado** da cadeia tiver mudado, é preferível **mudar o nome da chave**: uma chave nova não pode herdar -uma tradução desatualizada. Esse foi o padrão utilizado em #8463. +Se o **significado** da string tiver mudado, dê preferência a **renomear a chave**: uma chave nova não pode herdar +uma tradução desatualizada. Foi esse o padrão utilizado em #8463. ```bash npm run i18n:check-value-drift # estrito (o que a CI executa) @@ -231,48 +235,48 @@ npm run i18n:check-value-drift:warn # apenas relatório BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Termina com o código 0 e `SKIP reason=base-unresolved` quando não é possível ler o catálogo base (clone -superficial sem a referência base), refletindo o comportamento de `check-openapi-breaking`. +Termina com o código 0 e `SKIP reason=base-unresolved` quando o catálogo de base não pode ser lido (clone +superficial sem a ref de base), em linha com `check-openapi-breaking`. -### Job: `i18n` +### Tarefa: `i18n` -Matriz completa de validação de i18n (um job por locale). O job inteiro é informativo. +Matriz completa de validação de i18n (uma tarefa por locale). Toda a tarefa é informativa. -| Script | Valida | Bloqueio | -| ------------------------------- | --------------------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | Completude da tradução por locale | **Informativo** (`continue-on-error: true` em todo o job) | +| Script | Valida | Bloqueante | +| ------------------------------- | --------------------------------- | ------------------------------------------------------------ | +| `validate_translation.py quick` | Completude da tradução por locale | **Informativo** (`continue-on-error: true` em toda a tarefa) | -### Job: `pr-test-policy` +### Tarefa: `pr-test-policy` -É executado apenas em pull requests. +Executada apenas em pull requests. -| Script | Valida | Bloqueio | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | Os PRs que alteram código de produção em `src/`, `open-sse/`, `electron/` ou `bin/` têm de incluir ou atualizar testes (Regra Rígida #8) | Sim | -| `check:test-masking` | Os ficheiros de teste alterados não reduzem a contagem líquida de asserções nem adicionam tautologias `assert.ok(true)` | Sim | -| `check:pr-evidence` | O corpo do PR apresenta provas de testes/VPS para a alteração (mecaniza a Regra Rígida #18 procurando padrões no texto do PR — frágil, ver Backlog) | Sim | +| Script | Valida | Bloqueante | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | +| `check:pr-test-policy` | Os PRs que alteram código de produção em `src/`, `open-sse/`, `electron/` ou `bin/` têm de incluir ou atualizar testes (Regra Rígida #8) | Sim | +| `check:test-masking` | Os ficheiros de teste alterados não reduzem a contagem líquida de asserções nem adicionam tautologias `assert.ok(true)` | Sim | +| `check:pr-evidence` | O corpo do PR menciona evidências de testes/VPS para a alteração (automatiza a Regra Rígida #18 pesquisando o texto do PR — frágil, ver Backlog) | Sim | -### Job: `test-vitest` +### Tarefa: `test-vitest` -É executado após `build`. Bloqueia a integração em caso de falha. +Executada após `build`. Bloqueia a integração em caso de falha. -| Suite | Valida | Bloqueio | -| ---------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Servidor MCP (110 ferramentas), autoCombo, cache — runner vitest | Sim | -| `test:vitest:ui` | Testes de componentes da IU — runner vitest | **Bloqueante** — as falhas preexistentes são explicitamente excluídas em `vitest.config.ts`; novas falhas fazem o job falhar | +| Suite | Valida | Bloqueante | +| ---------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Servidor MCP (110 ferramentas), autoCombo, cache — executor vitest | Sim | +| `test:vitest:ui` | Testes de componentes da IU — executor vitest | **Bloqueante** — as falhas preexistentes estão explicitamente excluídas em `vitest.config.ts`; novas falhas fazem a tarefa falhar | ### Workflows noturnos (agendados, informativos) -São executados segundo um agendamento cron (e através de `workflow_dispatch`), nunca em PRs. Todos são informativos. +São executados de acordo com um agendamento cron (e `workflow_dispatch`), nunca em PRs. Todos são informativos. -| Workflow | Valida | Bloqueio | +| Workflow | Valida | Bloqueante | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | Testes baseados em propriedades com fast-check, utilizando uma seed aleatória e um número elevado de execuções | **Informativo** | -| `nightly-resilience` | Controlo do crescimento da heap, injeção caótica de falhas, testes de carga/soak com k6 | **Informativo** | -| `nightly-llm-security` | Proteção contra injeção do promptfoo (modo de bloqueio) + sondas garak (ignoradas sem um segredo de fornecedor) | **Informativo** | +| `nightly-property` | Testes baseados em propriedades com fast-check, uma semente aleatória e um número elevado de execuções | **Informativo** | +| `nightly-resilience` | Validação do crescimento do heap, injeção caótica de falhas, testes de carga/prolongados com k6 | **Informativo** | +| `nightly-llm-security` | Proteção contra injeção com promptfoo (modo de bloqueio) + sondas garak (ignoradas sem um segredo de fornecedor) | **Informativo** | | `nightly-schemathesis` | Fuzzing do contrato OpenAPI (schemathesis) contra uma instância OmniRoute ativa utilizando `docs/openapi.yaml` — revela violações da especificação/erros 500 não tratados (Fase 8 B.4) | **Informativo** | -| `nightly-mutation` | Pontuação dos testes de mutação Stryker na via rápida de testes unitários — mutantes sobreviventes revelam asserções fracas | **Informativo** | -| `nightly-compat` | Matriz de compatibilidade do motor Node para os intervalos suportados de `engines.node` | **Informativo** | +| `nightly-mutation` | Pontuação dos testes de mutação Stryker na via rápida de testes unitários — os mutantes sobreviventes revelam asserções fracas | **Informativo** | +| `nightly-compat` | Matriz de compatibilidade do motor Node em todos os intervalos `engines.node` suportados | **Informativo** | --- @@ -536,43 +540,44 @@ erro de ligação e nunca interrompe as sessões. --- -## Lista de Pendentes de Racionalização (revisão de ROI — Fase 9 Onda 3) +## Backlog de racionalização (revisão de ROI — Fase 9 Onda 3) Este inventário foi reconciliado com `ci.yml` em 2026-06-17 (a versão anterior omitia `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Uma revisão de ROI do conjunto reconciliado -identificou os seguintes candidatos a racionalização. **As fusões são alterações mecânicas -de CI; as inversões/remoções são decisões de política reservadas ao operador.** Nada do que -se segue foi ainda aplicado. - -**Também não documentados acima** (consultivos, baixo sinal): a tarefa `docs-lint` -(markdownlint + Vale, tarefa completa com `continue-on-error`) e os fluxos de trabalho de análise autónomos -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` está em -`quality-baseline.json`, mas não está ligado a um mecanismo de bloqueio progressivo em `ci.yml` — a métrica +identificou os seguintes candidatos a racionalização. **As consolidações são alterações +mecânicas de CI; as ativações/desativações e remoções são decisões de política reservadas +ao operador.** Nada do que se segue foi aplicado. + +**Também não documentados acima** (consultivos, sinal fraco): a tarefa `docs-lint` +(markdownlint + Vale, com `continue-on-error` em toda a tarefa) e os workflows autónomos de +análise `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` consta de +`quality-baseline.json`, mas não está ligado a um ratchet bloqueante em `ci.yml` — a métrica está atualmente órfã. -### Fusão / desduplicação (mecânica, menor risco) +### Consolidação / desduplicação (mecânica, menor risco) -Cada candidato foi validado relativamente ao estado real dos controlos em 2026-06-17 (confiar, mas verificar); -várias fusões "óbvias" revelaram ocultar dívida e **não** são substituições diretas sem riscos. +Cada candidato foi validado face ao estado efetivo dos gates em 2026-06-17 (confiar, mas +verificar); várias consolidações "óbvias" acabaram por ocultar dívida e **não** podem ser +aplicadas diretamente sem problemas. -- **`check:docs-sync` é executado duas vezes** — de forma autónoma na tarefa `lint` e novamente dentro de `check:docs-all` (`docs-sync-strict`) e do hook de pre-commit do husky. ✅ **CONCLUÍDO** — invocação autónoma em `lint` removida. -- **Análise de CVE** — ❌ **NÃO é uma fusão simples.** `audit:deps` falha de forma definitiva perante qualquer CVE de gravidade alta/crítica; `check:vuln-ratchet` (osv) apenas falha perante uma _regressão_ relativamente à referência (atualmente 1 MODERATE). Semânticas diferentes — remover `audit:deps` eliminaria o controlo absoluto de gravidade alta/crítica. Manter ambos. -- **Deteção de ciclos** — ❌ **NÃO é uma fusão simples.** `check:circular-deps` (dpdm) comunica **91 ciclos** (razão pela qual é consultivo); não pode ser promovido a bloqueante sem os resolver primeiro e tem um âmbito mais abrangente do que o `check:cycles`, que está verde e foi cuidadosamente delimitado. Manter `check:cycles` como bloqueante; resolver os 91 ciclos do dpdm constitui uma tarefa pendente própria. -- **Complexidade** — ✅ **CONCLUÍDO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): uma passagem do ESLint, com contagens por ruleId, para que os valores de referência de complexidade ciclomática+máximo de linhas e de complexidade cognitiva permaneçam independentes; os comandos individuais `check:complexity` / `check:cognitive-complexity` permanecem disponíveis para `--update` local. -- **Anti-alucinação de `/api`** — ✅ **CONCLUÍDO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): um inventário do sistema de ficheiros de `src/app/api`; openapi-routes + docs-symbols continuam a produzir relatórios independentes; os comandos individuais permanecem disponíveis para execuções locais. -- **`check:node-runtime` é executado em 11 tarefas** — ⚠️ **ROI baixo.** Cada uma utiliza um executor separado e a verificação demora <1s; poupança total de ~10s, em troca da perda de uma salvaguarda económica por tarefa. Não justifica a perturbação. -- **`typecheck:noimplicit:core` no lint de CI** — ✅ **removido da tarefa lint** (era consultivo com `continue-on-error`); a superfície de tipos bloqueante é `typecheck:core` + `check:type-coverage`. Script local mantido. +- **`check:docs-sync` é executado duas vezes** — de forma autónoma na tarefa `lint` e novamente dentro de `check:docs-all` (`docs-sync-strict`) e do hook de pre-commit do husky. ✅ **CONCLUÍDO** — removida a invocação autónoma em `lint`. +- **Análise de CVE** — ❌ **NÃO é uma consolidação direta.** `audit:deps` falha de forma bloqueante perante qualquer CVE alta/crítica; `check:vuln-ratchet` (osv) só falha perante uma _regressão_ relativamente à baseline (atualmente 1 MODERATE). Semânticas diferentes — remover `audit:deps` eliminaria o gate absoluto para vulnerabilidades altas/críticas. Manter ambos. +- **Deteção de ciclos** — ✅ **CONCLUÍDO** (#15159 G-01/G-02). O texto anterior descrevia `check:cycles` como o gate "verde e curado" e justificava mantê-lo bloqueante porque `check:circular-deps` (dpdm) comunicava 91 ciclos. Esse resultado verde era um **falso positivo de sucesso**: `check:cycles` analisava 5 subdiretórios (450 ficheiros), apenas correspondia a `import|export … from` estáticos e descartava todos os especificadores `@/` e `@omniroute/open-sse/`, pelo que não conseguia detetar os ciclos de importação dinâmica + aliases que predominavam no repositório. Corrigido: o gate percorre agora `src` + `open-sse` (5023 ficheiros), recolhe especificadores da AST do TypeScript (pelo que `import("…")` conta e `typeof import("…")` em posição de tipo não conta) e resolve `paths` do tsconfig. Deteta **14** ciclos, não 0. Uma vez que 14 ciclos preexistentes não podem ser corrigidos num PR de gate, `check:cycles` é agora um **ratchet** (`--ratchet`, limite máximo `metrics.cycles.value = 14` em `quality-baseline.json`, `direction: down`) — bloqueia qualquer _regressão_ e a contagem só pode diminuir. O CI executa `npm run check:cycles:ratchet`. A redução progressiva será efetuada com **A-01**. `check:circular-deps` (dpdm) permanece consultivo como segunda opinião mais abrangente. +- **Complexidade** — ✅ **CONCLUÍDO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): uma passagem do ESLint, com contagens por ruleId para que as baselines de complexidade ciclomática+max-lines e cognitiva permaneçam independentes; `check:complexity` / `check:cognitive-complexity` individuais são mantidos para utilização local com `--update`. +- **Anti-alucinação de `/api`** — ✅ **CONCLUÍDO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): um único inventário do sistema de ficheiros de `src/app/api`; openapi-routes + docs-symbols continuam a produzir relatórios independentes; as verificações individuais são mantidas para execuções locais. +- **`check:node-runtime` é executado em 11 tarefas** — ⚠️ **ROI baixo.** Cada tarefa utiliza um runner separado e a verificação demora <1s; poupança total de ~10s, à custa da perda de uma salvaguarda económica por tarefa. Não justifica a perturbação. +- **`typecheck:noimplicit:core` no lint do CI** — ✅ **removido da tarefa lint** (era consultivo com `continue-on-error`); a superfície de tipos bloqueante é `typecheck:core` + `check:type-coverage`. Script local mantido. -### Inverter / decidir (política do operador) +### Ativar/desativar / decidir (política do operador) -- `check:openapi-security-tiers` (consultivo) — ❌ **NÃO pode ser simplesmente tornado bloqueante.** Termina com 0, mas avisa que várias rotas de `traffic-inspector` sob `LOCAL_ONLY_API_PREFIXES` não têm a anotação `x-loopback-only: true`. A sua aplicação obrigatória requer primeiro a adição dessas anotações a `openapi.yaml`. -- `typecheck:noimplicit:core` (consultivo) — amplamente substituído pelo mecanismo progressivo bloqueante `check:type-coverage`. Converter num mecanismo progressivo ou remover a segunda passagem redundante de `tsc`. -- `test:vitest:ui` (agora **bloqueante**) — as falhas preexistentes estão explicitamente excluídas em `vitest.config.ts` através de comentários de acompanhamento `// #8618`; novas falhas fazem a tarefa falhar. -- `check:secrets` (gitleaks, mecanismo progressivo bloqueante fixado em 3 falsos positivos documentados) — adicionar os 3 à lista de permissões para chegar a 0 ou despromover para consultivo. Sobrepõe-se à análise de segredos nativa do GitHub + `check:public-creds`. -- `check:pr-evidence` (bloqueante, procura padrões no texto do corpo do PR) — elevado risco de falsos positivos; a remoção enfraquece a aplicação da Regra Rígida #18, pelo que esta é uma verdadeira decisão de política. -- `semgrep` (autónomo consultivo) — sobrepõe-se ao CodeQL para as famílias OWASP; ligar o respetivo valor de referência a um mecanismo progressivo ou remover. +- `check:openapi-security-tiers` (consultivo) — ❌ **NÃO pode ser tornado bloqueante diretamente.** Termina com 0, mas avisa que várias rotas `traffic-inspector` sob `LOCAL_ONLY_API_PREFIXES` não possuem a anotação `x-loopback-only: true`. Torná-lo bloqueante exige primeiro adicionar essas anotações a `openapi.yaml`. +- `typecheck:noimplicit:core` (consultivo) — amplamente substituído pelo ratchet bloqueante `check:type-coverage`. Convertê-lo num ratchet ou remover a segunda passagem redundante do `tsc`. +- `test:vitest:ui` (agora **bloqueante**) — as falhas preexistentes são explicitamente excluídas em `vitest.config.ts` com comentários de acompanhamento `// #8618`; novas falhas fazem a tarefa falhar. +- `check:secrets` (gitleaks, ratchet bloqueante fixado em 3 falsos positivos documentados) — adicionar os 3 à lista de permissões para chegar a 0, ou despromover para consultivo. Sobrepõe-se à análise de segredos nativa do GitHub + `check:public-creds`. +- `check:pr-evidence` (bloqueante, procura padrões no texto do corpo do PR) — risco elevado de falsos positivos; a sua remoção enfraquece a aplicação da Regra Rígida #18, pelo que esta é uma verdadeira decisão de política. +- `semgrep` (consultivo autónomo) — sobrepõe-se ao CodeQL nas famílias OWASP; ligar a respetiva baseline a um ratchet ou remover. --- diff --git a/docs/i18n/ro/CONTRIBUTING.md b/docs/i18n/ro/CONTRIBUTING.md index 3d56a534472..70139ecaebe 100644 --- a/docs/i18n/ro/CONTRIBUTING.md +++ b/docs/i18n/ro/CONTRIBUTING.md @@ -391,18 +391,18 @@ Scrieți teste unitare în `tests/unit/` care să acopere cel puțin: - [ ] Testele trec (`npm test`) - [ ] Verificarea lint trece (`npm run lint`) -- [ ] Compilarea reușește (`npm run build`) +- [ ] Build-ul reușește (`npm run build`) - [ ] Au fost adăugate tipuri TypeScript pentru noile funcții și interfețe publice - [ ] Nu există secrete sau valori de rezervă codificate direct -- [ ] Credențialele publice upstream sunt încorporate prin `resolvePublicCred()` (consultați [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), niciodată ca valori literale +- [ ] Credențialele publice upstream sunt încorporate prin `resolvePublicCred()` (consultați [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), niciodată ca literali - [ ] Răspunsurile de eroare sunt procesate prin `buildErrorBody()` / `sanitizeErrorMessage()` — fără urme de stivă neprelucrate în corpurile răspunsurilor (consultați [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Comenzile shell (`exec` / `spawn`) transmit valorile din timpul execuției prin `env`, nu prin interpolarea șirurilor - [ ] Toate datele de intrare sunt validate cu scheme Zod -- [ ] A fost adăugat un **fragment** de jurnal al modificărilor în `changelog.d/{features|fixes|maintenance}/-.md` pentru modificările vizibile utilizatorilor (consultați [`changelog.d/README.md`](./changelog.d/README.md)) — **nu** editați direct `CHANGELOG.md`; fragmentele sunt agregate la momentul lansării și nu intră niciodată în conflict între PR-uri +- [ ] A fost adăugat un **fragment** de jurnal de modificări în `changelog.d/{features|fixes|maintenance}/-.md` pentru modificările vizibile utilizatorilor (consultați [`changelog.d/README.md`](./changelog.d/README.md)) — **nu** editați direct `CHANGELOG.md`; fragmentele sunt agregate la momentul lansării și nu intră niciodată în conflict între PR-uri - [ ] Documentația a fost actualizată (dacă este cazul) -- [ ] Nu au fost deschise alerte CodeQL / Secret-Scanning noi sau fiecare a fost respinsă cu o justificare tehnică ce face referire la documentul relevant din `docs/security/` -- [ ] Rutele care lansează procese copil (`/api/mcp/`, `/api/cli-tools/runtime/`) sunt clasificate ca `isLocalOnlyPath()` în `src/server/authz/routeGuard.ts` — consultați [Regula strictă nr. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Nu există trailere `Co-Authored-By` în mesajele commit-urilor — commit-urile trebuie să apară exclusiv sub identitatea Git a proprietarului depozitului (Regula strictă nr. 16) +- [ ] Nu au fost deschise alerte CodeQL / Secret-Scanning noi sau fiecare dintre acestea a fost respinsă cu o justificare tehnică ce face referire la documentul relevant din `docs/security/` +- [ ] Rutele care generează procese copil (`/api/mcp/`, `/api/cli-tools/runtime/`) sunt clasificate drept `isLocalOnlyPath()` în `src/server/authz/routeGuard.ts` — consultați [Regula strictă nr. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Mesajele de commit nu conțin trailere AI/bot `Co-authored-by` (Regula strictă nr. 16) — colaboratorii umani a căror muncă este reutilizată sunt creditați prin trailere standard `Co-authored-by: Name ` --- diff --git a/docs/i18n/ro/docs/architecture/QUALITY_GATES.md b/docs/i18n/ro/docs/architecture/QUALITY_GATES.md index 9834a73ae90..6878f162592 100644 --- a/docs/i18n/ro/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ro/docs/architecture/QUALITY_GATES.md @@ -15,225 +15,214 @@ pentru reproducerea aceluiași sistem, consultați --- -## Inventarul porților și profilurile de execuție +## Inventarul gate-urilor și profilurile de execuție ### Admiterea candidaților -Fluxurile de lucru CI și Quality Gates emit fiecare un verdict stabil: `Gate / CI` și +Fluxurile de lucru CI și Quality Gates emit fiecare câte un verdict stabil: `Gate / CI` și `Gate / Quality`. Politica lor de admitere versionată enumeră fiecare job din amonte -ca fiind obligatoriu sau consultativ. Un job obligatoriu aplicabil trebuie să reușească: -rezultatele lipsă, anulate, omise, în așteptare și necunoscute nu pot stabili un rezultat -PASS. O clasificare validă exclusiv pentru documentație sau exclusiv pentru catalog poate -face ca o pistă de cod să nu fie aplicabilă; un PR în stadiu de ciornă nu este un candidat -acceptat. O etichetă `hotfix` nu elimină cerința privind dovezile. - -Ambele fluxuri de lucru acoperă PR-urile și operațiunile push către ramurile main/release, -declanșarea manuală și evenimentele merge-group. Operațiunile push, declanșările și -grupurile de îmbinare execută selecția completă. Fork-urile și grupurile de îmbinare -utilizează runner-e găzduite pentru joburile care, în alte condiții, selectează runner-e -auto-găzduite; înainte de lansare trebuie verificată existența unei capacități găzduite -suficiente. - -Fiecare dovadă JSON identifică SHA-ul checkout-ului, execuția fluxului de lucru și -încercarea. CLI-ul respinge o neconcordanță între SHA-ul checkout-ului și cel al -evenimentului. Testele fluxului de lucru leagă apartenența la politică de lista `needs` -a jobului de verdict, astfel încât o pistă nouă sau eliminată să nu poată dispărea fără -a fi observată. Dovezile acoperă propriul flux de lucru, nu publicarea, implementarea -sau mecanismele interne ale unui scaner consultativ existent. Activarea ambelor nume -de verificare în regulile ramurii reprezintă o modificare administrativă separată; -adăugarea acestor joburi nu protejează în sine o ramură. +drept obligatoriu sau consultativ. Un job obligatoriu aplicabil trebuie să reușească: rezultatele +lipsă, anulate, omise, în așteptare și necunoscute nu pot stabili PASS. O clasificare validă +doar pentru documentație sau doar pentru catalog poate face ca o pistă de cod să fie neaplicabilă; +un PR în stare draft nu este un candidat acceptat. O etichetă `hotfix` nu elimină obligația dovezilor. + +Ambele fluxuri de lucru acoperă PR-urile și push-urile către ramurile main/release, declanșarea manuală și +evenimentele merge-group. Push-urile, declanșările și evenimentele merge-group rulează selecția completă. Fork-urile +și grupurile de îmbinare folosesc runneri găzduiți pentru joburile care altfel ar selecta runneri auto-găzduiți; +înainte de lansare trebuie verificată existența unei capacități găzduite suficiente. + +Fiecare chitanță JSON identifică SHA-ul checkout-ului, rularea fluxului de lucru și încercarea. +CLI-ul respinge o neconcordanță între SHA-ul checkout-ului și cel al evenimentului. Testele fluxului de lucru leagă apartenența la politică +de lista `needs` a jobului de verdict, astfel încât o pistă nouă sau eliminată să nu poată dispărea neobservată. +Chitanțele acoperă propriul flux de lucru, nu publicarea, implementarea sau mecanismele interne +ale unui scaner consultativ existent. Activarea ambelor nume de verificare în regulile ramurii reprezintă o +modificare administrativă separată; adăugarea acestor joburi nu protejează în sine o ramură. ### Inventarul scanării statice -Inventarul versionat de aliasuri npm și apartenența la scanarea statică se află în +Inventarul versionat al aliasurilor npm și apartenența la scanarea statică se află în `config/quality/gate-manifest.json`. Rulați `npm run check:gate-manifest` pentru a valida -numele scripturilor și comenzile exacte în raport cu `package.json`; adăugările, -eliminările și modificările comenzilor duc la eșuarea atât a hook-ului local, cât și a -joburilor de clasificare a modificărilor din CI. Un alias nu este un job al fluxului de -lucru, o instanță a matricei sau un caz de testare: aceste numărători nu trebuie +numele scripturilor și comenzile exacte în raport cu `package.json`; adăugările, eliminările și +abaterile comenzilor duc la eșecul atât al hook-ului local, cât și al joburilor de clasificare a modificărilor din CI. +Un alias nu este un job de flux de lucru, o instanță de matrice sau un caz de testare: aceste numărători nu trebuie prezentate ca fiind interschimbabile. Utilizați `npm run quality:scan -- --list` sau `npm run quality:scan:fast -- --list` -pentru a inspecta aliasurile selectate fără a le executa. Runner-ul invocă punctul de -intrare npm, astfel încât mediul său de execuție (inclusiv Bun, acolo unde este -configurat) este păstrat. Manifestul înregistrează aliasurile din afara acestor profiluri -ca fiind invocate separat, iar comenzile de mentenanță sunt interzise în profilurile de -scanare doar în citire. - -Aceste profiluri acoperă numai scanarea statică. Ele nu certifică testele produsului, -acoperirea, împachetarea, verificările externe sau acceptarea completă a unui candidat -pentru lansare. Admiterea în fluxul de lucru utilizează fișierele asociate -`config/quality/admission-policy.json` și `scripts/quality/admission-verdict.mjs`. -Profilurile release-observer rămân separate; inspectați independent verificările -aplicabile și dovezile acestora. Inventarul descriptiv de mai jos este o referință, -nu o dovadă că o poartă a fost executată efectiv. - -Scripturile se află în `scripts/check/` (porți pentru politici) și `scripts/quality/` -(motor de limitare progresivă). Sursa de adevăr pentru CI este `.github/workflows/ci.yml`. +pentru a inspecta aliasurile selectate fără a le executa. Runnerul invocă punctul de intrare +npm, astfel încât runtime-ul acestuia (inclusiv Bun, acolo unde este configurat) este păstrat. +Manifestul înregistrează aliasurile din afara acestor profiluri ca fiind invocate separat, iar +comenzile de întreținere sunt interzise în profilurile de scanare doar în citire. + +Aceste profiluri acoperă doar scanarea statică. Ele nu certifică testele produsului, +acoperirea, împachetarea, verificările externe sau acceptarea completă pentru lansare a unui candidat. +Admiterea fluxului de lucru utilizează fișierele asociate `config/quality/admission-policy.json` și +`scripts/quality/admission-verdict.mjs`. Profilurile release-observer rămân separate; +inspectați independent verificările și chitanțele aplicabile acestora. Inventarul +descriptiv de mai jos este o referință, nu o dovadă că un gate a fost executat efectiv. + +Scripturile se află în `scripts/check/` (gate-uri de politică) și `scripts/quality/` (motorul ratchet). +Sursa de adevăr pentru CI este `.github/workflows/ci.yml`. ### Calea rapidă pentru PR-uri de lansare (`quality.yml`) -`.github/workflows/quality.yml` completează CI pentru PR-urile către main/release, -operațiunile push către ramurile protejate, declanșările și grupurile de îmbinare. -PR-urile utilizează verificări rapide filtrate în funcție de căi. Compilarea duplicată -dezactivată permanent a fost eliminată; verificările reale de compilare, împachetare și -pornire rămân în CI. - -| Job | Domeniu de aplicare | Blocant | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `Docs Gates (fast-path)` | PR-uri de documentație/cod; referințe pentru documentația API și întreaga documentație | Da | -| `Fast Quality Gates` | PR-uri de cod; verificări statice, verificarea tipurilor, verificarea tipurilor pentru dashboard, teste unitare afectate | Da | -| `Forgotten sibling tests` | PR-uri de cod; modulele modificate sunt urmărite până la consumatorii statici și testele candidate înrudite; căile prin barrel-uri și importuri dinamice sunt raportate ca diagnostice consultative, cu excepțiile aferente din lista de permisiuni | **Consultativ** | -| `Vitest (fast-path)` | PR-uri de cod; suita rapidă vitest | Da | -| `Unit Tests fast-path` | PR-uri de cod; suită de teste unitare împărțită în 4 shard-uri | Da | -| `No new ESLint warnings` | PR-uri de cod; protecție lint care ține cont de suprimări | Da, inclusiv fork-uri | -| `Merge integrity (changelog + generated skills)` | PR-uri care nu sunt ciorne; sincronizarea jurnalului de modificări și a skill-urilor generate | Da, inclusiv fork-uri | - -#### Raport privind testele înrudite uitate - -`npm run check:forgotten-sibling-tests` reutilizează resolver-ul de importuri din spatele hărții -impactului asupra testelor. Pentru fiecare modul de producție modificat, acesta raportează -lanțuri deterministe `modul/simbol modificat -> consumator static -> test candidat înrudit` -atunci când testul candidat lipsește din diff-ul pull request-ului. Rezumatul Markdown și -rezultatul JSON sunt păstrate drept artefactul de flux de lucru `forgotten-sibling-tests` -pentru calibrare înainte de orice lansare cu caracter blocant. - -Re-exporturile de tip barrel și importurile dinamice sunt doar diagnostice de rezoluție; acestea nu creează niciodată o +`.github/workflows/quality.yml` completează CI pentru PR-urile către main/release, push-urile către ramuri +protejate, declanșările și grupurile de îmbinare. PR-urile utilizează verificări rapide filtrate după căi. Build-ul +duplicat dezactivat permanent a fost eliminat; verificările reale de build/împachetare/pornire rămân în CI. + +| Job | Domeniu de aplicare | Blocant | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- | +| `Docs Gates (fast-path)` | PR-uri de documentație/cod; referințe pentru documentația API și întreaga documentație | Da | +| `Fast Quality Gates` | PR-uri de cod; verificări statice, verificarea tipurilor, verificarea tipurilor pentru dashboard, teste unitare afectate | Da | +| `Forgotten sibling tests` | PR-uri de cod; modulele modificate sunt urmărite până la consumatorii statici și testele sibling candidate; căile prin barrel și importurile dinamice sunt raportate ca diagnostice consultative, cu excepțiile aferente din lista de permisiuni | **Consultativ** | +| `Vitest (fast-path)` | PR-uri de cod; suita rapidă vitest | Da | +| `Unit Tests fast-path` | PR-uri de cod; suită de teste unitare în 4 shard-uri | Da | +| `No new ESLint warnings` | PR-uri de cod; protecție lint care ține cont de suprimări | Da, inclusiv fork-uri | +| `Merge integrity (changelog + generated skills)` | PR-uri care nu sunt draft; sincronizarea jurnalului de modificări și a skill-urilor generate | Da, inclusiv fork-uri | + +#### Raportul privind testele sibling omise + +`npm run check:forgotten-sibling-tests` reutilizează resolverul de importuri folosit de harta impactului testelor. +Pentru fiecare modul de producție modificat, acesta raportează lanțuri deterministe +`modul/simbol modificat -> consumator static -> test sibling candidat` atunci când testul +candidat lipsește din diff-ul pull request-ului. Rezumatul Markdown și rezultatul JSON sunt păstrate ca +artefact al fluxului de lucru `forgotten-sibling-tests`, pentru calibrare înainte de orice lansare cu caracter blocant. + +Reexporturile de tip barrel și importurile dinamice sunt doar diagnostice de rezoluție; acestea nu creează niciodată o constatare blocantă. Excepțiile revizuite se află în -`config/quality/forgotten-sibling-allowlist.json`. Fiecare intrare trebuie să specifice testul consumator și testul candidat, -să ofere o justificare concretă și să includă un link către un issue sau pull request GitHub. Intrările incorecte determină -respingerea. Excepțiile nu pot suprima un test candidat șters sau un diff care adaugă `.skip`/`.todo`; -slăbirea aserțiunilor și alte forme de mascare rămân în responsabilitatea verificării blocante independente +`config/quality/forgotten-sibling-allowlist.json`. Fiecare intrare trebuie să specifice consumatorul și testul +candidat, să ofere o justificare specifică și să includă un link către un issue sau un pull request GitHub. Intrările incorecte +eșuează în mod închis. Excepțiile nu pot suprima un test candidat șters sau un diff care adaugă `.skip`/`.todo`; +slăbirea aserțiunilor și alte forme de mascare rămân în responsabilitatea porții blocante independente `check:test-masking`. ### Job: `lint` -Rulează pentru fiecare PR către `main`. Blochează îmbinarea în caz de eșec. - -| Script (`npm run ...`) | Validează | Blocant | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | Versiunea Node.js se află în intervalul acceptat | Da | -| `check:cycles` | Importuri circulare — toate modulele din `src/` + `open-sse/` | Da | -| `check:route-validation:t06` | Scheme Zod prezente pe toate rutele (politica Nivelului 6) | Da | -| `check:any-budget:t11` | Numărul de `@ts-expect-error // any` nu depășește bugetul (catraca Nivelului 11) | Da | -| `check:provider-consistency` | Fiecare furnizor din `providers.ts` are o intrare corespunzătoare în `providerRegistry.ts` (și invers, în cadrul listei de permisiuni) | Da | -| `check:model-lifecycle` | Cele trei tabele de rutare întreținute manual rămân consecvente cu instantaneul ciclului de viață inclus în depozit (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nu acordă niciun scor vreunui id retras pe care `REGISTRY` îl poate ruta; fiecare țintă din `BUILT_IN_ALIASES` este prezentă în `REGISTRY` și absentă din instantaneul id-urilor retrase; fiecare id retras încă prezent în `REGISTRY` este redirecționat sau enumerat în `allowedRetiredInCatalog`; și nicio sursă sau țintă din `DEFAULT_DEGRADATION_MAP` nu apare ca retrasă în acel instantaneu. Aceasta nu demonstrează că un model este deservit în prezent de un serviciu upstream activ. Offline — compară cu `config/quality/model-lifecycle.json`, reîmprospătat manual cu `npm run quality:refresh-model-lifecycle` (necesită rețea; nu este integrat în CI). `allowedRetiredInCatalog` este un mecanism incremental de reducere: adăugați o intrare numai împreună cu o problemă de urmărire. | Da | -| `check:fetch-targets` | Fiecare `fetch("/api/...")` din `src/` de partea clientului se rezolvă la un fișier `route.ts` real | Da | -| `check:deps` | Toate dependențele care pot fi instalate cu `npm install` din fiecare `package.json` din depozit se află în `dependency-allowlist.json`; pachetele noi fără versiune fixată sau care pot reprezenta tentative de slopsquatting sunt semnalate | Da | -| `audit:deps` | `npm audit` (rădăcină + electron) — fără avertismente cu severitate ridicată/critică (se suprapune cu `check:vuln-ratchet` din osv; consultați Registrul restant de raționalizare) | Da | -| `check:lockfile` | Integritatea `package-lock.json` — registru https, hash-uri de integritate, fără suprascrieri ale gazdei | Da | -| `check:licenses` | Lista de permisiuni pentru licențe SPDX aferentă dependențelor de producție | Da | -| `check:tracked-artifacts` | Fără artefacte de build / linkuri simbolice `node_modules` incluse în commituri (rulează și în etapa husky pre-commit; pre-push este intenționat minimal — #6716) | Da | -| `check:ai-attribution` | Fără trailer `Co-Authored-By` atribuit AI-ului/unui bot sau subsol privind generarea cu AI în commiturile, titlul sau corpul PR-ului — Regula strictă #16 (în bucla de verificări rapide `quality.yml` pentru PR→`release/**` — citește payloadul evenimentului, nu efectuează nicio operație în afara PR-urilor — și într-un pas exclusiv pentru PR-uri în verificarea lint din `ci.yml` pentru PR→`main`; de asemenea, în hook-ul husky `commit-msg`; coautorii umani sunt permiși; #14436) | -| `check:vitest-exclusions` | Fiecare excludere Vitest menționează un issue de urmărire și apare în `config/quality/vitest-exclusions.json` (#13204) | Da | -| `check:file-size` | Niciun fișier sursă nu depășește limita specifică extensiei (ratchet: fișierele mari înghețate se află în lista `frozen`) | Da | -| `check:error-helper` | Răspunsurile de eroare din executori/handlere utilizează `buildErrorBody()` / `sanitizeErrorMessage()` (Regula strictă #12) | Da | -| `check:migration-numbering` | Fișierele SQL de migrare sunt numerotate secvențial, fără goluri sau duplicate | Da | -| `check:public-creds` | Nu există valori OAuth literale pentru `client_id`/`client_secret` sau chei Firebase Web în afara `publicCreds.ts` (Regula strictă nr. 11) | Da | -| `check:db-rules` | Nu există SQL brut în afara modulelor `src/lib/db/`; nu există importuri de tip barrel din `localDb.ts` (Regulile stricte nr. 2/nr. 5) | Da | -| `check:known-symbols` | Executorii furnizorilor, strategiile de rutare și translatoarele înregistrate în tabelele lor de dispecerizare corespund fișierelor de pe disc — fără simboluri orfane sau nedeclarate | Da | -| `check:route-guard-membership` | Fiecare rută care lansează un proces copil este clasificată de `isLocalOnlyPath()` (Regulile stricte nr. 15/nr. 17) | Da | -| `check:test-discovery` | Fiecare fișier `*.test.ts` / `*.spec.ts` din depozit este colectat de cel puțin un executor de teste (ratchet: lista fișierelor orfane din `test-discovery-baseline.json` poate doar să se micșoreze) | Da | -| `check:agent-skills-sync` | Artefactele generate pentru agent-skills corespund catalogului sursă (fără divergențe) | -| `check:provider-asset-provenance` | Siglele/resursele furnizorilor au o înregistrare de proveniență | -| `lint:json` | Fișierele de configurare JSON sunt analizate cu succes și respectă regulile de lint ale depozitului | -| `typecheck:core` | Compilare TypeScript fără erori (doar avertismente consultative) | Da | -| `typecheck:noimplicit:core` | Verificare strictă `noImplicitAny` — orientată spre viitor; multe locuri de apel preexistente necesită încă adnotări | **Consultativ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` limitat la `src/app/(dashboard)/**` (#7033) — lista atent selectată de 27 de fișiere a `typecheck:core` nu include niciun fișier TSX din dashboard, iar `next build` nu efectuează niciodată verificarea tipurilor pentru acestea (`next.config.mjs` setează `ignoreBuildErrors: true`), astfel încât regresiile privind identificatorii orfani de acolo (#6625/#6909) erau invizibile pentru CI. Compară cu o bază de referință înghețată a numărului de erori pentru fiecare fișier/cod TS (`config/quality/dashboard-typecheck-baseline.json`, același model de impunere pentru intrările învechite ca la `check:known-symbols`) — numai erorile NOI care depășesc numărul din baza de referință fac ca verificarea să eșueze; reduceți treptat baza cu `--update` atunci când este remediată o eroare preexistentă. | Da | - -### Job: `quality-gate` +Rulează la fiecare PR către `main`. Blochează îmbinarea în caz de eșec. + +| Script (`npm run ...`) | Validează | Blocant | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | Versiunea Node.js se află în intervalul acceptat | Da | +| `check:cycles` | Importurile circulare din întregul `src/` + `open-sse/` (bazat pe AST, cu `paths` din tsconfig rezolvate). Rularea simplă = informativă, listează ciclurile. `check:cycles:ratchet` (ceea ce rulează CI) blochează atunci când numărul depășește pragul `metrics.cycles` din `quality-baseline.json` — în prezent 14, `direction: down`, deci poate doar să scadă (#15159 G-01/G-02) | Da (catracă) | +| `check:route-validation:t06` | Scheme Zod prezente pe toate rutele (politica Nivelului 6) | Da | +| `check:any-budget:t11` | Numărul de `@ts-expect-error // any` nu depășește bugetul (catracă de Nivel 11) | Da | +| `check:provider-consistency` | Fiecare furnizor din `providers.ts` are o intrare corespunzătoare în `providerRegistry.ts` (și invers, în limitele listei de permisiuni) | Da | +| `check:model-lifecycle` | Cele trei tabele de rutare întreținute manual rămân consecvente cu instantaneul ciclului de viață inclus în depozit (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nu acordă un scor niciunui id retras pe care `REGISTRY` îl poate ruta; fiecare destinație `BUILT_IN_ALIASES` este prezentă în `REGISTRY` și absentă din instantaneul id-urilor retrase; fiecare id retras încă prezent în `REGISTRY` este redirecționat sau enumerat în `allowedRetiredInCatalog`; și nicio sursă sau destinație din `DEFAULT_DEGRADATION_MAP` nu apare ca fiind retrasă în instantaneul respectiv. Acest lucru nu dovedește că un model este furnizat în prezent de un serviciu upstream activ. Offline — compară cu `config/quality/model-lifecycle.json`, actualizat manual prin `npm run quality:refresh-model-lifecycle` (necesită rețea; nu este integrat în CI). `allowedRetiredInCatalog` este un mecanism cu limitare progresivă: adăugați o intrare numai împreună cu o problemă de urmărire. | Da | +| `check:fetch-targets` | Fiecare `fetch("/api/...")` din `src/` pe partea de client se rezolvă către un `route.ts` real | Da | +| `check:deps` | Toate dependențele instalabile prin `npm install` din fiecare `package.json` al depozitului se află în `dependency-allowlist.json`; pachetele noi fără versiune fixată sau care imită numele altor pachete sunt semnalate | Da | +| `audit:deps` | `npm audit` (rădăcină + electron) — fără avertismente de severitate ridicată/critică (se suprapune cu `check:vuln-ratchet` din osv; consultați restanțele de raționalizare) | Da | +| `check:lockfile` | Integritatea fișierului `package-lock.json` — registru https, hash-uri de integritate, fără înlocuiri ale gazdei | Da | +| `check:licenses` | Listă de permisiuni pentru licențele SPDX ale dependențelor de producție | Da | +| `check:tracked-artifacts` | Fără artefacte de compilare / linkuri simbolice `node_modules` incluse în commituri (rulează și în pre-commit-ul husky; pre-push este intenționat simplificat — #6716) | Da | +| `check:ai-attribution` | Fără trailer AI/bot `Co-Authored-By` sau subsol privind generarea prin AI în commiturile, titlul sau corpul PR-ului — Regula strictă #16 (în bucla de verificări rapide din `quality.yml` pentru PR→`release/**` — citește conținutul evenimentului, nu efectuează nicio operație în afara PR-urilor — și ca pas exclusiv pentru PR-uri în verificarea lint din `ci.yml` pentru PR→`main`; de asemenea, hook-ul husky `commit-msg`; coautorii umani sunt permiși; #14436) | +| `check:vitest-exclusions` | Fiecare excludere Vitest indică o problemă de urmărire și apare în `config/quality/vitest-exclusions.json` (#13204) | Da | +| `check:file-size` | Niciun fișier sursă nu depășește limita specifică extensiei (mecanism cu prag progresiv: fișierele mari blocate sunt în lista `frozen`) | Da | +| `check:error-helper` | Răspunsurile de eroare din executori/gestionare folosesc `buildErrorBody()` / `sanitizeErrorMessage()` (Regula strictă #12) | Da | +| `check:migration-numbering` | Fișierele SQL de migrare sunt numerotate secvențial, fără întreruperi sau duplicate | Da | +| `check:public-creds` | Nu există valori literale OAuth `client_id`/`client_secret` sau chei Firebase Web în afara `publicCreds.ts` (Regula strictă nr. 11) | Da | +| `check:db-rules` | Nu există SQL brut în afara modulelor `src/lib/db/`; nu există importuri de tip barrel din `localDb.ts` (Regulile stricte nr. 2/nr. 5) | Da | +| `check:known-symbols` | Executorii furnizorilor, strategiile de rutare și translatoarele înregistrate în tabelele lor de expediere corespund fișierelor de pe disc — fără simboluri orfane sau nedeclarate | Da | +| `check:route-guard-membership` | Fiecare rută care generează un proces copil este clasificată de `isLocalOnlyPath()` (Regulile stricte nr. 15/nr. 17) | Da | +| `check:test-discovery` | Fiecare fișier `*.test.ts` / `*.spec.ts` din depozit este colectat de cel puțin un executor de teste (ratchet: lista de fișiere orfane din `test-discovery-baseline.json` poate doar să se restrângă) | Da | +| `check:agent-skills-sync` | Artefactele agent-skills generate corespund catalogului lor sursă (fără divergențe) | +| `check:provider-asset-provenance` | Siglele/activele furnizorilor au o înregistrare de proveniență | +| `lint:json` | Fișierele de configurare JSON sunt analizate cu succes și respectă regulile de linting ale depozitului | +| `typecheck:core` | Compilare TypeScript fără erori (doar avertismente consultative) | Da | +| `typecheck:noimplicit:core` | `noImplicitAny` strict — orientat spre viitor; multe locuri de apelare preexistente necesită încă adnotări | **Consultativ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` limitat la `src/app/(dashboard)/**` (#7033) — lista atent selectată de 27 de fișiere a `typecheck:core` nu include niciun fișier TSX al tabloului de bord, iar `next build` nu efectuează niciodată verificarea tipurilor pentru acesta (`next.config.mjs` setează `ignoreBuildErrors: true`), astfel încât regresiile privind identificatorii orfani de acolo (#6625/#6909) erau invizibile pentru CI. Compară cu o bază de referință înghețată a numărului de erori per fișier/per cod TS (`config/quality/dashboard-typecheck-baseline.json`, același model de aplicare pentru elemente învechite ca `check:known-symbols`) — doar erorile NOI care depășesc numărul din baza de referință determină eșecul verificării; reduceți treptat baza cu `--update` atunci când este remediată o eroare preexistentă. | Da | + +### Sarcină: `quality-gate` Rulează după `test-coverage`. Blochează îmbinarea în caz de eșec. -| Script | Validează | Blocant | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | -| `quality:collect` | Generează `quality-metrics.json` (numărul de avertismente ESLint, acoperirea din raportul combinat al fragmentelor) | Da (în amonte față de ratchet) | -| `quality:ratchet` | Nicio metrică din `quality-baseline.json` nu a regresat (avertismente ESLint ≤ valoarea de referință; acoperire ≥ valoarea de referință) | Da | -| `check:duplication` | Duplicarea codului (jscpd@4) nu depășește valoarea de referință din `quality-baseline.json` | Da | -| `check:complexity` | Complexitatea ciclomatică la nivel de fișier nu depășește limita (regulile ESLint de bază `complexity` + `max-lines-per-function`) | Da | -| `check:cognitive-complexity` | Pragul progresiv pentru complexitatea cognitivă (`eslint-plugin-sonarjs`) — rulare ESLint separată; CI le rulează pe ambele, combinate în pasul unic `check:complexity-ratchets` | Da | -| `check:dead-code` | Pragul progresiv pentru exporturile/fișierele neutilizate (knip) nu regresează față de valoarea de referință | Da | -| `check:compression-budget` | Bugetul pentru testul de performanță al compresiei — pragurile minime de economisire a tokenurilor pentru fiecare motor nu trebuie să regreseze | Da | -| `check:type-coverage` | Pragul progresiv al procentului de cod tipizat (`type-coverage`) nu regresează; în mare parte înlocuiește `typecheck:noimplicit:core` | Da | -| `check:codeql-ratchet` | Numărul alertelor CodeQL deschise nu regresează (citit prin `gh api`; omitere controlată fără token) — pentru frecvența actualizării și declanșarea manuală: consultați „Pragul progresiv CodeQL” de mai jos | Da | +| Script | Validează | Blocant | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `quality:collect` | Generează `quality-metrics.json` (numărul de avertismente ESLint, acoperirea din raportul combinat al shard-urilor) | Da (în amonte față de mecanismul ratchet) | +| `quality:ratchet` | Fiecare metrică din `quality-baseline.json` nu a regresat (avertismente ESLint ≤ valoarea de referință; acoperire ≥ valoarea de referință) | Da | +| `check:duplication` | Duplicarea codului (jscpd@4) nu depășește valoarea de referință din `quality-baseline.json` | Da | +| `check:complexity` | Complexitatea ciclomatică la nivel de fișier nu depășește limita (regulile ESLint de bază `complexity` + `max-lines-per-function`) | Da | +| `check:cognitive-complexity` | Mecanism ratchet pentru complexitatea cognitivă (`eslint-plugin-sonarjs`) — rulare ESLint separată; CI le execută pe ambele, reunite într-un singur pas `check:complexity-ratchets` | Da | +| `check:dead-code` | Mecanismul ratchet pentru exporturile/fișierele neutilizate (knip) nu regresează față de valoarea de referință | Da | +| `check:compression-budget` | Bugetul benchmarkului de compresie — pragurile minime ale economiilor de tokenuri pentru fiecare motor nu trebuie să regreseze | Da | +| `check:type-coverage` | Mecanismul ratchet pentru procentul de cod tipizat (`type-coverage`) nu regresează; în mare parte, îl înlocuiește pe `typecheck:noimplicit:core` | Da | +| `check:codeql-ratchet` | Numărul alertelor CodeQL deschise nu regresează (citire prin `gh api`; omitere controlată fără token) — pentru frecvența actualizării și declanșarea manuală: consultați „CodeQL ratchet” mai jos | Da | ### Job: `quality-extended` -Întregul job are caracter consultativ (`continue-on-error: true`). Pragurile progresive bazate pe npm rulează -efectiv; scanerele externe se instalează prin `gh release download` și se omit automat (cod de ieșire 0) -atunci când un binar este încă absent. +Întregul job are caracter consultativ (`continue-on-error: true`). Mecanismele ratchet bazate pe npm rulează +efectiv; scanerele externe se instalează prin `gh release download` și se omit automat (exit 0) +atunci când un binar continuă să lipsească. -| Script | Validează | Caracter blocant | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | -| `check:circular-deps` | Nu există dependențe circulare (dpdm) | **Consultativ** | -| `check:bundle-size` | Dimensiunea pachetului nu depășește limita | **Consultativ** | -| `check:secrets` | Scanarea secretelor (gitleaks) — este omisă dacă binarul lipsește | **Consultativ** | -| `check:vuln-ratchet` | Vulnerabilitățile dependențelor (osv-scanner) nu regresează — verificarea este omisă dacă binarul lipsește | **Consultativ** | -| `check:workflows` | Verificarea lint a fluxurilor de lucru (actionlint + zizmor); scanerele lipsă/defecte, rapoartele nevalide sau absența valorii de referință pentru pragul progresiv produc starea INCOMPLET. Constatările valide urmează politica strictă/consultativă/cu prag progresiv selectată | Execuție obligatorie; pragul progresiv zizmor este blocant în CI | -| `check:openapi-breaking` | Modificări incompatibile ale contractului API public (`openapi.yaml`) față de ramura de bază (oasdiff) — generează `openapiBreaking=N`; verificarea este omisă dacă oasdiff lipsește sau specificația de bază nu poate fi rezolvată | **Consultativ** | +| Script | Validează | Blocant | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| `check:circular-deps` | Nu există dependențe circulare (dpdm) | **Consultativ** | +| `check:bundle-size` | Dimensiunea bundle-ului nu depășește limita | **Consultativ** | +| `check:secrets` | Scanarea secretelor (gitleaks) — se omite dacă binarul lipsește | **Consultativ** | +| `check:vuln-ratchet` | Vulnerabilitățile dependențelor (osv-scanner) nu regresează — se omite dacă binarul lipsește | **Consultativ** | +| `check:workflows` | Lint pentru workflow-uri (actionlint + zizmor); scanerele lipsă/defecte, rapoartele nevalide sau absența valorii de referință pentru mecanismul ratchet eșuează cu INCOMPLETE. Constatările valide urmează politica strictă/consultativă/ratchet selectată | Execuție obligatorie; mecanismul ratchet zizmor este blocant în CI | +| `check:openapi-breaking` | Modificări incompatibile ale contractului API public (`openapi.yaml`) față de ramura de bază (oasdiff) — generează `openapiBreaking=N`; se omite dacă oasdiff lipsește sau specificația de bază nu poate fi rezolvată | **Consultativ** | ### Job: `docs-sync-strict` Rulează pentru fiecare PR către `main`. Blochează îmbinarea în caz de eșec. -| Script | Validează | Blocant | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | Metapoartă care rulează secvențial cele 6 subporți de mai jos | Da | -| ↳ `check:docs-sync` | Consecvența versiunilor din CHANGELOG / OpenAPI / llm.txt | Da | -| ↳ `check:docs-counts` | Valorile numerice din text (numărul de furnizori, numărul de migrări etc.) se încadrează în intervalul permis față de valorile reale | Da | -| ↳ `check:env-doc-sync` | Fiecare variabilă de mediu din `.env.example` este documentată într-un tabel din documentație și viceversa | Da | -| ↳ `check:deprecated-versions` | Nu există șiruri de versiune depreciate în documentație | Da | -| ↳ `check:doc-links` | Linkurile markdown interne din documentație trimit la fișiere reale (formatul `[text]`/`(path)`) | Da | -| ↳ `check:fabricated-docs` | Rutele, variabilele de mediu, comenzile CLI, numele hook-urilor și căile de fișiere menționate în documentație există în baza de cod. Poartă strictă prin `--strict`; eșec neblocant fără acest indicator. | Da (prin `--strict` în CI) | -| `check:cli-i18n` | Șirurile comenzilor CLI sunt prezente în toate fișierele de localizare i18n | Da | -| `check:openapi-coverage` | Specificația OpenAPI acoperă cel puțin un prag ajustat progresiv al rutelor reale | Da | -| `check:openapi-security-tiers` | Adnotările nivelurilor de securitate din `openapi.yaml` sunt consecvente cu clasificările din `routeGuard.ts` | **Consultativ** | -| `check:openapi-routes` | Fiecare cale din `openapi.yaml` corespunde unui fișier `route.ts` real (prevenirea halucinațiilor) | Da | -| `check:docs-symbols` | Fiecare referință `/api/...` din `docs/**/*.md` corespunde unui fișier `route.ts` real (prevenirea halucinațiilor) | Da | -| `i18n translation drift` | Chei netraduse în fișierele de localizare i18n — doar avertisment | **Consultativ** | +| Script | Validează | Blocant | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | Meta-poartă care rulează secvențial cele 6 sub-porți de mai jos | Da | +| ↳ `check:docs-sync` | Consecvența versiunilor din CHANGELOG / OpenAPI / llm.txt | Da | +| ↳ `check:docs-counts` | Valorile numerice din text (numărul de furnizori, numărul de migrări etc.) se încadrează în intervalul de ajustare progresivă al valorilor reale | Da | +| ↳ `check:env-doc-sync` | Fiecare variabilă de mediu din `.env.example` este documentată într-un tabel din documentație și invers | Da | +| ↳ `check:deprecated-versions` | Nu există șiruri de versiune perimate în documentație | Da | +| ↳ `check:doc-links` | Linkurile markdown interne din documentație indică fișiere reale (forma `[text]`/`(path)`) | Da | +| ↳ `check:fabricated-docs` | Rutele, variabilele de mediu, comenzile CLI, numele hook-urilor și căile de fișiere menționate în documentație există în baza de cod. Poartă strictă prin `--strict`; eșec neblocant fără opțiune. | Da (prin `--strict` în CI) | +| `check:cli-i18n` | Șirurile comenzilor CLI sunt prezente în toate fișierele de localizare i18n | Da | +| `check:openapi-coverage` | Specificația OpenAPI acoperă cel puțin un prag ajustat progresiv al rutelor reale | Da | +| `check:openapi-security-tiers` | Adnotările nivelurilor de securitate din `openapi.yaml` sunt consecvente cu clasificările din `routeGuard.ts` | **Consultativ** | +| `check:openapi-routes` | Fiecare cale din `openapi.yaml` corespunde unui fișier `route.ts` real (anti-halucinație) | Da | +| `check:docs-symbols` | Fiecare referință `/api/...` din `docs/**/*.md` corespunde unui fișier `route.ts` real (anti-halucinație) | Da | +| `i18n translation drift` | Chei netraduse în fișierele de localizare i18n — doar avertizare | **Consultativ** | ### Job: `i18n-ui-coverage` -| Script | Validează | Blocant | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (inline) | Acoperirea cheilor i18n din interfața cu utilizatorul este ≥ 65% | Da | -| `check-ui-value-drift` (inline) | O **valoare** în limba engleză care a fost rescrisă nu lasă în urmă nicio traducere învechită | Da | -| `check-new-key-coverage` (inline) | O cheie **nouă** în limba engleză este tradusă în fiecare localizare — un marcaj `__MISSING__:` este respins | Da | -| `check-translation-ratio` | Raportul traducerilor reale pentru fiecare localizare (valori identice cu cele în engleză / substituenți / elemente lipsă din afara listei de excluderi) nu trebuie să depășească `config/quality/i18n-translation-baseline.json` + marja permisă | **Consultativ** | +| Script | Validează | Blocant | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (inline) | Acoperirea cheilor i18n din interfața cu utilizatorul este ≥ 65% | Da | +| `check-ui-value-drift` (inline) | O **valoare** în engleză rescrisă nu lasă în urmă nicio traducere învechită | Da | +| `check-new-key-coverage` (inline) | O cheie **nouă** în engleză este tradusă în fiecare localizare — un marcaj `__MISSING__:` este respins | Da | +| `check-translation-ratio` | Raportul traducerilor reale pentru fiecare localizare (valori identice cu engleza / substituenți / elemente lipsă din afara listei de permisiuni) nu trebuie să depășească `config/quality/i18n-translation-baseline.json` + marja | **Consultativ** | -Necesită `fetch-depth: 0` — poarta pentru detectarea valorilor învechite compară diferențele dintre `en.json` și baza îmbinării. +Necesită `fetch-depth: 0` — poarta pentru detectarea valorilor învechite compară `en.json` cu baza de îmbinare. #### `check-ui-value-drift` — poartă pentru traduceri învechite -Detectează singura regresie i18n pe care celelalte porți nu o pot identifica structural: o valoare în limba engleză -este rescrisă, iar traducerile derivate din textul englezesc _anterior_ rămân neschimbate, astfel încât -utilizatorii care nu folosesc limba engleză continuă să citească un text formulat cu încredere, dar care acum este greșit. +Detectează acea regresie i18n pe care celelalte porți nu o pot identifica structural: o valoare în engleză +este rescrisă, iar traducerile derivate din textul în engleză _anterior_ rămân neschimbate, astfel încât +utilizatorii care nu folosesc limba engleză continuă să citească un text formulat cu încredere, dar acum incorect. -Acest lucru a ajuns efectiv în producție. `oauthModal.googleOAuthWarning` a fost rescris când a fost introdus -asistentul de autentificare Antigravity (#5203); **39 din 43 de localizări** au păstrat textul care le spunea operatorilor să „copieze -adresa URL completă și să o lipească mai jos” — un flux care nu poate fi finalizat pentru furnizorul respectiv. Problema a rămas -neobservată până la #8463 deoarece: +Acest lucru s-a întâmplat efectiv în producție. `oauthModal.googleOAuthWarning` a fost rescris când a fost +introdus utilitarul de autentificare Antigravity (#5203); **39 dintre cele 43 de localizări** au păstrat textul +care le spunea operatorilor să „copieze URL-ul complet și să îl lipească mai jos” — un flux care nu poate fi +finalizat pentru furnizorul respectiv. Problema a trecut neobservată până la #8463 deoarece: -- `sync-ui-keys` completează doar cheile care sunt **absente**, niciodată pe cele care sunt **învechite**; +- `sync-ui-keys` completează doar cheile care sunt **absente**, niciodată pe cele **învechite**; - `check-ui-keys-coverage` numără _prezența_ cheilor, astfel încât o traducere învechită este considerată acoperită; - `check-translation-drift` urmărește copiile documentației din `docs/i18n//**.md` — - nu citește niciodată `src/i18n/messages/*.json`. Este blocant în jobul `docs-sync-strict` începând cu - resincronizarea din 2026-09: editați un document principal → `npm run i18n:run -- --files=` (la nivel de secțiune, cu cost redus). + nu citește niciodată `src/i18n/messages/*.json`. Blocant în jobul `docs-sync-strict` începând cu + resincronizarea din 2026-09: modificați un document de bază → `npm run i18n:run -- --files=` (la nivel de secțiune, cu cost redus). -**Conștient de diff, nu bazat pe un baseline.** Compară `en.json` de la baza îmbinării cu -arborele de lucru; pentru fiecare cheie a cărei valoare în engleză s-a modificat, orice localizare -care încă păstrează o traducere neatinsă este învechită. Aceasta **îngheață intenționat datoria preexistentă** — un diff -nu poate dezvălui din ce versiune veche în engleză provine o traducere existentă de mult timp, astfel încât verificarea evaluează -doar ceea ce este afectat de modificarea curentă. Alternativa (un baseline cu hash pentru fiecare cheie) ar necesita -un fișier generat de ~600 KB, de 3× mai mare decât cel mai mare baseline existent, modificat la fiecare PR i18n. +**Conștient de diff, fără suportul unei baze de referință.** Compară `en.json` de la baza îmbinării cu +arborele de lucru; pentru fiecare cheie a cărei valoare în engleză s-a modificat, orice localizare care încă păstrează o +traducere nemodificată este învechită. Acest lucru **îngheață în mod deliberat datoria preexistentă** — un diff +nu poate dezvălui din ce versiune veche în engleză provine o traducere existentă de mult timp, astfel că verificarea evaluează +doar ceea ce atinge modificarea curentă. Alternativa (o bază de referință cu hash pentru fiecare cheie) ar necesita +un fișier generat de aproximativ 600 KB, de 3 ori mai mare decât cea mai mare bază de referință existentă, care s-ar modifica la fiecare PR de i18n. -Există două modalități de a trece verificarea: +Există două modalități de a îndeplini cerința: 1. actualizați traducerile afectate sau -2. setați-le la `__MISSING__:` — în acest caz, runtime-ul furnizează textul corectat în engleză - (`src/i18n/request.ts::deepMergeFallback`, #7258), iar cheia este adăugată în coada pentru traducere. +2. setați-le la `__MISSING__:` — la rulare va fi furnizat apoi textul corectat în engleză + (`src/i18n/request.ts::deepMergeFallback`, #7258), iar cheia va fi pusă în coada pentru traducere. -Dacă s-a schimbat **sensul** șirului, este preferabil să **redenumiți cheia**: o cheie nouă nu poate moșteni +Dacă **sensul** șirului s-a schimbat, preferați **redenumirea cheii**: o cheie nouă nu poate moșteni o traducere învechită. Acesta este modelul utilizat de #8463. ```bash @@ -242,12 +231,12 @@ npm run i18n:check-value-drift:warn # doar raportare BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Se încheie cu 0 și `SKIP reason=base-unresolved` atunci când catalogul de bază nu poate fi citit (clonă -superficială fără referința de bază), reflectând comportamentul `check-openapi-breaking`. +Se încheie cu codul 0 și `SKIP reason=base-unresolved` atunci când catalogul de bază nu poate fi citit (clonă +superficială fără referința de bază), similar cu `check-openapi-breaking`. ### Job: `i18n` -Matrice completă de validare i18n (câte un job pentru fiecare localizare). Întregul job este consultativ. +Matrice completă de validare i18n (un job pentru fiecare localizare). Întregul job are caracter consultativ. | Script | Validează | Blocant | | ------------------------------- | ---------------------------------------- | --------------------------------------------------------------- | @@ -255,7 +244,7 @@ Matrice completă de validare i18n (câte un job pentru fiecare localizare). În ### Job: `pr-test-policy` -Rulează numai pentru cererile de tip pull. +Rulează numai pentru pull request-uri. | Script | Validează | Blocant | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | @@ -267,23 +256,23 @@ Rulează numai pentru cererile de tip pull. Rulează după `build`. Blochează îmbinarea în caz de eșec. -| Suită | Validează | Blocant | -| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | Serverul MCP (110 instrumente), autoCombo, cache — runner vitest | Da | -| `test:vitest:ui` | Testele componentelor UI — runner vitest | **Blocant** — eșecurile preexistente sunt excluse explicit în `vitest.config.ts`; eșecurile noi determină eșecul jobului | +| Suită | Validează | Blocant | +| ---------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Serverul MCP (110 instrumente), autoCombo, cache — executor vitest | Da | +| `test:vitest:ui` | Testele componentelor UI — executor vitest | **Blocant** — eșecurile preexistente sunt excluse explicit în `vitest.config.ts`; eșecurile noi provoacă eșecul jobului | ### Fluxuri de lucru nocturne (programate, consultative) -Acestea rulează conform unei programări cron (și prin `workflow_dispatch`), niciodată pentru PR-uri. Toate sunt consultative. +Acestea rulează conform unei programări cron (și prin `workflow_dispatch`), niciodată pentru PR-uri. Toate au caracter consultativ. -| Flux de lucru | Validează | Blocant | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | teste bazate pe proprietăți fast-check, cu seed aleatoriu și un număr mare de rulări | **Consultativ** | -| `nightly-resilience` | verificarea creșterii heap-ului, injectarea haotică a defecțiunilor, teste k6 de încărcare/anduranță | **Consultativ** | -| `nightly-llm-security` | protecție promptfoo împotriva injecțiilor (mod de blocare) + sonde garak (omise în lipsa unui secret pentru furnizor) | **Consultativ** | -| `nightly-schemathesis` | fuzzing al contractului OpenAPI (schemathesis) pe o instanță OmniRoute activă, utilizând `docs/openapi.yaml` — evidențiază încălcări ale specificației / erori 500 negestionate (Faza 8 B.4) | **Consultativ** | -| `nightly-mutation` | scorul testării prin mutații Stryker pentru culoarul rapid de teste unitare — mutanții supraviețuitori evidențiază aserțiuni slabe | **Consultativ** | -| `nightly-compat` | matricea de compatibilitate a motorului Node pentru intervalele `engines.node` acceptate | **Consultativ** | +| Flux de lucru | Validează | Blocant | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `nightly-property` | Teste bazate pe proprietăți fast-check, cu seed aleatoriu și număr mare de rulări | **Consultativ** | +| `nightly-resilience` | Verificarea creșterii heap-ului, injectarea haotică a defecțiunilor, teste k6 de încărcare/anduranță | **Consultativ** | +| `nightly-llm-security` | Protecție promptfoo împotriva injecțiilor (mod de blocare) + sonde garak (omise în lipsa unui secret pentru furnizor) | **Consultativ** | +| `nightly-schemathesis` | Fuzzing al contractului OpenAPI (schemathesis) pe o instanță OmniRoute activă, folosind `docs/openapi.yaml` — evidențiază încălcările specificației / erorile 500 negestionate (Faza 8 B.4) | **Consultativ** | +| `nightly-mutation` | Scorul testării prin mutații Stryker pentru fluxul rapid de teste unitare — mutanții supraviețuitori evidențiază aserțiunile slabe | **Consultativ** | +| `nightly-compat` | Matricea de compatibilitate a motorului Node pentru intervalele `engines.node` acceptate | **Consultativ** | --- @@ -547,44 +536,43 @@ eroare de conexiune și nu întrerupe niciodată sesiunile. --- -## Restanțe de raționalizare (revizuire ROI — Faza 9 Valul 3) +## Restanțe de raționalizare (analiză ROI — Faza 9 Valul 3) Acest inventar a fost reconciliat cu `ci.yml` la 2026-06-17 (versiunea anterioară omitea `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). O revizuire ROI a setului reconciliat +`check:codeql-ratchet`, `check:pr-evidence`). O analiză ROI a setului reconciliat a identificat următorii candidați pentru raționalizare. **Comasările sunt modificări CI -mecanice; activările/dezactivările sunt decizii de politică rezervate operatorului.** Nimic din cele de mai jos +mecanice; schimbările de stare/eliminările sunt decizii de politică rezervate operatorului.** Nimic din cele de mai jos nu este aplicat încă. **De asemenea, nedocumentate mai sus** (consultative, semnal slab): jobul `docs-lint` -(markdownlint + Vale, întregul job cu `continue-on-error`) și fluxurile de lucru autonome pentru scanare +(markdownlint + Vale, întregul job având `continue-on-error`) și fluxurile de lucru autonome de scanare `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` se află în -`quality-baseline.json`, dar nu este conectat la un mecanism de blocare bazat pe prag în `ci.yml` — metrica este +`quality-baseline.json`, dar nu este conectat la un prag incremental blocant în `ci.yml` — metrica este în prezent orfană. -### Comasare / deduplicare (mecanică, risc mai scăzut) +### Comasare / deduplicare (mecanică, risc mai redus) -Fiecare candidat a fost validat în raport cu starea efectivă a barierelor la 2026-06-17 (încredere, dar cu verificare); -mai multe comasări „evidente” s-au dovedit a ascunde datorie tehnică și **nu** pot fi aplicate -direct fără probleme. +Fiecare candidat a fost validat în raport cu starea efectivă a mecanismelor de control la 2026-06-17 (încredere, dar cu verificare); +mai multe comasări „evidente” s-au dovedit a ascunde datorie și **nu** pot fi aplicate direct fără probleme. -- **`check:docs-sync` rulează de două ori** — separat în jobul `lint` și din nou în `check:docs-all` (`docs-sync-strict`) și în hook-ul husky pre-commit. ✅ **FINALIZAT** — invocarea separată din `lint` a fost eliminată. -- **Scanarea CVE** — ❌ **NU este o comasare simplă.** `audit:deps` eșuează ferm la orice CVE cu severitate ridicată/critică; `check:vuln-ratchet` (osv) eșuează doar la o _regresie_ față de valoarea de referință (în prezent 1 MODERATE). Semantică diferită — eliminarea `audit:deps` ar elimina bariera absolută pentru severități ridicate/critice. Păstrați-le pe ambele. -- **Detectarea ciclurilor** — ❌ **NU este o comasare simplă.** `check:circular-deps` (dpdm) raportează **91 de cicluri** (acesta este motivul pentru care are caracter consultativ); nu poate fi promovat la statut de blocare fără a le rezolva mai întâi și are un domeniu de aplicare mai larg decât `check:cycles`, care este verde și atent configurat. Păstrați `check:cycles` ca mecanism de blocare; rezolvarea celor 91 de cicluri dpdm constituie o restanță separată. -- **Complexitate** — ✅ **FINALIZAT** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): o singură parcurgere ESLint, cu numărare după ruleId, astfel încât valorile de referință pentru complexitatea ciclomatică+numărul maxim de linii și complexitatea cognitivă să rămână independente; comenzile individuale `check:complexity` / `check:cognitive-complexity` sunt păstrate pentru rulări locale cu `--update`. -- **Prevenirea halucinațiilor pentru `/api`** — ✅ **FINALIZAT** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): un singur inventar FS pentru `src/app/api`, openapi-routes + docs-symbols continuă să raporteze independent; comenzile individuale sunt păstrate pentru rulări locale. -- **`check:node-runtime` rulează în 11 joburi** — ⚠️ **ROI scăzut.** Fiecare folosește un runner separat, iar verificarea durează <1s; economia totală este de ~10s, cu prețul pierderii unei protecții ieftine pentru fiecare job. Nu merită schimbările aferente. -- **`typecheck:noimplicit:core` în lint-ul CI** — ✅ **eliminat din jobul lint** (avea caracter consultativ, cu `continue-on-error`); suprafața de tipuri blocantă este `typecheck:core` + `check:type-coverage`. Scriptul local a fost păstrat. +- **`check:docs-sync` rulează de două ori** — autonom în jobul `lint` și din nou în `check:docs-all` (`docs-sync-strict`) și în hook-ul husky de pre-commit. ✅ **FINALIZAT** — invocarea autonomă din `lint` a fost eliminată. +- **Scanarea CVE** — ❌ **NU este o comasare fără probleme.** `audit:deps` eșuează categoric pentru orice CVE de severitate ridicată/critică; `check:vuln-ratchet` (osv) eșuează numai la o _regresie_ față de valoarea de referință (în prezent 1 MODERATE). Semantică diferită — eliminarea `audit:deps` ar înlătura pragul absolut pentru severitate ridicată/critică. Păstrați-le pe ambele. +- **Detectarea ciclurilor** — ✅ **FINALIZAT** (#15159 G-01/G-02). Textul anterior numea `check:cycles` mecanismul de control „verde, selecționat” și justifica păstrarea sa ca blocant deoarece `check:circular-deps` (dpdm) raporta 91 de cicluri. Acel rezultat verde era un **fals pozitiv verde**: `check:cycles` scana 5 subdirectoare (450 de fișiere), identifica numai construcțiile statice `import|export … from` și elimina fiecare specificator `@/` și `@omniroute/open-sse/`, astfel încât nu putea detecta ciclurile cu import dinamic + alias care predominau în depozit. Remediere: mecanismul de control parcurge acum `src` + `open-sse` (5023 de fișiere), colectează specificatorii din AST-ul TypeScript (astfel încât `import("…")` este luat în calcul, iar `typeof import("…")` din poziții de tip nu este) și rezolvă `paths` din tsconfig. Găsește **14** cicluri, nu 0. Deoarece 14 cicluri preexistente nu pot fi remediate într-un PR dedicat mecanismului de control, `check:cycles` este acum un **prag incremental** (`--ratchet`, plafon `metrics.cycles.value = 14` în `quality-baseline.json`, `direction: down`) — blochează orice _regresie_, iar numărul poate doar să scadă. CI rulează `npm run check:cycles:ratchet`. Reducerea treptată este gestionată împreună cu **A-01**. `check:circular-deps` (dpdm) rămâne consultativ, ca a doua opinie mai cuprinzătoare. +- **Complexitate** — ✅ **FINALIZAT** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): o singură parcurgere ESLint, cu numărare după ruleId, astfel încât valorile de referință pentru complexitatea ciclomatică+numărul maxim de linii și cele cognitive să rămână independente; comenzile individuale `check:complexity` / `check:cognitive-complexity` rămân disponibile pentru rularea locală cu `--update`. +- **Anti-halucinații pentru `/api`** — ✅ **FINALIZAT** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): un singur inventar FS pentru `src/app/api`; openapi-routes + docs-symbols continuă să raporteze independent; comenzile individuale rămân disponibile pentru rulări locale. +- **`check:node-runtime` rulează în 11 joburi** — ⚠️ **ROI scăzut.** Fiecare folosește un runner separat, iar verificarea durează <1s; economia totală este de ~10s, în schimbul pierderii unei verificări ieftine pentru fiecare job. Nu merită perturbarea. +- **`typecheck:noimplicit:core` în lint-ul CI** — ✅ **eliminat din jobul lint** (era consultativ, cu `continue-on-error`); suprafața de tipuri blocantă este `typecheck:core` + `check:type-coverage`. Scriptul local a fost păstrat. -### Activare / decizie (politica operatorului) +### Schimbare de stare / decizie (politica operatorului) -- `check:openapi-security-tiers` (consultativ) — ❌ **NU poate fi activat fără modificări prealabile.** Se încheie cu codul 0, dar avertizează că mai multe rute `traffic-inspector` din `LOCAL_ONLY_API_PREFIXES` nu au adnotarea `x-loopback-only: true`. Impunerea verificării necesită mai întâi adăugarea acestor adnotări în `openapi.yaml`. -- `typecheck:noimplicit:core` (consultativ) — este în mare parte acoperit de mecanismul blocant bazat pe prag `check:type-coverage`. Transformați-l într-un mecanism bazat pe prag sau eliminați a doua trecere `tsc`, care este redundantă. -- `test:vitest:ui` (acum **blocant**) — erorile preexistente sunt excluse explicit în `vitest.config.ts` prin comentarii de urmărire `// #8618`; erorile noi fac jobul să eșueze. -- `check:secrets` (gitleaks, mecanism blocant bazat pe prag, fixat la 3 rezultate fals pozitive documentate) — adăugați-le pe cele 3 în lista de permisiuni pentru a ajunge la 0 sau retrogradați verificarea la statut consultativ. Se suprapune cu scanarea nativă GitHub a secretelor + `check:public-creds`. -- `check:pr-evidence` (blocant, caută expresii în textul corpului PR-ului) — risc ridicat de rezultate fals pozitive; eliminarea sa slăbește aplicarea Regulii stricte #18, așadar aceasta este o decizie autentică de politică. -- `semgrep` (flux autonom consultativ) — se suprapune cu CodeQL pentru familiile OWASP; conectați valoarea sa de referință la un mecanism bazat pe prag sau eliminați-l. +- `check:openapi-security-tiers` (consultativ) — ❌ **NU poate deveni blocant fără modificări prealabile.** Se încheie cu codul 0, dar avertizează că mai multe rute `traffic-inspector` din `LOCAL_ONLY_API_PREFIXES` nu au adnotarea `x-loopback-only: true`. Aplicarea strictă necesită mai întâi adăugarea acestor adnotări în `openapi.yaml`. +- `typecheck:noimplicit:core` (consultativ) — în mare parte înlocuit de pragul incremental blocant `check:type-coverage`. Transformați-l într-un prag incremental sau eliminați a doua rulare redundantă a `tsc`. +- `test:vitest:ui` (acum **blocant**) — eșecurile preexistente sunt excluse explicit în `vitest.config.ts` prin comentarii de urmărire `// #8618`; eșecurile noi duc la eșuarea jobului. +- `check:secrets` (gitleaks, prag incremental blocant înghețat la 3 rezultate fals pozitive documentate) — adăugați-le pe cele 3 în lista de permisiuni pentru a ajunge la 0 sau retrogradați verificarea la statut consultativ. Se suprapune cu scanarea nativă a secretelor oferită de GitHub + `check:public-creds`. +- `check:pr-evidence` (blocant, caută prin grep în proza din corpul PR-ului) — risc ridicat de rezultate fals pozitive; eliminarea sa slăbește aplicarea Regulii stricte #18, deci aceasta este o veritabilă decizie de politică. +- `semgrep` (autonom, consultativ) — se suprapune cu CodeQL pentru familiile OWASP; conectați valoarea sa de referință la un prag incremental sau eliminați-l. --- diff --git a/docs/i18n/ru/CONTRIBUTING.md b/docs/i18n/ru/CONTRIBUTING.md index 740b3832454..55c7c57a947 100644 --- a/docs/i18n/ru/CONTRIBUTING.md +++ b/docs/i18n/ru/CONTRIBUTING.md @@ -390,19 +390,19 @@ docs/ # Documentation ## Контрольный список Pull Request - [ ] Тесты проходят (`npm test`) -- [ ] Линтинг проходит (`npm run lint`) -- [ ] Сборка выполняется успешно (`npm run build`) +- [ ] Проверка линтером проходит (`npm run lint`) +- [ ] Сборка завершается успешно (`npm run build`) - [ ] Для новых публичных функций и интерфейсов добавлены типы TypeScript - [ ] Нет жёстко заданных секретов или резервных значений -- [ ] Публичные учётные данные вышестоящих сервисов встраиваются через `resolvePublicCred()` (см. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), но никогда не задаются литералами -- [ ] Ответы с ошибками проходят через `buildErrorBody()` / `sanitizeErrorMessage()` — никаких необработанных трассировок стека в телах ответов (см. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Команды оболочки (`exec` / `spawn`) передают значения времени выполнения через `env`, а не посредством строковой интерполяции +- [ ] Публичные учётные данные вышестоящих сервисов встраиваются через `resolvePublicCred()` (см. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), а не задаются литералами +- [ ] Ответы с ошибками проходят через `buildErrorBody()` / `sanitizeErrorMessage()` — необработанные трассировки стека не включаются в тела ответов (см. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Команды оболочки (`exec` / `spawn`) передают значения времени выполнения через `env`, а не посредством интерполяции строк - [ ] Все входные данные проверяются с помощью схем Zod -- [ ] Для изменений, заметных пользователям, добавлен **фрагмент** журнала изменений в `changelog.d/{features|fixes|maintenance}/-.md` (см. [`changelog.d/README.md`](./changelog.d/README.md)) — **не** редактируйте `CHANGELOG.md` напрямую; фрагменты объединяются во время выпуска и никогда не создают конфликтов между PR +- [ ] Для изменений, видимых пользователям, добавлен **фрагмент** журнала изменений в `changelog.d/{features|fixes|maintenance}/-.md` (см. [`changelog.d/README.md`](./changelog.d/README.md)) — **не** редактируйте `CHANGELOG.md` напрямую; фрагменты объединяются при выпуске релиза и никогда не вызывают конфликтов между PR - [ ] Документация обновлена (если применимо) - [ ] Не создано новых предупреждений CodeQL / Secret-Scanning либо каждое из них отклонено с техническим обоснованием и ссылкой на соответствующий документ в `docs/security/` -- [ ] Маршруты, запускающие дочерние процессы (`/api/mcp/`, `/api/cli-tools/runtime/`), классифицированы как `isLocalOnlyPath()` в `src/server/authz/routeGuard.ts` — см. [Жёсткое правило №15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] В сообщениях коммитов отсутствуют завершающие строки `Co-Authored-By` — коммиты должны отображаться исключительно под Git-идентичностью владельца репозитория (Жёсткое правило №16) +- [ ] Маршруты, запускающие дочерние процессы (`/api/mcp/`, `/api/cli-tools/runtime/`), классифицированы как `isLocalOnlyPath()` в `src/server/authz/routeGuard.ts` — см. [жёсткое правило № 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] В сообщениях коммитов отсутствуют трейлеры `Co-authored-by` для ИИ/ботов (жёсткое правило № 16) — люди, чья работа была повторно использована, указываются как соавторы с помощью стандартных трейлеров `Co-authored-by: Name ` --- diff --git a/docs/i18n/ru/docs/architecture/QUALITY_GATES.md b/docs/i18n/ru/docs/architecture/QUALITY_GATES.md index 90fa60e02e8..87a6fe08df8 100644 --- a/docs/i18n/ru/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ru/docs/architecture/QUALITY_GATES.md @@ -15,221 +15,221 @@ --- -## Инвентаризация проверок и профили выполнения +## Инвентаризация гейтов и профили выполнения -### Допуск кандидата +### Допуск кандидатов Рабочие процессы CI и Quality Gates формируют стабильные вердикты: `Gate / CI` и `Gate / Quality`. Их версионируемая политика допуска определяет каждую вышестоящую задачу как обязательную или рекомендательную. Применимая обязательная задача должна завершиться -успешно: отсутствующий, отменённый, пропущенный, ожидающий выполнения или неизвестный -результат не может подтвердить PASS. Корректная классификация «только документация» или -«только каталог» может сделать ветку проверки кода неприменимой; черновик PR не считается -принятым кандидатом. Метка `hotfix` не отменяет требования к подтверждающим данным. - -Оба рабочих процесса охватывают PR и отправку изменений в ветки main/release, ручной запуск и -события групп слияния. При отправке изменений, ручном запуске и запуске для группы слияния -выполняется полный набор проверок. Для форков и групп слияния используются размещённые -раннеры в задачах, которые в иных случаях выбирают собственные раннеры; перед развёртыванием -необходимо убедиться в достаточной доступной мощности размещённых раннеров. - -Каждая JSON-квитанция идентифицирует извлечённый SHA, запуск рабочего процесса и попытку. -CLI отклоняет несовпадение SHA извлечённой версии и события. Тесты рабочего процесса -связывают состав политики со списком `needs` задачи вердикта, чтобы новая или удалённая -ветка проверки не могла незаметно исчезнуть. Квитанции охватывают только соответствующий -рабочий процесс, но не публикацию, развёртывание или внутреннюю работу существующего -рекомендательного сканера. Активация обоих имён проверок в правилах ветки является -отдельным административным изменением; добавление этих задач само по себе не защищает ветку. +успешно: отсутствующие, отменённые, пропущенные, ожидающие выполнения и неизвестные результаты +не могут установить статус PASS. Корректная классификация «только документация» или «только каталог» +может сделать ветку проверки кода неприменимой; черновик PR не считается допущенным кандидатом. +Метка `hotfix` не отменяет требование о наличии подтверждений. + +Оба рабочих процесса охватывают PR и отправки изменений в ветки main/release, ручной запуск и +события групп слияния. При отправке изменений, ручном запуске и запуске для группы слияния выполняется +полный набор проверок. Для форков и групп слияния используются размещённые раннеры в задачах, которые +в иных случаях выбирают самостоятельно размещённые раннеры; перед развёртыванием необходимо проверить +наличие достаточных ресурсов размещённых раннеров. + +Каждая JSON-квитанция идентифицирует SHA извлечённой версии, запуск рабочего процесса и попытку. +CLI отклоняет несовпадение SHA извлечённой версии и события. Тесты рабочего процесса связывают +членство в политике со списком `needs` задачи вердикта, чтобы новая или удалённая ветка проверки +не могла незаметно исчезнуть. Квитанции охватывают собственный рабочий процесс, но не публикацию, +развёртывание или внутреннюю реализацию существующего рекомендательного сканера. Активация обоих +названий проверок в правилах ветвей является отдельным административным изменением; добавление этих +задач само по себе не защищает ветку. ### Инвентаризация статического сканирования -Версионируемая инвентаризация псевдонимов npm и состав статического сканирования находятся в -`config/quality/gate-manifest.json`. Выполните `npm run check:gate-manifest`, чтобы проверить -имена скриптов и точные команды по `package.json`; добавления, удаления и изменения команд +Версионируемая инвентаризация npm-псевдонимов и состав статического сканирования находятся в +`config/quality/gate-manifest.json`. Запустите `npm run check:gate-manifest`, чтобы проверить +названия скриптов и точные команды по `package.json`; добавления, удаления и расхождения команд приводят к сбою как локального хука, так и задач классификации изменений в CI. Псевдоним не является задачей рабочего процесса, экземпляром матрицы или тестовым случаем: -числа для этих сущностей нельзя представлять как взаимозаменяемые. +количество этих сущностей нельзя представлять как взаимозаменяемое. Используйте `npm run quality:scan -- --list` или `npm run quality:scan:fast -- --list`, чтобы просмотреть выбранные псевдонимы без их выполнения. Раннер вызывает точку входа -npm, поэтому используемая ею среда выполнения (включая Bun, где он настроен) сохраняется. -Манифест отмечает псевдонимы вне этих профилей как вызываемые отдельно, а команды -обслуживания запрещены в профилях сканирования, доступных только для чтения. +npm, поэтому среда её выполнения (включая Bun, где он настроен) сохраняется. +Манифест регистрирует псевдонимы за пределами этих профилей как вызываемые отдельно, а +команды обслуживания запрещены в профилях сканирования, предназначенных только для чтения. -Эти профили охватывают только статическое сканирование. Они не подтверждают тесты продукта, -покрытие, упаковку, внешние проверки или полный допуск кандидата к выпуску. +Эти профили охватывают только статическое сканирование. Они не подтверждают прохождение тестов +продукта, проверку покрытия, упаковку, внешние проверки или полный допуск кандидата к выпуску. Для допуска в рабочем процессе используются связанные `config/quality/admission-policy.json` и `scripts/quality/admission-verdict.mjs`. Профили наблюдения за выпуском остаются отдельными; -проверяйте их применимые проверки и квитанции независимо. Приведённая ниже текстовая -инвентаризация является справочной и не доказывает, что проверка действительно выполнялась. +проверяйте применимые к ним проверки и квитанции независимо. Приведённая ниже текстовая +инвентаризация является справочной и не доказывает, что гейт действительно выполнялся. -Скрипты находятся в `scripts/check/` (проверки политик) и `scripts/quality/` (механизм ратчета). -Единым источником истины для CI является `.github/workflows/ci.yml`. +Скрипты находятся в `scripts/check/` (гейты политики) и `scripts/quality/` (механизм храповика). +Источник истины для CI — `.github/workflows/ci.yml`. ### Ускоренный путь для PR выпуска (`quality.yml`) -`.github/workflows/quality.yml` дополняет CI для PR в ветки main/release, отправки изменений +`.github/workflows/quality.yml` дополняет CI для PR в ветки main/release, отправок изменений в защищённые ветки, ручного запуска и групп слияния. Для PR используются быстрые проверки -с фильтрацией по путям. Постоянно отключённая дублирующая сборка удалена; фактические -проверки сборки, упаковки и запуска остаются в CI. - -| Задача | Область действия | Блокирующая | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `Docs Gates (fast-path)` | PR документации/кода; ссылки документации API и вся документация | Да | -| `Fast Quality Gates` | PR кода; статические проверки, проверка типов, проверка типов панели мониторинга, затронутые модульные тесты | Да | -| `Forgotten sibling tests` | PR кода; изменённые модули сопоставляются со статическими потребителями и потенциальными соседними тестами; пути через индексные модули и динамические импорты выводятся как рекомендательная диагностика с указанными исключениями из списка разрешений | **Рекомендательная** | -| `Vitest (fast-path)` | PR кода; быстрый набор тестов vitest | Да | -| `Unit Tests fast-path` | PR кода; набор модульных тестов в 4 сегментах | Да | -| `No new ESLint warnings` | PR кода; проверка линтинга с учётом подавлений | Да, включая форки | -| `Merge integrity (changelog + generated skills)` | Нечерновые PR; синхронизация журнала изменений и сгенерированных навыков | Да, включая форки | +с фильтрацией по путям. Постоянно отключённая дублирующая сборка была удалена; реальные проверки +сборки, упаковки и загрузки остаются в CI. + +| Задача | Область | Блокирующая | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | PR документации/кода; ссылки на документацию API и docs-all | Да | +| `Fast Quality Gates` | PR кода; статические проверки, проверка типов, проверка типов панели мониторинга, затронутые модульные тесты | Да | +| `Forgotten sibling tests` | PR кода; изменённые модули отслеживаются до статических потребителей и потенциальных соседних тестов; пути через barrel-файлы и динамический импорт выводятся как рекомендательная диагностика с указанными исключениями из списка разрешений | **Рекомендательная** | +| `Vitest (fast-path)` | PR кода; быстрый набор тестов vitest | Да | +| `Unit Tests fast-path` | PR кода; набор модульных тестов в 4 шардах | Да | +| `No new ESLint warnings` | PR кода; проверка линтера с учётом подавлений | Да, включая форки | +| `Merge integrity (changelog + generated skills)` | Нечерновые PR; синхронизация журнала изменений и сгенерированных навыков | Да, включая форки | #### Отчёт о забытых соседних тестах `npm run check:forgotten-sibling-tests` повторно использует механизм разрешения импортов, -лежащий в основе карты влияния на тесты. Для каждого изменённого производственного модуля -он выводит детерминированные цепочки -`изменённый модуль/символ -> статический потребитель -> потенциальный соседний тест`, если -потенциальный тест отсутствует в разнице изменений pull request. Сводка Markdown и результат -JSON сохраняются как артефакт рабочего процесса `forgotten-sibling-tests` для калибровки -перед возможным переводом проверки в блокирующий режим. - -Повторные экспорты через barrel-файлы и динамические импорты используются только для диагностики разрешения зависимостей; они никогда не создают -блокирующее нарушение. Проверенные исключения находятся в +лежащий в основе карты влияния на тесты. Для каждого изменённого производственного модуля он +выводит детерминированные цепочки +`изменённый модуль/символ -> статический потребитель -> потенциальный соседний тест`, если потенциальный +тест отсутствует в различиях pull request. Сводка Markdown и результат JSON сохраняются как +артефакт рабочего процесса `forgotten-sibling-tests` для калибровки перед возможным переходом +к блокирующему режиму. + +Повторные экспорты через barrel-файлы и динамические импорты используются только для диагностики разрешения; они никогда не создают +блокирующую проблему. Проверенные исключения находятся в `config/quality/forgotten-sibling-allowlist.json`. Каждая запись должна указывать потребителя и тест-кандидат, -содержать конкретное обоснование и ссылку на задачу GitHub или pull request. При некорректных записях -проверка завершается с ошибкой. Исключения не могут скрыть удалённый тест-кандидат или изменение, добавляющее `.skip`/`.todo`; -ослабление утверждений и другие способы маскировки по-прежнему контролируются независимо блокирующим -шлюзом `check:test-masking`. - -### Задание: `lint` - -Запускается для каждого PR в `main`. При ошибке блокирует слияние. - -| Скрипт (`npm run ...`) | Проверяет | Блокирует | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| `check:node-runtime` | Версия Node.js находится в поддерживаемом диапазоне | Да | -| `check:cycles` | Циклические импорты во всех модулях `src/` и `open-sse/` | Да | -| `check:route-validation:t06` | Наличие схем Zod во всех маршрутах (политика уровня 6) | Да | -| `check:any-budget:t11` | Количество `@ts-expect-error // any` не превышает установленный лимит (турникет уровня 11) | Да | -| `check:provider-consistency` | Каждому провайдеру в `providers.ts` соответствует запись в `providerRegistry.ts` (и наоборот, в пределах списка разрешённых) | Да | -| `check:model-lifecycle` | Три вручную поддерживаемые таблицы маршрутизации остаются согласованными с зафиксированным в репозитории снимком жизненного цикла (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не присваивает оценку ни одному выведенному из эксплуатации идентификатору, который может маршрутизировать `REGISTRY`; каждая цель `BUILT_IN_ALIASES` присутствует в `REGISTRY` и отсутствует в снимке выведенных из эксплуатации идентификаторов; каждый выведенный из эксплуатации идентификатор, всё ещё присутствующий в `REGISTRY`, перенаправляется или указан в `allowedRetiredInCatalog`; и ни один источник или цель `DEFAULT_DEGRADATION_MAP` не отмечены в этом снимке как выведенные из эксплуатации. Это не доказывает, что модель в настоящее время обслуживается работающим вышестоящим сервисом. Проверка выполняется офлайн — путём сравнения с `config/quality/model-lifecycle.json`, который обновляется вручную с помощью `npm run quality:refresh-model-lifecycle` (требуется сеть; не подключено к CI). `allowedRetiredInCatalog` — это храповик постепенного сокращения: добавляйте запись только при наличии задачи для отслеживания. | Да | -| `check:fetch-targets` | Каждый вызов `fetch("/api/...")` в клиентской части `src/` разрешается в реальный `route.ts` | Да | -| `check:deps` | Все зависимости, устанавливаемые через `npm install`, во всех файлах `package.json` репозитория присутствуют в `dependency-allowlist.json`; новые незакреплённые или подменённые через слопсквоттинг пакеты помечаются | Да | -| `audit:deps` | `npm audit` (корень + electron) — отсутствие предупреждений высокого/критического уровня (частично дублирует osv `check:vuln-ratchet`; см. журнал рационализации) | Да | -| `check:lockfile` | Целостность `package-lock.json` — реестр https, хеши целостности, отсутствие переопределений хоста | Да | -| `check:licenses` | Список разрешённых лицензий SPDX для production-зависимостей | Да | -| `check:tracked-artifacts` | Отсутствие артефактов сборки / закоммиченных символических ссылок `node_modules` (также запускается в husky pre-commit; pre-push намеренно облегчён — #6716) | Да | -| `check:ai-attribution` | Отсутствие трейлера AI/бота `Co-Authored-By` или примечания о генерации с помощью AI в коммитах, заголовке или описании PR — жёсткое правило №16 (в цикле быстрых проверок `quality.yml` для PR→`release/**` — считывает данные события, ничего не делает вне PR — и отдельный шаг только для PR в lint-проверке `ci.yml` для PR→`main`; также хук husky `commit-msg`; соавторы-люди разрешены; #14436) | -| `check:vitest-exclusions` | Каждое исключение Vitest содержит ссылку на отслеживаемую задачу и присутствует в `config/quality/vitest-exclusions.json` (#13204) | Да | -| `check:file-size` | Ни один исходный файл не превышает ограничение для соответствующего расширения (храповик: зафиксированные крупные файлы в списке `frozen`) | Да | -| `check:error-helper` | Ответы с ошибками в исполнителях/обработчиках используют `buildErrorBody()` / `sanitizeErrorMessage()` (жёсткое правило №12) | Да | -| `check:migration-numbering` | SQL-файлы миграций пронумерованы последовательно, без пропусков и дубликатов | Да | -| `check:public-creds` | За пределами `publicCreds.ts` отсутствуют литеральные значения OAuth `client_id`/`client_secret` и веб-ключи Firebase (жёсткое правило №11) | Да | -| `check:db-rules` | За пределами модулей `src/lib/db/` отсутствует необработанный SQL; отсутствуют импорты из barrel-файла `localDb.ts` (жёсткие правила №2/№5) | Да | -| `check:known-symbols` | Исполнители провайдеров, стратегии маршрутизации и трансляторы, зарегистрированные в соответствующих таблицах диспетчеризации, совпадают с файлами на диске — отсутствуют потерянные или необъявленные символы | Да | -| `check:route-guard-membership` | Каждый маршрут, порождающий дочерний процесс, классифицируется функцией `isLocalOnlyPath()` (жёсткие правила №15/№17) | Да | -| `check:test-discovery` | Каждый файл `*.test.ts` / `*.spec.ts` в репозитории обнаруживается хотя бы одним средством запуска тестов (храповый механизм: список необнаруженных файлов в `test-discovery-baseline.json` может только сокращаться) | Да | -| `check:agent-skills-sync` | Сгенерированные артефакты agent-skills соответствуют исходному каталогу (без расхождений) | -| `check:provider-asset-provenance` | Для логотипов/ресурсов провайдеров указана информация о происхождении | -| `lint:json` | Файлы конфигурации JSON корректно разбираются и соответствуют правилам линтинга репозитория | -| `typecheck:core` | Компиляция TypeScript без ошибок (только рекомендательные предупреждения) | Да | -| `typecheck:noimplicit:core` | Строгий режим `noImplicitAny` — рассчитан на будущее; многие существующие места вызова всё ещё требуют аннотаций | **Рекомендательно** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, ограниченный областью `src/app/(dashboard)/**` (#7033), — поддерживаемый вручную список разрешённых 27 файлов в `typecheck:core` не включает ни одного TSX-файла панели мониторинга, а `next build` также никогда не выполняет для них проверку типов (`next.config.mjs` задаёт `ignoreBuildErrors: true`), поэтому регрессии с потерянными идентификаторами в этих файлах (#6625/#6909) были невидимы для CI. Выполняется сравнение с зафиксированным базовым уровнем количества ошибок для каждого файла и каждого кода TS (`config/quality/dashboard-typecheck-baseline.json`, тот же шаблон контроля устаревания, что и в `check:known-symbols`): проверка завершается неудачно только при появлении НОВЫХ ошибок сверх количества, зафиксированного в базовом уровне; уменьшайте базовый уровень с помощью `--update` после исправления существующей ошибки. | Да | +содержать конкретное обоснование и ссылку на issue или pull request в GitHub. Некорректные записи приводят +к запрету по умолчанию. Исключения не могут скрыть удалённый тест-кандидат или diff, добавляющий `.skip`/`.todo`; +ослабление утверждений и другие способы маскировки остаются в ведении независимо блокирующего +гейта `check:test-masking`. + +### Задача: `lint` + +Запускается для каждого PR в `main`. При сбое блокирует слияние. + +| Скрипт (`npm run ...`) | Что проверяет | Блокирует | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | +| `check:node-runtime` | Версия Node.js находится в поддерживаемом диапазоне | Да | +| `check:cycles` | Циклические импорты во всех `src/` + `open-sse/` (на основе AST, с разрешением `paths` из tsconfig). Без аргументов работает в рекомендательном режиме и выводит список циклов. `check:cycles:ratchet` (запускаемый в CI) блокирует, когда их количество превышает порог `metrics.cycles` в `quality-baseline.json` — сейчас 14, `direction: down`, поэтому оно может только уменьшаться (#15159 G-01/G-02) | Да (ratchet) | +| `check:route-validation:t06` | Наличие схем Zod на всех маршрутах (политика Tier 6) | Да | +| `check:any-budget:t11` | Количество `@ts-expect-error // any` не превышает бюджет (catraca Tier 11) | Да | +| `check:provider-consistency` | Каждый провайдер в `providers.ts` имеет соответствующую запись в `providerRegistry.ts` (и наоборот, в пределах списка разрешений) | Да | +| `check:model-lifecycle` | Три поддерживаемые вручную таблицы маршрутизации остаются согласованными с зафиксированным в репозитории снимком жизненного цикла (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не оценивает ни один выведенный из эксплуатации идентификатор, который может маршрутизировать `REGISTRY`; каждая цель `BUILT_IN_ALIASES` присутствует в `REGISTRY` и отсутствует в снимке выведенных из эксплуатации идентификаторов; каждый выведенный из эксплуатации идентификатор, всё ещё находящийся в `REGISTRY`, перенаправляется или указан в `allowedRetiredInCatalog`; и ни один источник или цель `DEFAULT_DEGRADATION_MAP` не помечены в этом снимке как выведенные из эксплуатации. Это не доказывает, что модель в настоящее время обслуживается работающим вышестоящим сервисом. Проверка выполняется автономно — данные сравниваются с `config/quality/model-lifecycle.json`, который обновляется вручную с помощью `npm run quality:refresh-model-lifecycle` (требуется сеть; не подключено к CI). `allowedRetiredInCatalog` — это механизм постепенного сокращения: добавляйте запись только при наличии задачи для отслеживания. | Да | +| `check:fetch-targets` | Каждый вызов `fetch("/api/...")` в клиентском коде `src/` разрешается в реально существующий `route.ts` | Да | +| `check:deps` | Все зависимости, устанавливаемые с помощью `npm install`, во всех файлах `package.json` репозитория присутствуют в `dependency-allowlist.json`; новые зависимости без зафиксированных версий или пакеты, подозреваемые в слопсквоттинге, помечаются | Да | +| `audit:deps` | `npm audit` (корень + electron) — нет предупреждений высокой/критической степени опасности (пересекается с osv `check:vuln-ratchet`; см. журнал отложенной рационализации) | Да | +| `check:lockfile` | Целостность `package-lock.json` — реестр https, хеши целостности, отсутствие переопределений хостов | Да | +| `check:licenses` | Список разрешённых лицензий SPDX для production-зависимостей | Да | +| `check:tracked-artifacts` | Отсутствие артефактов сборки / закоммиченных символических ссылок `node_modules` (также запускается в husky pre-commit; pre-push намеренно облегчён — #6716) | Да | +| `check:ai-attribution` | Отсутствие трейлера AI/бота `Co-Authored-By` или примечания об AI-генерации в коммитах, заголовке или описании PR — строгое правило №16 (в цикле быстрых проверок `quality.yml` для PR→`release/**` — считывает данные события и ничего не делает вне PR — и отдельный шаг только для PR в lint-задаче `ci.yml` для PR→`main`; также хук husky `commit-msg`; соавторы-люди разрешены; #14436) | +| `check:vitest-exclusions` | Каждое исключение Vitest содержит ссылку на отслеживаемую задачу и присутствует в `config/quality/vitest-exclusions.json` (#13204) | Да | +| `check:file-size` | Ни один исходный файл не превышает ограничение для своего расширения (храповик: зафиксированные крупные файлы в списке `frozen`) | Да | +| `check:error-helper` | Ответы с ошибками в исполнителях/обработчиках используют `buildErrorBody()` / `sanitizeErrorMessage()` (строгое правило №12) | Да | +| `check:migration-numbering` | SQL-файлы миграций имеют последовательную нумерацию, без пропусков и дубликатов | Да | +| `check:public-creds` | Нет литеральных значений OAuth `client_id`/`client_secret` или веб-ключей Firebase за пределами `publicCreds.ts` (жёсткое правило №11) | Да | +| `check:db-rules` | Нет необработанного SQL за пределами модулей `src/lib/db/`; нет импорта через агрегирующий модуль из `localDb.ts` (жёсткие правила №2/№5) | Да | +| `check:known-symbols` | Исполнители провайдеров, стратегии маршрутизации и трансляторы, зарегистрированные в соответствующих таблицах диспетчеризации, соответствуют файлам на диске — без потерянных или необъявленных символов | Да | +| `check:route-guard-membership` | Каждый маршрут, запускающий дочерний процесс, классифицируется функцией `isLocalOnlyPath()` (жёсткие правила №15/№17) | Да | +| `check:test-discovery` | Каждый файл `*.test.ts` / `*.spec.ts` в репозитории обнаруживается хотя бы одним средством запуска тестов (храповый механизм: список потерянных тестов в `test-discovery-baseline.json` может только сокращаться) | Да | +| `check:agent-skills-sync` | Сгенерированные артефакты agent-skills соответствуют исходному каталогу (без расхождений) | +| `check:provider-asset-provenance` | Для логотипов/ресурсов провайдеров указаны сведения об их происхождении | +| `lint:json` | Файлы конфигурации JSON успешно разбираются и соответствуют правилам линтинга репозитория | +| `typecheck:core` | Компиляция TypeScript без ошибок (только рекомендательные предупреждения) | Да | +| `typecheck:noimplicit:core` | Строгий режим `noImplicitAny` — задел на будущее; многие существующие места вызова всё ещё требуют аннотаций | **Рекомендательный** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, ограниченный областью `src/app/(dashboard)/**` (#7033), — подготовленный список разрешённых 27 файлов в `typecheck:core` не включает ни одного TSX-файла панели мониторинга, а `next build` также никогда не проверяет их типы (`next.config.mjs` задаёт `ignoreBuildErrors: true`), поэтому регрессии с потерянными идентификаторами в этих файлах (#6625/#6909) оставались незаметными для CI. Результаты сравниваются с зафиксированным базовым количеством ошибок для каждого файла и кода TS (`config/quality/dashboard-typecheck-baseline.json`, по той же схеме контроля устаревания, что и `check:known-symbols`): проверка завершается неудачей только при появлении НОВЫХ ошибок сверх базового количества; уменьшайте базовый уровень с помощью `--update` после исправления существующей ошибки. | Да | ### Задание: `quality-gate` -Запускается после `test-coverage`. При ошибке блокирует слияние. +Запускается после `test-coverage`. При сбое блокирует слияние. -| Скрипт | Проверяет | Блокирующий | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | -| `quality:collect` | Создаёт `quality-metrics.json` (количество предупреждений ESLint, покрытие из объединённого отчёта по шардам) | Да (предшествует ratchet-проверке) | -| `quality:ratchet` | Ни одна метрика в `quality-baseline.json` не ухудшилась (предупреждения ESLint ≤ базового уровня; покрытие ≥ базового уровня) | Да | -| `check:duplication` | Дублирование кода (jscpd@4) не превышает базовый уровень в `quality-baseline.json` | Да | -| `check:complexity` | Цикломатическая сложность на уровне файла не превышает предельного значения (правила `complexity` + `max-lines-per-function` из ядра ESLint) | Да | -| `check:cognitive-complexity` | Ratchet-проверка когнитивной сложности (`eslint-plugin-sonarjs`) — отдельный проход ESLint; в CI оба запуска объединены в один этап `check:complexity-ratchets` | Да | -| `check:dead-code` | Ratchet-проверка неиспользуемых экспортов / файлов (knip) не ухудшилась относительно базового уровня | Да | -| `check:compression-budget` | Бюджет бенчмарка сжатия — минимальные пороги экономии токенов для каждого движка не должны ухудшаться | Да | -| `check:type-coverage` | Ratchet-проверка процента типизированного кода (`type-coverage`) не ухудшилась; в значительной степени заменяет `typecheck:noimplicit:core` | Да | -| `check:codeql-ratchet` | Количество открытых предупреждений CodeQL не увеличилось (получает данные через `gh api`; корректно пропускается без токена) — частоту обновления и ручной запуск см. ниже, в разделе «CodeQL ratchet» | Да | +| Скрипт | Что проверяет | Блокирующий | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `quality:collect` | Создаёт `quality-metrics.json` (количество предупреждений ESLint, покрытие из объединённого отчёта по шардам) | Да (предшествует ratchet) | +| `quality:ratchet` | Ни одна метрика в `quality-baseline.json` не ухудшилась (предупреждения ESLint ≤ базового уровня; покрытие ≥ базового уровня) | Да | +| `check:duplication` | Дублирование кода (jscpd@4) не превышает базовый уровень из `quality-baseline.json` | Да | +| `check:complexity` | Цикломатическая сложность на уровне файла не превышает предельное значение (правила ядра ESLint `complexity` + `max-lines-per-function`) | Да | +| `check:cognitive-complexity` | Ratchet когнитивной сложности (`eslint-plugin-sonarjs`) — отдельный проход ESLint; в CI оба запуска объединены в единый шаг `check:complexity-ratchets` | Да | +| `check:dead-code` | Ratchet неиспользуемых экспортов / файлов (knip) не ухудшился относительно базового уровня | Да | +| `check:compression-budget` | Бюджет бенчмарка сжатия — минимальные пороги экономии токенов для каждого движка не должны ухудшаться | Да | +| `check:type-coverage` | Ratchet процента типизированного кода (`type-coverage`) не ухудшился; в основном заменяет `typecheck:noimplicit:core` | Да | +| `check:codeql-ratchet` | Количество открытых оповещений CodeQL не увеличилось (получает данные через `gh api`; корректно пропускается без токена) — периодичность обновления и ручной запуск: см. «Ratchet CodeQL» ниже | Да | ### Задание: `quality-extended` -Всё задание носит рекомендательный характер (`continue-on-error: true`). Ratchet-проверки на основе npm выполняются -по-настоящему; внешние сканеры устанавливаются через `gh release download` и самостоятельно пропускают -проверку (код выхода 0), если исполняемый файл по-прежнему отсутствует. +Всё задание носит рекомендательный характер (`continue-on-error: true`). Ratchet-проверки на базе npm выполняются +полноценно; внешние сканеры устанавливаются через `gh release download` и самостоятельно пропускают проверку (exit 0), +если исполняемый файл всё ещё отсутствует. -| Скрипт | Проверяет | Блокирующий | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -| `check:circular-deps` | Отсутствие циклических зависимостей (dpdm) | **Рекомендательный** | -| `check:bundle-size` | Размер бандла не превышает предельного значения | **Рекомендательный** | -| `check:secrets` | Сканирование секретов (gitleaks) — пропускается, если исполняемый файл отсутствует | **Рекомендательный** | -| `check:vuln-ratchet` | Уязвимости зависимостей (osv-scanner) не увеличились — пропускается, если исполняемый файл отсутствует | **Рекомендательный** | -| `check:workflows` | Линтинг рабочих процессов (actionlint + zizmor); отсутствующие/неработающие сканеры, недействительные отчёты или отсутствующий базовый уровень ratchet-проверки приводят к ошибке INCOMPLETE. Обнаруженные проблемы обрабатываются согласно выбранной строгой/рекомендательной/ratchet-политике | Выполнение обязательно; ratchet-проверка zizmor блокирует CI | -| `check:openapi-breaking` | Критические изменения публичного контракта API (`openapi.yaml`) относительно базовой ветки (oasdiff) — создаёт `openapiBreaking=N`; пропускается, если oasdiff отсутствует или базовую спецификацию невозможно разрешить | **Рекомендательный** | +| Скрипт | Что проверяет | Блокирующий | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| `check:circular-deps` | Отсутствие циклических зависимостей (dpdm) | **Рекомендательный** | +| `check:bundle-size` | Размер бандла не превышает предельное значение | **Рекомендательный** | +| `check:secrets` | Сканирование секретов (gitleaks) — пропускается, если исполняемый файл отсутствует | **Рекомендательный** | +| `check:vuln-ratchet` | Уязвимости зависимостей (osv-scanner) не увеличились — пропускается, если исполняемый файл отсутствует | **Рекомендательный** | +| `check:workflows` | Линтинг рабочих процессов (actionlint + zizmor); отсутствие/сбой сканеров, недопустимые отчёты или отсутствие базового уровня ratchet приводят к статусу INCOMPLETE. Допустимые находки обрабатываются согласно выбранной строгой/рекомендательной/ratchet-политике | Выполнение обязательно; ratchet zizmor блокирует в CI | +| `check:openapi-breaking` | Критические изменения публичного контракта API (`openapi.yaml`) относительно базовой ветки (oasdiff) — создаёт `openapiBreaking=N`; пропускается, если oasdiff отсутствует или базовую спецификацию невозможно разрешить | **Рекомендательный** | ### Задание: `docs-sync-strict` Запускается для каждого PR в `main`. При ошибке блокирует слияние. -| Скрипт | Что проверяет | Блокирующий | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | Мета-проверка, которая последовательно запускает 6 подпроверок ниже | Да | -| ↳ `check:docs-sync` | Согласованность версий в CHANGELOG / OpenAPI / llm.txt | Да | -| ↳ `check:docs-counts` | Числа в тексте (количество провайдеров, миграций и т. д.) находятся в пределах окна храповика относительно фактических значений | Да | -| ↳ `check:env-doc-sync` | Каждая переменная окружения из `.env.example` задокументирована в таблице документации, и наоборот | Да | -| ↳ `check:deprecated-versions` | В документации отсутствуют строки с устаревшими версиями | Да | -| ↳ `check:doc-links` | Внутренние markdown-ссылки в документации указывают на существующие файлы (формат `[текст]`/`(путь)`) | Да | -| ↳ `check:fabricated-docs` | Маршруты, переменные окружения, команды CLI, имена хуков и пути к файлам, упомянутые в документации, существуют в кодовой базе. Жёсткая проверка с `--strict`; без флага ошибка не блокирует. | Да (через `--strict` в CI) | -| `check:cli-i18n` | Строки команд CLI присутствуют во всех файлах локалей i18n | Да | -| `check:openapi-coverage` | Спецификация OpenAPI покрывает как минимум пороговое количество реальных маршрутов, заданное храповиком | Да | -| `check:openapi-security-tiers` | Аннотации уровней безопасности в `openapi.yaml` согласованы с классификациями в `routeGuard.ts` | **Рекомендательный** | -| `check:openapi-routes` | Каждый путь в `openapi.yaml` соответствует реальному `route.ts` (защита от галлюцинаций) | Да | -| `check:docs-symbols` | Каждая ссылка `/api/...` в `docs/**/*.md` соответствует реальному `route.ts` (защита от галлюцинаций) | Да | -| `i18n translation drift` | Непереведённые ключи в файлах локалей i18n — только предупреждение | **Рекомендательный** | +| Скрипт | Что проверяет | Блокирующий | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `check:docs-all` | Мета-проверка, последовательно запускающая 6 проверок ниже | Да | +| ↳ `check:docs-sync` | Согласованность версий в CHANGELOG / OpenAPI / llm.txt | Да | +| ↳ `check:docs-counts` | Числовые значения в тексте (количество провайдеров, миграций и т. д.) находятся в пределах допустимого окна относительно фактических значений | Да | +| ↳ `check:env-doc-sync` | Каждая переменная окружения из `.env.example` задокументирована в таблице документации, и наоборот | Да | +| ↳ `check:deprecated-versions` | В документации отсутствуют строки с устаревшими версиями | Да | +| ↳ `check:doc-links` | Внутренние markdown-ссылки в документации указывают на существующие файлы (формат `[текст]`/`(путь)`) | Да | +| ↳ `check:fabricated-docs` | Упомянутые в документации маршруты, переменные окружения, команды CLI, имена хуков и пути к файлам существуют в кодовой базе. Строгая проверка с `--strict`; без флага ошибка не блокирует. | Да (с `--strict` в CI) | +| `check:cli-i18n` | Строки команд CLI присутствуют во всех файлах локалей i18n | Да | +| `check:openapi-coverage` | Спецификация OpenAPI покрывает не меньше установленного порогового количества реальных маршрутов | Да | +| `check:openapi-security-tiers` | Аннотации уровней безопасности в `openapi.yaml` согласованы с классификациями в `routeGuard.ts` | **Рекомендательный** | +| `check:openapi-routes` | Каждый путь в `openapi.yaml` соответствует реальному `route.ts` (защита от галлюцинаций) | Да | +| `check:docs-symbols` | Каждая ссылка `/api/...` в `docs/**/*.md` соответствует реальному `route.ts` (защита от галлюцинаций) | Да | +| `i18n translation drift` | Непереведённые ключи в файлах локалей i18n — только предупреждение | **Рекомендательный** | ### Задание: `i18n-ui-coverage` -| Скрипт | Что проверяет | Блокирующий | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| `check-ui-keys-coverage` (inline) | Покрытие ключей i18n пользовательского интерфейса составляет ≥ 65% | Да | -| `check-ui-value-drift` (inline) | После изменения английского **значения** не остаётся устаревших переводов | Да | -| `check-new-key-coverage` (inline) | **Новый** английский ключ переведён во всех локалях — маркер `__MISSING__:` недопустим | Да | -| `check-translation-ratio` | Доля фактических переводов для каждой локали (совпадающие с английским / шаблонные / отсутствующие конечные узлы вне списка разрешений) не должна превышать `config/quality/i18n-translation-baseline.json` + допустимый запас | **Рекомендательный** | +| Скрипт | Что проверяет | Блокирующий | +| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `check-ui-keys-coverage` (встроенный) | Покрытие ключей i18n интерфейса составляет ≥ 65% | Да | +| `check-ui-value-drift` (встроенный) | После изменения английского **значения** не остаётся устаревших переводов | Да | +| `check-new-key-coverage` (встроенный) | **Новый** английский ключ переведён во всех локалях — маркер `__MISSING__:` недопустим | Да | +| `check-translation-ratio` | Доля реальных переводов для каждой локали (значения, идентичные английским, заполнители или отсутствующие элементы вне списка разрешённых исключений) не должна превышать `config/quality/i18n-translation-baseline.json` + допустимый запас | **Рекомендательный** | -Требуется `fetch-depth: 0` — проверка расхождений значений сравнивает `en.json` с базой слияния. +Требуется `fetch-depth: 0` — проверка изменения значений сравнивает `en.json` с базой слияния. #### `check-ui-value-drift` — проверка устаревших переводов -Выявляет единственную регрессию i18n, которую другие проверки структурно не способны обнаружить: английское значение -переписывается, а переводы, созданные на основе _предыдущего_ английского текста, остаются без изменений, поэтому -неанглоязычные пользователи продолжают читать уверенно сформулированный, но уже неверный текст. - -Это действительно попало в релиз. `oauthModal.googleOAuthWarning` был переписан при добавлении помощника входа -Antigravity (#5203); в **39 из 43 локалей** остался текст, предписывающий операторам «скопировать -полный URL-адрес и вставить его ниже» — сценарий, который невозможно завершить для этого провайдера. Это -оставалось незамеченным до #8463, потому что: - -- `sync-ui-keys` добавляет только **отсутствующие** ключи и никогда не обновляет **устаревшие**; -- `check-ui-keys-coverage` учитывает _наличие_ ключа, поэтому устаревший перевод считается покрытым; -- `check-translation-drift` отслеживает зеркала документации `docs/i18n//**.md` — - он никогда не читает `src/i18n/messages/*.json`. Блокирует в задании `docs-sync-strict` после - повторной синхронизации 2026-09: изменили основной документ → `npm run i18n:run -- --files=` (на уровне раздела, с небольшими затратами). - -**Учитывает diff, а не опирается на baseline.** Он сравнивает `en.json` в merge base -с рабочим деревом; для каждого ключа, английское значение которого изменилось, локаль, -всё ещё содержащая нетронутый перевод, считается устаревшей. Такой подход намеренно -**замораживает существующий технический долг** — по diff невозможно определить, из какой -старой английской строки был получен давно существующий перевод, поэтому проверка оценивает -только то, что затрагивает текущее изменение. Альтернатива (baseline с хешем для каждого ключа) -потребовала бы генерируемого файла размером около 600 КБ, в 3 раза больше крупнейшего -существующего baseline, который изменялся бы при каждом i18n PR. +Выявляет единственную регрессию i18n, которую остальные проверки структурно не способны обнаружить: английское значение +переписывается, а переводы, созданные на основе _предыдущего_ английского текста, остаются неизменными, из-за чего +пользователи с неанглийской локалью продолжают читать уверенно сформулированный, но уже неверный текст. + +Такая проблема действительно попала в релиз. `oauthModal.googleOAuthWarning` был переписан при добавлении вспомогательного инструмента +входа Antigravity (#5203); в **39 из 43 локалей** сохранился текст, предлагавший операторам «скопировать +полный URL-адрес и вставить его ниже», — при таком сценарии вход через этого провайдера невозможно завершить. Проблема +оставалась незамеченной до #8463, поскольку: + +- `sync-ui-keys` добавляет только **отсутствующие** ключи, но никогда не обновляет **устаревшие**; +- `check-ui-keys-coverage` учитывает наличие ключа, поэтому устаревший перевод считается покрытым; +- `check-translation-drift` отслеживает зеркальные копии документации `docs/i18n//**.md` — + файлы `src/i18n/messages/*.json` он никогда не читает. Блокирует в задании `docs-sync-strict` после + повторной синхронизации 2026-09: измените основной документ → `npm run i18n:run -- --files=` (на уровне раздела, быстро). + +**Учитывает различия, а не опирается на базовый файл.** Он сравнивает `en.json` в точке слияния с +рабочим деревом; для каждого ключа, английское значение которого изменилось, любой языковой файл, +где перевод остался нетронутым, считается устаревшим. Это намеренно **фиксирует уже существующий +технический долг** — по различиям невозможно определить, из какой старой английской строки был +получен давно существующий перевод, поэтому проверка оценивает только то, чего касается текущее +изменение. Альтернатива (базовый файл с хешем для каждого ключа) потребовала бы сгенерированного +файла размером около 600 КБ — втрое больше крупнейшего существующего базового файла — и создавала +бы изменения при каждом PR, связанном с i18n. Есть два способа пройти проверку: 1. обновить затронутые переводы или -2. задать им значение `__MISSING__:<новый английский текст>` — тогда во время выполнения - будет возвращаться исправленный английский текст - (`src/i18n/request.ts::deepMergeFallback`, #7258), а ключ будет поставлен в очередь на перевод. +2. задать для них значение `__MISSING__:` — тогда во время выполнения будет + использоваться исправленный английский текст (`src/i18n/request.ts::deepMergeFallback`, #7258), + а ключ будет поставлен в очередь на перевод. Если изменился **смысл** строки, предпочтительно **переименовать ключ**: новый ключ не может унаследовать устаревший перевод. Именно этот подход использовался в #8463. @@ -240,51 +240,49 @@ npm run i18n:check-value-drift:warn # только отчёт BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Завершается с кодом 0 и сообщением `SKIP reason=base-unresolved`, если базовый каталог -невозможно прочитать (поверхностный клон без базового ref), аналогично -`check-openapi-breaking`. +Завершается с кодом 0 и сообщением `SKIP reason=base-unresolved`, если базовый каталог невозможно +прочитать (поверхностный клон без базовой ссылки), аналогично `check-openapi-breaking`. ### Задание: `i18n` -Полная матрица проверок i18n (по одному заданию на локаль). Всё задание носит +Полная матрица проверок i18n (одно задание для каждого языкового файла). Всё задание носит рекомендательный характер. -| Скрипт | Что проверяет | Блокирует | -| ------------------------------- | ---------------------------------- | ----------------------------------------------------- | -| `validate_translation.py quick` | Полноту перевода для каждой локали | **Нет** (`continue-on-error: true` для всего задания) | +| Скрипт | Что проверяет | Блокировка | +| ------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------- | +| `validate_translation.py quick` | Полноту перевода для каждого языкового файла | **Рекомендательная проверка** (`continue-on-error: true` для всего задания) | ### Задание: `pr-test-policy` Выполняется только для pull request. -| Скрипт | Что проверяет | Блокирует | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | -| `check:pr-test-policy` | PR, изменяющие рабочий код в `src/`, `open-sse/`, `electron/` или `bin/`, должны включать или обновлять тесты (жёсткое правило № 8) | Да | -| `check:test-masking` | Изменённые файлы тестов не уменьшают общее количество assert и не добавляют тавтологии `assert.ok(true)` | Да | -| `check:pr-evidence` | Текст PR содержит подтверждения тестирования/VPS для изменения (механизация жёсткого правила № 18 через grep текста PR — ненадёжно, см. Backlog) | Да | +| Скрипт | Что проверяет | Блокировка | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | PR, изменяющие рабочий код в `src/`, `open-sse/`, `electron/` или `bin/`, должны добавлять или обновлять тесты (жёсткое правило №8) | Да | +| `check:test-masking` | Изменённые тестовые файлы не уменьшают итоговое количество проверок и не добавляют тавтологии `assert.ok(true)` | Да | +| `check:pr-evidence` | Тело PR содержит сведения о тестировании/VPS для изменения (автоматизирует жёсткое правило №18 через поиск в тексте PR — ненадёжно, см. бэклог) | Да | ### Задание: `test-vitest` Выполняется после `build`. При сбое блокирует слияние. -| Набор тестов | Что проверяет | Блокирует | -| ---------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-сервер (110 инструментов), autoCombo, кеш — vitest | Да | -| `test:vitest:ui` | Тесты компонентов UI — vitest | **Да** — существующие ранее сбои явно исключены в `vitest.config.ts`; новые сбои приводят к провалу задания | +| Набор тестов | Что проверяет | Блокировка | +| ---------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Сервер MCP (110 инструментов), autoCombo, кеш — Vitest | Да | +| `test:vitest:ui` | Тесты компонентов UI — Vitest | **Блокирующая проверка** — существовавшие ранее сбои явно исключены в `vitest.config.ts`; новые сбои приводят к падению задания | -### Ночные workflow (по расписанию, рекомендательные) +### Ночные рабочие процессы (по расписанию, рекомендательные) -Они запускаются по расписанию cron (и через `workflow_dispatch`), но никогда не запускаются -для PR. Все они носят рекомендательный характер. +Они запускаются по расписанию cron (а также через `workflow_dispatch`) и никогда не выполняются для PR. Все они носят рекомендательный характер. -| Workflow | Что проверяет | Блокирует | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `nightly-property` | property-тесты fast-check со случайным seed и большим количеством запусков | **Нет** | -| `nightly-resilience` | порог роста heap, внедрение хаотических сбоев, нагрузочное/длительное тестирование k6 | **Нет** | -| `nightly-llm-security` | защиту promptfoo от инъекций (режим блокировки) и проверки garak (пропускаются без секрета провайдера) | **Нет** | -| `nightly-schemathesis` | фаззинг контракта OpenAPI (schemathesis) для запущенного OmniRoute с использованием `docs/openapi.yaml` — выявляет нарушения спецификации / необработанные ошибки 500 (Fase 8 B.4) | **Нет** | -| `nightly-mutation` | оценку мутационного тестирования Stryker для быстрого набора модульных тестов — выжившие мутанты выявляют слабые assert | **Нет** | -| `nightly-compat` | матрицу совместимости движка Node для поддерживаемых диапазонов `engines.node` | **Нет** | +| Рабочий процесс | Что проверяет | Блокировка | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `nightly-property` | Тесты свойств fast-check со случайным начальным значением и большим числом запусков | **Рекомендательная проверка** | +| `nightly-resilience` | Ограничение роста кучи, внедрение хаотических сбоев, нагрузочное/длительное тестирование k6 | **Рекомендательная проверка** | +| `nightly-llm-security` | Защиту promptfoo от инъекций (режим блокировки) и проверки garak (пропускаются при отсутствии секрета провайдера) | **Рекомендательная проверка** | +| `nightly-schemathesis` | Фаззинг контракта OpenAPI (schemathesis) на работающем OmniRoute с использованием `docs/openapi.yaml` — выявляет нарушения спецификации / необработанные ошибки 500 (этап 8 B.4) | **Рекомендательная проверка** | +| `nightly-mutation` | Показатель мутационного тестирования Stryker для быстрого набора модульных тестов — выжившие мутанты выявляют слабые проверки | **Рекомендательная проверка** | +| `nightly-compat` | Матрицу совместимости движка Node для поддерживаемых диапазонов `engines.node` | **Рекомендательная проверка** | --- @@ -522,42 +520,41 @@ CodeQL: По умолчанию → Расширенная. Не добавля ## Бэклог рационализации (оценка ROI — фаза 9, волна 3) -Этот перечень был сверен с `ci.yml` 2026-06-17 (в предыдущей версии были пропущены +Эта инвентаризация была сверена с `ci.yml` 2026-06-17 (в предыдущей версии были пропущены `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Оценка ROI сверенного набора выявила следующие кандидатуры на рационализацию. **Объединения представляют собой механические -изменения CI; включение обязательного режима и удаление — это решения в области политик, остающиеся за оператором.** Ничто из перечисленного ниже +изменения CI; переключение режимов и удаление — это решения по политикам, остающиеся за оператором.** Ничто из перечисленного ниже пока не применено. -**Также не задокументированы выше** (рекомендательные проверки с низкой информативностью): задание `docs-lint` -(markdownlint + Vale, для всего задания задано `continue-on-error`) и автономные рабочие процессы сканирования -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. Значение `semgrepFindings: 0` присутствует в -`quality-baseline.json`, но не подключено к блокирующему храповому механизму в `ci.yml` — в настоящее -время эта метрика изолирована. - -### Объединение / устранение дублирования (механические изменения, более низкий риск) - -Каждая кандидатура была проверена на соответствие фактическому состоянию шлюзов 2026-06-17 (доверяй, но проверяй); -несколько «очевидных» объединений, как выяснилось, скрывают технический долг и **не** являются чистыми -прямыми заменами. - -- **`check:docs-sync` запускается дважды** — отдельно в задании `lint`, а затем ещё раз внутри `check:docs-all` (`docs-sync-strict`) и в pre-commit-хуке husky. ✅ **ВЫПОЛНЕНО** — отдельный вызов из `lint` удалён. -- **Сканирование CVE** — ❌ **НЕ является чистым объединением.** `audit:deps` завершается с ошибкой при любой CVE высокой/критической серьёзности; `check:vuln-ratchet` (osv) завершается с ошибкой только при _регрессии_ относительно базового уровня (сейчас 1 MODERATE). Семантика различается — удаление `audit:deps` привело бы к потере абсолютного шлюза для высокой/критической серьёзности. Сохранить оба. -- **Обнаружение циклов** — ❌ **НЕ является чистым объединением.** `check:circular-deps` (dpdm) сообщает о **91 цикле** (поэтому эта проверка и является рекомендательной); её нельзя сделать блокирующей, не устранив сначала эти циклы, а область её действия шире, чем у успешно проходящей курируемой проверки `check:cycles`. Оставить `check:cycles` блокирующей; устранение 91 цикла dpdm — отдельная задача в бэклоге. -- **Сложность** — ✅ **ВЫПОЛНЕНО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): один проход ESLint, подсчёт по ruleId, поэтому базовые уровни цикломатической сложности+max-lines и когнитивной сложности остаются независимыми; отдельные `check:complexity` / `check:cognitive-complexity` сохранены для локального запуска с `--update`. -- **Защита от галлюцинаций `/api`** — ✅ **ВЫПОЛНЕНО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): одна инвентаризация `src/app/api` через ФС, openapi-routes + docs-symbols по-прежнему формируют отчёты независимо; отдельные проверки сохранены для локальных запусков. -- **`check:node-runtime` запускается в 11 заданиях** — ⚠️ **низкий ROI.** Каждое из них выполняется на отдельном раннере, а проверка занимает <1 с; общая экономия составит ~10 с ценой потери дешёвой проверки в каждом задании. Изменения того не стоят. -- **`typecheck:noimplicit:core` в CI lint** — ✅ **удалено из задания lint** (проверка была рекомендательной с `continue-on-error`); блокирующая проверка поверхности типов обеспечивается `typecheck:core` + `check:type-coverage`. Локальный скрипт сохранён. - -### Включить обязательный режим / принять решение (политика оператора) - -- `check:openapi-security-tiers` (рекомендательная) — ❌ **нельзя просто сделать блокирующей.** Она завершается с кодом 0, но предупреждает, что у нескольких маршрутов `traffic-inspector` в `LOCAL_ONLY_API_PREFIXES` отсутствует аннотация `x-loopback-only: true`. Для её обязательного применения необходимо сначала добавить эти аннотации в `openapi.yaml`. -- `typecheck:noimplicit:core` (рекомендательная) — в значительной степени перекрывается блокирующим храповым механизмом `check:type-coverage`. Преобразовать в храповую проверку или удалить избыточный второй проход `tsc`. -- `test:vitest:ui` (теперь **блокирующая**) — существовавшие ранее сбои явно исключены в `vitest.config.ts` с отслеживающими комментариями `// #8618`; новые сбои приводят к ошибке задания. -- `check:secrets` (gitleaks, блокирующий храповой механизм, зафиксированный на уровне 3 задокументированных ложноположительных результатов) — добавить эти 3 результата в список разрешённых, чтобы достичь 0, либо перевести проверку в рекомендательный режим. Перекрывается встроенным сканированием секретов GitHub + `check:public-creds`. -- `check:pr-evidence` (блокирующая, выполняет grep по тексту тела PR) — высокий риск ложноположительных результатов; её удаление ослабит контроль соблюдения жёсткого правила №18, поэтому это действительно вопрос политики. -- `semgrep` (автономная рекомендательная проверка) — пересекается с CodeQL по семействам OWASP; подключить её базовый уровень к храповому механизму или удалить. +**Также не задокументированы выше** (рекомендательные, низкий уровень сигнала): задание `docs-lint` +(markdownlint + Vale, всё задание с `continue-on-error`) и автономные рабочие процессы сканирования +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` присутствует в +`quality-baseline.json`, но не подключён к блокирующему храповому механизму в `ci.yml` — сейчас эта метрика +изолирована. + +### Объединение / устранение дублирования (механические изменения, меньший риск) + +Каждая кандидатура была проверена по фактическому состоянию гейтов на 2026-06-17 (доверяй, но проверяй); +оказалось, что несколько «очевидных» объединений скрывают технический долг и **не** являются беспроблемной заменой. + +- **`check:docs-sync` запускается дважды** — отдельно в задании `lint`, а затем ещё раз внутри `check:docs-all` (`docs-sync-strict`) и в pre-commit-хуке husky. ✅ **ГОТОВО** — отдельный вызов в `lint` удалён. +- **Сканирование CVE** — ❌ **НЕ является беспроблемным объединением.** `audit:deps` завершается с ошибкой при любой CVE уровня high/critical; `check:vuln-ratchet` (osv) завершается с ошибкой только при _регрессии_ относительно базового уровня (сейчас 1 MODERATE). Семантика различается — удаление `audit:deps` приведёт к потере абсолютного гейта для уровней high/critical. Сохранить оба. +- **Обнаружение циклов** — ✅ **ГОТОВО** (#15159 G-01/G-02). В старом тексте `check:cycles` назывался «зелёным, тщательно настроенным» гейтом, а его блокирующий статус обосновывался тем, что `check:circular-deps` (dpdm) обнаруживал 91 цикл. Этот зелёный статус был **ложноположительным**: `check:cycles` сканировал 5 подкаталогов (450 файлов), находил только статические конструкции `import|export … from` и отбрасывал все спецификаторы `@/` и `@omniroute/open-sse/`, поэтому не мог увидеть циклы с динамическим импортом и псевдонимами, преобладавшие в репозитории. Исправлено: теперь гейт обходит `src` + `open-sse` (5023 файла), собирает спецификаторы из AST TypeScript (поэтому `import("…")` учитывается, а `typeof import("…")` в позиции типа — нет) и разрешает `paths` из tsconfig. Он обнаруживает **14** циклов, а не 0. Поскольку 14 существовавших ранее циклов нельзя исправить в PR для гейта, `check:cycles` теперь является **храповым механизмом** (`--ratchet`, порог `metrics.cycles.value = 14` в `quality-baseline.json`, `direction: down`) — он блокирует любую _регрессию_, а количество циклов может только уменьшаться. CI запускает `npm run check:cycles:ratchet`. Постепенное устранение выполняется в рамках **A-01**. `check:circular-deps` (dpdm) остаётся рекомендательной более широкой второй проверкой. +- **Сложность** — ✅ **ГОТОВО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): один проход ESLint, подсчёт по ruleId, поэтому базовые уровни цикломатической сложности + максимального числа строк и когнитивной сложности остаются независимыми; отдельные `check:complexity` / `check:cognitive-complexity` сохранены для локального запуска с `--update`. +- **Защита от галлюцинаций `/api`** — ✅ **ГОТОВО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): одна инвентаризация `src/app/api` в файловой системе, openapi-routes + docs-symbols по-прежнему формируют отчёты независимо; отдельные проверки сохранены для локального запуска. +- **`check:node-runtime` запускается в 11 заданиях** — ⚠️ **низкий ROI.** Каждое выполняется на отдельном раннере, а проверка занимает <1 с; общая экономия составит ~10 с ценой потери дешёвой защиты в каждом задании. Не стоит вносимых изменений. +- **`typecheck:noimplicit:core` в CI lint** — ✅ **удалён из задания lint** (был рекомендательным с `continue-on-error`); блокирующая поверхность типов обеспечивается `typecheck:core` + `check:type-coverage`. Локальный скрипт сохранён. + +### Переключить / решить (политика оператора) + +- `check:openapi-security-tiers` (рекомендательный) — ❌ **НЕЛЬЗЯ беспроблемно перевести в блокирующий режим.** Он завершается с кодом 0, но предупреждает, что у нескольких маршрутов `traffic-inspector` в `LOCAL_ONLY_API_PREFIXES` отсутствует аннотация `x-loopback-only: true`. Для принудительного применения сначала необходимо добавить эти аннотации в `openapi.yaml`. +- `typecheck:noimplicit:core` (рекомендательный) — в значительной степени перекрывается блокирующим храповым механизмом `check:type-coverage`. Перевести на храповой механизм или удалить избыточный второй проход `tsc`. +- `test:vitest:ui` (теперь **блокирующий**) — существовавшие ранее сбои явно исключены в `vitest.config.ts` с отслеживающими комментариями `// #8618`; новые сбои приводят к провалу задания. +- `check:secrets` (gitleaks, блокирующий храповой механизм, зафиксированный на 3 задокументированных ложноположительных результатах) — добавить эти 3 результата в список разрешений, чтобы достичь 0, либо перевести проверку в рекомендательный режим. Перекрывается нативным сканированием секретов GitHub + `check:public-creds`. +- `check:pr-evidence` (блокирующий, ищет шаблоны в тексте тела PR) — высокий риск ложноположительных результатов; его удаление ослабит соблюдение Hard Rule #18, поэтому это действительно вопрос политики. +- `semgrep` (рекомендательный автономный процесс) — перекрывается с CodeQL по семействам OWASP; подключить его базовый уровень к храповому механизму или удалить. --- diff --git a/docs/i18n/si/CONTRIBUTING.md b/docs/i18n/si/CONTRIBUTING.md index e65bf5642ca..5ca128a4871 100644 --- a/docs/i18n/si/CONTRIBUTING.md +++ b/docs/i18n/si/CONTRIBUTING.md @@ -402,19 +402,19 @@ docs/ ## Pull Request පිරික්සුම් ලැයිස්තුව - [ ] පරීක්ෂණ සමත් වේ (`npm test`) -- [ ] ලින්ට් කිරීම සමත් වේ (`npm run lint`) -- [ ] ගොඩනැගීම සාර්ථක වේ (`npm run build`) -- [ ] නව පොදු ශ්රිත සහ අතුරුමුහුණත් සඳහා TypeScript වර්ග එක් කර ඇත -- [ ] දෘඪ-කේතනය කළ රහස් හෝ පෙරනිමි විකල්ප අගයන් නොමැත -- [ ] පොදු ඉහළ මට්ටමේ අක්තපත්ර `resolvePublicCred()` හරහා කේතයට ඇතුළත් කර ඇත ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) බලන්න), කිසිවිටෙක ලිටරල ලෙස නොවේ -- [ ] දෝෂ ප්රතිචාර `buildErrorBody()` / `sanitizeErrorMessage()` හරහා යොමු වේ — ප්රතිචාර බොඩි තුළ අමු ස්ටැක් ට්රේස් නොමැත ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) බලන්න) -- [ ] Shell විධාන (`exec` / `spawn`) ධාවනකාල අගයන් තන්තු අන්තර්නිවේෂණය හරහා නොව `env` හරහා ලබා දෙයි -- [ ] සියලු ආදාන Zod ස්කීමා මඟින් වලංගු කර ඇත -- [ ] පරිශීලකයාට පෙනෙන වෙනස්කම් සඳහා `changelog.d/{features|fixes|maintenance}/-.md` යටතේ වෙනස්කම් ලොග් **ඛණ්ඩයක්** එක් කර ඇත ([`changelog.d/README.md`](./changelog.d/README.md) බලන්න) — `CHANGELOG.md` සෘජුවම සංස්කරණය **නොකරන්න**; නිකුත් කිරීමේදී ඛණ්ඩ එක්රැස් කෙරෙන අතර ඒවා PR අතර කිසිවිටෙක ගැටුම් ඇති නොකරයි -- [ ] ලේඛන යාවත්කාලීන කර ඇත (අදාළ නම්) -- [ ] නව CodeQL / Secret-Scanning අනතුරු ඇඟවීම් විවෘත කර නැත, නැතහොත් සෑම එකක්ම අදාළ `docs/security/` ලේඛනය සඳහන් කරන තාක්ෂණික සාධාරණීකරණයක් සමඟ ප්රතික්ෂේප කර ඇත -- [ ] උප ක්රියාවලි ආරම්භ කරන මාර්ග (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` තුළ `isLocalOnlyPath()` ලෙස වර්ගීකරණය කර ඇත — [දැඩි රීතිය #15](docs/security/ROUTE_GUARD_TIERS.md) බලන්න -- [ ] commit පණිවිඩ තුළ `Co-Authored-By` ට්රේලර් නොමැත — commits ගබඩා හිමිකරුගේ Git අනන්යතාව යටතේ පමණක් දිස් විය යුතුය (දැඩි රීතිය #16) +- [ ] Linting සමත් වේ (`npm run lint`) +- [ ] Build කිරීම සාර්ථක වේ (`npm run build`) +- [ ] නව public functions සහ interfaces සඳහා TypeScript types එක් කර ඇත +- [ ] Hardcode කළ secrets හෝ fallback values නොමැත +- [ ] Public upstream credentials, literals ලෙස නොව `resolvePublicCred()` හරහා embed කර ඇත ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) බලන්න) +- [ ] Error responses, `buildErrorBody()` / `sanitizeErrorMessage()` හරහා යොමු වේ — response bodies තුළ raw stack traces නොමැත ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) බලන්න) +- [ ] Shell commands (`exec` / `spawn`), string interpolation හරහා නොව `env` හරහා runtime values ලබා දෙයි +- [ ] සියලු inputs, Zod schemas සමඟ validate කර ඇත +- [ ] පරිශීලකයාට පෙනෙන වෙනස්කම් සඳහා `changelog.d/{features|fixes|maintenance}/-.md` යටතේ Changelog **fragment** එකක් එක් කර ඇත ([`changelog.d/README.md`](./changelog.d/README.md) බලන්න) — `CHANGELOG.md` සෘජුව සංස්කරණය **නොකරන්න**; release අවස්ථාවේදී fragments එකතු කෙරෙන අතර PR අතර කිසිවිටෙක ගැටුම් ඇති නොවේ +- [ ] Documentation යාවත්කාලීන කර ඇත (අදාළ නම්) +- [ ] නව CodeQL / Secret-Scanning alerts කිසිවක් විවෘත කර නැත, නැතහොත් අදාළ `docs/security/` ලේඛනය සඳහන් කරන තාක්ෂණික සාධාරණීකරණයක් සමඟ ඒ සෑම එකක්ම ඉවත දමා ඇත +- [ ] Child processes ආරම්භ කරන routes (`/api/mcp/`, `/api/cli-tools/runtime/`), `src/server/authz/routeGuard.ts` තුළ `isLocalOnlyPath()` ලෙස වර්ගීකරණය කර ඇත — [දැඩි රීතිය #15](docs/security/ROUTE_GUARD_TIERS.md) බලන්න +- [ ] Commit messages තුළ AI/bot `Co-authored-by` trailers නොමැත (දැඩි රීතිය #16) — නැවත භාවිත කරන ලද කාර්යයේ මානව සහයෝගිතාකරුවන්ට සම්මත `Co-authored-by: Name ` trailers මඟින් ගෞරවය ලබා දී ඇත --- diff --git a/docs/i18n/si/docs/architecture/QUALITY_GATES.md b/docs/i18n/si/docs/architecture/QUALITY_GATES.md index a0b5c5e877e..e0fbb8971b8 100644 --- a/docs/i18n/si/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/si/docs/architecture/QUALITY_GATES.md @@ -17,261 +17,255 @@ ratchet මූලික රේඛාවක් හෝ සමත්/අසමත ## ගේට් ඉන්වෙන්ටරිය සහ ක්රියාත්මක කිරීමේ පැතිකඩ -### අපේක්ෂක පිළිගැනීම - -CI සහ Quality Gates වැඩප්රවාහ දෙකම ස්ථාවර තීන්දුවක් නිකුත් කරයි: `Gate / CI` සහ -`Gate / Quality`. ඒවායේ අනුවාදගත පිළිගැනීමේ ප්රතිපත්තිය සෑම ඉහළ-ප්රවාහ කාර්යයක්ම -අනිවාර්ය හෝ උපදේශනාත්මක ලෙස ලැයිස්තුගත කරයි. අදාළ වන අනිවාර්ය කාර්යයක් සාර්ථක විය යුතුය: -නොමැති, අවලංගු කළ, මඟහැරුණු, පොරොත්තු සහ නොදන්නා ප්රතිඵල මඟින් PASS තහවුරු කළ නොහැක. -වලංගු docs-only හෝ catalog-only වර්ගීකරණයක් මඟින් කේත මංතීරුවක් අදාළ නොවන බවට පත් කළ -හැකිය; කෙටුම්පත් PR එකක් පිළිගත් අපේක්ෂකයක් නොවේ. `hotfix` ලේබලයක් සාක්ෂි අවශ්යතාව -ඉවත් නොකරයි. - -වැඩප්රවාහ දෙකම PR, main/release ශාඛා වෙත pushes, අතින් dispatch කිරීම සහ -merge-group සිදුවීම් ආවරණය කරයි. Push, dispatch සහ merge-group සම්පූර්ණ තේරීම ක්රියාත්මක -කරයි. සාමාන්යයෙන් self-hosted runners තෝරන කාර්ය සඳහා forks සහ merge groups විසින් -hosted runners භාවිත කරයි; rollout කිරීමට පෙර ප්රමාණවත් hosted ධාරිතාවක් ඇති බව තහවුරු -කළ යුතුය. - -සෑම JSON ලදුපතක්ම check out කළ SHA, වැඩප්රවාහ ධාවනය සහ උත්සාහය හඳුනා දෙයි. -CLI එක checkout/event SHA නොගැළපීමක් ප්රතික්ෂේප කරයි. නව හෝ ඉවත් කළ මංතීරුවක් නිහඬව -අතුරුදහන් වීමට නොහැකි වන පරිදි, වැඩප්රවාහ පරීක්ෂණ මඟින් ප්රතිපත්ති සාමාජිකත්වය තීන්දු -කාර්යයේ `needs` ලැයිස්තුවට බැඳ තබයි. ලදුපත් ආවරණය කරන්නේ ඒවාට අදාළ වැඩප්රවාහය පමණි; -ප්රකාශනය, යෙදවීම හෝ පවතින උපදේශනාත්මක scanner එකක අභ්යන්තර ක්රියාකාරීත්වය නොවේ. -ශාඛා නීති තුළ check නම් දෙකම සක්රිය කිරීම වෙනම පරිපාලන වෙනස්කමකි; මෙම කාර්ය එකතු -කිරීමෙන් පමණක් ශාඛාවක් ආරක්ෂා නොවේ. +### අපේක්ෂක ඇතුළත් කිරීම + +CI සහ Quality Gates කාර්ය ප්රවාහ දෙකම ස්ථාවර තීන්දුවක් නිකුත් කරයි: `Gate / CI` සහ +`Gate / Quality`. ඒවායේ අනුවාදගත ඇතුළත් කිරීමේ ප්රතිපත්තිය සෑම උඩුගං කාර්යයක්ම +අනිවාර්ය හෝ උපදේශාත්මක ලෙස ලැයිස්තුගත කරයි. අදාළ වන අනිවාර්ය කාර්යයක් සාර්ථක විය යුතුය: නොමැති, +අවලංගු කළ, මඟහැරුණු, අපේක්ෂිත සහ නොදන්නා ප්රතිඵලවලට PASS තහවුරු කළ නොහැක. වලංගු +docs-only හෝ catalog-only වර්ගීකරණයකට කේත මංතීරුවක් අදාළ නොවන බවට පත් කළ හැක; +කෙටුම්පත් PR එකක් පිළිගත් අපේක්ෂකයෙකු නොවේ. `hotfix` ලේබලයක් සාක්ෂි අවශ්යතාව ඉවත් නොකරයි. + +කාර්ය ප්රවාහ දෙකම PR, main/release ශාඛා වෙත push කිරීම්, අතින් dispatch කිරීම් සහ +merge-group සිදුවීම් ආවරණය කරයි. Push, dispatch සහ merge-group සම්පූර්ණ තේරීම ක්රියාත්මක කරයි. Fork සහ +merge group, වෙනත් අවස්ථාවල self-hosted runner තෝරාගන්නා කාර්ය සඳහා hosted runner භාවිත කරයි; +නිකුත් කිරීමට පෙර ප්රමාණවත් hosted ධාරිතාව සත්යාපනය කළ යුතුය. + +සෑම JSON ලදුපතක්ම checkout කළ SHA, workflow run සහ attempt හඳුනාගනී. +CLI මඟින් checkout/event SHA නොගැළපීමක් ප්රතික්ෂේප කරයි. නව හෝ ඉවත් කළ මංතීරුවක් නිහඬව අතුරුදහන් වීමට නොහැකි වන පරිදි, +workflow පරීක්ෂණ මඟින් ප්රතිපත්ති සාමාජිකත්වය තීන්දුව ලබාදෙන කාර්යයේ `needs` ලැයිස්තුවට බැඳ තබයි. +ලදුපත් මඟින් ආවරණය කරන්නේ ඒවායේම කාර්ය ප්රවාහය මිස ප්රකාශනය, යෙදවීම හෝ +පවතින උපදේශාත්මක scanner එකක අභ්යන්තර ක්රියාකාරීත්වය නොවේ. ශාඛා නීති තුළ check නාම දෙකම සක්රිය කිරීම +වෙනම පරිපාලන වෙනසකි; මෙම කාර්ය එක් කිරීමෙන් පමණක් ශාඛාවක් ආරක්ෂා නොවේ. ### ස්ථිතික scan ඉන්වෙන්ටරිය අනුවාදගත npm-alias ඉන්වෙන්ටරිය සහ static-scan සාමාජිකත්වය -`config/quality/gate-manifest.json` තුළ ඇත. script නම් සහ නිශ්චිත command -`package.json` සමඟ සසඳා වලංගු කිරීමට `npm run check:gate-manifest` ධාවනය කරන්න; -එක් කිරීම්, ඉවත් කිරීම් සහ command වෙනස්වීම් නිසා local hook එක සහ CI තුළ ඇති -වෙනස්කම්-වර්ගීකරණ කාර්ය දෙකම අසාර්ථක වේ. alias එකක් යනු workflow job එකක්, matrix -instance එකක් හෝ test case එකක් නොවේ: මෙම ගණන් එකිනෙකට හුවමාරු කළ හැකි ලෙස ඉදිරිපත් -නොකළ යුතුය. - -තෝරාගත් aliases ක්රියාත්මක නොකර පරීක්ෂා කිරීමට `npm run quality:scan -- --list` හෝ -`npm run quality:scan:fast -- --list` භාවිත කරන්න. runner එක npm entrypoint එක කැඳවන -බැවින්, එහි runtime එක (වින්යාස කර ඇති තැන්වල Bun ද ඇතුළුව) නොවෙනස්ව පවතී. -manifest එක මෙම පැතිකඩවලින් පිටත aliases වෙනම කැඳවන ඒවා ලෙස සටහන් කරන අතර, read-only -scan පැතිකඩ තුළ maintenance commands තහනම් වේ. - -මෙම පැතිකඩ ආවරණය කරන්නේ static scan එක පමණි. ඒවා product tests, coverage, packaging, -external checks හෝ අපේක්ෂකයකුගේ සම්පූර්ණ release acceptance සහතික නොකරයි. -Workflow admission සඳහා සම්බන්ධිත `config/quality/admission-policy.json` සහ -`scripts/quality/admission-verdict.mjs` භාවිත වේ. Release-observer පැතිකඩ වෙනමම පවතී; -ඒවාට අදාළ checks සහ receipts ස්වාධීනව පරීක්ෂා කරන්න. පහත ගද්ය -ඉන්වෙන්ටරිය යොමුවක් පමණක් වන අතර, gate එකක් සැබවින්ම ධාවනය වූ බවට සාක්ෂියක් නොවේ. - -Scripts පිහිටා ඇත්තේ `scripts/check/` (policy gates) සහ `scripts/quality/` (ratchet engine) -යටතේය. CI සඳහා සත්යයේ මූලාශ්රය `.github/workflows/ci.yml` වේ. +`config/quality/gate-manifest.json` තුළ ඇත. script නාම සහ නිශ්චිත command +`package.json` සමඟ සසඳා වලංගු කිරීමට `npm run check:gate-manifest` ක්රියාත්මක කරන්න; එක් කිරීම්, ඉවත් කිරීම් සහ +command වෙනස්වීම් හේතුවෙන් local hook එක සහ CI තුළ change-classification කාර්ය යන දෙකම අසාර්ථක වේ. +Alias එකක් workflow job එකක්, matrix instance එකක් හෝ test case එකක් නොවේ: මෙම ගණන් +එකිනෙකට හුවමාරු කළ හැකි ලෙස ඉදිරිපත් නොකළ යුතුය. + +තෝරාගත් alias ක්රියාත්මක නොකර පරීක්ෂා කිරීමට `npm run quality:scan -- --list` හෝ `npm run quality:scan:fast -- --list` +භාවිත කරන්න. Runner එක npm entrypoint එක ක්රියාත්මක කරන බැවින්, +එහි runtime එක (වින්යාස කර ඇති තැන්වල Bun ද ඇතුළුව) සුරැකේ. +මෙම පැතිකඩවලට පිටත ඇති alias වෙනම ක්රියාත්මක වන ඒවා ලෙස manifest එකේ සටහන් කර ඇති අතර, +read-only scan පැතිකඩ තුළ maintenance command තහනම්ය. + +මෙම පැතිකඩ ආවරණය කරන්නේ static scan එක පමණි. ඒවා product test, +coverage, packaging, external check හෝ අපේක්ෂකයෙකුගේ සම්පූර්ණ release acceptance සහතික නොකරයි. +Workflow admission සඳහා සබැඳි `config/quality/admission-policy.json` සහ +`scripts/quality/admission-verdict.mjs` භාවිත කරයි. Release-observer පැතිකඩ වෙනම පවතී; +ඒවාට අදාළ check සහ receipt ස්වාධීනව පරීක්ෂා කරන්න. පහත ඇති විස්තරාත්මක +ඉන්වෙන්ටරිය යොමුවක් මිස gate එකක් සැබවින්ම ක්රියාත්මක වූ බවට සාක්ෂියක් නොවේ. + +Script පිහිටා ඇත්තේ `scripts/check/` (ප්රතිපත්ති gate) සහ `scripts/quality/` (ratchet engine) යටතේය. +CI සඳහා සත්යයේ මූලාශ්රය `.github/workflows/ci.yml` වේ. ### Release PR වේගවත් මාර්ගය (`quality.yml`) -`.github/workflows/quality.yml` මඟින් main/release PR, ආරක්ෂිත-ශාඛා pushes, dispatch සහ -merge groups සඳහා CI සම්පූර්ණ කරයි. PR මඟින් මාර්ග-පෙරහන් කළ වේගවත් checks භාවිත කරයි. -ස්ථිරව අක්රිය කර තිබූ අනුපිටපත් build එක ඉවත් කර ඇත; සැබෑ build/package/boot checks -CI තුළ දිගටම පවතී. - -| කාර්යය | විෂය පථය | අවහිරකාරී | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `Docs Gates (fast-path)` | Docs/code PR; API docs refs සහ docs-all | ඔව් | -| `Fast Quality Gates` | Code PR; static checks, typecheck, dashboard typecheck, බලපෑමට ලක් වූ unit tests | ඔව් | -| `Forgotten sibling tests` | Code PR; වෙනස් කළ modules, static consumers සහ අපේක්ෂිත sibling tests වෙත හඹා යයි; barrel සහ dynamic-import මාර්ග, යොමු කළ allowlist ව්යතිරේක සමඟ උපදේශනාත්මක diagnostics ලෙස වාර්තා කෙරේ | **උපදේශනාත්මක** | -| `Vitest (fast-path)` | Code PR; වේගවත් vitest suite | ඔව් | -| `Unit Tests fast-path` | Code PR; 4-shard unit suite | ඔව් | -| `No new ESLint warnings` | Code PR; suppressions-aware lint guard | ඔව්, forks ද ඇතුළුව | -| `Merge integrity (changelog + generated skills)` | කෙටුම්පත් නොවන PR; changelog සහ generated skill සමමුහුර්තකරණය | ඔව්, forks ද ඇතුළුව | - -#### අමතක වූ sibling tests වාර්තාව - -`npm run check:forgotten-sibling-tests` test-impact map එක පිටුපස ඇති import resolver එක -නැවත භාවිත කරයි. වෙනස් කළ සෑම production module එකක් සඳහාම, අපේක්ෂිත -test එක pull-request diff තුළ නොමැති විට එය නිර්ණායක -`changed module/symbol -> static consumer -> candidate sibling test` දාම වාර්තා කරයි. -කිසියම් blocking rollout එකකට පෙර calibration කිරීම සඳහා Markdown සාරාංශය සහ JSON -ප්රතිඵලය `forgotten-sibling-tests` workflow artifact එක ලෙස රඳවා තබා ගනී. - -Barrel නැවත අපනයන සහ ගතික ආයාත විභේදන රෝගනිර්ණ සඳහා පමණි; ඒවා කිසි විටෙකත් +`.github/workflows/quality.yml` මඟින් main/release PR, ආරක්ෂිත ශාඛා වෙත +push කිරීම්, dispatch සහ merge group සඳහා CI පූරණය කරයි. PR මඟින් path-filtered වේගවත් check භාවිත කරයි. ස්ථිරව +අක්රිය කළ අනුපිටපත් build එක ඉවත් කර ඇත; සැබෑ build/package/boot check CI තුළ පවතී. + +| කාර්යය | විෂය පථය | අවහිරකාරී | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | +| `Docs Gates (fast-path)` | Docs/code PR; API docs යොමු සහ docs-all | ඔව් | +| `Fast Quality Gates` | Code PR; static check, typecheck, dashboard typecheck, බලපෑමට ලක්වූ unit test | ඔව් | +| `Forgotten sibling tests` | Code PR; වෙනස් කළ module static consumer සහ අපේක්ෂිත sibling test වෙත අනුරේඛනය කරයි; barrel සහ dynamic-import මාර්ග, යොමු කළ allowlist ව්යතිරේක සමඟ උපදේශාත්මක diagnostics ලෙස වාර්තා කරයි | **උපදේශාත්මකයි** | +| `Vitest (fast-path)` | Code PR; වේගවත් vitest කට්ටලය | ඔව් | +| `Unit Tests fast-path` | Code PR; shard 4ක unit කට්ටලය | ඔව් | +| `No new ESLint warnings` | Code PR; suppression පිළිබඳව සැලකිලිමත් වන lint guard | ඔව්, fork ද ඇතුළුව | +| `Merge integrity (changelog + generated skills)` | කෙටුම්පත් නොවන PR; changelog සහ ජනනය කළ skill සමමුහුර්තකරණය | ඔව්, fork ද ඇතුළුව | + +#### අමතක වූ sibling test වාර්තාව + +`npm run check:forgotten-sibling-tests` මඟින් test-impact map එක පිටුපස ඇති import resolver නැවත භාවිත කරයි. +වෙනස් කළ සෑම production module එකක් සඳහාම, අපේක්ෂිත +test එක pull-request diff එකේ නොමැති විට එය නියතික +`changed module/symbol -> static consumer -> candidate sibling test` දාම වාර්තා කරයි. අවහිරකාරී rollout එකකට පෙර ක්රමාංකනය සඳහා Markdown සාරාංශය සහ JSON ප්රතිඵලය +`forgotten-sibling-tests` workflow artifact එක ලෙස රඳවා තබයි. + +Barrel නැවත-අපනයන සහ ගතික ආයාත විභේදන රෝගනිශ්චය සඳහා පමණි; ඒවා කිසිවිටෙකත් අවහිර කරන සොයාගැනීමක් නිර්මාණය නොකරයි. සමාලෝචනය කළ ව්යතිරේක -`config/quality/forgotten-sibling-allowlist.json` තුළ පවතී. සෑම ඇතුළත් කිරීමක්ම පරිභෝජකයා සහ අපේක්ෂක -පරීක්ෂණය නම් කළ යුතු අතර, නිශ්චිත හේතු දැක්වීමක් ලබා දී GitHub issue එකකට හෝ pull request එකකට සබැඳියක් යෙදිය යුතුය. වැරදි ලෙස සැකසූ ඇතුළත් කිරීම් -පෙරනිමියෙන් අසාර්ථක වේ. ව්යතිරේකවලට මකා දැමූ අපේක්ෂක පරීක්ෂණයක් හෝ `.skip`/`.todo` එක් කරන diff එකක් යටපත් කළ නොහැක; -assertion දුර්වල කිරීම සහ අනෙකුත් ආවරණය කිරීම් ස්වාධීනව අවහිර කරන -`check:test-masking` gate එක යටතේම පවතී. +`config/quality/forgotten-sibling-allowlist.json` තුළ පවතී. සෑම ඇතුළත් කිරීමක්ම පාරිභෝගිකයා සහ අපේක්ෂක +පරීක්ෂණය නම් කළ යුතු අතර, නිශ්චිත හේතු දැක්වීමක් ලබා දී GitHub ගැටලුවකට හෝ pull request එකකට සබැඳියක් එක් කළ යුතුය. වැරදි ලෙස සැකසූ ඇතුළත් කිරීම් +සංවෘත ආකාරයෙන් අසාර්ථක වේ. ව්යතිරේකවලට මකා දැමූ අපේක්ෂක පරීක්ෂණයක් හෝ `.skip`/`.todo` එක් කරන වෙනසක් යටපත් කළ නොහැක; +assertion දුර්වල කිරීම සහ අනෙකුත් වසන් කිරීම් ස්වාධීනව අවහිර කරන +`check:test-masking` දොරටුව යටතේම පවතී. ### කාර්යය: `lint` -`main` වෙත යොමු කරන සෑම PR එකකදීම ක්රියාත්මක වේ. අසාර්ථක වුවහොත් merge කිරීම අවහිර කරයි. - -| ස්ක්රිප්ට් (`npm run ...`) | වලංගු කරන්නේ | අවහිර කරයිද | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Node.js අනුවාදය සහාය දක්වන පරාසය තුළ පවතී | ඔව් | -| `check:cycles` | චක්රීය ආයාත — සියලුම `src/` + `open-sse/` මොඩියුල | ඔව් | -| `check:route-validation:t06` | සියලුම routes මත Zod schemas පවතී (Tier 6 ප්රතිපත්තිය) | ඔව් | -| `check:any-budget:t11` | `@ts-expect-error // any` ගණන අයවැය ඉක්මවා නොයයි (Tier 11 catraca) | ඔව් | -| `check:provider-consistency` | `providers.ts` හි ඇති සෑම provider එකකටම `providerRegistry.ts` හි ගැළපෙන entry එකක් ඇත (එමෙන්ම ප්රතිවිරුද්ධ දිශාවටද, allowlist එක තුළ) | ඔව් | -| `check:model-lifecycle` | අතින් නඩත්තු කරන routing table තුන checked-in lifecycle snapshot එක (#11503) සමඟ අනුකූලව පවතී: `FITNESS_TABLE` (`taskFitness.ts`) මඟින් `REGISTRY` හරහා route කළ හැකි retired id එකකටවත් score ලබා නොදේ; සෑම `BUILT_IN_ALIASES` target එකක්ම `REGISTRY` හි තිබෙන අතර retired-id snapshot එකෙහි නොමැත; තවමත් `REGISTRY` හි ඇති සෑම retired id එකක්ම forward කර හෝ `allowedRetiredInCatalog` හි ලැයිස්තුගත කර ඇත; තවද `DEFAULT_DEGRADATION_MAP` හි කිසිදු source එකක් හෝ target එකක් එම snapshot එකෙහි retired ලෙස නොපෙන්වයි. model එකක් දැනට සජීවී upstream එකකින් සපයන බව මෙයින් සනාථ නොවේ. Offline — `config/quality/model-lifecycle.json` සමඟ සසඳයි; එය `npm run quality:refresh-model-lifecycle` මඟින් අතින් refresh කෙරේ (network; CI සමඟ සම්බන්ධ කර නැත). `allowedRetiredInCatalog` යනු burn-down ratchet එකකි: entry එකක් එක් කළ යුත්තේ tracking issue එකක් සමඟ පමණි. | ඔව් | -| `check:fetch-targets` | client-side `src/` හි ඇති සෑම `fetch("/api/...")` එකක්ම සැබෑ `route.ts` එකකට resolve වේ | ඔව් | -| `check:deps` | repo එකේ ඇති සෑම `package.json` එකක් පුරාම `npm install` කළ හැකි සියලු deps `dependency-allowlist.json` හි ඇත; නව unpinned හෝ slopsquatted packages සලකුණු කෙරේ | ඔව් | -| `audit:deps` | `npm audit` (root + electron) — high/critical advisories කිසිවක් නැත (osv `check:vuln-ratchet` සමඟ අතිච්ඡාදනය වේ; Rationalization Backlog බලන්න) | ඔව් | -| `check:lockfile` | `package-lock.json` අඛණ්ඩතාව — https registry, integrity hashes, host overrides නොමැත | ඔව් | -| `check:licenses` | නිෂ්පාදන පරායත්තතා සඳහා SPDX බලපත්ර අවසර ලැයිස්තුව | ඔව් | -| `check:tracked-artifacts` | build artifacts / commit කළ `node_modules` symlinks නොමැත (husky pre-commit තුළද ධාවනය වේ; pre-push හිතාමතාම සැහැල්ලුවෙන් තබා ඇත — #6716) | ඔව් | -| `check:ai-attribution` | PR commits, title හෝ body තුළ AI/bot `Co-Authored-By` trailer හෝ AI-generation footer නොමැත — දැඩි රීතිය #16 (`quality.yml` හි PR→`release/**` සඳහා වන fast-gates loop තුළ — event payload එක කියවයි, PR නොවන විට කිසිවක් නොකරයි — සහ `ci.yml` lint තුළ PR→`main` සඳහා PR-පමණක් වන පියවරක්; එසේම husky `commit-msg` hook එකද; මානව සම-කර්තෘවරුන්ට අවසර ඇත; #14436) | -| `check:vitest-exclusions` | සෑම Vitest exclusion එකක්ම tracking issue එකක් නම් කරන අතර `config/quality/vitest-exclusions.json` තුළ දිස්වේ (#13204) | ඔව් | -| `check:file-size` | කිසිදු source file එකක් extension එකකට අදාළ උපරිම සීමාව ඉක්මවන්නේ නැත (ratchet: විශාල ලෙස ස්ථිර කළ ගොනු `frozen` ලැයිස්තුවේ ඇත) | ඔව් | -| `check:error-helper` | executors/handlers තුළ error responses සඳහා `buildErrorBody()` / `sanitizeErrorMessage()` භාවිත වේ (දැඩි රීතිය #12) | ඔව් | -| `check:migration-numbering` | Migration SQL ගොනු හිඩැස් හෝ අනුපිටපත් නොමැතිව අනුක්රමිකව අංකනය කර ඇත | ඔව් | -| `check:public-creds` | `publicCreds.ts` පිටත සෘජුව ඇතුළත් කළ OAuth `client_id`/`client_secret` හෝ Firebase Web යතුරු නොමැත (දැඩි රීතිය #11) | ඔව් | -| `check:db-rules` | `src/lib/db/` මොඩියුලවලින් පිටත අමු SQL නොමැත; `localDb.ts` වෙතින් barrel-imports නොමැත (දැඩි රීති #2/#5) | ඔව් | -| `check:known-symbols` | ඒවායේ dispatch වගුවල ලියාපදිංචි කර ඇති provider executors, routing strategies සහ translators තැටියේ ඇති ගොනුවලට ගැළපේ — අනාථ හෝ ප්රකාශ නොකළ symbols නොමැත | ඔව් | -| `check:route-guard-membership` | child process එකක් ආරම්භ කරන සෑම route එකක්ම `isLocalOnlyPath()` මඟින් වර්ගීකරණය කර ඇත (දැඩි රීති #15/#17) | ඔව් | -| `check:test-discovery` | repo එකේ ඇති සෑම `*.test.ts` / `*.spec.ts` ගොනුවක්ම අවම වශයෙන් එක් test runner එකක් මඟින් රැස් කරනු ලැබේ (ratchet: `test-discovery-baseline.json` හි අනාථ ලැයිස්තුව හැකිලීම පමණක් සිදු විය හැක) | ඔව් | -| `check:agent-skills-sync` | ජනනය කළ agent-skills කෘති ඒවායේ මූලාශ්ර නාමාවලිය සමඟ ගැළපේ (වෙනස්වීමක් නැත) | -| `check:provider-asset-provenance` | සැපයුම්කරුගේ ලාංඡන/වත්කම් සඳහා වාර්තාගත මූලාරම්භ සටහනක් ඇත | -| `lint:json` | JSON වින්යාස ගොනු නිවැරදිව විග්රහ වන අතර repo lint නීති සපුරාලයි | -| `typecheck:core` | දෝෂ රහිත TypeScript සම්පාදනය (උපදේශාත්මක අනතුරු ඇඟවීම් පමණි) | ඔව් | -| `typecheck:noimplicit:core` | දැඩි `noImplicitAny` — ඉදිරියට යොමු වූවකි; පෙර සිට පවතින බොහෝ ඇමතුම් ස්ථාන සඳහා තවමත් විවරණ අවශ්ය වේ | **උපදේශාත්මකයි** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` වෙත සීමා කළ `tsc` (#7033) — `typecheck:core` හි තෝරාගත් ගොනු 27ක අවසර ලැයිස්තුවට කිසිදු dashboard TSX ගොනුවක් ඇතුළත් නොවන අතර, `next build` ද එය කිසිවිටෙක type-check නොකරයි (`next.config.mjs` විසින් `ignoreBuildErrors: true` සකසයි); එබැවින් එහි අනාථ-හඳුන්වනය ප්රතිගමන (#6625/#6909) CI වෙත නොපෙනුණි. ස්ථාවර කළ එක්-ගොනුවකට/එක්-TS-code එකකට අදාළ සංඛ්යා පාදක රේඛාවකට (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` හි ඇති එකම කල් ඉකුත් වූ අයිතම බලාත්මක කිරීමේ රටාව) එරෙහිව වෙනස්කම් සසඳයි — පාදක රේඛාවේ සංඛ්යාව ඉක්මවන නව දෝෂ පමණක් දොරටුව අසමත් කරයි; පෙර සිට පවතින දෝෂයක් නිවැරදි කළ විට `--update` සමඟ සීමාව පහළට ගෙන එන්න. | ඔව් | +`main` වෙත යොමු කරන සෑම PR එකකදීම ක්රියාත්මක වේ. අසාර්ථක වුවහොත් ඒකාබද්ධ කිරීම අවහිර කරයි. + +| ස්ක්රිප්ට් (`npm run ...`) | වලංගු කරන්නේ | අවහිර කිරීම | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Node.js අනුවාදය සහාය දක්වන පරාසය තුළ පවතී | ඔව් | +| `check:cycles` | `src/` + `open-sse/` සියල්ල හරහා ඇති චක්රීය ආයාත (AST-පදනම් වූ, tsconfig `paths` විභේදනය කළ). තනිව ධාවනය කළ විට = උපදේශාත්මක වන අතර, චක්ර ලැයිස්තුගත කරයි. `check:cycles:ratchet` (CI ධාවනය කරන්නේ මෙයයි) ගණන `quality-baseline.json` තුළ ඇති `metrics.cycles` උපරිම සීමාව ඉක්මවන විට අවහිර කරයි — දැනට 14, `direction: down`, එබැවින් එය අඩු වීමට පමණක් හැකිය (#15159 G-01/G-02) | ඔව් (ratchet) | +| `check:route-validation:t06` | සියලු routes මත Zod schemas පවතින බව (Tier 6 ප්රතිපත්තිය) | ඔව් | +| `check:any-budget:t11` | `@ts-expect-error // any` ගණන අයවැය ඉක්මවා නොයන බව (Tier 11 catraca) | ඔව් | +| `check:provider-consistency` | `providers.ts` හි ඇති සෑම provider එකකටම `providerRegistry.ts` හි ගැළපෙන entry එකක් ඇත (සහ ප්රතිවිරුද්ධවද, allowlist සීමාව තුළ) | ඔව් | +| `check:model-lifecycle` | අතින් නඩත්තු කරන routing tables තුන checked-in lifecycle snapshot (#11503) සමඟ අනුකූලව පවතී: `FITNESS_TABLE` (`taskFitness.ts`) මඟින් `REGISTRY` වෙත route කළ නොහැකි retired id එකකටවත් score ලබා නොදේ; සෑම `BUILT_IN_ALIASES` target එකක්ම `REGISTRY` හි පවතින අතර retired-id snapshot එකෙහි නොපවතී; තවමත් `REGISTRY` හි ඇති සෑම retired id එකක්ම forward කර ඇත, නැතහොත් `allowedRetiredInCatalog` හි ලැයිස්තුගත කර ඇත; තවද `DEFAULT_DEGRADATION_MAP` හි කිසිදු source එකක් හෝ target එකක් එම snapshot එකෙහි retired ලෙස නොපෙන්වයි. මෙය model එකක් දැනට සජීවී upstream එකක් මඟින් සපයන බව සනාථ නොකරයි. Offline — `config/quality/model-lifecycle.json` සමඟ සසඳයි; එය `npm run quality:refresh-model-lifecycle` මඟින් අතින් refresh කරනු ලැබේ (network; CI වෙත සම්බන්ධ කර නැත). `allowedRetiredInCatalog` යනු burn-down ratchet එකකි: entry එකක් එක් කළ යුත්තේ tracking issue එකක් සමඟ පමණි. | ඔව් | +| `check:fetch-targets` | client-side `src/` තුළ ඇති සෑම `fetch("/api/...")` එකක්ම සැබෑ `route.ts` එකකට resolve වේ | ඔව් | +| `check:deps` | repo එකෙහි සෑම `package.json` එකක් පුරාම ඇති `npm install` කළ හැකි සියලු deps, `dependency-allowlist.json` හි ඇත; pin නොකළ හෝ slopsquatted වූ නව packages flag කරනු ලැබේ | ඔව් | +| `audit:deps` | `npm audit` (root + electron) — high/critical advisories කිසිවක් නැත (osv `check:vuln-ratchet` සමඟ overlap වේ; Rationalization Backlog බලන්න) | ඔව් | +| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hashes, host overrides නොමැත | ඔව් | +| `check:licenses` | නිෂ්පාදන පරායත්තතා සඳහා SPDX බලපත්ර අවසර ලැයිස්තුව | ඔව් | +| `check:tracked-artifacts` | build artifacts / commit කළ `node_modules` symlinks නොමැත (husky pre-commit තුළද ධාවනය වේ; pre-push හිතාමතාම සැහැල්ලුවෙන් තබා ඇත — #6716) | ඔව් | +| `check:ai-attribution` | PR commits, title හෝ body තුළ AI/bot `Co-Authored-By` trailer හෝ AI-generation footer නොමැත — දැඩි රීතිය #16 (`quality.yml` හි PR→`release/**` සඳහා වන fast-gates loop එක තුළ — event payload එක කියවයි, PR නොවන විට කිසිවක් නොකරයි — සහ PR→`main` සඳහා `ci.yml` lint හි PR-පමණක් වන පියවරක්; එසේම husky `commit-msg` hook එක; මානව co-authors සඳහා අවසර ඇත; #14436) | +| `check:vitest-exclusions` | සෑම Vitest exclusion එකක්ම tracking issue එකක් නම් කරන අතර `config/quality/vitest-exclusions.json` තුළ දිස් වේ (#13204) | ඔව් | +| `check:file-size` | කිසිදු source file එකක් එහි extension එකට අදාළ උපරිම සීමාව ඉක්මවා නොයයි (ratchet: විශාල files `frozen` ලැයිස්තුවේ ස්ථිර කර ඇත) | ඔව් | +| `check:error-helper` | executors/handlers තුළ error responses සඳහා `buildErrorBody()` / `sanitizeErrorMessage()` භාවිත කරයි (දැඩි රීතිය #12) | ඔව් | +| `check:migration-numbering` | Migration SQL ගොනු හිඩැස් හෝ අනුපිටපත් නොමැතිව අනුක්රමිකව අංකනය කර ඇත | ඔව් | +| `check:public-creds` | `publicCreds.ts` පිටත literal OAuth `client_id`/`client_secret` හෝ Firebase Web යතුරු නොමැත (දැඩි රීතිය #11) | ඔව් | +| `check:db-rules` | `src/lib/db/` මොඩියුලවලින් පිටත raw SQL නොමැත; `localDb.ts` වෙතින් barrel-imports නොමැත (දැඩි රීති #2/#5) | ඔව් | +| `check:known-symbols` | ඒවායේ dispatch වගුවල ලියාපදිංචි කර ඇති provider executors, routing strategies සහ translators තැටියේ ඇති ගොනු සමඟ ගැළපේ — අනාථ හෝ ප්රකාශ නොකළ symbols නොමැත | ඔව් | +| `check:route-guard-membership` | child process එකක් ආරම්භ කරන සෑම route එකක්ම `isLocalOnlyPath()` මඟින් වර්ගීකරණය කර ඇත (දැඩි රීති #15/#17) | ඔව් | +| `check:test-discovery` | repo එකේ ඇති සෑම `*.test.ts` / `*.spec.ts` ගොනුවක්ම අවම වශයෙන් එක් test runner එකක් මඟින් එකතු කරනු ලැබේ (ratchet: `test-discovery-baseline.json` හි orphan ලැයිස්තුව හැකිලීමට පමණක් හැකිය) | ඔව් | +| `check:agent-skills-sync` | ජනනය කළ agent-skills කලාකෘති ඒවායේ මූලාශ්ර නාමාවලියට ගැළපේ (වෙනස්වීමක් නොමැත) | +| `check:provider-asset-provenance` | සැපයුම්කරුගේ ලාංඡන/වත්කම් සඳහා වාර්තා කළ මූලාශ්ර ප්රවේශයක් ඇත | +| `lint:json` | JSON වින්යාස ගොනු නිවැරදිව විග්රහ වන අතර repo lint නීති සපුරාලයි | +| `typecheck:core` | දෝෂ නොමැති TypeScript සම්පාදනය (උපදේශාත්මක අනතුරු ඇඟවීම් පමණි) | ඔව් | +| `typecheck:noimplicit:core` | දැඩි `noImplicitAny` — අනාගතය ඉලක්ක කරගත් පරීක්ෂාවකි; පෙර සිට පවතින ඇමතුම් ස්ථාන බොහොමයකට තවමත් විවරණ අවශ්ය වේ | **උපදේශාත්මකයි** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` වෙත සීමා කළ `tsc` (#7033) — `typecheck:core` හි තෝරාගත් ගොනු 27ක අවසර ලැයිස්තුවට කිසිදු dashboard TSX ගොනුවක් ඇතුළත් නොවන අතර, `next build` ද එය කිසිවිටෙක වර්ග-පරීක්ෂා නොකරයි (`next.config.mjs` තුළ `ignoreBuildErrors: true` සකසයි); එබැවින් එහි තිබූ අනාථ හඳුනාගැනීම් සම්බන්ධ ප්රතිගමන (#6625/#6909) CI වෙත නොපෙනුණි. ස්ථිර කළ එක්-ගොනුවකට/එක්-TS-code එකකට අදාළ ගණන් මූලරේඛාවකට (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` හි ඇති යල්පැනීම බලාත්මක කිරීමේ රටාවම) එරෙහිව වෙනස්කම් සසඳයි — මූලරේඛාගත ගණන ඉක්මවන නව දෝෂ පමණක් දොරටුව අසමත් කරයි; පෙර සිට පැවති දෝෂයක් නිවැරදි කළ විට `--update` සමඟ මූලරේඛාව පහළට සකසන්න. | ඔව් | ### කාර්යය: `quality-gate` `test-coverage` පසු ධාවනය වේ. අසමත් වුවහොත් ඒකාබද්ධ කිරීම අවහිර කරයි. -| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිර කිරීම | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -| `quality:collect` | `quality-metrics.json` නිකුත් කරයි (ESLint අනතුරු ඇඟවීම් ගණන, ඒකාබද්ධ කළ shard වාර්තාවෙන් ආවරණය) | ඔව් (ratchet ට පෙර ක්රියාත්මක වේ) | -| `quality:ratchet` | `quality-baseline.json` හි සෑම මිනුමක්ම පසුබැස නැත (ESLint අනතුරු ඇඟවීම් ≤ baseline; ආවරණය ≥ baseline) | ඔව් | -| `check:duplication` | කේත අනුපිටපත් වීම (jscpd@4) `quality-baseline.json` හි baseline ඉක්මවා නොයයි | ඔව් | -| `check:complexity` | ගොනු-මට්ටමේ cyclomatic සංකීර්ණතාව සීමාව ඉක්මවා නොයයි (මූලික ESLint `complexity` + `max-lines-per-function`) | ඔව් | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — වෙනම ESLint ධාවනයකි; CI තුළ දෙකම තනි `check:complexity-ratchets` පියවර ලෙස ඒකාබද්ධ කර ධාවනය කරයි | ඔව් | -| `check:dead-code` | භාවිත නොකරන exports / ගොනු සඳහා වන ratchet (knip), baseline සමඟ සැසඳීමේදී පසුබැස නැත | ඔව් | -| `check:compression-budget` | සම්පීඩන benchmark අයවැය — එක් එක් engine සඳහා token-savings අවම සීමාවන් පසුබැසිය නොහැක | ඔව් | -| `check:type-coverage` | ටයිප් කළ ප්රතිශතය සඳහා වන ratchet (`type-coverage`) පසුබැස නැත; බොහෝ දුරට `typecheck:noimplicit:core` අන්තර්ග්රහණය කරයි | ඔව් | -| `check:codeql-ratchet` | විවෘත CodeQL ඇඟවීම් ගණන පසුබැස නැත (`gh api` හරහා කියවයි; token නොමැති විට සුමටව මඟ හරියි) — නැවුම් කිරීමේ වාර ගණන සහ අතින් trigger කිරීම: පහත "CodeQL ratchet" බලන්න | ඔව් | +| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිර කිරීම | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `quality:collect` | `quality-metrics.json` නිකුත් කරයි (ESLint අනතුරු ඇඟවීම් ගණන, ඒකාබද්ධ කළ shard වාර්තාවෙන් ආවරණය) | ඔව් (ratchetට පෙර) | +| `quality:ratchet` | `quality-baseline.json` හි සෑම මිනුමක්ම පසුබැසී නොමැත (ESLint අනතුරු ඇඟවීම් ≤ මූලික අගය; ආවරණය ≥ මූලික අගය) | ඔව් | +| `check:duplication` | කේත අනුපිටපත් වීම (jscpd@4) `quality-baseline.json` හි මූලික අගය ඉක්මවා නොයයි | ඔව් | +| `check:complexity` | ගොනු මට්ටමේ චක්රීය සංකීර්ණතාව සීමාව ඉක්මවා නොයයි (මූලික ESLint `complexity` + `max-lines-per-function`) | ඔව් | +| `check:cognitive-complexity` | ප්රජානන සංකීර්ණතා ratchet (`eslint-plugin-sonarjs`) — වෙනම ESLint ධාවනයකි; CI විසින් දෙකම තනි `check:complexity-ratchets` පියවර ලෙස ඒකාබද්ධ කර ධාවනය කරයි | ඔව් | +| `check:dead-code` | භාවිත නොකළ exports / ගොනු ratchet (knip) මූලික අගයට සාපේක්ෂව පසුබැසී නොමැත | ඔව් | +| `check:compression-budget` | සම්පීඩන මිණුම් ලකුණු අයවැය — එක් එක් engine සඳහා token ඉතිරිකිරීමේ අවම අගයන් පසුබැසිය යුතු නොවේ | ඔව් | +| `check:type-coverage` | type කර ඇති ප්රතිශතයේ ratchet (`type-coverage`) පසුබැසී නොමැත; බොහෝ දුරට `typecheck:noimplicit:core` ආවරණය කරයි | ඔව් | +| `check:codeql-ratchet` | විවෘත CodeQL ඇඟවීම් ගණන පසුබැසී නොමැත (`gh api` හරහා කියවයි; token නොමැතිව සුමටව මඟ හරී) — යාවත්කාලීන කිරීමේ වාර ගණන සහ අතින් ක්රියාත්මක කිරීම: පහත "CodeQL ratchet" බලන්න | ඔව් | ### කාර්යය: `quality-extended` -සම්පූර්ණ කාර්යයම උපදේශනාත්මකය (`continue-on-error: true`). npm-මත පදනම් වූ ratchets +සම්පූර්ණ කාර්යයම උපදේශාත්මකය (`continue-on-error: true`). npm-පදනම් වූ ratchets සැබෑ ලෙස ධාවනය වේ; බාහිර scanners `gh release download` හරහා ස්ථාපනය වන අතර binary එකක් -තවමත් නොමැති විට ස්වයංක්රීයව මඟ හරියි (exit 0). +තවමත් නොමැති විට ස්වයංක්රීයව මඟ හරී (exit 0). -| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිර කිරීම | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `check:circular-deps` | චක්රීය පරායත්තතා නොමැත (dpdm) | **උපදේශනාත්මක** | -| `check:bundle-size` | Bundle ප්රමාණය සීමාව ඉක්මවා නොයයි | **උපදේශනාත්මක** | -| `check:secrets` | රහස් තොරතුරු පරිලෝකනය (gitleaks) — binary එක නොමැති නම් මඟ හරියි | **උපදේශනාත්මක** | -| `check:vuln-ratchet` | පරායත්තතා දුර්වලතා (osv-scanner) පසුබැස නැත — binary එක නොමැති නම් මඟ හරියි | **උපදේශනාත්මක** | -| `check:workflows` | Workflow lint කිරීම (actionlint + zizmor); නොමැති/බිඳුණු scanners, වලංගු නොවන වාර්තා හෝ නොමැති ratchet baseline එකක් INCOMPLETE ලෙස අසාර්ථක වේ. වලංගු සොයාගැනීම් තෝරාගත් strict/advisory/ratchet ප්රතිපත්තිය අනුගමනය කරයි | ක්රියාත්මක කිරීම අවශ්යයි; CI හි zizmor ratchet අවහිර කරයි | -| `check:openapi-breaking` | මූලික branch එකට සාපේක්ෂව පොදු API ගිවිසුමේ (`openapi.yaml`) බිඳවැටෙන වෙනස්කම් (oasdiff) — `openapiBreaking=N` නිකුත් කරයි; oasdiff නොමැති නම් හෝ මූලික spec එක resolve කළ නොහැකි නම් මඟ හරියි | **උපදේශනාත්මක** | +| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිර කිරීම | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| `check:circular-deps` | චක්රීය dependencies නොමැත (dpdm) | **උපදේශාත්මක** | +| `check:bundle-size` | Bundle ප්රමාණය සීමාව ඉක්මවා නොයයි | **උපදේශාත්මක** | +| `check:secrets` | රහස් පරිලෝකනය (gitleaks) — binary එක නොමැති නම් මඟ හරී | **උපදේශාත්මක** | +| `check:vuln-ratchet` | Dependency දුර්වලතා (osv-scanner) පසුබැසී නොමැත — binary එක නොමැති නම් මඟ හරී | **උපදේශාත්මක** | +| `check:workflows` | Workflow lint කිරීම (actionlint + zizmor); නොමැති/බිඳුණු scanners, වලංගු නොවන වාර්තා හෝ නොමැති ratchet මූලික අගයක් INCOMPLETE ලෙස අසමත් වේ. වලංගු සොයාගැනීම් තෝරාගත් strict/advisory/ratchet ප්රතිපත්තිය අනුගමනය කරයි | ක්රියාත්මක කිරීම අවශ්යයි; CI තුළ zizmor ratchet අවහිර කරයි | +| `check:openapi-breaking` | මූලික branch එකට සාපේක්ෂව පොදු API ගිවිසුමේ (`openapi.yaml`) බිඳවැටෙන වෙනස්කම් (oasdiff) — `openapiBreaking=N` නිකුත් කරයි; oasdiff නොමැති නම් හෝ මූලික spec එක නිරාකරණය කළ නොහැකි නම් මඟ හරී | **උපදේශාත්මක** | ### කාර්යය: `docs-sync-strict` -`main` වෙත වන සෑම PR එකකදීම ධාවනය වේ. අසාර්ථක වුවහොත් merge කිරීම අවහිර කරයි. - -| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිර කරන්නේ | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | පහත උප-ගේට් 6 අනුක්රමිකව ධාවනය කරන මෙටා-ගේට් එක | ඔව් | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt අනුවාද අනුකූලතාව | ඔව් | -| ↳ `check:docs-counts` | ගද්යයේ ඇති ගණන් (සපයන්නන් ගණන, සංක්රමණ ගණන ආදිය) සැබෑ ගණන්වල රැචට් කවුළුව තුළ තිබීම | ඔව් | -| ↳ `check:env-doc-sync` | `.env.example` තුළ ඇති සෑම පරිසර විචල්යයක්ම ලේඛන වගුවක ලේඛනගත කර තිබීම සහ එහි ප්රතිලෝමය | ඔව් | -| ↳ `check:deprecated-versions` | ලේඛන තුළ අභාවිත කළ අනුවාද තන්තු නොතිබීම | ඔව් | -| ↳ `check:doc-links` | ලේඛන තුළ ඇති අභ්යන්තර markdown සබැඳි සැබෑ ගොනු වෙත විසඳීම (`[text]`/`(path)` ආකෘතිය) | ඔව් | -| ↳ `check:fabricated-docs` | ලේඛනවල සඳහන් මාර්ග, පරිසර විචල්ය, CLI විධාන, hook නම් සහ ගොනු මාර්ග කේත පදනමේ පැවතීම. `--strict` හරහා දැඩි ගේට් එකක්; ධජය නොමැතිව මෘදු අසමත් වීමක්. | ඔව් (CI තුළ `--strict` හරහා) | -| `check:cli-i18n` | CLI විධාන තන්තු සියලු i18n පෙදෙසි ගොනුවල තිබීම | ඔව් | -| `check:openapi-coverage` | OpenAPI පිරිවිතරය සැබෑ මාර්ග සඳහා අවම වශයෙන් රැචට් කළ පහළ සීමාවක් ආවරණය කිරීම | ඔව් | -| `check:openapi-security-tiers` | `openapi.yaml` තුළ ඇති ආරක්ෂක මට්ටම් විවරණ `routeGuard.ts` වර්ගීකරණ සමඟ අනුකූල වීම | **උපදේශාත්මකයි** | -| `check:openapi-routes` | `openapi.yaml` තුළ ඇති සෑම මාර්ගයක්ම සැබෑ `route.ts` එකකට විසඳීම (ප්රබන්ධ-විරෝධී) | ඔව් | -| `check:docs-symbols` | `docs/**/*.md` තුළ ඇති සෑම `/api/...` යොමුවක්ම සැබෑ `route.ts` එකකට විසඳීම (ප්රබන්ධ-විරෝධී) | ඔව් | -| `i18n translation drift` | i18n පෙදෙසි ගොනුවල පරිවර්තනය නොකළ යතුරු — අනතුරු ඇඟවීමක් පමණි | **උපදේශාත්මකයි** | +`main` වෙත වන සෑම PR එකකදීම ධාවනය වේ. අසමත් වුවහොත් merge කිරීම අවහිර කරයි. + +| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිරකාරී | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | +| `check:docs-all` | පහත උප-ගේට්ටු 6 අනුක්රමිකව ධාවනය කරන මෙටා-ගේට්ටුවකි | ඔව් | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt අනුවාද අනුකූලතාව | ඔව් | +| ↳ `check:docs-counts` | ගද්යයේ සඳහන් ගණන් (සපයන්නන් ගණන, සංක්රමණ ගණන ආදිය) සත්ය ගණන්වල ratchet පරාසය තුළ තිබීම | ඔව් | +| ↳ `check:env-doc-sync` | `.env.example` හි සෑම env var එකක්ම ලේඛන වගුවක ලේඛනගත කර තිබීම සහ එහි ප්රතිවිරුද්ධය ද සත්ය වීම | ඔව් | +| ↳ `check:deprecated-versions` | ලේඛනවල අත්හැර දැමූ අනුවාද තන්තු නොතිබීම | ඔව් | +| ↳ `check:doc-links` | ලේඛනවල අභ්යන්තර markdown සබැඳි සැබෑ ගොනු වෙත යොමු වීම (`[text]`/`(path)` ආකෘතිය) | ඔව් | +| ↳ `check:fabricated-docs` | ලේඛනවල සඳහන් මාර්ග, env vars, CLI විධාන, hook නම් සහ ගොනු මාර්ග codebase එකේ පැවතීම. `--strict` හරහා දැඩි ගේට්ටුවකි; flag එක නොමැතිව මෘදු අසමත් වීමකි. | ඔව් (CI හි `--strict` හරහා) | +| `check:cli-i18n` | CLI විධාන තන්තු සියලු i18n locale ගොනුවල තිබීම | ඔව් | +| `check:openapi-coverage` | OpenAPI පිරිවිතරය සැබෑ මාර්ගවලින් අවම වශයෙන් ratchet කළ පහළ සීමාවක් ආවරණය කිරීම | ඔව් | +| `check:openapi-security-tiers` | `openapi.yaml` හි ආරක්ෂක මට්ටම් විවරණ `routeGuard.ts` වර්ගීකරණ සමඟ අනුකූල වීම | **උපදේශාත්මක** | +| `check:openapi-routes` | `openapi.yaml` හි සෑම මාර්ගයක්ම සැබෑ `route.ts` එකක් වෙත යොමු වීම (ව්යාජ නිර්මාණ වැළැක්වීම) | ඔව් | +| `check:docs-symbols` | `docs/**/*.md` හි සෑම `/api/...` යොමුවක්ම සැබෑ `route.ts` එකක් වෙත යොමු වීම (ව්යාජ නිර්මාණ වැළැක්වීම) | ඔව් | +| `i18n translation drift` | i18n locale ගොනුවල පරිවර්තනය නොකළ keys — අනතුරු ඇඟවීම පමණි | **උපදේශාත්මක** | ### කාර්යය: `i18n-ui-coverage` -| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිර කරන්නේ | -| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `check-ui-keys-coverage` (පේළිය තුළ) | UI i18n යතුරු ආවරණය ≥ 65% වීම | ඔව් | -| `check-ui-value-drift` (පේළිය තුළ) | නැවත ලියන ලද ඉංග්රීසි **අගයක්** පිටුපස යල්පැන ගිය පරිවර්තනයක් ඉතිරි නොකිරීම | ඔව් | -| `check-new-key-coverage` (පේළිය තුළ) | **නව** ඉංග්රීසි යතුරක් සෑම පෙදෙසකම පරිවර්තනය කර තිබීම — `__MISSING__:` සලකුණක් ප්රතික්ෂේප කෙරේ | ඔව් | -| `check-translation-ratio` | එක් එක් පෙදෙස සඳහා සැබෑ-පරිවර්තන අනුපාතය (අවසර ලැයිස්තුවෙන් පිටත ඉංග්රීසියට සමාන / තැන්පත්කාරක / අස්ථානගත පත්ර) `config/quality/i18n-translation-baseline.json` + ඉඩකඩ නොඉක්මවිය යුතුය | **උපදේශාත්මකයි** | +| ස්ක්රිප්ට් | වලංගු කරන්නේ | අවහිරකාරී | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (inline) | UI i18n key ආවරණය ≥ 65% වීම | ඔව් | +| `check-ui-value-drift` (inline) | නැවත ලියන ලද ඉංග්රීසි **අගයක්** පරණ පරිවර්තනයක් ඉතිරි නොකිරීම | ඔව් | +| `check-new-key-coverage` (inline) | **නව** ඉංග්රීසි key එකක් සෑම locale එකකම පරිවර්තනය කර තිබීම — `__MISSING__:` සලකුණක් ප්රතික්ෂේප කෙරේ | ඔව් | +| `check-translation-ratio` | locale එකකට සැබෑ-පරිවර්තන අනුපාතය (allowlist එකෙන් පිටත ඉංග්රීසියට සමාන / placeholder / නොමැති leaves) `config/quality/i18n-translation-baseline.json` + slack ඉක්මවා නොයා යුතුය | **උපදේශාත්මක** | -`fetch-depth: 0` අවශ්ය වේ — අගය-වෙනස්වීමේ ගේට් එක ඒකාබද්ධ පදනමට එරෙහිව `en.json` වෙනස්කම් සසඳයි. +`fetch-depth: 0` අවශ්ය වේ — value-drift ගේට්ටුව merge base එකට සාපේක්ෂව `en.json` හි වෙනස්කම් සසඳයි. -#### `check-ui-value-drift` — යල්පැන ගිය පරිවර්තන ගේට් එක +#### `check-ui-value-drift` — පරණ-පරිවර්තන ගේට්ටුව -වෙනත් ගේට්වලට ව්යුහාත්මකව දැකිය නොහැකි එක් i18n ප්රතිගමනය මෙය හඳුනා ගනී: ඉංග්රීසි අගයක් -නැවත ලියන නමුත් _පෙර_ ඉංග්රීසි අගයෙන් ව්යුත්පන්න කළ පරිවර්තන ඉතිරි වන බැවින්, -ඉංග්රීසි නොවන පරිශීලකයන් විශ්වාසදායක ලෙස ලියා ඇති, දැන් වැරදි පෙළක් දිගටම කියවයි. +අනෙකුත් ගේට්ටුවලට ව්යුහාත්මකව දැකිය නොහැකි එකම i18n ප්රතිගමනය මෙය හසුකරයි: ඉංග්රීසි අගයක් +නැවත ලියන නමුත් _පෙර_ ඉංග්රීසි අගයෙන් ව්යුත්පන්න කළ පරිවර්තන එලෙසම ඉතිරි වන බැවින්, +ඉංග්රීසි නොවන පරිශීලකයන් විශ්වාසදායක ලෙස ලියා ඇති, නමුත් දැන් වැරදි පෙළ දිගටම කියවයි. -මෙය සැබවින්ම නිකුත් විය. Antigravity පිවිසුම් සහායකය එක් කළ විට (#5203) -`oauthModal.googleOAuthWarning` නැවත ලියන ලදී; **පෙදෙසි 43න් 39ක්** ක්රියාකරුවන්ට "සම්පූර්ණ -URL එක පිටපත් කර පහත අලවන්න" යැයි කියන පෙළ තබාගෙන තිබුණි — එම සපයන්නා සඳහා සම්පූර්ණ -කළ නොහැකි ප්රවාහයකි. පහත හේතු නිසා #8463 තෙක් එය නොදැකී පැවතුණි: +මෙය සැබැවින්ම නිකුත් විය. Antigravity පිවිසුම් සහායකය එක් කළ විට (#5203) +`oauthModal.googleOAuthWarning` නැවත ලියන ලදී; **locale 43න් 39ක්** ක්රියාකරුවන්ට "සම්පූර්ණ +URL එක පිටපත් කර පහළින් අලවන්න" යැයි කියන පෙළ තබාගෙන තිබුණි — එම සපයන්නා සඳහා සම්පූර්ණ කළ +නොහැකි ප්රවාහයකි. පහත හේතු නිසා #8463 වන තෙක් එය අවධානයට ලක් නොවීය: -- `sync-ui-keys` පසුපිරවීම කරන්නේ **නොමැති** යතුරු පමණක් වන අතර, **යල්පැන ගිය** යතුරු කිසිවිටෙක නොවේ; -- `check-ui-keys-coverage` යතුරු _පැවතීම_ ගණන් කරන බැවින්, යල්පැන ගිය පරිවර්තනයක් ආවරණය වූවක් ලෙස ලකුණු ලබයි; -- `check-translation-drift` `docs/i18n//**.md` ලේඛන පිළිබිඹු නිරීක්ෂණය කරයි — - එය කිසිවිටෙක `src/i18n/messages/*.json` කියවන්නේ නැත. 2026-09 නැවත සමමුහුර්ත කිරීමේ සිට - `docs-sync-strict` කාර්යයේ අවහිර කරයි: මූලික ලේඛනයක් සංස්කරණය කරන්න → `npm run i18n:run -- --files=` (කොටස්-මට්ටමේ, අඩු වියදම්). +- `sync-ui-keys` පසුපුරවන්නේ **නොපවතින** keys පමණක් වන අතර, **පරණ** ඒවා කිසිවිටෙක නොවේ; +- `check-ui-keys-coverage` key _පැවතීම_ ගණනය කරන බැවින්, පරණ පරිවර්තනයක් ආවරණය වී ඇති ලෙස ලකුණු ලබයි; +- `check-translation-drift` `docs/i18n//**.md` ලේඛන දර්පණ නිරීක්ෂණය කරයි — + එය කිසිවිටෙක `src/i18n/messages/*.json` නොකියවයි. 2026-09 නැවත සමමුහුර්ත කිරීමේ සිට `docs-sync-strict` + කාර්යයේ අවහිර කරයි: ප්රධාන ලේඛනයක් සංස්කරණය කරන්න → `npm run i18n:run -- --files=` (කොටස් මට්ටමේ, අඩු වියදම්). -**වෙනස්කම් පිළිබඳ දැනුවත්, baseline මත පදනම් නොවූ.** එය merge base හි ඇති `en.json`, working tree එක සමඟ සසඳයි; ඉංග්රීසි අගය වෙනස් වූ සෑම key එකක් සඳහාම, තවමත් නොවෙනස් කළ පරිවර්තනයක් අඩංගු ඕනෑම locale එකක් යල්පැන ඇත. මෙය හිතාමතාම **පෙර සිට පැවති ණය ස්ථාවර කරයි** — දිගු කලක් පැවති පරිවර්තනයක් කුමන පැරණි ඉංග්රීසි පාඨයකින් පැමිණියේ දැයි diff එකකින් හෙළි කළ නොහැකි බැවින්, gate එක විනිශ්චය කරන්නේ වත්මන් වෙනස ස්පර්ශ කරන දෑ පමණි. විකල්පය වන (එක් එක් key එක සඳහා hash baseline එකක්) ~600 KB ප්රමාණයේ ජනනය කළ ගොනුවක් අවශ්ය කරනු ඇත; එය දැනට පවතින විශාලතම baseline එක මෙන් 3 ගුණයක් වන අතර සෑම i18n PR එකකදීම වෙනස් වනු ඇත. +**Diff පිළිබඳ දැනුවත්ය, මූලික පාදකයක් මත රඳා නොපවතී.** එය merge base හි ඇති `en.json`, working tree එක සමඟ සසඳයි; ඉංග්රීසි අගය වෙනස් වූ සෑම key එකක් සඳහාම, තවමත් වෙනස් නොකළ පරිවර්තනයක් දරන ඕනෑම locale එකක් යල්පැන ඇත. මෙය හිතාමතාම **පෙර සිට පවතින ණය ස්ථාවර කරයි** — දිගු කලක් පවතින පරිවර්තනයක් පැමිණියේ කුමන පැරණි ඉංග්රීසි පාඨයෙන්දැයි diff එකකට හෙළි කළ නොහැකි බැවින්, gate එක විනිශ්චය කරන්නේ වත්මන් වෙනස ස්පර්ශ කරන දේ පමණි. විකල්පය (key එකකට hash baseline එකක්) සඳහා ~600 KB ජනනය කළ ගොනුවක් අවශ්ය වන අතර, එය දැනට පවතින විශාලතම baseline එක මෙන් 3× විශාල වන අතර සෑම i18n PR එකකදීම වෙනස්කම් ඇති කරයි. -එය සපුරාලීමට ක්රම දෙකක් ඇත: +එය සපුරාලිය හැකි ක්රම දෙකකි: -1. බලපෑමට ලක්වූ පරිවර්තන යාවත්කාලීන කරන්න, හෝ -2. ඒවා `__MISSING__:` ලෙස සකසන්න — ඉන්පසු runtime එක නිවැරදි කළ ඉංග්රීසි පාඨය සපයයි - (`src/i18n/request.ts::deepMergeFallback`, #7258) සහ key එක පරිවර්තනය සඳහා පෝලිම්ගත වේ. +1. බලපෑමට ලක් වූ පරිවර්තන යාවත්කාලීන කරන්න, හෝ +2. ඒවා `__MISSING__:` ලෙස සකසන්න — එවිට runtime එක නිවැරදි කළ ඉංග්රීසි පාඨය සපයයි + (`src/i18n/request.ts::deepMergeFallback`, #7258), සහ key එක පරිවර්තනය සඳහා පෝලිම්ගත වේ. string එකේ **අර්ථය** වෙනස් වී ඇත්නම්, **key එක නැවත නම් කිරීම** වඩාත් සුදුසුය: නව key එකකට යල්පැන ගිය පරිවර්තනයක් උරුම විය නොහැක. #8463 භාවිත කළ රටාව එයයි. ```bash -npm run i18n:check-value-drift # දැඩි (CI ධාවනය කරන්නේ මෙයයි) +npm run i18n:check-value-drift # දැඩි (CI ධාවනය කරන ආකාරය) npm run i18n:check-value-drift:warn # වාර්තා කිරීම පමණි BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -මූලික catalog එක කියවිය නොහැකි විට (base ref එක නොමැති shallow clone එකක්), `check-openapi-breaking` අනුකරණය කරමින් `SKIP reason=base-unresolved` සමඟ 0 ලෙස පිටවේ. +base catalog එක කියවිය නොහැකි විට (base ref එක නොමැති shallow clone එකක්), `check-openapi-breaking` අනුකරණය කරමින් `SKIP reason=base-unresolved` සමඟ 0 ලෙස පිටවෙයි. ### කාර්යය: `i18n` -සම්පූර්ණ i18n වලංගුකරණ matrix එක (එක් locale එකකට එක් කාර්යයක්). මුළු කාර්යයම උපදේශාත්මකය. +සම්පූර්ණ i18n වලංගුකරණ න්යාසය (locale එකකට එක් කාර්යයක්). සම්පූර්ණ කාර්යයම උපදේශාත්මකය. -| Script | වලංගු කරන්නේ | අවහිර කිරීම | -| ------------------------------- | ---------------------------------------- | -------------------------------------------------------------- | -| `validate_translation.py quick` | එක් එක් locale එකේ පරිවර්තන සම්පූර්ණත්වය | **උපදේශාත්මකයි** (මුළු කාර්යය සඳහාම `continue-on-error: true`) | +| Script | වලංගු කරන්නේ | අවහිර කිරීම | +| ------------------------------- | --------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | locale එකකට පරිවර්තන සම්පූර්ණත්වය | **උපදේශාත්මකයි** (සම්පූර්ණ කාර්යයේම `continue-on-error: true`) | ### කාර්යය: `pr-test-policy` -pull request සඳහා පමණක් ධාවනය වේ. +pull request මත පමණක් ධාවනය වේ. | Script | වලංගු කරන්නේ | අවහිර කිරීම | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, හෝ `bin/` හි production code වෙනස් කරන PR සඳහා tests ඇතුළත් කිරීම හෝ යාවත්කාලීන කිරීම අනිවාර්යයි (දැඩි නීතිය #8) | ඔව් | -| `check:test-masking` | වෙනස් කළ test ගොනු ශුද්ධ assert ගණන අඩු නොකරන අතර `assert.ok(true)` වැනි tautology එකතු නොකරයි | ඔව් | -| `check:pr-evidence` | PR body එක වෙනස සඳහා test/VPS සාක්ෂි උපුටා දක්වයි (PR ගද්යය grep කිරීමෙන් දැඩි නීතිය #18 යාන්ත්රික කරයි — බිඳෙනසුලුයි, Backlog බලන්න) | ඔව් | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, හෝ `bin/` තුළ production code වෙනස් කරන PR වල පරීක්ෂණ ඇතුළත් කිරීම හෝ යාවත්කාලීන කිරීම අනිවාර්යය (දැඩි රීතිය #8) | ඔව් | +| `check:test-masking` | වෙනස් කළ test ගොනු ශුද්ධ assert ගණන අඩු නොකරන අතර `assert.ok(true)` වැනි පුනරුක්ති එක් නොකරයි | ඔව් | +| `check:pr-evidence` | PR body එක වෙනස සඳහා test/VPS සාක්ෂි උපුටා දක්වයි (PR ගද්යය grep කිරීමෙන් දැඩි රීතිය #18 යාන්ත්රීකරණය කරයි — බිඳෙනසුලුය, Backlog බලන්න) | ඔව් | ### කාර්යය: `test-vitest` -`build` පසු ධාවනය වේ. අසාර්ථක වුවහොත් merge කිරීම අවහිර කරයි. +`build` පසු ධාවනය වේ. අසමත් වුවහොත් merge කිරීම අවහිර කරයි. -| Suite | වලංගු කරන්නේ | අවහිර කිරීම | -| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (tools 110), autoCombo, cache — vitest runner | ඔව් | -| `test:vitest:ui` | UI component tests — vitest runner | **අවහිර කරයි** — පෙර සිට පැවති අසාර්ථකත්ව `vitest.config.ts` තුළ පැහැදිලිව බැහැර කර ඇත; නව අසාර්ථකත්ව කාර්යය අසාර්ථක කරයි | +| Suite | වලංගු කරන්නේ | අවහිර කිරීම | +| ---------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (මෙවලම් 110), autoCombo, cache — vitest runner | ඔව් | +| `test:vitest:ui` | UI component පරීක්ෂණ — vitest runner | **අවහිර කරයි** — පෙර සිට පවතින අසමත්වීම් `vitest.config.ts` තුළ පැහැදිලිව බැහැර කර ඇත; නව අසමත්වීම් කාර්යය අසමත් කරයි | -### රාත්රී workflows (කාලසටහන්ගත, උපදේශාත්මක) +### රාත්රී workflow (කාලසටහන්ගත, උපදේශාත්මක) -මේවා cron කාලසටහනක් මත (සහ `workflow_dispatch` මඟින්) ධාවනය වන අතර කිසිවිටෙකත් PR මත ධාවනය නොවේ. සියල්ලම උපදේශාත්මකය. +මේවා cron කාලසටහනක් මත (සහ `workflow_dispatch`) ධාවනය වන අතර, PR මත කිසිවිටෙකත් ධාවනය නොවේ. සියල්ල උපදේශාත්මකය. -| Workflow | වලංගු කරන්නේ | අවහිර කිරීම | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `nightly-property` | අහඹු seed එකක් සහ ඉහළ ධාවන ගණනක් සහිත fast-check property tests | **උපදේශාත්මකයි** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **උපදේශාත්මකයි** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret එකක් නොමැති විට මඟ හරිනු ලැබේ) | **උපදේශාත්මකයි** | -| `nightly-schemathesis` | `docs/openapi.yaml` භාවිතයෙන් සජීවී OmniRoute එකකට එරෙහි OpenAPI contract fuzzing (schemathesis) — spec උල්ලංඝන / හසුරුවා නොගත් 500s මතු කරයි (Fase 8 B.4) | **උපදේශාත්මකයි** | -| `nightly-mutation` | වේගවත් unit lane එක මත Stryker mutation-testing ලකුණු — නොනැසී පවතින mutants දුර්වල asserts හෙළි කරයි | **උපදේශාත්මකයි** | -| `nightly-compat` | සහාය දක්වන `engines.node` පරාස හරහා Node engine compatibility matrix එක | **උපදේශාත්මකයි** | +| Workflow | වලංගු කරන්නේ | අවහිර කිරීම | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | අහඹු seed එකක් සහ ඉහළ ධාවන ගණනක් සහිත fast-check property පරීක්ෂණ | **උපදේශාත්මකයි** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **උපදේශාත්මකයි** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret එකක් නොමැතිව මඟ හරිනු ලැබේ) | **උපදේශාත්මකයි** | +| `nightly-schemathesis` | `docs/openapi.yaml` භාවිත කරමින් සජීවී OmniRoute එකකට එරෙහි OpenAPI contract fuzzing (schemathesis) — spec උල්ලංඝන / හසුරුවා නොගත් 500s මතු කරයි (අදියර 8 B.4) | **උපදේශාත්මකයි** | +| `nightly-mutation` | වේගවත් unit lane එක මත Stryker mutation-testing ලකුණු — නොනැසී පවතින mutants දුර්වල asserts මතු කරයි | **උපදේශාත්මකයි** | +| `nightly-compat` | සහය දක්වන `engines.node` පරාස හරහා Node engine අනුකූලතා න්යාසය | **උපදේශාත්මකයි** | --- @@ -541,41 +535,41 @@ connection error එකක් log කිරීම පමණක් කරන අ ## තාර්කිකකරණ පසුබැසීම් ලැයිස්තුව (ROI සමාලෝචනය — අදියර 9 රැල්ල 3) -මෙම ඉන්වෙන්ටරිය 2026-06-17 දින `ci.yml` සමඟ සැසඳීමෙන් සමාදාන කරන ලදී (පෙර අනුවාදයේ +මෙම ලේඛනය 2026-06-17 දින `ci.yml` සමඟ සසඳා ප්රතිසන්ධානය කරන ලදී (පෙර අනුවාදයේ `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` අත්හැරී තිබුණි). සමාදාන කළ කට්ටලය පිළිබඳ ROI සමාලෝචනයකින් -පහත තාර්කිකකරණ අපේක්ෂකයන් හඳුනා ගන්නා ලදී. **ඒකාබද්ධ කිරීම් යාන්ත්රික CI -වෙනස්කම් වේ; තත්ත්ව මාරු කිරීම්/ඉවත් කිරීම් යනු ක්රියාකරු සඳහා වෙන් කළ ප්රතිපත්තිමය තීරණ වේ.** පහත කිසිවක් -තවම යොදා නැත. +`check:codeql-ratchet`, `check:pr-evidence` අත්හැරී තිබුණි). ප්රතිසන්ධානය කළ කට්ටලයේ ROI සමාලෝචනයකින් +පහත තාර්කිකකරණ අපේක්ෂකයන් හඳුනාගන්නා ලදී. **ඒකාබද්ධ කිරීම් යාන්ත්රික CI +වෙනස්කම් වේ; මාරු කිරීම්/ඉවත් කිරීම් ක්රියාකරු සඳහා වෙන් කළ ප්රතිපත්තිමය තීරණ වේ.** පහත කිසිවක් +තවම ක්රියාත්මක කර නොමැත. -**ඉහත ලේඛනගත කර නොමැති තවත් දෑ** (උපදේශාත්මක, අඩු සංඥාවක් සහිත): `docs-lint` කාර්යය -(markdownlint + Vale, සම්පූර්ණ කාර්යයම `continue-on-error`) සහ ස්වාධීන ස්කෑනර් කාර්ය ප්රවාහ +**ඉහත ලේඛනගත නොකළ තවත් දෑ** (උපදේශාත්මක, අඩු සංඥා සහිත): `docs-lint` කාර්යය +(markdownlint + Vale, සම්පූර්ණ කාර්යයටම `continue-on-error`) සහ ස්වාධීන ස්කෑනර් කාර්යප්රවාහ `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` යන්න -`quality-baseline.json` තුළ ඇතත්, `ci.yml` හි අවහිර කරන රැචට්ටුවකට සම්බන්ධ කර නැත — මෙම ප්රමිතිකය +`quality-baseline.json` තුළ ඇත, නමුත් `ci.yml` හි අවහිරකාරී රැචට්ටුවකට සම්බන්ධ කර නැත — මෙම මෙට්රික් එක දැනට අනාථව ඇත. ### ඒකාබද්ධ කිරීම / අනුපිටපත් ඉවත් කිරීම (යාන්ත්රික, අඩු අවදානමක්) -සෑම අපේක්ෂකයෙකුම 2026-06-17 දින සජීවී ද්වාර තත්ත්වයට එරෙහිව වලංගු කරන ලදී (විශ්වාස කරන්න, නමුත් සත්යාපනය කරන්න); -“පැහැදිලි” ලෙස පෙනුණු ඒකාබද්ධ කිරීම් කිහිපයක් ණය සඟවා ඇති බව පෙනී ගිය අතර ඒවා **පිරිසිදු සෘජු ආදේශන නොවේ**. - -- **`check:docs-sync` දෙවරක් ක්රියාත්මක වේ** — `lint` කාර්යය තුළ ස්වාධීනවද, නැවත `check:docs-all` (`docs-sync-strict`) තුළ සහ husky pre-commit hook එක තුළද ක්රියාත්මක වේ. ✅ **අවසන්** — ස්වාධීන `lint` ආමන්ත්රණය ඉවත් කරන ලදී. -- **CVE ස්කෑන් කිරීම** — ❌ **පිරිසිදු ඒකාබද්ධ කිරීමක් නොවේ.** `audit:deps` ඕනෑම ඉහළ/අතිශය තීරණාත්මක CVE එකක් මත දැඩි ලෙස අසාර්ථක වේ; `check:vuln-ratchet` (osv) අසාර්ථක වන්නේ මූලික මට්ටමට සාපේක්ෂව _පසුබෑමක්_ ඇති විට පමණි (දැනට MODERATE 1ක්). අර්ථවිද්යාව වෙනස්ය — `audit:deps` ඉවත් කිරීමෙන් නිරපේක්ෂ ඉහළ/අතිශය තීරණාත්මක ද්වාරය අහිමි වනු ඇත. දෙකම තබා ගන්න. -- **චක්ර හඳුනාගැනීම** — ❌ **පිරිසිදු ඒකාබද්ධ කිරීමක් නොවේ.** `check:circular-deps` (dpdm) මඟින් **චක්ර 91ක්** වාර්තා කරයි (එය උපදේශාත්මක වන්නේ ඒ නිසාය); ඒවා මුලින් විසඳීමකින් තොරව එය අවහිර කරන තත්ත්වයට උසස් කළ නොහැකි අතර, හරිත තත්ත්වයේ පවතින තෝරාගත් `check:cycles` ට වඩා පුළුල් විෂය පථයක් එයට ඇත. `check:cycles` අවහිර කරන ලෙස තබා ගන්න; dpdm චක්ර 91 විසඳීම වෙනම පසුබැසීම් කාර්යයකි. -- **සංකීර්ණත්වය** — ✅ **අවසන්** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): එක් ESLint පරිලෝකනයක්, `ruleId` අනුව ගණනය කරන බැවින් cyclomatic+max-lines සහ cognitive මූලික මට්ටම් ස්වාධීනව පවතී; දේශීය `--update` සඳහා තනි `check:complexity` / `check:cognitive-complexity` තවදුරටත් පවතී. -- **`/api` ප්රති-භ්රාන්තිය** — ✅ **අවසන්** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` සඳහා එක් FS ඉන්වෙන්ටරියක්, openapi-routes + docs-symbols තවමත් ස්වාධීනව වාර්තා කරයි; දේශීය ක්රියාත්මක කිරීම් සඳහා තනි ඒවා තවදුරටත් පවතී. -- **`check:node-runtime` කාර්ය 11ක ක්රියාත්මක වේ** — ⚠️ **අඩු ROI.** සෑම එකක්ම වෙනම runner එකක් වන අතර පරීක්ෂාව තත්පර 1කට අඩුය; ලාභදායී එක්-කාර්ය ආරක්ෂකයක් අහිමි කිරීමට සාපේක්ෂව, සමස්ත ඉතිරිය තත්පර ~10කි. මෙම කැලඹීම වටින්නේ නැත. -- **CI lint මත `typecheck:noimplicit:core`** — ✅ **lint කාර්යයෙන් ඉවත් කරන ලදී** (එය උපදේශාත්මක `continue-on-error` එකක් විය); අවහිර කරන type පෘෂ්ඨය `typecheck:core` + `check:type-coverage` වේ. දේශීය ස්ක්රිප්ට් එක රඳවා ඇත. - -### තත්ත්වය මාරු කිරීම / තීරණය කිරීම (ක්රියාකරු ප්රතිපත්තිය) - -- `check:openapi-security-tiers` (උපදේශාත්මක) — ❌ **පිරිසිදුව තත්ත්වය මාරු කළ නොහැක.** එය 0 සමඟ පිටවන නමුත්, `LOCAL_ONLY_API_PREFIXES` යටතේ ඇති `traffic-inspector` මාර්ග කිහිපයක `x-loopback-only: true` අනුසටහන නොමැති බවට අනතුරු අඟවයි. එය බලාත්මක කිරීමට පළමුව එම අනුසටහන් `openapi.yaml` වෙත එක් කිරීම අවශ්ය වේ. -- `typecheck:noimplicit:core` (උපදේශාත්මක) — අවහිර කරන `check:type-coverage` රැචට්ටුව මඟින් බොහෝ දුරට ආවරණය කර ඇත. එය රැචට්ටුවකට මාරු කරන්න, නැතහොත් අතිරික්ත දෙවන `tsc` වාරය ඉවත් කරන්න. -- `test:vitest:ui` (දැන් **අවහිර කරන**) — පෙර සිට පැවති අසාර්ථකවීම් `vitest.config.ts` තුළ `// #8618` ලුහුබැඳීමේ අදහස් සමඟ පැහැදිලිව බැහැර කර ඇත; නව අසාර්ථකවීම් කාර්යය අසාර්ථක කරයි. -- `check:secrets` (gitleaks, ලේඛනගත ව්යාජ ධනාත්මක 3කදී ස්ථිර කළ අවහිර කරන රැචට්ටුව) — 0 දක්වා ළඟා වීමට එම 3 අවසර ලැයිස්තුවට එක් කරන්න, නැතහොත් උපදේශාත්මක තත්ත්වයට පහත හෙළන්න. GitHub හි ස්වදේශීය secret-scanning + `check:public-creds` සමඟ අතිච්ඡාදනය වේ. -- `check:pr-evidence` (අවහිර කරන, PR-body ගද්යය තුළ සොයයි) — ව්යාජ ධනාත්මක සඳහා ඉහළ අවදානමක් ඇත; ඉවත් කළහොත් Hard Rule #18 බලාත්මක කිරීම දුර්වල වේ, එබැවින් මෙය සැබෑ ප්රතිපත්තිමය තීරණයකි. -- `semgrep` (ස්වාධීන උපදේශාත්මක කාර්යයක්) — OWASP පවුල් සම්බන්ධයෙන් CodeQL සමඟ අතිච්ඡාදනය වේ; එහි මූලික මට්ටම රැචට්ටුවකට සම්බන්ධ කරන්න, නැතහොත් ඉවත් කරන්න. +සෑම අපේක්ෂකයෙකුම 2026-06-17 දින සජීවී ද්වාර තත්ත්වයට එරෙහිව වලංගු කරන ලදී (විශ්වාස කරන්න-නමුත්-තහවුරු කරන්න); +“පැහැදිලි” ලෙස පෙනුණු ඒකාබද්ධ කිරීම් කිහිපයක් ණය සඟවා ඇති බව හෙළි වූ අතර ඒවා **පිරිසිදු** සෘජු ආදේශන නොවේ. + +- **`check:docs-sync` දෙවරක් ධාවනය වේ** — `lint` කාර්යය තුළ ස්වාධීනව සහ නැවත `check:docs-all` (`docs-sync-strict`) තුළ මෙන්ම husky pre-commit හුක් එක තුළද. ✅ **නිමයි** — ස්වාධීන `lint` ආමන්ත්රණය ඉවත් කරන ලදී. +- **CVE ස්කෑන් කිරීම** — ❌ **පිරිසිදු ඒකාබද්ධ කිරීමක් නොවේ.** ඕනෑම ඉහළ/අතිශය වැදගත් CVE එකක් සඳහා `audit:deps` දැඩි ලෙස අසමත් වේ; `check:vuln-ratchet` (osv) අසමත් වන්නේ මූලික රේඛාවට සාපේක්ෂව _පසුබෑමක්_ ඇති විට පමණි (දැනට 1 MODERATE). අර්ථකථන වෙනස්ය — `audit:deps` ඉවත් කිරීමෙන් නිරපේක්ෂ ඉහළ/අතිශය වැදගත් ද්වාරය අහිමි වනු ඇත. දෙකම තබා ගන්න. +- **චක්ර හඳුනාගැනීම** — ✅ **නිමයි** (#15159 G-01/G-02). මෙහි පැරණි පාඨය `check:cycles` යන්න “හරිත, තෝරා සැකසූ” ද්වාරය ලෙස හැඳින්වූ අතර `check:circular-deps` (dpdm) චක්ර 91ක් වාර්තා කළ බැවින් එය අවහිරකාරීව තබා ගැනීම සාධාරණීකරණය කළේය. එම හරිත තත්ත්වය **ව්යාජ හරිත තත්ත්වයක්** විය: `check:cycles` උපබහලුම් 5ක් (ගොනු 450ක්) ස්කෑන් කළ අතර, ස්ථිතික `import|export … from` පමණක් ගැළපූ අතර, සෑම `@/` සහ `@omniroute/open-sse/` විශේෂකයක්ම ඉවත් කළේය; එබැවින් ගබඩාව පුරා ප්රමුඛ වූ ගතික-import + alias චක්ර එයට දැකගත නොහැකි විය. නිවැරදි කරන ලදී: ද්වාරය දැන් `src` + `open-sse` (ගොනු 5023ක්) හරහා ගමන් කරයි, TypeScript AST වෙතින් විශේෂක රැස් කරයි (ඒ අනුව `import("…")` ගණන් ගන්නා අතර type-position `typeof import("…")` ගණන් නොගනී), සහ tsconfig `paths` විසඳයි. එය 0ක් නොව, චක්ර **14ක්** සොයා ගනී. පෙර පැවති චක්ර 14ක් ද්වාර PR එකක් තුළ නිවැරදි කළ නොහැකි බැවින්, `check:cycles` දැන් **රැචට්ටුවකි** (`--ratchet`, `quality-baseline.json` තුළ සීමාව `metrics.cycles.value = 14`, `direction: down`) — එය ඕනෑම _පසුබෑමක්_ අවහිර කරන අතර ගණනට අඩු විය හැක්කේ පමණි. CI විසින් `npm run check:cycles:ratchet` ධාවනය කරයි. අඩු කිරීම **A-01** සමඟ සිදු වේ. පුළුල් දෙවන මතයක් ලෙස `check:circular-deps` (dpdm) උපදේශාත්මකව පවතී. +- **සංකීර්ණත්වය** — ✅ **නිමයි** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): එක් ESLint ගමන් කිරීමක්, චක්රීය+උපරිම-පේළි සහ සංජානන මූලික රේඛා ස්වාධීනව තබා ගැනීමට ruleId අනුව ගණන් කරයි; තනි `check:complexity` / `check:cognitive-complexity` දේශීය `--update` සඳහා පවතී. +- **`/api` ප්රති-මායාකල්පනය** — ✅ **නිමයි** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` සඳහා එක් FS ලැයිස්තුගත කිරීමක්, openapi-routes + docs-symbols තවමත් ස්වාධීනව වාර්තා කරයි; තනි ධාවන දේශීය ධාවන සඳහා පවතී. +- **`check:node-runtime` කාර්ය 11ක් තුළ ධාවනය වේ** — ⚠️ **අඩු ROI.** සෑම එකක්ම වෙනම ධාවකයක් වන අතර පරීක්ෂාව තත්පර 1කට අඩුය; ලාභය සමස්තයෙන් ~තත්පර 10ක් වන අතර, ඒ වෙනුවෙන් ලාභදායී එක්-කාර්ය ආරක්ෂකයක් අහිමි වේ. මෙතරම් වෙනස්කම් කිරීම වටින්නේ නැත. +- **CI lint හි `typecheck:noimplicit:core`** — ✅ **lint කාර්යයෙන් ඉවත් කරන ලදී** (එය උපදේශාත්මක `continue-on-error` එකක් විය); අවහිරකාරී වර්ග පෘෂ්ඨය `typecheck:core` + `check:type-coverage` වේ. දේශීය ස්ක්රිප්ටය තබා ගන්නා ලදී. + +### මාරු කිරීම / තීරණය කිරීම (ක්රියාකරු ප්රතිපත්තිය) + +- `check:openapi-security-tiers` (උපදේශාත්මක) — ❌ **පිරිසිදුව මාරු කළ නොහැක.** එය 0 සමඟ පිටවන නමුත් `LOCAL_ONLY_API_PREFIXES` යටතේ ඇති `traffic-inspector` මාර්ග කිහිපයක `x-loopback-only: true` සටහන නොමැති බවට අනතුරු අඟවයි. එය බලාත්මක කිරීමට පළමුව එම සටහන් `openapi.yaml` වෙත එක් කළ යුතුය. +- `typecheck:noimplicit:core` (උපදේශාත්මක) — අවහිරකාරී `check:type-coverage` රැචට්ටුව මගින් බොහෝ දුරට ආවරණය වේ. රැචට්ටුවකට මාරු කරන්න හෝ අතිරික්ත දෙවන `tsc` ගමන් කිරීම ඉවත් කරන්න. +- `test:vitest:ui` (දැන් **අවහිරකාරී**) — පෙර පැවති අසමත්වීම් `vitest.config.ts` තුළ `// #8618` ලුහුබැඳීමේ අදහස් සමඟ පැහැදිලිව බැහැර කර ඇත; නව අසමත්වීම් කාර්යය අසමත් කරයි. +- `check:secrets` (gitleaks, ලේඛනගත ව්යාජ-ධනාත්මක 3ක ස්ථිර කළ අවහිරකාරී රැචට්ටුවක්) — 0 වෙත ළඟා වීමට එම 3 අවසර ලැයිස්තුවට එක් කරන්න, නැතහොත් උපදේශාත්මක තත්ත්වයට පහත හෙළන්න. GitHub හි ස්වදේශීය රහස්-ස්කෑන් කිරීම + `check:public-creds` සමඟ අතිච්ඡාදනය වේ. +- `check:pr-evidence` (අවහිරකාරී, PR-body ගද්යය තුළ සොයයි) — ව්යාජ-ධනාත්මක අවදානම ඉහළය; ඉවත් කළහොත් දැඩි රීතිය #18 බලාත්මක කිරීම දුර්වල වන බැවින්, මෙය සැබෑ ප්රතිපත්තිමය තීරණයකි. +- `semgrep` (උපදේශාත්මක ස්වාධීන කාර්යප්රවාහයක්) — OWASP පවුල් සඳහා CodeQL සමඟ අතිච්ඡාදනය වේ; එහි මූලික රේඛාව රැචට්ටුවකට සම්බන්ධ කරන්න හෝ ඉවත් කරන්න. --- diff --git a/docs/i18n/sk/CONTRIBUTING.md b/docs/i18n/sk/CONTRIBUTING.md index 340bdba2f38..46e080c6ea0 100644 --- a/docs/i18n/sk/CONTRIBUTING.md +++ b/docs/i18n/sk/CONTRIBUTING.md @@ -399,22 +399,22 @@ Napíšte jednotkové testy v `tests/unit/`, ktoré pokrývajú minimálne: --- -## Kontrolný zoznam pull requestu +## Kontrolný zoznam pre Pull Request -- [ ] Testy sú úspešné (`npm test`) -- [ ] Kontrola lintovania je úspešná (`npm run lint`) +- [ ] Testy prechádzajú (`npm test`) +- [ ] Kontrola lintingu prechádza (`npm run lint`) - [ ] Zostavenie je úspešné (`npm run build`) -- [ ] Pre nové verejné funkcie a rozhrania boli pridané typy TypeScript +- [ ] Pre nové verejné funkcie a rozhrania sú pridané typy TypeScript - [ ] Žiadne napevno zadané tajné údaje ani záložné hodnoty -- [ ] Verejné upstream prihlasovacie údaje sú vložené pomocou `resolvePublicCred()` (pozrite si [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikdy nie ako literály -- [ ] Chybové odpovede prechádzajú cez `buildErrorBody()` / `sanitizeErrorMessage()` — telá odpovedí neobsahujú nespracované trasovania zásobníka (pozrite si [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Verejné prihlasovacie údaje upstream služieb sú vložené prostredníctvom `resolvePublicCred()` (pozrite si [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikdy nie ako literály +- [ ] Chybové odpovede prechádzajú cez `buildErrorBody()` / `sanitizeErrorMessage()` — v telách odpovedí nie sú žiadne nespracované výpisy zásobníka (pozrite si [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Shellové príkazy (`exec` / `spawn`) odovzdávajú hodnoty za behu prostredníctvom `env`, nie pomocou interpolácie reťazcov -- [ ] Všetky vstupy sú overené pomocou schém Zod -- [ ] Pre zmeny viditeľné používateľom bol do `changelog.d/{features|fixes|maintenance}/-.md` pridaný **fragment** zoznamu zmien (pozrite si [`changelog.d/README.md`](./changelog.d/README.md)) — **neupravujte** priamo `CHANGELOG.md`; fragmenty sa agregujú pri vydaní a medzi pull requestmi nikdy nevytvárajú konflikty -- [ ] Dokumentácia bola aktualizovaná (ak je to relevantné) +- [ ] Všetky vstupy sú validované pomocou schém Zod +- [ ] Pre zmeny viditeľné pre používateľov je pridaný **fragment** záznamu zmien v `changelog.d/{features|fixes|maintenance}/-.md` (pozrite si [`changelog.d/README.md`](./changelog.d/README.md)) — **neupravujte** priamo `CHANGELOG.md`; fragmenty sa agregujú pri vydaní a medzi Pull Requestmi nikdy nevznikajú konflikty +- [ ] Dokumentácia je aktualizovaná (ak je to relevantné) - [ ] Neboli vytvorené žiadne nové upozornenia CodeQL / Secret-Scanning alebo bolo každé z nich zamietnuté s technickým odôvodnením odkazujúcim na príslušný dokument v `docs/security/` -- [ ] Trasy, ktoré spúšťajú podriadené procesy (`/api/mcp/`, `/api/cli-tools/runtime/`), sú klasifikované ako `isLocalOnlyPath()` v `src/server/authz/routeGuard.ts` — pozrite si [Pevné pravidlo č. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Správy commitov neobsahujú riadky `Co-Authored-By` — commity musia byť uvedené výlučne pod identitou Git vlastníka repozitára (Pevné pravidlo č. 16) +- [ ] Trasy, ktoré spúšťajú podradené procesy (`/api/mcp/`, `/api/cli-tools/runtime/`), sú klasifikované ako `isLocalOnlyPath()` v `src/server/authz/routeGuard.ts` — pozrite si [Prísne pravidlo č. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Správy commitov neobsahujú pätičky `Co-authored-by` pre AI/botov (Prísne pravidlo č. 16) — ľudskí spolupracovníci, ktorých práca je opätovne použitá, sú uvedení pomocou štandardných pätičiek `Co-authored-by: Name ` --- diff --git a/docs/i18n/sk/docs/architecture/QUALITY_GATES.md b/docs/i18n/sk/docs/architecture/QUALITY_GATES.md index 05ab0eda0c7..62e6483be27 100644 --- a/docs/i18n/sk/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/sk/docs/architecture/QUALITY_GATES.md @@ -19,213 +19,211 @@ rovnakého systému nezávislý od nástrojov nájdete v dokumente ### Prijatie kandidáta -Pracovné postupy CI a Quality Gates poskytujú stabilné verdikty: `Gate / CI` a +Workflowy CI a Quality Gates poskytujú stabilný verdikt: `Gate / CI` a `Gate / Quality`. Ich verzovaná politika prijímania uvádza každú nadradenú úlohu -ako povinnú alebo odporúčanú. Každá relevantná povinná úloha musí uspieť: chýbajúce, -zrušené, preskočené, čakajúce a neznáme výsledky nemôžu stanoviť stav PASS. Platná -klasifikácia iba pre dokumentáciu alebo iba pre katalóg môže spôsobiť, že vetva pre -kód nebude relevantná; koncept PR nie je akceptovaným kandidátom. Označenie `hotfix` -neruší požiadavku na dôkazy. - -Oba pracovné postupy pokrývajú PR a odoslania do vetiev main/release, manuálne -spustenie a udalosti merge-group. Odoslanie, spustenie a merge-group vykonávajú -úplný výber. Forky a skupiny zlúčenia používajú hostované runnery pre úlohy, ktoré -by inak vybrali samostatne hostované runnery; pred nasadením treba overiť dostatočnú -hostovanú kapacitu. - -Každé potvrdenie JSON identifikuje checkout SHA, spustenie pracovného postupu a pokus. -CLI odmietne nezhodu SHA medzi checkoutom a udalosťou. Testy pracovných postupov viažu -členstvo v politike na zoznam `needs` úlohy verdiktu, takže nová alebo odstránená vetva -nemôže nepozorovane zmiznúť. Potvrdenia pokrývajú vlastný pracovný postup, nie -publikovanie, nasadenie ani interné fungovanie existujúceho odporúčacieho skenera. -Aktivácia oboch názvov kontrol v pravidlách vetvy je samostatnou administratívnou -zmenou; pridanie týchto úloh samo osebe vetvu nechráni. - -### Inventár statických kontrol - -Verzovaný inventár aliasov npm a členstvo v statických kontrolách sa nachádzajú v +ako povinnú alebo poradnú. Príslušná povinná úloha musí uspieť: chýbajúce, +zrušené, preskočené, čakajúce a neznáme výsledky nemôžu stanoviť PASS. Platná +klasifikácia iba pre dokumentáciu alebo iba pre katalóg môže spôsobiť, že vetva +pre kód nebude relevantná; koncept PR nie je prijateľným kandidátom. Označenie +`hotfix` neruší požiadavku na dôkazy. + +Oba workflowy pokrývajú PR a odoslania zmien do hlavných/vydávacích vetiev, manuálne +spustenie a udalosti skupín zlučovania. Odoslanie zmien, manuálne spustenie a skupiny +zlučovania spúšťajú úplný výber. Forky a skupiny zlučovania používajú hostované +runnery pre úlohy, ktoré by inak vybrali samostatne hostované runnery; pred nasadením +je potrebné overiť dostatočnú kapacitu hostovaných runnerov. + +Každé potvrdenie JSON identifikuje checkoutnutý SHA, beh workflowu a pokus. +CLI odmietne nezhodu medzi SHA checkoutu a udalosti. Testy workflowu viažu členstvo +v politike na zoznam `needs` úlohy s verdiktom, aby nová alebo odstránená vetva +nemohla nepozorovane zmiznúť. Potvrdenia pokrývajú vlastný workflow, nie publikovanie, +nasadenie ani interné fungovanie existujúceho poradného skenera. Aktivácia oboch +názvov kontrol v pravidlách vetvy je samostatná administratívna zmena; pridanie +týchto úloh samo osebe nechráni vetvu. + +### Inventár statického skenovania + +Verzovaný inventár aliasov npm a členstvo v statickom skenovaní sa nachádzajú v `config/quality/gate-manifest.json`. Spustením `npm run check:gate-manifest` overíte -názvy skriptov a presné príkazy voči súboru `package.json`; pridania, odstránenia -a odchýlky príkazov spôsobia zlyhanie lokálneho hooku aj úloh klasifikácie zmien -v CI. Alias nie je úloha pracovného postupu, inštancia matice ani testovací prípad: -tieto počty sa nesmú prezentovať ako vzájomne zameniteľné. +názvy skriptov a presné príkazy voči `package.json`; pridania, odstránenia a +odchýlky príkazov spôsobia zlyhanie lokálneho hooku aj úloh klasifikácie zmien v CI. +Alias nie je úloha workflowu, inštancia matice ani testovací prípad: tieto počty sa +nesmú prezentovať ako vzájomne zameniteľné. Použite `npm run quality:scan -- --list` alebo `npm run quality:scan:fast -- --list` -na kontrolu vybraných aliasov bez ich vykonania. Runner vyvoláva vstupný bod npm, -takže jeho runtime (vrátane Bun tam, kde je nakonfigurovaný) zostáva zachovaný. -Manifest zaznamenáva aliasy mimo týchto profilov ako vyvolávané samostatne a -príkazy údržby sú v profiloch kontroly iba na čítanie zakázané. +na kontrolu vybraných aliasov bez ich spustenia. Runner vyvoláva vstupný bod npm, +takže jeho runtime (vrátane Bun, kde je nakonfigurovaný) zostáva zachovaný. +Manifest zaznamenáva aliasy mimo týchto profilov ako spúšťané samostatne a +príkazy údržby sú v profiloch skenovania určených iba na čítanie zakázané. -Tieto profily pokrývajú iba statické kontroly. Necertifikujú testy produktu, +Tieto profily pokrývajú iba statické skenovanie. Necertifikujú testy produktu, pokrytie, balenie, externé kontroly ani úplné prijatie kandidáta na vydanie. -Prijímanie v pracovnom postupe používa prepojené súbory -`config/quality/admission-policy.json` a `scripts/quality/admission-verdict.mjs`. -Profily pozorovateľa vydania zostávajú oddelené; ich relevantné kontroly a -potvrdenia overujte nezávisle. Textový inventár uvedený nižšie slúži ako referencia, -nie ako dôkaz, že sa brána skutočne spustila. - -Skripty sa nachádzajú v `scripts/check/` (brány politík) a `scripts/quality/` -(ratchet mechanizmus). Zdrojom pravdy pre CI je `.github/workflows/ci.yml`. - -### Zrýchlená cesta PR vydania (`quality.yml`) - -`.github/workflows/quality.yml` dopĺňa CI pre PR do vetiev main/release, odoslania -do chránených vetiev, manuálne spustenia a skupiny zlúčenia. PR používajú rýchle -kontroly filtrované podľa ciest. Trvalo zakázaná duplicitná zostava bola odstránená; -skutočné kontroly zostavenia, balíka a spustenia zostávajú v CI. - -| Úloha | Rozsah | Blokovanie | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `Docs Gates (fast-path)` | PR dokumentácie/kódu; odkazy na dokumentáciu API a docs-all | Áno | -| `Fast Quality Gates` | PR kódu; statické kontroly, kontrola typov, kontrola typov dashboardu, ovplyvnené jednotkové testy | Áno | -| `Forgotten sibling tests` | PR kódu; zmenené moduly vysledované k statickým konzumentom a kandidátskym súrodeneckým testom; cesty cez barrel a dynamický import sa hlásia ako odporúčacie diagnostiky s odkazovanými výnimkami zo zoznamu povolení | **Odporúčacie** | -| `Vitest (fast-path)` | PR kódu; rýchly balík testov vitest | Áno | -| `Unit Tests fast-path` | PR kódu; jednotkové testy rozdelené do 4 shardov | Áno | -| `No new ESLint warnings` | PR kódu; kontrola lintu zohľadňujúca potlačenia | Áno, vrátane forkov | -| `Merge integrity (changelog + generated skills)` | PR, ktoré nie sú konceptmi; synchronizácia changelogu a generovaných zručností | Áno, vrátane forkov | - -#### Hlásenie zabudnutých súrodeneckých testov - -`npm run check:forgotten-sibling-tests` opätovne používa resolver importov, na ktorom -je založená mapa vplyvu testov. Pre každý zmenený produkčný modul hlási deterministické -reťazce `changed module/symbol -> static consumer -> candidate sibling test`, keď -kandidátsky test chýba v diff-e pull requestu. Súhrn Markdown a výsledok JSON sa -uchovávajú ako artefakt pracovného postupu `forgotten-sibling-tests` na kalibráciu -pred prípadným zavedením blokovania. - -Re-exporty barrelov a dynamické importy slúžia iba na diagnostiku rozlíšenia; nikdy nevytvárajú -blokujúce zistenie. Skontrolované výnimky sa nachádzajú v +Prijímanie vo workflowe používa prepojené súbory `config/quality/admission-policy.json` a +`scripts/quality/admission-verdict.mjs`. Profily pozorovateľa vydania zostávajú oddelené; +ich príslušné kontroly a potvrdenia kontrolujte nezávisle. Textový +inventár nižšie slúži ako referencia, nie ako dôkaz, že sa brána skutočne spustila. + +Skripty sa nachádzajú v `scripts/check/` (brány politík) a `scripts/quality/` (mechanizmus postupného sprísňovania). +Zdrojom pravdy pre CI je `.github/workflows/ci.yml`. + +### Zrýchlený postup pre PR vydania (`quality.yml`) + +`.github/workflows/quality.yml` dopĺňa CI pri PR do hlavných/vydávacích vetiev, +odoslaniach zmien do chránených vetiev, manuálnom spustení a skupinách zlučovania. +PR používajú rýchle kontroly filtrované podľa ciest. Trvalo zakázané duplicitné +zostavenie bolo odstránené; skutočné kontroly zostavenia/balenia/spustenia zostávajú v CI. + +| Úloha | Rozsah | Blokujúca | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `Docs Gates (fast-path)` | PR dokumentácie/kódu; referencie dokumentácie API a všetka dokumentácia | Áno | +| `Fast Quality Gates` | PR kódu; statické kontroly, kontrola typov, kontrola typov dashboardu, ovplyvnené jednotkové testy | Áno | +| `Forgotten sibling tests` | PR kódu; zmenené moduly vysledované k statickým konzumentom a kandidátskym súrodeneckým testom; cesty cez barrel súbory a dynamické importy sa hlásia ako poradná diagnostika s odkazmi na výnimky v zozname povolení | **Poradná** | +| `Vitest (fast-path)` | PR kódu; rýchla sada Vitest | Áno | +| `Unit Tests fast-path` | PR kódu; jednotková sada so 4 shardmi | Áno | +| `No new ESLint warnings` | PR kódu; lintovacia kontrola zohľadňujúca potlačenia | Áno, vrátane forkov | +| `Merge integrity (changelog + generated skills)` | PR, ktoré nie sú konceptmi; synchronizácia changelogu a generovaných zručností | Áno, vrátane forkov | + +#### Správa o zabudnutých súrodeneckých testoch + +`npm run check:forgotten-sibling-tests` opätovne používa resolver importov, na ktorom je založená mapa vplyvu testov. +Pre každý zmenený produkčný modul hlási deterministické reťazce +`changed module/symbol -> static consumer -> candidate sibling test`, keď kandidátsky +test chýba v rozdiele pull requestu. Súhrn vo formáte Markdown a výsledok JSON sa uchovávajú ako +artefakt workflowu `forgotten-sibling-tests` na účely kalibrácie pred akýmkoľvek zavedením blokovania. + +Reexporty zo súhrnných modulov a dynamické importy slúžia iba na diagnostiku rozlíšenia; nikdy +nevytvárajú blokujúce zistenie. Skontrolované výnimky sa nachádzajú v `config/quality/forgotten-sibling-allowlist.json`. Každá položka musí uvádzať konzumenta a kandidátsky -test, obsahovať konkrétne odôvodnenie a odkazovať na issue alebo pull request na GitHube. Chybne vytvorené položky spôsobia -zlyhanie. Výnimky nemôžu potlačiť odstránený kandidátsky test ani diff, ktorý pridáva `.skip`/`.todo`; -oslabovanie asercií a ďalšie maskovanie naďalej spadajú pod nezávisle blokujúcu -bránu `check:test-masking`. +test, obsahovať konkrétne odôvodnenie a odkazovať na problém alebo pull request na GitHube. Chybne +vytvorené položky sú automaticky zamietnuté. Výnimky nemôžu potlačiť odstránený kandidátsky test ani +rozdiel, ktorý pridáva `.skip`/`.todo`; oslabovanie asercií a ďalšie maskovanie naďalej spadajú pod +nezávisle blokujúcu bránu `check:test-masking`. ### Úloha: `lint` -Spúšťa sa pri každom PR do `main`. Pri zlyhaní blokuje zlúčenie. - -| Skript (`npm run ...`) | Overuje | Blokujúce | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:node-runtime` | Verzia Node.js je v podporovanom rozsahu | Áno | -| `check:cycles` | Cyklické importy — všetky moduly v `src/` + `open-sse/` | Áno | -| `check:route-validation:t06` | Schémy Zod sú prítomné na všetkých trasách (pravidlá úrovne 6) | Áno | -| `check:any-budget:t11` | Počet `@ts-expect-error // any` neprekračuje limit (kontrolný mechanizmus úrovne 11) | Áno | -| `check:provider-consistency` | Každý poskytovateľ v `providers.ts` má zodpovedajúcu položku v `providerRegistry.ts` (a naopak, v rámci zoznamu povolených položiek) | Áno | -| `check:model-lifecycle` | Tri ručne udržiavané smerovacie tabuľky zostávajú konzistentné so snapshotom životného cyklu uloženým v repozitári (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nehodnotí žiadne vyradené id, ktoré dokáže `REGISTRY` smerovať; každý cieľ `BUILT_IN_ALIASES` sa nachádza v `REGISTRY` a nenachádza sa v snapshote vyradených id; každé vyradené id, ktoré je stále v `REGISTRY`, je presmerované alebo uvedené v `allowedRetiredInCatalog`; a žiadny zdroj ani cieľ `DEFAULT_DEGRADATION_MAP` sa v tomto snapshote nenachádza medzi vyradenými. Toto nedokazuje, že model momentálne poskytuje aktívna upstreamová služba. Offline — porovnáva sa s `config/quality/model-lifecycle.json`, ktorý sa ručne obnovuje pomocou `npm run quality:refresh-model-lifecycle` (vyžaduje sieť; nie je zapojené do CI). `allowedRetiredInCatalog` je postupne sprísňovaná západka: položku pridajte iba spolu so sledovacím problémom. | Áno | -| `check:fetch-targets` | Každé `fetch("/api/...")` v klientskom `src/` smeruje na skutočný `route.ts` | Áno | -| `check:deps` | Všetky závislosti inštalovateľné pomocou `npm install` vo všetkých súboroch `package.json` v repozitári sa nachádzajú v `dependency-allowlist.json`; nové závislosti bez pevne určenej verzie alebo balíky s názvami napodobňujúcimi iné balíky sú označené | Áno | -| `audit:deps` | `npm audit` (koreňový adresár + electron) — žiadne upozornenia s vysokou/kritickou závažnosťou (prekrýva sa s osv `check:vuln-ratchet`; pozrite si zoznam úloh na racionalizáciu) | Áno | -| `check:lockfile` | Integrita `package-lock.json` — register https, hashe integrity, žiadne prepísania hostiteľa | Áno | -| `check:licenses` | Zoznam povolených licencií SPDX pre produkčné závislosti | Áno | -| `check:tracked-artifacts` | Žiadne artefakty zostavenia ani potvrdené symbolické odkazy na `node_modules` (spúšťa sa aj v husky pre-commit; pre-push je zámerne nenáročný — #6716) | Áno | -| `check:ai-attribution` | Žiadna pätička `Co-Authored-By` od AI/bota ani pätička o generovaní pomocou AI v commitoch, názve alebo tele PR — pevné pravidlo č. 16 (v slučke rýchlych kontrol v `quality.yml` pre PR→`release/**` — číta údaje udalosti, mimo PR nevykonáva žiadnu operáciu — a krok iba pre PR v lintovaní v `ci.yml` pre PR→`main`; takisto hook `commit-msg` v husky; ľudskí spoluautori sú povolení; #14436) | -| `check:vitest-exclusions` | Každé vylúčenie Vitest uvádza sledovaný problém a nachádza sa v `config/quality/vitest-exclusions.json` (#13204) | Áno | -| `check:file-size` | Žiadny zdrojový súbor neprekračuje limit pre príslušnú príponu (západka: zmrazené veľké súbory v zozname `frozen`) | Áno | -| `check:error-helper` | Chybové odpovede v exekútoroch/obslužných rutinách používajú `buildErrorBody()` / `sanitizeErrorMessage()` (pevné pravidlo č. 12) | Áno | -| `check:migration-numbering` | Migračné SQL súbory sú číslované postupne, bez medzier alebo duplicít | Áno | -| `check:public-creds` | Žiadne explicitné OAuth `client_id`/`client_secret` ani webové kľúče Firebase mimo `publicCreds.ts` (Pevné pravidlo č. 11) | Áno | -| `check:db-rules` | Žiadne nespracované SQL mimo modulov `src/lib/db/`; žiadne hromadné importy z `localDb.ts` (Pevné pravidlá č. 2/č. 5) | Áno | -| `check:known-symbols` | Vykonávacie moduly poskytovateľov, stratégie smerovania a prekladače zaregistrované vo svojich dispečerských tabuľkách zodpovedajú súborom na disku — žiadne osirotené ani nedeklarované symboly | Áno | -| `check:route-guard-membership` | Každá trasa, ktorá vytvára podradený proces, je klasifikovaná pomocou `isLocalOnlyPath()` (Pevné pravidlá č. 15/č. 17) | Áno | -| `check:test-discovery` | Každý súbor `*.test.ts` / `*.spec.ts` v repozitári je zahrnutý aspoň jedným nástrojom na spúšťanie testov (západka: zoznam osirotených súborov v `test-discovery-baseline.json` sa môže iba zmenšovať) | Áno | -| `check:agent-skills-sync` | Vygenerované artefakty agent-skills sa zhodujú so zdrojovým katalógom (bez odchýlok) | -| `check:provider-asset-provenance` | Logá a aktíva poskytovateľov majú zaznamenaný pôvod | -| `lint:json` | Konfiguračné súbory JSON je možné analyzovať a spĺňajú pravidlá lintovania repozitára | -| `typecheck:core` | Kompilácia TypeScriptu bez chýb (iba informatívne upozornenia) | Áno | -| `typecheck:noimplicit:core` | Striktné `noImplicitAny` — zamerané do budúcnosti; mnohé existujúce miesta volania stále potrebujú anotácie | **Informatívne** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` obmedzené na `src/app/(dashboard)/**` (#7033) — starostlivo vybraný zoznam 27 súborov v `typecheck:core` neobsahuje žiadny dashboardový súbor TSX a ani `next build` ich nikdy typovo nekontroluje (`next.config.mjs` nastavuje `ignoreBuildErrors: true`), takže regresie osirelých identifikátorov v tejto oblasti (#6625/#6909) boli pre CI neviditeľné. Rozdiely sa porovnávajú so zmrazenou východiskovou hodnotou počtu chýb podľa jednotlivých súborov a kódov TS (`config/quality/dashboard-typecheck-baseline.json`, rovnaký vzor vynucovania neaktuálnosti ako pri `check:known-symbols`) — kontrola zlyhá iba pri NOVÝCH chybách nad rámec východiskového počtu; keď sa opraví existujúca chyba, znížte východiskovú hodnotu pomocou `--update`. | Áno | +Spúšťa sa pri každom PR do vetvy `main`. Pri zlyhaní blokuje zlúčenie. + +| Skript (`npm run ...`) | Overuje | Blokujúce | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:node-runtime` | Verzia Node.js je v podporovanom rozsahu | Áno | +| `check:cycles` | Cyklické importy v celom `src/` + `open-sse/` (založené na AST, s rozlíšenými `paths` z tsconfig). Samostatné spustenie = informatívne, vypíše cykly. `check:cycles:ratchet` (spúšťaný v CI) blokuje, keď počet prekročí horný limit `metrics.cycles` v súbore `quality-baseline.json` — aktuálne 14, `direction: down`, takže môže iba klesať (#15159 G-01/G-02) | Áno (západka) | +| `check:route-validation:t06` | Prítomnosť schém Zod na všetkých trasách (pravidlá úrovne 6) | Áno | +| `check:any-budget:t11` | Počet `@ts-expect-error // any` neprekračuje limit (západka úrovne 11) | Áno | +| `check:provider-consistency` | Každý poskytovateľ v `providers.ts` má zodpovedajúci záznam v `providerRegistry.ts` (a naopak, v rámci zoznamu povolených položiek) | Áno | +| `check:model-lifecycle` | Tri ručne udržiavané smerovacie tabuľky zostávajú konzistentné so snapshotom životného cyklu uloženým v repozitári (#11503): `FITNESS_TABLE` (`taskFitness.ts`) nepriraďuje skóre žiadnemu vyradenému id, ktoré dokáže `REGISTRY` smerovať; každý cieľ `BUILT_IN_ALIASES` sa nachádza v `REGISTRY` a nenachádza sa v snapshote vyradených id; každé vyradené id, ktoré je stále v `REGISTRY`, je presmerované alebo uvedené v `allowedRetiredInCatalog`; a žiadny zdroj ani cieľ `DEFAULT_DEGRADATION_MAP` sa v tomto snapshote nejaví ako vyradený. Toto nedokazuje, že model je momentálne poskytovaný aktívnou upstream službou. Offline — porovnáva sa s `config/quality/model-lifecycle.json`, ktorý sa ručne obnovuje pomocou `npm run quality:refresh-model-lifecycle` (vyžaduje sieť; nie je zapojené do CI). `allowedRetiredInCatalog` je postupne sprísňovaný zoznam: záznam pridávajte iba spolu so sledovacou úlohou. | Áno | +| `check:fetch-targets` | Každé `fetch("/api/...")` v klientskej časti `src/` sa prekladá na skutočný `route.ts` | Áno | +| `check:deps` | Všetky závislosti inštalovateľné pomocou `npm install` naprieč každým súborom `package.json` v repozitári sa nachádzajú v `dependency-allowlist.json`; nové závislosti bez pevne určenej verzie alebo balíky s názvami napodobňujúcimi iné balíky sú označené | Áno | +| `audit:deps` | `npm audit` (koreňový projekt + electron) — žiadne upozornenia s vysokou alebo kritickou závažnosťou (prekrýva sa s osv `check:vuln-ratchet`; pozrite si Rationalization Backlog) | Áno | +| `check:lockfile` | Integrita súboru `package-lock.json` — register https, kontrolné súčty integrity, žiadne prepísania hostiteľa | Áno | +| `check:licenses` | Zoznam povolených licencií SPDX pre produkčné závislosti | Áno | +| `check:tracked-artifacts` | Žiadne artefakty zostavenia ani zahrnuté symbolické odkazy na `node_modules` (spúšťa sa aj v husky pre-commit; pre-push je zámerne odľahčený — #6716) | Áno | +| `check:ai-attribution` | Žiadna pätička `Co-Authored-By` od AI/bota ani pätička o generovaní pomocou AI v commitoch, názve či tele PR — Prísne pravidlo č. 16 (v slučke rýchlych kontrol `quality.yml` pre PR→`release/**` — číta dáta udalosti, mimo PR nevykoná nič — a krok len pre PR v kontrole lint súboru `ci.yml` pre PR→`main`; tiež hook husky `commit-msg`; ľudskí spoluautori sú povolení; #14436) | +| `check:vitest-exclusions` | Každé vylúčenie Vitest uvádza sledovaný problém a nachádza sa v `config/quality/vitest-exclusions.json` (#13204) | Áno | +| `check:file-size` | Žiadny zdrojový súbor neprekračuje limit pre danú príponu (postupné sprísňovanie: veľké súbory zmrazené v zozname `frozen`) | Áno | +| `check:error-helper` | Chybové odpovede v executoroch/handleroch používajú `buildErrorBody()` / `sanitizeErrorMessage()` (Prísne pravidlo č. 12) | Áno | +| `check:migration-numbering` | Migračné SQL súbory sú číslované sekvenčne, bez medzier alebo duplicít | Áno | +| `check:public-creds` | Žiadne doslovné OAuth `client_id`/`client_secret` ani webové kľúče Firebase mimo `publicCreds.ts` (Pevné pravidlo č. 11) | Áno | +| `check:db-rules` | Žiadne nespracované SQL mimo modulov `src/lib/db/`; žiadne súhrnné importy z `localDb.ts` (Pevné pravidlá č. 2/5) | Áno | +| `check:known-symbols` | Vykonávacie moduly poskytovateľov, stratégie smerovania a prekladače registrované vo svojich dispečerských tabuľkách sa zhodujú so súbormi na disku — žiadne osirelé ani nedeklarované symboly | Áno | +| `check:route-guard-membership` | Každá trasa, ktorá spúšťa podriadený proces, je klasifikovaná pomocou `isLocalOnlyPath()` (Pevné pravidlá č. 15/17) | Áno | +| `check:test-discovery` | Každý súbor `*.test.ts` / `*.spec.ts` v repozitári je zahrnutý aspoň jedným nástrojom na spúšťanie testov (západka: zoznam osirelých súborov v `test-discovery-baseline.json` sa môže iba zmenšovať) | Áno | +| `check:agent-skills-sync` | Vygenerované artefakty agent-skills zodpovedajú svojmu zdrojovému katalógu (bez odchýlok) | +| `check:provider-asset-provenance` | Logá/aktíva poskytovateľov majú zaznamenaný údaj o pôvode | +| `lint:json` | Konfiguračné súbory JSON sa dajú analyzovať a spĺňajú pravidlá lintovania repozitára | +| `typecheck:core` | Kompilácia TypeScript bez chýb (iba informatívne upozornenia) | Áno | +| `typecheck:noimplicit:core` | Striktné `noImplicitAny` — zamerané do budúcnosti; mnohé existujúce miesta volania stále potrebujú anotácie | **Informatívne** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` obmedzené na `src/app/(dashboard)/**` (#7033) — starostlivo vybraný zoznam 27 súborov v `typecheck:core` neobsahuje žiadne dashboard TSX a ani `next build` ich nikdy typovo nekontroluje (`next.config.mjs` nastavuje `ignoreBuildErrors: true`), takže regresie osirelých identifikátorov v tejto oblasti (#6625/#6909) neboli pre CI viditeľné. Rozdiely sa porovnávajú so zmrazenou východiskovou hodnotou počtu chýb podľa súboru a kódu TS (`config/quality/dashboard-typecheck-baseline.json`, rovnaký vzor vynucovania neaktuálnosti ako pri `check:known-symbols`) — kontrola zlyhá iba pri NOVÝCH chybách nad rámec východiskového počtu; po oprave existujúcej chyby znížte východiskovú hodnotu pomocou `--update`. | Áno | ### Úloha: `quality-gate` Spúšťa sa po `test-coverage`. Pri zlyhaní zablokuje zlúčenie. -| Skript | Overuje | Blokujúce | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | -| `quality:collect` | Vytvorí `quality-metrics.json` (počet upozornení ESLint, pokrytie zo zlúčenej správy segmentov) | Áno (predchádza mechanizmu ratchet) | -| `quality:ratchet` | Žiadna metrika v `quality-baseline.json` sa nezhoršila (upozornenia ESLint ≤ základná hodnota; pokrytie ≥ základná hodnota) | Áno | -| `check:duplication` | Duplikácia kódu (jscpd@4) neprekračuje základnú hodnotu v `quality-baseline.json` | Áno | -| `check:complexity` | Cyklomatická zložitosť na úrovni súboru neprekračuje limit (základné pravidlá ESLint `complexity` + `max-lines-per-function`) | Áno | -| `check:cognitive-complexity` | Ratchet kognitívnej zložitosti (`eslint-plugin-sonarjs`) — samostatný priechod ESLint; CI spúšťa oba zlúčené do jediného kroku `check:complexity-ratchets` | Áno | -| `check:dead-code` | Ratchet nepoužitých exportov/súborov (knip) sa v porovnaní so základnou hodnotou nezhoršil | Áno | -| `check:compression-budget` | Rozpočet benchmarku kompresie — minimálne úspory tokenov pre jednotlivé enginy sa nesmú zhoršiť | Áno | -| `check:type-coverage` | Ratchet percentuálneho podielu typovaného kódu (`type-coverage`) sa nezhoršil; do značnej miery nahrádza `typecheck:noimplicit:core` | Áno | -| `check:codeql-ratchet` | Počet otvorených upozornení CodeQL sa nezhoršil (načítava sa cez `gh api`; bez tokenu sa kontrola korektne preskočí) — frekvencia obnovovania a manuálne spustenie: pozrite nižšie „CodeQL ratchet“ | Áno | +| Skript | Overuje | Blokujúce | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `quality:collect` | Vytvára `quality-metrics.json` (počet upozornení ESLint, pokrytie zo zlúčenej správy segmentov) | Áno (predchádza sprísňovaniu) | +| `quality:ratchet` | Žiadna metrika v `quality-baseline.json` sa nezhoršila (upozornenia ESLint ≤ základná hodnota; pokrytie ≥ základná hodnota) | Áno | +| `check:duplication` | Duplikácia kódu (jscpd@4) neprekračuje základnú hodnotu v `quality-baseline.json` | Áno | +| `check:complexity` | Cyklomatická zložitosť na úrovni súborov neprekračuje limit (základné pravidlá ESLint `complexity` + `max-lines-per-function`) | Áno | +| `check:cognitive-complexity` | Sprísňovanie kognitívnej zložitosti (`eslint-plugin-sonarjs`) — samostatný priechod ESLint; CI spúšťa obe kontroly zlúčené do jediného kroku `check:complexity-ratchets` | Áno | +| `check:dead-code` | Sprísňovanie nepoužitých exportov/súborov (knip) sa oproti základnej hodnote nezhoršilo | Áno | +| `check:compression-budget` | Rozpočet benchmarku kompresie — minimálne úspory tokenov pre jednotlivé enginy sa nesmú zhoršiť | Áno | +| `check:type-coverage` | Sprísňovanie percentuálneho podielu typovaného kódu (`type-coverage`) sa nezhoršilo; do veľkej miery nahrádza `typecheck:noimplicit:core` | Áno | +| `check:codeql-ratchet` | Počet otvorených upozornení CodeQL sa nezhoršil (načítava cez `gh api`; bez tokenu sa korektne preskočí) — frekvencia obnovovania a manuálne spustenie: pozrite si časť „Sprísňovanie CodeQL“ nižšie | Áno | ### Úloha: `quality-extended` -Celá úloha má poradný charakter (`continue-on-error: true`). Ratchety založené na npm sa -spúšťajú reálne; externé skenery sa inštalujú pomocou `gh release download` a samy sa -preskočia (exit 0), keď binárny súbor stále chýba. +Celá úloha je informatívna (`continue-on-error: true`). Sprísňovacie kontroly založené na npm sa spúšťajú +naostro; externé skenery sa inštalujú cez `gh release download` a samy sa preskočia (ukončovací kód 0), +ak binárny súbor stále chýba. -| Skript | Overuje | Blokujúce | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| `check:circular-deps` | Žiadne cyklické závislosti (dpdm) | **Poradné** | -| `check:bundle-size` | Veľkosť balíka neprekračuje limit | **Poradné** | -| `check:secrets` | Skenovanie tajných údajov (gitleaks) — preskočí sa, ak binárny súbor chýba | **Poradné** | -| `check:vuln-ratchet` | Zraniteľnosti závislostí (osv-scanner) sa nezhoršili — preskočí sa, ak binárny súbor chýba | **Poradné** | -| `check:workflows` | Kontrola workflowov (actionlint + zizmor); chýbajúce/nefunkčné skenery, neplatné správy alebo chýbajúca základná hodnota ratchetu spôsobia zlyhanie so stavom INCOMPLETE. Platné nálezy sa riadia vybranou prísnou/poradnou/ratchet politikou | Vykonanie je povinné; ratchet zizmor je v CI blokujúci | -| `check:openapi-breaking` | Nekompatibilné zmeny verejného kontraktu API (`openapi.yaml`) oproti základnej vetve (oasdiff) — vytvorí `openapiBreaking=N`; preskočí sa, ak oasdiff chýba alebo základnú špecifikáciu nemožno načítať | **Poradné** | +| Skript | Overuje | Blokujúce | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| `check:circular-deps` | Žiadne cyklické závislosti (dpdm) | **Informatívne** | +| `check:bundle-size` | Veľkosť balíka neprekračuje limit | **Informatívne** | +| `check:secrets` | Skenovanie tajných údajov (gitleaks) — preskočí sa, ak binárny súbor chýba | **Informatívne** | +| `check:vuln-ratchet` | Zraniteľnosti závislostí (osv-scanner) sa nezhoršili — preskočí sa, ak binárny súbor chýba | **Informatívne** | +| `check:workflows` | Kontrola pracovných postupov (actionlint + zizmor); chýbajúce/nefunkčné skenery, neplatné správy alebo chýbajúca základná hodnota sprísňovania zlyhajú so stavom INCOMPLETE. Platné nálezy sa riadia vybranou prísnou/informatívnou/sprísňovacou politikou | Spustenie je povinné; sprísňovanie zizmor je v CI blokujúce | +| `check:openapi-breaking` | Nekompatibilné zmeny verejného kontraktu API (`openapi.yaml`) oproti základnej vetve (oasdiff) — vytvára `openapiBreaking=N`; preskočí sa, ak oasdiff chýba alebo základnú špecifikáciu nemožno načítať | **Informatívne** | ### Úloha: `docs-sync-strict` -Spúšťa sa pri každom PR do `main`. Pri zlyhaní blokuje zlúčenie. - -| Skript | Overuje | Blokujúce | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `check:docs-all` | Metakontrola, ktorá postupne spúšťa 6 čiastkových kontrol uvedených nižšie | Áno | -| ↳ `check:docs-sync` | Konzistentnosť verzií v CHANGELOG-u / OpenAPI / llm.txt | Áno | -| ↳ `check:docs-counts` | Počty v texte (počet poskytovateľov, počet migrácií atď.) sú v rámci sprísňujúceho sa tolerančného rozsahu skutočných počtov | Áno | -| ↳ `check:env-doc-sync` | Každá premenná prostredia v `.env.example` je zdokumentovaná v tabuľke dokumentácie a naopak | Áno | -| ↳ `check:deprecated-versions` | V dokumentácii sa nenachádzajú žiadne reťazce zastaraných verzií | Áno | -| ↳ `check:doc-links` | Interné markdownové odkazy v dokumentácii odkazujú na existujúce súbory (formát `[text]`/`(path)`) | Áno | -| ↳ `check:fabricated-docs` | Trasy, premenné prostredia, príkazy CLI, názvy hookov a cesty k súborom uvedené v dokumentácii existujú v kódovej základni. Tvrdá kontrola cez `--strict`; bez príznaku iba upozornenie. | Áno (cez `--strict` v CI) | -| `check:cli-i18n` | Reťazce príkazov CLI sa nachádzajú vo všetkých lokalizačných súboroch i18n | Áno | -| `check:openapi-coverage` | Špecifikácia OpenAPI pokrýva aspoň postupne zvyšované minimum skutočných trás | Áno | -| `check:openapi-security-tiers` | Anotácie úrovní zabezpečenia v `openapi.yaml` sú konzistentné s klasifikáciami v `routeGuard.ts` | **Odporúčacie** | -| `check:openapi-routes` | Každá cesta v `openapi.yaml` odkazuje na skutočný súbor `route.ts` (ochrana proti halucináciám) | Áno | -| `check:docs-symbols` | Každý odkaz `/api/...` v `docs/**/*.md` odkazuje na skutočný súbor `route.ts` (ochrana proti halucináciám) | Áno | -| `i18n translation drift` | Nepreložené kľúče v lokalizačných súboroch i18n — iba upozornenie | **Odporúčacie** | +Spúšťa sa pri každom PR do vetvy `main`. Pri zlyhaní zablokuje zlúčenie. + +| Skript | Overuje | Blokujúce | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `check:docs-all` | Metabrána, ktorá postupne spúšťa 6 nižšie uvedených čiastkových brán | Áno | +| ↳ `check:docs-sync` | Konzistentnosť verzií v CHANGELOG / OpenAPI / llm.txt | Áno | +| ↳ `check:docs-counts` | Počty v texte (počet poskytovateľov, počet migrácií atď.) sú v rámci sprísňujúceho sa tolerančného rozsahu skutočných počtov | Áno | +| ↳ `check:env-doc-sync` | Každá premenná prostredia v `.env.example` je zdokumentovaná v tabuľke dokumentácie a naopak | Áno | +| ↳ `check:deprecated-versions` | V dokumentácii sa nenachádzajú žiadne reťazce zastaraných verzií | Áno | +| ↳ `check:doc-links` | Interné markdownové odkazy v dokumentácii odkazujú na existujúce súbory (vo formáte `[text]`/`(path)`) | Áno | +| ↳ `check:fabricated-docs` | Trasy, premenné prostredia, príkazy CLI, názvy hookov a cesty k súborom uvedené v dokumentácii existujú v kódovej báze. Pevná brána cez `--strict`; bez príznaku mäkké zlyhanie. | Áno (cez `--strict` v CI) | +| `check:cli-i18n` | Reťazce príkazov CLI sa nachádzajú vo všetkých lokalizačných súboroch i18n | Áno | +| `check:openapi-coverage` | Špecifikácia OpenAPI pokrýva aspoň postupne zvyšovanú minimálnu hranicu skutočných trás | Áno | +| `check:openapi-security-tiers` | Anotácie úrovní zabezpečenia v `openapi.yaml` sú konzistentné s klasifikáciami v `routeGuard.ts` | **Odporúčacie** | +| `check:openapi-routes` | Každá cesta v `openapi.yaml` odkazuje na skutočný súbor `route.ts` (ochrana proti halucináciám) | Áno | +| `check:docs-symbols` | Každý odkaz `/api/...` v `docs/**/*.md` odkazuje na skutočný súbor `route.ts` (ochrana proti halucináciám) | Áno | +| `i18n translation drift` | Nepreložené kľúče v lokalizačných súboroch i18n — iba upozornenie | **Odporúčacie** | ### Úloha: `i18n-ui-coverage` -| Skript | Overuje | Blokujúce | -| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (vložený) | Pokrytie kľúčov i18n používateľského rozhrania je ≥ 65 % | Áno | -| `check-ui-value-drift` (vložený) | Prepísaná anglická **hodnota** po sebe nezanechá žiadny zastaraný preklad | Áno | -| `check-new-key-coverage` (vložený) | **Nový** anglický kľúč je preložený v každej lokalizácii — značka `__MISSING__:` je odmietnutá | Áno | -| `check-translation-ratio` | Pomer skutočných prekladov podľa lokalizácie (položky zhodné s angličtinou / zástupné / chýbajúce mimo zoznamu povolených výnimiek) nesmie prekročiť `config/quality/i18n-translation-baseline.json` + toleranciu | **Odporúčacie** | +| Skript | Overuje | Blokujúce | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | +| `check-ui-keys-coverage` (inline) | Pokrytie kľúčov i18n používateľského rozhrania je ≥ 65 % | Áno | +| `check-ui-value-drift` (inline) | Prepísaná anglická **hodnota** po sebe nezanechá žiadny zastaraný preklad | Áno | +| `check-new-key-coverage` (inline) | **Nový** anglický kľúč je preložený v každej lokalizácii — značka `__MISSING__:` sa zamietne | Áno | +| `check-translation-ratio` | Pomer skutočných prekladov v jednotlivých lokalizáciách (hodnoty zhodné s angličtinou / zástupné hodnoty / chýbajúce listy mimo zoznamu povolených výnimiek) nesmie prekročiť `config/quality/i18n-translation-baseline.json` + toleranciu | **Odporúčacie** | -Vyžaduje `fetch-depth: 0` — kontrola odchýlok hodnôt porovnáva `en.json` voči spoločnému predkovi vetiev. +Vyžaduje `fetch-depth: 0` — brána odchýlky hodnôt porovnáva `en.json` so spoločným základom zlúčenia. -#### `check-ui-value-drift` — kontrola zastaraných prekladov +#### `check-ui-value-drift` — brána zastaraných prekladov -Zachytáva jedinú regresiu i18n, ktorú ostatné kontroly zo svojej podstaty nedokážu odhaliť: anglická hodnota -sa prepíše, ale preklady odvodené od _predchádzajúcej_ anglickej verzie zostanú nezmenené, takže -používatelia iných jazykov naďalej čítajú sebavedomo formulovaný, no už nesprávny text. +Zachytáva tú regresiu i18n, ktorú ostatné brány zo svojej podstaty nedokážu odhaliť: anglická hodnota +sa prepíše a preklady odvodené od _predchádzajúcej_ anglickej verzie zostanú nezmenené, takže +používatelia iných jazykov naďalej čítajú presvedčivo formulovaný, no už nesprávny text. -Tento problém sa skutočne dostal do vydanej verzie. `oauthModal.googleOAuthWarning` bol prepísaný pri pridaní -pomocníka na prihlásenie Antigravity (#5203); **39 zo 43 lokalizácií** si ponechalo text, ktorý operátorom -prikazoval „skopírovať celú URL adresu a vložiť ju nižšie“ — postup, ktorý pri tomto poskytovateľovi nemožno -dokončiť. Problém zostal nepovšimnutý až do #8463, pretože: +Toto sa skutočne dostalo do vydania. `oauthModal.googleOAuthWarning` bol prepísaný po pridaní pomocníka +prihlásenia Antigravity (#5203); **39 zo 43 lokalizácií** si ponechalo text, ktorý operátorom prikazoval „skopírovať +celú adresu URL a vložiť ju nižšie“ — postup, ktorý sa pri danom poskytovateľovi nedá dokončiť. Problém +zostal nepovšimnutý až do #8463, pretože: - `sync-ui-keys` dopĺňa iba kľúče, ktoré **chýbajú**, nikdy nie tie, ktoré sú **zastarané**; - `check-ui-keys-coverage` počíta _prítomnosť_ kľúčov, takže zastaraný preklad sa započíta ako pokrytý; -- `check-translation-drift` sleduje zrkadlá dokumentácie `docs/i18n//**.md` — - nikdy nečíta `src/i18n/messages/*.json`. Blokujúce v úlohe `docs-sync-strict` od opätovnej synchronizácie - 2026-09: upravte hlavný dokument → `npm run i18n:run -- --files=` (na úrovni sekcie, nenáročné). +- `check-translation-drift` sleduje zrkadlové kópie dokumentácie `docs/i18n//**.md` — + nikdy nečíta `src/i18n/messages/*.json`. V úlohe `docs-sync-strict` je blokujúci od opätovnej + synchronizácie 2026-09: upravte základný dokument → `npm run i18n:run -- --files=` (na úrovni sekcií, nenáročné). -**Zohľadňuje rozdiely, nie je založená na východiskovom stave.** Porovnáva `en.json` v spoločnom predkovi s -pracovným stromom; pre každý kľúč, ktorého anglická hodnota sa zmenila, je každý jazyk, ktorý stále obsahuje -nezmenený preklad, zastaraný. Týmto sa zámerne **zmrazí už existujúci dlh** — z rozdielu -nemožno zistiť, z ktorej starej anglickej verzie dlhodobý preklad pochádza, takže kontrola posudzuje -iba to, čoho sa aktuálna zmena týka. Alternatíva (východiskový hash pre každý kľúč) by si vyžadovala -~600 KB generovaný súbor, 3× väčší než najväčší existujúci východiskový súbor, ktorý by sa menil pri každom i18n PR. +**Zohľadňuje rozdiely, nie je založená na východiskovom stave.** Porovnáva `en.json` v spoločnom predkovi vetiev +s pracovným stromom; pri každom kľúči, ktorého anglická hodnota sa zmenila, je každý jazyk, ktorý stále obsahuje +nezmenený preklad, zastaraný. Tým sa zámerne **zmrazí už existujúci dlh** — z rozdielu +nemožno zistiť, z ktorej starej anglickej verzie dlhodobo existujúci preklad pochádza, preto kontrola posudzuje +iba to, čo aktuálna zmena ovplyvňuje. Alternatíva (východiskový stav s hashom pre každý kľúč) by si vyžadovala +približne 600 KB generovaný súbor, 3× väčší než najväčší existujúci východiskový súbor, ktorý by sa menil pri každom i18n PR. -Kontrolu možno splniť dvoma spôsobmi: +Požiadavku možno splniť dvoma spôsobmi: 1. aktualizovať dotknuté preklady alebo -2. nastaviť ich na `__MISSING__:` — za behu sa potom zobrazí opravená angličtina +2. nastaviť ich na `__MISSING__:` — aplikácia potom za behu poskytne opravený anglický text (`src/i18n/request.ts::deepMergeFallback`, #7258) a kľúč sa zaradí do frontu na preklad. Ak sa zmenil **význam** reťazca, uprednostnite **premenovanie kľúča**: nový kľúč nemôže zdediť @@ -233,20 +231,20 @@ zastaraný preklad. Tento postup bol použitý v #8463. ```bash npm run i18n:check-value-drift # striktné (spúšťa sa v CI) -npm run i18n:check-value-drift:warn # iba hlásenie +npm run i18n:check-value-drift:warn # iba výpis BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Skončí s kódom 0 a hlásením `SKIP reason=base-unresolved`, keď sa východiskový katalóg nedá načítať (plytký -klon bez východiskovej referencie), rovnako ako `check-openapi-breaking`. +Skončí s kódom 0 a hlásením `SKIP reason=base-unresolved`, keď nemožno načítať základný katalóg (plytký +klon bez základnej referencie), rovnako ako `check-openapi-breaking`. ### Úloha: `i18n` -Úplná matica validácie i18n (jedna úloha pre každý jazyk). Celá úloha je informačná. +Úplná matica validácie i18n (jedna úloha pre každý jazyk). Celá úloha je informatívna. -| Skript | Overuje | Blokovanie | -| ------------------------------- | -------------------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | Úplnosť prekladu pre každý jazyk | **Informačné** (`continue-on-error: true` pre celú úlohu) | +| Skript | Overuje | Blokovanie | +| ------------------------------- | -------------------------------- | ----------------------------------------------------------- | +| `validate_translation.py quick` | Úplnosť prekladu pre každý jazyk | **Informatívne** (`continue-on-error: true` pre celú úlohu) | ### Úloha: `pr-test-policy` @@ -255,30 +253,30 @@ Spúšťa sa iba pri pull requestoch. | Skript | Overuje | Blokovanie | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | | `check:pr-test-policy` | PR, ktoré menia produkčný kód v `src/`, `open-sse/`, `electron/` alebo `bin/`, musia obsahovať alebo aktualizovať testy (Prísne pravidlo č. 8) | Áno | -| `check:test-masking` | Zmenené testovacie súbory neznižujú celkový počet asertov ani nepridávajú tautológie `assert.ok(true)` | Áno | +| `check:test-masking` | Zmenené testovacie súbory neznižujú čistý počet kontrol ani nepridávajú tautológie `assert.ok(true)` | Áno | | `check:pr-evidence` | Telo PR uvádza dôkazy z testov/VPS pre danú zmenu (automatizuje Prísne pravidlo č. 18 prehľadávaním textu PR — krehké, pozri Backlog) | Áno | ### Úloha: `test-vitest` -Spúšťa sa po `build`. Pri zlyhaní blokuje zlúčenie. +Spúšťa sa po `build`. Pri zlyhaní zablokuje zlúčenie. -| Sada | Overuje | Blokovanie | -| ---------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Server MCP (110 nástrojov), autoCombo, cache — spúšťač vitest | Áno | -| `test:vitest:ui` | Testy komponentov používateľského rozhrania — spúšťač vitest | **Blokujúce** — už existujúce zlyhania sú explicitne vylúčené v `vitest.config.ts`; nové zlyhania spôsobia zlyhanie úlohy | +| Sada | Overuje | Blokovanie | +| ---------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Server MCP (110 nástrojov), autoCombo, vyrovnávacia pamäť — testovací nástroj vitest | Áno | +| `test:vitest:ui` | Testy komponentov používateľského rozhrania — testovací nástroj vitest | **Blokujúce** — už existujúce zlyhania sú explicitne vylúčené v `vitest.config.ts`; nové zlyhania spôsobia zlyhanie úlohy | -### Nočné pracovné postupy (plánované, informačné) +### Nočné pracovné postupy (plánované, informatívne) -Spúšťajú sa podľa plánu cron (a pomocou `workflow_dispatch`), nikdy nie pri PR. Všetky sú informačné. +Spúšťajú sa podľa plánu cron (a cez `workflow_dispatch`), nikdy nie pri PR. Všetky sú informatívne. -| Pracovný postup | Overuje | Blokovanie | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | -| `nightly-property` | Testy vlastností fast-check s náhodným počiatočným číslom + vysokým počtom behov | **Informačné** | -| `nightly-resilience` | Kontrola rastu haldy, vkladanie chaotických porúch, záťažové/dlhotrvajúce testovanie k6 | **Informačné** | -| `nightly-llm-security` | Ochrana promptfoo proti injekciám (režim blokovania) + sondy garak (preskočené bez tajného kľúča poskytovateľa) | **Informačné** | -| `nightly-schemathesis` | Fuzzovanie kontraktu OpenAPI (schemathesis) proti spustenej službe OmniRoute pomocou `docs/openapi.yaml` — odhaľuje porušenia špecifikácie / neošetrené chyby 500 (Fáza 8 B.4) | **Informačné** | -| `nightly-mutation` | Skóre mutačného testovania Stryker v rýchlej vetve jednotkových testov — prežívajúce mutanty odhaľujú slabé aserty | **Informačné** | -| `nightly-compat` | Matica kompatibility enginu Node naprieč podporovanými rozsahmi `engines.node` | **Informačné** | +| Pracovný postup | Overuje | Blokovanie | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `nightly-property` | Testy vlastností fast-check s náhodným počiatočným semenom a vysokým počtom spustení | **Informatívne** | +| `nightly-resilience` | Kontrolu rastu haldy, vkladanie porúch na testovanie odolnosti, záťažové/dlhodobé testy k6 | **Informatívne** | +| `nightly-llm-security` | Ochranu promptfoo proti injekciám (režim blokovania) + sondy garak (preskočené bez tajného kľúča poskytovateľa) | **Informatívne** | +| `nightly-schemathesis` | Fuzzovanie kontraktu OpenAPI (schemathesis) voči spustenej službe OmniRoute pomocou `docs/openapi.yaml` — odhaľuje porušenia špecifikácie / neošetrené chyby 500 (Fáza 8 B.4) | **Informatívne** | +| `nightly-mutation` | Skóre mutačného testovania Stryker v rýchlej vetve jednotkových testov — prežívajúce mutanty odhaľujú slabé kontroly | **Informatívne** | +| `nightly-compat` | Maticu kompatibility jadra Node v podporovaných rozsahoch `engines.node` | **Informatívne** | --- @@ -542,43 +540,43 @@ chybu pripojenia a nikdy nepreruší relácie. --- -## Zoznam racionalizácie (preskúmanie ROI — Fáza 9 Vlna 3) +## Zoznam racionalizačných úloh (preskúmanie ROI — fáza 9, vlna 3) -Tento inventár bol 2026-06-17 zosúladený s `ci.yml` (predchádzajúca verzia vynechala +Tento inventár bol 2026-06-17 zosúladený s `ci.yml` (predchádzajúca verzia vynechávala `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Preskúmanie ROI zosúladenej množiny -identifikovalo nasledujúcich kandidátov na racionalizáciu. **Zlúčenia sú mechanické zmeny -CI; prepnutia/odstránenia sú politické rozhodnutia vyhradené pre operátora.** Nič z nižšie +identifikovalo nasledujúcich kandidátov na racionalizáciu. **Zlúčenia sú mechanické zmeny CI; +prepnutia/odstránenia sú politické rozhodnutia vyhradené pre operátora.** Nič z nižšie uvedeného zatiaľ nebolo aplikované. **Vyššie takisto nezdokumentované** (informatívne, nízka výpovedná hodnota): úloha `docs-lint` (markdownlint + Vale, celá úloha s `continue-on-error`) a samostatné pracovné postupy skenerov `semgrep.yml` / `codeql.yml` / `scorecard.yml`. Hodnota `semgrepFindings: 0` sa nachádza v -`quality-baseline.json`, ale nie je prepojená s blokujúcou západkou v `ci.yml` — metrika je +`quality-baseline.json`, ale v `ci.yml` nie je napojená na blokujúcu západku — metrika je momentálne osirelá. ### Zlúčenie / deduplikácia (mechanické, nižšie riziko) -Každý kandidát bol 2026-06-17 overený voči aktuálnemu stavu kontrolných brán (dôveruj, ale preveruj); -ukázalo sa, že viacero „zrejmých“ zlúčení skrýva technický dlh a **nie sú** priamočiarymi náhradami. +Každý kandidát bol 2026-06-17 overený voči aktuálnemu stavu brán (dôveruj, ale preveruj); +ukázalo sa, že viaceré „zjavné“ zlúčenia skrývajú dlh a **nie sú** bezproblémovými náhradami. -- **`check:docs-sync` sa spúšťa dvakrát** — samostatne v úlohe `lint` a znova v rámci `check:docs-all` (`docs-sync-strict`) aj v pre-commit hooku husky. ✅ **HOTOVO** — samostatné spustenie v úlohe `lint` bolo odstránené. -- **Skenovanie CVE** — ❌ **NIE JE to čisté zlúčenie.** `audit:deps` bezpodmienečne zlyhá pri akejkoľvek CVE s vysokou/kritickou závažnosťou; `check:vuln-ratchet` (osv) zlyhá iba pri _regresii_ oproti východiskovému stavu (aktuálne 1 MODERATE). Odlišná sémantika — odstránením `audit:deps` by sa stratila absolútna kontrolná brána pre vysokú/kritickú závažnosť. Ponechať obe. -- **Detekcia cyklov** — ❌ **NIE JE to čisté zlúčenie.** `check:circular-deps` (dpdm) hlási **91 cyklov** (preto má informatívny charakter); nemožno ho zmeniť na blokujúci bez ich predchádzajúceho vyriešenia a má širší rozsah než úspešná, cielene zostavená kontrola `check:cycles`. Ponechať `check:cycles` ako blokujúcu; vyriešenie 91 cyklov dpdm je samostatnou položkou zoznamu úloh. -- **Zložitosť** — ✅ **HOTOVO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jeden prechod ESLint, počítanie podľa ruleId, takže východiskové hodnoty cyklomatickej zložitosti + maximálneho počtu riadkov a kognitívnej zložitosti zostávajú nezávislé; samostatné `check:complexity` / `check:cognitive-complexity` zostávajú zachované na lokálne použitie s `--update`. -- **Ochrana `/api` proti halucináciám** — ✅ **HOTOVO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jeden inventár FS pre `src/app/api`, openapi-routes + docs-symbols naďalej hlásia výsledky nezávisle; samostatné kontroly zostávajú zachované na lokálne spustenia. -- **`check:node-runtime` sa spúšťa v 11 úlohách** — ⚠️ **nízke ROI.** Každá používa samostatný runner a kontrola trvá <1 s; celková úspora je približne 10 s za cenu straty lacnej ochrany v každej úlohe. Nestojí to za tieto zmeny. -- **`typecheck:noimplicit:core` v kontrole lint CI** — ✅ **odstránené z úlohy lint** (bolo informatívne s `continue-on-error`); blokujúci typový povrch tvoria `typecheck:core` + `check:type-coverage`. Lokálny skript zostal zachovaný. +- **`check:docs-sync` sa spúšťa dvakrát** — samostatne v úlohe `lint` a znova v rámci `check:docs-all` (`docs-sync-strict`) a hooku husky pre pre-commit. ✅ **HOTOVO** — samostatné spustenie v úlohe `lint` bolo odstránené. +- **Skenovanie CVE** — ❌ **NIE JE to bezproblémové zlúčenie.** `audit:deps` tvrdo zlyhá pri ľubovoľnej CVE s vysokou/kritickou závažnosťou; `check:vuln-ratchet` (osv) zlyhá iba pri _regresii_ oproti východiskovej hodnote (aktuálne 1 MODERATE). Odlišná sémantika — odstránením `audit:deps` by sa stratila absolútna brána pre vysokú/kritickú závažnosť. Ponechať obe. +- **Detekcia cyklov** — ✅ **HOTOVO** (#15159 G-01/G-02). Starý text tu označoval `check:cycles` za „zelenú, starostlivo zostavenú“ bránu a odôvodňoval jej zachovanie ako blokujúcej tým, že `check:circular-deps` (dpdm) hlásil 91 cyklov. Tento zelený stav bol **falošne zelený**: `check:cycles` skenoval 5 podadresárov (450 súborov), vyhľadával iba statické `import|export … from` a zahadzoval každý špecifikátor `@/` a `@omniroute/open-sse/`, takže nemohol zachytiť cykly dynamických importov a aliasov, ktoré v repozitári prevládali. Opravené: brána teraz prechádza `src` + `open-sse` (5023 súborov), zhromažďuje špecifikátory z AST TypeScriptu (takže `import("…")` sa započítava a `typeof import("…")` v typovej pozícii nie) a rozpoznáva `paths` z tsconfig. Nachádza **14** cyklov, nie 0. Keďže 14 existujúcich cyklov nemožno opraviť v PR pre bránu, `check:cycles` je teraz **západka** (`--ratchet`, strop `metrics.cycles.value = 14` v `quality-baseline.json`, `direction: down`) — blokuje akúkoľvek _regresiu_ a počet môže iba klesať. CI spúšťa `npm run check:cycles:ratchet`. Postupné odstraňovanie prebieha spolu s **A-01**. `check:circular-deps` (dpdm) zostáva informatívny ako širší druhý názor. +- **Zložitosť** — ✅ **HOTOVO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): jeden prechod ESLintom, počítanie podľa ruleId, aby východiskové hodnoty cyklomatickej zložitosti + max-lines a kognitívnej zložitosti zostali nezávislé; jednotlivé `check:complexity` / `check:cognitive-complexity` zostávajú na lokálne použitie s `--update`. +- **Ochrana `/api` proti halucináciám** — ✅ **HOTOVO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): jeden inventár FS pre `src/app/api`, openapi-routes + docs-symbols naďalej hlásia výsledky nezávisle; jednotlivé kontroly zostávajú na lokálne spúšťanie. +- **`check:node-runtime` sa spúšťa v 11 úlohách** — ⚠️ **nízke ROI.** Každá beží na samostatnom runneri a kontrola trvá <1 s; celková úspora je približne 10 s za cenu straty lacnej ochrany v každej úlohe. Nestojí to za súvisiace zmeny. +- **`typecheck:noimplicit:core` v úlohe lint CI** — ✅ **odstránené z úlohy lint** (bolo informatívne s `continue-on-error`); blokujúci typový povrch tvoria `typecheck:core` + `check:type-coverage`. Lokálny skript bol zachovaný. ### Prepnúť / rozhodnúť (politika operátora) -- `check:openapi-security-tiers` (informatívne) — ❌ **NEDÁ SA čisto prepnúť.** Končí s kódom 0, ale upozorňuje, že viacerým trasám `traffic-inspector` v rámci `LOCAL_ONLY_API_PREFIXES` chýba anotácia `x-loopback-only: true`. Jeho vynútenie najskôr vyžaduje pridanie týchto anotácií do `openapi.yaml`. -- `typecheck:noimplicit:core` (informatívne) — z veľkej časti ho nahrádza blokujúca západka `check:type-coverage`. Zmeniť na západku alebo odstrániť redundantný druhý prechod `tsc`. -- `test:vitest:ui` (teraz **blokujúce**) — už existujúce zlyhania sú explicitne vylúčené v `vitest.config.ts` pomocou sledovacích komentárov `// #8618`; nové zlyhania spôsobia zlyhanie úlohy. -- `check:secrets` (gitleaks, blokujúca západka zmrazená na 3 zdokumentovaných falošne pozitívnych nálezoch) — pridať tieto 3 nálezy do zoznamu povolených a dosiahnuť tak 0 alebo zmeniť kontrolu na informatívnu. Prekrýva sa s natívnym skenovaním tajomstiev GitHubu + `check:public-creds`. -- `check:pr-evidence` (blokujúce, prehľadáva text tela PR pomocou grep) — vysoké riziko falošne pozitívnych nálezov; jeho odstránenie oslabí vynucovanie pevného pravidla č. 18, takže ide o skutočné politické rozhodnutie. -- `semgrep` (samostatné informatívne) — pri rodinách OWASP sa prekrýva s CodeQL; prepojiť jeho východiskový stav so západkou alebo ho odstrániť. +- `check:openapi-security-tiers` (informatívne) — ❌ **NEDÁ SA bezproblémovo prepnúť.** Končí s kódom 0, ale upozorňuje, že viacerým trasám `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` chýba anotácia `x-loopback-only: true`. Jej vynútenie si najprv vyžaduje pridanie týchto anotácií do `openapi.yaml`. +- `typecheck:noimplicit:core` (informatívne) — do značnej miery ho nahrádza blokujúca západka `check:type-coverage`. Prepnúť na západku alebo odstrániť redundantný druhý prechod `tsc`. +- `test:vitest:ui` (teraz **blokujúce**) — existujúce zlyhania sú explicitne vylúčené vo `vitest.config.ts` pomocou sledovacích komentárov `// #8618`; nové zlyhania spôsobia zlyhanie úlohy. +- `check:secrets` (gitleaks, blokujúca západka zmrazená na 3 zdokumentovaných falošne pozitívnych nálezoch) — pridať tieto 3 prípady do zoznamu povolených a dostať sa na 0 alebo degradovať na informatívnu kontrolu. Prekrýva sa s natívnym skenovaním tajomstiev v GitHube + `check:public-creds`. +- `check:pr-evidence` (blokujúce, prehľadáva prózu v tele PR pomocou grep) — vysoké riziko falošne pozitívnych nálezov; odstránenie oslabí vynucovanie pevného pravidla č. 18, takže ide o skutočné politické rozhodnutie. +- `semgrep` (samostatné informatívne) — pri rodinách OWASP sa prekrýva s CodeQL; napojiť jeho východiskovú hodnotu na západku alebo ho odstrániť. --- diff --git a/docs/i18n/sl/CONTRIBUTING.md b/docs/i18n/sl/CONTRIBUTING.md index 16b40b81e57..0055940da7f 100644 --- a/docs/i18n/sl/CONTRIBUTING.md +++ b/docs/i18n/sl/CONTRIBUTING.md @@ -404,17 +404,17 @@ Napišite teste enot v `tests/unit/`, ki zajemajo najmanj: - [ ] Testi so uspešni (`npm test`) - [ ] Preverjanje sloga kode je uspešno (`npm run lint`) - [ ] Gradnja je uspešna (`npm run build`) -- [ ] Tipi TypeScript so dodani za nove javne funkcije in vmesnike +- [ ] Za nove javne funkcije in vmesnike so dodani tipi TypeScript - [ ] Ni trdo kodiranih skrivnosti ali nadomestnih vrednosti -- [ ] Javne poverilnice izvornega ponudnika so vdelane prek `resolvePublicCred()` (glejte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikoli kot literali -- [ ] Odgovori o napakah potekajo skozi `buildErrorBody()` / `sanitizeErrorMessage()` — v telesih odgovorov ni neobdelanih skladovnih sledi (glejte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Lupinski ukazi (`exec` / `spawn`) posredujejo vrednosti izvajalnega okolja prek `env`, ne prek interpolacije nizov +- [ ] Javne poverilnice nadrejenega projekta so vdelane prek `resolvePublicCred()` (glejte [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), nikoli kot literali +- [ ] Odgovori z napakami se obdelajo prek `buildErrorBody()` / `sanitizeErrorMessage()` — brez neobdelanih sledov sklada v telesih odgovorov (glejte [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Lupinski ukazi (`exec` / `spawn`) posredujejo vrednosti med izvajanjem prek `env`, ne prek interpolacije nizov - [ ] Vsi vnosi so preverjeni s shemami Zod -- [ ] **Fragment** dnevnika sprememb je za spremembe, vidne uporabnikom, dodan v `changelog.d/{features|fixes|maintenance}/-.md` (glejte [`changelog.d/README.md`](./changelog.d/README.md)) — datoteke `CHANGELOG.md` **ne** urejajte neposredno; fragmenti se združijo ob izdaji in med zahtevami za združitev nikoli ne povzročajo sporov +- [ ] Za spremembe, vidne uporabnikom, je dodan **fragment** dnevnika sprememb v `changelog.d/{features|fixes|maintenance}/-.md` (glejte [`changelog.d/README.md`](./changelog.d/README.md)) — datoteke `CHANGELOG.md` **ne** urejajte neposredno; fragmenti se združijo ob izdaji in nikoli ne povzročajo sporov med zahtevami za združitev - [ ] Dokumentacija je posodobljena (če je ustrezno) - [ ] Ni novih opozoril CodeQL / Secret-Scanning oziroma je vsako zavrnjeno s tehnično utemeljitvijo, ki se sklicuje na ustrezen dokument v `docs/security/` -- [ ] Poti, ki ustvarjajo podrejene procese (`/api/mcp/`, `/api/cli-tools/runtime/`), so razvrščene kot `isLocalOnlyPath()` v `src/server/authz/routeGuard.ts` — glejte [Strogo pravilo št. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] V sporočilih potrditev ni zaključnih vrstic `Co-Authored-By` — potrditve morajo biti prikazane izključno pod identiteto Git lastnika repozitorija (Strogo pravilo št. 16) +- [ ] Poti, ki zaženejo podrejene procese (`/api/mcp/`, `/api/cli-tools/runtime/`), so v `src/server/authz/routeGuard.ts` razvrščene kot `isLocalOnlyPath()` — glejte [Strogo pravilo št. 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] V sporočilih potrditev ni zaključnih vrstic `Co-authored-by` za UI/bote (Strogo pravilo št. 16) — človeški sodelavci, katerih delo je ponovno uporabljeno, so navedeni s standardnimi zaključnimi vrsticami `Co-authored-by: Name ` --- diff --git a/docs/i18n/sl/docs/architecture/QUALITY_GATES.md b/docs/i18n/sl/docs/architecture/QUALITY_GATES.md index c427eaaa28c..6ab26295943 100644 --- a/docs/i18n/sl/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/sl/docs/architecture/QUALITY_GATES.md @@ -15,263 +15,263 @@ načrt ponovitve istega sistema glejte --- -## Inventar vrat in profili izvajanja +## Inventar pregrad in profili izvajanja -### Sprejem kandidata +### Sprejem kandidatov -Poteka dela CI in Quality Gates vsak objavita stabilno presojo: `Gate / CI` in -`Gate / Quality`. Njuna različicami določena politika sprejema vsako predhodno opravilo -opredeli kot obvezno ali svetovalno. Obvezno opravilo, ki se uporablja, mora uspeti: -manjkajoči, preklicani, preskočeni, čakajoči in neznani rezultati ne morejo potrditi stanja PASS. -Veljavna razvrstitev docs-only ali catalog-only lahko naredi programsko vejo neuporabljivo; +Delovna procesa CI in Quality Gates vsak ustvarita stabilno presojo: `Gate / CI` in +`Gate / Quality`. Njuna različično vodena politika sprejema določa vsako predhodno opravilo +kot obvezno ali svetovalno. Ustrezno obvezno opravilo mora uspeti: manjkajoči, +preklicani, preskočeni, čakajoči in neznani rezultati ne morejo potrditi stanja PASS. Veljavna +razvrstitev zgolj za dokumentacijo ali zgolj za katalog lahko naredi kodno vejo neustrezno; osnutek PR-ja ni sprejet kandidat. Oznaka `hotfix` ne odpravlja zahteve po dokazilih. -Oba poteka dela zajemata PR-je in potiske v glavne/izdajne veje, ročni zagon in -dogodke skupin združevanja. Potiski, ročni zagoni in skupine združevanja izvedejo celoten izbor. -Razcepi in skupine združevanja uporabljajo gostovane izvajalnike za opravila, ki bi sicer izbrala -samostojno gostovane izvajalnike; pred uvedbo je treba preveriti zadostno gostovano zmogljivost. +Oba delovna procesa pokrivata PR-je in potiske v glavne/izdajne veje, ročni zagon ter +dogodke skupin za spajanje. Potiski, ročni zagoni in skupine za spajanje izvedejo celoten izbor. Razvejitve +in skupine za spajanje uporabljajo gostovane izvajalnike za opravila, ki bi sicer izbrala lastno gostovane +izvajalnike; pred uvedbo je treba preveriti zadostno gostovano zmogljivost. -Vsako potrdilo JSON določa SHA prevzete revizije, izvajanje poteka dela in poskus. -CLI zavrne neujemanje med SHA prevzete revizije in dogodka. Preizkusi poteka dela povežejo članstvo v politiki -s seznamom `needs` opravila za presojo, tako da nova ali odstranjena veja ne more neopazno izginiti. -Potrdila zajemajo lasten potek dela, ne pa objave, uvedbe ali notranjega delovanja +Vsako potrdilo JSON določa SHA prevzete različice, izvedbo delovnega procesa in poskus. +CLI zavrne neujemanje SHA med prevzeto različico in dogodkom. Testi delovnega procesa vežejo članstvo v politiki +na seznam `needs` opravila presoje, zato nova ali odstranjena veja ne more neopazno izginiti. +Potrdila pokrivajo lasten delovni proces, ne pa objave, uvedbe ali notranjega delovanja obstoječega svetovalnega pregledovalnika. Aktiviranje obeh imen preverjanj v pravilih vej je ločena skrbniška sprememba; dodajanje teh opravil samo po sebi ne zaščiti veje. ### Inventar statičnega pregleda -Različicami določeni inventar vzdevkov npm in članstvo v statičnem pregledu sta v -`config/quality/gate-manifest.json`. Za preverjanje imen skriptov in natančnih ukazov glede na -`package.json` zaženite `npm run check:gate-manifest`; dodatki, odstranitve in -odstopanja ukazov povzročijo neuspeh tako lokalne kljuke kot opravil za razvrščanje sprememb v CI. -Vzdevek ni opravilo poteka dela, primerek matrike ali preskusni primer: teh števil -se ne sme predstavljati kot medsebojno zamenljivih. +Različično vodeni inventar vzdevkov npm in članstvo v statičnem pregledu sta v +`config/quality/gate-manifest.json`. Za preverjanje imen skriptov in natančnih ukazov +glede na `package.json` zaženite `npm run check:gate-manifest`; dodatki, odstranitve in +odstopanja ukazov povzročijo neuspeh lokalne kljuke in opravil za razvrščanje sprememb v CI. +Vzdevek ni opravilo delovnega procesa, primerek matrike ali testni primer: teh števil +ne smete predstavljati kot medsebojno zamenljivih. Za pregled izbranih vzdevkov brez njihovega izvajanja uporabite `npm run quality:scan -- --list` ali `npm run quality:scan:fast -- --list`. Izvajalnik prikliče vstopno točko npm, zato se njeno izvajalno okolje (vključno z Bun, kjer je konfiguriran) ohrani. -Manifest beleži vzdevke zunaj teh profilov kot ločeno priklicane, vzdrževalni -ukazi pa so v profilih pregledovanja samo za branje prepovedani. +Manifest beleži vzdevke zunaj teh profilov kot ločeno priklicane, ukazi za +vzdrževanje pa so v profilih pregledovanja samo za branje prepovedani. -Ti profili zajemajo samo statični pregled. Ne potrjujejo preskusov izdelka, +Ti profili pokrivajo samo statični pregled. Ne potrjujejo testov izdelka, pokritosti, pakiranja, zunanjih preverjanj ali celotnega sprejema kandidata za izdajo. -Sprejem v poteku dela uporablja povezana `config/quality/admission-policy.json` in -`scripts/quality/admission-verdict.mjs`. Profili za opazovanje izdaj ostajajo ločeni; -njihova veljavna preverjanja in potrdila preglejte neodvisno. Spodnji opisni -inventar je referenca in ne dokaz, da so bila vrata dejansko izvedena. +Sprejem delovnega procesa uporablja povezana `config/quality/admission-policy.json` in +`scripts/quality/admission-verdict.mjs`. Profili opazovalnika izdaj ostajajo ločeni; +njihova ustrezna preverjanja in potrdila preglejte neodvisno. Spodnji besedilni +inventar je referenca in ne dokaz, da se je pregrada dejansko izvedla. -Skripti so v `scripts/check/` (vrata politik) in `scripts/quality/` (mehanizem zaskočke). +Skripti so v `scripts/check/` (pregrade pravilnikov) in `scripts/quality/` (mehanizem postopnega zaostrovanja). Vir resnice za CI je `.github/workflows/ci.yml`. ### Hitra pot za PR izdaje (`quality.yml`) `.github/workflows/quality.yml` dopolnjuje CI pri PR-jih za glavne/izdajne veje, potiskih -v zaščitene veje, ročnih zagonih in skupinah združevanja. PR-ji uporabljajo hitra preverjanja, -filtrirana po poteh. Trajno onemogočena podvojena gradnja je bila odstranjena; dejanska -preverjanja gradnje/pakiranja/zagona ostajajo v CI. - -| Opravilo | Obseg | Blokiranje | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `Docs Gates (fast-path)` | PR-ji dokumentacije/programske kode; reference dokumentacije API in vsa dokumentacija | Da | -| `Fast Quality Gates` | PR-ji programske kode; statična preverjanja, preverjanje tipov, preverjanje tipov nadzorne plošče, prizadeti preizkusi enot | Da | -| `Forgotten sibling tests` | PR-ji programske kode; sledenje spremenjenim modulom do statičnih porabnikov in kandidatnih sorodnih preizkusov; poti prek zbirnih modulov in dinamičnih uvozov so navedene kot svetovalna diagnostika z navedenimi izjemami na seznamu dovoljenih | **Svetovalno** | -| `Vitest (fast-path)` | PR-ji programske kode; hitra zbirka Vitest | Da | -| `Unit Tests fast-path` | PR-ji programske kode; zbirka preizkusov enot v 4 delih | Da | -| `No new ESLint warnings` | PR-ji programske kode; varovalo za preverjanje sloga, ki upošteva opustitve opozoril | Da, vključno z razcepi | -| `Merge integrity (changelog + generated skills)` | PR-ji, ki niso osnutki; usklajevanje dnevnika sprememb in ustvarjenih veščin | Da, vključno z razcepi | - -#### Poročilo o pozabljenih sorodnih preizkusih - -`npm run check:forgotten-sibling-tests` ponovno uporabi razreševalnik uvozov, ki ga uporablja zemljevid vpliva preizkusov. +v zaščitene veje, ročnih zagonih in skupinah za spajanje. PR-ji uporabljajo hitra preverjanja, filtrirana po poteh. Trajno +onemogočena podvojena gradnja je bila odstranjena; prava preverjanja gradnje/pakiranja/zagona ostajajo v CI. + +| Opravilo | Obseg | Blokira | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `Docs Gates (fast-path)` | PR-ji dokumentacije/kode; sklici dokumentacije API in celotna dokumentacija | Da | +| `Fast Quality Gates` | PR-ji kode; statična preverjanja, preverjanje tipov, preverjanje tipov nadzorne plošče, prizadeti testi enot | Da | +| `Forgotten sibling tests` | PR-ji kode; sledenje spremenjenim modulom do statičnih porabnikov in kandidatnih sorodnih testov; poti prek zbirnih modulov in dinamičnega uvoza so sporočene kot svetovalna diagnostika z navedenimi izjemami s seznama dovoljenih | **Svetovalno** | +| `Vitest (fast-path)` | PR-ji kode; hitri paket testov vitest | Da | +| `Unit Tests fast-path` | PR-ji kode; paket testov enot s 4 delci | Da | +| `No new ESLint warnings` | PR-ji kode; zaščita lint, ki upošteva izključitve | Da, vključno z razvejitvami | +| `Merge integrity (changelog + generated skills)` | PR-ji, ki niso osnutki; usklajenost dnevnika sprememb in ustvarjenih veščin | Da, vključno z razvejitvami | + +#### Poročilo o pozabljenih sorodnih testih + +`npm run check:forgotten-sibling-tests` ponovno uporabi razreševalnik uvozov, na katerem temelji zemljevid vpliva testov. Za vsak spremenjeni produkcijski modul poroča o determinističnih verigah -`spremenjeni modul/simbol -> statični porabnik -> kandidatni sorodni preizkus`, kadar kandidatni -preizkus ni prisoten v razliki zahtevka za poteg. Povzetek Markdown in rezultat JSON se ohranita kot -artefakt poteka dela `forgotten-sibling-tests` za umerjanje pred morebitno uvedbo blokiranja. +`spremenjeni modul/simbol -> statični porabnik -> kandidatni sorodni test`, kadar kandidatni +test manjka v spremembah zahtevka za vlečenje. Povzetek Markdown in rezultat JSON se ohranita kot +artefakt delovnega procesa `forgotten-sibling-tests` za umerjanje pred morebitno uvedbo blokiranja. Ponovni izvozi prek zbirnih modulov in dinamični uvozi so namenjeni samo diagnostiki razreševanja; nikoli ne ustvarijo -blokirajoče ugotovitve. Pregledane izjeme so shranjene v -`config/quality/forgotten-sibling-allowlist.json`. Vsak vnos mora navesti potrošnika in kandidatni -test, podati konkretno utemeljitev ter vsebovati povezavo do težave ali zahteve za vključitev sprememb na GitHubu. Nepravilno oblikovani vnosi -se privzeto zavrnejo. Izjeme ne morejo prikriti izbrisanega kandidatnega testa ali spremembe, ki doda `.skip`/`.todo`; -slabljenje trditev in drugo prikrivanje ostajata v pristojnosti neodvisno blokirajočega -preverjanja `check:test-masking`. +blokirajoče ugotovitve. Pregledane izjeme so v datoteki +`config/quality/forgotten-sibling-allowlist.json`. Vsak vnos mora navesti uporabnika in kandidatni +test, podati konkretno utemeljitev ter vsebovati povezavo do GitHub težave ali zahteve za vključitev sprememb. Nepravilno oblikovani vnosi se +privzeto zavrnejo. Izjeme ne morejo prezreti izbrisanega kandidatnega testa ali spremembe, ki doda `.skip`/`.todo`; +oslabitev trditev in druga prikrivanja še naprej obravnava neodvisno blokirajoče +preverjanje `check:test-masking`. ### Opravilo: `lint` Izvede se ob vsaki zahtevi za vključitev sprememb v `main`. Ob neuspehu blokira združitev. -| Skript (`npm run ...`) | Preverja | Blokira | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Različica Node.js je znotraj podprtega razpona | Da | -| `check:cycles` | Krožne uvoze — vse module v `src/` + `open-sse/` | Da | -| `check:route-validation:t06` | Prisotnost shem Zod na vseh poteh (pravilnik 6. ravni) | Da | -| `check:any-budget:t11` | Število `@ts-expect-error // any` ne presega omejitve (zapornica 11. ravni) | Da | -| `check:provider-consistency` | Vsak ponudnik v `providers.ts` ima ustrezen vnos v `providerRegistry.ts` (in obratno, znotraj seznama dovoljenih) | Da | -| `check:model-lifecycle` | Tri ročno vzdrževane usmerjevalne tabele ostajajo skladne z vključeno sliko življenjskega cikla (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ne ovrednoti nobenega opuščenega identifikatorja, ki ga lahko usmerja `REGISTRY`; vsak cilj `BUILT_IN_ALIASES` je prisoten v `REGISTRY` in odsoten iz slike opuščenih identifikatorjev; vsak opuščeni identifikator, ki je še vedno v `REGISTRY`, je preusmerjen ali naveden v `allowedRetiredInCatalog`; noben vir ali cilj `DEFAULT_DEGRADATION_MAP` pa v tej sliki ni označen kot opuščen. To ne dokazuje, da model trenutno zagotavlja delujoči nadrejeni ponudnik. Brez povezave — primerja z `config/quality/model-lifecycle.json`, ki se ročno osveži z `npm run quality:refresh-model-lifecycle` (zahteva omrežje; ni vključeno v CI). `allowedRetiredInCatalog` je postopoma poostrujoč omejevalni mehanizem: vnos dodajte le skupaj z nalogo za sledenje. | Da | -| `check:fetch-targets` | Vsak `fetch("/api/...")` v odjemalskem delu `src/` se razreši v dejanski `route.ts` | Da | -| `check:deps` | Vse odvisnosti, ki jih je mogoče namestiti z `npm install`, iz vseh datotek `package.json` v repozitoriju so navedene v `dependency-allowlist.json`; novi nepripeti paketi ali paketi z imeni, podobnimi drugim paketom, so označeni | Da | -| `audit:deps` | `npm audit` (korenski projekt + Electron) — brez opozoril visoke/kritične stopnje (prekriva se z OSV `check:vuln-ratchet`; glejte seznam za racionalizacijo) | Da | -| `check:lockfile` | Celovitost datoteke `package-lock.json` — register HTTPS, zgoščene vrednosti celovitosti, brez preglasitev gostitelja | Da | -| `check:licenses` | Seznam dovoljenih licenc SPDX za produkcijske odvisnosti | Da | -| `check:tracked-artifacts` | Brez gradbenih artefaktov / potrjenih simbolnih povezav `node_modules` (izvede se tudi v husky pre-commit; pre-push je namenoma lahek — #6716) | Da | -| `check:ai-attribution` | Brez zaključne vrstice AI/bota `Co-Authored-By` ali noge o ustvarjanju z AI v potrditvah, naslovu ali telesu PR-ja — Strogo pravilo št. 16 (v zanki hitrih preverjanj `quality.yml` za PR→`release/**` — bere vsebino dogodka, zunaj PR-jev pa ne izvede ničesar — in korak samo za PR-je v preverjanju lint datoteke `ci.yml` za PR→`main`; tudi kavelj husky `commit-msg`; človeški soavtorji so dovoljeni; #14436) | -| `check:vitest-exclusions` | Vsaka izključitev Vitest navaja sledilno težavo in je navedena v `config/quality/vitest-exclusions.json` (#13204) | Da | -| `check:file-size` | Nobena datoteka z izvorno kodo ne presega omejitve za posamezno končnico (zaskočni mehanizem: velike datoteke, zamrznjene na seznamu `frozen`) | Da | -| `check:error-helper` | Odgovori o napakah v izvajalnikih/obdelovalnikih uporabljajo `buildErrorBody()` / `sanitizeErrorMessage()` (Strogo pravilo št. 12) | Da | -| `check:migration-numbering` | Datoteke SQL za migracije so zaporedno oštevilčene, brez vrzeli ali podvojenih številk | Da | -| `check:public-creds` | Zunaj datoteke `publicCreds.ts` ni dobesedno zapisanih vrednosti OAuth `client_id`/`client_secret` ali spletnih ključev Firebase (strogo pravilo št. 11) | Da | -| `check:db-rules` | Zunaj modulov `src/lib/db/` ni neobdelanih poizvedb SQL; iz `localDb.ts` ni skupinskih uvozov (strogi pravili št. 2/št. 5) | Da | -| `check:known-symbols` | Izvajalniki ponudnikov, strategije usmerjanja in prevajalniki, registrirani v svojih tabelah razpošiljanja, se ujemajo z datotekami na disku — brez osirotelih ali nedeklariranih simbolov | Da | -| `check:route-guard-membership` | Vsaka pot, ki ustvari podrejeni proces, je razvrščena s funkcijo `isLocalOnlyPath()` (strogi pravili št. 15/št. 17) | Da | -| `check:test-discovery` | Vsako datoteko `*.test.ts` / `*.spec.ts` v repozitoriju zbere vsaj en izvajalnik testov (raglja: seznam osirotelih datotek v `test-discovery-baseline.json` se lahko samo krči) | Da | -| `check:agent-skills-sync` | Ustvarjeni artefakti agent-skills se ujemajo z izvornim katalogom (brez odstopanj) | -| `check:provider-asset-provenance` | Logotipi/sredstva ponudnikov imajo zabeležen vnos o izvoru | -| `lint:json` | Konfiguracijske datoteke JSON se pravilno razčlenijo in izpolnjujejo pravila preverjanja repozitorija | -| `typecheck:core` | Prevajanje TypeScript brez napak (samo svetovalna opozorila) | Da | -| `typecheck:noimplicit:core` | Strogi `noImplicitAny` — usmerjeno v prihodnost; številna obstoječa mesta klicev še vedno potrebujejo anotacije | **Svetovalno** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, omejen na `src/app/(dashboard)/**` (#7033) — skrbno izbran seznam 27 dovoljenih datotek v `typecheck:core` ne vključuje nobene datoteke TSX nadzorne plošče, prav tako pa jih `next build` nikoli ne preverja glede tipov (`next.config.mjs` nastavi `ignoreBuildErrors: true`), zato so bile regresije osirotelih identifikatorjev na tem mestu (#6625/#6909) za CI nevidne. Razlike se primerjajo z zamrznjeno osnovo števila napak za posamezno datoteko/kodo TS (`config/quality/dashboard-typecheck-baseline.json`, enak vzorec uveljavljanja zastarelosti kot pri `check:known-symbols`) — preverjanje spodleti samo zaradi NOVIH napak, ki presegajo osnovno število; ko je obstoječa napaka odpravljena, osnovo zmanjšajte z `--update`. | Da | +| Skript (`npm run ...`) | Preverja | Blokirajoče | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | Različica Node.js je znotraj podprtega razpona | Da | +| `check:cycles` | Krožne uvoze v celotnih `src/` + `open-sse/` (na podlagi AST, z razrešenimi `paths` iz tsconfig). Samostojni ukaz je svetovalen in izpiše cikle. `check:cycles:ratchet` (ki ga izvaja CI) blokira, kadar število preseže zgornjo mejo `metrics.cycles` v `quality-baseline.json` — trenutno 14, `direction: down`, zato se lahko le znižuje (#15159 G-01/G-02) | Da (raglja) | +| `check:route-validation:t06` | Prisotnost shem Zod na vseh poteh (pravilnik 6. ravni) | Da | +| `check:any-budget:t11` | Število `@ts-expect-error // any` ne presega proračuna (raglja 11. ravni) | Da | +| `check:provider-consistency` | Vsak ponudnik v `providers.ts` ima ustrezen vnos v `providerRegistry.ts` (in obratno, znotraj seznama dovoljenih) | Da | +| `check:model-lifecycle` | Tri ročno vzdrževane usmerjevalne tabele ostajajo skladne z vključeno kopijo stanj življenjskega cikla (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ne ocenjuje nobenega opuščenega ID-ja, ki ga lahko usmerja `REGISTRY`; vsak cilj `BUILT_IN_ALIASES` je prisoten v `REGISTRY` in odsoten iz kopije opuščenih ID-jev; vsak opuščeni ID, ki je še vedno v `REGISTRY`, je preusmerjen ali naveden v `allowedRetiredInCatalog`; noben vir ali cilj `DEFAULT_DEGRADATION_MAP` pa v tej kopiji ni označen kot opuščen. To ne dokazuje, da model trenutno zagotavlja dejavni zunanji ponudnik. Brez povezave — primerja z `config/quality/model-lifecycle.json`, ki se ročno osveži z `npm run quality:refresh-model-lifecycle` (zahteva omrežje; ni vključeno v CI). `allowedRetiredInCatalog` je enosmerni seznam za postopno odpravo: vnos dodajte le skupaj z zadevo za sledenje. | Da | +| `check:fetch-targets` | Vsak `fetch("/api/...")` v odjemalskem delu `src/` se razreši v dejanski `route.ts` | Da | +| `check:deps` | Vse odvisnosti, ki jih je mogoče namestiti z `npm install`, v vseh datotekah `package.json` v repozitoriju so navedene v `dependency-allowlist.json`; novi nepripeti paketi ali paketi z imeni, podobnimi obstoječim, so označeni | Da | +| `audit:deps` | `npm audit` (korenski projekt + Electron) — brez opozoril visoke/kritične stopnje (prekriva se s preverjanjem OSV `check:vuln-ratchet`; glejte seznam za poznejšo racionalizacijo) | Da | +| `check:lockfile` | Celovitost datoteke `package-lock.json` — register HTTPS, zgoščene vrednosti celovitosti, brez preglasitev gostitelja | Da | +| `check:licenses` | Seznam dovoljenih licenc SPDX za produkcijske odvisnosti | Da | +| `check:tracked-artifacts` | Brez artefaktov gradnje / potrjenih simbolnih povezav `node_modules` (izvede se tudi v husky pre-commit; pre-push je namenoma minimalen — #6716) | Da | +| `check:ai-attribution` | Brez zaključne vrstice `Co-Authored-By` za UI/bote ali noge o ustvarjanju z UI v potrditvah, naslovu ali telesu zahtevka PR — strogo pravilo št. 16 (v zanki hitrih preverjanj `quality.yml` za PR→`release/**` — prebere koristno vsebino dogodka, zunaj zahtevkov PR pa ne izvede ničesar — in korak samo za PR v preverjanju lint datoteke `ci.yml` za PR→`main`; prav tako kavelj husky `commit-msg`; človeški soavtorji so dovoljeni; #14436) | +| `check:vitest-exclusions` | Vsaka izključitev Vitest navaja sledljivo težavo in je navedena v `config/quality/vitest-exclusions.json` (#13204) | Da | +| `check:file-size` | Nobena izvorna datoteka ne presega omejitve za svojo končnico (zaskočni mehanizem: velike datoteke, zamrznjene na seznamu `frozen`) | Da | +| `check:error-helper` | Odgovori o napakah v izvajalnikih/obdelovalnikih uporabljajo `buildErrorBody()` / `sanitizeErrorMessage()` (strogo pravilo št. 12) | Da | +| `check:migration-numbering` | Datoteke SQL za migracije so oštevilčene zaporedno, brez vrzeli ali podvojenih številk | Da | +| `check:public-creds` | Brez dobesednih poverilnic OAuth `client_id`/`client_secret` ali spletnih ključev Firebase zunaj `publicCreds.ts` (strogo pravilo št. 11) | Da | +| `check:db-rules` | Brez neposrednega SQL-a zunaj modulov `src/lib/db/`; brez zbirnih uvozov iz `localDb.ts` (strogi pravili št. 2/št. 5) | Da | +| `check:known-symbols` | Izvajalniki ponudnikov, strategije usmerjanja in prevajalniki, registrirani v svojih razpošiljevalnih tabelah, se ujemajo z datotekami na disku — brez osirotelih ali nedeklariranih simbolov | Da | +| `check:route-guard-membership` | Vsaka pot, ki ustvari podrejeni proces, je razvrščena s funkcijo `isLocalOnlyPath()` (strogi pravili št. 15/št. 17) | Da | +| `check:test-discovery` | Vsako datoteko `*.test.ts` / `*.spec.ts` v repozitoriju zazna vsaj en izvajalnik testov (zapora: seznam osirotelih datotek v `test-discovery-baseline.json` se lahko le krajša) | Da | +| `check:agent-skills-sync` | Ustvarjeni artefakti agent-skills se ujemajo z izvornim katalogom (brez odstopanj) | +| `check:provider-asset-provenance` | Logotipi/sredstva ponudnikov imajo zabeležen vnos o izvoru | +| `lint:json` | Konfiguracijske datoteke JSON je mogoče razčleniti in izpolnjujejo pravila preverjanja repozitorija | +| `typecheck:core` | Prevajanje TypeScript brez napak (samo svetovalna opozorila) | Da | +| `typecheck:noimplicit:core` | Strogi `noImplicitAny` — usmerjeno v prihodnost; številna obstoječa mesta klicev še vedno potrebujejo anotacije | **Svetovalno** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, omejen na `src/app/(dashboard)/**` (#7033) — skrbno izbran seznam 27 datotek v `typecheck:core` ne vključuje nobene datoteke TSX nadzorne plošče, prav tako pa jih `next build` nikoli ne preverja glede tipov (`next.config.mjs` nastavi `ignoreBuildErrors: true`), zato so bile regresije osirotelih identifikatorjev na tem mestu (#6625/#6909) za CI nevidne. Razlike se primerjajo z zamrznjenim izhodiščem števila napak po datoteki in kodi TS (`config/quality/dashboard-typecheck-baseline.json`, enak vzorec uveljavljanja zastarelosti kot pri `check:known-symbols`) — vrata padejo samo zaradi NOVIH napak, ki presegajo izhodiščno število; ko je obstoječa napaka odpravljena, izhodišče znižajte z `--update`. | Da | ### Opravilo: `quality-gate` Zažene se po `test-coverage`. Ob neuspehu blokira združitev. -| Skript | Preverja | Blokira | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `quality:collect` | Ustvari `quality-metrics.json` (število opozoril ESLint, pokritost iz združenega poročila razdeljenih opravil) | Da (predhodni korak za ratchet) | -| `quality:ratchet` | Nobena metrika v `quality-baseline.json` se ni poslabšala (opozorila ESLint ≤ izhodiščna vrednost; pokritost ≥ izhodiščna vrednost) | Da | -| `check:duplication` | Podvajanje kode (jscpd@4) ne presega izhodiščne vrednosti v `quality-baseline.json` | Da | -| `check:complexity` | Ciklomatska kompleksnost na ravni datoteke ne presega zgornje meje (osnovni pravili ESLint `complexity` + `max-lines-per-function`) | Da | -| `check:cognitive-complexity` | Postopno omejevanje kognitivne kompleksnosti (`eslint-plugin-sonarjs`) — ločen prehod ESLint; CI oba združi v en korak `check:complexity-ratchets` | Da | -| `check:dead-code` | Postopno omejevanje neuporabljenih izvozov/datotek (knip) se glede na izhodiščno vrednost ne poslabša | Da | -| `check:compression-budget` | Proračun primerjalnega preizkusa stiskanja — najnižje dovoljene vrednosti prihranka žetonov za posamezen pogon se ne smejo poslabšati | Da | -| `check:type-coverage` | Postopno omejevanje odstotka tipizirane kode (`type-coverage`) se ne poslabša; večinoma nadomešča `typecheck:noimplicit:core` | Da | -| `check:codeql-ratchet` | Število odprtih opozoril CodeQL se ne poslabša (bere prek `gh api`; brez žetona se preskoči brez napake) — pogostost osveževanja in ročni sprožilec: glejte »Postopno omejevanje CodeQL« spodaj | Da | +| Skript | Preverja | Blokira | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | Ustvari `quality-metrics.json` (število opozoril ESLint, pokritost iz združenega poročila delov) | Da (predpogoj za zaskok) | +| `quality:ratchet` | Nobena metrika v `quality-baseline.json` se ni poslabšala (opozorila ESLint ≤ izhodiščna vrednost; pokritost ≥ izhodiščna vrednost) | Da | +| `check:duplication` | Podvajanje kode (jscpd@4) ne presega izhodiščne vrednosti v `quality-baseline.json` | Da | +| `check:complexity` | Ciklomatična kompleksnost na ravni datoteke ne presega omejitve (osnovni pravili ESLint `complexity` + `max-lines-per-function`) | Da | +| `check:cognitive-complexity` | Zaskok kognitivne kompleksnosti (`eslint-plugin-sonarjs`) — ločen prehod ESLint; CI oba združi v en korak `check:complexity-ratchets` | Da | +| `check:dead-code` | Zaskok neuporabljenih izvozov/datotek (knip) se glede na izhodiščno vrednost ne poslabša | Da | +| `check:compression-budget` | Proračun primerjalnega preizkusa stiskanja — najnižje dovoljene vrednosti prihranka žetonov za posamezen pogon se ne smejo poslabšati | Da | +| `check:type-coverage` | Zaskok odstotka tipizirane kode (`type-coverage`) se ne poslabša; večinoma nadomešča `typecheck:noimplicit:core` | Da | +| `check:codeql-ratchet` | Število odprtih opozoril CodeQL se ne poveča (bere prek `gh api`; brez žetona preverjanje varno preskoči) — pogostost osveževanja in ročni sprožilec: glejte »Zaskok CodeQL« spodaj | Da | ### Opravilo: `quality-extended` -Celotno opravilo je svetovalne narave (`continue-on-error: true`). Postopna omejevanja, ki temeljijo na npm, se dejansko izvedejo; zunanji pregledovalniki se namestijo prek `gh release download` in se sami preskočijo (izhodna koda 0), če binarna datoteka še vedno ni na voljo. +Celotno opravilo je svetovalne narave (`continue-on-error: true`). Zaskoki, ki temeljijo na npm, se +dejansko izvedejo; zunanji pregledovalniki se namestijo prek `gh release download` in se sami preskočijo (izhodna koda 0), +če binarna datoteka še vedno ni na voljo. -| Skript | Preverja | Blokira | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------- | -| `check:circular-deps` | Ni krožnih odvisnosti (dpdm) | **Svetovalno** | -| `check:bundle-size` | Velikost paketa ne presega zgornje meje | **Svetovalno** | -| `check:secrets` | Iskanje skrivnosti (gitleaks) — preskoči se, če binarna datoteka ni na voljo | **Svetovalno** | -| `check:vuln-ratchet` | Ranljivosti odvisnosti (osv-scanner) se ne poslabšajo — preskoči se, če binarna datoteka ni na voljo | **Svetovalno** | -| `check:workflows` | Preverjanje delovnih tokov (actionlint + zizmor); manjkajoči ali okvarjeni pregledovalniki, neveljavna poročila ali manjkajoča izhodiščna vrednost za postopno omejevanje povzročijo stanje INCOMPLETE. Veljavne ugotovitve upoštevajo izbrani strogi/svetovalni/pravilnik postopnega omejevanja | Izvedba je obvezna; postopno omejevanje zizmor blokira v CI | -| `check:openapi-breaking` | Prelomne spremembe pogodbe javnega API-ja (`openapi.yaml`) glede na osnovno vejo (oasdiff) — ustvari `openapiBreaking=N`; preskoči se, če oasdiff ni na voljo ali osnovne specifikacije ni mogoče razrešiti | **Svetovalno** | +| Skript | Preverja | Blokira | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:circular-deps` | Ni krožnih odvisnosti (dpdm) | **Svetovalno** | +| `check:bundle-size` | Velikost svežnja ne presega omejitve | **Svetovalno** | +| `check:secrets` | Pregled skrivnosti (gitleaks) — preskoči, če binarna datoteka ni na voljo | **Svetovalno** | +| `check:vuln-ratchet` | Ranljivosti odvisnosti (osv-scanner) se ne povečajo — preskoči, če binarna datoteka ni na voljo | **Svetovalno** | +| `check:workflows` | Preverjanje delovnih tokov (actionlint + zizmor); manjkajoči/okvarjeni pregledovalniki, neveljavna poročila ali manjkajoča izhodiščna vrednost zaskoka povzročijo stanje INCOMPLETE. Veljavne ugotovitve sledijo izbranemu strogemu/svetovalnemu pravilniku oziroma pravilniku zaskoka | Izvedba je obvezna; zaskok zizmor blokira v CI | +| `check:openapi-breaking` | Prelomne spremembe pogodbe javnega API-ja (`openapi.yaml`) glede na osnovno vejo (oasdiff) — ustvari `openapiBreaking=N`; preskoči, če oasdiff ni na voljo ali osnovne specifikacije ni mogoče razrešiti | **Svetovalno** | ### Opravilo: `docs-sync-strict` -Izvede se pri vsakem PR-ju v `main`. Ob neuspehu blokira združitev. +Izvede se ob vsakem PR-ju v `main`. Ob neuspehu blokira združitev. | Skript | Preverja | Blokirajoče | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| `check:docs-all` | Metaprehod, ki zaporedno izvede spodnjih 6 podprehodov | Da | -| ↳ `check:docs-sync` | Skladnost različic v CHANGELOG / OpenAPI / llm.txt | Da | -| ↳ `check:docs-counts` | Števila v besedilu (število ponudnikov, število migracij itd.) so znotraj drsečega dovoljenega obsega glede na dejanska števila | Da | +| `check:docs-all` | Metaprehod, ki zaporedoma izvede spodnjih 6 podprehodov | Da | +| ↳ `check:docs-sync` | Skladnost različic med CHANGELOG / OpenAPI / llm.txt | Da | +| ↳ `check:docs-counts` | Števila v besedilu (število ponudnikov, število migracij itd.) so znotraj zaostrenega razpona dejanskih vrednosti | Da | | ↳ `check:env-doc-sync` | Vsaka okoljska spremenljivka v `.env.example` je dokumentirana v tabeli dokumentacije in obratno | Da | -| ↳ `check:deprecated-versions` | V dokumentaciji ni nizov z opuščenimi različicami | Da | -| ↳ `check:doc-links` | Notranje markdown povezave v dokumentaciji kažejo na dejanske datoteke (oblika `[besedilo]`/`(path)`) | Da | -| ↳ `check:fabricated-docs` | Poti, okoljske spremenljivke, ukazi CLI, imena kavljev in poti datotek, navedeni v dokumentaciji, obstajajo v kodni zbirki. Strogi prehod z `--strict`; brez zastavice le nezavezujoča napaka. | Da (prek `--strict` v CI) | +| ↳ `check:deprecated-versions` | V dokumentaciji ni nizov z zastarelimi različicami | Da | +| ↳ `check:doc-links` | Notranje povezave markdown v dokumentaciji kažejo na obstoječe datoteke (oblika `[besedilo]`/`(path)`) | Da | +| ↳ `check:fabricated-docs` | Poti, okoljske spremenljivke, ukazi CLI, imena kavljev in poti datotek, navedeni v dokumentaciji, obstajajo v kodni bazi. Strogi prehod prek `--strict`; brez zastavice neuspeh ni blokirajoč. | Da (prek `--strict` v CI) | | `check:cli-i18n` | Nizi ukazov CLI so prisotni v vseh področnih datotekah i18n | Da | -| `check:openapi-coverage` | Specifikacija OpenAPI pokriva vsaj postopoma zviševani spodnji prag dejanskih poti | Da | +| `check:openapi-coverage` | Specifikacija OpenAPI pokriva vsaj zaostreno spodnjo mejo dejanskih poti | Da | | `check:openapi-security-tiers` | Oznake varnostnih ravni v `openapi.yaml` so skladne s klasifikacijami v `routeGuard.ts` | **Svetovalno** | -| `check:openapi-routes` | Vsaka pot v `openapi.yaml` kaže na dejanski `route.ts` (preprečevanje halucinacij) | Da | -| `check:docs-symbols` | Vsak sklic `/api/...` v `docs/**/*.md` kaže na dejanski `route.ts` (preprečevanje halucinacij) | Da | +| `check:openapi-routes` | Vsaka pot v `openapi.yaml` se razreši v dejanski `route.ts` (preprečevanje halucinacij) | Da | +| `check:docs-symbols` | Vsak sklic `/api/...` v `docs/**/*.md` se razreši v dejanski `route.ts` (preprečevanje halucinacij) | Da | | `i18n translation drift` | Neprevedeni ključi v področnih datotekah i18n — samo opozorilo | **Svetovalno** | ### Opravilo: `i18n-ui-coverage` -| Skript | Preverja | Blokirajoče | -| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (vgrajeno) | Pokritost ključev i18n uporabniškega vmesnika je ≥ 65 % | Da | -| `check-ui-value-drift` (vgrajeno) | Spremenjena angleška **vrednost** ne pušča zastarelega prevoda | Da | -| `check-new-key-coverage` (vgrajeno) | **Nov** angleški ključ je preveden v vsakem področnem jeziku — oznaka `__MISSING__:` je zavrnjena | Da | -| `check-translation-ratio` | Delež dejanskih prevodov po področnem jeziku (listi zunaj dovoljenega seznama, ki so enaki angleščini, nadomestni ali manjkajoči) ne sme preseči `config/quality/i18n-translation-baseline.json` + rezerve | **Svetovalno** | +| Skript | Preverja | Blokirajoče | +| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (vgrajeno) | Pokritost ključev i18n uporabniškega vmesnika je ≥ 65 % | Da | +| `check-ui-value-drift` (vgrajeno) | Po spremembi angleške **vrednosti** ne ostane noben zastarel prevod | Da | +| `check-new-key-coverage` (vgrajeno) | **Nov** angleški ključ je preveden v vseh področnih nastavitvah — oznaka `__MISSING__:` je zavrnjena | Da | +| `check-translation-ratio` | Delež dejanskih prevodov po področnih nastavitvah (listi, ki so enaki angleškim / nadomestni / manjkajoči in niso na seznamu dovoljenih) ne sme preseči `config/quality/i18n-translation-baseline.json` + rezerve | **Svetovalno** | -Zahteva `fetch-depth: 0` — prehod za odkrivanje odklona vrednosti primerja spremembe v `en.json` glede na osnovo združitve. +Zahteva `fetch-depth: 0` — prehod za odkrivanje odstopanj vrednosti primerja `en.json` z osnovo združitve. #### `check-ui-value-drift` — prehod za zastarele prevode -Zazna edino regresijo i18n, ki je drugi prehodi strukturno ne morejo opaziti: angleška vrednost -je spremenjena, prevodi, izpeljani iz _prejšnje_ angleške različice, pa ostanejo, zato +Zazna tisto regresijo i18n, ki je drugi prehodi strukturno ne morejo zaznati: angleška vrednost +je spremenjena, prevodi, izpeljani iz _prejšnje_ angleške vrednosti, pa ostanejo, zato neangleško govoreči uporabniki še naprej berejo samozavestno zapisano, vendar zdaj napačno besedilo. -To se je dejansko znašlo v izdaji. `oauthModal.googleOAuthWarning` je bil spremenjen ob uvedbi -pomočnika za prijavo Antigravity (#5203); **39 od 43 področnih jezikov** je ohranilo besedilo, ki je skrbnikom naročalo, naj »kopirajo -celoten URL in ga prilepijo spodaj« — postopek, ki ga pri tem ponudniku ni mogoče dokončati. To je -ostalo neopaženo do #8463, ker: +To se je dejansko znašlo v izdani različici. `oauthModal.googleOAuthWarning` je bil spremenjen ob uvedbi +pomočnika za prijavo Antigravity (#5203); **39 od 43 področnih nastavitev** je ohranilo besedilo, ki je skrbnikom +naročalo, naj »kopirajo celoten URL in ga prilepijo spodaj« — postopka, ki ga pri tem ponudniku ni mogoče +dokončati. To je ostalo neopaženo do #8463, ker: -- `sync-ui-keys` dopolni samo ključe, ki **manjkajo**, nikoli tistih, ki so **zastareli**; +- `sync-ui-keys` zapolni samo ključe, ki so **odsotni**, nikoli pa tistih, ki so **zastareli**; - `check-ui-keys-coverage` šteje _prisotnost_ ključev, zato se zastarel prevod šteje kot pokrit; - `check-translation-drift` spremlja zrcalne kopije dokumentacije `docs/i18n//**.md` — - nikoli ne bere `src/i18n/messages/*.json`. Blokirajoče v opravilu `docs-sync-strict` od - ponovne sinhronizacije 2026-09: uredite osrednji dokument → `npm run i18n:run -- --files=` (na ravni razdelka, hitro). + datotek `src/i18n/messages/*.json` nikoli ne bere. Od ponovne sinhronizacije 2026-09 je blokirajoč v opravilu `docs-sync-strict`: uredite osrednji dokument → `npm run i18n:run -- --files=` (na ravni razdelka, cenovno ugodno). -**Upošteva razlike in ne temelji na izhodišču.** Primerja `en.json` v skupnem predniku združitve z +**Upošteva razlike in se ne opira na referenčno osnovo.** Primerja `en.json` v združitveni osnovi z delovnim drevesom; za vsak ključ, katerega angleška vrednost se je spremenila, je vsak jezik, ki še vedno vsebuje -nespremenjen prevod, zastarel. To namenoma **zamrzne obstoječi dolg** — iz razlike -ni mogoče ugotoviti, iz katere stare angleške vrednosti izvira dolgo obstoječi prevod, zato preverjanje presoja -samo to, česar se dotika trenutna sprememba. Alternativa (izhodišče z zgoščeno vrednostjo za vsak ključ) bi zahtevala -približno 600 KB veliko ustvarjeno datoteko, 3-krat večjo od največjega obstoječega izhodišča, ki bi se spreminjala ob vsakem i18n PR-ju. +nespremenjen prevod, zastarel. To namenoma **zamrzne že obstoječi dolg** — iz razlike +ni mogoče ugotoviti, iz katere stare angleške vrednosti izvira dolgo obstoječi prevod, zato kontrola presoja +samo to, česar se dotika trenutna sprememba. Alternativa (referenčna osnova z zgoščeno vrednostjo za vsak ključ) bi zahtevala +približno 600 KB veliko ustvarjeno datoteko, 3× večjo od največje obstoječe referenčne osnove, ki bi se spreminjala ob vsakem i18n PR-ju. -Preverjanje je mogoče zadovoljiti na dva načina: +Kontrolo je mogoče zadovoljiti na dva načina: 1. posodobite zadevne prevode ali -2. jih nastavite na `__MISSING__:` — izvajalno okolje nato uporabi popravljeno angleško vrednost +2. jih nastavite na `__MISSING__:` — izvajalno okolje nato uporabi popravljeno angleško besedilo (`src/i18n/request.ts::deepMergeFallback`, #7258), ključ pa se uvrsti v čakalno vrsto za prevod. Če se je spremenil **pomen** niza, raje **preimenujte ključ**: novi ključ ne more podedovati zastarelega prevoda. Ta vzorec je bil uporabljen v #8463. ```bash -npm run i18n:check-value-drift # strogo (kar izvaja CI) -npm run i18n:check-value-drift:warn # samo poročanje +npm run i18n:check-value-drift # strogo (kot se izvaja v CI-ju) +npm run i18n:check-value-drift:warn # samo poročilo BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` Konča se s kodo 0 in sporočilom `SKIP reason=base-unresolved`, kadar osnovnega kataloga ni mogoče prebrati (plitko -kloniranje brez osnovnega sklica), podobno kot `check-openapi-breaking`. +kloniranje brez osnovnega sklica), kar je skladno z `check-openapi-breaking`. ### Opravilo: `i18n` -Celotna matrika preverjanja i18n (eno opravilo na jezik). Celotno opravilo je svetovalno. +Celotna matrika preverjanja i18n (eno opravilo na jezik). Celotno opravilo je svetovalne narave. -| Skript | Preverja | Blokiranje | -| ------------------------------- | ------------------------------------ | -------------------------------------------------------------- | -| `validate_translation.py quick` | Popolnost prevoda za posamezni jezik | **Svetovalno** (`continue-on-error: true` za celotno opravilo) | +| Skript | Preverja | Blokiranje | +| ------------------------------- | -------------------------------- | -------------------------------------------------------------- | +| `validate_translation.py quick` | Popolnost prevodov za vsak jezik | **Svetovalno** (`continue-on-error: true` za celotno opravilo) | ### Opravilo: `pr-test-policy` -Izvaja se samo pri zahtevah za vključitev sprememb. +Izvede se samo pri zahtevah za vključitev sprememb. | Skript | Preverja | Blokiranje | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PR-ji, ki spreminjajo produkcijsko kodo v `src/`, `open-sse/`, `electron/` ali `bin/`, morajo vključevati ali posodobiti teste (strogo pravilo št. 8) | Da | -| `check:test-masking` | Spremenjene testne datoteke ne zmanjšajo skupnega neto števila preverjanj in ne dodajajo tavtologij `assert.ok(true)` | Da | -| `check:pr-evidence` | Telo PR-ja navaja dokazila o testiranju/VPS za spremembo (avtomatizira strogo pravilo št. 18 z iskanjem po besedilu PR-ja — krhko, glejte seznam odprtih nalog) | Da | +| `check:pr-test-policy` | PR-ji, ki spreminjajo produkcijsko kodo v `src/`, `open-sse/`, `electron/` ali `bin/`, morajo vključiti ali posodobiti teste (strogo pravilo št. 8) | Da | +| `check:test-masking` | Spremenjene testne datoteke ne zmanjšajo neto števila preverjanj in ne dodajajo tavtologij `assert.ok(true)` | Da | +| `check:pr-evidence` | Telo PR-ja navaja dokaze o testiranju/VPS-u za spremembo (avtomatizira strogo pravilo št. 18 z iskanjem po besedilu PR-ja — krhko, glejte seznam odprtih nalog) | Da | ### Opravilo: `test-vitest` Izvede se po `build`. Ob neuspehu blokira združitev. -| Zbirka | Preverja | Blokiranje | -| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -| `test:vitest` | Strežnik MCP (110 orodij), autoCombo, predpomnilnik — izvajalnik vitest | Da | -| `test:vitest:ui` | Testi komponent uporabniškega vmesnika — izvajalnik vitest | **Blokira** — obstoječe napake so izrecno izključene v `vitest.config.ts`; nove napake povzročijo neuspeh opravila | +| Zbirka | Preverja | Blokiranje | +| ---------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Strežnik MCP (110 orodij), autoCombo, predpomnilnik — izvajalnik vitest | Da | +| `test:vitest:ui` | Testi komponent uporabniškega vmesnika — izvajalnik vitest | **Blokira** — že obstoječe napake so izrecno izključene v `vitest.config.ts`; nove napake povzročijo neuspeh opravila | ### Nočni delovni tokovi (načrtovani, svetovalni) -Izvajajo se po urniku cron (in prek `workflow_dispatch`), nikoli pri PR-jih. Vsi so svetovalni. +Izvajajo se po urniku cron (in prek `workflow_dispatch`), nikoli pri PR-jih. Vsi so svetovalne narave. -| Delovni tok | Preverja | Blokiranje | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | Lastnostni testi fast-check z naključnim semenom in velikim številom izvedb | **Svetovalno** | -| `nightly-resilience` | prag rasti kopice, vbrizgavanje napak za testiranje kaosa, obremenitveni/dolgotrajni testi k6 | **Svetovalno** | -| `nightly-llm-security` | zaščita pred vbrizgavanjem promptfoo (način blokiranja) in sonde garak (preskočene brez skrivnosti ponudnika) | **Svetovalno** | -| `nightly-schemathesis` | Mehko testiranje pogodbe OpenAPI (schemathesis) proti delujočemu OmniRoute z uporabo `docs/openapi.yaml` — razkrije kršitve specifikacije/neobravnavane napake 500 (faza 8 B.4) | **Svetovalno** | -| `nightly-mutation` | Rezultat mutacijskega testiranja Stryker v hitrem pasu testov enot — preživeli mutanti razkrijejo šibka preverjanja | **Svetovalno** | -| `nightly-compat` | Matrika združljivosti izvajalnega okolja Node v podprtih obsegih `engines.node` | **Svetovalno** | +| Delovni tok | Preverja | Blokiranje | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | Lastnostne teste fast-check z naključnim semenom in velikim številom izvajanj | **Svetovalno** | +| `nightly-resilience` | Kontrolo rasti kopice, vbrizgavanje napak za testiranje odpornosti in obremenitvene/dolgotrajne teste k6 | **Svetovalno** | +| `nightly-llm-security` | Zaščito pred vbrizgavanjem promptfoo (način blokiranja) in preizkuse garak (preskočeno brez skrivnosti ponudnika) | **Svetovalno** | +| `nightly-schemathesis` | Mehko testiranje pogodbe OpenAPI (schemathesis) na delujočem OmniRoute z uporabo `docs/openapi.yaml` — razkrije kršitve specifikacije/neobravnavane napake 500 (faza 8 B.4) | **Svetovalno** | +| `nightly-mutation` | Rezultat mutacijskega testiranja Stryker za hitro vejo testov enot — preživeli mutanti razkrijejo šibka preverjanja | **Svetovalno** | +| `nightly-compat` | Matriko združljivosti izvajalnika Node v podprtih razponih `engines.node` | **Svetovalno** | --- @@ -534,43 +534,43 @@ napako povezave in nikoli ne prekine sej. --- -## Zaostanek racionalizacije (pregled ROI — Faza 9 Val 3) +## Seznam za racionalizacijo (pregled ROI — Faza 9, val 3) -Ta inventar je bil 2026-06-17 usklajen z `ci.yml` (prejšnja različica je izpustila +Ta popis je bil 2026-06-17 usklajen z `ci.yml` (prejšnja različica je izpustila `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Pregled ROI usklajenega nabora -je opredelil naslednje kandidate za racionalizacijo. **Združitve so mehanske spremembe CI; -preklopi/opustitve pa so politične odločitve, pridržane upravljavcu.** Nič od spodaj navedenega -še ni uporabljeno. +`check:codeql-ratchet`, `check:pr-evidence`). Pregled ROI usklajenega nabora je +opredelil naslednje kandidate za racionalizacijo. **Združitve so mehanske spremembe CI; +preklopi/opustitve so odločitve o pravilnikih, pridržane operaterju.** Nič od spodaj +navedenega še ni uveljavljeno. -**Prav tako zgoraj ni dokumentirano** (svetovalno, šibek signal): opravilo `docs-lint` -(markdownlint + Vale, celotno opravilo ima `continue-on-error`) in samostojni delovni tokovi pregledovalnikov -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` je v -`quality-baseline.json`, vendar ni povezan z blokirajočim mehanizmom za preprečevanje regresij v `ci.yml` — metrika je -trenutno osirotela. +**Prav tako ni dokumentirano zgoraj** (svetovalno, šibek signal): opravilo `docs-lint` +(markdownlint + Vale, celotno opravilo ima `continue-on-error`) in samostojni delovni tokovi +pregledovalnikov `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` je v +`quality-baseline.json`, vendar ni povezan z blokirno zaskočko v `ci.yml` — metrika je +trenutno nepovezana. ### Združitev / odstranjevanje podvajanj (mehansko, manjše tveganje) -Vsak kandidat je bil 2026-06-17 preverjen glede na dejansko stanje kontrol (zaupaj, vendar preveri); -izkazalo se je, da več »očitnih« združitev skriva tehnični dolg in **niso** neposredno nadomestljive. - -- **`check:docs-sync` se izvede dvakrat** — samostojno v opravilu `lint` in znova znotraj `check:docs-all` (`docs-sync-strict`) ter v predpotrditvenem kavlju husky. ✅ **KONČANO** — samostojni klic v `lint` je odstranjen. -- **Pregledovanje CVE** — ❌ **NI čista združitev.** `audit:deps` povzroči strogo napako ob katerem koli CVE z visoko/kritično resnostjo; `check:vuln-ratchet` (osv) pa odpove samo ob _regresiji_ glede na izhodiščno vrednost (trenutno 1 MODERATE). Semantika se razlikuje — opustitev `audit:deps` bi odstranila absolutno kontrolo za visoko/kritično resnost. Ohranite oboje. -- **Zaznavanje ciklov** — ❌ **NI čista združitev.** `check:circular-deps` (dpdm) poroča o **91 ciklih** (zato je svetovalen); brez njihove predhodne odprave ga ni mogoče povišati v blokirajočo kontrolo, poleg tega ima širši obseg kot uspešna, skrbno izbrana kontrola `check:cycles`. `check:cycles` naj ostane blokirajoč; odprava 91 ciklov dpdm je ločena postavka zaostanka. -- **Kompleksnost** — ✅ **KONČANO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): en prehod ESLint, štetje po ruleId, tako da izhodiščne vrednosti za ciklomatsko kompleksnost + največje število vrstic ter kognitivno kompleksnost ostanejo neodvisne; posamezna ukaza `check:complexity` / `check:cognitive-complexity` ostajata za lokalni `--update`. -- **Preprečevanje halucinacij za `/api`** — ✅ **KONČANO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): en popis datotečnega sistema za `src/app/api`, openapi-routes + docs-symbols še vedno poročata neodvisno; posamezni ukazi ostajajo za lokalna izvajanja. -- **`check:node-runtime` se izvaja v 11 opravilih** — ⚠️ **nizek ROI.** Vsako se izvaja na ločenem izvajalniku in preverjanje traja <1 s; skupni prihranek je ~10 s, v zameno pa bi izgubili poceni zaščito za vsako opravilo. Sprememba ni vredna pretresov. -- **`typecheck:noimplicit:core` v preverjanju lint v CI** — ✅ **odstranjeno iz opravila lint** (bilo je svetovalno z `continue-on-error`); blokirajočo kontrolo površine tipov predstavljata `typecheck:core` + `check:type-coverage`. Lokalni skript je ohranjen. - -### Preklop / odločitev (politika upravljavca) - -- `check:openapi-security-tiers` (svetovalno) — ❌ **NI mogoče preprosto preklopiti.** Konča se s kodo 0, vendar opozori, da več poti `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` nima pripisa `x-loopback-only: true`. Pred uveljavitvijo je treba te pripise najprej dodati v `openapi.yaml`. -- `typecheck:noimplicit:core` (svetovalno) — v veliki meri ga nadomešča blokirajoči mehanizem `check:type-coverage` za preprečevanje regresij. Preklopite ga v mehanizem za preprečevanje regresij ali opustite odvečni drugi prehod `tsc`. -- `test:vitest:ui` (zdaj **blokirajoče**) — obstoječe napake so izrecno izključene v `vitest.config.ts` s sledilnimi komentarji `// #8618`; nove napake povzročijo neuspeh opravila. -- `check:secrets` (gitleaks, blokirajoči mehanizem za preprečevanje regresij, zamrznjen pri 3 dokumentiranih lažno pozitivnih zadetkih) — dodajte 3 zadetke na seznam dovoljenih, da dosežete 0, ali ga znižajte na svetovalnega. Prekriva se z izvornim GitHubovim pregledovanjem skrivnosti + `check:public-creds`. -- `check:pr-evidence` (blokirajoče, preiskuje besedilo telesa PR) — visoko tveganje lažno pozitivnih zadetkov; opustitev oslabi uveljavljanje Strogega pravila št. 18, zato gre za pravo politično odločitev. -- `semgrep` (samostojno svetovalno preverjanje) — pri družinah OWASP se prekriva s CodeQL; povežite njegovo izhodiščno vrednost z mehanizmom za preprečevanje regresij ali ga opustite. +Vsak kandidat je bil 2026-06-17 preverjen glede na dejansko stanje prehodov (zaupaj, vendar preveri); +izkazalo se je, da več »očitnih« združitev skriva dolg in **niso** neposredno uporabne zamenjave. + +- **`check:docs-sync` se izvede dvakrat** — samostojno v opravilu `lint` in ponovno znotraj `check:docs-all` (`docs-sync-strict`) ter v huskyjevi zanki pred potrditvijo. ✅ **OPRAVLJENO** — samostojni klic v `lint` je odstranjen. +- **Pregledovanje CVE-jev** — ❌ **NI primeren za neposredno združitev.** `audit:deps` se konča z napako ob katerem koli CVE-ju visoke/kritične stopnje; `check:vuln-ratchet` (osv) odpove samo ob _nazadovanju_ glede na izhodišče (trenutno 1 MODERATE). Različna semantika — opustitev `audit:deps` bi odstranila absolutni prehod za visoko/kritično stopnjo. Obdržite oba. +- **Zaznavanje ciklov** — ✅ **OPRAVLJENO** (#15159 G-01/G-02). Staro besedilo je `check:cycles` imenovalo »zeleni, kurirani« prehod in utemeljevalo, da mora ostati blokiren, ker je `check:circular-deps` (dpdm) poročal o 91 ciklih. Ta zelena oznaka je bila **lažno pozitivna**: `check:cycles` je pregledal 5 podimenikov (450 datotek), prepoznal samo statične `import|export … from` in zavrgel vsak določilnik `@/` ter `@omniroute/open-sse/`, zato ni mogel zaznati ciklov dinamičnih uvozov in vzdevkov, ki so prevladovali v repozitoriju. Popravljeno: prehod zdaj prehodi `src` + `open-sse` (5023 datotek), zbira določilnike iz AST-ja TypeScript (zato `import("…")` šteje, `typeof import("…")` na položaju tipa pa ne) in razrešuje `paths` iz tsconfig. Najde **14** ciklov, ne 0. Ker 14 obstoječih ciklov ni mogoče popraviti v PR-ju prehoda, je `check:cycles` zdaj **zaskočka** (`--ratchet`, zgornja meja `metrics.cycles.value = 14` v `quality-baseline.json`, `direction: down`) — blokira vsako _nazadovanje_, število pa se lahko samo zmanjšuje. CI izvaja `npm run check:cycles:ratchet`. Postopno odpravljanje poteka skupaj z **A-01**. `check:circular-deps` (dpdm) ostaja svetovalen kot širše drugo mnenje. +- **Kompleksnost** — ✅ **OPRAVLJENO** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): en prehod ESLint, štetje po ruleId, tako da izhodišča za ciklomatsko kompleksnost + največje število vrstic ter kognitivno kompleksnost ostanejo neodvisna; posamezna `check:complexity` / `check:cognitive-complexity` ostaneta za lokalni `--update`. +- **Preprečevanje halucinacij `/api`** — ✅ **OPRAVLJENO** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): en popis datotečnega sistema za `src/app/api`, openapi-routes + docs-symbols še vedno poročata neodvisno; posamezni pregledi ostanejo za lokalna izvajanja. +- **`check:node-runtime` se izvaja v 11 opravilih** — ⚠️ **nizek ROI.** Vsako opravilo uporablja ločen izvajalnik in pregled traja <1 s; skupni prihranek je ~10 s, v zameno pa bi izgubili poceni varovalo za vsako opravilo. Ni vredno spreminjanja. +- **`typecheck:noimplicit:core` v preverjanju CI lint** — ✅ **odstranjeno iz opravila lint** (bilo je svetovalno z `continue-on-error`); blokirno površino tipov zagotavljata `typecheck:core` + `check:type-coverage`. Lokalni skript je ohranjen. + +### Preklop / odločitev (pravilnik operaterja) + +- `check:openapi-security-tiers` (svetovalno) — ❌ **NI mogoče neposredno preklopiti.** Konča se s kodo 0, vendar opozori, da več poti `traffic-inspector` pod `LOCAL_ONLY_API_PREFIXES` nima oznake `x-loopback-only: true`. Pred uveljavitvijo je treba te oznake najprej dodati v `openapi.yaml`. +- `typecheck:noimplicit:core` (svetovalno) — večinoma ga nadomešča blokirna zaskočka `check:type-coverage`. Preklopite ga na zaskočko ali opustite odvečni drugi prehod `tsc`. +- `test:vitest:ui` (zdaj **blokirno**) — obstoječe napake so izrecno izključene v `vitest.config.ts` s sledilnimi komentarji `// #8618`; nove napake povzročijo neuspeh opravila. +- `check:secrets` (gitleaks, blokirna zaskočka, zamrznjena pri 3 dokumentiranih lažno pozitivnih zadetkih) — dodajte te 3 na seznam dovoljenih, da dosežete 0, ali ga znižajte na svetovalnega. Prekriva se z GitHubovim vgrajenim pregledovanjem skrivnosti + `check:public-creds`. +- `check:pr-evidence` (blokirno, išče vzorce v proznem besedilu telesa PR-ja) — visoko tveganje lažno pozitivnih zadetkov; opustitev oslabi uveljavljanje strogega pravila št. 18, zato je to dejanska odločitev o pravilniku. +- `semgrep` (samostojno svetovalno) — pri družinah OWASP se prekriva s CodeQL; povežite njegovo izhodišče z zaskočko ali ga opustite. --- diff --git a/docs/i18n/sr/CONTRIBUTING.md b/docs/i18n/sr/CONTRIBUTING.md index 3205f9d49e7..6bd6260ad6b 100644 --- a/docs/i18n/sr/CONTRIBUTING.md +++ b/docs/i18n/sr/CONTRIBUTING.md @@ -399,22 +399,24 @@ docs/ --- -## Листа за проверу Pull Request-а +## Контролна листа за Pull Request - [ ] Тестови пролазе (`npm test`) -- [ ] Linting пролази (`npm run lint`) -- [ ] Build успешно пролази (`npm run build`) -- [ ] TypeScript типови додати за нове јавне функције и интерфејсе -- [ ] Нема хардкодованих тајни (secrets) или fallback вредности -- [ ] Јавни upstream креденцијали уграђени преко `resolvePublicCred()` (погледајте [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), никада као литерали -- [ ] Одговори са грешкама пролазе кроз `buildErrorBody()` / `sanitizeErrorMessage()` — нема сирових stack trace-ова у телима одговора (погледајте [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell команде (`exec` / `spawn`) прослеђују runtime вредности преко `env`, а не путем интерполације стринга -- [ ] Сви инпути су валидирани помоћу Zod шема -- [ ] Додат changelog **фрагмент** унутар `changelog.d/{features|fixes|maintenance}/-.md` за промене видљиве корисницима (погледајте [`changelog.d/README.md`](./changelog.d/README.md)) — **немојте** директно уређивати `CHANGELOG.md`; фрагменти се агрегирају приликом издања и никада се не сукобљавају између PR-ова -- [ ] Документација ажурирана (ако је применљиво) -- [ ] Нема нових CodeQL / Secret-Scanning упозорења, или је свако од њих одбачено са техничким образложењем које упућује на релевантан документ из `docs/security/` -- [ ] Руте које покрећу подпроцесе (`/api/mcp/`, `/api/cli-tools/runtime/`) класификоване као `isLocalOnlyPath()` у `src/server/authz/routeGuard.ts` — погледајте [Строго правило бр. 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Нема `Co-Authored-By` додатака у commit порукама — commit-ови морају бити исписани искључиво под Git идентитетом власника репозиторијума (Строго правило бр. 16) +- [ ] Провера lint правила пролази (`npm run lint`) +- [ ] Изградња је успешна (`npm run build`) +- [ ] Додати су TypeScript типови за нове јавне функције и интерфејсе +- [ ] Нема хардкодованих тајни или резервних вредности +- [ ] Јавни приступни подаци узводног система уграђени су помоћу `resolvePublicCred()` (погледајте [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), никада као литерали +- [ ] Одговори са грешкама пролазе кроз `buildErrorBody()` / `sanitizeErrorMessage()` — нема необрађених stack trace-ова у телима одговора (погледајте [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Команде љуске (`exec` / `spawn`) прослеђују вредности током извршавања преко `env`, а не путем интерполације стрингова +- [ ] Сви улази су валидирани помоћу Zod шема +- [ ] Додат је **фрагмент** евиденције измена у `changelog.d/{features|fixes|maintenance}/-.md` за измене видљиве корисницима (погледајте [`changelog.d/README.md`](./changelog.d/README.md)) — немојте директно уређивати `CHANGELOG.md`; фрагменти се обједињују приликом издавања и никада не изазивају конфликте између PR-ова +- [ ] Документација је ажурирана (ако је применљиво) +- [ ] Нису отворена нова CodeQL упозорења нити упозорења Secret-Scanning-а, или је свако одбачено уз техничко образложење које упућује на релевантни документ у `docs/security/` +- [ ] Руте које покрећу подређене процесе (`/api/mcp/`, `/api/cli-tools/runtime/`) класификоване су као `isLocalOnlyPath()` у `src/server/authz/routeGuard.ts` — погледајте [Строго правило #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Нема AI/bot `Co-authored-by` завршних редова у порукама commit-а (Строго правило #16) — људски сарадници чији је рад поново употребљен наводе се помоћу стандардних `Co-authored-by: Name ` завршних редова + +--- ## Издавање diff --git a/docs/i18n/sr/docs/architecture/QUALITY_GATES.md b/docs/i18n/sr/docs/architecture/QUALITY_GATES.md index 00fb73d855c..f5fdcd29211 100644 --- a/docs/i18n/sr/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/sr/docs/architecture/QUALITY_GATES.md @@ -19,23 +19,23 @@ ### Прихватање кандидата -CI токови рада и токови рада за капије квалитета емитују стабилан исход: `Gate / CI` и -`Gate / Quality`. Њихова верзионисана политика прихватања наводи сваки узводни посао -као обавезан или саветодаван. Применљив обавезан посао мора бити успешан: недостајући, -отказани, прескочени, резултати на чекању и непознати резултати не могу да утврде PASS. Важећа -класификација само за документацију или само за каталог може учинити програмску путању неприменљивом; -нацрт PR-а није прихваћен кандидат. Ознака `hotfix` не укида захтев за доказима. - -Оба тока рада обухватају PR-ове и прослеђивања на главне/издавачке гране, ручно покретање и -догађаје групе спајања. Прослеђивање, ручно покретање и група спајања извршавају пун избор. Форкови -и групе спајања користе хостоване извршиоце за послове који би иначе изабрали -самостално хостоване извршиоце; пре увођења мора се проверити довољан хостовани капацитет. - -Свака JSON потврда идентификује преузети SHA, извршавање тока рада и покушај. -CLI одбацује неподударност SHA вредности преузете верзије и догађаја. Тестови тока рада повезују чланство у политици -са листом `needs` посла за утврђивање исхода, тако да нова или уклоњена путања не може неприметно нестати. -Потврде покривају сопствени ток рада, а не објављивање, примену или унутрашњи рад -постојећег саветодавног скенера. Активирање оба назива провера у правилима гране представља +CI и Quality Gates токови рада емитују стабилан исход: `Gate / CI` и +`Gate / Quality`. Њихова верзионисана политика прихватања наводи сваки претходни посао +као обавезан или саветодаван. Применљив обавезни посао мора успети: недостајући, +отказани, прескочени, исходи на чекању и непознати исходи не могу установити PASS. Важећа +класификација само за документацију или само за каталог може учинити програмску грану неприменљивом; +нацрт PR-а није прихваћени кандидат. Ознака `hotfix` не укида захтев за доказима. + +Оба тока рада обухватају PR-ове и слања на главне/release гране, ручно покретање и +догађаје групе спајања. Слање, ручно покретање и група спајања извршавају пун избор. Форкови +и групе спајања користе хостоване покретаче за послове који би иначе изабрали самостално хостоване +покретаче; пре увођења мора се проверити довољан хостовани капацитет. + +Свака JSON потврда идентификује преузети SHA, покретање тока рада и покушај. +CLI одбацује неподударање SHA вредности преузетог стања и догађаја. Тестови тока рада везују чланство у политици +за листу `needs` посла који доноси исход, тако да нова или уклоњена грана извршавања не може неприметно нестати. +Потврде обухватају сопствени ток рада, а не објављивање, примену или интерну логику +постојећег саветодавног скенера. Активирање оба назива провере у правилима гране представља засебну административну измену; додавање ових послова само по себи не штити грану. ### Инвентар статичког скенирања @@ -43,190 +43,190 @@ CLI одбацује неподударност SHA вредности преу Верзионисани инвентар npm алијаса и чланство у статичком скенирању налазе се у `config/quality/gate-manifest.json`. Покрените `npm run check:gate-manifest` да бисте проверили називе скрипти и тачне команде у односу на `package.json`; додавања, уклањања и -одступања команди узрокују неуспех и локалне куке и послова класификације измена у CI-ју. -Алијас није посао тока рада, инстанца матрице или тест случај: ови бројеви се +одступања команди доводе до неуспеха и локалне куке и послова класификације измена у CI-ју. +Алијас није посао тока рада, инстанца матрице нити тестни случај: ови бројеви се не смеју представљати као међусобно заменљиви. Користите `npm run quality:scan -- --list` или `npm run quality:scan:fast -- --list` -да бисте прегледали изабране алијасе без њиховог извршавања. Извршилац позива -npm улазну тачку, тако да се њено окружење за извршавање (укључујући Bun тамо где је конфигурисан) задржава. -Манифест бележи алијасе изван ових профила као засебно позване, а +да бисте прегледали изабране алијасе без њиховог извршавања. Покретач позива +npm улазну тачку, тако да је њено окружење за извршавање (укључујући Bun тамо где је конфигурисан) очувано. +Манифест бележи алијасе изван тих профила као засебно позиване, а команде за одржавање су забрањене у профилима скенирања само за читање. -Ови профили покривају само статичко скенирање. Они не потврђују тестове производа, -покривеност, паковање, спољне провере или потпуно прихватање кандидата за издање. -Прихватање у току рада користи повезани `config/quality/admission-policy.json` и -`scripts/quality/admission-verdict.mjs`. Профили за надгледање издања остају одвојени; -њихове применљиве провере и потврде прегледајте независно. Текстуални +Ови профили обухватају само статичко скенирање. Они не сертификују тестове производа, +покривеност, паковање, спољне провере нити потпуно прихватање кандидата за издање. +Прихватање у току рада користи повезане `config/quality/admission-policy.json` и +`scripts/quality/admission-verdict.mjs`. Профили посматрача издања остају засебни; +независно прегледајте њихове применљиве провере и потврде. Текстуални инвентар у наставку служи као референца, а не као доказ да је капија заиста извршена. -Скрипте се налазе у `scripts/check/` (капије политика) и `scripts/quality/` (механизам постепеног пооштравања). +Скрипте се налазе у `scripts/check/` (капије политике) и `scripts/quality/` (механизам постепеног пооштравања). CI извор истине је `.github/workflows/ci.yml`. -### Брза путања PR-а за издање (`quality.yml`) +### Брза путања за PR издања (`quality.yml`) -`.github/workflows/quality.yml` допуњује CI за PR-ове главних/издавачких грана, прослеђивања -на заштићене гране, ручна покретања и групе спајања. PR-ови користе брзе провере филтриране према путањи. Трајно +`.github/workflows/quality.yml` допуњује CI за PR-ове на главним/release гранама, слања +на заштићене гране, ручна покретања и групе спајања. PR-ови користе брзе провере филтриране по путањама. Трајно онемогућена дуплирана изградња је уклоњена; стварне провере изградње/паковања/покретања остају у CI-ју. -| Посао | Опсег | Блокирајући | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `Docs Gates (fast-path)` | PR-ови документације/кода; референце API документације и целокупна документација | Да | -| `Fast Quality Gates` | PR-ови кода; статичке провере, провера типова, провера типова контролне табле, тестови јединица на које измене утичу | Да | -| `Forgotten sibling tests` | PR-ови кода; измењени модули праћени до статичких потрошача и тестова сродних кандидата; путање преко збирних модула и динамичког увоза пријављују се као саветодавна дијагностика, уз наведене изузетке са листе дозвољених ставки | **Саветодавно** | -| `Vitest (fast-path)` | PR-ови кода; брзи Vitest скуп | Да | -| `Unit Tests fast-path` | PR-ови кода; скуп тестова јединица у 4 партиције | Да | -| `No new ESLint warnings` | PR-ови кода; заштита од упозорења линтера која узима у обзир потискивања | Да, укључујући форкове | -| `Merge integrity (changelog + generated skills)` | PR-ови који нису нацрти; синхронизација дневника измена и генерисаних вештина | Да, укључујући форкове | +| Посао | Опсег | Блокирајуће | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `Docs Gates (fast-path)` | PR-ови документације/кода; референце API документације и сва документација | Да | +| `Fast Quality Gates` | PR-ови кода; статичке провере, провера типова, провера типова контролне табле, обухваћени јединични тестови | Да | +| `Forgotten sibling tests` | PR-ови кода; измењени модули праћени до статичких потрошача и кандидата за сродне тестове; путање barrel модула и динамичког увоза пријављују се као саветодавна дијагностика, уз наведене изузетке са листе дозвољених | **Саветодавно** | +| `Vitest (fast-path)` | PR-ови кода; брзи скуп vitest тестова | Да | +| `Unit Tests fast-path` | PR-ови кода; скуп јединичних тестова у 4 шарда | Да | +| `No new ESLint warnings` | PR-ови кода; заштита lint провере која узима у обзир потискивања | Да, укључујући форкове | +| `Merge integrity (changelog + generated skills)` | PR-ови који нису нацрти; синхронизација дневника измена и генерисаних вештина | Да, укључујући форкове | #### Извештај о заборављеним сродним тестовима -`npm run check:forgotten-sibling-tests` поново користи разрешавач увоза који стоји иза мапе утицаја на тестове. +`npm run check:forgotten-sibling-tests` поново користи разрешивач увоза који стоји иза мапе утицаја тестова. За сваки измењени продукциони модул пријављује детерминистичке ланце -`измењени модул/симбол -> статички потрошач -> сродни тест кандидат` када тест кандидат -није присутан у разлици захтева за повлачење. Markdown сажетак и JSON резултат чувају се као +`измењени модул/симбол -> статички потрошач -> кандидат за сродни тест` када кандидат +за тест није присутан у разлици захтева за повлачење. Markdown сажетак и JSON резултат чувају се као артефакт тока рада `forgotten-sibling-tests` ради калибрације пре било каквог увођења блокирања. Barrel поновни извози и динамички увози служе само за дијагностику разрешавања; они никада не стварају блокирајући налаз. Прегледани изузеци налазе се у `config/quality/forgotten-sibling-allowlist.json`. Свака ставка мора да наведе потрошача и кандидатски -тест, пружи конкретно образложење и садржи везу ка GitHub проблему или pull request-у. Неисправне ставке се -подразумевано одбијају. Изузеци не могу да прикрију обрисани кандидатски тест нити измену која додаје `.skip`/`.todo`; +тест, пружи конкретно образложење и садржи везу ка GitHub проблему или захтеву за спајање. Неисправне ставке се +подразумевано одбијају. Изузеци не могу да потисну обрисани кандидатски тест нити diff који додаје `.skip`/`.todo`; слабљење тврдњи и друга прикривања остају у надлежности независно блокирајуће `check:test-masking` контроле. ### Задатак: `lint` -Покреће се за сваки PR ка грани `main`. Блокира спајање у случају неуспеха. - -| Скрипта (`npm run ...`) | Проверава | Блокирајуће | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------- | -| `check:node-runtime` | Верзија Node.js-а је унутар подржаног опсега | Да | -| `check:cycles` | Цикличне увозе — све модуле у `src/` + `open-sse/` | Да | -| `check:route-validation:t06` | Zod шеме су присутне на свим рутама (Tier 6 смерница) | Да | -| `check:any-budget:t11` | Број `@ts-expect-error // any` не премашује буџет (Tier 11 catraca) | Да | -| `check:provider-consistency` | Сваки провајдер у `providers.ts` има одговарајући унос у `providerRegistry.ts` (и обрнуто, у оквиру листе дозвољених) | Да | -| `check:model-lifecycle` | Три ручно одржаване табеле рутирања остају усклађене са снимком животног циклуса који је укључен у репозиторијум (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не бодује ниједан повучени id који `REGISTRY` може да рутира; сваки циљ из `BUILT_IN_ALIASES` присутан је у `REGISTRY` и одсутан из снимка повучених id-ова; сваки повучени id који је још увек у `REGISTRY` прослеђује се или је наведен у `allowedRetiredInCatalog`; и ниједан извор или циљ из `DEFAULT_DEGRADATION_MAP` није означен као повучен у том снимку. Ово не доказује да активни узводни сервис тренутно опслужује модел. Офлајн — пореди са `config/quality/model-lifecycle.json`, који се ручно освежава помоћу `npm run quality:refresh-model-lifecycle` (захтева мрежу; није повезано са CI-јем). `allowedRetiredInCatalog` је механизам са постепеним смањивањем: додајте унос само уз проблем за праћење. | Да | -| `check:fetch-targets` | Сваки `fetch("/api/...")` у клијентском `src/` разрешава се на стварни `route.ts` | Да | -| `check:deps` | Све зависности које се могу инсталирати помоћу `npm install` из сваког `package.json` у репозиторијуму налазе се у `dependency-allowlist.json`; нови пакети без фиксиране верзије или са називима који подсећају на постојеће пакете биће означени | Да | -| `audit:deps` | `npm audit` (корени пакет + Electron) — нема упозорења високог/критичног нивоа (преклапа се са OSV провером `check:vuln-ratchet`; погледајте списак за накнадно рационализовање) | Да | -| `check:lockfile` | Интегритет датотеке `package-lock.json` — HTTPS регистар, хешеви интегритета, без замене хостова | Да | -| `check:licenses` | Lista dozvoljenih SPDX licenci za produkcione zavisnosti | Da | -| `check:tracked-artifacts` | Bez artefakata izgradnje / komitovanih `node_modules` simboličkih veza (pokreće se i u husky pre-commit kuki; pre-push je namerno minimalan — #6716) | Da | -| `check:ai-attribution` | Bez AI/bot `Co-Authored-By` prikolice ili podnožja o AI generisanju u PR komitovima, naslovu ili telu — Strogo pravilo #16 (u petlji brzih provera u `quality.yml` za PR→`release/**` — čita sadržaj događaja, ne radi ništa van PR-ova — i korak samo za PR u lint proveri u `ci.yml` za PR→`main`; takođe i husky `commit-msg` kuka; ljudski koautori su dozvoljeni; #14436) | -| `check:vitest-exclusions` | Svako Vitest izuzimanje navodi prateći problem i nalazi se u `config/quality/vitest-exclusions.json` (#13204) | Da | -| `check:file-size` | Nijedna izvorna datoteka ne premašuje ograničenje za odgovarajuću ekstenziju (račva: zamrznute velike datoteke na listi `frozen`) | Da | -| `check:error-helper` | Odgovori sa greškama u izvršiocima/rukovaocima koriste `buildErrorBody()` / `sanitizeErrorMessage()` (Strogo pravilo #12) | Da | -| `check:migration-numbering` | Миграционе SQL датотеке су нумерисане узастопно, без празнина или дупликата | Да | -| `check:public-creds` | Нема дословно наведених OAuth вредности `client_id`/`client_secret` нити Firebase Web кључева изван `publicCreds.ts` (Строго правило бр. 11) | Да | -| `check:db-rules` | Нема необрађеног SQL-а изван модула `src/lib/db/`; нема обједињених увоза из `localDb.ts` (Строга правила бр. 2/5) | Да | -| `check:known-symbols` | Извршиоци добављача, стратегије рутирања и преводиоци регистровани у својим табелама за отпремање подударају се са датотекама на диску — нема неповезаних нити недекларисаних симбола | Да | -| `check:route-guard-membership` | Свака рута која покреће подређени процес класификована је помоћу `isLocalOnlyPath()` (Строга правила бр. 15/17) | Да | -| `check:test-discovery` | Сваку датотеку `*.test.ts` / `*.spec.ts` у репозиторијуму прикупља барем један покретач тестова (запорни механизам: листа неповезаних датотека у `test-discovery-baseline.json` може само да се смањује) | Да | -| `check:agent-skills-sync` | Генерисани agent-skills артефакти одговарају свом изворном каталогу (без одступања) | -| `check:provider-asset-provenance` | Логотипи/ресурси провајдера имају забележен податак о пореклу | -| `lint:json` | JSON конфигурационе датотеке се исправно рашчлањују и задовољавају правила линтовања репозиторијума | -| `typecheck:core` | TypeScript компилација без грешака (само саветодавна упозорења) | Да | -| `typecheck:noimplicit:core` | Строги `noImplicitAny` — усмерено на будуће стање; многа постојећа места позива и даље захтевају анотације | **Саветодавно** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ограничен на `src/app/(dashboard)/**` (#7033) — пажљиво одабрана листа од 27 датотека у `typecheck:core` не обухвата ниједан dashboard TSX, а ни `next build` никада не проверава њихове типове (`next.config.mjs` поставља `ignoreBuildErrors: true`), па су регресије са идентификаторима без дефиниције у њима (#6625/#6909) биле невидљиве CI-ју. Разлике се пореде са замрзнутом основном вредношћу броја грешака по датотеци и TS коду (`config/quality/dashboard-typecheck-baseline.json`, исти образац провере застарелости као код `check:known-symbols`) — само НОВЕ грешке изнад броја у основној вредности обарају проверу; постепено смањујте основну вредност помоћу `--update` када се постојећа грешка исправи. | Да | +Покреће се при сваком PR-у ка `main`. У случају неуспеха блокира спајање. + +| Скрипта (`npm run ...`) | Проверава | Блокирајуће | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | Верзија Node.js-а је унутар подржаног опсега | Да | +| `check:cycles` | Цикличне увозе у целом `src/` + `open-sse/` (засновано на AST-у, разрешене су tsconfig `paths` путање). Самостално покретање = саветодавно, наводи циклусе. `check:cycles:ratchet` (који CI покреће) блокира када број премаши горњу границу `metrics.cycles` у `quality-baseline.json` — тренутно 14, `direction: down`, тако да може само да се смањује (#15159 G-01/G-02) | Да (механизам постепеног пооштравања) | +| `check:route-validation:t06` | Zod шеме су присутне на свим рутама (политика нивоа 6) | Да | +| `check:any-budget:t11` | Број `@ts-expect-error // any` не премашује ограничење (catraca нивоа 11) | Да | +| `check:provider-consistency` | Сваки провајдер у `providers.ts` има одговарајући унос у `providerRegistry.ts` (и обрнуто, у оквиру листе дозвољених) | Да | +| `check:model-lifecycle` | Три ручно одржаване табеле рутирања остају усклађене са снимком животног циклуса који је укључен у репозиторијум (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не бодује ниједан повучени id који `REGISTRY` може да рутира; сваки циљ из `BUILT_IN_ALIASES` присутан је у `REGISTRY` и одсутан из снимка повучених id-ова; сваки повучени id који је и даље у `REGISTRY` прослеђује се или је наведен у `allowedRetiredInCatalog`; и ниједан извор или циљ из `DEFAULT_DEGRADATION_MAP` није означен као повучен у том снимку. Ово не доказује да модел тренутно опслужује активни узводни систем. Ради ван мреже — пореди са `config/quality/model-lifecycle.json`, који се ручно освежава помоћу `npm run quality:refresh-model-lifecycle` (захтева мрежу; није повезано са CI-јем). `allowedRetiredInCatalog` је механизам постепеног смањивања: унос додајте само уз проблем за праћење. | Да | +| `check:fetch-targets` | Сваки `fetch("/api/...")` у клијентском `src/` разрешава се на стварни `route.ts` | Да | +| `check:deps` | Све зависности које се могу инсталирати помоћу `npm install` у сваком `package.json` у репозиторијуму налазе се у `dependency-allowlist.json`; нови неприковани или slopsquatted пакети се означавају | Да | +| `audit:deps` | `npm audit` (корен + electron) — нема упозорења високог/критичног нивоа (преклапа се са osv `check:vuln-ratchet`; погледајте Заостатак за рационализацију) | Да | +| `check:lockfile` | Интегритет датотеке `package-lock.json` — https регистар, хешеви интегритета, без замена хоста | Да | +| `check:licenses` | Листа дозвољених SPDX лиценци за продукционе зависности | Да | +| `check:tracked-artifacts` | Нема артефаката изградње / комитованих симболичких веза ка `node_modules` (такође се покреће у husky pre-commit куки; pre-push је намерно поједностављен — #6716) | Да | +| `check:ai-attribution` | Нема AI/bot `Co-Authored-By` завршног реда нити подножја о AI генерисању у PR комитовима, наслову или телу — Строго правило #16 (у `quality.yml` петљи брзих провера за PR→`release/**` — чита садржај догађаја и не ради ништа ван PR-ова — и корак само за PR у `ci.yml` lint провери за PR→`main`; такође и husky `commit-msg` кука; људски коаутори су дозвољени; #14436) | +| `check:vitest-exclusions` | Свако Vitest изузеће наводи проблем за праћење и налази се у `config/quality/vitest-exclusions.json` (#13204) | Да | +| `check:file-size` | Ниједна изворна датотека не премашује ограничење за своју екстензију (чегртаљка: велике датотеке су замрзнуте у листи `frozen`) | Да | +| `check:error-helper` | Одговори о грешкама у извршиоцима/обрађивачима користе `buildErrorBody()` / `sanitizeErrorMessage()` (Строго правило #12) | Да | +| `check:migration-numbering` | Миграционе SQL датотеке су нумерисане редом, без празнина или дупликата | Да | +| `check:public-creds` | Нема дословних OAuth вредности `client_id`/`client_secret` нити Firebase Web кључева изван `publicCreds.ts` (строго правило бр. 11) | Да | +| `check:db-rules` | Нема сировог SQL-а изван модула у `src/lib/db/`; нема збирних увоза из `localDb.ts` (строга правила бр. 2/5) | Да | +| `check:known-symbols` | Извршиоци добављача, стратегије усмеравања и преводиоци регистровани у својим табелама за отпремање подударају се са датотекама на диску — нема неповезаних или непријављених симбола | Да | +| `check:route-guard-membership` | Свака рута која покреће подређени процес класификована је помоћу `isLocalOnlyPath()` (строга правила бр. 15/17) | Да | +| `check:test-discovery` | Свака датотека `*.test.ts` / `*.spec.ts` у репозиторијуму обухваћена је најмање једним покретачем тестова (механизам са чегртаљком: листа неповезаних датотека у `test-discovery-baseline.json` може само да се смањује) | Да | +| `check:agent-skills-sync` | Генерисани agent-skills артефакти одговарају свом изворном каталогу (без одступања) | +| `check:provider-asset-provenance` | Логотипи/ресурси добављача имају забележен податак о пореклу | +| `lint:json` | JSON конфигурационе датотеке се успешно рашчлањују и задовољавају правила провере репозиторијума | +| `typecheck:core` | TypeScript компилација без грешака (само саветодавна упозорења) | Да | +| `typecheck:noimplicit:core` | Строги `noImplicitAny` — усмерено ка будућности; многа постојећа места позива и даље захтевају анотације | **Саветодавно** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ограничен на `src/app/(dashboard)/**` (#7033) — пажљиво одабрана листа од 27 датотека у `typecheck:core` не обухвата ниједан dashboard TSX, а ни `next build` га никада не проверава типски (`next.config.mjs` поставља `ignoreBuildErrors: true`), па су регресије са идентификаторима без дефиниције у њему (#6625/#6909) биле невидљиве CI-ју. Разлике се пореде са замрзнутом основном линијом броја грешака по датотеци и TS коду (`config/quality/dashboard-typecheck-baseline.json`, исти образац за спровођење застарелости као код `check:known-symbols`) — само НОВЕ грешке изнад броја у основној линији доводе до неуспеха контроле; постепено смањујте основну линију помоћу `--update` када се исправи постојећа грешка. | Да | ### Задатак: `quality-gate` Покреће се након `test-coverage`. Неуспех блокира спајање. -| Скрипта | Проверава | Блокирајуће | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `quality:collect` | Генерише `quality-metrics.json` (број ESLint упозорења, покривеност из обједињеног извештаја сегмената) | Да (претходи механизму ratchet) | -| `quality:ratchet` | Ниједна метрика у `quality-baseline.json` није назадовала (ESLint упозорења ≤ основна вредност; покривеност ≥ основна вредност) | Да | -| `check:duplication` | Дуплирање кода (jscpd@4) не премашује основну вредност у `quality-baseline.json` | Да | -| `check:complexity` | Цикломатска сложеност на нивоу датотеке не премашује ограничење (основни ESLint `complexity` + `max-lines-per-function`) | Да | -| `check:cognitive-complexity` | Ratchet когнитивне сложености (`eslint-plugin-sonarjs`) — засебно покретање ESLint-а; CI оба покреће обједињено као један корак `check:complexity-ratchets` | Да | -| `check:dead-code` | Ratchet некоришћених извоза / датотека (knip) не назадује у односу на основну вредност | Да | -| `check:compression-budget` | Буџет за мерење перформанси компресије — минималне уштеде токена по механизму не смеју назадовати | Да | -| `check:type-coverage` | Ratchet процента типизованог кода (`type-coverage`) не назадује; у великој мери обухвата `typecheck:noimplicit:core` | Да | -| `check:codeql-ratchet` | Број отворених CodeQL упозорења не назадује (чита преко `gh api`; безбедно прескаче без токена) — учесталост освежавања и ручно покретање: погледајте „CodeQL ratchet“ испод | Да | - -### Посао: `quality-extended` - -Цео посао је саветодаван (`continue-on-error: true`). Ratchet провере засноване на npm-у заиста се -извршавају; спољни скенери се инсталирају преко `gh release download` и сами се прескачу (излазни кôд 0) +| Скрипта | Проверава | Блокирајуће | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | +| `quality:collect` | Генерише `quality-metrics.json` (број ESLint упозорења, покривеност из обједињеног извештаја партиција) | Да (претходи механизму прага) | +| `quality:ratchet` | Ниједна метрика у `quality-baseline.json` није назадовала (ESLint упозорења ≤ референтна вредност; покривеност ≥ референтна вредност) | Да | +| `check:duplication` | Дуплирање кода (jscpd@4) не премашује референтну вредност у `quality-baseline.json` | Да | +| `check:complexity` | Цикломатска сложеност на нивоу датотеке не премашује горњу границу (основни ESLint `complexity` + `max-lines-per-function`) | Да | +| `check:cognitive-complexity` | Механизам прага когнитивне сложености (`eslint-plugin-sonarjs`) — засебно ESLint извршавање; CI обједињује оба у један корак `check:complexity-ratchets` | Да | +| `check:dead-code` | Механизам прага за некоришћене извозе / датотеке (knip) не назадује у односу на референтну вредност | Да | +| `check:compression-budget` | Буџет бенчмарка компресије — минималне уштеде токена по механизму не смеју да назадују | Да | +| `check:type-coverage` | Механизам прага за проценат типизираног кода (`type-coverage`) не назадује; у великој мери обухвата `typecheck:noimplicit:core` | Да | +| `check:codeql-ratchet` | Број отворених CodeQL упозорења не назадује (чита преко `gh api`; безбедно прескаче без токена) — учесталост освежавања и ручно покретање: погледајте „CodeQL механизам прага“ испод | Да | + +### Задатак: `quality-extended` + +Цео задатак је саветодаван (`continue-on-error: true`). Механизми прага засновани на npm-у заиста се извршавају; +спољни скенери се инсталирају преко `gh release download` и сами се прескачу (излазни код 0) када бинарна датотека и даље није присутна. -| Скрипта | Проверава | Блокирајуће | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| `check:circular-deps` | Нема кружних зависности (dpdm) | **Саветодавно** | -| `check:bundle-size` | Величина пакета не премашује ограничење | **Саветодавно** | -| `check:secrets` | Скенирање тајни (gitleaks) — прескаче се ако бинарна датотека није присутна | **Саветодавно** | -| `check:vuln-ratchet` | Рањивости зависности (osv-scanner) не назадују — прескаче се ако бинарна датотека није присутна | **Саветодавно** | -| `check:workflows` | Провера радних токова (actionlint + zizmor); скенери који недостају или не раде, неважећи извештаји или основна ratchet вредност која недостаје узрокују неуспех са статусом INCOMPLETE. Важећи налази прате изабрану строгу/саветодавну/ratchet политику | Извршавање је обавезно; zizmor ratchet блокира у CI-ју | -| `check:openapi-breaking` | Неусклађене измене јавног API уговора (`openapi.yaml`) у односу на основну грану (oasdiff) — генерише `openapiBreaking=N`; прескаче се ако oasdiff није присутан или основна спецификација не може да се разреши | **Саветодавно** | - -### Посао: `docs-sync-strict` - -Покреће се при сваком PR-у ка грани `main`. Блокира спајање у случају неуспеха. - -| Скрипта | Проверава | Блокирајуће | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | -| `check:docs-all` | Мета-услов који редом покреће 6 услова у наставку | Да | -| ↳ `check:docs-sync` | Усклађеност верзија у CHANGELOG-у / OpenAPI-ју / llm.txt | Да | -| ↳ `check:docs-counts` | Бројеви у тексту (број добављача, број миграција итд.) налазе се унутар прогресивно ограниченог опсега стварних вредности | Да | -| ↳ `check:env-doc-sync` | Свака променљива окружења у `.env.example` документована је у табели документације и обрнуто | Да | -| ↳ `check:deprecated-versions` | У документацији нема застарелих ознака верзија | Да | -| ↳ `check:doc-links` | Интерне markdown везе у документацији упућују на постојеће датотеке (облик `[text]`/`(path)`) | Да | -| ↳ `check:fabricated-docs` | Руте, променљиве окружења, CLI команде, називи hook-ова и путање датотека наведени у документацији постоје у бази кода. Строг услов уз `--strict`; без те опције неуспех је неблокирајући. | Да (помоћу `--strict` у CI-ју) | -| `check:cli-i18n` | Ниске CLI команди присутне су у свим i18n датотекама локализације | Да | -| `check:openapi-coverage` | OpenAPI спецификација покрива најмање прогресивно повећаван минимални број стварних рута | Да | -| `check:openapi-security-tiers` | Ознаке безбедносних нивоа у `openapi.yaml` усклађене су са класификацијама у `routeGuard.ts` | **Саветодавно** | -| `check:openapi-routes` | Свака путања у `openapi.yaml` одговара стварној датотеци `route.ts` (заштита од халуцинација) | Да | -| `check:docs-symbols` | Свака референца `/api/...` у `docs/**/*.md` одговара стварној датотеци `route.ts` (заштита од халуцинација) | Да | -| `i18n translation drift` | Непреведени кључеви у i18n датотекама локализације — само упозорење | **Саветодавно** | +| Скрипта | Проверава | Блокирајуће | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | +| `check:circular-deps` | Нема кружних зависности (dpdm) | **Саветодавно** | +| `check:bundle-size` | Величина пакета не премашује горњу границу | **Саветодавно** | +| `check:secrets` | Скенирање тајни (gitleaks) — прескаче се ако бинарна датотека није присутна | **Саветодавно** | +| `check:vuln-ratchet` | Рањивости зависности (osv-scanner) не назадују — прескаче се ако бинарна датотека није присутна | **Саветодавно** | +| `check:workflows` | Провера токова рада (actionlint + zizmor); скенери који недостају или не раде, неважећи извештаји или референтна вредност механизма прага која недостаје узрокују статус INCOMPLETE. Важећи налази прате изабрану строгу/саветодавну политику или политику прага | Извршавање је обавезно; zizmor механизам прага блокира у CI-ју | +| `check:openapi-breaking` | Неусклађене измене јавног API уговора (`openapi.yaml`) у односу на основну грану (oasdiff) — генерише `openapiBreaking=N`; прескаче се ако oasdiff није присутан или се основна спецификација не може разрешити | **Саветодавно** | + +### Задатак: `docs-sync-strict` + +Покреће се при сваком PR-у ка `main`. Блокира спајање у случају неуспеха. + +| Скрипта | Проверава | Блокирајуће | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `check:docs-all` | Мета-капија која редом покреће 6 поткапија наведених испод | Да | +| ↳ `check:docs-sync` | Усклађеност верзија у CHANGELOG-у, OpenAPI-ју и llm.txt | Да | +| ↳ `check:docs-counts` | Бројеви у тексту (број добављача, број миграција итд.) налазе се унутар постепено пооштраваног опсега стварних вредности | Да | +| ↳ `check:env-doc-sync` | Свака променљива окружења у `.env.example` документована је у табели документације и обрнуто | Да | +| ↳ `check:deprecated-versions` | У документацији нема ниски застарелих верзија | Да | +| ↳ `check:doc-links` | Интерне markdown везе у документацији разрешавају се у стварне датотеке (облик `[текст]`/`(путања)`) | Да | +| ↳ `check:fabricated-docs` | Руте, променљиве окружења, CLI команде, називи hook-ова и путање датотека наведени у документацији постоје у бази кода. Строга капија преко `--strict`; без ове опције грешка није блокирајућа. | Да (преко `--strict` у CI-ју) | +| `check:cli-i18n` | Ниске CLI команди присутне су у свим i18n датотекама локализација | Да | +| `check:openapi-coverage` | OpenAPI спецификација покрива најмање постепено повећавани минимални праг стварних рута | Да | +| `check:openapi-security-tiers` | Ознаке безбедносних нивоа у `openapi.yaml` усклађене су са класификацијама у `routeGuard.ts` | **Саветодавно** | +| `check:openapi-routes` | Свака путања у `openapi.yaml` разрешава се у стварни `route.ts` (спречавање халуцинација) | Да | +| `check:docs-symbols` | Свака референца `/api/...` у `docs/**/*.md` разрешава се у стварни `route.ts` (спречавање халуцинација) | Да | +| `i18n translation drift` | Непреведени кључеви у i18n датотекама локализација — само упозорење | **Саветодавно** | ### Задатак: `i18n-ui-coverage` -| Скрипта | Проверава | Блокирајуће | -| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | -| `check-ui-keys-coverage` (уграђено) | Покривеност UI i18n кључева је ≥ 65% | Да | -| `check-ui-value-drift` (уграђено) | Измењена енглеска **вредност** не оставља за собом застарели превод | Да | -| `check-new-key-coverage` (уграђено) | **Нови** енглески кључ преведен је у свакој локализацији — ознака `__MISSING__:` се одбија | Да | -| `check-translation-ratio` | Удео стварних превода по локализацији (листови идентични енглеском / резервисане вредности / листови који недостају ван листе дозвољених) не сме премашити `config/quality/i18n-translation-baseline.json` + толеранцију | **Саветодавно** | +| Скрипта | Проверава | Блокирајуће | +| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (уграђено) | Покривеност UI i18n кључева је ≥ 65% | Да | +| `check-ui-value-drift` (уграђено) | Измењена енглеска **вредност** не оставља за собом застарели превод | Да | +| `check-new-key-coverage` (уграђено) | **Нови** енглески кључ преведен је у свакој локализацији — маркер `__MISSING__:` се одбија | Да | +| `check-translation-ratio` | Удео стварних превода по локализацији (листови идентични енглеском / резервисани текст / недостајући листови ван листе дозвољених изузетака) не сме премашити `config/quality/i18n-translation-baseline.json` + толеранцију | **Саветодавно** | -Захтева `fetch-depth: 0` — услов за одступање вредности пореди разлике у `en.json` у односу на основу спајања. +Захтева `fetch-depth: 0` — капија за одступање вредности пореди `en.json` са заједничком базом спајања. -#### `check-ui-value-drift` — услов за застареле преводе +#### `check-ui-value-drift` — капија за застареле преводе -Открива ону i18n регресију коју остали услови структурно не могу да уоче: енглеска вредност -се измени, док преводи изведени из _претходног_ енглеског остану непромењени, па +Открива једну i18n регресију коју друге капије структурно не могу да уоче: енглеска вредност +се измени, а преводи изведени из _претходног_ енглеског остану непромењени, па корисници који не говоре енглески настављају да читају самоуверено формулисан, али сада нетачан текст. Ово се заиста нашло у издању. `oauthModal.googleOAuthWarning` је измењен када је додат Antigravity помоћник за пријављивање (#5203); **39 од 43 локализације** задржало је текст који оператерима говори да „копирају -цео URL и налепе га испод“ — ток који за тог добављача није могуће довршити. То је +целу URL адресу и налепе је испод“ — ток који код тог добављача није могуће довршити. То је остало непримећено све до #8463 зато што: -- `sync-ui-keys` допуњава само кључеве који су **одсутни**, никада оне који су **застарели**; -- `check-ui-keys-coverage` броји _присутност_ кључа, па се застарели превод рачуна као покривен; -- `check-translation-drift` прати документационе копије у `docs/i18n//**.md` — +- `sync-ui-keys` допуњава само кључеве који **недостају**, никада оне који су **застарели**; +- `check-ui-keys-coverage` рачуна _присуство_ кључа, па се застарели превод рачуна као покривен; +- `check-translation-drift` прати документационе одразе `docs/i18n//**.md` — никада не чита `src/i18n/messages/*.json`. Блокирајуће у задатку `docs-sync-strict` од - поновне синхронизације 2026-09: измените основни документ → `npm run i18n:run -- --files=` (на нивоу одељка, брзо). + поновне синхронизације 2026-09: измените основни документ → `npm run i18n:run -- --files=` (на нивоу одељка, јефтино). **Узима у обзир разлике, без ослањања на основно стање.** Пореди `en.json` у основи спајања са радним стаблом; за сваки кључ чија се енглеска вредност променила, сваки локалитет који и даље садржи -нетакнути превод сматра се застарелим. Ово намерно **замрзава већ постојећи дуг** — разлика -не може да открије из које је старе енглеске верзије настао дугогодишњи превод, па контрола оцењује -само оно што тренутна измена обухвата. Алтернатива (основно стање хеша за сваки кључ) захтевала би -генерисану датотеку од око 600 KB, 3× већу од највећег постојећег основног стања, која би се мењала при сваком i18n PR-у. +нетакнут превод сматра се застарелим. Ово намерно **замрзава постојећи дуг** — разлика +не може да открије из ког старог енглеског текста потиче дуготрајни превод, па контролни механизам процењује +само оно што тренутна измена дотиче. Алтернатива (основно стање хеша за сваки кључ) захтевала би +генерисану датотеку од ~600 KB, 3× већу од највећег постојећег основног стања, која би се мењала при сваком i18n PR-у. Постоје два начина да се услов испуни: 1. ажурирати обухваћене преводе или -2. поставити их на `__MISSING__:` — током извршавања се тада приказује исправљени енглески +2. поставити их на `__MISSING__:<нови енглески текст>` — окружење за извршавање тада испоручује исправљени енглески текст (`src/i18n/request.ts::deepMergeFallback`, #7258), а кључ се ставља у ред за превођење. Ако се променило **значење** ниске, пожељно је **преименовати кључ**: нови кључ не може да наследи -застарели превод. Тај образац је употребљен у #8463. +застарели превод. То је образац коришћен у #8463. ```bash -npm run i18n:check-value-drift # строго (оно што CI покреће) +npm run i18n:check-value-drift # строго (оно што CI извршава) npm run i18n:check-value-drift:warn # само извештај BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` @@ -234,45 +234,45 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift Завршава се кодом 0 уз `SKIP reason=base-unresolved` када основни каталог не може да се прочита (плитко клонирање без основне референце), по узору на `check-openapi-breaking`. -### Посао: `i18n` +### Задатак: `i18n` -Пуна матрица i18n провере (један посао по локалитету). Цео посао је саветодаван. +Пуна матрица i18n провере (један задатак по локалитету). Цео задатак је саветодаван. -| Скрипта | Проверава | Блокирање | -| ------------------------------- | ------------------------------- | -------------------------------------------------------- | -| `validate_translation.py quick` | Потпуност превода по локалитету | **Саветодавно** (`continue-on-error: true` за цео посао) | +| Скрипта | Проверава | Блокирање | +| ------------------------------- | ------------------------------- | ---------------------------------------------------------- | +| `validate_translation.py quick` | Потпуност превода по локалитету | **Саветодавно** (`continue-on-error: true` за цео задатак) | -### Посао: `pr-test-policy` +### Задатак: `pr-test-policy` -Покреће се само за захтеве за спајање. +Извршава се само за захтеве за повлачење. -| Скрипта | Проверава | Блокирање | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| `check:pr-test-policy` | PR-ови који мењају продукциони кôд у `src/`, `open-sse/`, `electron/` или `bin/` морају да укључе или ажурирају тестове (Строго правило #8) | Да | -| `check:test-masking` | Измењене датотеке тестова не смањују нето број провера нити додају таутологије `assert.ok(true)` | Да | -| `check:pr-evidence` | Тело PR-а наводи доказе из тестова/VPS-а за измену (аутоматизује Строго правило #18 претраживањем текста PR-а — непоуздано, видети Заостатак) | Да | +| Скрипта | Проверава | Блокирање | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | +| `check:pr-test-policy` | PR-ови који мењају продукциони кôд у `src/`, `open-sse/`, `electron/` или `bin/` морају да укључе или ажурирају тестове (строго правило #8) | Да | +| `check:test-masking` | Измењене тестне датотеке не смањују укупан нето број провера нити додају таутологије `assert.ok(true)` | Да | +| `check:pr-evidence` | Тело PR-а наводи доказе о тестирању/VPS-у за измену (аутоматизује строго правило #18 претрагом текста PR-а — крхко, видети Backlog) | Да | -### Посао: `test-vitest` +### Задатак: `test-vitest` -Покреће се након `build`. Блокира спајање у случају неуспеха. +Извршава се после `build`. У случају неуспеха блокира спајање. -| Пакет тестова | Проверава | Блокирање | -| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP сервер (110 алата), autoCombo, кеш — vitest покретач | Да | -| `test:vitest:ui` | Тестови UI компоненти — vitest покретач | **Блокира** — већ постојећи неуспеси су изричито изузети у `vitest.config.ts`; нови неуспеси обарају посао | +| Пакет тестова | Проверава | Блокирање | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP сервер (110 алата), autoCombo, кеш — vitest покретач | Да | +| `test:vitest:ui` | Тестови UI компоненти — vitest покретач | **Блокира** — постојећи неуспеси су изричито изузети у `vitest.config.ts`; нови неуспеси доводе до неуспеха задатка | ### Ноћни токови рада (заказани, саветодавни) -Покрећу се по cron распореду (и путем `workflow_dispatch`), никада за PR-ове. Сви су саветодавни. +Они се извршавају према cron распореду (и путем `workflow_dispatch`), никада за PR-ове. Сви су саветодавни. -| Ток рада | Проверава | Блокирање | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | fast-check тестове својстава са насумичним почетним семеном + великим бројем покретања | **Саветодавно** | -| `nightly-resilience` | контролу раста хипа, убризгавање хаотичних грешака, k6 тестове оптерећења/дуготрајног рада | **Саветодавно** | -| `nightly-llm-security` | promptfoo заштиту од убризгавања (режим блокирања) + garak сонде (прескачу се без тајне добављача) | **Саветодавно** | -| `nightly-schemathesis` | фузинг OpenAPI уговора (schemathesis) над активним OmniRoute-ом помоћу `docs/openapi.yaml` — открива кршења спецификације / необрађене грешке 500 (Фаза 8 B.4) | **Саветодавно** | -| `nightly-mutation` | Stryker резултат мутационог тестирања над брзом граном јединичних тестова — преживели мутанти откривају слабе провере | **Саветодавно** | -| `nightly-compat` | матрицу компатибилности Node механизма у свим подржаним опсезима `engines.node` | **Саветодавно** | +| Ток рада | Проверава | Блокирање | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `nightly-property` | fast-check тестове својстава са насумичним почетним параметром + великим бројем покретања | **Саветодавно** | +| `nightly-resilience` | контролу раста хипа, хаотично убризгавање грешака, k6 тестове оптерећења/издржљивости | **Саветодавно** | +| `nightly-llm-security` | promptfoo заштиту од убризгавања (режим блокирања) + garak сонде (прескачу се без тајне добављача) | **Саветодавно** | +| `nightly-schemathesis` | расплинуто тестирање OpenAPI уговора (schemathesis) над активним OmniRoute-ом помоћу `docs/openapi.yaml` — открива кршења спецификације / необрађене грешке 500 (фаза 8 B.4) | **Саветодавно** | +| `nightly-mutation` | резултат Stryker мутационог тестирања над брзом путањом јединичних тестова — преживели мутанти откривају слабе провере | **Саветодавно** | +| `nightly-compat` | матрицу компатибилности Node механизма за подржане опсеге `engines.node` | **Саветодавно** | --- @@ -536,7 +536,7 @@ CodeQL: Default → Advanced. Немојте додавати окидач `sche --- -## Заостатак рационализације (преглед ROI — фаза 9, талас 3) +## Заостатак рационализације (преглед ROI — Фаза 9 Талас 3) Овај инвентар је усклађен са `ci.yml` 2026-06-17 (претходна верзија је изоставила `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, @@ -549,30 +549,30 @@ CodeQL: Default → Advanced. Немојте додавати окидач `sche **Такође није документовано изнад** (саветодавно, слаб сигнал): посао `docs-lint` (markdownlint + Vale, цео посао има `continue-on-error`) и самостални токови рада скенера `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` се налази у -`quality-baseline.json`, али није повезан са блокирајућим прагом у `ci.yml` — метрика је +`quality-baseline.json`, али није повезан са блокирајућим механизмом постепеног пооштравања у `ci.yml` — метрика је тренутно неповезана. -### Спајање / уклањање дупликата (механички, мањи ризик) +### Спајање / уклањање дупликата (механички, нижи ризик) Сваки кандидат је проверен у односу на актуелно стање контролних механизама 2026-06-17 (веруј, али провери); -испоставило се да неколико „очигледних“ спајања скрива технички дуг и **нису** директне замене без додатних измена. +испоставило се да неколико „очигледних“ спајања прикрива технички дуг и **нису** непосредне замене без додатних измена. -- **`check:docs-sync` се покреће двапут** — самостално у послу `lint`, а затим поново унутар `check:docs-all` (`docs-sync-strict`) и husky pre-commit куке. ✅ **ЗАВРШЕНО** — самостално позивање у оквиру `lint` је уклоњено. -- **CVE скенирање** — ❌ **НИЈЕ чисто спајање.** `audit:deps` безусловно пада за сваки CVE високог/критичног нивоа; `check:vuln-ratchet` (osv) пада само при _регресији_ у односу на основну вредност (тренутно 1 MODERATE). Различита семантика — уклањањем `audit:deps` изгубила би се апсолутна контрола за високи/критични ниво. Задржати оба. -- **Откривање циклуса** — ❌ **НИЈЕ чисто спајање.** `check:circular-deps` (dpdm) пријављује **91 циклус** (због тога је саветодаван); не може постати блокирајући пре него што се они реше, а има и шири опсег од успешног, пажљиво одабраног `check:cycles`. Задржати `check:cycles` као блокирајући; решавање 91 dpdm циклуса представља засебну ставку заостатка. -- **Сложеност** — ✅ **ЗАВРШЕНО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): један ESLint пролаз, бројање по ruleId тако да основне вредности за цикломатску сложеност+максималан број линија и когнитивну сложеност остану независне; појединачне провере `check:complexity` / `check:cognitive-complexity` остају за локално покретање са `--update`. -- **Спречавање халуцинација за `/api`** — ✅ **ЗАВРШЕНО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): један FS инвентар директоријума `src/app/api`, openapi-routes + docs-symbols и даље извештавају независно; појединачне провере остају за локална покретања. -- **`check:node-runtime` се покреће у 11 послова** — ⚠️ **низак ROI.** Сваки се извршава на засебном покретачу, а провера траје <1s; укупна уштеда је ~10s, по цену губитка јефтине заштите по послу. Није вредно измена. -- **`typecheck:noimplicit:core` у CI lint-у** — ✅ **уклоњен из посла lint** (био је саветодаван са `continue-on-error`); блокирајућу површину типова чине `typecheck:core` + `check:type-coverage`. Локална скрипта је задржана. +- **`check:docs-sync` се покреће два пута** — самостално у послу `lint`, а затим поново унутар `check:docs-all` (`docs-sync-strict`) и husky pre-commit hook-а. ✅ **ЗАВРШЕНО** — самостално позивање у `lint` је уклоњено. +- **CVE скенирање** — ❌ **НИЈЕ чисто спајање.** `audit:deps` завршава неуспехом при било ком CVE-у високог/критичног нивоа; `check:vuln-ratchet` (osv) завршава неуспехом само при _регресији_ у односу на полазну вредност (тренутно 1 MODERATE). Различита семантика — уклањањем `audit:deps` изгубио би се апсолутни контролни механизам за висок/критичан ниво. Задржати оба. +- **Откривање циклуса** — ✅ **ЗАВРШЕНО** (#15159 G-01/G-02). Стари текст је овде називао `check:cycles` „зеленим, ручно одабраним“ контролним механизмом и оправдавао задржавање његовог блокирајућег статуса тиме што је `check:circular-deps` (dpdm) пријављивао 91 циклус. То зелено стање било је **лажно зелено**: `check:cycles` је скенирао 5 потдиректоријума (450 датотека), препознавао само статички образац `import|export … from` и одбацивао сваки спецификатор `@/` и `@omniroute/open-sse/`, па није могао да уочи циклусе динамичког увоза и алијаса који су доминирали репозиторијумом. Исправљено: контролни механизам сада обилази `src` + `open-sse` (5023 датотеке), прикупља спецификаторе из TypeScript AST-а (тако да се `import("…")` рачуна, док се `typeof import("…")` на позицији типа не рачуна) и разрешава `paths` из tsconfig-а. Проналази **14** циклуса, а не 0. Пошто 14 постојећих циклуса не може да се исправи у PR-у за контролни механизам, `check:cycles` је сада механизам **постепеног пооштравања** (`--ratchet`, горња граница `metrics.cycles.value = 14` у `quality-baseline.json`, `direction: down`) — блокира сваку _регресију_, а број може само да опада. CI покреће `npm run check:cycles:ratchet`. Постепено смањивање се спроводи у оквиру **A-01**. `check:circular-deps` (dpdm) остаје саветодаван као шире друго мишљење. +- **Сложеност** — ✅ **ЗАВРШЕНО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): један ESLint пролаз, бројање по ruleId-у како би полазне вредности за цикломатску сложеност+максималан број редова и когнитивну сложеност остале независне; појединачни `check:complexity` / `check:cognitive-complexity` остају за локални `--update`. +- **`/api` заштита од халуцинација** — ✅ **ЗАВРШЕНО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): један FS инвентар за `src/app/api`, openapi-routes + docs-symbols и даље извештавају независно; појединачне провере остају за локална покретања. +- **`check:node-runtime` се покреће у 11 послова** — ⚠️ **низак ROI.** Сваки се извршава на засебном runner-у, а провера траје <1s; укупна уштеда је ~10s, уз губитак јефтине заштите по послу. Није вредно ремећења. +- **`typecheck:noimplicit:core` у CI lint-у** — ✅ **уклоњено из lint посла** (било је саветодавно уз `continue-on-error`); блокирајућу површину типова чине `typecheck:core` + `check:type-coverage`. Локална скрипта је задржана. ### Променити статус / одлучити (политика оператера) -- `check:openapi-security-tiers` (саветодавно) — ❌ **НИЈЕ могуће чисто пребацити.** Завршава се кодом 0, али упозорава да неколико `traffic-inspector` рута под `LOCAL_ONLY_API_PREFIXES` нема анотацију `x-loopback-only: true`. Његово спровођење најпре захтева додавање тих анотација у `openapi.yaml`. -- `typecheck:noimplicit:core` (саветодавно) — у великој мери га обухвата блокирајући праг `check:type-coverage`. Пребацити га на праг или уклонити сувишни други `tsc` пролаз. -- `test:vitest:ui` (сада **блокирајући**) — раније постојећи неуспеси су изричито искључени у `vitest.config.ts` помоћу коментара за праћење `// #8618`; нови неуспеси обарају посао. -- `check:secrets` (gitleaks, блокирајући праг замрзнут на 3 документована лажно позитивна резултата) — додати та 3 резултата на листу дозвољених како би се достигла 0, или спустити проверу на саветодавни ниво. Преклапа се са GitHub-овим изворним скенирањем тајни + `check:public-creds`. -- `check:pr-evidence` (блокирајући, претражује прозни текст тела PR-а) — висок ризик од лажно позитивних резултата; уклањање слаби спровођење строгог правила бр. 18, па је ово стварна одлука о политици. -- `semgrep` (саветодавни самостални ток) — преклапа се са CodeQL-ом за OWASP породице; повезати његову основну вредност са прагом или га уклонити. +- `check:openapi-security-tiers` (саветодавно) — ❌ **НИЈЕ могуће чисто променити статус.** Завршава се кодом 0, али упозорава да неколико `traffic-inspector` рута под `LOCAL_ONLY_API_PREFIXES` нема анотацију `x-loopback-only: true`. Његово наметање прво захтева додавање тих анотација у `openapi.yaml`. +- `typecheck:noimplicit:core` (саветодавно) — у великој мери је обухваћено блокирајућим механизмом постепеног пооштравања `check:type-coverage`. Претворити га у механизам постепеног пооштравања или уклонити сувишни други `tsc` пролаз. +- `test:vitest:ui` (сада **блокирајуће**) — постојећи неуспеси су изричито изузети у `vitest.config.ts` уз коментаре за праћење `// #8618`; нови неуспеси обарају посао. +- `check:secrets` (gitleaks, блокирајући механизам постепеног пооштравања замрзнут на 3 документована лажно позитивна резултата) — додати та 3 резултата на листу дозвољених како би се достигла 0 или спустити статус на саветодавни. Преклапа се са GitHub-овим уграђеним скенирањем тајни + `check:public-creds`. +- `check:pr-evidence` (блокирајуће, претражује прозни текст PR-а) — висок ризик од лажно позитивних резултата; уклањање слаби спровођење строгог правила бр. 18, па је ово стварна одлука о политици. +- `semgrep` (саветодаван, самосталан) — преклапа се са CodeQL-ом за OWASP породице; повезати његову полазну вредност са механизмом постепеног пооштравања или га уклонити. --- diff --git a/docs/i18n/sv/CONTRIBUTING.md b/docs/i18n/sv/CONTRIBUTING.md index f56ed565dc9..0b5c8631127 100644 --- a/docs/i18n/sv/CONTRIBUTING.md +++ b/docs/i18n/sv/CONTRIBUTING.md @@ -389,20 +389,20 @@ Skriv enhetstester i `tests/unit/` som minst omfattar: ## Checklista för pull request -- [ ] Tester godkänns (`npm test`) -- [ ] Lintning godkänns (`npm run lint`) +- [ ] Testerna godkänns (`npm test`) +- [ ] Lintningen godkänns (`npm run lint`) - [ ] Bygget lyckas (`npm run build`) - [ ] TypeScript-typer har lagts till för nya publika funktioner och gränssnitt - [ ] Inga hårdkodade hemligheter eller reservvärden -- [ ] Publika autentiseringsuppgifter för uppströmsresurser bäddas in via `resolvePublicCred()` (se [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), aldrig som literaler -- [ ] Felsvar dirigeras via `buildErrorBody()` / `sanitizeErrorMessage()` — inga råa stackspårningar i svarskroppar (se [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Skalkommandon (`exec` / `spawn`) skickar värden vid körning via `env`, inte via stränginterpolering +- [ ] Publika autentiseringsuppgifter för uppströmskällor bäddas in via `resolvePublicCred()` (se [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), aldrig som literaler +- [ ] Felsvar hanteras via `buildErrorBody()` / `sanitizeErrorMessage()` — inga råa stackspårningar i svarskroppar (se [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Skalkommandon (`exec` / `spawn`) skickar körtidsvärden via `env`, inte via stränginterpolering - [ ] Alla indata valideras med Zod-scheman -- [ ] Ett **fragment** för ändringsloggen har lagts till under `changelog.d/{features|fixes|maintenance}/-.md` för användarsynliga ändringar (se [`changelog.d/README.md`](./changelog.d/README.md)) — redigera **inte** `CHANGELOG.md` direkt; fragment sammanställs vid lansering och orsakar aldrig konflikter mellan pull requests +- [ ] Ett **fragment** för ändringsloggen har lagts till under `changelog.d/{features|fixes|maintenance}/-.md` för användarsynliga ändringar (se [`changelog.d/README.md`](./changelog.d/README.md)) — redigera **inte** `CHANGELOG.md` direkt; fragmenten sammanställs vid lansering och orsakar aldrig konflikter mellan pull requests - [ ] Dokumentationen har uppdaterats (om tillämpligt) -- [ ] Inga nya CodeQL-varningar eller varningar från hemlighetsskanning har skapats, alternativt har var och en avfärdats med en teknisk motivering som hänvisar till relevant dokument i `docs/security/` -- [ ] Rutter som startar underprocesser (`/api/mcp/`, `/api/cli-tools/runtime/`) har klassificerats som `isLocalOnlyPath()` i `src/server/authz/routeGuard.ts` — se [hård regel nr 15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Inga `Co-Authored-By`-slutrader i commit-meddelanden — commits måste visas enbart under databasägarens Git-identitet (hård regel nr 16) +- [ ] Inga nya CodeQL-/Secret-Scanning-varningar har skapats, eller så har var och en avfärdats med en teknisk motivering som hänvisar till relevant dokument under `docs/security/` +- [ ] Rutter som startar underordnade processer (`/api/mcp/`, `/api/cli-tools/runtime/`) har klassificerats som `isLocalOnlyPath()` i `src/server/authz/routeGuard.ts` — se [Hård regel nr 15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Inga `Co-authored-by`-trailrar för AI/botar i commit-meddelanden (Hård regel nr 16) — mänskliga medarbetare vars arbete återanvänds krediteras med vanliga `Co-authored-by: Name `-trailrar --- diff --git a/docs/i18n/sv/docs/architecture/QUALITY_GATES.md b/docs/i18n/sv/docs/architecture/QUALITY_GATES.md index 5e3403912c3..15787e8015e 100644 --- a/docs/i18n/sv/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/sv/docs/architecture/QUALITY_GATES.md @@ -15,27 +15,27 @@ plan för att replikera samma system finns i --- -## Inventering av grindar och körningsprofiler +## Inventering av kontrollsteg och körningsprofiler ### Godkännande av kandidater -Arbetsflödena CI och Quality Gates avger varsitt stabilt utfall: `Gate / CI` och -`Gate / Quality`. Deras versionshanterade godkännandepolicy anger varje uppströmsjobb +Arbetsflödena CI och Quality Gates avger vart och ett ett stabilt utfall: `Gate / CI` och +`Gate / Quality`. Deras versionshanterade godkännandepolicy listar varje uppströmsjobb som obligatoriskt eller rådgivande. Ett tillämpligt obligatoriskt jobb måste lyckas: saknade, avbrutna, överhoppade, väntande och okända resultat kan inte fastställa PASS. En giltig -klassificering som endast dokumentation eller endast katalog kan göra ett kodspår ej tillämpligt; -ett utkast till PR godtas inte som kandidat. En `hotfix`-etikett innebär inte att beviskraven frångås. - -Båda arbetsflödena omfattar PR:er och pushar till main-/release-grenar, manuell körning och -merge-group-händelser. Push, manuell körning och merge-group kör hela urvalet. Förgreningar -och merge-grupper använder värdbaserade körmiljöer för jobb som annars väljer lokalt driftade -körmiljöer; tillräcklig värdbaserad kapacitet måste verifieras före utrullning. - -Varje JSON-kvitto identifierar utcheckad SHA, arbetsflödeskörning och försök. -CLI:t avvisar om SHA för utcheckning och händelse inte matchar. Arbetsflödestester binder policymedlemskap -till utfallsjobbets `needs`-lista så att ett nytt eller borttaget spår inte kan försvinna obemärkt. -Kvittona omfattar det egna arbetsflödet, inte publicering, driftsättning eller de interna delarna -av en befintlig rådgivande skanner. Att aktivera båda kontrollnamnen i grenreglerna är en +klassificering som enbart dokumentation eller enbart katalog kan göra ett kodspår ej tillämpligt; +en PR i utkastläge är inte en godkänd kandidat. Etiketten `hotfix` innebär inte att beviskrav frångås. + +Båda arbetsflödena omfattar PR:er och pushar till main/release-grenar, manuell start och +merge-group-händelser. Push, manuell start och merge-group kör hela urvalet. Forkar +och merge groups använder värdbaserade runners för jobb som annars väljer självhanterade +runners; tillräcklig värdbaserad kapacitet måste verifieras före utrullning. + +Varje JSON-kvitto identifierar utcheckad SHA, arbetsflödeskörning och körningsförsök. +CLI-verktyget avvisar om SHA för utcheckning och händelse inte matchar. Arbetsflödestester binder policymedlemskap +till utfallsjobbets `needs`-lista så att ett nytt eller borttaget spår inte obemärkt kan försvinna. +Kvittona omfattar det egna arbetsflödet, inte publicering, driftsättning eller den interna funktionen +hos en befintlig rådgivande skanner. Att aktivera båda kontrollnamnen i grenregler är en separat administrativ ändring; att lägga till dessa jobb skyddar inte i sig en gren. ### Inventering av statisk skanning @@ -43,45 +43,45 @@ separat administrativ ändring; att lägga till dessa jobb skyddar inte i sig en Den versionshanterade inventeringen av npm-alias och medlemskapet för statisk skanning finns i `config/quality/gate-manifest.json`. Kör `npm run check:gate-manifest` för att validera skriptnamn och exakta kommandon mot `package.json`; tillägg, borttagningar och -kommandoavvikelser gör att både den lokala kroken och jobb för ändringsklassificering i CI misslyckas. +kommandoavvikelser gör att både den lokala hooken och ändringsklassificeringsjobben i CI misslyckas. Ett alias är inte ett arbetsflödesjobb, en matrisinstans eller ett testfall: dessa antal får inte framställas som utbytbara. Använd `npm run quality:scan -- --list` eller `npm run quality:scan:fast -- --list` -för att granska de valda aliasen utan att köra dem. Körmiljön anropar -npm-startpunkten, så dess exekveringsmiljö (inklusive Bun där det konfigurerats) bevaras. +för att inspektera valda alias utan att köra dem. Runnern anropar +npm-startpunkten, så dess exekveringsmiljö (inklusive Bun där det är konfigurerat) bevaras. Manifestet registrerar alias utanför dessa profiler som separat anropade, och underhållskommandon är förbjudna i skrivskyddade skanningsprofiler. Dessa profiler omfattar endast den statiska skanningen. De certifierar inte produkttester, -täckning, paketering, externa kontroller eller en kandidats fullständiga releasegodkännande. -Godkännande i arbetsflödet använder länkade `config/quality/admission-policy.json` och -`scripts/quality/admission-verdict.mjs`. Profiler för releaseövervakning förblir separata; -granska deras tillämpliga kontroller och kvitton oberoende av varandra. Textinventeringen -nedan är en referens, inte ett bevis på att en grind faktiskt kördes. +täckning, paketering, externa kontroller eller en kandidats fullständiga versionsgodkännande. +Arbetsflödets godkännande använder den länkade `config/quality/admission-policy.json` och +`scripts/quality/admission-verdict.mjs`. Profiler för versionsövervakning förblir separata; +inspektera deras tillämpliga kontroller och kvitton oberoende. Textinventeringen +nedan är en referens, inte ett bevis på att ett kontrollsteg faktiskt kördes. -Skript finns under `scripts/check/` (policygrindar) och `scripts/quality/` (ratchet-motor). +Skript finns under `scripts/check/` (policykontroller) och `scripts/quality/` (ratchet-motor). Sanningskällan för CI är `.github/workflows/ci.yml`. -### Snabbspår för release-PR (`quality.yml`) +### Snabbspår för versions-PR (`quality.yml`) -`.github/workflows/quality.yml` kompletterar CI för PR:er mot main-/release-grenar, pushar till -skyddade grenar, manuella körningar och merge-grupper. PR:er använder sökvägsfiltrerade snabbkontroller. Det permanent -inaktiverade duplicerade bygget har tagits bort; de riktiga kontrollerna för bygge/paketering/uppstart finns kvar i CI. +`.github/workflows/quality.yml` kompletterar CI för PR:er mot main/release, pushar till skyddade grenar, +manuell start och merge groups. PR:er använder sökvägsfiltrerade snabbkontroller. Det permanent +inaktiverade duplicerade bygget har tagits bort; de verkliga kontrollerna för bygge/paketering/uppstart finns kvar i CI. -| Jobb | Omfattning | Blockerande | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `Docs Gates (fast-path)` | Dokumentations-/kod-PR:er; referenser i API-dokumentation och all dokumentation | Ja | -| `Fast Quality Gates` | Kod-PR:er; statiska kontroller, typkontroll, typkontroll av kontrollpanelen, påverkade enhetstester | Ja | -| `Forgotten sibling tests` | Kod-PR:er; ändrade moduler spåras till statiska konsumenter och möjliga syskontroller; sökvägar via samlingsfiler och dynamisk import rapporteras som rådgivande diagnostik, med refererade undantag i tillåtelselistan | **Rådgivande** | -| `Vitest (fast-path)` | Kod-PR:er; snabb Vitest-svit | Ja | -| `Unit Tests fast-path` | Kod-PR:er; enhetstestsvit med 4 shards | Ja | -| `No new ESLint warnings` | Kod-PR:er; undertryckningsmedvetet lint-skydd | Ja, inklusive förgreningar | -| `Merge integrity (changelog + generated skills)` | PR:er som inte är utkast; synkronisering av ändringslogg och genererade färdigheter | Ja, inklusive förgreningar | +| Job | Omfattning | Blockerande | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| `Docs Gates (fast-path)` | Dokumentations-/kod-PR:er; referenser i API-dokumentation och docs-all | Ja | +| `Fast Quality Gates` | Kod-PR:er; statiska kontroller, typkontroll, typkontroll av dashboard, påverkade enhetstester | Ja | +| `Forgotten sibling tests` | Kod-PR:er; ändrade moduler spåras till statiska konsumenter och möjliga syskontroller; barrel- och dynamic-import-sökvägar rapporteras som rådgivande diagnostik, med refererade undantag i tillåtelselistan | **Rådgivande** | +| `Vitest (fast-path)` | Kod-PR:er; snabb Vitest-svit | Ja | +| `Unit Tests fast-path` | Kod-PR:er; enhetstestsvit med 4 shards | Ja | +| `No new ESLint warnings` | Kod-PR:er; undertryckningsmedveten lint-kontroll | Ja, inklusive forkar | +| `Merge integrity (changelog + generated skills)` | PR:er som inte är utkast; synkronisering av ändringslogg och genererade skills | Ja, inklusive forkar | -#### Rapport om glömda syskontroller +#### Rapport över bortglömda syskontroller -`npm run check:forgotten-sibling-tests` återanvänder importmatcharen bakom kartan över testpåverkan. +`npm run check:forgotten-sibling-tests` återanvänder importlösaren bakom kartan över testpåverkan. För varje ändrad produktionsmodul rapporterar den deterministiska kedjor av typen `ändrad modul/symbol -> statisk konsument -> möjlig syskontroll` när den möjliga kontrollen saknas i pull request-diffen. Markdown-sammanfattningen och JSON-resultatet bevaras som @@ -89,138 +89,138 @@ arbetsflödesartefakten `forgotten-sibling-tests` för kalibrering före en even Barrel-återexporter och dynamiska importer används endast för upplösningsdiagnostik; de skapar aldrig ett blockerande fynd. Granskade undantag finns i -`config/quality/forgotten-sibling-allowlist.json`. Varje post måste ange konsumenten och det föreslagna -testet, ge en specifik motivering och länka till ett GitHub-ärende eller en pull request. Felaktiga poster -avvisas. Undantag kan inte undertrycka ett borttaget föreslaget test eller en diff som lägger till `.skip`/`.todo`; -försvagning av kontroller och annan maskering hanteras fortsatt av den oberoende blockerande -`check:test-masking`-kontrollen. +`config/quality/forgotten-sibling-allowlist.json`. Varje post måste ange konsumenten och det möjliga +testet, ge en specifik motivering och länka till ett GitHub-ärende eller en pull request. Felaktigt utformade poster leder +till blockering. Undantag kan inte undertrycka ett borttaget möjligt test eller en diff som lägger till `.skip`/`.todo`; +försvagning av assertioner och annan maskering hanteras fortsatt av den oberoende blockerande +`check:test-masking`-grinden. ### Jobb: `lint` Körs för varje PR till `main`. Blockerar sammanslagning vid fel. -| Skript (`npm run ...`) | Validerar | Blockerande | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Node.js-versionen ligger inom det intervall som stöds | Ja | -| `check:cycles` | Cirkulära importer — alla moduler i `src/` + `open-sse/` | Ja | -| `check:route-validation:t06` | Zod-scheman finns för alla routes (policy för nivå 6) | Ja | -| `check:any-budget:t11` | Antalet `@ts-expect-error // any` överskrider inte budgeten (nivå 11-spärr) | Ja | -| `check:provider-consistency` | Varje leverantör i `providers.ts` har en motsvarande post i `providerRegistry.ts` (och vice versa, inom tillåtelselistan) | Ja | -| `check:model-lifecycle` | De tre manuellt underhållna routningstabellerna förblir konsekventa med den incheckade livscykelögonblicksbilden (#11503): `FITNESS_TABLE` (`taskFitness.ts`) poängsätter inget utfasat id som `REGISTRY` kan routa; varje mål för `BUILT_IN_ALIASES` finns i `REGISTRY` och saknas i ögonblicksbilden över utfasade id:n; varje utfasat id som fortfarande finns i `REGISTRY` vidarebefordras eller listas i `allowedRetiredInCatalog`; och varken källor eller mål i `DEFAULT_DEGRADATION_MAP` förekommer som utfasade i den ögonblicksbilden. Detta bevisar inte att en modell för närvarande tillhandahålls av en aktiv uppströmsleverantör. Offline — jämför med `config/quality/model-lifecycle.json`, som uppdateras manuellt med `npm run quality:refresh-model-lifecycle` (nätverk; inte integrerat i CI). `allowedRetiredInCatalog` är en stegvis avvecklingsspärr: lägg endast till en post med ett spårningsärende. | Ja | -| `check:fetch-targets` | Varje `fetch("/api/...")` i `src/` på klientsidan leder till en faktisk `route.ts` | Ja | -| `check:deps` | Alla beroenden som kan installeras med `npm install` i varje `package.json` i kodförrådet finns i `dependency-allowlist.json`; nya ofästa eller felskrivningskapade paket flaggas | Ja | -| `audit:deps` | `npm audit` (rot + Electron) — inga allvarliga/kritiska säkerhetsmeddelanden (överlappar OSV-kontrollen `check:vuln-ratchet`; se rationaliseringsbackloggen) | Ja | -| `check:lockfile` | Integriteten för `package-lock.json` — HTTPS-register, integritetshashar, inga värdåsidosättningar | Ja | -| `check:licenses` | SPDX-licenstillåtelselista för produktionsberoenden | Ja | -| `check:tracked-artifacts` | Inga byggartefakter/incheckade symboliska länkar till `node_modules` (körs även i husky pre-commit; pre-push är avsiktligt lättviktig — #6716) | Ja | -| `check:ai-attribution` | Ingen AI-/bot-`Co-Authored-By`-trailer eller AI-genererad sidfot i PR-commits, titel eller beskrivning — hård regel #16 (i snabbslingan i `quality.yml` för PR→`release/**` — läser händelsens nyttolast, gör inget utanför PR:er — samt ett steg endast för PR:er i lint-jobbet i `ci.yml` för PR→`main`; även husky-hooken `commit-msg`; mänskliga medförfattare är tillåtna; #14436) | -| `check:vitest-exclusions` | Varje Vitest-undantag anger ett spårningsärende och finns i `config/quality/vitest-exclusions.json` (#13204) | Ja | -| `check:file-size` | Ingen källfil överskrider gränsen för respektive filändelse (spärr: frysta stora filer i listan `frozen`) | Ja | -| `check:error-helper` | Felsvar i exekverare/hanterare använder `buildErrorBody()`/`sanitizeErrorMessage()` (hård regel #12) | Ja | -| `check:migration-numbering` | SQL-migreringsfiler är sekventiellt numrerade, utan luckor eller dubbletter | Ja | -| `check:public-creds` | Inga literala OAuth-`client_id`/`client_secret`-värden eller Firebase-webbnycklar utanför `publicCreds.ts` (strikt regel nr 11) | Ja | -| `check:db-rules` | Ingen rå SQL utanför modulerna i `src/lib/db/`; inga barrel-importer från `localDb.ts` (strikta regler nr 2/nr 5) | Ja | -| `check:known-symbols` | Provider-exekverare, routningsstrategier och översättare som är registrerade i sina dispatch-tabeller matchar filerna på disk — inga föräldralösa eller odeklarerade symboler | Ja | -| `check:route-guard-membership` | Varje route som startar en underordnad process klassificeras av `isLocalOnlyPath()` (strikta regler nr 15/nr 17) | Ja | -| `check:test-discovery` | Varje `*.test.ts`- eller `*.spec.ts`-fil i repot samlas in av minst en test runner (spärrmekanism: listan över föräldralösa filer i `test-discovery-baseline.json` kan endast krympa) | Ja | -| `check:agent-skills-sync` | Genererade agent-skills-artefakter matchar sin källkatalog (ingen avvikelse) | -| `check:provider-asset-provenance` | Leverantörslogotyper/-resurser har en registrerad provenienspost | -| `lint:json` | JSON-konfigurationsfiler kan tolkas och uppfyller repo-lintreglerna | -| `typecheck:core` | TypeScript-kompilering utan fel (endast rådgivande varningar) | Ja | -| `typecheck:noimplicit:core` | Strikt `noImplicitAny` — framåtblickande; många befintliga anropsplatser behöver fortfarande annoteringar | **Rådgivande** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` begränsad till `src/app/(dashboard)/**` (#7033) — den kuraterade listan med 27 tillåtna filer i `typecheck:core` omfattar ingen TSX för instrumentpanelen, och `next build` typkontrollerar den inte heller (`next.config.mjs` anger `ignoreBuildErrors: true`), så regressioner med fristående identifierare där (#6625/#6909) var osynliga för CI. Jämför mot en fryst baslinje för antal per fil/per TS-kod (`config/quality/dashboard-typecheck-baseline.json`, samma mönster för kontroll av inaktualitet som `check:known-symbols`) — endast NYA fel utöver det baslinjedefinierade antalet gör att kontrollen misslyckas; skruva ned baslinjen med `--update` när ett befintligt fel åtgärdas. | Ja | +| Skript (`npm run ...`) | Validerar | Blockerande | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | +| `check:node-runtime` | Node.js-versionen ligger inom det intervall som stöds | Ja | +| `check:cycles` | Cirkulära importer i hela `src/` + `open-sse/` (AST-baserat, `paths` i tsconfig löses upp). Utan argument = rådgivande, listar cyklerna. `check:cycles:ratchet` (det som CI kör) blockerar när antalet överstiger taket `metrics.cycles` i `quality-baseline.json` — för närvarande 14, `direction: down`, så det kan bara minska (#15159 G-01/G-02) | Ja (ratchet) | +| `check:route-validation:t06` | Zod-scheman finns på alla rutter (policy för nivå 6) | Ja | +| `check:any-budget:t11` | Antalet `@ts-expect-error // any` överskrider inte budgeten (catraca för nivå 11) | Ja | +| `check:provider-consistency` | Varje leverantör i `providers.ts` har en motsvarande post i `providerRegistry.ts` (och vice versa, inom tillåtelselistan) | Ja | +| `check:model-lifecycle` | De tre manuellt underhållna routningstabellerna förblir konsekventa med den incheckade livscykelögonblicksbilden (#11503): `FITNESS_TABLE` (`taskFitness.ts`) poängsätter inget utfasat id som `REGISTRY` kan routa; varje mål för `BUILT_IN_ALIASES` finns i `REGISTRY` och saknas i ögonblicksbilden över utfasade id:n; varje utfasat id som fortfarande finns i `REGISTRY` vidarebefordras eller listas i `allowedRetiredInCatalog`; och ingen källa eller destination i `DEFAULT_DEGRADATION_MAP` visas som utfasad i den ögonblicksbilden. Detta bevisar inte att en modell för närvarande tillhandahålls av en aktiv uppströmsleverantör. Offline — jämför mot `config/quality/model-lifecycle.json`, som uppdateras manuellt med `npm run quality:refresh-model-lifecycle` (nätverk; inte inkopplat i CI). `allowedRetiredInCatalog` är en stegvis avvecklingsspärr: lägg endast till en post med ett spårningsärende. | Ja | +| `check:fetch-targets` | Varje `fetch("/api/...")` i `src/` på klientsidan matchar en faktisk `route.ts` | Ja | +| `check:deps` | Alla beroenden som kan installeras med `npm install` i varje `package.json` i kodförrådet finns i `dependency-allowlist.json`; nya ofästa eller felskrivningskapade paket flaggas | Ja | +| `audit:deps` | `npm audit` (rot + electron) — inga varningar med hög/kritisk allvarlighetsgrad (överlappar osv `check:vuln-ratchet`; se rationaliseringslistan) | Ja | +| `check:lockfile` | Integritet för `package-lock.json` — https-register, integritetshashar, inga värdåsidosättningar | Ja | +| `check:licenses` | SPDX-licenstillåtelselista för produktionsberoenden | Ja | +| `check:tracked-artifacts` | Inga byggartefakter/incheckade symboliska länkar till `node_modules` (körs även i huskys pre-commit; pre-push är avsiktligt lättviktig — #6716) | Ja | +| `check:ai-attribution` | Ingen AI-/bot-`Co-Authored-By`-trailer eller AI-genererad sidfot i PR-commits, titel eller beskrivning — hård regel #16 (i `quality.yml`:s fast-gates-loop för PR→`release/**` — läser händelsens nyttolast, gör inget utanför PR:er — samt ett PR-specifikt steg i `ci.yml`:s lint för PR→`main`; även huskys `commit-msg`-hook; mänskliga medförfattare tillåts; #14436) | +| `check:vitest-exclusions` | Varje Vitest-undantag anger ett spårningsärende och finns i `config/quality/vitest-exclusions.json` (#13204) | Ja | +| `check:file-size` | Ingen källkodsfil överskrider gränsen per filändelse (spärrmekanism: frysta stora filer i listan `frozen`) | Ja | +| `check:error-helper` | Felsvar i exekverare/hanterare använder `buildErrorBody()`/`sanitizeErrorMessage()` (hård regel #12) | Ja | +| `check:migration-numbering` | SQL-migreringsfiler är sekventiellt numrerade, utan luckor eller dubbletter | Ja | +| `check:public-creds` | Inga bokstavliga OAuth-värden för `client_id`/`client_secret` eller Firebase Web-nycklar utanför `publicCreds.ts` (Hård regel #11) | Ja | +| `check:db-rules` | Ingen rå SQL utanför modulerna i `src/lib/db/`; inga barrel-importer från `localDb.ts` (Hårda regler #2/#5) | Ja | +| `check:known-symbols` | Provider-exekverare, routningsstrategier och översättare som är registrerade i sina dispatch-tabeller matchar filerna på disken – inga föräldralösa eller odeklarerade symboler | Ja | +| `check:route-guard-membership` | Varje route som startar en underordnad process klassificeras av `isLocalOnlyPath()` (Hårda regler #15/#17) | Ja | +| `check:test-discovery` | Varje `*.test.ts`- / `*.spec.ts`-fil i repot samlas in av minst en testkörare (spärrmekanism: listan över föräldralösa filer i `test-discovery-baseline.json` kan bara krympa) | Ja | +| `check:agent-skills-sync` | Genererade agent-skills-artefakter matchar sin källkatalog (ingen avvikelse) | +| `check:provider-asset-provenance` | Leverantörslogotyper/-resurser har en registrerad provenienspost | +| `lint:json` | JSON-konfigurationsfiler kan tolkas och uppfyller repositoriets lintregler | +| `typecheck:core` | TypeScript-kompilering utan fel (endast rådgivande varningar) | Ja | +| `typecheck:noimplicit:core` | Strikt `noImplicitAny` — framåtblickande; många befintliga anropsställen behöver fortfarande annoteringar | **Rådgivande** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` begränsat till `src/app/(dashboard)/**` (#7033) — den handplockade tillåtelselistan med 27 filer i `typecheck:core` inkluderar inga TSX-filer för instrumentpanelen, och `next build` typkontrollerar dem inte heller (`next.config.mjs` anger `ignoreBuildErrors: true`), så regressioner med övergivna identifierare där (#6625/#6909) var osynliga för CI. Jämför mot en fryst baslinje över antalet fel per fil och TS-kod (`config/quality/dashboard-typecheck-baseline.json`, samma mönster för kontroll av inaktualitet som `check:known-symbols`) — endast NYA fel utöver baslinjens antal gör att kontrollen misslyckas; sänk stegvis med `--update` när ett befintligt fel har åtgärdats. | Ja | ### Jobb: `quality-gate` Körs efter `test-coverage`. Blockerar sammanslagning vid fel. -| Skript | Validerar | Blockerande | -| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | Genererar `quality-metrics.json` (antal ESLint-varningar, täckning från sammanslagen shard-rapport) | Ja (före ratchet-steget) | -| `quality:ratchet` | Inget mätvärde i `quality-baseline.json` har försämrats (ESLint-varningar ≤ baslinje; täckning ≥ baslinje) | Ja | -| `check:duplication` | Kodduplicering (jscpd@4) överskrider inte baslinjen i `quality-baseline.json` | Ja | -| `check:complexity` | Cyklomatisk komplexitet på filnivå överskrider inte gränsen (ESLint-kärnreglerna `complexity` + `max-lines-per-function`) | Ja | -| `check:cognitive-complexity` | Ratchet för kognitiv komplexitet (`eslint-plugin-sonarjs`) — separat ESLint-körning; CI kör båda sammanslagna som det enda steget `check:complexity-ratchets` | Ja | -| `check:dead-code` | Ratchet för oanvända exporter/filer (knip) försämras inte jämfört med baslinjen | Ja | -| `check:compression-budget` | Budget för komprimeringsbenchmark — miniminivåerna för tokenbesparingar per motor får inte försämras | Ja | -| `check:type-coverage` | Ratchet för procentandel typad kod (`type-coverage`) försämras inte; ersätter till stor del `typecheck:noimplicit:core` | Ja | -| `check:codeql-ratchet` | Antalet öppna CodeQL-varningar försämras inte (läses via `gh api`; hoppas över utan fel om token saknas) — uppdateringsfrekvens och manuell utlösning: se "CodeQL-ratchet" nedan | Ja | +| Skript | Validerar | Blockerande | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | Skapar `quality-metrics.json` (antal ESLint-varningar, täckning från den sammanslagna shard-rapporten) | Ja (före ratchet-steget) | +| `quality:ratchet` | Varje mätvärde i `quality-baseline.json` har inte försämrats (ESLint-varningar ≤ baslinjen; täckning ≥ baslinjen) | Ja | +| `check:duplication` | Kodduplicering (jscpd@4) överskrider inte baslinjen i `quality-baseline.json` | Ja | +| `check:complexity` | Cyklomatisk komplexitet på filnivå överskrider inte gränsen (ESLint-kärnans `complexity` + `max-lines-per-function`) | Ja | +| `check:cognitive-complexity` | Ratchet för kognitiv komplexitet (`eslint-plugin-sonarjs`) — separat ESLint-körning; CI kör båda sammanslagna som det enda steget `check:complexity-ratchets` | Ja | +| `check:dead-code` | Ratchet för oanvända exporter/filer (knip) försämras inte jämfört med baslinjen | Ja | +| `check:compression-budget` | Budget för komprimeringsbenchmark — minimikraven för tokenbesparingar per motor får inte försämras | Ja | +| `check:type-coverage` | Ratchet för procentandel typad kod (`type-coverage`) försämras inte; ersätter till stor del `typecheck:noimplicit:core` | Ja | +| `check:codeql-ratchet` | Antalet öppna CodeQL-varningar försämras inte (läses via `gh api`; hoppas över utan fel om token saknas) — uppdateringsfrekvens och manuell utlösare: se "CodeQL-ratchet" nedan | Ja | ### Jobb: `quality-extended` Hela jobbet är rådgivande (`continue-on-error: true`). De npm-baserade ratchet-kontrollerna körs -på riktigt; de externa skannrarna installeras via `gh release download` och hoppar över sig själva (exit 0) +på riktigt; de externa skannrarna installeras via `gh release download` och hoppar själva över körningen (exit 0) när en binärfil fortfarande saknas. -| Skript | Validerar | Blockerande | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:circular-deps` | Inga cirkulära beroenden (dpdm) | **Rådgivande** | -| `check:bundle-size` | Paketstorleken överskrider inte gränsen | **Rådgivande** | -| `check:secrets` | Sökning efter hemligheter (gitleaks) — hoppas över om binärfilen saknas | **Rådgivande** | -| `check:vuln-ratchet` | Sårbarheter i beroenden (osv-scanner) försämras inte — hoppas över om binärfilen saknas | **Rådgivande** | -| `check:workflows` | Lintning av arbetsflöden (actionlint + zizmor); saknade/trasiga skannrar, ogiltiga rapporter eller saknad ratchet-baslinje ger felet INCOMPLETE. Giltiga fynd följer vald strikt/rådgivande/ratchet-policy | Körning krävs; zizmor-ratchet blockerar i CI | -| `check:openapi-breaking` | Bakåtinkompatibla ändringar i det publika API-kontraktet (`openapi.yaml`) jämfört med basgrenen (oasdiff) — genererar `openapiBreaking=N`; hoppas över om oasdiff saknas eller basspecifikationen inte kan lösas | **Rådgivande** | +| Skript | Validerar | Blockerande | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `check:circular-deps` | Inga cirkulära beroenden (dpdm) | **Rådgivande** | +| `check:bundle-size` | Paketstorleken överskrider inte gränsen | **Rådgivande** | +| `check:secrets` | Skanning efter hemligheter (gitleaks) — hoppas över om binärfilen saknas | **Rådgivande** | +| `check:vuln-ratchet` | Sårbarheter i beroenden (osv-scanner) försämras inte — hoppas över om binärfilen saknas | **Rådgivande** | +| `check:workflows` | Lintning av arbetsflöden (actionlint + zizmor); saknade/trasiga skannrar, ogiltiga rapporter eller saknad ratchet-baslinje ger resultatet INCOMPLETE. Giltiga fynd följer vald strikt/rådgivande/ratchet-policy | Körning krävs; zizmor-ratchet blockerar i CI | +| `check:openapi-breaking` | Bakåtinkompatibla ändringar i det offentliga API-kontraktet (`openapi.yaml`) jämfört med basgrenen (oasdiff) — genererar `openapiBreaking=N`; hoppas över om oasdiff saknas eller basspecifikationen inte kan lösas | **Rådgivande** | ### Jobb: `docs-sync-strict` Körs för varje PR till `main`. Blockerar sammanslagning vid fel. -| Skript | Validerar | Blockerande | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `check:docs-all` | Metagrind som kör de 6 delgrindarna nedan sekventiellt | Ja | -| ↳ `check:docs-sync` | Versionsöverensstämmelse mellan CHANGELOG / OpenAPI / llm.txt | Ja | -| ↳ `check:docs-counts` | Antal i löptext (antal leverantörer, antal migreringar osv.) ligger inom ratchet-fönstret för de verkliga antalen | Ja | -| ↳ `check:env-doc-sync` | Varje miljövariabel i `.env.example` är dokumenterad i en dokumentationstabell, och vice versa | Ja | -| ↳ `check:deprecated-versions` | Inga utfasade versionssträngar i dokumentationen | Ja | -| ↳ `check:doc-links` | Interna markdown-länkar i dokumentationen pekar på verkliga filer (`[text]`/`(path)`-format) | Ja | -| ↳ `check:fabricated-docs` | Rutter, miljövariabler, CLI-kommandon, hook-namn och filsökvägar som anges i dokumentationen finns i kodbasen. Hård grind via `--strict`; mjukt fel utan flaggan. | Ja (via `--strict` i CI) | -| `check:cli-i18n` | CLI-kommandosträngar finns i alla i18n-lokalfiler | Ja | -| `check:openapi-coverage` | OpenAPI-specifikationen täcker minst en stegvis höjd miniminivå av verkliga rutter | Ja | -| `check:openapi-security-tiers` | Säkerhetsnivåannoteringarna i `openapi.yaml` överensstämmer med klassificeringarna i `routeGuard.ts` | **Rådgivande** | -| `check:openapi-routes` | Varje sökväg i `openapi.yaml` motsvarar en verklig `route.ts` (motverkar hallucinationer) | Ja | -| `check:docs-symbols` | Varje `/api/...`-referens i `docs/**/*.md` motsvarar en verklig `route.ts` (motverkar hallucinationer) | Ja | -| `i18n translation drift` | Oöversatta nycklar i i18n-lokalfiler — endast varning | **Rådgivande** | +| Skript | Validerar | Blockerande | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `check:docs-all` | Metagrind som kör de 6 delgrindarna nedan sekventiellt | Ja | +| ↳ `check:docs-sync` | Versionskonsekvens mellan CHANGELOG / OpenAPI / llm.txt | Ja | +| ↳ `check:docs-counts` | Antal i löptext (antal leverantörer, antal migreringar osv.) ligger inom spärrintervallet för de verkliga antalen | Ja | +| ↳ `check:env-doc-sync` | Varje miljövariabel i `.env.example` är dokumenterad i en dokumentationstabell och vice versa | Ja | +| ↳ `check:deprecated-versions` | Inga utfasade versionssträngar i dokumentationen | Ja | +| ↳ `check:doc-links` | Interna markdown-länkar i dokumentationen pekar på verkliga filer (`[text]`/`(path)`-format) | Ja | +| ↳ `check:fabricated-docs` | Rutter, miljövariabler, CLI-kommandon, hooknamn och filsökvägar som anges i dokumentationen finns i kodbasen. Hård grind via `--strict`; mjukt fel utan flaggan. | Ja (via `--strict` i CI) | +| `check:cli-i18n` | CLI-kommandosträngar finns i alla i18n-språkfiler | Ja | +| `check:openapi-coverage` | OpenAPI-specifikationen täcker minst ett successivt höjt minimikrav för verkliga rutter | Ja | +| `check:openapi-security-tiers` | Säkerhetsnivåannoteringar i `openapi.yaml` överensstämmer med klassificeringarna i `routeGuard.ts` | **Rådgivande** | +| `check:openapi-routes` | Varje sökväg i `openapi.yaml` motsvarar en verklig `route.ts` (motverkar hallucinationer) | Ja | +| `check:docs-symbols` | Varje `/api/...`-referens i `docs/**/*.md` motsvarar en verklig `route.ts` (motverkar hallucinationer) | Ja | +| `i18n translation drift` | Oöversatta nycklar i i18n-språkfiler — endast varning | **Rådgivande** | ### Jobb: `i18n-ui-coverage` -| Skript | Validerar | Blockerande | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (inline) | Täckningen för UI-i18n-nycklar är ≥ 65 % | Ja | -| `check-ui-value-drift` (inline) | Ett omskrivet engelskt **värde** lämnar ingen inaktuell översättning kvar | Ja | -| `check-new-key-coverage` (inline) | En **ny** engelsk nyckel är översatt i varje lokal — en `__MISSING__:`-markör avvisas | Ja | -| `check-translation-ratio` | Andelen verkliga översättningar per lokal (löv utanför undantagslistan som är identiska med engelskan, platshållare eller saknas) får inte överstiga `config/quality/i18n-translation-baseline.json` + marginal | **Rådgivande** | +| Skript | Validerar | Blockerande | +| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `check-ui-keys-coverage` (infogat) | Täckningen för i18n-nycklar i användargränssnittet är ≥ 65 % | Ja | +| `check-ui-value-drift` (infogat) | Ett omskrivet engelskt **värde** lämnar inte kvar någon inaktuell översättning | Ja | +| `check-new-key-coverage` (infogat) | En **ny** engelsk nyckel är översatt i varje språkversion — en `__MISSING__:`-markör avvisas | Ja | +| `check-translation-ratio` | Andelen verkliga översättningar per språkversion (oförändrade engelska texter / platshållare / saknade löv utanför undantagslistan) får inte överstiga `config/quality/i18n-translation-baseline.json` + marginal | **Rådgivande** | -Kräver `fetch-depth: 0` — värdeavvikelsegrinden jämför `en.json` mot merge-basen. +Kräver `fetch-depth: 0` — grinden för värdeavvikelse jämför `en.json` mot sammanslagningsbasen. -#### `check-ui-value-drift` — grind för inaktuella översättningar +#### `check-ui-value-drift` — grind mot inaktuella översättningar -Upptäcker den enda i18n-regression som de andra grindarna strukturellt inte kan se: ett engelskt värde -skrivs om medan översättningarna som baserades på den _tidigare_ engelska texten lämnas kvar, så att -användare som inte använder engelska fortsätter att läsa självsäkert formulerad men numera felaktig text. +Fångar den enda i18n-regression som de andra grindarna strukturellt inte kan upptäcka: ett engelskt värde +skrivs om medan översättningarna som härletts från den _tidigare_ engelska texten ligger kvar, så att +icke-engelskspråkiga användare fortsätter läsa självsäkert formulerad men nu felaktig text. -Detta nådde faktiskt produktion. `oauthModal.googleOAuthWarning` skrevs om när inloggningshjälpen för Antigravity -lanserades (#5203); **39 av 43 lokaler** behöll text som instruerade operatörer att ”kopiera hela -URL:en och klistra in den nedan” — ett flöde som inte kan slutföras för den leverantören. Det +Detta levererades faktiskt. `oauthModal.googleOAuthWarning` skrevs om när inloggningshjälpen för Antigravity +lades till (#5203); **39 av 43 språkversioner** behöll text som uppmanade operatörer att ”kopiera den +fullständiga URL:en och klistra in den nedan” — ett flöde som inte kan slutföras för den leverantören. Det förblev oupptäckt fram till #8463 eftersom: -- `sync-ui-keys` endast fyller i nycklar som **saknas**, aldrig sådana som är **inaktuella**; -- `check-ui-keys-coverage` räknar nycklars _förekomst_, så en inaktuell översättning räknas som täckt; -- `check-translation-drift` spårar dokumentationsspeglingarna i `docs/i18n//**.md` — +- `sync-ui-keys` fyller endast i nycklar som **saknas**, aldrig sådana som är **inaktuella**; +- `check-ui-keys-coverage` räknar _förekomsten_ av nycklar, så en inaktuell översättning räknas som täckt; +- `check-translation-drift` spårar dokumentationsspeglarna i `docs/i18n//**.md` — den läser aldrig `src/i18n/messages/*.json`. Blockerande i jobbet `docs-sync-strict` sedan - omsynkroniseringen 2026-09: redigera ett centralt dokument → `npm run i18n:run -- --files=` (på avsnittsnivå, resurssnålt). + omsynkroniseringen 2026-09: redigera ett centralt dokument → `npm run i18n:run -- --files=` (på avsnittsnivå, billigt). -**Diffmedveten, inte baslinjestödd.** Den jämför `en.json` vid sammanslagningsbasen med -arbetsträdet; för varje nyckel vars engelska värde har ändrats är alla språkversioner som fortfarande har en -orörd översättning inaktuella. Detta **fryser avsiktligt befintlig skuld** — en diff -kan inte visa vilken äldre engelsk text en sedan länge befintlig översättning kom från, så kontrollen bedömer -endast det som den aktuella ändringen berör. Alternativet (en hashbaslinje per nyckel) skulle kräva -en genererad fil på ~600 KB, 3× större än den största befintliga baslinjen, med ändringar i varje i18n-PR. +**Differensmedveten, inte baslinjestödd.** Den jämför `en.json` vid sammanslagningsbasen med +arbetsträdet. För varje nyckel vars engelska värde har ändrats är varje språkversion som +fortfarande innehåller en orörd översättning inaktuell. Detta **fryser avsiktligt befintlig skuld** — en differens +kan inte visa vilken äldre engelsk text en sedan länge befintlig översättning härstammar från, så kontrollen bedömer +endast det som den aktuella ändringen berör. Alternativet (en baslinje med hash per nyckel) skulle kräva +en genererad fil på ~600 KB, tre gånger större än den största befintliga baslinjen, som skulle ändras vid varje i18n-PR. Det finns två sätt att uppfylla kravet: 1. uppdatera de berörda översättningarna, eller -2. ange dem som `__MISSING__:` — körningen visar då den korrigerade engelska texten - (`src/i18n/request.ts::deepMergeFallback`, #7258) och nyckeln köas för översättning. +2. ange dem som `__MISSING__:` — vid körning används då den korrigerade engelska texten + (`src/i18n/request.ts::deepMergeFallback`, #7258), och nyckeln köas för översättning. Om strängens **betydelse** har ändrats bör du i stället **byta namn på nyckeln**: en ny nyckel kan inte ärva en inaktuell översättning. Det är mönstret som användes i #8463. @@ -231,48 +231,48 @@ npm run i18n:check-value-drift:warn # endast rapportering BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Avslutas med 0 och `SKIP reason=base-unresolved` när baskatalogen inte kan läsas (ytlig -klon utan basreferensen), i likhet med `check-openapi-breaking`. +Avslutas med 0 och `SKIP reason=base-unresolved` när baskatalogen inte kan läsas (grund +klon utan basreferensen), i enlighet med `check-openapi-breaking`. ### Jobb: `i18n` Fullständig matris för i18n-validering (ett jobb per språkversion). Hela jobbet är rådgivande. -| Skript | Validerar | Blockerande | -| ------------------------------- | -------------------------------------------- | ---------------------------------------------------------- | -| `validate_translation.py quick` | Översättningsfullständighet per språkversion | **Rådgivande** (`continue-on-error: true` för hela jobbet) | +| Skript | Validerar | Blockerande | +| ------------------------------- | ----------------------------------------------- | ---------------------------------------------------------- | +| `validate_translation.py quick` | Översättningens fullständighet per språkversion | **Rådgivande** (`continue-on-error: true` för hela jobbet) | ### Jobb: `pr-test-policy` Körs endast för pull requests. -| Skript | Validerar | Blockerande | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | PR:er som ändrar produktionskod i `src/`, `open-sse/`, `electron/` eller `bin/` måste inkludera eller uppdatera tester (hård regel nr 8) | Ja | -| `check:test-masking` | Ändrade testfiler minskar inte nettoantalet asserts och lägger inte till tautologier av typen `assert.ok(true)` | Ja | -| `check:pr-evidence` | PR-texten hänvisar till test-/VPS-underlag för ändringen (automatiserar hård regel nr 18 genom grep-sökning i PR-text — bräckligt, se Backlog) | Ja | +| Skript | Validerar | Blockerande | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check:pr-test-policy` | PR:er som ändrar produktionskod i `src/`, `open-sse/`, `electron/` eller `bin/` måste inkludera eller uppdatera tester (hård regel nr 8) | Ja | +| `check:test-masking` | Ändrade testfiler minskar inte nettoantalet verifieringar och lägger inte till tautologier av typen `assert.ok(true)` | Ja | +| `check:pr-evidence` | PR-beskrivningen hänvisar till test-/VPS-bevis för ändringen (automatiserar hård regel nr 18 genom att söka i PR-texten — bräckligt, se backloggen) | Ja | ### Jobb: `test-vitest` Körs efter `build`. Blockerar sammanslagning vid fel. -| Testsvit | Validerar | Blockerande | -| ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP-server (110 verktyg), autoCombo, cache — vitest-körning | Ja | -| `test:vitest:ui` | UI-komponenttester — vitest-körning | **Blockerande** — befintliga fel undantas uttryckligen i `vitest.config.ts`; nya fel gör att jobbet misslyckas | +| Testsvit | Validerar | Blockerande | +| ---------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP-server (110 verktyg), autoCombo, cache — vitest-körning | Ja | +| `test:vitest:ui` | Tester av UI-komponenter — vitest-körning | **Blockerande** — befintliga fel är uttryckligen undantagna i `vitest.config.ts`; nya fel gör att jobbet misslyckas | ### Nattliga arbetsflöden (schemalagda, rådgivande) -Dessa körs enligt ett cron-schema (och `workflow_dispatch`), aldrig för PR:er. Alla är rådgivande. +Dessa körs enligt ett cron-schema (och `workflow_dispatch`), aldrig för PR:er. Samtliga är rådgivande. -| Arbetsflöde | Validerar | Blockerande | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | fast-check-egenskapstester med ett slumpmässigt startvärde + stort antal körningar | **Rådgivande** | -| `nightly-resilience` | kontroll av heap-tillväxt, kaosbaserad felinjektion, k6-belastnings-/uthållighetstestning | **Rådgivande** | -| `nightly-llm-security` | promptfoo-injektionsskydd (blockeringsläge) + garak-prober (hoppas över utan en leverantörshemlighet) | **Rådgivande** | -| `nightly-schemathesis` | Fuzzning av OpenAPI-kontrakt (schemathesis) mot en aktiv OmniRoute med `docs/openapi.yaml` — blottlägger specifikationsöverträdelser/oavlyssnade 500-fel (Fas 8 B.4) | **Rådgivande** | -| `nightly-mutation` | Poäng för Stryker-mutationstestning över den snabba enhetstestbanan — överlevande mutanter blottlägger svaga asserts | **Rådgivande** | -| `nightly-compat` | Kompatibilitetsmatris för Node-motorn över de stödda `engines.node`-intervallen | **Rådgivande** | +| Arbetsflöde | Validerar | Blockerande | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | fast-check-egenskapstester med ett slumpmässigt startvärde + många körningar | **Rådgivande** | +| `nightly-resilience` | kontroll av heap-tillväxt, kaosbaserad felinjektion, k6-belastnings-/uthållighetstest | **Rådgivande** | +| `nightly-llm-security` | promptfoo-skydd mot injektion (blockeringsläge) + garak-prober (hoppas över utan en leverantörshemlighet) | **Rådgivande** | +| `nightly-schemathesis` | Fuzzning av OpenAPI-kontrakt (schemathesis) mot en aktiv OmniRoute med `docs/openapi.yaml` — synliggör specifikationsöverträdelser/ohanterade 500-fel (fas 8 B.4) | **Rådgivande** | +| `nightly-mutation` | Poäng från Stryker-mutationstestning för den snabba enhetstestbanan — överlevande mutanter synliggör svaga verifieringar | **Rådgivande** | +| `nightly-compat` | Kompatibilitetsmatris för Node-motorn över de `engines.node`-intervall som stöds | **Rådgivande** | --- @@ -536,9 +536,9 @@ anslutningsfel och avbryter aldrig sessioner. --- -## Rationaliseringsbacklogg (ROI-granskning — Fas 9 Våg 3) +## Rationaliseringsbacklogg (ROI-granskning — fas 9 våg 3) -Denna inventering stämdes av mot `ci.yml` den 2026-06-17 (den föregående versionen utelämnade +Den här inventeringen stämdes av mot `ci.yml` den 2026-06-17 (den föregående versionen utelämnade `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). En ROI-granskning av den avstämda uppsättningen @@ -546,33 +546,33 @@ identifierade följande kandidater för rationalisering. **Sammanslagningarna ä ändringar; växlingarna/borttagningarna är policybeslut som är förbehållna operatören.** Inget nedan har tillämpats ännu. -**Också odokumenterade ovan** (rådgivande, låg signal): jobbet `docs-lint` +**Inte heller dokumenterat ovan** (rådgivande, låg signal): jobbet `docs-lint` (markdownlint + Vale, hela jobbet har `continue-on-error`) och de fristående skanningsarbetsflödena `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` finns i -`quality-baseline.json` men är inte kopplat till en blockerande spärr i `ci.yml` — mätvärdet är +`quality-baseline.json` men är inte kopplat till någon blockerande spärrmekanism i `ci.yml` — mätvärdet är för närvarande frikopplat. -### Slå samman / deduplicera (mekaniskt, lägre risk) +### Slå ihop / deduplicera (mekaniskt, lägre risk) -Varje kandidat validerades mot det aktiva grindläget den 2026-06-17 (lita men verifiera); -flera ”uppenbara” sammanslagningar visade sig dölja skuld och är **inte** rena direktlösningar. +Varje kandidat validerades mot det aktuella grindläget den 2026-06-17 (lita men verifiera); +flera ”uppenbara” sammanslagningar visade sig dölja skuld och är **inte** problemfria direktlösningar. -- **`check:docs-sync` körs två gånger** — fristående i jobbet `lint` och igen inuti `check:docs-all` (`docs-sync-strict`) samt i huskys pre-commit-hook. ✅ **KLART** — den fristående `lint`-körningen har tagits bort. -- **CVE-skanning** — ❌ **INTE en ren sammanslagning.** `audit:deps` leder till ett hårt fel vid varje CVE med allvarlighetsgrad high/critical; `check:vuln-ratchet` (osv) misslyckas endast vid en _regression_ jämfört med baslinjen (för närvarande 1 MODERATE). Olika semantik — att ta bort `audit:deps` skulle innebära att den absoluta grinden för high/critical försvinner. Behåll båda. -- **Cykeldetektering** — ❌ **INTE en ren sammanslagning.** `check:circular-deps` (dpdm) rapporterar **91 cykler** (det är därför den är rådgivande); den kan inte göras blockerande utan att dessa först åtgärdas, och den har ett bredare omfång än den godkända, handplockade `check:cycles`. Behåll `check:cycles` som blockerande; att åtgärda de 91 dpdm-cyklerna är en separat backloggpost. -- **Komplexitet** — ✅ **KLART** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): en ESLint-genomgång, räknar per ruleId så att baslinjerna för cyklomatisk komplexitet+max-lines och kognitiv komplexitet förblir oberoende; separata `check:complexity` / `check:cognitive-complexity` finns kvar för lokal `--update`. -- **Antihallucination för `/api`** — ✅ **KLART** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): en FS-inventering av `src/app/api`, openapi-routes + docs-symbols rapporterar fortfarande oberoende av varandra; de separata kontrollerna finns kvar för lokala körningar. -- **`check:node-runtime` körs i 11 jobb** — ⚠️ **låg ROI.** Varje körning sker på en separat runner och kontrollen tar <1 s; total besparing ~10 s, till priset av att en billig skyddskontroll per jobb går förlorad. Inte värt omarbetningen. -- **`typecheck:noimplicit:core` i CI-lintning** — ✅ **borttaget från lint-jobbet** (var rådgivande med `continue-on-error`); den blockerande typytan utgörs av `typecheck:core` + `check:type-coverage`. Det lokala skriptet har behållits. +- **`check:docs-sync` körs två gånger** — fristående i jobbet `lint` och återigen inuti `check:docs-all` (`docs-sync-strict`) samt i husky-pre-commit-kroken. ✅ **KLART** — den fristående anropningen i `lint` har tagits bort. +- **CVE-skanning** — ❌ **INTE en problemfri sammanslagning.** `audit:deps` stoppar ovillkorligen vid varje CVE med hög/kritisk allvarlighetsgrad; `check:vuln-ratchet` (osv) misslyckas endast vid en _regression_ jämfört med baslinjen (för närvarande 1 MODERATE). Olika semantik — att ta bort `audit:deps` skulle innebära att den absoluta grinden för hög/kritisk allvarlighetsgrad försvinner. Behåll båda. +- **Cykeldetektering** — ✅ **KLART** (#15159 G-01/G-02). Den gamla texten här kallade `check:cycles` för den ”gröna, handplockade” grinden och motiverade att den skulle förbli blockerande eftersom `check:circular-deps` (dpdm) rapporterade 91 cykler. Det gröna resultatet var **falskt grönt**: `check:cycles` skannade 5 underkataloger (450 filer), matchade endast statiska `import|export … from` och ignorerade varje `@/`- och `@omniroute/open-sse/`-specifierare, så den kunde inte se de cykler med dynamisk import + alias som dominerade kodbasen. Åtgärdat: grinden går nu igenom `src` + `open-sse` (5023 filer), samlar in specifierare från TypeScript-AST:n (så `import("…")` räknas medan `typeof import("…")` i typposition inte gör det) och löser tsconfig-`paths`. Den hittar **14** cykler, inte 0. Eftersom 14 befintliga cykler inte kan åtgärdas i en grind-PR är `check:cycles` nu en **spärrmekanism** (`--ratchet`, tak `metrics.cycles.value = 14` i `quality-baseline.json`, `direction: down`) — den blockerar varje _regression_ och antalet kan endast minska. CI kör `npm run check:cycles:ratchet`. Nedarbetningen följer med **A-01**. `check:circular-deps` (dpdm) förblir rådgivande som en bredare andrahandsbedömning. +- **Komplexitet** — ✅ **KLART** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): en ESLint-genomgång, räknar per ruleId så att baslinjerna för cyklomatisk komplexitet + maximalt antal rader och kognitiv komplexitet förblir oberoende; individuella `check:complexity` / `check:cognitive-complexity` finns kvar för lokal `--update`. +- **Antihallucination för `/api`** — ✅ **KLART** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): en FS-inventering av `src/app/api`, openapi-routes + docs-symbols rapporterar fortfarande oberoende; individuella kontroller finns kvar för lokala körningar. +- **`check:node-runtime` körs i 11 jobb** — ⚠️ **låg ROI.** Varje jobb har en separat körmiljö och kontrollen tar <1 s; total besparing ~10 s, på bekostnad av att förlora ett billigt skydd per jobb. Inte värt omarbetningen. +- **`typecheck:noimplicit:core` i CI-lint** — ✅ **borttaget från lint-jobbet** (var rådgivande med `continue-on-error`); den blockerande typytan är `typecheck:core` + `check:type-coverage`. Det lokala skriptet har behållits. ### Växla / besluta (operatörspolicy) -- `check:openapi-security-tiers` (rådgivande) — ❌ **KAN INTE växlas direkt.** Det avslutas med 0 men varnar för att flera `traffic-inspector`-rutter under `LOCAL_ONLY_API_PREFIXES` saknar annoteringen `x-loopback-only: true`. För att göra det tvingande måste dessa annoteringar först läggas till i `openapi.yaml`. -- `typecheck:noimplicit:core` (rådgivande) — ersätts till stor del av den blockerande `check:type-coverage`-spärren. Gör om den till en spärr eller ta bort det redundanta andra `tsc`-passet. -- `test:vitest:ui` (nu **blockerande**) — befintliga fel undantas uttryckligen i `vitest.config.ts` med spårningskommentarer av typen `// #8618`; nya fel gör att jobbet misslyckas. -- `check:secrets` (gitleaks, blockerande spärr fryst vid 3 dokumenterade falska positiva resultat) — lägg till de 3 i tillåtelselistan för att nå 0, eller nedgradera till rådgivande. Överlappar GitHubs inbyggda hemlighetsskanning + `check:public-creds`. -- `check:pr-evidence` (blockerande, söker igenom PR-beskrivningens prosa med grep) — hög risk för falska positiva resultat; om den tas bort försvagas efterlevnaden av Hård regel nr 18, så detta är ett genuint policybeslut. -- `semgrep` (rådgivande, fristående) — överlappar CodeQL för OWASP-familjerna; koppla dess baslinje till en spärr eller ta bort den. +- `check:openapi-security-tiers` (rådgivande) — ❌ **KAN INTE växlas utan föregående åtgärder.** Den avslutas med 0 men varnar för att flera `traffic-inspector`-rutter under `LOCAL_ONLY_API_PREFIXES` saknar annoteringen `x-loopback-only: true`. För att verkställa den måste dessa annoteringar först läggas till i `openapi.yaml`. +- `typecheck:noimplicit:core` (rådgivande) — ersätts till stor del av den blockerande spärrmekanismen `check:type-coverage`. Växla till en spärrmekanism eller ta bort den redundanta andra `tsc`-körningen. +- `test:vitest:ui` (nu **blockerande**) — befintliga fel exkluderas uttryckligen i `vitest.config.ts` med spårningskommentarer av typen `// #8618`; nya fel gör att jobbet misslyckas. +- `check:secrets` (gitleaks, blockerande spärrmekanism fryst vid 3 dokumenterade falska positiva resultat) — tillåtelselista de 3 för att nå 0 eller nedgradera till rådgivande. Överlappar GitHubs inbyggda hemlighetsskanning + `check:public-creds`. +- `check:pr-evidence` (blockerande, söker med grep i PR-beskrivningens prosa) — hög risk för falska positiva resultat; att ta bort den försvagar upprätthållandet av hård regel nr 18, så detta är ett verkligt policybeslut. +- `semgrep` (fristående rådgivande) — överlappar CodeQL för OWASP-familjerna; koppla dess baslinje till en spärrmekanism eller ta bort den. --- diff --git a/docs/i18n/sw/CONTRIBUTING.md b/docs/i18n/sw/CONTRIBUTING.md index b5083526c56..5ef92f12078 100644 --- a/docs/i18n/sw/CONTRIBUTING.md +++ b/docs/i18n/sw/CONTRIBUTING.md @@ -391,18 +391,18 @@ Andika majaribio ya vipengele katika `tests/unit/` yanayojumuisha angalau: - [ ] Majaribio yanafaulu (`npm test`) - [ ] Ukaguzi wa lint unafaulu (`npm run lint`) -- [ ] Ujenzi unafanikiwa (`npm run build`) +- [ ] Uundaji unafaulu (`npm run build`) - [ ] Aina za TypeScript zimeongezwa kwa functions na interfaces mpya za umma -- [ ] Hakuna siri au thamani mbadala zilizowekwa moja kwa moja -- [ ] Vitambulisho vya umma vya upstream vimepachikwa kupitia `resolvePublicCred()` (angalia [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), kamwe si kama literals -- [ ] Majibu ya hitilafu hupitishwa kupitia `buildErrorBody()` / `sanitizeErrorMessage()` — hakuna stack traces ghafi katika miili ya majibu (angalia [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Amri za shell (`exec` / `spawn`) hupitisha thamani za runtime kupitia `env`, si kupitia uingizaji wa thamani kwenye string -- [ ] Ingizo zote zimethibitishwa kwa schemas za Zod -- [ ] **Kipande** cha changelog kimeongezwa chini ya `changelog.d/{features|fixes|maintenance}/-.md` kwa mabadiliko yanayoonekana kwa mtumiaji (angalia [`changelog.d/README.md`](./changelog.d/README.md)) — **usihariri** `CHANGELOG.md` moja kwa moja; vipande huunganishwa wakati wa toleo na kamwe havikinzani kati ya PR -- [ ] Nyaraka zimesasishwa (ikiwa inatumika) -- [ ] Hakuna arifa mpya za CodeQL / Secret-Scanning zilizofunguliwa, au kila moja imepuuzwa kwa uhalalishaji wa kiufundi unaorejelea hati husika ya `docs/security/` -- [ ] Routes zinazoanzisha child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) zimeainishwa kama `isLocalOnlyPath()` katika `src/server/authz/routeGuard.ts` — angalia [Kanuni Isiyobadilika #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Hakuna trailers za `Co-Authored-By` katika commit messages — commits lazima zionekane chini ya Git identity ya mmiliki wa repository pekee (Kanuni Isiyobadilika #16) +- [ ] Hakuna siri au thamani mbadala zilizowekwa moja kwa moja kwenye msimbo +- [ ] Vitambulisho vya upstream vya umma vimepachikwa kupitia `resolvePublicCred()` (tazama [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), kamwe si kama literals +- [ ] Majibu ya hitilafu yanapitia `buildErrorBody()` / `sanitizeErrorMessage()` — hakuna stack traces ghafi katika response bodies (tazama [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Amri za shell (`exec` / `spawn`) hupitisha thamani za wakati wa utekelezaji kupitia `env`, si kupitia string interpolation +- [ ] Ingizo zote zimethibitishwa kwa Zod schemas +- [ ] **Kipande** cha changelog kimeongezwa chini ya `changelog.d/{features|fixes|maintenance}/-.md` kwa mabadiliko yanayoonekana kwa watumiaji (tazama [`changelog.d/README.md`](./changelog.d/README.md)) — **usihariri** `CHANGELOG.md` moja kwa moja; vipande huunganishwa wakati wa toleo na kamwe havikinzani kati ya PRs +- [ ] Nyaraka zimesasishwa (ikiwa inahusika) +- [ ] Hakuna arifa mpya za CodeQL / Secret-Scanning zilizofunguliwa, au kila moja imekataliwa kwa uhalalisho wa kiufundi unaorejelea hati husika ya `docs/security/` +- [ ] Routes zinazoanzisha child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) zimeainishwa kama `isLocalOnlyPath()` katika `src/server/authz/routeGuard.ts` — tazama [Kanuni Kali #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Hakuna trailers za AI/bot za `Co-authored-by` katika commit messages (Kanuni Kali #16) — washirika wanadamu ambao kazi yao imetumika tena wanatambuliwa kwa trailers za kawaida za `Co-authored-by: Name ` --- diff --git a/docs/i18n/sw/docs/architecture/QUALITY_GATES.md b/docs/i18n/sw/docs/architecture/QUALITY_GATES.md index 4f49b04d7ba..11cfeb48fce 100644 --- a/docs/i18n/sw/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/sw/docs/architecture/QUALITY_GATES.md @@ -17,262 +17,262 @@ wa kuiga mfumo huo huo, angalia ## Orodha ya malango na wasifu wa utekelezaji -### Uidhinishaji wa mgombea +### Kukubaliwa kwa mgombea Mitiririko ya kazi ya CI na Quality Gates kila mmoja hutoa uamuzi thabiti: `Gate / CI` na -`Gate / Quality`. Sera yao ya uidhinishaji yenye matoleo huorodhesha kila kazi ya awali -kama ya lazima au ya ushauri. Kazi husika ya lazima lazima ifanikiwe: matokeo +`Gate / Quality`. Sera yao ya kukubali yenye matoleo huorodhesha kila kazi ya awali +kuwa ya lazima au ya ushauri. Kazi husika ya lazima lazima ifanikiwe: matokeo yanayokosekana, yaliyoghairiwa, yaliyorukwa, yanayosubiri na yasiyojulikana hayawezi kuthibitisha PASS. Uainishaji halali wa docs-only au catalog-only unaweza kufanya njia ya msimbo isihusike; PR ya rasimu si mgombea anayekubalika. Lebo ya `hotfix` haiondoi hitaji la ushahidi. -Mitiririko yote miwili ya kazi inahusu PR na misukumo kwenda kwenye matawi ya main/release, uanzishaji wa mwenyewe na -matukio ya merge-group. Push, dispatch na merge-group huendesha uteuzi kamili. Forks -na merge groups hutumia waendeshaji wanaopangishwa kwa kazi ambazo vinginevyo huchagua waendeshaji -wanaojipangisha; uwezo wa kutosha wa huduma iliyopangishwa lazima uthibitishwe kabla ya uzinduzi. +Mitiririko yote miwili ya kazi inahusisha PR na usukumaji kwenda kwenye matawi ya main/release, uanzishaji wa +mikono na matukio ya merge-group. Usukumaji, uanzishaji na merge-group hutekeleza uteuzi kamili. Forks +na merge groups hutumia hosted runners kwa kazi ambazo vinginevyo huchagua self-hosted +runners; uwezo wa kutosha wa hosted lazima uthibitishwe kabla ya kusambaza mabadiliko. -Kila risiti ya JSON hutambulisha SHA iliyopakuliwa, utekelezaji wa mtiririko wa kazi na jaribio. -CLI hukataa kutolingana kwa SHA ya checkout/event. Majaribio ya mtiririko wa kazi huunganisha uanachama wa sera -na orodha ya `needs` ya kazi ya uamuzi ili njia mpya au iliyoondolewa isiweze kutoweka kimya kimya. -Risiti zinahusu mtiririko wao wenyewe wa kazi, si uchapishaji, upelekaji, au vipengele vya ndani -vya kichanganuzi kilichopo cha ushauri. Kuwasha majina yote mawili ya ukaguzi katika kanuni za tawi ni -badiliko tofauti la kiutawala; kuongeza kazi hizi pekee hakulindi tawi. +Kila risiti ya JSON hutambulisha SHA iliyochukuliwa, utekelezaji wa mtiririko wa kazi na jaribio. +CLI hukataa kutolingana kwa SHA ya checkout/event. Majaribio ya mtiririko wa kazi hufungamanisha uanachama wa sera +na orodha ya `needs` ya kazi ya uamuzi ili njia mpya au iliyoondolewa isipotee bila kutambuliwa. +Risiti hushughulikia mtiririko wake wenyewe wa kazi, si uchapishaji, upelekaji, au utendaji wa ndani +wa kichanganuzi kilichopo cha ushauri. Kuwasha majina yote mawili ya ukaguzi katika kanuni za tawi ni +badiliko tofauti la kiutawala; kuongeza kazi hizi hakulindi tawi moja kwa moja. ### Orodha ya uchanganuzi tuli -Orodha ya npm-alias yenye matoleo na uanachama wa uchanganuzi tuli hupatikana katika -`config/quality/gate-manifest.json`. Endesha `npm run check:gate-manifest` ili kuthibitisha -majina ya hati na amri kamili dhidi ya `package.json`; nyongeza, uondoaji na -mabadiliko ya amri husababisha kushindwa kwa hook ya ndani na kazi za uainishaji wa mabadiliko katika CI. -Alias si kazi ya mtiririko wa kazi, instance ya matrix au kesi ya jaribio: idadi hizi hazipaswi -kuwasilishwa kana kwamba zinaweza kutumika kwa kubadilishana. +Orodha ya npm-alias yenye matoleo na uanachama wa uchanganuzi tuli vinapatikana katika +`config/quality/gate-manifest.json`. Tekeleza `npm run check:gate-manifest` ili kuthibitisha +majina ya script na amri halisi dhidi ya `package.json`; nyongeza, uondoaji na +mabadiliko ya amri husababisha hook ya ndani na kazi za uainishaji wa mabadiliko katika CI kushindwa. +Alias si kazi ya mtiririko wa kazi, instance ya matrix au test case: hesabu hizi hazipaswi +kuwasilishwa kana kwamba zinaweza kubadilishana. Tumia `npm run quality:scan -- --list` au `npm run quality:scan:fast -- --list` -kukagua alias zilizochaguliwa bila kuzitekeleza. Kiendeshaji huita -sehemu ya kuingilia ya npm, kwa hivyo runtime yake (ikiwemo Bun pale iliposanidiwa) hudumishwa. -Manifest hurekodi alias zilizo nje ya wasifu huo kama zinazoitwa kando, na +kukagua aliases zilizochaguliwa bila kuzitekeleza. Runner huanzisha +npm entrypoint, hivyo runtime yake (ikiwemo Bun pale iliposanidiwa) huhifadhiwa. +Manifest hurekodi aliases zilizo nje ya wasifu huo kuwa zinaanzishwa kivyake, na amri za matengenezo zimepigwa marufuku katika wasifu wa uchanganuzi wa kusoma pekee. Wasifu huu unahusu uchanganuzi tuli pekee. Hauthibitishi majaribio ya bidhaa, -coverage, ufungashaji, ukaguzi wa nje au uidhinishaji kamili wa toleo la mgombea. -Uidhinishaji wa mtiririko wa kazi hutumia `config/quality/admission-policy.json` iliyounganishwa na -`scripts/quality/admission-verdict.mjs`. Wasifu wa release-observer hubaki tofauti; -kagua ukaguzi na risiti zake husika kwa kujitegemea. Orodha ya maelezo -iliyo hapa chini ni marejeleo, si uthibitisho kwamba lango liliendeshwa. +coverage, packaging, ukaguzi wa nje au ukubalifu kamili wa mgombea kwa toleo. +Ukubalishaji wa mtiririko wa kazi hutumia `config/quality/admission-policy.json` iliyounganishwa na +`scripts/quality/admission-verdict.mjs`. Wasifu wa release-observer unasalia tofauti; +kagua ukaguzi na risiti zake husika kivyake. Orodha ya maelezo +iliyo hapa chini ni rejeleo, si uthibitisho kwamba lango lilitekelezwa. -Hati zipo chini ya `scripts/check/` (malango ya sera) na `scripts/quality/` (injini ya ratchet). -Chanzo cha ukweli cha CI ni `.github/workflows/ci.yml`. +Scripts zinapatikana chini ya `scripts/check/` (malango ya sera) na `scripts/quality/` (injini ya ratchet). +Chanzo rasmi cha CI ni `.github/workflows/ci.yml`. ### Njia ya haraka ya PR ya toleo (`quality.yml`) -`.github/workflows/quality.yml` hukamilisha CI kwenye PR za main/release, misukumo ya protected-branch, -dispatch na merge groups. PR hutumia ukaguzi wa haraka uliochujwa kwa njia. Build rudufu iliyokuwa -imezimwa kabisa iliondolewa; ukaguzi halisi wa build/package/boot unabaki katika CI. - -| Kazi | Upeo | Inazuia | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `Docs Gates (fast-path)` | PR za nyaraka/msimbo; marejeleo ya nyaraka za API na docs-all | Ndiyo | -| `Fast Quality Gates` | PR za msimbo; ukaguzi tuli, typecheck, typecheck ya dashboard, majaribio ya unit yaliyoathiriwa | Ndiyo | -| `Forgotten sibling tests` | PR za msimbo; moduli zilizobadilishwa zinazofuatiliwa hadi kwa watumiaji tuli na majaribio sibling yanayoweza kuchaguliwa; njia za barrel na dynamic-import huripotiwa kama uchunguzi wa ushauri, pamoja na tofauti zilizorejelewa za allowlist | **Ushauri** | -| `Vitest (fast-path)` | PR za msimbo; mkusanyiko wa haraka wa vitest | Ndiyo | -| `Unit Tests fast-path` | PR za msimbo; mkusanyiko wa unit wenye shard 4 | Ndiyo | -| `No new ESLint warnings` | PR za msimbo; ulinzi wa lint unaotambua suppressions | Ndiyo, ikijumuisha forks | -| `Merge integrity (changelog + generated skills)` | PR zisizo rasimu; usawazishaji wa changelog na skill zilizozalishwa | Ndiyo, ikijumuisha forks | - -#### Ripoti ya majaribio sibling yaliyosahaulika - -`npm run check:forgotten-sibling-tests` hutumia tena kitatuzi cha import kilicho nyuma ya ramani ya athari za majaribio. -Kwa kila moduli ya uzalishaji iliyobadilishwa, huripoti minyororo bainifu ya -`changed module/symbol -> static consumer -> candidate sibling test` wakati jaribio linaloweza kuchaguliwa -halipo katika diff ya pull-request. Muhtasari wa Markdown na matokeo ya JSON huhifadhiwa kama -artifact ya mtiririko wa kazi ya `forgotten-sibling-tests` kwa ajili ya urekebishaji kabla ya uzinduzi wowote unaozuia. - -Uhamishaji upya wa barrel na uingizaji dhabiti ni uchunguzi wa utatuzi pekee; hauwahi kuunda +`.github/workflows/quality.yml` hukamilisha CI kwenye PR za main/release, usukumaji kwenye matawi +yanayolindwa, uanzishaji na merge groups. PR hutumia ukaguzi wa haraka uliochujwa kulingana na path. Build nakala +iliyozimwa kabisa iliondolewa; ukaguzi halisi wa build/package/boot unasalia katika CI. + +| Kazi | Upeo | Inazuia | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `Docs Gates (fast-path)` | PR za docs/code; marejeleo ya API docs na docs-all | Ndiyo | +| `Fast Quality Gates` | PR za msimbo; ukaguzi tuli, typecheck, typecheck ya dashboard, unit tests zilizoathiriwa | Ndiyo | +| `Forgotten sibling tests` | PR za msimbo; moduli zilizobadilishwa zinazofuatiliwa hadi kwa watumiaji tuli na sibling tests zinazoweza kuchaguliwa; njia za barrel na dynamic-import huripotiwa kama uchunguzi wa ushauri, pamoja na vighairi vya allowlist vilivyorejelewa | **Ushauri** | +| `Vitest (fast-path)` | PR za msimbo; mkusanyiko wa haraka wa vitest | Ndiyo | +| `Unit Tests fast-path` | PR za msimbo; mkusanyiko wa unit wa shards 4 | Ndiyo | +| `No new ESLint warnings` | PR za msimbo; kinga ya lint inayozingatia suppressions | Ndiyo, ikiwemo forks | +| `Merge integrity (changelog + generated skills)` | PR zisizo rasimu; ulandanishaji wa changelog na skill zilizozalishwa | Ndiyo, ikiwemo forks | + +#### Ripoti ya forgotten sibling tests + +`npm run check:forgotten-sibling-tests` hutumia tena import resolver iliyo nyuma ya ramani ya athari za majaribio. +Kwa kila moduli ya uzalishaji iliyobadilishwa, huripoti misururu thabiti ya +`changed module/symbol -> static consumer -> candidate sibling test` wakati test inayoweza kuchaguliwa +haipo katika tofauti ya pull-request. Muhtasari wa Markdown na matokeo ya JSON huhifadhiwa kama +artifact ya mtiririko wa kazi ya `forgotten-sibling-tests` kwa ajili ya usawazishaji kabla ya utekelezaji wowote wa kuzuia. + +Uhamishaji upya wa barrel na uingizaji wa kidinamiki ni uchunguzi wa utatuzi pekee; kamwe hauleti ugunduzi unaozuia. Vighairi vilivyokaguliwa vinapatikana katika `config/quality/forgotten-sibling-allowlist.json`. Kila ingizo lazima litaje jaribio la mtumiaji na la mgombea, -litoe sababu mahususi, na liunganishe na suala au ombi la kuvuta la GitHub. Maingizo yenye muundo usio sahihi -hukataliwa kwa chaguo-msingi. Vighairi haviwezi kuficha jaribio la mgombea lililofutwa au tofauti inayoongeza `.skip`/`.todo`; -udhoofishaji wa madai na ufichaji mwingine hubaki chini ya lango linalozuia kwa kujitegemea la -`check:test-masking`. +litoe sababu mahususi, na liunganishe suala au ombi la kuvuta la GitHub. Maingizo yenye muundo usio sahihi hushindwa +kwa hali funge. Vighairi haviwezi kuficha jaribio la mgombea lililofutwa au tofauti inayoongeza `.skip`/`.todo`; +udhoofishaji wa madai na ufichaji mwingine unasalia chini ya lango la +`check:test-masking` linalozuia kwa kujitegemea. ### Kazi: `lint` -Huendeshwa kwenye kila PR kwenda `main`. Huzuia uunganishaji ikishindwa. - -| Hati (`npm run ...`) | Huthibitisha | Inazuia | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Toleo la Node.js liko ndani ya masafa yanayotumika | Ndiyo | -| `check:cycles` | Uingizaji wa mzunguko — moduli zote za `src/` + `open-sse/` | Ndiyo | -| `check:route-validation:t06` | Skima za Zod zipo kwenye njia zote (sera ya Kiwango cha 6) | Ndiyo | -| `check:any-budget:t11` | Idadi ya `@ts-expect-error // any` haizidi bajeti (catraca ya Kiwango cha 11) | Ndiyo | -| `check:provider-consistency` | Kila mtoa huduma katika `providers.ts` ana ingizo linalolingana katika `providerRegistry.ts` (na kinyume chake, ndani ya orodha ya ruhusa) | Ndiyo | -| `check:model-lifecycle` | Majedwali matatu ya uelekezaji yanayotunzwa kwa mikono yanaendelea kuwiana na nakala ya hali ya mzunguko wa maisha iliyohifadhiwa (#11503): `FITNESS_TABLE` (`taskFitness.ts`) haitoi alama kwa id yoyote iliyostaafishwa ambayo `REGISTRY` inaweza kuelekeza; kila lengo la `BUILT_IN_ALIASES` lipo katika `REGISTRY` na halipo katika nakala ya id zilizostaafishwa; kila id iliyostaafishwa ambayo bado ipo katika `REGISTRY` inaelekezwa kwingine au imeorodheshwa katika `allowedRetiredInCatalog`; na hakuna chanzo au lengo la `DEFAULT_DEGRADATION_MAP` linaloonekana kuwa limestaafishwa katika nakala hiyo. Hili halithibitishi kwamba modeli inahudumiwa kwa sasa na huduma ya juu iliyo hai. Nje ya mtandao — hulinganisha dhidi ya `config/quality/model-lifecycle.json`, inayosasishwa kwa mikono kwa kutumia `npm run quality:refresh-model-lifecycle` (mtandao; haijaunganishwa kwenye CI). `allowedRetiredInCatalog` ni utaratibu wa kupunguza orodha hatua kwa hatua: ongeza ingizo tu likiwa na suala la ufuatiliaji. | Ndiyo | -| `check:fetch-targets` | Kila `fetch("/api/...")` katika `src/` ya upande wa mteja huelekezwa kwenye `route.ts` halisi | Ndiyo | -| `check:deps` | Vitegemezi vyote vinavyoweza kusakinishwa kwa `npm install` katika kila `package.json` kwenye hazina vimo katika `dependency-allowlist.json`; vifurushi vipya visivyofungwa kwenye toleo mahususi au vilivyosakinishwa kimakosa kutokana na majina yanayofanana vinaalamishwa | Ndiyo | -| `audit:deps` | `npm audit` (mzizi + electron) — hakuna tahadhari za kiwango cha juu/kritikali (inaingiliana na osv `check:vuln-ratchet`; tazama Orodha ya Maboresho ya Kurahisisha) | Ndiyo | -| `check:lockfile` | Uadilifu wa `package-lock.json` — sajili ya https, heshi za uadilifu, hakuna ubatilishaji wa seva pangishi | Ndiyo | -| `check:licenses` | Orodha ya leseni za SPDX zinazoruhusiwa kwa vitegemezi vya uzalishaji | Ndiyo | -| `check:tracked-artifacts` | Hakuna mabaki ya ujenzi / viungo vya kiishara vya `node_modules` vilivyowekwa kwenye hazina (pia huendeshwa katika husky pre-commit; pre-push imefanywa nyepesi kimakusudi — #6716) | Ndiyo | -| `check:ai-attribution` | Hakuna mstari wa mwisho wa AI/boti wa `Co-Authored-By` au kijachini cha uzalishaji wa AI katika commits, kichwa au maelezo ya PR — Kanuni Ngumu #16 (katika kitanzi cha fast-gates cha `quality.yml` kwa PR→`release/**` — husoma payload ya tukio, haifanyi chochote nje ya PR — na hatua ya PR pekee katika lint ya `ci.yml` kwa PR→`main`; pia hook ya husky ya `commit-msg`; waandishi wenza wa kibinadamu wanaruhusiwa; #14436) | -| `check:vitest-exclusions` | Kila kutengwa kwa Vitest hutaja suala la ufuatiliaji na huonekana katika `config/quality/vitest-exclusions.json` (#13204) | Ndiyo | -| `check:file-size` | Hakuna faili ya msimbo-chanzo inayozidi kikomo cha kila kiendelezi (ratchet: faili kubwa zilizogandishwa katika orodha ya `frozen`) | Ndiyo | -| `check:error-helper` | Majibu ya hitilafu katika vitekelezaji/vishughulikiaji hutumia `buildErrorBody()` / `sanitizeErrorMessage()` (Kanuni Ngumu #12) | Ndiyo | -| `check:migration-numbering` | Faili za SQL za uhamishaji zimepewa nambari zinazofuatana, bila mapengo au marudio | Ndiyo | -| `check:public-creds` | Hakuna thamani halisi za OAuth `client_id`/`client_secret` au funguo za Firebase Web nje ya `publicCreds.ts` (Kanuni Ngumu #11) | Ndiyo | -| `check:db-rules` | Hakuna SQL ghafi nje ya moduli za `src/lib/db/`; hakuna uingizaji wa pamoja kutoka `localDb.ts` (Kanuni Ngumu #2/#5) | Ndiyo | -| `check:known-symbols` | Vitekelezaji vya watoa huduma, mikakati ya uelekezaji, na vitafsiri vilivyosajiliwa katika majedwali yao ya usambazaji vinalingana na faili zilizo kwenye diski—hakuna alama yatima au ambazo hazijatangazwa | Ndiyo | -| `check:route-guard-membership` | Kila njia inayoanzisha mchakato mtoto imeainishwa na `isLocalOnlyPath()` (Kanuni Ngumu #15/#17) | Ndiyo | -| `check:test-discovery` | Kila faili ya `*.test.ts` / `*.spec.ts` katika hazina hukusanywa na angalau kiendesha majaribio kimoja (ratchet: orodha ya faili yatima katika `test-discovery-baseline.json` inaweza kupungua tu) | Ndiyo | -| `check:agent-skills-sync` | Artefakti zilizozalishwa za agent-skills zinalingana na katalogi yao chanzo (hakuna tofauti) | -| `check:provider-asset-provenance` | Nembo/rasilimali za mtoa huduma zina ingizo lililorekodiwa la asili | -| `lint:json` | Faili za usanidi za JSON zinachanganuliwa na zinakidhi kanuni za lint za repo | -| `typecheck:core` | Ukusanyaji wa TypeScript bila hitilafu (maonyo ya ushauri pekee) | Ndiyo | -| `typecheck:noimplicit:core` | `noImplicitAny` kali — kwa ajili ya siku zijazo; maeneo mengi ya simu yaliyokuwepo tayari bado yanahitaji ufafanuzi wa aina | **Ushauri** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` yenye upeo wa `src/app/(dashboard)/**` (#7033) — orodha iliyoratibiwa ya faili 27 inayoruhusiwa ya `typecheck:core` haijumuishi TSX yoyote ya dashibodi, na `next build` pia haikagui aina zake kamwe (`next.config.mjs` huweka `ignoreBuildErrors: true`), kwa hivyo marejeo yaliyovunjika ya vitambulisho huko (#6625/#6909) hayakuonekana na CI. Tofauti hulinganishwa na msingi uliogandishwa wa idadi kwa kila faili/kila msimbo wa TS (`config/quality/dashboard-typecheck-baseline.json`, muundo uleule wa utekelezaji dhidi ya msingi uliopitwa na wakati kama `check:known-symbols`) — ni hitilafu MPYA pekee zinazozidi idadi iliyowekwa kwenye msingi ndizo zinazofanya lango lishindwe; punguza hatua kwa hatua kwa kutumia `--update` hitilafu iliyokuwepo tayari inaporekebishwa. | Ndiyo | +Huendeshwa kwa kila PR kwenda `main`. Huzuia uunganishaji inaposhindwa. + +| Hati (`npm run ...`) | Huthibitisha | Inazuia | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Toleo la Node.js liko ndani ya masafa yanayotumika | Ndiyo | +| `check:cycles` | Uingizaji wa mzunguko katika `src/` + `open-sse/` yote (unategemea AST, `paths` za tsconfig zimetatuliwa). Bare = ushauri, huorodhesha mizunguko. `check:cycles:ratchet` (kile ambacho CI huendesha) huzuia idadi inapozidi kikomo cha `metrics.cycles` katika `quality-baseline.json` — kwa sasa 14, `direction: down`, kwa hivyo inaweza kupungua pekee (#15159 G-01/G-02) | Ndiyo (ratchet) | +| `check:route-validation:t06` | Schema za Zod zipo kwenye route zote (sera ya Tier 6) | Ndiyo | +| `check:any-budget:t11` | Idadi ya `@ts-expect-error // any` haizidi bajeti (catraca ya Tier 11) | Ndiyo | +| `check:provider-consistency` | Kila mtoa huduma katika `providers.ts` ana ingizo linalolingana katika `providerRegistry.ts` (na kinyume chake, ndani ya orodha ya kuruhusu) | Ndiyo | +| `check:model-lifecycle` | Majedwali matatu ya uelekezaji yanayotunzwa kwa mkono yanaendelea kuendana na picha ya hali ya mzunguko wa maisha iliyohifadhiwa (#11503): `FITNESS_TABLE` (`taskFitness.ts`) haitoi alama kwa kitambulisho chochote kilichostaafishwa ambacho `REGISTRY` inaweza kuelekeza; kila lengo la `BUILT_IN_ALIASES` lipo katika `REGISTRY` na halipo katika picha ya hali ya vitambulisho vilivyostaafishwa; kila kitambulisho kilichostaafishwa ambacho bado kipo katika `REGISTRY` kinaelekezwa mbele au kimeorodheshwa katika `allowedRetiredInCatalog`; na hakuna chanzo wala lengo la `DEFAULT_DEGRADATION_MAP` linaloonekana kuwa limestaafishwa katika picha hiyo ya hali. Hili halithibitishi kwamba modeli kwa sasa inahudumiwa na chanzo hai cha juu. Nje ya mtandao — hulinganisha dhidi ya `config/quality/model-lifecycle.json`, inayosasishwa kwa mkono kwa kutumia `npm run quality:refresh-model-lifecycle` (mtandao; haijaunganishwa katika CI). `allowedRetiredInCatalog` ni utaratibu wa kupunguza hatua kwa hatua: ongeza ingizo tu likiwa na suala la ufuatiliaji. | Ndiyo | +| `check:fetch-targets` | Kila `fetch("/api/...")` katika `src/` ya upande wa mteja hutatuliwa hadi `route.ts` halisi | Ndiyo | +| `check:deps` | Vitegemezi vyote vinavyoweza kusakinishwa kwa `npm install` katika kila `package.json` kwenye hifadhi vipo katika `dependency-allowlist.json`; vifurushi vipya visivyofungwa kwa toleo maalum au vilivyosajiliwa kwa jina linalofanana kimakusudi vinawekewa alama | Ndiyo | +| `audit:deps` | `npm audit` (mzizi + electron) — hakuna tahadhari za kiwango cha juu/hatari sana (inaingiliana na osv `check:vuln-ratchet`; angalia Orodha ya Masuala ya Kuratibiwa) | Ndiyo | +| `check:lockfile` | Uadilifu wa `package-lock.json` — sajili ya https, heshi za uadilifu, hakuna ubatilishaji wa seva mwenyeji | Ndiyo | +| `check:licenses` | Orodha ya leseni za SPDX zinazoruhusiwa kwa vitegemezi vya uzalishaji | Ndiyo | +| `check:tracked-artifacts` | Hakuna mabaki ya ujenzi / viungo vya ishara vya `node_modules` vilivyowekwa kwenye hazina (pia huendeshwa katika husky pre-commit; pre-push imefanywa kuwa nyepesi kimakusudi — #6716) | Ndiyo | +| `check:ai-attribution` | Hakuna kionjo cha `Co-Authored-By` cha AI/boti au kijachini cha uzalishaji wa AI katika commit, kichwa au maelezo ya PR — Kanuni Ngumu #16 (katika mzunguko wa ukaguzi wa haraka wa `quality.yml` kwa PR→`release/**` — husoma payload ya tukio, haifanyi chochote nje ya PR — na hatua ya PR pekee katika lint ya `ci.yml` kwa PR→`main`; pia hook ya husky `commit-msg`; waandishi-wenza binadamu wanaruhusiwa; #14436) | +| `check:vitest-exclusions` | Kila utengaji wa Vitest hutaja suala la ufuatiliaji na huonekana katika `config/quality/vitest-exclusions.json` (#13204) | Ndiyo | +| `check:file-size` | Hakuna faili ya msimbo chanzo inayozidi kikomo cha kila kiendelezi (ratchet: faili kubwa zilizogandishwa katika orodha ya `frozen`) | Ndiyo | +| `check:error-helper` | Majibu ya hitilafu katika vitekelezaji/vishughulikiaji hutumia `buildErrorBody()` / `sanitizeErrorMessage()` (Kanuni Ngumu #12) | Ndiyo | +| `check:migration-numbering` | Faili za SQL za uhamishaji zimepewa nambari kwa mfuatano, bila mapengo au marudio | Ndiyo | +| `check:public-creds` | Hakuna OAuth `client_id`/`client_secret` halisi au funguo za Firebase Web nje ya `publicCreds.ts` (Kanuni Ngumu #11) | Ndiyo | +| `check:db-rules` | Hakuna SQL ghafi nje ya moduli za `src/lib/db/`; hakuna uingizaji wa pamoja kutoka `localDb.ts` (Kanuni Ngumu #2/#5) | Ndiyo | +| `check:known-symbols` | Vitekelezaji vya watoa huduma, mikakati ya uelekezaji, na vitafsiri vilivyosajiliwa katika majedwali yao ya usambazaji vinalingana na faili kwenye diski — hakuna alama zisizo na faili husika au ambazo hazijatangazwa | Ndiyo | +| `check:route-guard-membership` | Kila njia inayozindua mchakato mtoto imeainishwa na `isLocalOnlyPath()` (Kanuni Ngumu #15/#17) | Ndiyo | +| `check:test-discovery` | Kila faili ya `*.test.ts` / `*.spec.ts` katika hazina inakusanywa na angalau kiendeshaji kimoja cha majaribio (ratchet: orodha ya faili zisizokusanywa katika `test-discovery-baseline.json` inaweza kupungua pekee) | Ndiyo | +| `check:agent-skills-sync` | Artifakti zilizozalishwa za agent-skills zinalingana na katalogi yao chanzo (hakuna kupotoka) | +| `check:provider-asset-provenance` | Nembo/rasilimali za watoa huduma zina ingizo la asili lililorekodiwa | +| `lint:json` | Faili za usanidi wa JSON zinachanganuliwa na kukidhi kanuni za lint za repo | +| `typecheck:core` | Ukusanyaji wa TypeScript bila hitilafu (maonyo ya ushauri pekee) | Ndiyo | +| `typecheck:noimplicit:core` | `noImplicitAny` kali — inalenga siku zijazo; maeneo mengi ya mwito yaliyokuwepo tayari bado yanahitaji maelezo ya aina | **Ushauri** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` inayolenga `src/app/(dashboard)/**` (#7033) — orodha iliyoruhusiwa ya faili 27 iliyochaguliwa kwa `typecheck:core` haijumuishi TSX yoyote ya dashibodi, na `next build` pia haiikagui aina kamwe (`next.config.mjs` huweka `ignoreBuildErrors: true`), kwa hivyo hitilafu za utambulisho usio na marejeleo huko (#6625/#6909) hazikuonekana kwa CI. Hulinganisha tofauti dhidi ya msingi uliogandishwa wa idadi kwa kila faili/kila msimbo wa TS (`config/quality/dashboard-typecheck-baseline.json`, muundo uleule wa utekelezaji dhidi ya hali iliyopitwa na wakati kama `check:known-symbols`) — ni hitilafu MPYA pekee zinazozidi idadi ya msingi zinazofanya lango lishindwe; punguza msingi hatua kwa hatua kwa `--update` hitilafu iliyokuwepo tayari inaporekebishwa. | Ndiyo | ### Kazi: `quality-gate` -Huendeshwa baada ya `test-coverage`. Huzuia uunganishaji inaposhindwa. +Huendeshwa baada ya `test-coverage`. Huzuia uunganishaji ikishindwa. -| Skripti | Huthibitisha | Inazuia | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ | -| `quality:collect` | Hutoa `quality-metrics.json` (idadi ya maonyo ya ESLint, ufunikaji kutoka kwenye ripoti iliyounganishwa ya sehemu) | Ndiyo (kabla ya ratchet) | -| `quality:ratchet` | Kila kipimo katika `quality-baseline.json` hakijarudi nyuma (maonyo ya ESLint ≤ kiwango cha msingi; ufunikaji ≥ kiwango cha msingi) | Ndiyo | -| `check:duplication` | Urudiaji wa msimbo (jscpd@4) hauzidi kiwango cha msingi katika `quality-baseline.json` | Ndiyo | -| `check:complexity` | Utata wa kisaiklomati katika kiwango cha faili hauzidi kikomo (ESLint ya msingi `complexity` + `max-lines-per-function`) | Ndiyo | -| `check:cognitive-complexity` | Ratchet ya utata wa kiutambuzi (`eslint-plugin-sonarjs`) — utekelezaji tofauti wa ESLint; CI huendesha zote mbili zikiwa zimeunganishwa kama hatua moja ya `check:complexity-ratchets` | Ndiyo | -| `check:dead-code` | Ratchet ya exports / faili zisizotumika (knip) hairudi nyuma ikilinganishwa na kiwango cha msingi | Ndiyo | -| `check:compression-budget` | Bajeti ya kipimo cha utendaji wa ubanaji — viwango vya chini vya uokoaji wa tokeni kwa kila injini havipaswi kurudi nyuma | Ndiyo | -| `check:type-coverage` | Ratchet ya asilimia iliyowekewa aina (`type-coverage`) hairudi nyuma; kwa kiasi kikubwa inajumuisha `typecheck:noimplicit:core` | Ndiyo | -| `check:codeql-ratchet` | Idadi ya arifa zilizo wazi za CodeQL hairudi nyuma (husoma kupitia `gh api`; huruka bila hitilafu pasipo tokeni) — marudio ya uonyeshaji upya na kichochezi cha mkono: tazama "Ratchet ya CodeQL" hapa chini | Ndiyo | +| Skripti | Huthibitisha | Inazuia | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | Hutoa `quality-metrics.json` (idadi ya maonyo ya ESLint, kiwango cha ufunikaji kutoka kwenye ripoti iliyounganishwa ya shard) | Ndiyo (kabla ya ratchet) | +| `quality:ratchet` | Kila kipimo katika `quality-baseline.json` hakijarudi nyuma (maonyo ya ESLint ≤ kiwango cha msingi; ufunikaji ≥ kiwango cha msingi) | Ndiyo | +| `check:duplication` | Urudiaji wa msimbo (jscpd@4) hauzidi kiwango cha msingi katika `quality-baseline.json` | Ndiyo | +| `check:complexity` | Utata wa kisiklomati katika kiwango cha faili hauzidi kikomo (ESLint ya msingi `complexity` + `max-lines-per-function`) | Ndiyo | +| `check:cognitive-complexity` | Ratchet ya utata wa kiutambuzi (`eslint-plugin-sonarjs`) — ukaguzi tofauti wa ESLint; CI huendesha zote mbili zikiwa zimeunganishwa kama hatua moja ya `check:complexity-ratchets` | Ndiyo | +| `check:dead-code` | Ratchet ya exports / faili zisizotumika (knip) hairudi nyuma ikilinganishwa na kiwango cha msingi | Ndiyo | +| `check:compression-budget` | Bajeti ya kipimo cha ulinganishi wa mbano — viwango vya chini vya uokoaji wa tokeni kwa kila injini havipaswi kurudi nyuma | Ndiyo | +| `check:type-coverage` | Ratchet ya asilimia iliyowekewa aina (`type-coverage`) hairudi nyuma; kwa kiasi kikubwa inajumuisha `typecheck:noimplicit:core` | Ndiyo | +| `check:codeql-ratchet` | Idadi ya arifa zilizo wazi za CodeQL hairudi nyuma (husoma kupitia `gh api`; huruka kwa ustaarabu bila tokeni) — marudio ya kuonyesha upya na uanzishaji wa mikono: angalia "Ratchet ya CodeQL" hapa chini | Ndiyo | ### Kazi: `quality-extended` -Kazi nzima ni ya ushauri (`continue-on-error: true`). Ratchet zinazotumia npm huendeshwa -kihalisi; vikaguzi vya nje husakinishwa kupitia `gh release download` na hujiruka vyenyewe (exit 0) -wakati faili tekelezi bado haipo. +Kazi nzima ni ya ushauri (`continue-on-error: true`). Ratchet zinazotegemea npm huendeshwa +kikamilifu; vichanganuzi vya nje husakinishwa kupitia `gh release download` na hujiruka vyenyewe (exit 0) +wakati binary bado haipo. -| Skripti | Huthibitisha | Inazuia | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -| `check:circular-deps` | Hakuna vitegemezi vya mzunguko (dpdm) | **Ya ushauri** | -| `check:bundle-size` | Ukubwa wa kifurushi hauzidi kikomo | **Ya ushauri** | -| `check:secrets` | Uchanganuzi wa siri (gitleaks) — huruka ikiwa faili tekelezi haipo | **Ya ushauri** | -| `check:vuln-ratchet` | Udhaifu wa vitegemezi (osv-scanner) haurudi nyuma — huruka ikiwa faili tekelezi haipo | **Ya ushauri** | -| `check:workflows` | Ukaguzi wa mtiririko wa kazi (actionlint + zizmor); vikaguzi vinavyokosekana/vilivyoharibika, ripoti batili au kiwango cha msingi cha ratchet kinachokosekana hushindwa kama INCOMPLETE. Matokeo halali hufuata sera iliyochaguliwa ya madhubuti/ushauri/ratchet | Utekelezaji unahitajika; ratchet ya zizmor inazuia katika CI | -| `check:openapi-breaking` | Mabadiliko yanayovunja mkataba wa API ya umma (`openapi.yaml`) dhidi ya tawi la msingi (oasdiff) — hutoa `openapiBreaking=N`; huruka ikiwa oasdiff haipo au spec ya msingi haiwezi kutatuliwa | **Ya ushauri** | +| Skripti | Huthibitisha | Inazuia | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------- | +| `check:circular-deps` | Hakuna vitegemezi vya mzunguko (dpdm) | **Ya ushauri** | +| `check:bundle-size` | Ukubwa wa bundle hauzidi kikomo | **Ya ushauri** | +| `check:secrets` | Uchanganuzi wa siri (gitleaks) — huruka ikiwa binary haipo | **Ya ushauri** | +| `check:vuln-ratchet` | Udhaifu wa vitegemezi (osv-scanner) haurudi nyuma — huruka ikiwa binary haipo | **Ya ushauri** | +| `check:workflows` | Ukaguzi wa workflow (actionlint + zizmor); vichanganuzi vinavyokosekana/kuharibika, ripoti batili au kukosekana kwa kiwango cha msingi cha ratchet husababisha INCOMPLETE. Matokeo halali hufuata sera iliyochaguliwa ya strict/advisory/ratchet | Utekelezaji unahitajika; ratchet ya zizmor huzuia katika CI | +| `check:openapi-breaking` | Mabadiliko yanayovunja mkataba wa API ya umma (`openapi.yaml`) dhidi ya tawi la msingi (oasdiff) — hutoa `openapiBreaking=N`; huruka ikiwa oasdiff haipo au spec ya msingi haiwezi kutatuliwa | **Ya ushauri** | ### Kazi: `docs-sync-strict` -Huendeshwa kwenye kila PR kwenda `main`. Huzuia kuunganisha endapo itashindwa. - -| Skripti | Inathibitisha | Inazuia | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `check:docs-all` | Lango kuu linalotekeleza malango madogo 6 yaliyo hapa chini kwa mfuatano | Ndiyo | -| ↳ `check:docs-sync` | Ulinganifu wa matoleo ya CHANGELOG / OpenAPI / llm.txt | Ndiyo | -| ↳ `check:docs-counts` | Idadi katika maelezo (idadi ya watoa huduma, idadi ya uhamishaji, n.k.) ziko ndani ya dirisha la hatua la idadi halisi | Ndiyo | -| ↳ `check:env-doc-sync` | Kila kigezo cha mazingira katika `.env.example` kimeandikwa katika jedwali la nyaraka, na kinyume chake | Ndiyo | -| ↳ `check:deprecated-versions` | Hakuna mifuatano ya matoleo yaliyopitwa na wakati katika nyaraka | Ndiyo | -| ↳ `check:doc-links` | Viungo vya ndani vya markdown katika nyaraka vinaelekeza kwenye faili halisi (muundo wa `[text]`/`(path)`) | Ndiyo | -| ↳ `check:fabricated-docs` | Njia, vigezo vya mazingira, amri za CLI, majina ya hook, na njia za faili zilizotajwa katika nyaraka zipo katika msingi wa msimbo. Lango gumu kupitia `--strict`; hushindwa bila kuzuia bila bendera. | Ndiyo (kupitia `--strict` katika CI) | -| `check:cli-i18n` | Mifuatano ya amri za CLI ipo katika faili zote za lugha za i18n | Ndiyo | -| `check:openapi-coverage` | Vipimo vya OpenAPI vinashughulikia angalau kiwango cha chini kinachoongezeka hatua kwa hatua cha njia halisi | Ndiyo | -| `check:openapi-security-tiers` | Maelezo ya viwango vya usalama katika `openapi.yaml` yanalingana na uainishaji wa `routeGuard.ts` | **Ushauri** | -| `check:openapi-routes` | Kila path katika `openapi.yaml` inaelekeza kwenye `route.ts` halisi (kuzuia taarifa za kubuniwa) | Ndiyo | -| `check:docs-symbols` | Kila rejeleo la `/api/...` katika `docs/**/*.md` linaelekeza kwenye `route.ts` halisi (kuzuia taarifa za kubuniwa) | Ndiyo | -| `i18n translation drift` | Funguo ambazo hazijatafsiriwa katika faili za lugha za i18n — onyo pekee | **Ushauri** | +Huendeshwa kwenye kila PR kwenda `main`. Huzuia uunganishaji ikifeli. + +| Skripti | Inathibitisha | Inazuia | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ | +| `check:docs-all` | Kizuizi kikuu kinachoendesha vizuizi vidogo 6 vilivyo hapa chini kwa mfuatano | Ndiyo | +| ↳ `check:docs-sync` | Ulinganifu wa matoleo ya CHANGELOG / OpenAPI / llm.txt | Ndiyo | +| ↳ `check:docs-counts` | Idadi zilizo katika maandishi (idadi ya watoa huduma, idadi ya uhamishaji, n.k.) ziko ndani ya dirisha la ratchet la idadi halisi | Ndiyo | +| ↳ `check:env-doc-sync` | Kila kigezo cha mazingira katika `.env.example` kimeandikwa katika jedwali la nyaraka, na kinyume chake | Ndiyo | +| ↳ `check:deprecated-versions` | Hakuna mifuatano ya matoleo yaliyopitwa na wakati katika nyaraka | Ndiyo | +| ↳ `check:doc-links` | Viungo vya ndani vya markdown katika nyaraka vinaelekeza kwenye faili halisi (muundo wa `[text]`/`(path)`) | Ndiyo | +| ↳ `check:fabricated-docs` | Njia, vigezo vya mazingira, amri za CLI, majina ya hook, na njia za faili zilizotajwa katika nyaraka zipo katika codebase. Kizuizi kigumu kupitia `--strict`; hushindwa kwa tahadhari bila flag. | Ndiyo (kupitia `--strict` katika CI) | +| `check:cli-i18n` | Mifuatano ya amri za CLI ipo katika faili zote za lugha za i18n | Ndiyo | +| `check:openapi-coverage` | Vipimo vya OpenAPI vinajumuisha angalau kiwango cha chini kilichowekwa kwa ratchet cha njia halisi | Ndiyo | +| `check:openapi-security-tiers` | Maelezo ya viwango vya usalama katika `openapi.yaml` yanaendana na uainishaji wa `routeGuard.ts` | **Ushauri** | +| `check:openapi-routes` | Kila njia katika `openapi.yaml` inaelekeza kwenye `route.ts` halisi (kuzuia uzushi) | Ndiyo | +| `check:docs-symbols` | Kila rejeleo la `/api/...` katika `docs/**/*.md` linaelekeza kwenye `route.ts` halisi (kuzuia uzushi) | Ndiyo | +| `i18n translation drift` | Funguo ambazo hazijatafsiriwa katika faili za lugha za i18n — onyo pekee | **Ushauri** | ### Kazi: `i18n-ui-coverage` -| Skripti | Inathibitisha | Inazuia | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check-ui-keys-coverage` (inline) | Ushughulikiaji wa funguo za UI za i18n ni ≥ 65% | Ndiyo | -| `check-ui-value-drift` (inline) | **Thamani** ya Kiingereza iliyoandikwa upya haiachi tafsiri yoyote ya zamani | Ndiyo | -| `check-new-key-coverage` (inline) | Ufunguo **mpya** wa Kiingereza umetafsiriwa katika kila lugha — alama ya `__MISSING__:` inakataliwa | Ndiyo | -| `check-translation-ratio` | Uwiano wa tafsiri halisi kwa kila lugha (zinazofanana na Kiingereza / vibadala / thamani zinazokosekana nje ya orodha ya kuruhusu) haupaswi kuzidi `config/quality/i18n-translation-baseline.json` + nafasi ya ziada | **Ushauri** | +| Skripti | Inathibitisha | Inazuia | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (inline) | Ujumuishaji wa funguo za i18n za UI ni ≥ 65% | Ndiyo | +| `check-ui-value-drift` (inline) | **Thamani** ya Kiingereza iliyoandikwa upya haiachi tafsiri yoyote ya zamani | Ndiyo | +| `check-new-key-coverage` (inline) | Ufunguo **mpya** wa Kiingereza umetafsiriwa katika kila lugha — kiashirio cha `__MISSING__:` kinakataliwa | Ndiyo | +| `check-translation-ratio` | Uwiano wa tafsiri halisi kwa kila lugha (zinazofanana na Kiingereza / kishikilia nafasi / zilizoachwa bila kutafsiri nje ya orodha inayoruhusiwa) haupaswi kuzidi `config/quality/i18n-translation-baseline.json` + nafasi ya ziada | **Ushauri** | -Inahitaji `fetch-depth: 0` — lango la mabadiliko ya thamani hulinganisha tofauti za `en.json` dhidi ya msingi wa kuunganisha. +Inahitaji `fetch-depth: 0` — kizuizi cha mabadiliko ya thamani hulinganisha `en.json` dhidi ya merge base. -#### `check-ui-value-drift` — lango la tafsiri zilizopitwa na wakati +#### `check-ui-value-drift` — kizuizi cha tafsiri za zamani -Hunasa hitilafu moja ya i18n ambayo malango mengine hayawezi kuiona kimuundo: thamani ya Kiingereza +Hugundua hitilafu moja ya i18n ambayo vizuizi vingine haviwezi kuiona kimuundo: thamani ya Kiingereza inaandikwa upya huku tafsiri zilizotokana na Kiingereza cha _awali_ zikibaki, hivyo -watumiaji wasiotumia Kiingereza huendelea kusoma maandishi yenye kujiamini lakini ambayo sasa si sahihi. +watumiaji wasiotumia Kiingereza wanaendelea kusoma maandishi yenye uhakika lakini ambayo sasa si sahihi. -Hili lilitolewa katika toleo halisi. `oauthModal.googleOAuthWarning` iliandikwa upya wakati kisaidizi cha -kuingia cha Antigravity kilipoanzishwa (#5203); **lugha 39 kati ya 43** zilibakiza maandishi yaliyowaambia waendeshaji “kunakili -URL kamili na kuibandika hapa chini” — mtiririko ambao hauwezi kukamilika kwa mtoa huduma huyo. Hili +Hili lilitolewa kwa watumiaji katika hali halisi. `oauthModal.googleOAuthWarning` iliandikwa upya wakati kisaidizi cha kuingia cha Antigravity +kilipoletwa (#5203); **lugha 39 kati ya 43** zilibaki na maandishi yaliyowaambia waendeshaji "kunakili +URL kamili na kuibandika hapa chini" — mtiririko ambao hauwezi kukamilika kwa mtoa huduma huyo. Hili halikugunduliwa hadi #8463 kwa sababu: -- `sync-ui-keys` hujaza tu funguo ambazo **hazipo**, kamwe si zile ambazo **zimepitwa na wakati**; -- `check-ui-keys-coverage` huhesabu _uwepo_ wa ufunguo, hivyo tafsiri iliyopitwa na wakati huhesabiwa kuwa imeshughulikiwa; +- `sync-ui-keys` huongeza tu funguo ambazo **hazipo**, kamwe si zile ambazo ni **za zamani**; +- `check-ui-keys-coverage` huhesabu _uwepo_ wa funguo, hivyo tafsiri ya zamani huhesabiwa kuwa imejumuishwa; - `check-translation-drift` hufuatilia vioo vya nyaraka vya `docs/i18n//**.md` — - haisomi kamwe `src/i18n/messages/*.json`. Inazuia katika kazi ya `docs-sync-strict` tangu - usawazishaji upya wa 2026-09: hariri waraka mkuu → `npm run i18n:run -- --files=` (kwa kiwango cha sehemu, gharama ndogo). + haisomi kamwe `src/i18n/messages/*.json`. Inazuia katika kazi `docs-sync-strict` tangu usawazishaji upya wa + 2026-09: hariri hati kuu → `npm run i18n:run -- --files=` (kwa kiwango cha sehemu, gharama nafuu). -**Inatambua diff, haitegemei baseline.** Inalinganisha `en.json` kwenye merge base dhidi ya -working tree; kwa kila key ambayo thamani yake ya Kiingereza imebadilika, locale yoyote ambayo bado ina -tafsiri ambayo haijaguswa imepitwa na wakati. Hii kwa makusudi **inagandisha deni lililokuwepo awali** — diff -haiwezi kufichua tafsiri ya muda mrefu ilitokana na Kiingereza gani cha zamani, kwa hivyo gate hutathmini -tu kile ambacho badiliko la sasa linagusa. Njia mbadala (baseline ya hash kwa kila key) ingehitaji -faili inayozalishwa ya ~600 KB, kubwa mara 3 kuliko baseline kubwa zaidi iliyopo, na ingebadilika katika kila PR ya i18n. +**Inatambua tofauti, haitegemei baseline.** Hulinganisha `en.json` kwenye merge base dhidi ya +working tree; kwa kila ufunguo ambao thamani yake ya Kiingereza imebadilika, locale yoyote ambayo bado ina +tafsiri ambayo haijaguswa imepitwa na wakati. Hii kwa makusudi **hufungia deni lililokuwepo awali** — diff +haiwezi kubaini tafsiri ya muda mrefu ilitokana na Kiingereza gani cha zamani, kwa hivyo gate hutathmini +tu kile ambacho badiliko la sasa linagusa. Njia mbadala (baseline ya hash kwa kila ufunguo) ingeongeza +faili iliyozalishwa ya ~600 KB, mara 3 ya baseline kubwa zaidi iliyopo, huku ikibadilika katika kila PR ya i18n. -Njia mbili za kuitimiza: +Njia mbili za kukidhi sharti hili: 1. sasisha tafsiri zilizoathiriwa, au 2. ziweke kuwa `__MISSING__:` — wakati wa utekelezaji kisha hutoa Kiingereza kilichosahihishwa - (`src/i18n/request.ts::deepMergeFallback`, #7258), na key huingizwa kwenye foleni ya kutafsiriwa. + (`src/i18n/request.ts::deepMergeFallback`, #7258) na ufunguo huwekwa kwenye foleni ya kutafsiriwa. -Ikiwa **maana** ya string imebadilika, ni bora **kubadilisha jina la key**: key mpya haiwezi kurithi -tafsiri iliyopitwa na wakati. Huo ndio muundo uliotumiwa na #8463. +Ikiwa **maana** ya kifungu imebadilika, ni vyema zaidi **kubadilisha jina la ufunguo**: ufunguo mpya hauwezi kurithi +tafsiri iliyopitwa na wakati. Huo ndio mtindo uliotumiwa na #8463. ```bash -npm run i18n:check-value-drift # madhubuti (kile ambacho CI huendesha) +npm run i18n:check-value-drift # hali kali (kile CI huendesha) npm run i18n:check-value-drift:warn # toa ripoti pekee BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Hutoka kwa 0 ikiwa na `SKIP reason=base-unresolved` wakati katalogi ya msingi haiwezi kusomwa (shallow +Hutoka kwa msimbo 0 pamoja na `SKIP reason=base-unresolved` wakati katalogi ya msingi haiwezi kusomwa (shallow clone isiyo na base ref), sawa na `check-openapi-breaking`. -### Job: `i18n` +### Kazi: `i18n` -Matrix kamili ya uthibitishaji wa i18n (job moja kwa kila locale). Job nzima ni ya ushauri. +Matriki kamili ya uthibitishaji wa i18n (kazi moja kwa kila locale). Kazi nzima ni ya ushauri. -| Script | Huthibitisha | Uzuiaji | -| ------------------------------- | ------------------------------------ | ----------------------------------------------------------- | -| `validate_translation.py quick` | Ukamilifu wa tafsiri kwa kila locale | **Ya ushauri** (`continue-on-error: true` kwenye job nzima) | +| Skripti | Huthibitisha | Uzuiaji | +| ------------------------------- | ------------------------------------ | ------------------------------------------------------------ | +| `validate_translation.py quick` | Ukamilifu wa tafsiri kwa kila locale | **Ya ushauri** (`continue-on-error: true` kwenye kazi nzima) | -### Job: `pr-test-policy` +### Kazi: `pr-test-policy` -Huendeshwa kwenye pull requests pekee. +Huendeshwa kwenye pull request pekee. -| Script | Huthibitisha | Uzuiaji | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `check:pr-test-policy` | PR zinazobadilisha code ya uzalishaji katika `src/`, `open-sse/`, `electron/`, au `bin/` lazima zijumuishe au zisasisha tests (Kanuni Ngumu #8) | Ndiyo | -| `check:test-masking` | Faili za test zilizobadilishwa hazipunguzi jumla halisi ya idadi ya assertions wala kuongeza tautolojia za `assert.ok(true)` | Ndiyo | -| `check:pr-evidence` | Maelezo ya PR yanataja ushahidi wa test/VPS wa badiliko (huifanya Kanuni Ngumu #18 kuwa ya kiotomatiki kwa kutafuta maandishi ya PR — ni dhaifu, angalia Orodha ya kazi zilizobaki) | Ndiyo | +| Skripti | Huthibitisha | Uzuiaji | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `check:pr-test-policy` | PR zinazobadilisha msimbo wa uzalishaji katika `src/`, `open-sse/`, `electron/`, au `bin/` lazima zijumuishe au zisasisha majaribio (Kanuni Ngumu #8) | Ndiyo | +| `check:test-masking` | Faili za majaribio zilizobadilishwa hazipunguzi jumla halisi ya idadi ya assert wala kuongeza tautolojia za `assert.ok(true)` | Ndiyo | +| `check:pr-evidence` | Maelezo ya PR yanataja ushahidi wa jaribio/VPS kuhusu badiliko (hufanyia Kanuni Ngumu #18 utekelezaji kiotomatiki kwa kutumia grep kwenye maelezo ya PR — ni dhaifu, angalia Backlog) | Ndiyo | -### Job: `test-vitest` +### Kazi: `test-vitest` -Huendeshwa baada ya `build`. Huzuia merge ikifeli. +Huendeshwa baada ya `build`. Huzuia merge ikishindwa. -| Suite | Huthibitisha | Uzuiaji | -| ---------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (tools 110), autoCombo, cache — vitest runner | Ndiyo | -| `test:vitest:ui` | Tests za UI components — vitest runner | **Huzuia** — failures zilizokuwepo awali zimeondolewa waziwazi katika `vitest.config.ts`; failures mpya husababisha job ifeli | +| Suite | Huthibitisha | Uzuiaji | +| ---------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Seva ya MCP (zana 110), autoCombo, cache — kiendesha vitest | Ndiyo | +| `test:vitest:ui` | Majaribio ya vijenzi vya UI — kiendesha vitest | **Huzuia** — hitilafu zilizokuwepo awali zimeondolewa waziwazi katika `vitest.config.ts`; hitilafu mpya husababisha kazi kushindwa | -### Workflows za kila usiku (zimeratibiwa, za ushauri) +### Workflow za kila usiku (zimeratibiwa, za ushauri) Hizi huendeshwa kwa ratiba ya cron (na `workflow_dispatch`), kamwe si kwenye PR. Zote ni za ushauri. -| Workflow | Huthibitisha | Uzuiaji | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | Tests za property za fast-check zenye seed nasibu + idadi kubwa ya runs | **Ya ushauri** | -| `nightly-resilience` | gate ya ukuaji wa heap, chaos fault-injection, load/soak ya k6 | **Ya ushauri** | -| `nightly-llm-security` | ulinzi wa injection wa promptfoo (block mode) + probes za garak (hurukwa bila provider secret) | **Ya ushauri** | -| `nightly-schemathesis` | Fuzzing ya mkataba wa OpenAPI (schemathesis) dhidi ya OmniRoute inayofanya kazi kwa kutumia `docs/openapi.yaml` — hufichua ukiukaji wa spec / 500 ambazo hazijashughulikiwa (Awamu ya 8 B.4) | **Ya ushauri** | -| `nightly-mutation` | Alama ya mutation-testing ya Stryker kwenye mkondo wa haraka wa unit — mutants zinazonusurika hufichua assertions dhaifu | **Ya ushauri** | -| `nightly-compat` | Matrix ya uoanifu wa Node engine katika safu zinazotumika za `engines.node` | **Ya ushauri** | +| Workflow | Huthibitisha | Uzuiaji | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | Majaribio ya sifa ya fast-check yenye seed ya nasibu + idadi kubwa ya utekelezaji | **Ya ushauri** | +| `nightly-resilience` | gate ya ukuaji wa heap, uingizaji wa hitilafu wa chaos, mzigo/soak wa k6 | **Ya ushauri** | +| `nightly-llm-security` | kinga ya promptfoo dhidi ya injection (hali ya block) + uchunguzi wa garak (hurukwa bila siri ya mtoa huduma) | **Ya ushauri** | +| `nightly-schemathesis` | Fuzzing ya mkataba wa OpenAPI (schemathesis) dhidi ya OmniRoute inayotumika kwa kutumia `docs/openapi.yaml` — huibua ukiukaji wa spec / hitilafu za 500 zisizoshughulikiwa (Awamu ya 8 B.4) | **Ya ushauri** | +| `nightly-mutation` | Alama ya majaribio ya mutation ya Stryker kwenye mkondo wa haraka wa unit — mutants zinazonusurika huibua assert dhaifu | **Ya ushauri** | +| `nightly-compat` | Matriki ya uoanifu wa injini ya Node katika masafa yanayotumika ya `engines.node` | **Ya ushauri** | --- @@ -536,42 +536,42 @@ kosa la muunganisho na kamwe halivunji vipindi. --- -## Orodha ya Kazi za Urasimishaji (mapitio ya ROI — Awamu ya 9 Wimbi la 3) +## Orodha ya Maboresho Yanayosubiri (mapitio ya ROI — Awamu ya 9 Wimbi la 3) Orodha hii ilioanishwa na `ci.yml` tarehe 2026-06-17 (toleo la awali liliacha `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, `check:codeql-ratchet`, `check:pr-evidence`). Mapitio ya ROI ya seti iliyoanishwa -yalibaini vipengee vifuatavyo vinavyoweza kurasimishwa. **Miunganisho ni mabadiliko ya kiufundi ya CI; -mabadiliko/ufutaji ni maamuzi ya sera yaliyohifadhiwa kwa mwendeshaji.** Hakuna chochote hapa chini -ambacho bado kimetekelezwa. - -**Pia hayajaandikwa hapo juu** (ya ushauri, ishara dhaifu): job ya `docs-lint` -(markdownlint + Vale, job nzima ikiwa na `continue-on-error`) na workflows huru za uchanganuzi -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ipo katika -`quality-baseline.json` lakini haijaunganishwa na ratchet inayozuia katika `ci.yml` — kipimo hicho +yalibaini yafuatayo kuwa mambo yanayoweza kurahisishwa. **Miunganisho hiyo ni mabadiliko +ya kimakanika ya CI; mabadiliko ya hali/ufutaji ni maamuzi ya sera yaliyohifadhiwa kwa +mwendeshaji.** Hakuna kilicho hapa chini ambacho kimetekelezwa bado. + +**Pia hayajaandikwa hapo juu** (ya ushauri, ishara dhaifu): kazi ya `docs-lint` +(markdownlint + Vale, kazi nzima ikiwa na `continue-on-error`) na mitiririko huru ya kazi +ya uchanganuzi `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` ipo +katika `quality-baseline.json` lakini haijaunganishwa na ratchet inayozuia katika `ci.yml` — kipimo hicho kwa sasa hakijaunganishwa na chochote. -### Unganisha / ondoa urudufu (kiufundi, hatari ndogo) +### Unganisha / ondoa urudufu (kimakanika, hatari ndogo) -Kila kipengee kilithibitishwa dhidi ya hali halisi ya gate tarehe 2026-06-17 (amini-lakini-thibitisha); -miunganisho kadhaa iliyoonekana kuwa "dhahiri" ilibainika kuficha deni na **si** mbadala safi. +Kila kipengele kilithibitishwa dhidi ya hali halisi ya vizuizi tarehe 2026-06-17 (amini-lakini-thibitisha); +miunganisho kadhaa "iliyo dhahiri" ilibainika kuficha deni na **si** vibadala safi vinavyoweza kuwekwa moja kwa moja. -- **`check:docs-sync` huendeshwa mara mbili** — kivyake katika job ya `lint` na tena ndani ya `check:docs-all` (`docs-sync-strict`) na hook ya husky ya pre-commit. ✅ **IMEKAMILIKA** — utekelezaji wa pekee wa `lint` umeondolewa. -- **Uchanganuzi wa CVE** — ❌ **SI muunganisho safi.** `audit:deps` hushindwa moja kwa moja kwa CVE yoyote ya kiwango cha juu/muhimu; `check:vuln-ratchet` (osv) hushindwa tu kunapokuwa na _kurudi nyuma_ ikilinganishwa na baseline (kwa sasa 1 MODERATE). Semantiki ni tofauti — kuondoa `audit:deps` kungeondoa gate kamili ya kiwango cha juu/muhimu. Zihifadhi zote mbili. -- **Ugunduzi wa mizunguko** — ❌ **SI muunganisho safi.** `check:circular-deps` (dpdm) huripoti **mizunguko 91** (hiyo ndiyo sababu ni ya ushauri); haiwezi kupandishwa kuwa ya kuzuia bila kwanza kuitatua, na ina upeo mpana zaidi kuliko `check:cycles` iliyochaguliwa kwa makusudi na inayofaulu. Endelea kuweka `check:cycles` kama ya kuzuia; kutatua mizunguko 91 ya dpdm ni kazi tofauti katika orodha ya kazi. -- **Utata** — ✅ **IMEKAMILIKA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): upitishaji mmoja wa ESLint, huhesabu kwa ruleId ili baseline za cyclomatic+max-lines na cognitive ziendelee kuwa huru; `check:complexity` / `check:cognitive-complexity` binafsi zinasalia kwa `--update` ya ndani. -- **Uzuiaji wa uzushi wa `/api`** — ✅ **IMEKAMILIKA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): orodha moja ya FS ya `src/app/api`, openapi-routes + docs-symbols bado huripoti kivyake; kila moja inasalia kwa utekelezaji wa ndani. -- **`check:node-runtime` huendeshwa katika jobs 11** — ⚠️ **ROI ndogo.** Kila moja ni runner tofauti na ukaguzi ni <1s; jumla ya muda unaookolewa ni ~10s, dhidi ya kupoteza ulinzi wa bei nafuu kwa kila job. Haifai usumbufu wa mabadiliko hayo. -- **`typecheck:noimplicit:core` kwenye lint ya CI** — ✅ **imeondolewa kwenye job ya lint** (ilikuwa ya ushauri ikiwa na `continue-on-error`); eneo la aina linalozuia ni `typecheck:core` + `check:type-coverage`. Script ya ndani imehifadhiwa. +- **`check:docs-sync` huendeshwa mara mbili** — kivyake katika kazi ya `lint` na tena ndani ya `check:docs-all` (`docs-sync-strict`) na hook ya husky ya pre-commit. ✅ **IMEKAMILIKA** — mwito wa pekee wa `lint` umeondolewa. +- **Uchanganuzi wa CVE** — ❌ **SI muunganisho safi.** `audit:deps` hushindwa moja kwa moja kwa CVE yoyote ya kiwango cha juu/muhimu; `check:vuln-ratchet` (osv) hushindwa tu kunapokuwa na _kurudi nyuma_ ikilinganishwa na baseline (kwa sasa 1 MODERATE). Maana zake ni tofauti — kuondoa `audit:deps` kungeondoa kizuizi kamili cha kiwango cha juu/muhimu. Zihifadhi zote mbili. +- **Ugunduzi wa mizunguko** — ✅ **IMEKAMILIKA** (#15159 G-01/G-02). Maandishi ya zamani hapa yaliita `check:cycles` kizuizi "cha kijani, kilichoratibiwa" na kuhalalisha kukiweka kama kizuizi kwa sababu `check:circular-deps` (dpdm) iliripoti mizunguko 91. Hali hiyo ya kijani ilikuwa **hali ya kijani ya uongo**: `check:cycles` ilichanganua saraka ndogo 5 (faili 450), ililinganisha tu `import|export … from` tuli, na ilitupilia mbali kila kibainishi cha `@/` na `@omniroute/open-sse/`, kwa hivyo haikuweza kuona mizunguko ya dynamic-import + alias iliyotawala repo. Imerekebishwa: kizuizi sasa hupitia `src` + `open-sse` (faili 5023), hukusanya vibainishi kutoka TypeScript AST (kwa hivyo `import("…")` huhesabiwa lakini `typeof import("…")` ya nafasi ya aina haihesabiwi), na hutatua `paths` za tsconfig. Kinapata mizunguko **14**, si 0. Kwa kuwa mizunguko 14 iliyokuwepo awali haiwezi kurekebishwa katika PR ya kizuizi, `check:cycles` sasa ni **ratchet** (`--ratchet`, kikomo `metrics.cycles.value = 14` katika `quality-baseline.json`, `direction: down`) — huzuia _kurudi nyuma_ kokote na idadi inaweza kupungua tu. CI huendesha `npm run check:cycles:ratchet`. Upunguzaji wa hatua kwa hatua unaendelea pamoja na **A-01**. `check:circular-deps` (dpdm) inabaki kuwa ya ushauri kama maoni mapana ya pili. +- **Uchangamani** — ✅ **IMEKAMILIKA** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): mpito mmoja wa ESLint, huhesabu kwa ruleId ili baseline za cyclomatic+max-lines na cognitive zibaki huru; `check:complexity` / `check:cognitive-complexity` binafsi zinabaki kwa `--update` ya ndani. +- **Kuzuia uzushi wa `/api`** — ✅ **IMEKAMILIKA** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): orodha moja ya FS ya `src/app/api`, openapi-routes + docs-symbols bado huripoti kivyake; kila moja inabaki kwa utekelezaji wa ndani. +- **`check:node-runtime` huendeshwa katika kazi 11** — ⚠️ **ROI ndogo.** Kila moja ni runner tofauti na ukaguzi ni <1s; jumla ya muda unaookolewa ni ~10s, dhidi ya kupoteza ulinzi nafuu wa kila kazi. Haifai usumbufu wa mabadiliko. +- **`typecheck:noimplicit:core` kwenye lint ya CI** — ✅ **imeondolewa kwenye kazi ya lint** (ilikuwa ya ushauri ikiwa na `continue-on-error`); sehemu ya aina inayozuia ni `typecheck:core` + `check:type-coverage`. Script ya ndani imehifadhiwa. -### Badilisha / amua (sera ya mwendeshaji) +### Badilisha hali / amua (sera ya mwendeshaji) -- `check:openapi-security-tiers` (ya ushauri) — ❌ **HAIWEZI kubadilishwa moja kwa moja.** Hutoka kwa 0 lakini huonya kwamba routes kadhaa za `traffic-inspector` chini ya `LOCAL_ONLY_API_PREFIXES` hazina ufafanuzi wa `x-loopback-only: true`. Kuitekeleza kunahitaji kwanza kuongeza maelezo hayo kwenye `openapi.yaml`. -- `typecheck:noimplicit:core` (ya ushauri) — kwa kiasi kikubwa imejumuishwa na ratchet ya `check:type-coverage` inayozuia. Ibadilishe iwe ratchet au ondoa upitishaji wa pili wa `tsc` wenye urudufu. -- `test:vitest:ui` (sasa **inazuia**) — hitilafu zilizokuwepo tayari zimeondolewa waziwazi katika `vitest.config.ts` kwa maoni ya ufuatiliaji ya `// #8618`; hitilafu mpya husababisha job ishindwe. -- `check:secrets` (gitleaks, ratchet inayozuia iliyogandishwa kwenye matokeo 3 ya uongo yaliyoandikwa) — yaweke hayo 3 kwenye allowlist ili kufikia 0, au ishushwe kuwa ya ushauri. Inaingiliana na uchanganuzi asilia wa siri wa GitHub + `check:public-creds`. -- `check:pr-evidence` (inazuia, hutafuta maandishi katika maelezo ya PR kwa grep) — hatari kubwa ya matokeo ya uongo; kuiondoa hudhoofisha utekelezaji wa Kanuni Ngumu #18, kwa hivyo huu ni uamuzi halisi wa sera. +- `check:openapi-security-tiers` (ya ushauri) — ❌ **HAIWEZI kubadilishwa hali kwa usafi.** Hutoka kwa 0 lakini huonya kuwa routes kadhaa za `traffic-inspector` chini ya `LOCAL_ONLY_API_PREFIXES` hazina anoteshini ya `x-loopback-only: true`. Kuilazimisha kunahitaji kwanza kuongeza anoteshini hizo kwenye `openapi.yaml`. +- `typecheck:noimplicit:core` (ya ushauri) — kwa kiasi kikubwa imejumuishwa na ratchet inayozuia ya `check:type-coverage`. Ibadilishe kuwa ratchet au ondoa mpito wa pili wa `tsc` unaojirudia. +- `test:vitest:ui` (sasa **inazuia**) — hitilafu zilizokuwepo awali zimeondolewa waziwazi katika `vitest.config.ts` kwa maoni ya ufuatiliaji ya `// #8618`; hitilafu mpya husababisha kazi kushindwa. +- `check:secrets` (gitleaks, ratchet inayozuia iliyogandishwa katika false-positive 3 zilizoandikwa) — ziweke hizo 3 kwenye allowlist ili kufikia 0, au ishushe kuwa ya ushauri. Inaingiliana na uchanganuzi asilia wa siri wa GitHub + `check:public-creds`. +- `check:pr-evidence` (inazuia, hutafuta maandishi ya mwili wa PR kwa grep) — hatari kubwa ya false-positive; kuiondoa kunadhoofisha utekelezaji wa Hard Rule #18, kwa hivyo hili ni chaguo halisi la sera. - `semgrep` (huru na ya ushauri) — inaingiliana na CodeQL kwa familia za OWASP; unganisha baseline yake na ratchet au iondoe. --- diff --git a/docs/i18n/ta/CONTRIBUTING.md b/docs/i18n/ta/CONTRIBUTING.md index c19a3d1d709..8be0bee151e 100644 --- a/docs/i18n/ta/CONTRIBUTING.md +++ b/docs/i18n/ta/CONTRIBUTING.md @@ -392,16 +392,16 @@ OAuth நற்சான்றுகளை `src/lib/oauth/constants/oauth.ts`- - [ ] Linting வெற்றிபெறுகிறது (`npm run lint`) - [ ] Build வெற்றிபெறுகிறது (`npm run build`) - [ ] புதிய public functions மற்றும் interfaces-க்கு TypeScript types சேர்க்கப்பட்டுள்ளன -- [ ] Hardcoded secrets அல்லது fallback values எதுவும் இல்லை -- [ ] Public upstream credentials, literals-ஆக அல்லாமல் `resolvePublicCred()` வழியாக உட்பொதிக்கப்பட்டுள்ளன ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)-ஐப் பார்க்கவும்) +- [ ] Hardcoded secrets அல்லது fallback values இல்லை +- [ ] Public upstream credentials, literals-ஆக ஒருபோதும் இல்லாமல், `resolvePublicCred()` வழியாகப் பதிக்கப்பட்டுள்ளன ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)-ஐப் பார்க்கவும்) - [ ] Error responses, `buildErrorBody()` / `sanitizeErrorMessage()` வழியாக அனுப்பப்படுகின்றன — response bodies-இல் raw stack traces இல்லை ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)-ஐப் பார்க்கவும்) - [ ] Shell commands (`exec` / `spawn`), runtime values-ஐ string interpolation வழியாக அல்லாமல் `env` வழியாக அனுப்புகின்றன - [ ] அனைத்து inputs-உம் Zod schemas மூலம் சரிபார்க்கப்பட்டுள்ளன -- [ ] பயனர்களுக்குத் தெரியக்கூடிய மாற்றங்களுக்கு `changelog.d/{features|fixes|maintenance}/-.md`-இன் கீழ் Changelog **fragment** சேர்க்கப்பட்டுள்ளது ([`changelog.d/README.md`](./changelog.d/README.md)-ஐப் பார்க்கவும்) — `CHANGELOG.md`-ஐ நேரடியாகத் திருத்த **வேண்டாம்**; fragments, release நேரத்தில் ஒருங்கிணைக்கப்படுவதால் PR-களுக்கு இடையே ஒருபோதும் முரண்படாது +- [ ] பயனர்கள் காணக்கூடிய மாற்றங்களுக்கு `changelog.d/{features|fixes|maintenance}/-.md`-இன் கீழ் Changelog **fragment** சேர்க்கப்பட்டுள்ளது ([`changelog.d/README.md`](./changelog.d/README.md)-ஐப் பார்க்கவும்) — `CHANGELOG.md`-ஐ நேரடியாகத் திருத்த **வேண்டாம்**; fragments வெளியீட்டு நேரத்தில் ஒருங்கிணைக்கப்படுவதால், PR-களுக்கு இடையே ஒருபோதும் முரண்படாது - [ ] ஆவணங்கள் புதுப்பிக்கப்பட்டுள்ளன (பொருந்தினால்) -- [ ] புதிய CodeQL / Secret-Scanning alerts எதுவும் உருவாக்கப்படவில்லை, அல்லது ஒவ்வொன்றும் தொடர்புடைய `docs/security/` ஆவணத்தை மேற்கோளிட்டு தொழில்நுட்ப நியாயத்துடன் நிராகரிக்கப்பட்டுள்ளது -- [ ] Child processes-ஐ உருவாக்கும் routes (`/api/mcp/`, `/api/cli-tools/runtime/`), `src/server/authz/routeGuard.ts`-இல் `isLocalOnlyPath()` என வகைப்படுத்தப்பட்டுள்ளன — [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md)-ஐப் பார்க்கவும் -- [ ] Commit messages-இல் `Co-Authored-By` trailers இல்லை — commits, repository உரிமையாளரின் Git identity-இன் கீழ் மட்டுமே தோன்ற வேண்டும் (Hard Rule #16) +- [ ] புதிய CodeQL / Secret-Scanning alerts எதுவும் உருவாக்கப்படவில்லை; அல்லது ஒவ்வொன்றும் தொடர்புடைய `docs/security/` ஆவணத்தைக் குறிப்பிடும் தொழில்நுட்ப நியாயத்துடன் நிராகரிக்கப்பட்டுள்ளது +- [ ] Child processes-ஐத் தொடங்கும் routes (`/api/mcp/`, `/api/cli-tools/runtime/`), `src/server/authz/routeGuard.ts`-இல் `isLocalOnlyPath()` என வகைப்படுத்தப்பட்டுள்ளன — [Hard Rule #15](docs/security/ROUTE_GUARD_TIERS.md)-ஐப் பார்க்கவும் +- [ ] Commit messages-இல் AI/bot `Co-authored-by` trailers இல்லை (Hard Rule #16) — மீண்டும் பயன்படுத்தப்பட்ட பணிக்குரிய மனித collaborators, நிலையான `Co-authored-by: Name ` trailers மூலம் குறிப்பிடப்பட்டுள்ளனர் --- diff --git a/docs/i18n/ta/docs/architecture/QUALITY_GATES.md b/docs/i18n/ta/docs/architecture/QUALITY_GATES.md index a655988c810..30be51815b6 100644 --- a/docs/i18n/ta/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ta/docs/architecture/QUALITY_GATES.md @@ -15,208 +15,208 @@ ratchet baseline அல்லது pass/fail கொள்கையைப் ப --- -## கேட் இருப்புப் பட்டியல் மற்றும் செயலாக்க சுயவிவரங்கள் - -### வேட்பாளர் ஏற்பு - -CI மற்றும் Quality Gates பணிப்பாய்வுகள் ஒவ்வொன்றும் நிலையான ஒரு தீர்ப்பை வெளியிடுகின்றன: `Gate / CI` மற்றும் -`Gate / Quality`. அவற்றின் பதிப்பிடப்பட்ட ஏற்புக் கொள்கை, மேல்நிலைப் பணிகள் அனைத்தையும் -கட்டாயமானவை அல்லது ஆலோசனை சார்ந்தவை எனப் பட்டியலிடுகிறது. பொருந்தக்கூடிய கட்டாயப் பணி வெற்றிபெற வேண்டும்: -காணாமல் போன, ரத்துசெய்யப்பட்ட, தவிர்க்கப்பட்ட, நிலுவையிலுள்ள மற்றும் அறியப்படாத முடிவுகள் PASS என்பதை நிறுவ முடியாது. செல்லுபடியாகும் -docs-only அல்லது catalog-only வகைப்பாடு ஒரு code lane-ஐப் பொருந்தாததாக மாற்றலாம்; -வரைவு PR ஏற்றுக்கொள்ளப்பட்ட வேட்பாளர் அல்ல. `hotfix` லேபிள் ஆதாரத் தேவையை நீக்காது. - -இரு பணிப்பாய்வுகளும் PR-கள், main/release கிளைகளுக்கான push-கள், கைமுறை dispatch மற்றும் -merge-group நிகழ்வுகளை உள்ளடக்குகின்றன. Push, dispatch மற்றும் merge-group முழுத் தேர்வையும் இயக்குகின்றன. Fork-கள் -மற்றும் merge group-கள், இயல்பாக self-hosted runner-களைத் தேர்ந்தெடுக்கும் பணிகளுக்கு hosted runner-களைப் பயன்படுத்துகின்றன; -வெளியீட்டிற்கு முன் போதுமான hosted திறன் சரிபார்க்கப்பட வேண்டும். - -ஒவ்வொரு JSON ரசீதும் checkout செய்யப்பட்ட SHA, workflow run மற்றும் attempt-ஐ அடையாளப்படுத்துகிறது. -checkout/event SHA பொருந்தாமையை CLI நிராகரிக்கிறது. புதிய அல்லது நீக்கப்பட்ட lane ஒன்று கவனிக்கப்படாமல் மறைந்துவிடாதபடி, -பணிப்பாய்வு சோதனைகள் கொள்கை உறுப்புரிமையை verdict job-இன் `needs` பட்டியலுடன் பிணைக்கின்றன. -இந்த ரசீதுகள் அவற்றின் சொந்த பணிப்பாய்வை மட்டுமே உள்ளடக்குகின்றன; publication, deployment அல்லது ஏற்கனவே உள்ள -advisory scanner-இன் உள் செயல்பாடுகளை அல்ல. கிளை விதிகளில் இரு check பெயர்களையும் செயல்படுத்துவது -தனியான நிர்வாக மாற்றமாகும்; இந்தப் பணிகளைச் சேர்ப்பது மட்டுமே ஒரு கிளையைப் பாதுகாக்காது. - -### நிலையான ஸ்கேன் இருப்புப் பட்டியல் - -பதிப்பிடப்பட்ட npm-alias இருப்புப் பட்டியலும் static-scan உறுப்புரிமையும் -`config/quality/gate-manifest.json`-இல் உள்ளன. script பெயர்களையும் துல்லியமான command-களையும் -`package.json`-க்கு எதிராகச் சரிபார்க்க `npm run check:gate-manifest`-ஐ இயக்கவும்; சேர்த்தல்கள், நீக்கல்கள் மற்றும் -command மாற்றங்கள் local hook மற்றும் CI-இல் உள்ள change-classification பணிகள் இரண்டிலும் தோல்வியை ஏற்படுத்தும். -ஒரு alias என்பது workflow job, matrix instance அல்லது test case அல்ல: இந்த எண்ணிக்கைகள் -ஒன்றுக்கொன்று மாற்றிப் பயன்படுத்தக்கூடியவை எனக் காட்டப்படக் கூடாது. +## கேட்டுகளின் பட்டியல் மற்றும் செயல்படுத்தல் சுயவிவரங்கள் + +### வேட்பாளர் அனுமதி + +CI மற்றும் Quality Gates பணிப்பாய்வுகள் ஒவ்வொன்றும் நிலையான தீர்ப்பை வெளியிடுகின்றன: `Gate / CI` மற்றும் +`Gate / Quality`. அவற்றின் பதிப்பிடப்பட்ட அனுமதிக் கொள்கை, ஒவ்வொரு மேல்நிலைப் பணியையும் +கட்டாயமானதாகவோ ஆலோசனைக்குரியதாகவோ பட்டியலிடுகிறது. பொருந்தக்கூடிய கட்டாயப் பணி வெற்றிபெற வேண்டும்: விடுபட்ட, +ரத்துசெய்யப்பட்ட, தவிர்க்கப்பட்ட, நிலுவையிலுள்ள மற்றும் அறியப்படாத முடிவுகளால் PASS என்பதை உறுதிப்படுத்த முடியாது. செல்லுபடியாகும் +ஆவணங்கள்-மட்டும் அல்லது பட்டியல்-மட்டும் வகைப்பாடு, குறியீட்டுத் தடத்தைப் பொருந்தாததாக்கலாம்; +வரைவு PR ஏற்றுக்கொள்ளப்பட்ட வேட்பாளர் அல்ல. `hotfix` சிட்டை ஆதாரத் தேவையை நீக்காது. + +இரு பணிப்பாய்வுகளும் PR-களையும் main/release கிளைகளுக்கான push-களையும், கைமுறை dispatch மற்றும் +merge-group நிகழ்வுகளையும் உள்ளடக்குகின்றன. Push, dispatch மற்றும் merge-group ஆகியவை முழுத் தேர்வையும் இயக்குகின்றன. Fork-களும் +merge group-களும், வழக்கமாக self-hosted runner-களைத் தேர்ந்தெடுக்கும் பணிகளுக்கு hosted runner-களைப் பயன்படுத்துகின்றன; +வெளியீட்டுக்கு முன் போதுமான hosted திறன் சரிபார்க்கப்பட வேண்டும். + +ஒவ்வொரு JSON ரசீதும் checkout செய்யப்பட்ட SHA, பணிப்பாய்வு இயக்கம் மற்றும் முயற்சியை அடையாளப்படுத்துகிறது. +checkout/event SHA பொருந்தாமையை CLI நிராகரிக்கிறது. ஒரு புதிய அல்லது நீக்கப்பட்ட தடம் அமைதியாக மறைந்துவிடாதபடி, +கொள்கை உறுப்புரிமையை தீர்ப்புப் பணியின் `needs` பட்டியலுடன் பணிப்பாய்வுச் சோதனைகள் பிணைக்கின்றன. +இந்த ரசீதுகள் அவற்றின் சொந்தப் பணிப்பாய்வை உள்ளடக்குகின்றன; வெளியீடு, deployment அல்லது ஏற்கனவே உள்ள +ஆலோசனை scanner-இன் உள்ளக செயல்பாடுகளை அல்ல. Branch விதிகளில் இரு check பெயர்களையும் செயல்படுத்துவது +தனியான நிர்வாக மாற்றமாகும்; இந்தப் பணிகளைச் சேர்ப்பது மட்டும் ஒரு branch-ஐப் பாதுகாக்காது. + +### நிலையான scan பட்டியல் + +பதிப்பிடப்பட்ட npm-alias பட்டியலும் static-scan உறுப்புரிமையும் +`config/quality/gate-manifest.json`-இல் உள்ளன. Script பெயர்களையும் சரியான command-களையும் +`package.json`-உடன் ஒப்பிட்டு சரிபார்க்க `npm run check:gate-manifest`-ஐ இயக்கவும்; சேர்த்தல்கள், நீக்கங்கள் மற்றும் +command மாறுபாடுகள் local hook மற்றும் CI-இன் மாற்ற-வகைப்பாட்டுப் பணிகள் இரண்டையும் தோல்வியடையச் செய்கின்றன. +ஒரு alias என்பது பணிப்பாய்வுப் பணி, matrix instance அல்லது test case அல்ல: இந்த எண்ணிக்கைகளை +ஒன்றுக்கொன்று மாற்றிப் பயன்படுத்தக்கூடியவையாகக் காட்டக்கூடாது. தேர்ந்தெடுக்கப்பட்ட alias-களை இயக்காமல் ஆய்வு செய்ய `npm run quality:scan -- --list` அல்லது -`npm run quality:scan:fast -- --list`-ஐப் பயன்படுத்தவும். runner, npm entrypoint-ஐ இயக்குவதால், -அதன் runtime பாதுகாக்கப்படுகிறது; உள்ளமைக்கப்பட்ட இடங்களில் Bun-உம் இதில் அடங்கும். -இந்தச் சுயவிவரங்களுக்கு வெளியே உள்ள alias-களை தனியாக இயக்கப்படுபவையாக manifest பதிவு செய்கிறது; மேலும் -படிக்க மட்டும் அனுமதிக்கும் scan profile-களில் maintenance command-கள் தடைசெய்யப்பட்டுள்ளன. +`npm run quality:scan:fast -- --list` பயன்படுத்தவும். Runner npm entrypoint-ஐ அழைப்பதால், +அதன் runtime (உள்ளமைக்கப்பட்ட இடங்களில் Bun உட்பட) பாதுகாக்கப்படுகிறது. +அந்தச் சுயவிவரங்களுக்கு வெளியே உள்ள alias-கள் தனித்தனியாக அழைக்கப்படுவதாக manifest பதிவுசெய்கிறது; மேலும் +பராமரிப்பு command-கள் படிக்க-மட்டும் scan சுயவிவரங்களில் தடைசெய்யப்பட்டுள்ளன. -இந்தச் சுயவிவரங்கள் static scan-ஐ மட்டுமே உள்ளடக்குகின்றன. இவை product test-கள், -coverage, packaging, வெளிப்புற check-கள் அல்லது ஒரு வேட்பாளரின் முழுமையான release acceptance-ஐச் சான்றளிப்பதில்லை. -Workflow admission, இணைக்கப்பட்ட `config/quality/admission-policy.json` மற்றும் -`scripts/quality/admission-verdict.mjs`-ஐப் பயன்படுத்துகிறது. Release-observer profile-கள் தனியாகவே இருக்கும்; -அவற்றுக்குப் பொருந்தும் check-களையும் ரசீதுகளையும் தனித்தனியாக ஆய்வு செய்யவும். கீழேயுள்ள உரைநடை -இருப்புப் பட்டியல் ஒரு மேற்கோள் மட்டுமே; ஒரு gate உண்மையில் இயக்கப்பட்டது என்பதற்கான ஆதாரம் அல்ல. +இந்தச் சுயவிவரங்கள் static scan-ஐ மட்டுமே உள்ளடக்குகின்றன. இவை தயாரிப்புச் சோதனைகள், +coverage, packaging, வெளிப்புற check-கள் அல்லது ஒரு வேட்பாளரின் முழுமையான release ஏற்றுக்கொள்ளுதலைச் சான்றளிப்பதில்லை. +பணிப்பாய்வு அனுமதி, இணைக்கப்பட்டுள்ள `config/quality/admission-policy.json` மற்றும் +`scripts/quality/admission-verdict.mjs`-ஐப் பயன்படுத்துகிறது. Release-observer சுயவிவரங்கள் தனித்தே உள்ளன; +அவற்றின் பொருந்தக்கூடிய check-களையும் ரசீதுகளையும் தனித்தனியாக ஆய்வு செய்யவும். கீழே உள்ள உரைநடைப் +பட்டியல் ஒரு குறிப்புதான்; ஒரு gate உண்மையில் இயங்கியது என்பதற்கான ஆதாரம் அல்ல. -Script-கள் `scripts/check/` (policy gate-கள்) மற்றும் `scripts/quality/` (ratchet engine) ஆகியவற்றின் கீழ் உள்ளன. -CI-க்கான ஒற்றை உண்மை ஆதாரம் `.github/workflows/ci.yml` ஆகும். +Script-கள் `scripts/check/` (கொள்கை gate-கள்) மற்றும் `scripts/quality/` (ratchet engine) ஆகியவற்றின் கீழ் உள்ளன. +CI-க்கான அதிகாரப்பூர்வ மூலம் `.github/workflows/ci.yml` ஆகும். ### Release PR விரைவுப் பாதை (`quality.yml`) -`.github/workflows/quality.yml`, main/release PR-கள், பாதுகாக்கப்பட்ட கிளைகளுக்கான -push-கள், dispatch மற்றும் merge group-களில் CI-க்கு துணையாகச் செயல்படுகிறது. PR-கள் பாதை-வடிகட்டப்பட்ட விரைவுச் சோதனைகளைப் பயன்படுத்துகின்றன. நிரந்தரமாக -முடக்கப்பட்டிருந்த நகல் build அகற்றப்பட்டது; உண்மையான build/package/boot சோதனைகள் CI-இல் தொடர்ந்து உள்ளன. +`.github/workflows/quality.yml`, main/release PR-கள், பாதுகாக்கப்பட்ட branch-களுக்கான +push-கள், dispatch மற்றும் merge group-களில் CI-ஐ நிறைவுசெய்கிறது. PR-கள் path-filter செய்யப்பட்ட விரைவான check-களைப் பயன்படுத்துகின்றன. நிரந்தரமாக +முடக்கப்பட்டிருந்த நகல் build அகற்றப்பட்டது; உண்மையான build/package/boot check-கள் CI-இல் தொடர்ந்து உள்ளன. -| பணி | வரம்பு | தடுப்பதா | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `Docs Gates (fast-path)` | Docs/code PR-கள்; API docs refs மற்றும் docs-all | ஆம் | -| `Fast Quality Gates` | Code PR-கள்; static check-கள், typecheck, dashboard typecheck, பாதிக்கப்பட்ட unit test-கள் | ஆம் | -| `Forgotten sibling tests` | Code PR-கள்; மாற்றப்பட்ட module-களிலிருந்து static consumer-கள் மற்றும் candidate sibling test-கள் வரை பின்தொடர்தல்; barrel மற்றும் dynamic-import பாதைகள் ஆலோசனை நோயறிதல்களாக அறிக்கையிடப்படுகின்றன, குறிப்பிடப்பட்ட allowlist விதிவிலக்குகளுடன் | **ஆலோசனை சார்ந்தது** | -| `Vitest (fast-path)` | Code PR-கள்; விரைவான vitest suite | ஆம் | -| `Unit Tests fast-path` | Code PR-கள்; 4-shard unit suite | ஆம் | -| `No new ESLint warnings` | Code PR-கள்; suppression-களை அறிந்த lint guard | ஆம், fork-கள் உட்பட | -| `Merge integrity (changelog + generated skills)` | வரைவு அல்லாத PR-கள்; changelog மற்றும் உருவாக்கப்பட்ட skill ஒத்திசைவு | ஆம், fork-கள் உட்பட | +| பணி | வரம்பு | தடுப்பது | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | +| `Docs Gates (fast-path)` | ஆவணங்கள்/குறியீட்டு PR-கள்; API ஆவணக் குறிப்புகள் மற்றும் அனைத்து ஆவணங்களும் | ஆம் | +| `Fast Quality Gates` | குறியீட்டு PR-கள்; static check-கள், typecheck, dashboard typecheck, தாக்கமுற்ற unit test-கள் | ஆம் | +| `Forgotten sibling tests` | குறியீட்டு PR-கள்; மாற்றப்பட்ட module-களிலிருந்து static consumer-கள் மற்றும் சாத்தியமான sibling test-கள் வரை தடமறிதல்; barrel மற்றும் dynamic-import path-கள், குறிப்பிடப்பட்ட allowlist விதிவிலக்குகளுடன், ஆலோசனை diagnostics ஆக அறிவிக்கப்படுகின்றன | **ஆலோசனைக்குரியது** | +| `Vitest (fast-path)` | குறியீட்டு PR-கள்; விரைவான vitest suite | ஆம் | +| `Unit Tests fast-path` | குறியீட்டு PR-கள்; 4-shard unit suite | ஆம் | +| `No new ESLint warnings` | குறியீட்டு PR-கள்; suppression-களை அறிந்த lint guard | ஆம், fork-கள் உட்பட | +| `Merge integrity (changelog + generated skills)` | வரைவு அல்லாத PR-கள்; changelog மற்றும் உருவாக்கப்பட்ட skill ஒத்திசைவு | ஆம், fork-கள் உட்பட | #### மறக்கப்பட்ட sibling test-கள் அறிக்கை `npm run check:forgotten-sibling-tests`, test-impact map-க்குப் பின்னால் உள்ள import resolver-ஐ மீண்டும் பயன்படுத்துகிறது. -மாற்றப்பட்ட ஒவ்வொரு production module-க்கும், candidate -test pull-request diff-இல் இல்லாதபோது, தீர்மானகரமான `changed module/symbol -> static consumer -> candidate sibling test` சங்கிலிகளை அறிக்கையிடுகிறது. -எந்தவொரு blocking rollout-க்கும் முன் அளவுத்திருத்தத்திற்காக Markdown summary மற்றும் JSON result ஆகியவை -`forgotten-sibling-tests` workflow artifact ஆகத் தக்கவைக்கப்படுகின்றன. +மாற்றப்பட்ட ஒவ்வொரு production module-க்கும், சாத்தியமான +test pull-request diff-இல் இல்லாதபோது, நிர்ணயிக்கப்பட்ட +`changed module/symbol -> static consumer -> candidate sibling test` சங்கிலிகளை இது அறிவிக்கிறது. தடுப்புச் செயலாக்கத்திற்கு முந்தைய அளவுத்திருத்தத்திற்காக, +Markdown சுருக்கமும் JSON முடிவும் `forgotten-sibling-tests` பணிப்பாய்வு artifact ஆகத் தக்கவைக்கப்படுகின்றன. -Barrel மறு-ஏற்றுமதிகளும் dynamic imports-உம் resolution கண்டறிதல்களுக்கு மட்டுமே பயன்படுத்தப்படுகின்றன; அவை ஒருபோதும் -தடுக்கும் கண்டறிதலை உருவாக்காது. மதிப்பாய்வு செய்யப்பட்ட விதிவிலக்குகள் +Barrel மறு-ஏற்றுமதிகளும் dynamic imports-உம் resolution கண்டறிதல்களுக்காக மட்டுமே; அவை ஒருபோதும் +தடுக்கும் finding-ஐ உருவாக்காது. மதிப்பாய்வு செய்யப்பட்ட விதிவிலக்குகள் `config/quality/forgotten-sibling-allowlist.json`-இல் உள்ளன. ஒவ்வொரு பதிவும் consumer மற்றும் candidate -test-ஐக் குறிப்பிட வேண்டும், ஒரு குறிப்பிட்ட காரணத்தை வழங்க வேண்டும், மேலும் ஒரு GitHub issue அல்லது pull request-க்கு இணைக்க வேண்டும். தவறான வடிவமைப்பைக் கொண்ட பதிவுகள் -தானாகவே தோல்வியடையும். நீக்கப்பட்ட candidate test அல்லது `.skip`/`.todo`-ஐச் சேர்க்கும் diff-ஐ விதிவிலக்குகளால் புறக்கணிக்க முடியாது; -assertion-ஐ வலுவிழக்கச் செய்தல் மற்றும் பிற மறைத்தல் செயல்கள், சுயாதீனமாகத் தடுக்கும் -`check:test-masking` gate-இன் பொறுப்பிலேயே தொடரும். +test-ஐக் குறிப்பிட வேண்டும், குறிப்பிட்ட காரணத்தை வழங்க வேண்டும், மேலும் ஒரு GitHub issue அல்லது pull request-ஐ இணைக்க வேண்டும். தவறாக வடிவமைக்கப்பட்ட பதிவுகள் +மூடிய நிலையில் தோல்வியடையும். நீக்கப்பட்ட candidate test அல்லது `.skip`/`.todo`-ஐச் சேர்க்கும் diff-ஐ விதிவிலக்குகளால் மறைக்க முடியாது; +assertion-ஐ பலவீனப்படுத்துதல் மற்றும் பிற masking செயல்கள், தனித்தனியாகத் தடுக்கும் +`check:test-masking` gate-இன் பொறுப்பிலேயே தொடர்கின்றன. ### பணி: `lint` `main`-க்கான ஒவ்வொரு PR-இலும் இயங்கும். தோல்வியடைந்தால் merge செய்வதைத் தடுக்கும். -| Script (`npm run ...`) | சரிபார்ப்பவை | தடுக்கும் தன்மை | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| `check:node-runtime` | Node.js பதிப்பு ஆதரிக்கப்படும் வரம்பிற்குள் உள்ளது | ஆம் | -| `check:cycles` | சுழற்சி imports — அனைத்து `src/` + `open-sse/` modules | ஆம் | -| `check:route-validation:t06` | அனைத்து routes-இலும் Zod schemas உள்ளன (Tier 6 கொள்கை) | ஆம் | -| `check:any-budget:t11` | `@ts-expect-error // any` எண்ணிக்கை வரம்பை மீறவில்லை (Tier 11 catraca) | ஆம் | -| `check:provider-consistency` | `providers.ts`-இல் உள்ள ஒவ்வொரு provider-க்கும் `providerRegistry.ts`-இல் பொருந்தும் பதிவு உள்ளது (மற்றும் மறுதிசையிலும், allowlist-க்குள்) | ஆம் | -| `check:model-lifecycle` | கைமுறையாகப் பராமரிக்கப்படும் மூன்று routing அட்டவணைகள், repository-இல் சேர்க்கப்பட்ட lifecycle snapshot (#11503)-உடன் சீராக உள்ளன: `FITNESS_TABLE` (`taskFitness.ts`), `REGISTRY` route செய்யக்கூடிய ஓய்வுபெற்ற எந்த id-க்கும் score வழங்காது; ஒவ்வொரு `BUILT_IN_ALIASES` target-உம் `REGISTRY`-இல் உள்ளது மற்றும் ஓய்வுபெற்ற id snapshot-இல் இல்லை; `REGISTRY`-இல் இன்னும் உள்ள ஒவ்வொரு ஓய்வுபெற்ற id-யும் forward செய்யப்பட்டுள்ளது அல்லது `allowedRetiredInCatalog`-இல் பட்டியலிடப்பட்டுள்ளது; மேலும் எந்த `DEFAULT_DEGRADATION_MAP` source அல்லது target-உம் அந்த snapshot-இல் ஓய்வுபெற்றதாகத் தோன்றாது. ஒரு model தற்போது செயலிலுள்ள upstream மூலம் வழங்கப்படுகிறது என்பதை இது நிரூபிக்காது. Offline — `config/quality/model-lifecycle.json`-உடன் ஒப்பிடுகிறது; இது `npm run quality:refresh-model-lifecycle` மூலம் கைமுறையாகப் புதுப்பிக்கப்படுகிறது (network; CI-உடன் இணைக்கப்படவில்லை). `allowedRetiredInCatalog` என்பது படிப்படியாகக் குறைக்கும் ratchet: tracking issue இருந்தால் மட்டுமே ஒரு பதிவைச் சேர்க்கவும். | ஆம் | -| `check:fetch-targets` | client-side `src/`-இல் உள்ள ஒவ்வொரு `fetch("/api/...")`-உம் உண்மையான `route.ts`-க்குத் தீர்மானிக்கப்படுகிறது | ஆம் | -| `check:deps` | repo-இல் உள்ள ஒவ்வொரு `package.json` முழுவதிலும் `npm install` செய்யக்கூடிய அனைத்து deps-உம் `dependency-allowlist.json`-இல் உள்ளன; புதிதாக pin செய்யப்படாத அல்லது slopsquat செய்யப்பட்ட packages குறியிடப்படுகின்றன | ஆம் | -| `audit:deps` | `npm audit` (root + electron) — high/critical advisories எதுவுமில்லை (osv `check:vuln-ratchet`-உடன் ஒன்றிணைகிறது; Rationalization Backlog-ஐப் பார்க்கவும்) | ஆம் | -| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hashes, host overrides எதுவுமில்லை | ஆம் | -| `check:licenses` | உற்பத்தி சார்புகளுக்கான SPDX உரிம அனுமதிப்பட்டியல் | ஆம் | -| `check:tracked-artifacts` | உருவாக்கக் கலைப்பொருட்கள் / commit செய்யப்பட்ட `node_modules` குறியீட்டு இணைப்புகள் எதுவும் இல்லை (husky pre-commit-இலும் இயங்கும்; pre-push வேண்டுமென்றே இலகுவாக வைக்கப்பட்டுள்ளது — #6716) | ஆம் | -| `check:ai-attribution` | PR commit-கள், தலைப்பு அல்லது உள்ளடக்கத்தில் AI/bot `Co-Authored-By` trailer அல்லது AI-உருவாக்க footer எதுவும் இல்லை — கடுமையான விதி #16 (`quality.yml`-இன் PR→`release/**` fast-gates சுழற்சியில் — event payload-ஐப் படிக்கும், PR அல்லாதபோது எந்தச் செயல்பாடும் செய்யாது — மேலும் PR→`main`-க்கான `ci.yml` lint-இல் PR-க்கு மட்டும் உரிய படிநிலை; husky `commit-msg` hook-லும்; மனித இணை ஆசிரியர்கள் அனுமதிக்கப்படுகிறார்கள்; #14436) | -| `check:vitest-exclusions` | ஒவ்வொரு Vitest விலக்கலும் ஒரு கண்காணிப்புச் சிக்கலைக் குறிப்பிடுவதுடன் `config/quality/vitest-exclusions.json`-இல் இடம்பெறுகிறது (#13204) | ஆம் | -| `check:file-size` | எந்த மூலக் கோப்பும் கோப்பு நீட்சிவாரியான உச்சவரம்பை மீறவில்லை (ratchet: `frozen` பட்டியலில் மாற்றமின்றி வைக்கப்பட்ட பெரிய கோப்புகள்) | ஆம் | -| `check:error-helper` | executor-கள்/handler-களில் உள்ள பிழைப் பதில்கள் `buildErrorBody()` / `sanitizeErrorMessage()`-ஐப் பயன்படுத்துகின்றன (கடுமையான விதி #12) | ஆம் | -| `check:migration-numbering` | Migration SQL கோப்புகள் இடைவெளிகளோ நகல்களோ இல்லாமல் தொடர்ச்சியாக எண்ணிடப்பட்டுள்ளன | ஆம் | -| `check:public-creds` | `publicCreds.ts`-க்கு வெளியே நேரடி OAuth `client_id`/`client_secret` அல்லது Firebase Web விசைகள் இல்லை (கடுமையான விதி #11) | ஆம் | -| `check:db-rules` | `src/lib/db/` தொகுதிகளுக்கு வெளியே நேரடி SQL இல்லை; `localDb.ts`-இலிருந்து barrel-import-கள் இல்லை (கடுமையான விதிகள் #2/#5) | ஆம் | -| `check:known-symbols` | அவற்றின் dispatch அட்டவணைகளில் பதிவுசெய்யப்பட்ட provider executor-கள், routing strategy-கள் மற்றும் translator-கள் வட்டில் உள்ள கோப்புகளுடன் பொருந்துகின்றன — தொடர்பற்ற அல்லது அறிவிக்கப்படாத symbol-கள் இல்லை | ஆம் | -| `check:route-guard-membership` | child process-ஐ உருவாக்கும் ஒவ்வொரு route-உம் `isLocalOnlyPath()` மூலம் வகைப்படுத்தப்பட்டுள்ளது (கடுமையான விதிகள் #15/#17) | ஆம் | -| `check:test-discovery` | repo-வில் உள்ள ஒவ்வொரு `*.test.ts` / `*.spec.ts` கோப்பும் குறைந்தது ஒரு test runner-ஆல் சேகரிக்கப்படுகிறது (ratchet: `test-discovery-baseline.json`-இல் உள்ள orphan பட்டியல் சுருங்க மட்டுமே முடியும்) | ஆம் | -| `check:agent-skills-sync` | உருவாக்கப்பட்ட agent-skills கலைப்பொருட்கள் அவற்றின் மூலப் பட்டியலுடன் பொருந்துகின்றன (வேறுபாடு இல்லை) | -| `check:provider-asset-provenance` | வழங்குநர் லோகோக்கள்/கலைப்பொருட்களுக்கு பதிவுசெய்யப்பட்ட மூலாதாரப் பதிவு உள்ளது | -| `lint:json` | JSON கட்டமைப்புக் கோப்புகள் சரியாகப் பகுக்கப்பட்டு repo lint விதிகளைப் பூர்த்தி செய்கின்றன | -| `typecheck:core` | பிழைகள் இல்லாத TypeScript தொகுத்தல் (ஆலோசனை எச்சரிக்கைகள் மட்டும்) | ஆம் | -| `typecheck:noimplicit:core` | கடுமையான `noImplicitAny` — எதிர்கால நோக்குடையது; முன்பிருந்த பல அழைப்பிடங்களுக்கு இன்னும் வகைக் குறிப்புகள் தேவை | **ஆலோசனை** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**`-க்கு வரம்பிடப்பட்ட `tsc` (#7033) — `typecheck:core`-இன் கவனமாகத் தேர்ந்தெடுக்கப்பட்ட 27-கோப்பு அனுமதிப்பட்டியலில் எந்த dashboard TSX-உம் இடம்பெறவில்லை; `next build` அதற்கான வகைச் சரிபார்ப்பையும் ஒருபோதும் செய்வதில்லை (`next.config.mjs` ஆனது `ignoreBuildErrors: true` என அமைக்கிறது). எனவே, அங்குள்ள தொடர்பற்ற அடையாளங்காட்டி பின்னடைவுகள் (#6625/#6909) CI-க்குப் புலப்படாமல் இருந்தன. நிலைப்படுத்தப்பட்ட ஒவ்வொரு கோப்பு/ஒவ்வொரு TS-குறியீட்டு எண்ணிக்கை அடிப்படைக்கோட்டுடன் (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` போன்ற அதே காலாவதி-அமலாக்க முறை) வேறுபாடுகள் ஒப்பிடப்படுகின்றன — அடிப்படைக்கோட்டு எண்ணிக்கைக்கு அப்பாற்பட்ட புதிய பிழைகள் மட்டுமே நுழைவாயிலைத் தோல்வியடையச் செய்யும்; முன்பிருந்த பிழை ஒன்று சரிசெய்யப்படும்போது `--update` மூலம் அடிப்படைக்கோட்டை படிப்படியாகக் குறைக்கவும். | ஆம் | +| ஸ்கிரிப்ட் (`npm run ...`) | சரிபார்ப்பது | தடுப்பது | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `check:node-runtime` | Node.js பதிப்பு ஆதரிக்கப்படும் வரம்பிற்குள் உள்ளது | ஆம் | +| `check:cycles` | `src/` + `open-sse/` முழுவதிலுமான சுழற்சி imports (AST அடிப்படையிலானது, tsconfig `paths` resolve செய்யப்படுகின்றன). Bare முறை = ஆலோசனை மட்டும்; சுழற்சிகளைப் பட்டியலிடும். `check:cycles:ratchet` (CI இயக்குவது) எண்ணிக்கை `quality-baseline.json`-இல் உள்ள `metrics.cycles` உச்சவரம்பை மீறும்போது தடுக்கும் — தற்போது 14, `direction: down`, எனவே அது குறைய மட்டுமே முடியும் (#15159 G-01/G-02) | ஆம் (ratchet) | +| `check:route-validation:t06` | அனைத்து routes-இலும் Zod schemas இருப்பது (Tier 6 கொள்கை) | ஆம் | +| `check:any-budget:t11` | `@ts-expect-error // any` எண்ணிக்கை budget-ஐ மீறவில்லை (Tier 11 catraca) | ஆம் | +| `check:provider-consistency` | `providers.ts`-இல் உள்ள ஒவ்வொரு வழங்குநருக்கும் `providerRegistry.ts`-இல் பொருந்தும் பதிவு உள்ளது (அதேபோல் மறுதிசையிலும், அனுமதிப்பட்டியலுக்குள்) | ஆம் | +| `check:model-lifecycle` | கைமுறையாகப் பராமரிக்கப்படும் மூன்று வழிப்படுத்தல் அட்டவணைகளும் களஞ்சியத்தில் சேர்க்கப்பட்ட வாழ்க்கைச்சுழற்சி நிலைப்படத்துடன் (#11503) ஒத்திசைவாக இருக்கும்: `REGISTRY` வழிப்படுத்தக்கூடிய ஓய்வுபெற்ற எந்த id-க்கும் `FITNESS_TABLE` (`taskFitness.ts`) மதிப்பெண் வழங்காது; ஒவ்வொரு `BUILT_IN_ALIASES` இலக்கும் `REGISTRY`-இல் இருக்கும் மற்றும் ஓய்வுபெற்ற-id நிலைப்படத்தில் இருக்காது; `REGISTRY`-இல் இன்னும் உள்ள ஒவ்வொரு ஓய்வுபெற்ற id-யும் முன்னனுப்பப்படும் அல்லது `allowedRetiredInCatalog`-இல் பட்டியலிடப்படும்; மேலும் எந்த `DEFAULT_DEGRADATION_MAP` மூலமோ இலக்கோ அந்த நிலைப்படத்தில் ஓய்வுபெற்றதாக இடம்பெறாது. ஒரு மாதிரி தற்போது நேரடி மேல்நிலைச் சேவையால் வழங்கப்படுகிறது என்பதை இது நிரூபிக்காது. இணையமில்லா முறை — `config/quality/model-lifecycle.json` உடன் ஒப்பிடுகிறது; இது `npm run quality:refresh-model-lifecycle` மூலம் கைமுறையாகப் புதுப்பிக்கப்படுகிறது (பிணையம் தேவை; CI-இல் இணைக்கப்படவில்லை). `allowedRetiredInCatalog` என்பது படிப்படியாகக் குறைக்கும் தடுப்புக் கருவி: கண்காணிப்புச் சிக்கல் இருந்தால் மட்டுமே ஒரு பதிவைச் சேர்க்கவும். | ஆம் | +| `check:fetch-targets` | கிளையன்ட் தரப்பு `src/`-இல் உள்ள ஒவ்வொரு `fetch("/api/...")`-உம் உண்மையான `route.ts`-க்குத் தீர்மானிக்கப்படுகிறது | ஆம் | +| `check:deps` | களஞ்சியத்திலுள்ள ஒவ்வொரு `package.json`-இலும் காணப்படும், `npm install` மூலம் நிறுவக்கூடிய அனைத்து சார்புகளும் `dependency-allowlist.json`-இல் உள்ளன; புதிதாகப் பதிப்பு நிலைநிறுத்தப்படாத அல்லது slopsquatting செய்யப்பட்ட தொகுப்புகள் குறியிடப்படுகின்றன | ஆம் | +| `audit:deps` | `npm audit` (மூலம் + electron) — அதிக/தீவிர ஆபத்துள்ள அறிவுறுத்தல்கள் எதுவும் இல்லை (osv `check:vuln-ratchet` உடன் மேற்படுகிறது; Rationalization Backlog-ஐப் பார்க்கவும்) | ஆம் | +| `check:lockfile` | `package-lock.json` முழுமைத்தன்மை — https பதிவகம், முழுமைத்தன்மை ஹாஷ்கள், ஹோஸ்ட் மேலெழுதல்கள் இல்லை | ஆம் | +| `check:licenses` | உற்பத்தி சார்புகளுக்கான SPDX உரிம அனுமதிப்பட்டியல் | ஆம் | +| `check:tracked-artifacts` | build artifacts / commit செய்யப்பட்ட `node_modules` symlinks எதுவும் இல்லை (husky pre-commit-இலும் இயங்கும்; pre-push திட்டமிட்டே இலகுவாக உள்ளது — #6716) | ஆம் | +| `check:ai-attribution` | PR commit-கள், தலைப்பு அல்லது body-இல் AI/bot `Co-Authored-By` trailer அல்லது AI-generation footer எதுவும் இல்லை — கடுமையான விதி #16 (`quality.yml`-இன் PR→`release/**`-க்கான fast-gates loop-இல் — event payload-ஐப் படிக்கும், PR அல்லாதவற்றில் எந்தச் செயல்பாடும் இல்லை — மேலும் `ci.yml` lint-இல் PR→`main`-க்கான PR-மட்டும் படி; husky `commit-msg` hook-உம் இதில் அடங்கும்; மனித இணை ஆசிரியர்கள் அனுமதிக்கப்படுகின்றனர்; #14436) | +| `check:vitest-exclusions` | ஒவ்வொரு Vitest exclusion-உம் ஒரு tracking issue-ஐக் குறிப்பிடுவதுடன் `config/quality/vitest-exclusions.json`-இல் இடம்பெற வேண்டும் (#13204) | ஆம் | +| `check:file-size` | எந்த source file-உம் அதன் extension-க்கான வரம்பை மீறக்கூடாது (ratchet: பெரிய உறையவைக்கப்பட்ட கோப்புகள் `frozen` பட்டியலில் உள்ளன) | ஆம் | +| `check:error-helper` | executors/handlers-இல் உள்ள பிழை responses, `buildErrorBody()` / `sanitizeErrorMessage()` ஆகியவற்றைப் பயன்படுத்துகின்றன (கடுமையான விதி #12) | ஆம் | +| `check:migration-numbering` | Migration SQL கோப்புகள் இடைவெளிகளோ நகல்களோ இல்லாமல் தொடர்ச்சியாக எண்ணிடப்பட்டுள்ளன | ஆம் | +| `check:public-creds` | `publicCreds.ts`-க்கு வெளியே நேரடி OAuth `client_id`/`client_secret` அல்லது Firebase Web விசைகள் இல்லை (கடுமையான விதி #11) | ஆம் | +| `check:db-rules` | `src/lib/db/` தொகுதிகளுக்கு வெளியே நேரடி SQL இல்லை; `localDb.ts`-இலிருந்து barrel-import-கள் இல்லை (கடுமையான விதிகள் #2/#5) | ஆம் | +| `check:known-symbols` | அவற்றின் dispatch அட்டவணைகளில் பதிவுசெய்யப்பட்ட provider executor-கள், routing strategy-கள் மற்றும் translator-கள் வட்டில் உள்ள கோப்புகளுடன் பொருந்துகின்றன — தொடர்பற்ற அல்லது அறிவிக்கப்படாத குறியீடுகள் இல்லை | ஆம் | +| `check:route-guard-membership` | child process-ஐ உருவாக்கும் ஒவ்வொரு route-உம் `isLocalOnlyPath()` மூலம் வகைப்படுத்தப்பட்டுள்ளது (கடுமையான விதிகள் #15/#17) | ஆம் | +| `check:test-discovery` | repo-வில் உள்ள ஒவ்வொரு `*.test.ts` / `*.spec.ts` கோப்பும் குறைந்தது ஒரு test runner மூலம் சேகரிக்கப்படுகிறது (ratchet: `test-discovery-baseline.json`-இல் உள்ள தொடர்பற்ற கோப்புகளின் பட்டியல் குறைய மட்டுமே முடியும்) | ஆம் | +| `check:agent-skills-sync` | உருவாக்கப்பட்ட agent-skills கலைப்பொருட்கள் அவற்றின் மூலப் பட்டியலுடன் பொருந்துகின்றன (விலகல் இல்லை) | +| `check:provider-asset-provenance` | வழங்குநர் லோகோக்கள்/கலைப்பொருட்களுக்கு பதிவுசெய்யப்பட்ட மூலம் குறித்த பதிவு உள்ளது | +| `lint:json` | JSON கட்டமைப்புக் கோப்புகள் பாகுபடுத்தப்பட்டு repo lint விதிகளைப் பூர்த்தி செய்கின்றன | +| `typecheck:core` | பிழைகள் இல்லாத TypeScript தொகுத்தல் (ஆலோசனை எச்சரிக்கைகள் மட்டும்) | ஆம் | +| `typecheck:noimplicit:core` | கண்டிப்பான `noImplicitAny` — எதிர்கால நோக்குடையது; முன்பே உள்ள பல அழைப்பிடங்களுக்கு இன்னும் சிறுகுறிப்புகள் தேவை | **ஆலோசனை** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**`-க்கு வரம்பிடப்பட்ட `tsc` (#7033) — `typecheck:core`-இன் தேர்ந்தெடுக்கப்பட்ட 27-கோப்பு அனுமதிப்பட்டியலில் dashboard TSX எதுவும் சேர்க்கப்படவில்லை; மேலும் `next build` அதனை ஒருபோதும் வகைச் சரிபார்ப்பதில்லை (`next.config.mjs`-இல் `ignoreBuildErrors: true` அமைக்கப்பட்டுள்ளது). எனவே, அங்குள்ள தனித்துவிடப்பட்ட அடையாளங்காட்டி பின்னடைவுகள் (#6625/#6909) CI-க்குப் புலப்படவில்லை. உறையவைக்கப்பட்ட ஒவ்வொரு-கோப்பு/ஒவ்வொரு-TS-குறியீட்டு எண்ணிக்கை அடிப்படையுடன் (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` போன்ற அதே பழையநிலை-அமலாக்க முறை) வேறுபாடுகள் ஒப்பிடப்படுகின்றன — அடிப்படை எண்ணிக்கையைத் தாண்டிய புதிய பிழைகள் மட்டுமே வாயிலைக் தோல்வியடையச் செய்யும்; முன்பே உள்ள பிழை ஒன்று சரிசெய்யப்படும்போது `--update` மூலம் அடிப்படையைக் குறைக்கவும். | ஆம் | ### பணி: `quality-gate` -`test-coverage`-க்குப் பிறகு இயங்கும். தோல்வியடைந்தால் இணைப்பைத் தடுக்கும். +`test-coverage`-க்குப் பிறகு இயங்கும். தோல்வியடைந்தால் ஒன்றிணைப்பைத் தடுக்கும். -| ஸ்கிரிப்ட் | சரிபார்ப்பது | தடுக்கும் தன்மை | -| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `quality:collect` | `quality-metrics.json`-ஐ உருவாக்குகிறது (ESLint எச்சரிக்கை எண்ணிக்கை, ஒன்றிணைக்கப்பட்ட ஷார்டு அறிக்கையிலிருந்து கவரேஜ்) | ஆம் (ratchet-க்கு முந்தையது) | -| `quality:ratchet` | `quality-baseline.json`-இல் உள்ள ஒவ்வொரு அளவீடும் பின்னடைவு அடையவில்லை (ESLint எச்சரிக்கைகள் ≤ அடிப்படை; கவரேஜ் ≥ அடிப்படை) | ஆம் | -| `check:duplication` | குறியீட்டு நகலெடுப்பு (jscpd@4), `quality-baseline.json`-இல் உள்ள அடிப்படையை மீறவில்லை | ஆம் | -| `check:complexity` | கோப்பு-நிலை சைக்ளோமேட்டிக் சிக்கல்தன்மை உச்சவரம்பை மீறவில்லை (மைய ESLint `complexity` + `max-lines-per-function`) | ஆம் | -| `check:cognitive-complexity` | அறிவாற்றல் சிக்கல்தன்மை ratchet (`eslint-plugin-sonarjs`) — தனி ESLint இயக்கம்; CI இரண்டையும் ஒன்றிணைத்து ஒற்றை `check:complexity-ratchets` படியாக இயக்குகிறது | ஆம் | -| `check:dead-code` | பயன்படுத்தப்படாத exports / கோப்புகளுக்கான ratchet (knip), அடிப்படையுடன் ஒப்பிடும்போது பின்னடைவு அடையவில்லை | ஆம் | -| `check:compression-budget` | சுருக்க ஒப்பீட்டுச் சோதனை வரம்பு — ஒவ்வொரு engine-க்குமான token சேமிப்பின் குறைந்தபட்ச அளவுகள் பின்னடைவு அடையக்கூடாது | ஆம் | -| `check:type-coverage` | தட்டச்சிடப்பட்ட சதவீதத்திற்கான ratchet (`type-coverage`) பின்னடைவு அடையவில்லை; பெருமளவில் `typecheck:noimplicit:core`-ஐ உள்ளடக்குகிறது | ஆம் | -| `check:codeql-ratchet` | திறந்த CodeQL விழிப்பூட்டல்களின் எண்ணிக்கை பின்னடைவு அடையவில்லை (`gh api` வழியாகப் படிக்கிறது; token இல்லையெனில் சிக்கலின்றித் தவிர்க்கிறது) — புதுப்பிப்பு இடைவெளி மற்றும் கைமுறைத் தூண்டல்: கீழே உள்ள "CodeQL ratchet"-ஐப் பார்க்கவும் | ஆம் | +| ஸ்கிரிப்ட் | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `quality:collect` | `quality-metrics.json`-ஐ உருவாக்குகிறது (ESLint எச்சரிக்கை எண்ணிக்கை, ஒன்றிணைக்கப்பட்ட shard அறிக்கையிலிருந்து coverage) | ஆம் (ratchet-க்கு முந்தைய நிலை) | +| `quality:ratchet` | `quality-baseline.json`-இல் உள்ள ஒவ்வொரு metric-உம் பின்னடைவு அடையவில்லை (ESLint எச்சரிக்கைகள் ≤ baseline; coverage ≥ baseline) | ஆம் | +| `check:duplication` | குறியீட்டு நகலெடுப்பு (jscpd@4), `quality-baseline.json`-இல் உள்ள baseline-ஐ மீறவில்லை | ஆம் | +| `check:complexity` | கோப்பு-நிலை cyclomatic complexity வரம்பை மீறவில்லை (மைய ESLint `complexity` + `max-lines-per-function`) | ஆம் | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — தனியான ESLint இயக்கம்; CI இரண்டையும் ஒற்றை `check:complexity-ratchets` படிநிலையாக ஒன்றிணைத்து இயக்குகிறது | ஆம் | +| `check:dead-code` | பயன்படுத்தப்படாத exports / கோப்புகளுக்கான ratchet (knip), baseline-உடன் ஒப்பிடும்போது பின்னடைவு அடையவில்லை | ஆம் | +| `check:compression-budget` | சுருக்க benchmark வரம்பு — engine-வாரியான token சேமிப்பின் குறைந்தபட்ச அளவுகள் பின்னடைவு அடையக்கூடாது | ஆம் | +| `check:type-coverage` | வகையிடப்பட்ட சதவீத ratchet (`type-coverage`) பின்னடைவு அடையவில்லை; பெருமளவில் `typecheck:noimplicit:core`-ஐ உள்ளடக்குகிறது | ஆம் | +| `check:codeql-ratchet` | திறந்த CodeQL alert எண்ணிக்கை பின்னடைவு அடையவில்லை (`gh api` வழியாகப் படிக்கிறது; token இல்லாதபோது சீராகத் தவிர்க்கிறது) — புதுப்பிப்பு இடைவெளி மற்றும் கைமுறைத் தொடக்கம்: கீழே உள்ள "CodeQL ratchet"-ஐப் பார்க்கவும் | ஆம் | ### பணி: `quality-extended` -முழுப் பணியும் ஆலோசனைத் தன்மை கொண்டது (`continue-on-error: true`). npm-அடிப்படையிலான ratchet-கள் -உண்மையாக இயங்குகின்றன; வெளிப்புற ஸ்கேனர்கள் `gh release download` வழியாக நிறுவப்பட்டு, binary இன்னும் -இல்லாதபோது தாமாகவே தவிர்க்கப்படுகின்றன (exit 0). +முழுப் பணியும் ஆலோசனை சார்ந்தது (`continue-on-error: true`). npm-அடிப்படையிலான ratchet-கள் +உண்மையாக இயக்கப்படுகின்றன; வெளிப்புற scanner-கள் `gh release download` வழியாக நிறுவப்பட்டு, binary +இன்னும் இல்லாதபோது தாமாகவே தவிர்க்கின்றன (exit 0). -| ஸ்கிரிப்ட் | சரிபார்ப்பது | தடுக்கும் தன்மை | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -| `check:circular-deps` | சுழற்சி சார்புகள் இல்லை (dpdm) | **ஆலோசனை** | -| `check:bundle-size` | Bundle அளவு உச்சவரம்பை மீறவில்லை | **ஆலோசனை** | -| `check:secrets` | இரகசியத் தகவல் ஸ்கேனிங் (gitleaks) — binary இல்லையெனில் தவிர்க்கிறது | **ஆலோசனை** | -| `check:vuln-ratchet` | சார்புநிலை பாதிப்புகள் (osv-scanner) பின்னடைவு அடையவில்லை — binary இல்லையெனில் தவிர்க்கிறது | **ஆலோசனை** | -| `check:workflows` | Workflow lint (actionlint + zizmor); இல்லாத/செயலிழந்த ஸ்கேனர்கள், செல்லாத அறிக்கைகள் அல்லது இல்லாத ratchet அடிப்படை ஆகியவை INCOMPLETE எனத் தோல்வியடையும். செல்லுபடியான கண்டறிதல்கள் தேர்ந்தெடுக்கப்பட்ட கடுமையான/ஆலோசனை/ratchet கொள்கையைப் பின்பற்றும் | இயக்கம் அவசியம்; CI-இல் zizmor ratchet தடுக்கும் | -| `check:openapi-breaking` | அடிப்படைக் கிளையுடன் ஒப்பிடும்போது பொது API ஒப்பந்தத்தில் (`openapi.yaml`) உள்ள இணக்கத்தை முறிக்கும் மாற்றங்கள் (oasdiff) — `openapiBreaking=N`-ஐ உருவாக்குகிறது; oasdiff இல்லையெனில் அல்லது அடிப்படை விவரக்குறிப்பைத் தீர்மானிக்க முடியாவிட்டால் தவிர்க்கிறது | **ஆலோசனை** | +| ஸ்கிரிப்ட் | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | +| `check:circular-deps` | சுற்றுச்சார்புகள் எதுவும் இல்லை (dpdm) | **ஆலோசனை சார்ந்தது** | +| `check:bundle-size` | Bundle அளவு வரம்பை மீறவில்லை | **ஆலோசனை சார்ந்தது** | +| `check:secrets` | ரகசியத் தகவல் scan செய்தல் (gitleaks) — binary இல்லையெனில் தவிர்க்கிறது | **ஆலோசனை சார்ந்தது** | +| `check:vuln-ratchet` | சார்பு பாதிப்புகள் (osv-scanner) பின்னடைவு அடையவில்லை — binary இல்லையெனில் தவிர்க்கிறது | **ஆலோசனை சார்ந்தது** | +| `check:workflows` | Workflow lint (actionlint + zizmor); scanner-கள் இல்லாமை/செயலிழப்பு, செல்லாத அறிக்கைகள் அல்லது ratchet baseline இல்லாமை ஆகியவை INCOMPLETE எனத் தோல்வியடையும். செல்லுபடியாகும் கண்டறிதல்கள் தேர்ந்தெடுக்கப்பட்ட strict/advisory/ratchet கொள்கையைப் பின்பற்றும் | இயக்கம் அவசியம்; CI-இல் zizmor ratchet தடுக்கும் | +| `check:openapi-breaking` | அடிப்படை branch-உடன் ஒப்பிடும்போது பொது API ஒப்பந்தத்தில் (`openapi.yaml`) ஏற்படும் முறிவு மாற்றங்கள் (oasdiff) — `openapiBreaking=N`-ஐ உருவாக்குகிறது; oasdiff இல்லையெனில் அல்லது அடிப்படை spec-ஐத் தீர்மானிக்க முடியாவிட்டால் தவிர்க்கிறது | **ஆலோசனை சார்ந்தது** | ### பணி: `docs-sync-strict` -`main`-க்கான ஒவ்வொரு PR-இலும் இயங்குகிறது. தோல்வியுற்றால் ஒன்றிணைப்பைத் தடுக்கிறது. - -| ஸ்கிரிப்ட் | சரிபார்ப்பவை | தடுக்கும் நிலை | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| `check:docs-all` | கீழேயுள்ள 6 துணை-வாயில்களையும் தொடர்ச்சியாக இயக்கும் மெட்டா-வாயில் | ஆம் | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt பதிப்பு ஒத்திசைவு | ஆம் | -| ↳ `check:docs-counts` | உரையில் உள்ள எண்ணிக்கைகள் (வழங்குநர் எண்ணிக்கை, இடமாற்ற எண்ணிக்கை போன்றவை) உண்மையான எண்ணிக்கைகளின் ராட்செட் வரம்பிற்குள் உள்ளன | ஆம் | -| ↳ `check:env-doc-sync` | `.env.example`-இல் உள்ள ஒவ்வொரு env var-உம் ஆவண அட்டவணையில் ஆவணப்படுத்தப்பட்டுள்ளது; அதேபோல் மறுதிசையிலும் சரிபார்க்கப்படுகிறது | ஆம் | -| ↳ `check:deprecated-versions` | ஆவணங்களில் வழக்கொழிந்த பதிப்புச் சரங்கள் இல்லை | ஆம் | -| ↳ `check:doc-links` | ஆவணங்களில் உள்ள உள் markdown இணைப்புகள் உண்மையான கோப்புகளுக்குச் செல்கின்றன (`[text]`/`(path)` வடிவம்) | ஆம் | -| ↳ `check:fabricated-docs` | ஆவணங்களில் குறிப்பிடப்பட்டுள்ள வழித்தடங்கள், env vars, CLI கட்டளைகள், hook பெயர்கள் மற்றும் கோப்புப் பாதைகள் codebase-இல் உள்ளன. `--strict` வழியாகக் கடின வாயில்; flag இல்லாமல் மென்மையான தோல்வி. | ஆம் (CI-இல் `--strict` வழியாக) | -| `check:cli-i18n` | CLI கட்டளைச் சரங்கள் அனைத்து i18n locale கோப்புகளிலும் உள்ளன | ஆம் | -| `check:openapi-coverage` | OpenAPI விவரக்குறிப்பு உண்மையான வழித்தடங்களின் ராட்செட் செய்யப்பட்ட குறைந்தபட்ச அளவையாவது உள்ளடக்குகிறது | ஆம் | -| `check:openapi-security-tiers` | `openapi.yaml`-இல் உள்ள பாதுகாப்பு அடுக்கு குறிப்புரைகள் `routeGuard.ts` வகைப்பாடுகளுடன் ஒத்திசைவாக உள்ளன | **ஆலோசனை** | -| `check:openapi-routes` | `openapi.yaml`-இல் உள்ள ஒவ்வொரு பாதையும் உண்மையான `route.ts`-க்குச் செல்கிறது (கற்பனையான தகவலைத் தடுப்பது) | ஆம் | -| `check:docs-symbols` | `docs/**/*.md`-இல் உள்ள ஒவ்வொரு `/api/...` குறிப்பும் உண்மையான `route.ts`-க்குச் செல்கிறது (கற்பனையான தகவலைத் தடுப்பது) | ஆம் | -| `i18n translation drift` | i18n locale கோப்புகளில் மொழிபெயர்க்கப்படாத விசைகள் — எச்சரிக்கை மட்டும் | **ஆலோசனை** | +`main`-க்கான ஒவ்வொரு PR-இலும் இயக்கப்படுகிறது. தோல்வி ஏற்பட்டால் merge செய்வதைத் தடுக்கிறது. + +| ஸ்கிரிப்ட் | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `check:docs-all` | கீழே உள்ள 6 துணை-வாயில்களை வரிசையாக இயக்கும் மெட்டா-வாயில் | ஆம் | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt பதிப்பு ஒத்திசைவு | ஆம் | +| ↳ `check:docs-counts` | உரைநடையில் உள்ள எண்ணிக்கைகள் (வழங்குநர் எண்ணிக்கை, இடம்பெயர்வு எண்ணிக்கை போன்றவை) உண்மையான எண்ணிக்கைகளின் ராட்செட் சாளரத்திற்குள் உள்ளனவா | ஆம் | +| ↳ `check:env-doc-sync` | `.env.example`-இல் உள்ள ஒவ்வொரு சூழல் மாறியும் ஆவண அட்டவணையில் ஆவணப்படுத்தப்பட்டுள்ளது, மேலும் அதற்கு நேர்மாறாகவும் உள்ளதா | ஆம் | +| ↳ `check:deprecated-versions` | ஆவணங்களில் வழக்கொழிந்த பதிப்புச் சரங்கள் எதுவும் இல்லையா | ஆம் | +| ↳ `check:doc-links` | ஆவணங்களில் உள்ள உள் markdown இணைப்புகள் உண்மையான கோப்புகளைக் குறிக்கின்றனவா (`[text]`/`(path)` வடிவம்) | ஆம் | +| ↳ `check:fabricated-docs` | ஆவணங்களில் குறிப்பிடப்பட்ட வழித்தடங்கள், சூழல் மாறிகள், CLI கட்டளைகள், hook பெயர்கள் மற்றும் கோப்புப் பாதைகள் codebase-இல் உள்ளனவா. `--strict` வழியாகக் கடுமையான வாயில்; கொடி இல்லாமல் மென்-தோல்வி. | ஆம் (CI-இல் `--strict` வழியாக) | +| `check:cli-i18n` | CLI கட்டளைச் சரங்கள் அனைத்து i18n locale கோப்புகளிலும் உள்ளனவா | ஆம் | +| `check:openapi-coverage` | OpenAPI விவரக்குறிப்பு உண்மையான வழித்தடங்களுக்கான ராட்செட் செய்யப்பட்ட குறைந்தபட்ச வரம்பையாவது உள்ளடக்குகிறதா | ஆம் | +| `check:openapi-security-tiers` | `openapi.yaml`-இல் உள்ள பாதுகாப்பு அடுக்கு சிறுகுறிப்புகள் `routeGuard.ts` வகைப்பாடுகளுடன் ஒத்திசைவாக உள்ளனவா | **ஆலோசனை** | +| `check:openapi-routes` | `openapi.yaml`-இல் உள்ள ஒவ்வொரு பாதையும் உண்மையான `route.ts`-ஐக் குறிக்கிறதா (கற்பிதத் தடுப்பு) | ஆம் | +| `check:docs-symbols` | `docs/**/*.md`-இல் உள்ள ஒவ்வொரு `/api/...` குறிப்பும் உண்மையான `route.ts`-ஐக் குறிக்கிறதா (கற்பிதத் தடுப்பு) | ஆம் | +| `i18n translation drift` | i18n locale கோப்புகளில் மொழிபெயர்க்கப்படாத விசைகள் — எச்சரிக்கை மட்டும் | **ஆலோசனை** | ### பணி: `i18n-ui-coverage` -| ஸ்கிரிப்ட் | சரிபார்ப்பவை | தடுக்கும் நிலை | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (inline) | UI i18n விசைகளின் கவரேஜ் ≥ 65% | ஆம் | -| `check-ui-value-drift` (inline) | மீண்டும் எழுதப்பட்ட ஆங்கில **மதிப்பு**, பழைய மொழிபெயர்ப்பு எதையும் எஞ்சவிடாது | ஆம் | -| `check-new-key-coverage` (inline) | ஒரு **புதிய** ஆங்கில விசை ஒவ்வொரு locale-இலும் மொழிபெயர்க்கப்பட்டுள்ளது — `__MISSING__:` குறியீடு நிராகரிக்கப்படுகிறது | ஆம் | -| `check-translation-ratio` | ஒரு locale-க்கான உண்மையான மொழிபெயர்ப்பு விகிதம் (அனுமதிப் பட்டியலுக்கு வெளியே ஆங்கிலத்துடன் ஒரே மாதிரியாக உள்ள / placeholder / விடுபட்ட இலைகள்) `config/quality/i18n-translation-baseline.json` + slack-ஐ மீறக்கூடாது | **ஆலோசனை** | +| ஸ்கிரிப்ட் | சரிபார்ப்பது | தடுக்கும் தன்மை | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (inline) | UI i18n விசை உள்ளடக்கம் ≥ 65% ஆக உள்ளதா | ஆம் | +| `check-ui-value-drift` (inline) | மீண்டும் எழுதப்பட்ட ஓர் ஆங்கில **மதிப்பு**, காலாவதியான மொழிபெயர்ப்பு எதையும் விட்டுச் செல்லவில்லையா | ஆம் | +| `check-new-key-coverage` (inline) | ஒரு **புதிய** ஆங்கில விசை ஒவ்வொரு locale-இலும் மொழிபெயர்க்கப்பட்டுள்ளதா — `__MISSING__:` குறியீடு நிராகரிக்கப்படும் | ஆம் | +| `check-translation-ratio` | locale-வாரியான உண்மை-மொழிபெயர்ப்பு விகிதம் (அனுமதிப்புப் பட்டியலுக்கு வெளியே ஆங்கிலத்துடன் ஒரே மாதிரியான / placeholder / விடுபட்ட இலைகள்) `config/quality/i18n-translation-baseline.json` + தளர்வை மீறக்கூடாது | **ஆலோசனை** | -`fetch-depth: 0` தேவை — மதிப்பு-மாறுபாட்டு வாயில், merge base-க்கு எதிராக `en.json`-ஐ diff செய்கிறது. +`fetch-depth: 0` தேவை — மதிப்பு-விலகல் வாயில், ஒன்றிணைப்பு அடிப்படைக்கு எதிராக `en.json`-ஐ ஒப்பிடுகிறது. -#### `check-ui-value-drift` — பழைய மொழிபெயர்ப்பு வாயில் +#### `check-ui-value-drift` — காலாவதியான-மொழிபெயர்ப்பு வாயில் -மற்ற வாயில்கள் கட்டமைப்பு ரீதியாகக் கண்டறிய முடியாத ஒரே i18n பின்னடைவை இது கண்டறிகிறது: ஓர் ஆங்கில மதிப்பு -மீண்டும் எழுதப்பட்ட பிறகும், _முந்தைய_ ஆங்கிலத்திலிருந்து உருவாக்கப்பட்ட மொழிபெயர்ப்புகள் அப்படியே எஞ்சிவிடுவதால், -ஆங்கிலமல்லாத பயனர்கள் நம்பிக்கையூட்டும் வகையில் எழுதப்பட்டிருந்தாலும் இப்போது தவறான உரையைத் தொடர்ந்து படிக்கிறார்கள். +மற்ற வாயில்களால் கட்டமைப்பு ரீதியாகக் கண்டறிய முடியாத ஒரு i18n பின்னடைவை இது கண்டறிகிறது: ஓர் ஆங்கில மதிப்பு +மீண்டும் எழுதப்பட்ட பின்னரும், _முந்தைய_ ஆங்கிலத்திலிருந்து பெறப்பட்ட மொழிபெயர்ப்புகள் அப்படியே இருப்பதால், +ஆங்கிலமல்லாத மொழிகளைப் பயன்படுத்துவோர் நம்பிக்கையுடன் எழுதப்பட்ட, ஆனால் இப்போது தவறான உரையையே தொடர்ந்து படிக்கிறார்கள். -இது உண்மையிலேயே வெளியீட்டுக்குச் சென்றது. Antigravity உள்நுழைவு உதவி சேர்க்கப்பட்டபோது (#5203) +இது உண்மையிலேயே வெளியீட்டில் இடம்பெற்றது. Antigravity உள்நுழைவு உதவி சேர்க்கப்பட்டபோது (#5203), `oauthModal.googleOAuthWarning` மீண்டும் எழுதப்பட்டது; **43 locale-களில் 39**-இல், இயக்குநர்களிடம் "முழு -URL-ஐ நகலெடுத்து கீழே ஒட்டவும்" என்று கூறும் உரை அப்படியே இருந்தது — அந்த வழங்குநருக்காக நிறைவுசெய்ய -முடியாத ஒரு செயல்முறை. பின்வரும் காரணங்களால் #8463 வரை இது கவனிக்கப்படவில்லை: +URL-ஐ நகலெடுத்து கீழே ஒட்டவும்" என்று கூறும் உரை அப்படியே இருந்தது — அந்த வழங்குநருக்காக நிறைவு செய்ய முடியாத ஒரு செயல்முறை. பின்வரும் காரணங்களால் +#8463 வரை இது கவனிக்கப்படவில்லை: -- `sync-ui-keys`, **இல்லாத** விசைகளை மட்டுமே பின்னிரப்புகிறது; **பழைய** விசைகளை ஒருபோதும் புதுப்பிப்பதில்லை; -- `check-ui-keys-coverage` விசை _இருப்பதை_ மட்டுமே கணக்கிடுகிறது; எனவே பழைய மொழிபெயர்ப்பும் உள்ளடக்கப்பட்டதாக மதிப்பெண் பெறுகிறது; -- `check-translation-drift`, `docs/i18n//**.md` ஆவணப் பிரதிகளைப் பின்தொடர்கிறது — - அது `src/i18n/messages/*.json`-ஐ ஒருபோதும் படிப்பதில்லை. 2026-09 மறு-ஒத்திசைவிலிருந்து `docs-sync-strict` பணியில் தடுக்கும் நிலை அமலில் உள்ளது: ஒரு முக்கிய ஆவணத்தைத் திருத்தவும் → `npm run i18n:run -- --files=` (பிரிவு-நிலை, குறைந்த செலவு). +- `sync-ui-keys`, **இல்லாத** விசைகளை மட்டுமே நிரப்புகிறது; **காலாவதியான** விசைகளை ஒருபோதும் அல்ல; +- `check-ui-keys-coverage`, விசை _இருப்பை_ எண்ணுகிறது; எனவே காலாவதியான மொழிபெயர்ப்பும் உள்ளடக்கப்பட்டதாக மதிப்பெண் பெறுகிறது; +- `check-translation-drift`, `docs/i18n//**.md` ஆவணப் பிரதிகளைத் தடமறிகிறது — + அது `src/i18n/messages/*.json`-ஐ ஒருபோதும் படிப்பதில்லை. 2026-09 மறு-ஒத்திசைவிலிருந்து `docs-sync-strict` பணியில் தடுப்பதாக உள்ளது: முதன்மை ஆவணத்தைத் திருத்தவும் → `npm run i18n:run -- --files=` (பிரிவு-நிலை, செலவு குறைவு). -**வேறுபாடு சார்ந்தது; அடிப்படைப் பதிவால் ஆதரிக்கப்படாதது.** இது merge base-இல் உள்ள `en.json`-ஐ working tree உடன் ஒப்பிடுகிறது; ஆங்கில மதிப்பு மாறிய ஒவ்வொரு key-க்கும், இன்னும் மாற்றப்படாத மொழிபெயர்ப்பைக் கொண்டிருக்கும் locale காலாவதியானதாகும். இது வேண்டுமென்றே **முன்பே இருக்கும் கடனை உறையவைக்கிறது** — நீண்டகாலமாக இருக்கும் ஒரு மொழிபெயர்ப்பு எந்தப் பழைய ஆங்கிலத்திலிருந்து வந்தது என்பதை ஒரு diff-ஆல் வெளிப்படுத்த முடியாது; எனவே தற்போதைய மாற்றம் தொடும் பகுதிகளை மட்டுமே gate மதிப்பிடுகிறது. மாற்று அணுகுமுறைக்கு (ஒவ்வொரு key-க்கும் ஒரு hash baseline) சுமார் 600 KB அளவிலான உருவாக்கப்பட்ட கோப்பு தேவைப்படும்; இது தற்போதுள்ள மிகப்பெரிய baseline-ஐ விட 3× பெரியது, மேலும் ஒவ்வொரு i18n PR-இலும் மாறிக்கொண்டிருக்கும். +**Diff-aware, baseline-backed அல்ல.** இது merge base-இல் உள்ள `en.json`-ஐ working tree உடன் ஒப்பிடுகிறது; ஆங்கில மதிப்பு மாறியுள்ள ஒவ்வொரு key-க்கும், இன்னும் மாற்றப்படாத மொழிபெயர்ப்பைக் கொண்டிருக்கும் locale காலாவதியானதாகும். இது வேண்டுமென்றே **முன்பே இருந்த கடனை உறையவைக்கிறது** — நீண்டகாலமாக இருக்கும் ஒரு மொழிபெயர்ப்பு எந்தப் பழைய ஆங்கில உரையிலிருந்து வந்தது என்பதை diff-ஆல் கண்டறிய முடியாது; எனவே தற்போதைய மாற்றம் தொடும் பகுதிகளை மட்டுமே gate மதிப்பிடுகிறது. மாற்று வழியான (ஒவ்வொரு key-க்கும் hash baseline) சுமார் 600 KB அளவுள்ள உருவாக்கப்பட்ட கோப்பைத் தேவைப்படுத்தும்; அது தற்போதுள்ள மிகப்பெரிய baseline-ஐ விட 3× பெரியது மற்றும் ஒவ்வொரு i18n PR-லும் தொடர்ந்து மாறும். -இதைப் பூர்த்தி செய்ய இரண்டு வழிகள் உள்ளன: +இதைப் பூர்த்திசெய்ய இரண்டு வழிகள் உள்ளன: 1. பாதிக்கப்பட்ட மொழிபெயர்ப்புகளைப் புதுப்பிக்கவும், அல்லது -2. அவற்றை `__MISSING__:` என அமைக்கவும் — பின்னர் runtime திருத்தப்பட்ட ஆங்கிலத்தை வழங்கும் +2. அவற்றை `__MISSING__:` என அமைக்கவும் — பின்னர் runtime திருத்தப்பட்ட ஆங்கில உரையை வழங்கும் (`src/i18n/request.ts::deepMergeFallback`, #7258), மேலும் அந்த key மொழிபெயர்ப்புக்கான வரிசையில் சேர்க்கப்படும். -சரத்தின் **பொருள்** மாறியிருந்தால், **key-ஐ மறுபெயரிடுவதை** விரும்பவும்: ஒரு புதிய key காலாவதியான மொழிபெயர்ப்பை மரபுரிமையாகப் பெற முடியாது. #8463 பயன்படுத்திய முறை இதுதான். +சரத்தின் **பொருள்** மாறியிருந்தால், **key-ஐ மறுபெயரிடுவதை** விரும்பவும்: ஒரு புதிய key காலாவதியான மொழிபெயர்ப்பை மரபாகப் பெற முடியாது. #8463 பயன்படுத்திய முறை இதுதான். ```bash npm run i18n:check-value-drift # கடுமையானது (CI இயக்குவது) @@ -224,47 +224,47 @@ npm run i18n:check-value-drift:warn # அறிக்கை மட்டு BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -அடிப்படை catalog-ஐப் படிக்க முடியாதபோது (base ref இல்லாத shallow clone), `check-openapi-breaking`-ஐப் பிரதிபலிக்கும் வகையில், `SKIP reason=base-unresolved` உடன் 0-ஆக வெளியேறும். +அடிப்படை catalog-ஐப் படிக்க முடியாதபோது (base ref இல்லாத shallow clone), `check-openapi-breaking`-ஐப் பிரதிபலிக்கும் விதமாக `SKIP reason=base-unresolved` உடன் 0 என்ற exit code-ஐ வழங்குகிறது. ### பணி: `i18n` -முழுமையான i18n சரிபார்ப்பு matrix (ஒவ்வொரு locale-க்கும் ஒரு பணி). முழுப் பணியும் ஆலோசனைத் தன்மையுடையது. +முழுமையான i18n சரிபார்ப்பு matrix (ஒவ்வொரு locale-க்கும் ஒரு பணி). முழுப் பணியும் ஆலோசனை சார்ந்தது. -| Script | சரிபார்ப்பது | தடுக்கும் தன்மை | -| ------------------------------- | ------------------------------------------- | --------------------------------------------------------------- | -| `validate_translation.py quick` | ஒவ்வொரு locale-க்குமான மொழிபெயர்ப்பு முழுமை | **ஆலோசனை மட்டும்** (முழுப் பணியிலும் `continue-on-error: true`) | +| Script | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ------------------------------- | ------------------------------------------- | ----------------------------------------------------------------- | +| `validate_translation.py quick` | ஒவ்வொரு locale-க்குமான மொழிபெயர்ப்பு முழுமை | **ஆலோசனை சார்ந்தது** (முழுப் பணியிலும் `continue-on-error: true`) | ### பணி: `pr-test-policy` Pull request-களில் மட்டும் இயங்கும். -| Script | சரிபார்ப்பது | தடுக்கும் தன்மை | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, அல்லது `bin/`-இல் உள்ள production code-ஐ மாற்றும் PR-கள் சோதனைகளைச் சேர்க்கவோ புதுப்பிக்கவோ வேண்டும் (கடுமையான விதி #8) | ஆம் | -| `check:test-masking` | மாற்றப்பட்ட சோதனைக் கோப்புகள் மொத்த assert எண்ணிக்கையைக் குறைக்கக்கூடாது அல்லது `assert.ok(true)` போன்ற tautology-களைச் சேர்க்கக்கூடாது | ஆம் | -| `check:pr-evidence` | PR body மாற்றத்திற்கான சோதனை/VPS ஆதாரத்தைக் குறிப்பிடுகிறது (PR உரையில் grep செய்வதன் மூலம் கடுமையான விதி #18-ஐ இயந்திரமயமாக்குகிறது — எளிதில் உடையக்கூடியது; Backlog-ஐப் பார்க்கவும்) | ஆம் | +| Script | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, அல்லது `bin/`-இல் உள்ள production code-ஐ மாற்றும் PR-கள் சோதனைகளைச் சேர்க்க அல்லது புதுப்பிக்க வேண்டும் (கடுமையான விதி #8) | ஆம் | +| `check:test-masking` | மாற்றப்பட்ட சோதனைக் கோப்புகள் மொத்த assert எண்ணிக்கையைக் குறைக்கவில்லை அல்லது `assert.ok(true)` tautology-களைச் சேர்க்கவில்லை | ஆம் | +| `check:pr-evidence` | மாற்றத்திற்கான சோதனை/VPS ஆதாரத்தை PR body மேற்கோள் காட்டுகிறது (PR உரையை grep செய்வதன் மூலம் கடுமையான விதி #18-ஐ இயந்திரமயமாக்குகிறது — எளிதில் உடையக்கூடியது, Backlog-ஐப் பார்க்கவும்) | ஆம் | ### பணி: `test-vitest` `build`-க்குப் பிறகு இயங்கும். தோல்வியடைந்தால் merge-ஐத் தடுக்கும். -| தொகுப்பு | சரிபார்ப்பது | தடுக்கும் தன்மை | -| ---------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 கருவிகள்), autoCombo, cache — vitest runner | ஆம் | -| `test:vitest:ui` | UI component சோதனைகள் — vitest runner | **தடுக்கும்** — முன்பே இருக்கும் தோல்விகள் `vitest.config.ts`-இல் வெளிப்படையாக விலக்கப்பட்டுள்ளன; புதிய தோல்விகள் பணியைத் தோல்வியடையச் செய்யும் | +| தொகுப்பு | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 கருவிகள்), autoCombo, cache — vitest runner | ஆம் | +| `test:vitest:ui` | UI component சோதனைகள் — vitest runner | **தடுக்கும்** — முன்பே இருந்த தோல்விகள் `vitest.config.ts`-இல் வெளிப்படையாக விலக்கப்பட்டுள்ளன; புதிய தோல்விகள் பணியைத் தோல்வியடையச் செய்யும் | -### இரவுநேர workflow-கள் (திட்டமிடப்பட்டவை, ஆலோசனை மட்டும்) +### இரவுநேர workflow-கள் (திட்டமிடப்பட்டவை, ஆலோசனை சார்ந்தவை) -இவை cron அட்டவணைப்படி (மற்றும் `workflow_dispatch` மூலம்) இயங்குகின்றன; PR-களில் ஒருபோதும் இயங்காது. அனைத்தும் ஆலோசனைத் தன்மையுடையவை. +இவை cron அட்டவணையில் (மற்றும் `workflow_dispatch` வழியாக) இயங்கும்; PR-களில் ஒருபோதும் இயங்காது. அனைத்தும் ஆலோசனை சார்ந்தவை. -| Workflow | சரிபார்ப்பது | தடுக்கும் தன்மை | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `nightly-property` | சீரற்ற seed மற்றும் அதிக run எண்ணிக்கையுடன் fast-check property சோதனைகள் | **ஆலோசனை மட்டும்** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **ஆலோசனை மட்டும்** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret இல்லாமல் தவிர்க்கப்படும்) | **ஆலோசனை மட்டும்** | -| `nightly-schemathesis` | `docs/openapi.yaml`-ஐப் பயன்படுத்தி இயங்கும் OmniRoute-க்கு எதிரான OpenAPI contract fuzzing (schemathesis) — specification மீறல்கள் / கையாளப்படாத 500 பிழைகளை வெளிக்கொணர்கிறது (கட்டம் 8 B.4) | **ஆலோசனை மட்டும்** | -| `nightly-mutation` | வேகமான unit lane-இல் Stryker mutation-testing மதிப்பெண் — தப்பிப்பிழைக்கும் mutants பலவீனமான assert-களை வெளிக்கொணர்கின்றன | **ஆலோசனை மட்டும்** | -| `nightly-compat` | ஆதரிக்கப்படும் `engines.node` வரம்புகள் முழுவதும் Node engine compatibility matrix | **ஆலோசனை மட்டும்** | +| Workflow | சரிபார்ப்பது | தடுக்கும் தன்மை | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `nightly-property` | சீரற்ற seed மற்றும் அதிக run எண்ணிக்கையுடன் fast-check property சோதனைகள் | **ஆலோசனை சார்ந்தது** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **ஆலோசனை சார்ந்தது** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret இல்லாமல் தவிர்க்கப்படும்) | **ஆலோசனை சார்ந்தது** | +| `nightly-schemathesis` | `docs/openapi.yaml`-ஐப் பயன்படுத்தி இயங்கும் OmniRoute-க்கு எதிரான OpenAPI contract fuzzing (schemathesis) — spec மீறல்கள் / கையாளப்படாத 500 பிழைகளை வெளிக்கொணரும் (கட்டம் 8 B.4) | **ஆலோசனை சார்ந்தது** | +| `nightly-mutation` | வேகமான unit lane மீதான Stryker mutation-testing மதிப்பெண் — தப்பிப் பிழைக்கும் mutants பலவீனமான assert-களை வெளிக்கொணரும் | **ஆலோசனை சார்ந்தது** | +| `nightly-compat` | ஆதரிக்கப்படும் `engines.node` வரம்புகள் முழுவதுமான Node engine இணக்கத்தன்மை matrix | **ஆலோசனை சார்ந்தது** | --- @@ -527,43 +527,43 @@ CI வாயில்களுக்கு அப்பால், OmniRoute ஒ --- -## சீராக்கல் நிலுவைப் பட்டியல் (ROI மதிப்பாய்வு — கட்டம் 9 அலை 3) +## நியாயப்படுத்தல் நிலுவைப் பட்டியல் (ROI மதிப்பாய்வு — கட்டம் 9 அலை 3) -இந்தப் பட்டியல் 2026-06-17 அன்று `ci.yml` உடன் ஒப்பிட்டு சரிசெய்யப்பட்டது (முந்தைய பதிப்பில் +இந்தப் பட்டியல் 2026-06-17 அன்று `ci.yml` உடன் ஒத்திசைத்துச் சரிபார்க்கப்பட்டது (முந்தைய பதிப்பில் `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` ஆகியவை விடுபட்டிருந்தன). சரிசெய்யப்பட்ட தொகுப்பின் ROI மதிப்பாய்வு -பின்வரும் சீராக்கல் வேட்பாளர்களை அடையாளம் கண்டது. **இணைப்புகள் இயந்திரரீதியான CI -மாற்றங்கள்; நிலைமாற்றங்கள்/நீக்கங்கள் இயக்குநருக்காக ஒதுக்கப்பட்ட கொள்கை முடிவுகள்.** கீழே உள்ள எதுவும் -இன்னும் செயல்படுத்தப்படவில்லை. - -**மேலே ஆவணப்படுத்தப்படாதவை** (ஆலோசனை மட்டும், குறைந்த சமிக்ஞை): `docs-lint` பணி -(markdownlint + Vale, முழுப் பணிக்கும் `continue-on-error`) மற்றும் தனித்தியங்கும் ஸ்கேனர் பணிப்பாய்வுகளான -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `quality-baseline.json`-இல் -`semgrepFindings: 0` உள்ளது, ஆனால் `ci.yml`-இல் தடுக்கும் ratchet ஒன்றுடன் இணைக்கப்படவில்லை — இந்த அளவீடு +`check:codeql-ratchet`, `check:pr-evidence` ஆகியவை விடுபட்டிருந்தன). ஒத்திசைக்கப்பட்ட தொகுப்பின் ROI மதிப்பாய்வு +பின்வரும் நியாயப்படுத்தல் வாய்ப்புகளைக் கண்டறிந்தது. **ஒன்றிணைப்புகள் இயந்திரரீதியான CI +மாற்றங்கள்; மாற்றங்கள்/நீக்கங்கள் இயக்குநருக்காக ஒதுக்கப்பட்ட கொள்கை முடிவுகள்.** கீழே உள்ள எதுவும் +இன்னும் பயன்படுத்தப்படவில்லை. + +**மேலே ஆவணப்படுத்தப்படாதவையும் உள்ளன** (ஆலோசனை மட்டுமே, குறைந்த சமிக்ஞை): `docs-lint` பணி +(markdownlint + Vale, முழுப் பணிக்கும் `continue-on-error`) மற்றும் தனித்தனி ஸ்கேனர் பணிப்பாய்வுகளான +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` என்பது +`quality-baseline.json`-இல் உள்ளது, ஆனால் `ci.yml`-இல் தடுக்கும் ratchet ஒன்றுடன் இணைக்கப்படவில்லை — இந்த அளவீடு தற்போது தொடர்பற்ற நிலையில் உள்ளது. -### இணைத்தல் / நகல் நீக்கம் (இயந்திரரீதியானது, குறைந்த அபாயம்) +### ஒன்றிணைத்தல் / நகல்நீக்கம் (இயந்திரரீதியானது, குறைந்த ஆபத்து) -ஒவ்வொரு வேட்பாளரும் 2026-06-17 அன்று நேரடி gate நிலைக்கு எதிராகச் சரிபார்க்கப்பட்டது (நம்பினாலும் சரிபார்); -பல "வெளிப்படையான" இணைப்புகள் கடனை மறைத்திருப்பது தெரியவந்ததால் அவை **தடையின்றி மாற்றக்கூடியவை அல்ல**. +ஒவ்வொரு வாய்ப்பும் 2026-06-17 அன்று நடைமுறையிலிருந்த gate நிலைக்கு எதிராகச் சரிபார்க்கப்பட்டது (நம்பு-ஆனால்-சரிபார்); +பல "வெளிப்படையான" ஒன்றிணைப்புகள் மறைந்திருந்த கடனை மூடிமறைத்தது தெரியவந்ததால், அவை **சுத்தமான** நேரடி மாற்றீடுகள் அல்ல. -- **`check:docs-sync` இருமுறை இயங்குகிறது** — `lint` பணியில் தனியாகவும், `check:docs-all` (`docs-sync-strict`) மற்றும் husky pre-commit hook ஆகியவற்றுக்குள்ளும் மீண்டும் இயங்குகிறது. ✅ **முடிந்தது** — தனித்த `lint` இயக்கம் நீக்கப்பட்டது. -- **CVE ஸ்கேனிங்** — ❌ **தடையற்ற இணைப்பு அல்ல.** எந்தவொரு high/critical CVE இருந்தாலும் `audit:deps` கடுமையாகத் தோல்வியடைகிறது; `check:vuln-ratchet` (osv), baseline உடன் ஒப்பிடும்போது ஒரு _பின்னடைவு_ ஏற்பட்டால் மட்டுமே தோல்வியடைகிறது (தற்போது 1 MODERATE). பொருளியல் வேறுபட்டது — `audit:deps`-ஐ நீக்குவது முழுமையான high/critical gate-ஐ இழக்கச் செய்யும். இரண்டையும் வைத்திருக்கவும். -- **சுழற்சி கண்டறிதல்** — ❌ **தடையற்ற இணைப்பு அல்ல.** `check:circular-deps` (dpdm) **91 சுழற்சிகளை** அறிக்கையிடுகிறது (அதனால்தான் அது ஆலோசனை நிலையிலுள்ளது); அவற்றை முதலில் தீர்க்காமல் அதைத் தடுக்கும் நிலைக்கு உயர்த்த முடியாது, மேலும் green நிலையில் உள்ள, தேர்ந்தெடுக்கப்பட்ட `check:cycles`-ஐ விட இதன் நோக்கெல்லை பரந்தது. `check:cycles`-ஐ தடுக்கும் நிலையில் வைத்திருக்கவும்; 91 dpdm சுழற்சிகளைத் தீர்ப்பது தனி நிலுவைப் பணியாகும். -- **சிக்கல்தன்மை** — ✅ **முடிந்தது** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ஒரே ESLint நடை, ruleId வாரியாக எண்ணுவதால் cyclomatic+max-lines மற்றும் cognitive baseline-கள் தனித்தனியாகவே இருக்கின்றன; தனிப்பட்ட `check:complexity` / `check:cognitive-complexity` உள்ளூர் `--update` பயன்பாட்டிற்காகத் தொடர்ந்து உள்ளன. -- **`/api` தவறான உருவாக்கத் தடுப்பு** — ✅ **முடிந்தது** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-க்கான ஒரே FS பட்டியல்; openapi-routes + docs-symbols இன்னும் தனித்தனியாக அறிக்கையிடுகின்றன; தனிப்பட்டவை உள்ளூர் இயக்கங்களுக்காகத் தொடர்ந்து உள்ளன. -- **`check:node-runtime` 11 பணிகளில் இயங்குகிறது** — ⚠️ **குறைந்த ROI.** ஒவ்வொன்றும் தனித்தனி runner ஆகும், மேலும் இந்தச் சோதனை <1s மட்டுமே எடுக்கும்; மலிவான ஒவ்வொரு பணிக்குமான பாதுகாப்பை இழப்பதற்கு எதிராக, மொத்தச் சேமிப்பு ~10s மட்டுமே. இந்த மாற்றக் குழப்பத்திற்குத் தகுதியானதல்ல. -- **CI lint-இல் `typecheck:noimplicit:core`** — ✅ **lint பணியிலிருந்து நீக்கப்பட்டது** (ஆலோசனை `continue-on-error` ஆக இருந்தது); தடுக்கும் type surface என்பது `typecheck:core` + `check:type-coverage`. உள்ளூர் script தக்கவைக்கப்பட்டது. +- **`check:docs-sync` இருமுறை இயங்குகிறது** — `lint` பணியில் தனியாகவும், `check:docs-all` (`docs-sync-strict`) மற்றும் husky pre-commit hook ஆகியவற்றிற்குள்ளும் இயங்குகிறது. ✅ **முடிந்தது** — தனித்தனி `lint` அழைப்பு அகற்றப்பட்டது. +- **CVE ஸ்கேனிங்** — ❌ **சுத்தமான ஒன்றிணைப்பு அல்ல.** உயர்/மிக முக்கியமான எந்த CVE இருந்தாலும் `audit:deps` உடனடியாகத் தோல்வியடைகிறது; `check:vuln-ratchet` (osv) baseline உடன் ஒப்பிடும்போது ஒரு _பின்னடைவு_ ஏற்பட்டால் மட்டுமே தோல்வியடைகிறது (தற்போது 1 MODERATE). வெவ்வேறு பொருளியல் — `audit:deps`-ஐ நீக்கினால் முழுமையான உயர்/மிக முக்கியமான gate இழக்கப்படும். இரண்டையும் வைத்திருக்கவும். +- **சுழற்சி கண்டறிதல்** — ✅ **முடிந்தது** (#15159 G-01/G-02). இங்கிருந்த பழைய உரை `check:cycles`-ஐ "பச்சை நிலையிலுள்ள, தேர்ந்தெடுக்கப்பட்ட" gate எனக் குறிப்பிட்டு, `check:circular-deps` (dpdm) 91 சுழற்சிகளைப் புகாரளித்ததால் அதைத் தடுக்கும் நிலையில் வைத்திருப்பதை நியாயப்படுத்தியது. அந்தப் பச்சை நிலை ஒரு **தவறான பச்சை நிலை**: `check:cycles` 5 துணைக் கோப்பகங்களை (450 கோப்புகள்) ஸ்கேன் செய்தது, நிலையான `import|export … from` உடன் மட்டுமே பொருத்தியது, மேலும் ஒவ்வொரு `@/` மற்றும் `@omniroute/open-sse/` specifier-ஐயும் விலக்கியது; எனவே repo-வில் ஆதிக்கம் செலுத்திய dynamic-import + alias சுழற்சிகளை அதனால் காண முடியவில்லை. சரிசெய்யப்பட்டது: இப்போது gate `src` + `open-sse` முழுவதையும் (5023 கோப்புகள்) பார்வையிட்டு, TypeScript AST-இலிருந்து specifier-களைச் சேகரிக்கிறது (எனவே `import("…")` கணக்கில் கொள்ளப்படும், ஆனால் type-position `typeof import("…")` கணக்கில் கொள்ளப்படாது), மேலும் tsconfig `paths`-ஐத் தீர்க்கிறது. இது 0 அல்ல, **14** சுழற்சிகளைக் கண்டறிகிறது. முன்பே இருந்த 14 சுழற்சிகளை ஒரு gate PR-இல் சரிசெய்ய முடியாது என்பதால், `check:cycles` இப்போது ஒரு **ratchet** (`--ratchet`, `quality-baseline.json`-இல் உச்சவரம்பு `metrics.cycles.value = 14`, `direction: down`) — எந்தப் _பின்னடைவையும்_ இது தடுக்கிறது, மேலும் எண்ணிக்கை குறைய மட்டுமே முடியும். CI `npm run check:cycles:ratchet`-ஐ இயக்குகிறது. படிப்படியான குறைப்பு **A-01** உடன் தொடர்கிறது. பரந்த இரண்டாவது மதிப்பீடாக `check:circular-deps` (dpdm) ஆலோசனை நிலையில் தொடர்கிறது. +- **சிக்கல்தன்மை** — ✅ **முடிந்தது** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ஒரே ESLint பார்வையிடல், ruleId அடிப்படையிலான எண்ணிக்கைகள்; எனவே cyclomatic+max-lines மற்றும் cognitive baseline-கள் தனித்தனியாகவே இருக்கும்; உள்ளூர் `--update` பயன்பாட்டிற்காகத் தனிப்பட்ட `check:complexity` / `check:cognitive-complexity` தொடர்ந்து வைக்கப்பட்டுள்ளன. +- **`/api` மாயத்தோற்றத் தடுப்பு** — ✅ **முடிந்தது** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`-இன் ஒரே FS பட்டியல், openapi-routes + docs-symbols இன்னும் தனித்தனியாகப் புகாரளிக்கின்றன; உள்ளூர் இயக்கங்களுக்காகத் தனிப்பட்டவை தொடர்ந்து வைக்கப்பட்டுள்ளன. +- **`check:node-runtime` 11 பணிகளில் இயங்குகிறது** — ⚠️ **குறைந்த ROI.** ஒவ்வொன்றும் தனித்தனி runner மற்றும் சரிபார்ப்பு <1s; மலிவான ஒவ்வொரு-பணிக்குமான பாதுகாப்பை இழப்பதற்கு எதிராக, மொத்தச் சேமிப்பு ~10s மட்டுமே. மாற்றக் குழப்பத்திற்கு இது தகுதியானதல்ல. +- **CI lint-இல் `typecheck:noimplicit:core`** — ✅ **lint பணியிலிருந்து அகற்றப்பட்டது** (ஆலோசனை நிலை `continue-on-error` ஆக இருந்தது); தடுக்கும் type பரப்பு `typecheck:core` + `check:type-coverage` ஆகும். உள்ளூர் script தக்கவைக்கப்பட்டது. -### நிலைமாற்றம் / முடிவு (இயக்குநர் கொள்கை) +### மாற்றுதல் / முடிவெடுத்தல் (இயக்குநர் கொள்கை) -- `check:openapi-security-tiers` (ஆலோசனை) — ❌ **தடையின்றி நிலைமாற்ற முடியாது.** இது 0-உடன் வெளியேறுகிறது, ஆனால் `LOCAL_ONLY_API_PREFIXES`-இன் கீழ் உள்ள பல `traffic-inspector` route-களில் `x-loopback-only: true` annotation இல்லை என எச்சரிக்கிறது. இதை அமல்படுத்துவதற்கு முதலில் அந்த annotation-களை `openapi.yaml`-இல் சேர்க்க வேண்டும். -- `typecheck:noimplicit:core` (ஆலோசனை) — தடுக்கும் `check:type-coverage` ratchet பெரும்பாலும் இதை உள்ளடக்குகிறது. இதை ratchet ஆக மாற்றவும் அல்லது தேவையற்ற இரண்டாவது `tsc` pass-ஐ நீக்கவும். -- `test:vitest:ui` (இப்போது **தடுக்கும் நிலையில்**) — ஏற்கெனவே இருந்த தோல்விகள் `vitest.config.ts`-இல் `// #8618` கண்காணிப்புக் குறிப்புகளுடன் வெளிப்படையாக விலக்கப்பட்டுள்ளன; புதிய தோல்விகள் பணியைத் தோல்வியடையச் செய்யும். -- `check:secrets` (gitleaks, ஆவணப்படுத்தப்பட்ட 3 false-positive-களில் உறையவைக்கப்பட்ட தடுக்கும் ratchet) — 0-ஐ அடைய அந்த 3-ஐ allowlist செய்யவும் அல்லது ஆலோசனை நிலைக்குத் தாழ்த்தவும். GitHub-இன் சொந்த secret-scanning + `check:public-creds` உடன் ஒன்றிணைகிறது. -- `check:pr-evidence` (தடுக்கும் நிலையில், PR-body உரையை grep செய்கிறது) — அதிக false-positive அபாயம்; நீக்கப்பட்டால் Hard Rule #18 அமலாக்கம் பலவீனமடையும், எனவே இது உண்மையான கொள்கை முடிவாகும். -- `semgrep` (தனித்தியங்கும் ஆலோசனை) — OWASP குடும்பங்களுக்கு CodeQL உடன் ஒன்றிணைகிறது; அதன் baseline-ஐ ஒரு ratchet உடன் இணைக்கவும் அல்லது நீக்கவும். +- `check:openapi-security-tiers` (ஆலோசனை நிலை) — ❌ **சுத்தமாகத் தடுக்கும் நிலைக்கு மாற்ற முடியாது.** இது 0 என்ற நிலையில் வெளியேறினாலும், `LOCAL_ONLY_API_PREFIXES`-இன் கீழுள்ள பல `traffic-inspector` route-களில் `x-loopback-only: true` annotation இல்லை என எச்சரிக்கிறது. இதை அமல்படுத்த முதலில் அந்த annotation-களை `openapi.yaml`-இல் சேர்க்க வேண்டும். +- `typecheck:noimplicit:core` (ஆலோசனை நிலை) — தடுக்கும் `check:type-coverage` ratchet இதன் பெரும்பகுதியை ஏற்கெனவே உள்ளடக்குகிறது. இதை ratchet ஆக மாற்றவும் அல்லது தேவையற்ற இரண்டாவது `tsc` pass-ஐ நீக்கவும். +- `test:vitest:ui` (இப்போது **தடுக்கும் நிலையில்**) — முன்பே இருந்த தோல்விகள் `vitest.config.ts`-இல் `// #8618` கண்காணிப்புக் குறிப்புகளுடன் வெளிப்படையாக விலக்கப்பட்டுள்ளன; புதிய தோல்விகள் பணியைத் தோல்வியடையச் செய்யும். +- `check:secrets` (gitleaks, ஆவணப்படுத்தப்பட்ட 3 false-positive-களில் நிலைநிறுத்தப்பட்ட தடுக்கும் ratchet) — 0-ஐ எட்ட அந்த 3-ஐ allowlist செய்யவும், அல்லது ஆலோசனை நிலைக்குக் குறைக்கவும். GitHub-இன் சொந்த secret-scanning + `check:public-creds` உடன் இது ஒன்றோடொன்று மேலெழுகிறது. +- `check:pr-evidence` (தடுக்கும் நிலையில், PR-body உரையை grep செய்கிறது) — false-positive ஆபத்து அதிகம்; இதை நீக்கினால் Hard Rule #18 அமலாக்கம் பலவீனமடையும், எனவே இது உண்மையான கொள்கை முடிவு. +- `semgrep` (தனித்தனி ஆலோசனை நிலை) — OWASP குடும்பங்களில் CodeQL உடன் ஒன்றோடொன்று மேலெழுகிறது; அதன் baseline-ஐ ratchet ஒன்றுடன் இணைக்கவும் அல்லது நீக்கவும். --- diff --git a/docs/i18n/te/CONTRIBUTING.md b/docs/i18n/te/CONTRIBUTING.md index 112075afb64..2644bd19cf3 100644 --- a/docs/i18n/te/CONTRIBUTING.md +++ b/docs/i18n/te/CONTRIBUTING.md @@ -380,22 +380,22 @@ docs/ # Documentation --- -## పుల్ రిక్వెస్ట్ తనిఖీ జాబితా +## పుల్ రిక్వెస్ట్ చెక్లిస్ట్ - [ ] పరీక్షలు విజయవంతమయ్యాయి (`npm test`) - [ ] లింటింగ్ విజయవంతమైంది (`npm run lint`) - [ ] బిల్డ్ విజయవంతమైంది (`npm run build`) - [ ] కొత్త పబ్లిక్ ఫంక్షన్లు మరియు ఇంటర్ఫేస్ల కోసం TypeScript టైప్లు జోడించబడ్డాయి - [ ] హార్డ్కోడ్ చేసిన సీక్రెట్లు లేదా ఫాల్బ్యాక్ విలువలు లేవు -- [ ] పబ్లిక్ అప్స్ట్రీమ్ క్రెడెన్షియల్లు లిటరల్లుగా కాకుండా `resolvePublicCred()` ద్వారా పొందుపరచబడ్డాయి ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) చూడండి) -- [ ] ఎర్రర్ రెస్పాన్స్లు `buildErrorBody()` / `sanitizeErrorMessage()` ద్వారా రూట్ చేయబడతాయి — రెస్పాన్స్ బాడీలలో ముడి స్టాక్ ట్రేస్లు ఉండకూడదు ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) చూడండి) +- [ ] పబ్లిక్ అప్స్ట్రీమ్ క్రెడెన్షియల్స్ను లిటరల్స్గా కాకుండా `resolvePublicCred()` ద్వారా పొందుపరిచారు ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) చూడండి) +- [ ] ఎర్రర్ రెస్పాన్స్లు `buildErrorBody()` / `sanitizeErrorMessage()` ద్వారా పంపబడతాయి — రెస్పాన్స్ బాడీలలో ముడి స్టాక్ ట్రేస్లు ఉండవు ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) చూడండి) - [ ] షెల్ కమాండ్లు (`exec` / `spawn`) రన్టైమ్ విలువలను స్ట్రింగ్ ఇంటర్పోలేషన్ ద్వారా కాకుండా `env` ద్వారా పంపుతాయి - [ ] అన్ని ఇన్పుట్లు Zod స్కీమాలతో ధ్రువీకరించబడ్డాయి - [ ] వినియోగదారులకు కనిపించే మార్పుల కోసం `changelog.d/{features|fixes|maintenance}/-.md` కింద చేంజ్లాగ్ **ఫ్రాగ్మెంట్** జోడించబడింది ([`changelog.d/README.md`](./changelog.d/README.md) చూడండి) — `CHANGELOG.md`ను నేరుగా సవరించవద్దు; ఫ్రాగ్మెంట్లు విడుదల సమయంలో సమీకరించబడతాయి మరియు PRల మధ్య ఎప్పటికీ విభేదించవు - [ ] డాక్యుమెంటేషన్ నవీకరించబడింది (వర్తిస్తే) -- [ ] కొత్త CodeQL / Secret-Scanning అలర్ట్లు ఏవీ తెరవబడలేదు, లేదా ప్రతి అలర్ట్ సంబంధిత `docs/security/` డాక్యుమెంట్ను ప్రస్తావించే సాంకేతిక సమర్థనతో విస్మరించబడింది +- [ ] కొత్త CodeQL / Secret-Scanning అలర్ట్లు ఏవీ తెరవబడలేదు లేదా ప్రతి అలర్ట్ను సంబంధిత `docs/security/` డాక్యుమెంట్ను సూచించే సాంకేతిక సమర్థనతో డిస్మిస్ చేశారు - [ ] చైల్డ్ ప్రాసెస్లను ప్రారంభించే రూట్లు (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts`లో `isLocalOnlyPath()`గా వర్గీకరించబడ్డాయి — [కఠిన నియమం #15](docs/security/ROUTE_GUARD_TIERS.md) చూడండి -- [ ] కమిట్ సందేశాలలో `Co-Authored-By` ట్రైలర్లు లేవు — కమిట్లు పూర్తిగా రిపాజిటరీ యజమాని Git గుర్తింపు కింద మాత్రమే కనిపించాలి (కఠిన నియమం #16) +- [ ] కమిట్ సందేశాలలో AI/బాట్ `Co-authored-by` ట్రైలర్లు లేవు (కఠిన నియమం #16) — తిరిగి ఉపయోగించిన పనికి చెందిన మానవ సహకారులకు ప్రామాణిక `Co-authored-by: Name ` ట్రైలర్లతో క్రెడిట్ ఇవ్వబడింది --- diff --git a/docs/i18n/te/docs/architecture/QUALITY_GATES.md b/docs/i18n/te/docs/architecture/QUALITY_GATES.md index c6420442135..7aaeb20607c 100644 --- a/docs/i18n/te/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/te/docs/architecture/QUALITY_GATES.md @@ -17,255 +17,261 @@ ratchet baseline లేదా pass/fail విధానాన్ని ఉపయ ## గేట్ ఇన్వెంటరీ మరియు అమలు ప్రొఫైల్లు -### అభ్యర్థి అనుమతి +### అభ్యర్థి ప్రవేశం -CI మరియు Quality Gates వర్క్ఫ్లోలు ఒక్కొక్కటి స్థిరమైన తీర్పును వెలువరిస్తాయి: `Gate / CI` మరియు -`Gate / Quality`. వాటి వెర్షన్ చేయబడిన అనుమతి విధానం ప్రతి అప్స్ట్రీమ్ జాబ్ను -తప్పనిసరి లేదా సలహాత్మకమైనదిగా పేర్కొంటుంది. వర్తించే తప్పనిసరి జాబ్ విజయవంతం కావాలి: లేని, +CI మరియు Quality Gates వర్క్ఫ్లోలు ఒక్కొక్కటి స్థిరమైన తీర్పును ఉత్పత్తి చేస్తాయి: `Gate / CI` మరియు +`Gate / Quality`. వాటి వెర్షన్ చేయబడిన ప్రవేశ విధానం ప్రతి అప్స్ట్రీమ్ జాబ్ను +తప్పనిసరి లేదా సలహాపరమైనదిగా జాబితా చేస్తుంది. వర్తించే తప్పనిసరి జాబ్ తప్పనిసరిగా విజయవంతం కావాలి: లేని, రద్దయిన, దాటవేయబడిన, పెండింగ్లో ఉన్న మరియు తెలియని ఫలితాలు PASSను నిర్ధారించలేవు. చెల్లుబాటు అయ్యే -docs-only లేదా catalog-only వర్గీకరణ ఒక కోడ్ లేన్ను వర్తించనిదిగా చేయగలదు; -డ్రాఫ్ట్ PR ఆమోదించబడిన అభ్యర్థి కాదు. `hotfix` లేబుల్ సాక్ష్యాధార అవసరాన్ని మినహాయించదు. +docs-only లేదా catalog-only వర్గీకరణ కోడ్ లేన్ను వర్తించనిదిగా చేయగలదు; +డ్రాఫ్ట్ PR ఆమోదించబడిన అభ్యర్థి కాదు. `hotfix` లేబుల్ ఆధారాల అవసరాన్ని మినహాయించదు. -రెండు వర్క్ఫ్లోలు PRలు మరియు main/release బ్రాంచ్లకు పుష్లు, మాన్యువల్ డిస్పాచ్ మరియు -merge-group ఈవెంట్లను కవర్ చేస్తాయి. Push, dispatch మరియు merge-group పూర్తి ఎంపికను అమలు చేస్తాయి. Forkలు -మరియు merge groupలు, లేనిపక్షంలో self-hosted రన్నర్లను ఎంచుకునే జాబ్ల కోసం hosted రన్నర్లను ఉపయోగిస్తాయి; +రెండు వర్క్ఫ్లోలు PRలను, main/release బ్రాంచ్లకు పుష్లను, మాన్యువల్ డిస్పాచ్ను మరియు +merge-group ఈవెంట్లను కవర్ చేస్తాయి. పుష్, డిస్పాచ్ మరియు merge-group పూర్తి ఎంపికను అమలు చేస్తాయి. సాధారణంగా self-hosted +రన్నర్లను ఎంచుకునే జాబ్ల కోసం ఫోర్క్లు మరియు merge groupలు hosted రన్నర్లను ఉపయోగిస్తాయి; రోల్అవుట్కు ముందు తగిన hosted సామర్థ్యాన్ని ధృవీకరించాలి. ప్రతి JSON రసీదు చెక్అవుట్ చేసిన SHA, వర్క్ఫ్లో రన్ మరియు ప్రయత్నాన్ని గుర్తిస్తుంది. -చెక్అవుట్/event SHA సరిపోలకపోతే CLI తిరస్కరిస్తుంది. వర్క్ఫ్లో పరీక్షలు విధాన సభ్యత్వాన్ని -తీర్పు జాబ్ యొక్క `needs` జాబితాకు బంధిస్తాయి, అందువల్ల కొత్తగా జోడించిన లేదా తొలగించిన లేన్ నిశ్శబ్దంగా అదృశ్యం కాలేదు. +చెక్అవుట్/event SHA అసమతుల్యతను CLI తిరస్కరిస్తుంది. కొత్త లేదా తొలగించిన లేన్ నిశ్శబ్దంగా కనుమరుగవకుండా, +వర్క్ఫ్లో పరీక్షలు విధాన సభ్యత్వాన్ని తీర్పు జాబ్ యొక్క `needs` జాబితాకు అనుసంధానిస్తాయి. రసీదులు వాటి స్వంత వర్క్ఫ్లోను కవర్ చేస్తాయి; ప్రచురణ, డిప్లాయ్మెంట్ లేదా ఇప్పటికే ఉన్న -సలహాత్మక స్కానర్ అంతర్గతాలను కాదు. బ్రాంచ్ నియమాలలో రెండు చెక్ పేర్లను సక్రియం చేయడం -వేరొక పరిపాలనా మార్పు; ఈ జాబ్లను జోడించడం మాత్రమే బ్రాంచ్ను రక్షించదు. +సలహాపరమైన స్కానర్ అంతర్గత అంశాలను కాదు. బ్రాంచ్ నియమాలలో రెండు చెక్ పేర్లను సక్రియం చేయడం +ఒక ప్రత్యేక పరిపాలనా మార్పు; ఈ జాబ్లను జోడించడం మాత్రమే బ్రాంచ్ను రక్షించదు. ### స్టాటిక్ స్కాన్ ఇన్వెంటరీ వెర్షన్ చేయబడిన npm-alias ఇన్వెంటరీ మరియు స్టాటిక్-స్కాన్ సభ్యత్వం `config/quality/gate-manifest.json`లో ఉంటాయి. స్క్రిప్ట్ పేర్లు మరియు ఖచ్చితమైన కమాండ్లను -`package.json`తో పోల్చి ధృవీకరించడానికి `npm run check:gate-manifest` అమలు చేయండి; జోడింపులు, తొలగింపులు మరియు +`package.json`తో సరిపోల్చి ధృవీకరించడానికి `npm run check:gate-manifest`ను అమలు చేయండి; జోడింపులు, తొలగింపులు మరియు కమాండ్ వ్యత్యాసాలు స్థానిక హుక్ మరియు CIలోని మార్పు-వర్గీకరణ జాబ్లు రెండింటినీ విఫలం చేస్తాయి. -ఒక alias అనేది వర్క్ఫ్లో జాబ్, మ్యాట్రిక్స్ ఇన్స్టాన్స్ లేదా టెస్ట్ కేస్ కాదు: ఈ లెక్కలను -పరస్పరం మార్పిడి చేయదగినవిగా చూపకూడదు. +ఒక alias అనేది వర్క్ఫ్లో జాబ్, మ్యాట్రిక్స్ ఇన్స్టాన్స్ లేదా టెస్ట్ కేస్ కాదు: ఈ గణనలను +పరస్పరం మార్చుకోదగినవిగా చూపకూడదు. ఎంచుకున్న aliasలను అమలు చేయకుండా పరిశీలించడానికి `npm run quality:scan -- --list` లేదా `npm run quality:scan:fast -- --list` -ఉపయోగించండి. రన్నర్ -npm ఎంట్రీపాయింట్ను అమలు చేస్తుంది, కాబట్టి దాని రన్టైమ్ (కాన్ఫిగర్ చేసిన చోట Bunతో సహా) అలాగే ఉంటుంది. -మానిఫెస్ట్ ఆ ప్రొఫైల్ల వెలుపల ఉన్న aliasలను విడిగా అమలు చేయబడేవిగా నమోదు చేస్తుంది, మరియు -రీడ్-ఓన్లీ స్కాన్ ప్రొఫైల్లలో నిర్వహణ కమాండ్లు నిషేధించబడ్డాయి. - -ఈ ప్రొఫైల్లు స్టాటిక్ స్కాన్ను మాత్రమే కవర్ చేస్తాయి. అవి ఉత్పత్తి పరీక్షలు, -కవరేజ్, ప్యాకేజింగ్, బాహ్య తనిఖీలు లేదా అభ్యర్థి యొక్క పూర్తి విడుదల ఆమోదాన్ని ధృవీకరించవు. -వర్క్ఫ్లో అనుమతి లింక్ చేయబడిన `config/quality/admission-policy.json` మరియు -`scripts/quality/admission-verdict.mjs`ను ఉపయోగిస్తుంది. Release-observer ప్రొఫైల్లు వేరుగా ఉంటాయి; -వాటికి వర్తించే తనిఖీలు మరియు రసీదులను స్వతంత్రంగా పరిశీలించండి. క్రింద ఉన్న వచన -ఇన్వెంటరీ ఒక సూచన మాత్రమే; గేట్ నిజంగా అమలైందనడానికి అది రుజువు కాదు. +ఉపయోగించండి. రన్నర్ npm ఎంట్రీపాయింట్ను ఆహ్వానిస్తుంది, కాబట్టి దాని రన్టైమ్ +(కాన్ఫిగర్ చేసిన చోట Bunతో సహా) అలాగే నిల్వ ఉంటుంది. +మానిఫెస్ట్ ఈ ప్రొఫైల్ల వెలుపల ఉన్న aliasలను విడిగా ఆహ్వానించబడినవిగా నమోదు చేస్తుంది, మరియు +read-only స్కాన్ ప్రొఫైల్లలో నిర్వహణ కమాండ్లు నిషేధించబడ్డాయి. + +ఈ ప్రొఫైల్లు స్టాటిక్ స్కాన్ను మాత్రమే కవర్ చేస్తాయి. ఇవి ప్రోడక్ట్ పరీక్షలు, +కవరేజ్, ప్యాకేజింగ్, బాహ్య చెక్లు లేదా అభ్యర్థి యొక్క పూర్తి విడుదల ఆమోదాన్ని ధృవీకరించవు. +వర్క్ఫ్లో ప్రవేశం అనుసంధానించిన `config/quality/admission-policy.json` మరియు +`scripts/quality/admission-verdict.mjs`ను ఉపయోగిస్తుంది. Release-observer ప్రొఫైల్లు వేరుగానే ఉంటాయి; +వాటికి వర్తించే చెక్లు మరియు రసీదులను స్వతంత్రంగా పరిశీలించండి. దిగువనున్న గద్య +ఇన్వెంటరీ ఒక సూచన మాత్రమే, గేట్ వాస్తవంగా అమలైందనే రుజువు కాదు. స్క్రిప్ట్లు `scripts/check/` (విధాన గేట్లు) మరియు `scripts/quality/` (ర్యాచెట్ ఇంజిన్) కింద ఉంటాయి. CIకి ప్రామాణిక మూలం `.github/workflows/ci.yml`. -### విడుదల PR ఫాస్ట్-పాత్ (`quality.yml`) +### విడుదల PR వేగవంతమైన మార్గం (`quality.yml`) `.github/workflows/quality.yml` main/release PRలు, రక్షిత-బ్రాంచ్ -పుష్లు, dispatch మరియు merge groupలపై CIకి అనుబంధంగా పనిచేస్తుంది. PRలు పాత్-ఫిల్టర్ చేసిన వేగవంతమైన తనిఖీలను ఉపయోగిస్తాయి. శాశ్వతంగా -నిలిపివేయబడిన డూప్లికేట్ బిల్డ్ తొలగించబడింది; అసలు build/package/boot తనిఖీలు CIలోనే ఉంటాయి. - -| జాబ్ | పరిధి | నిరోధక స్థితి | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `Docs Gates (fast-path)` | Docs/code PRలు; API docs రిఫరెన్స్లు మరియు docs-all | అవును | -| `Fast Quality Gates` | Code PRలు; స్టాటిక్ తనిఖీలు, typecheck, dashboard typecheck, ప్రభావిత unit tests | అవును | -| `Forgotten sibling tests` | Code PRలు; మార్చిన మాడ్యూల్ల నుంచి స్టాటిక్ వినియోగదారులు మరియు సంభావ్య sibling tests వరకు ట్రేస్ చేయడం; barrel మరియు dynamic-import పాత్లు సూచనాత్మక డయాగ్నస్టిక్స్గా నివేదించబడతాయి, సూచించబడిన allowlist మినహాయింపులతో సహా | **సలహాత్మకం** | -| `Vitest (fast-path)` | Code PRలు; వేగవంతమైన vitest సూట్ | అవును | -| `Unit Tests fast-path` | Code PRలు; 4-shard unit సూట్ | అవును | -| `No new ESLint warnings` | Code PRలు; suppressions-aware lint గార్డ్ | అవును, forksతో సహా | -| `Merge integrity (changelog + generated skills)` | డ్రాఫ్ట్ కాని PRలు; changelog మరియు రూపొందించిన skill సమకాలీకరణ | అవును, forksతో సహా | - -#### మరచిపోయిన sibling tests నివేదిక - -`npm run check:forgotten-sibling-tests` test-impact మ్యాప్ వెనుక ఉన్న import resolverను తిరిగి ఉపయోగిస్తుంది. +పుష్లు, డిస్పాచ్ మరియు merge groupలపై CIకి పూరకంగా పనిచేస్తుంది. PRలు పాత్ ఆధారంగా ఫిల్టర్ చేసిన వేగవంతమైన చెక్లను ఉపయోగిస్తాయి. శాశ్వతంగా +నిలిపివేసిన నకిలీ బిల్డ్ తొలగించబడింది; అసలు build/package/boot చెక్లు CIలోనే ఉన్నాయి. + +| జాబ్ | పరిధి | నిరోధకం | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| `Docs Gates (fast-path)` | Docs/code PRలు; API docs refs మరియు docs-all | అవును | +| `Fast Quality Gates` | Code PRలు; స్టాటిక్ చెక్లు, typecheck, dashboard typecheck, ప్రభావిత unit tests | అవును | +| `Forgotten sibling tests` | Code PRలు; మార్చిన మాడ్యూల్ల నుంచి స్టాటిక్ వినియోగదారులు మరియు సంభావ్య sibling tests వరకు ట్రేస్ చేస్తుంది; barrel మరియు dynamic-import మార్గాలు సూచించబడిన allowlist మినహాయింపులతో సలహాపరమైన డయాగ్నస్టిక్స్గా నివేదించబడతాయి | **సలహాపరమైనది** | +| `Vitest (fast-path)` | Code PRలు; వేగవంతమైన vitest సూట్ | అవును | +| `Unit Tests fast-path` | Code PRలు; 4-shard unit సూట్ | అవును | +| `No new ESLint warnings` | Code PRలు; suppressions-aware lint గార్డ్ | అవును, ఫోర్క్లతో సహా | +| `Merge integrity (changelog + generated skills)` | డ్రాఫ్ట్ కాని PRలు; changelog మరియు రూపొందించిన skill సమకాలీకరణ | అవును, ఫోర్క్లతో సహా | + +#### మరిచిపోయిన sibling tests నివేదిక + +`npm run check:forgotten-sibling-tests` టెస్ట్-ఇంపాక్ట్ మ్యాప్ వెనుక ఉన్న import resolverను తిరిగి ఉపయోగిస్తుంది. మార్చబడిన ప్రతి production module కోసం, సంభావ్య -test pull-request diffలో లేనప్పుడు ఇది నిర్ణీతమైన -`changed module/symbol -> static consumer -> candidate sibling test` చైన్లను నివేదిస్తుంది. ఏదైనా నిరోధక రోల్అవుట్కు ముందు కాలిబ్రేషన్ కోసం Markdown సారాంశం మరియు JSON ఫలితం +టెస్ట్ pull-request diffలో లేనప్పుడు ఇది నిర్ధారిత +`changed module/symbol -> static consumer -> candidate sibling test` గొలుసులను నివేదిస్తుంది. ఏదైనా నిరోధక రోల్అవుట్కు ముందు కాలిబ్రేషన్ కోసం Markdown సారాంశం మరియు JSON ఫలితం `forgotten-sibling-tests` వర్క్ఫ్లో ఆర్టిఫాక్ట్గా నిల్వ చేయబడతాయి. -బ్యారెల్ రీ-ఎక్స్పోర్ట్లు మరియు డైనమిక్ ఇంపోర్ట్లు కేవలం రిజల్యూషన్ డయాగ్నస్టిక్స్ మాత్రమే; అవి ఎప్పుడూ -బ్లాకింగ్ ఫైండింగ్ను సృష్టించవు. సమీక్షించిన మినహాయింపులు -`config/quality/forgotten-sibling-allowlist.json`లో ఉంటాయి. ప్రతి ఎంట్రీ తప్పనిసరిగా కన్స్యూమర్ మరియు అభ్యర్థి -టెస్ట్ను పేర్కొనాలి, నిర్దిష్టమైన కారణాన్ని ఇవ్వాలి, అలాగే GitHub ఇష్యూ లేదా పుల్ రిక్వెస్ట్కు లింక్ చేయాలి. తప్పుగా రూపొందించిన ఎంట్రీలు -క్లోజ్డ్గా విఫలమవుతాయి. తొలగించిన అభ్యర్థి టెస్ట్ను లేదా `.skip`/`.todo`ను జోడించే డిఫ్ను మినహాయింపులు నిరోధించలేవు; -అసెర్షన్ బలహీనపరచడం మరియు ఇతర మాస్కింగ్ స్వతంత్రంగా బ్లాక్ చేసే -`check:test-masking` గేట్ పరిధిలోనే ఉంటాయి. - -### జాబ్: `lint` - -`main`కు చేసే ప్రతి PRపై రన్ అవుతుంది. విఫలమైతే మెర్జ్ను బ్లాక్ చేస్తుంది. - -| స్క్రిప్ట్ (`npm run ...`) | ధృవీకరించేది | బ్లాకింగ్ | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Node.js వెర్షన్ మద్దతు ఉన్న పరిధిలో ఉంది | అవును | -| `check:cycles` | సర్క్యులర్ ఇంపోర్ట్లు — అన్ని `src/` + `open-sse/` మాడ్యూల్లు | అవును | -| `check:route-validation:t06` | అన్ని రూట్లలో Zod స్కీమాలు ఉన్నాయి (Tier 6 విధానం) | అవును | -| `check:any-budget:t11` | `@ts-expect-error // any` సంఖ్య బడ్జెట్ను మించదు (Tier 11 catraca) | అవును | -| `check:provider-consistency` | `providers.ts` లోని ప్రతి providerకు `providerRegistry.ts` లో సరిపోలే entry ఉంది (మరియు allowlist పరిధిలో దీనికి విరుద్ధంగా కూడా) | అవును | -| `check:model-lifecycle` | చేతితో నిర్వహించే మూడు routing tableలు checked-in lifecycle snapshot (#11503)తో స్థిరంగా ఉంటాయి: `FITNESS_TABLE` (`taskFitness.ts`) అనేది `REGISTRY` route చేయగల retired idకు score ఇవ్వదు; ప్రతి `BUILT_IN_ALIASES` target `REGISTRY`లో ఉంటుంది మరియు retired-id snapshotలో ఉండదు; ఇప్పటికీ `REGISTRY`లో ఉన్న ప్రతి retired id forward చేయబడుతుంది లేదా `allowedRetiredInCatalog`లో జాబితా చేయబడుతుంది; అలాగే ఆ snapshotలో retiredగా కనిపించే ఏ source లేదా target కూడా `DEFAULT_DEGRADATION_MAP`లో ఉండదు. ఒక model ప్రస్తుతం live upstream ద్వారా అందించబడుతోందని ఇది నిరూపించదు. Offline — చేతితో `npm run quality:refresh-model-lifecycle` (network; CIలో అనుసంధానించబడలేదు) ద్వారా refresh చేయబడిన `config/quality/model-lifecycle.json`తో పోలుస్తుంది. `allowedRetiredInCatalog` అనేది burn-down ratchet: tracking issue ఉన్నప్పుడు మాత్రమే entryని జోడించండి. | అవును | -| `check:fetch-targets` | client-side `src/`లోని ప్రతి `fetch("/api/...")` నిజమైన `route.ts`కు resolve అవుతుంది | అవును | -| `check:deps` | repoలోని ప్రతి `package.json` అంతటా ఉన్న `npm install` చేయగల అన్ని deps `dependency-allowlist.json`లో ఉంటాయి; కొత్తగా pin చేయని లేదా slopsquat చేసిన packageలు flag చేయబడతాయి | అవును | -| `audit:deps` | `npm audit` (root + electron) — high/critical advisoryలు లేవు (osv `check:vuln-ratchet`తో overlap అవుతుంది; Rationalization Backlog చూడండి) | అవును | -| `check:lockfile` | `package-lock.json` సమగ్రత — https registry, integrity hashలు, host overrideలు లేవు | అవును | -| `check:licenses` | ప్రొడక్షన్ డిపెండెన్సీల కోసం SPDX లైసెన్స్ అనుమతి జాబితా | అవును | -| `check:tracked-artifacts` | బిల్డ్ ఆర్టిఫాక్ట్లు / కమిట్ చేసిన `node_modules` సింబాలిక్ లింక్లు ఉండకూడదు (husky pre-commitలో కూడా అమలవుతుంది; pre-push ఉద్దేశపూర్వకంగా తేలికగా ఉంటుంది — #6716) | అవును | -| `check:ai-attribution` | PR కమిట్లు, శీర్షిక లేదా బాడీలో AI/bot `Co-Authored-By` ట్రైలర్ లేదా AI-జనరేషన్ ఫుటర్ ఉండకూడదు — కఠిన నియమం #16 (`quality.yml`లోని PR→`release/**` ఫాస్ట్-గేట్స్ లూప్లో — ఈవెంట్ పేలోడ్ను చదువుతుంది, PRలు కానప్పుడు ఏమీ చేయదు — మరియు PR→`main` కోసం `ci.yml` లింట్లోని PR-మాత్రమే దశ; అలాగే husky `commit-msg` హుక్; మానవ సహ-రచయితలకు అనుమతి ఉంది; #14436) | -| `check:vitest-exclusions` | ప్రతి Vitest మినహాయింపులో ఒక ట్రాకింగ్ ఇష్యూ పేర్కొనబడి, అది `config/quality/vitest-exclusions.json`లో కనిపించాలి (#13204) | అవును | -| `check:file-size` | ఏ సోర్స్ ఫైల్ కూడా దాని ఎక్స్టెన్షన్కు నిర్దేశించిన గరిష్ఠ పరిమితిని మించకూడదు (రాచెట్: `frozen` జాబితాలో స్థిరపరచిన పెద్ద ఫైళ్లు) | అవును | -| `check:error-helper` | ఎగ్జిక్యూటర్లు/హ్యాండ్లర్లలోని ఎర్రర్ రెస్పాన్స్లు `buildErrorBody()` / `sanitizeErrorMessage()`ను ఉపయోగించాలి (కఠిన నియమం #12) | అవును | -| `check:migration-numbering` | Migration SQL ఫైళ్లు ఖాళీలు లేదా నకళ్లు లేకుండా వరుస సంఖ్యలతో ఉంటాయి | అవును | -| `check:public-creds` | `publicCreds.ts` వెలుపల లిటరల్ OAuth `client_id`/`client_secret` లేదా Firebase Web కీలు ఉండవు (కఠిన నియమం #11) | అవును | -| `check:db-rules` | `src/lib/db/` మాడ్యూల్స్ వెలుపల ముడి SQL ఉండదు; `localDb.ts` నుండి barrel-imports ఉండవు (కఠిన నియమాలు #2/#5) | అవును | -| `check:known-symbols` | వాటి dispatch పట్టికలలో నమోదు చేసిన provider executors, routing strategies, మరియు translators డిస్క్లోని ఫైళ్లతో సరిపోలుతాయి — అనాథ లేదా ప్రకటించని symbols ఉండవు | అవును | -| `check:route-guard-membership` | child processను ప్రారంభించే ప్రతి route, `isLocalOnlyPath()` ద్వారా వర్గీకరించబడుతుంది (కఠిన నియమాలు #15/#17) | అవును | -| `check:test-discovery` | repoలోని ప్రతి `*.test.ts` / `*.spec.ts` ఫైల్ కనీసం ఒక test runner ద్వారా సేకరించబడుతుంది (ratchet: `test-discovery-baseline.json`లోని orphan list కేవలం తగ్గగలదు) | అవును | -| `check:agent-skills-sync` | రూపొందించిన agent-skills ఆర్టిఫాక్ట్లు వాటి మూల క్యాటలాగ్తో సరిపోలుతాయి (ఎటువంటి వ్యత్యాసం లేదు) | -| `check:provider-asset-provenance` | ప్రొవైడర్ లోగోలు/అసెట్లకు నమోదు చేసిన మూలాధార ఎంట్రీ ఉంటుంది | -| `lint:json` | JSON కాన్ఫిగ్ ఫైల్లు పార్స్ అవుతాయి మరియు repo lint నియమాలను అనుసరిస్తాయి | -| `typecheck:core` | లోపాలు లేకుండా TypeScript కంపైలేషన్ (సూచనాత్మక హెచ్చరికలు మాత్రమే) | అవును | -| `typecheck:noimplicit:core` | కఠినమైన `noImplicitAny` — భవిష్యత్ను దృష్టిలో ఉంచుకున్నది; ముందే ఉన్న అనేక కాల్ సైట్లకు ఇంకా అనోటేషన్లు అవసరం | **సూచనాత్మకం** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**`కు పరిమితమైన `tsc` (#7033) — `typecheck:core` యొక్క జాగ్రత్తగా ఎంపిక చేసిన 27-ఫైల్ అనుమతి జాబితాలో ఎలాంటి dashboard TSX లేదు, అలాగే `next build` కూడా దానిని ఎప్పుడూ టైప్-చెక్ చేయదు (`next.config.mjs`లో `ignoreBuildErrors: true` సెట్ చేయబడింది), కాబట్టి అక్కడి అనాథ-ఐడెంటిఫైయర్ రిగ్రెషన్లు (#6625/#6909) CIకి కనిపించలేదు. స్థిరీకరించిన ప్రతి-ఫైల్/ప్రతి-TS-కోడ్ కౌంట్ బేస్లైన్తో (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` మాదిరిగానే అదే stale-enforcement నమూనా) తేడాలను పోలుస్తుంది — బేస్లైన్ కౌంట్కు మించిన కొత్త లోపాలు మాత్రమే గేట్ను విఫలం చేస్తాయి; ముందే ఉన్న లోపం పరిష్కరించినప్పుడు `--update`తో బేస్లైన్ను తగ్గించండి. | అవును | +Barrel re-exports మరియు dynamic imports అనేవి resolution diagnostics మాత్రమే; అవి ఎప్పటికీ +నిరోధక findingను సృష్టించవు. సమీక్షించిన మినహాయింపులు +`config/quality/forgotten-sibling-allowlist.json`లో ఉంటాయి. ప్రతి entry తప్పనిసరిగా consumer మరియు candidate +testను పేర్కొనాలి, నిర్దిష్ట కారణాన్ని ఇవ్వాలి, అలాగే GitHub issue లేదా pull requestకు link చేయాలి. సరిగ్గా రూపొందించని entries +closedగా విఫలమవుతాయి. తొలగించిన candidate testను లేదా `.skip`/`.todo`ను జోడించే diffను మినహాయింపులు అణచివేయలేవు; +assertion weakening మరియు ఇతర masking అంశాలు స్వతంత్రంగా నిరోధించే +`check:test-masking` gate పరిధిలోనే ఉంటాయి. -### జాబ్: `quality-gate` - -`test-coverage` తర్వాత నడుస్తుంది. విఫలమైతే విలీనాన్ని నిరోధిస్తుంది. - -| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధక స్థితి | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `quality:collect` | `quality-metrics.json`ను ఉత్పత్తి చేస్తుంది (ESLint హెచ్చరికల సంఖ్య, విలీనం చేసిన shard నివేదిక నుండి coverage) | అవును (ratchetకు upstream) | -| `quality:ratchet` | `quality-baseline.json`లోని ప్రతి metric దిగజారలేదు (ESLint హెచ్చరికలు ≤ baseline; coverage ≥ baseline) | అవును | -| `check:duplication` | కోడ్ నకిలీకరణ (jscpd@4) `quality-baseline.json`లోని baselineను మించదు | అవును | -| `check:complexity` | ఫైల్-స్థాయి cyclomatic complexity పరిమితిని మించదు (core ESLint `complexity` + `max-lines-per-function`) | అవును | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — ప్రత్యేక ESLint pass; CI రెండింటినీ ఒకే `check:complexity-ratchets` దశగా విలీనం చేసి అమలు చేస్తుంది | అవును | -| `check:dead-code` | ఉపయోగించని exports / files ratchet (knip) baselineతో పోలిస్తే దిగజారదు | అవును | -| `check:compression-budget` | Compression benchmark budget — ఒక్కో engineకు token-savings కనిష్ఠ పరిమితులు దిగజారకూడదు | అవును | -| `check:type-coverage` | Percent-typed ratchet (`type-coverage`) దిగజారదు; ఇది ఎక్కువగా `typecheck:noimplicit:core`ను సమగ్రంగా కవర్ చేస్తుంది | అవును | -| `check:codeql-ratchet` | తెరిచి ఉన్న CodeQL alerts సంఖ్య పెరగదు (`gh api` ద్వారా చదువుతుంది; token లేకపోతే సురక్షితంగా skip చేస్తుంది) — refresh cadence మరియు manual trigger కోసం: దిగువనున్న "CodeQL ratchet" చూడండి | అవును | - -### Job: `quality-extended` - -మొత్తం job సలహాపూర్వకమైనది (`continue-on-error: true`). npm-ఆధారిత ratchets -వాస్తవంగా అమలవుతాయి; బాహ్య scanners `gh release download` ద్వారా install అవుతాయి మరియు binary -ఇంకా అందుబాటులో లేకపోతే స్వయంగా skip అవుతాయి (exit 0). - -| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధక స్థితి | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| `check:circular-deps` | Circular dependencies లేవు (dpdm) | **సలహాపూర్వకం** | -| `check:bundle-size` | Bundle పరిమాణం నిర్దేశిత పరిమితిని మించదు | **సలహాపూర్వకం** | -| `check:secrets` | Secret scanning (gitleaks) — binary లేకపోతే skip అవుతుంది | **సలహాపూర్వకం** | -| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) దిగజారవు — binary లేకపోతే skip అవుతుంది | **సలహాపూర్వకం** | -| `check:workflows` | Workflow lint (actionlint + zizmor); scanners లేకపోయినా/పనిచేయకపోయినా, reports చెల్లనివైనా లేదా ratchet baseline లేకపోయినా INCOMPLETEగా విఫలమవుతుంది. చెల్లుబాటు అయ్యే findings ఎంచుకున్న strict/advisory/ratchet policyని అనుసరిస్తాయి | అమలు తప్పనిసరి; CIలో zizmor ratchet నిరోధకమైనది | -| `check:openapi-breaking` | base branchతో పోలిస్తే public API contract (`openapi.yaml`)లో breaking changes (oasdiff) — `openapiBreaking=N`ను ఉత్పత్తి చేస్తుంది; oasdiff లేకపోతే లేదా base specను resolve చేయలేకపోతే skip అవుతుంది | **సలహాపూర్వకం** | - -### Job: `docs-sync-strict` +### Job: `lint` `main`కు వచ్చే ప్రతి PRపై అమలవుతుంది. విఫలమైతే mergeను నిరోధిస్తుంది. -| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధించేది | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | -| `check:docs-all` | దిగువనున్న 6 ఉప-గేట్లను వరుసగా అమలు చేసే మెటా-గేట్ | అవును | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt సంస్కరణ స్థిరత్వం | అవును | -| ↳ `check:docs-counts` | గద్యంలో ఉన్న లెక్కలు (ప్రొవైడర్ల సంఖ్య, మైగ్రేషన్ల సంఖ్య మొదలైనవి) వాస్తవ లెక్కల రాచెట్ పరిధిలో ఉంటాయి | అవును | -| ↳ `check:env-doc-sync` | `.env.example`లోని ప్రతి env var డాక్యుమెంటేషన్ పట్టికలో నమోదు చేయబడింది, అలాగే దానికి విరుద్ధంగానూ | అవును | -| ↳ `check:deprecated-versions` | డాక్యుమెంటేషన్లో కాలం చెల్లిన సంస్కరణ స్ట్రింగ్లు లేవు | అవును | -| ↳ `check:doc-links` | డాక్యుమెంటేషన్లోని అంతర్గత markdown లింక్లు వాస్తవ ఫైల్లకు పరిష్కరించబడతాయి (`[text]`/`(path)` రూపం) | అవును | -| ↳ `check:fabricated-docs` | డాక్యుమెంటేషన్లో పేర్కొన్న రూట్లు, env varలు, CLI కమాండ్లు, హుక్ పేర్లు మరియు ఫైల్ పాత్లు కోడ్బేస్లో ఉన్నాయి. `--strict` ద్వారా కఠిన గేట్; ఫ్లాగ్ లేకుండా సాఫ్ట్-ఫెయిల్. | అవును (CIలో `--strict` ద్వారా) | -| `check:cli-i18n` | CLI కమాండ్ స్ట్రింగ్లు అన్ని i18n లోకేల్ ఫైల్లలో ఉన్నాయి | అవును | -| `check:openapi-coverage` | OpenAPI స్పెక్ వాస్తవ రూట్లలో కనీసం రాచెట్ చేయబడిన కనిష్ఠ పరిమితిని కవర్ చేస్తుంది | అవును | -| `check:openapi-security-tiers` | `openapi.yaml`లోని భద్రతా స్థాయి అనోటేషన్లు `routeGuard.ts` వర్గీకరణలకు అనుగుణంగా ఉన్నాయి | **సలహాత్మకం** | -| `check:openapi-routes` | `openapi.yaml`లోని ప్రతి పాత్ వాస్తవ `route.ts`కు పరిష్కరించబడుతుంది (కల్పిత సమాచారం నిరోధం) | అవును | -| `check:docs-symbols` | `docs/**/*.md`లోని ప్రతి `/api/...` సూచన వాస్తవ `route.ts`కు పరిష్కరించబడుతుంది (కల్పిత సమాచారం నిరోధం) | అవును | -| `i18n translation drift` | i18n లోకేల్ ఫైల్లలో అనువదించని కీలు — హెచ్చరిక మాత్రమే | **సలహాత్మకం** | +| Script (`npm run ...`) | ధృవీకరించేది | నిరోధకమా | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:node-runtime` | Node.js version మద్దతు ఉన్న rangeలో ఉందో లేదో | అవును | +| `check:cycles` | `src/` + `open-sse/` అంతటా circular imports (AST-ఆధారితం, tsconfig `paths` resolve చేయబడతాయి). Bare = advisory, cyclesను జాబితా చేస్తుంది. `check:cycles:ratchet` (CI అమలు చేసేది) count, `quality-baseline.json`లోని `metrics.cycles` ceilingను మించినప్పుడు నిరోధిస్తుంది — ప్రస్తుతం 14, `direction: down`, కాబట్టి అది తగ్గడం మాత్రమే సాధ్యం (#15159 G-01/G-02) | అవును (ratchet) | +| `check:route-validation:t06` | అన్ని routesలో Zod schemas ఉన్నాయో లేదో (Tier 6 policy) | అవును | +| `check:any-budget:t11` | `@ts-expect-error // any` count budgetను మించదని (Tier 11 catraca) | అవును | +| `check:provider-consistency` | `providers.ts`లోని ప్రతి providerకు `providerRegistry.ts`లో సరిపోలే entry ఉంటుంది (మరియు దీనికి విరుద్ధంగా కూడా, allowlist పరిధిలో) | అవును | +| `check:model-lifecycle` | చేతితో నిర్వహించే మూడు routing tableలు checked-in lifecycle snapshot (#11503)తో స్థిరంగా ఉంటాయి: `FITNESS_TABLE` (`taskFitness.ts`)లో `REGISTRY` route చేయగల retired idకు score ఉండదు; ప్రతి `BUILT_IN_ALIASES` target `REGISTRY`లో ఉంటుంది మరియు retired-id snapshotలో ఉండదు; `REGISTRY`లో ఇప్పటికీ ఉన్న ప్రతి retired id forward చేయబడుతుంది లేదా `allowedRetiredInCatalog`లో జాబితా చేయబడుతుంది; అలాగే ఏ `DEFAULT_DEGRADATION_MAP` source లేదా target కూడా ఆ snapshotలో retiredగా కనిపించదు. ఒక model ప్రస్తుతం live upstream ద్వారా అందించబడుతోందని ఇది నిరూపించదు. Offline — `config/quality/model-lifecycle.json`తో పోలుస్తుంది; ఇది `npm run quality:refresh-model-lifecycle`తో చేతితో refresh చేయబడుతుంది (network; CIలో అనుసంధానించబడలేదు). `allowedRetiredInCatalog` ఒక burn-down ratchet: tracking issue ఉన్నప్పుడు మాత్రమే entryని జోడించండి. | అవును | +| `check:fetch-targets` | client-side `src/`లోని ప్రతి `fetch("/api/...")` నిజమైన `route.ts`కు resolve అవుతుంది | అవును | +| `check:deps` | repoలోని ప్రతి `package.json` అంతటా ఉన్న, `npm install` చేయగల అన్ని deps `dependency-allowlist.json`లో ఉంటాయి; కొత్త unpinned లేదా slopsquatted packageలు flag చేయబడతాయి | అవును | +| `audit:deps` | `npm audit` (root + electron) — high/critical advisoryలు లేవు (osv `check:vuln-ratchet`తో overlap అవుతుంది; Rationalization Backlog చూడండి) | అవును | +| `check:lockfile` | `package-lock.json` integrity — https registry, integrity hashలు, host overrideలు లేవు | అవును | +| `check:licenses` | ప్రొడక్షన్ డిపెండెన్సీల కోసం SPDX లైసెన్స్ అనుమతి జాబితా | అవును | +| `check:tracked-artifacts` | బిల్డ్ ఆర్టిఫాక్ట్లు / కమిట్ చేసిన `node_modules` సిమ్లింక్లు లేవు (husky pre-commitలో కూడా అమలవుతుంది; pre-push ఉద్దేశపూర్వకంగా తేలికగా ఉంటుంది — #6716) | అవును | +| `check:ai-attribution` | PR కమిట్లు, శీర్షిక లేదా బాడీలో AI/bot `Co-Authored-By` ట్రైలర్ లేదా AI-జనరేషన్ ఫుటర్ ఉండకూడదు — కఠిన నియమం #16 (`quality.yml`లోని PR→`release/**` కోసం fast-gates లూప్లో — ఈవెంట్ పేలోడ్ను చదువుతుంది, PRలు కానప్పుడు ఏమీ చేయదు — మరియు PR→`main` కోసం `ci.yml` lintలో PRకు మాత్రమే వర్తించే దశ; అలాగే husky `commit-msg` హుక్; మానవ సహ-రచయితలకు అనుమతి ఉంది; #14436) | +| `check:vitest-exclusions` | ప్రతి Vitest మినహాయింపు ఒక ట్రాకింగ్ ఇష్యూను పేర్కొని, `config/quality/vitest-exclusions.json`లో కనిపించాలి (#13204) | అవును | +| `check:file-size` | ఏ సోర్స్ ఫైల్ కూడా ప్రతి ఎక్స్టెన్షన్కు నిర్ణయించిన గరిష్ఠ పరిమితిని మించకూడదు (రాచెట్: `frozen` జాబితాలో స్థిరీకరించిన పెద్ద ఫైళ్లు) | అవును | +| `check:error-helper` | ఎగ్జిక్యూటర్లు/హ్యాండ్లర్లలోని ఎర్రర్ రెస్పాన్స్లు `buildErrorBody()` / `sanitizeErrorMessage()`ను ఉపయోగించాలి (కఠిన నియమం #12) | అవును | +| `check:migration-numbering` | Migration SQL ఫైళ్లు ఖాళీలు లేదా నకళ్లు లేకుండా వరుసగా సంఖ్యీకరించబడ్డాయి | అవును | +| `check:public-creds` | `publicCreds.ts` వెలుపల లిటరల్ OAuth `client_id`/`client_secret` లేదా Firebase Web కీలు లేవు (కఠిన నియమం #11) | అవును | +| `check:db-rules` | `src/lib/db/` మాడ్యూళ్ల వెలుపల రా SQL లేదు; `localDb.ts` నుండి బ్యారెల్ ఇంపోర్ట్లు లేవు (కఠిన నియమాలు #2/#5) | అవును | +| `check:known-symbols` | వాటి డిస్పాచ్ పట్టికల్లో నమోదు చేయబడిన ప్రొవైడర్ ఎగ్జిక్యూటర్లు, రూటింగ్ వ్యూహాలు మరియు ట్రాన్స్లేటర్లు డిస్క్లోని ఫైళ్లతో సరిపోలుతాయి — అనాథ లేదా ప్రకటించని సింబల్లు లేవు | అవును | +| `check:route-guard-membership` | చైల్డ్ ప్రాసెస్ను ప్రారంభించే ప్రతి రూట్ `isLocalOnlyPath()` ద్వారా వర్గీకరించబడింది (కఠిన నియమాలు #15/#17) | అవును | +| `check:test-discovery` | రెపోలోని ప్రతి `*.test.ts` / `*.spec.ts` ఫైల్ కనీసం ఒక టెస్ట్ రన్నర్ ద్వారా సేకరించబడుతుంది (రాచెట్: `test-discovery-baseline.json`లోని అనాథల జాబితా కేవలం తగ్గగలదు) | అవును | +| `check:agent-skills-sync` | రూపొందించబడిన agent-skills ఆర్టిఫాక్ట్లు వాటి మూల కేటలాగ్తో సరిపోలుతాయి (వ్యతాసం లేదు) | +| `check:provider-asset-provenance` | ప్రొవైడర్ లోగోలు/ఆస్తులకు నమోదు చేసిన మూలాధార ఎంట్రీ ఉంటుంది | +| `lint:json` | JSON కాన్ఫిగరేషన్ ఫైళ్లు పార్స్ అవుతాయి మరియు repo lint నియమాలను పాటిస్తాయి | +| `typecheck:core` | లోపాలు లేకుండా TypeScript కంపైలేషన్ (సలహా హెచ్చరికలు మాత్రమే) | అవును | +| `typecheck:noimplicit:core` | కఠినమైన `noImplicitAny` — భవిష్యత్-ఆధారితం; ముందే ఉన్న అనేక కాల్ సైట్లకు ఇప్పటికీ అనోటేషన్లు అవసరం | **సలహాపూర్వకం** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**`కు పరిమితమైన `tsc` (#7033) — `typecheck:core`లోని జాగ్రత్తగా ఎంపిక చేసిన 27-ఫైల్ allowlistలో ఏ dashboard TSX కూడా లేదు, అలాగే `next build` కూడా దానిని ఎప్పుడూ టైప్-చెక్ చేయదు (`next.config.mjs`లో `ignoreBuildErrors: true` సెట్ చేయబడింది), కాబట్టి అక్కడి అనాథ-ఐడెంటిఫైయర్ రిగ్రెషన్లు (#6625/#6909) CIకి కనిపించలేదు. స్థిరపరచిన ప్రతి-ఫైల్/ప్రతి-TS-కోడ్ గణన బేస్లైన్తో (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` మాదిరిగానే అదే stale-enforcement నమూనా) తేడాలను పోలుస్తుంది — బేస్లైన్లో ఉన్న గణనకు మించిన కొత్త లోపాలు మాత్రమే గేట్ను విఫలం చేస్తాయి; ముందే ఉన్న లోపం పరిష్కరించబడినప్పుడు `--update`తో పరిమితిని తగ్గించండి. | అవును | + +### జాబ్: `quality-gate` + +`test-coverage` తర్వాత రన్ అవుతుంది. విఫలమైతే విలీనాన్ని నిరోధిస్తుంది. + +| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధించేది | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `quality:collect` | `quality-metrics.json`ను ఉత్పత్తి చేస్తుంది (ESLint హెచ్చరికల సంఖ్య, విలీనం చేసిన షార్డ్ నివేదిక నుండి కవరేజ్) | అవును (రాచెట్కు అప్స్ట్రీమ్) | +| `quality:ratchet` | `quality-baseline.json`లోని ప్రతి మెట్రిక్ తిరోగమించలేదు (ESLint హెచ్చరికలు ≤ బేస్లైన్; కవరేజ్ ≥ బేస్లైన్) | అవును | +| `check:duplication` | కోడ్ నకిలీకరణ (jscpd@4) `quality-baseline.json`లోని బేస్లైన్ను మించదు | అవును | +| `check:complexity` | ఫైల్-స్థాయి సైక్లోమాటిక్ సంక్లిష్టత పరిమితిని మించదు (కోర్ ESLint `complexity` + `max-lines-per-function`) | అవును | +| `check:cognitive-complexity` | కాగ్నిటివ్ సంక్లిష్టత రాచెట్ (`eslint-plugin-sonarjs`) — ప్రత్యేక ESLint పాస్; CI రెండింటినీ కలిపి ఒకే `check:complexity-ratchets` దశగా అమలు చేస్తుంది | అవును | +| `check:dead-code` | ఉపయోగించని ఎక్స్పోర్ట్లు / ఫైళ్ల రాచెట్ (knip) బేస్లైన్తో పోలిస్తే తిరోగమించదు | అవును | +| `check:compression-budget` | కంప్రెషన్ బెంచ్మార్క్ బడ్జెట్ — ఒక్కో ఇంజిన్కు సంబంధించిన టోకెన్-పొదుపు కనిష్ఠ పరిమితులు తిరోగమించకూడదు | అవును | +| `check:type-coverage` | టైప్ చేయబడిన శాతం రాచెట్ (`type-coverage`) తిరోగమించదు; ఇది ఎక్కువగా `typecheck:noimplicit:core`ను కలుపుకుంటుంది | అవును | +| `check:codeql-ratchet` | తెరిచి ఉన్న CodeQL అలర్ట్ల సంఖ్య తిరోగమించదు (`gh api` ద్వారా చదువుతుంది; టోకెన్ లేకపోతే సురక్షితంగా దాటవేస్తుంది) — రిఫ్రెష్ అవధి మరియు మాన్యువల్ ట్రిగ్గర్ కోసం: దిగువ "CodeQL రాచెట్" చూడండి | అవును | + +### జాబ్: `quality-extended` + +మొత్తం జాబ్ సలహాపూర్వకమైనది (`continue-on-error: true`). npm-ఆధారిత రాచెట్లు +వాస్తవంగా అమలవుతాయి; బాహ్య స్కానర్లు `gh release download` ద్వారా ఇన్స్టాల్ అవుతాయి మరియు +బైనరీ ఇంకా లేకుంటే స్వయంగా దాటవేస్తాయి (exit 0). + +| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధించేది | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | +| `check:circular-deps` | సర్క్యులర్ డిపెండెన్సీలు లేవు (dpdm) | **సలహాపూర్వకం** | +| `check:bundle-size` | బండిల్ పరిమాణం గరిష్ఠ పరిమితిని మించదు | **సలహాపూర్వకం** | +| `check:secrets` | సీక్రెట్ స్కానింగ్ (gitleaks) — బైనరీ లేకుంటే దాటవేస్తుంది | **సలహాపూర్వకం** | +| `check:vuln-ratchet` | డిపెండెన్సీ దుర్బలతలు (osv-scanner) తిరోగమించవు — బైనరీ లేకుంటే దాటవేస్తుంది | **సలహాపూర్వకం** | +| `check:workflows` | వర్క్ఫ్లో లింట్ (actionlint + zizmor); స్కానర్లు లేకపోయినా/పాడైనా, నివేదికలు చెల్లనివైనా లేదా రాచెట్ బేస్లైన్ లేకపోయినా INCOMPLETEగా విఫలమవుతుంది. చెల్లుబాటు అయ్యే ఫైండింగ్లు ఎంచుకున్న కఠిన/సలహాపూర్వక/రాచెట్ విధానాన్ని అనుసరిస్తాయి | అమలు తప్పనిసరి; CIలో zizmor రాచెట్ నిరోధిస్తుంది | +| `check:openapi-breaking` | బేస్ బ్రాంచ్తో పోలిస్తే పబ్లిక్ API ఒప్పందానికి (`openapi.yaml`) బ్రేకింగ్ మార్పులు (oasdiff) — `openapiBreaking=N`ను ఉత్పత్తి చేస్తుంది; oasdiff లేకుంటే లేదా బేస్ స్పెక్ను పరిష్కరించలేకపోతే దాటవేస్తుంది | **సలహాపూర్వకం** | + +### జాబ్: `docs-sync-strict` + +`main`కు వచ్చే ప్రతి PRపై అమలవుతుంది. వైఫల్యం సంభవిస్తే విలీనాన్ని నిరోధిస్తుంది. + +| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధకమా | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `check:docs-all` | దిగువనున్న 6 ఉప-గేట్లను వరుసగా అమలు చేసే మెటా-గేట్ | అవును | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt సంస్కరణ అనుగుణ్యత | అవును | +| ↳ `check:docs-counts` | గద్యంలోని సంఖ్యలు (ప్రొవైడర్ల సంఖ్య, మైగ్రేషన్ల సంఖ్య మొదలైనవి) వాస్తవ సంఖ్యల రాచెట్ పరిధిలో ఉన్నాయి | అవును | +| ↳ `check:env-doc-sync` | `.env.example`లోని ప్రతి env var docs పట్టికలో డాక్యుమెంట్ చేయబడింది, అలాగే దానికి విరుద్ధంగా కూడా | అవును | +| ↳ `check:deprecated-versions` | docsలో విరమించబడిన సంస్కరణ స్ట్రింగ్లు లేవు | అవును | +| ↳ `check:doc-links` | docsలోని అంతర్గత markdown లింక్లు వాస్తవ ఫైల్లకు పరిష్కరించబడతాయి (`[text]`/`(path)` రూపం) | అవును | +| ↳ `check:fabricated-docs` | docsలో పేర్కొన్న రూట్లు, env vars, CLI కమాండ్లు, hook పేర్లు, ఫైల్ పాత్లు codebaseలో ఉన్నాయి. `--strict` ద్వారా కఠిన గేట్; ఫ్లాగ్ లేకుండా సాఫ్ట్-ఫెయిల్. | అవును (CIలో `--strict` ద్వారా) | +| `check:cli-i18n` | CLI కమాండ్ స్ట్రింగ్లు అన్ని i18n locale ఫైల్లలో ఉన్నాయి | అవును | +| `check:openapi-coverage` | OpenAPI స్పెక్ వాస్తవ రూట్లలో కనీసం రాచెట్ చేయబడిన కనిష్ఠ స్థాయిని కవర్ చేస్తుంది | అవును | +| `check:openapi-security-tiers` | `openapi.yaml`లోని భద్రతా స్థాయి annotationలు `routeGuard.ts` వర్గీకరణలతో అనుగుణంగా ఉన్నాయి | **సలహాత్మకం** | +| `check:openapi-routes` | `openapi.yaml`లోని ప్రతి పాత్ వాస్తవ `route.ts`కు పరిష్కరించబడుతుంది (భ్రమాత్మక సమాచార నిరోధం) | అవును | +| `check:docs-symbols` | `docs/**/*.md`లోని ప్రతి `/api/...` సూచన వాస్తవ `route.ts`కు పరిష్కరించబడుతుంది (భ్రమాత్మక సమాచార నిరోధం) | అవును | +| `i18n translation drift` | i18n locale ఫైల్లలో అనువదించని keyలు — హెచ్చరిక మాత్రమే | **సలహాత్మకం** | ### జాబ్: `i18n-ui-coverage` -| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధించేది | -| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `check-ui-keys-coverage` (ఇన్లైన్) | UI i18n కీ కవరేజ్ ≥ 65% | అవును | -| `check-ui-value-drift` (ఇన్లైన్) | తిరిగి వ్రాయబడిన ఆంగ్ల **విలువ** పాత అనువాదం ఏదీ మిగలకుండా చూస్తుంది | అవును | -| `check-new-key-coverage` (ఇన్లైన్) | ఒక **కొత్త** ఆంగ్ల కీ ప్రతి లోకేల్లో అనువదించబడుతుంది — `__MISSING__:` మార్కర్ తిరస్కరించబడుతుంది | అవును | -| `check-translation-ratio` | ప్రతి లోకేల్కు వాస్తవ-అనువాద నిష్పత్తి (అనుమతి జాబితా వెలుపల ఆంగ్లంతో సమానమైన / ప్లేస్హోల్డర్ / తప్పిపోయిన లీవ్లు) `config/quality/i18n-translation-baseline.json` + సడలింపును మించకూడదు | **సలహాత్మకం** | +| స్క్రిప్ట్ | ధృవీకరించేది | నిరోధకమా | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `check-ui-keys-coverage` (inline) | UI i18n key కవరేజ్ ≥ 65% | అవును | +| `check-ui-value-drift` (inline) | తిరిగి రాసిన ఆంగ్ల **విలువ** పాత అనువాదాన్ని ఏదీ మిగలనివ్వదు | అవును | +| `check-new-key-coverage` (inline) | ఒక **కొత్త** ఆంగ్ల key ప్రతి localeలో అనువదించబడుతుంది — `__MISSING__:` మార్కర్ తిరస్కరించబడుతుంది | అవును | +| `check-translation-ratio` | ప్రతి localeకు వాస్తవ-అనువాద నిష్పత్తి (allowlist వెలుపల ఆంగ్లంతో సమానమైన / placeholder / లేని leafలు) `config/quality/i18n-translation-baseline.json` + slackను మించకూడదు | **సలహాత్మకం** | -`fetch-depth: 0` అవసరం — విలువ-డ్రిఫ్ట్ గేట్ `en.json`ను మెర్జ్ బేస్తో పోల్చి తేడాలను గుర్తిస్తుంది. +`fetch-depth: 0` అవసరం — value-drift గేట్ merge baseతో `en.json`ను diff చేస్తుంది. #### `check-ui-value-drift` — పాత-అనువాద గేట్ -ఇతర గేట్లు నిర్మాణాత్మకంగా గుర్తించలేని ఒక i18n రిగ్రెషన్ను ఇది పట్టుకుంటుంది: ఒక ఆంగ్ల విలువ -తిరిగి వ్రాయబడినా, _మునుపటి_ ఆంగ్లం ఆధారంగా రూపొందించిన అనువాదాలు అలాగే మిగిలిపోతాయి, అందువల్ల -ఆంగ్లేతర వినియోగదారులు ధీమాగా వ్రాయబడిన, ఇప్పుడు తప్పుగా ఉన్న ప్రతిని చదువుతూనే ఉంటారు. +ఇతర గేట్లు నిర్మాణాత్మకంగా గుర్తించలేని ఒక i18n regressionను ఇది పట్టుకుంటుంది: ఒక ఆంగ్ల విలువ +తిరిగి రాయబడినా, _మునుపటి_ ఆంగ్లం ఆధారంగా రూపొందించిన అనువాదాలు అలాగే మిగిలిపోతాయి, అందువల్ల +ఆంగ్లేతర వినియోగదారులు నమ్మకంగా రాసినప్పటికీ ఇప్పుడు తప్పుగా ఉన్న పాఠ్యాన్నే చదువుతూ ఉంటారు. -ఇది నిజంగానే విడుదలైంది. Antigravity లాగిన్ సహాయకం వచ్చినప్పుడు (#5203) -`oauthModal.googleOAuthWarning` తిరిగి వ్రాయబడింది; **43 లోకేల్లలో 39** ఆపరేటర్లకు "పూర్తి -URLను కాపీ చేసి దిగువ అతికించండి" అని చెప్పే వచనాన్ని అలాగే ఉంచాయి — ఆ ప్రొవైడర్ కోసం పూర్తి -చేయలేని ప్రవాహం అది. #8463 వరకు ఇది గుర్తించబడలేదు, ఎందుకంటే: +ఇది నిజంగానే విడుదలైంది. Antigravity login helper వచ్చినప్పుడు (#5203) +`oauthModal.googleOAuthWarning` తిరిగి రాయబడింది; **43 localeలలో 39**లో ఆపరేటర్లకు "పూర్తి +URLను కాపీ చేసి దిగువన పేస్ట్ చేయండి" అని చెప్పే పాఠ్యం అలాగే ఉండిపోయింది — ఆ ప్రొవైడర్కు పూర్తి +చేయలేని ఫ్లో అది. #8463 వరకు ఇది గుర్తించబడలేదు, ఎందుకంటే: -- `sync-ui-keys` **లేని** కీలను మాత్రమే బ్యాక్ఫిల్ చేస్తుంది, **పాతబడిన** వాటిని ఎప్పుడూ చేయదు; -- `check-ui-keys-coverage` కీ _ఉనికిని_ లెక్కిస్తుంది, కాబట్టి పాత అనువాదం కవర్ అయినట్లుగా స్కోర్ పొందుతుంది; -- `check-translation-drift` అనేది `docs/i18n//**.md` డాక్యుమెంటేషన్ మిర్రర్లను ట్రాక్ చేస్తుంది — - అది `src/i18n/messages/*.json`ను ఎప్పుడూ చదవదు. 2026-09 రీ-సింక్ నుండి `docs-sync-strict` జాబ్లో నిరోధిస్తోంది: - ప్రధాన డాక్ను సవరించండి → `npm run i18n:run -- --files=` (విభాగ-స్థాయి, చవకైనది). +- `sync-ui-keys` **లేని** keyలను మాత్రమే backfill చేస్తుంది, **పాతబడిన** వాటిని ఎప్పుడూ చేయదు; +- `check-ui-keys-coverage` key _ఉనికిని_ లెక్కిస్తుంది, కాబట్టి పాత అనువాదం కవర్ అయినట్లుగా స్కోర్ పొందుతుంది; +- `check-translation-drift` అనేది `docs/i18n//**.md` డాక్యుమెంటేషన్ mirrorలను ట్రాక్ చేస్తుంది — + అది `src/i18n/messages/*.json`ను ఎప్పుడూ చదవదు. 2026-09 re-sync నుండి `docs-sync-strict` జాబ్లో నిరోధకంగా ఉంది: + ప్రధాన docను సవరించండి → `npm run i18n:run -- --files=` (విభాగ-స్థాయి, తక్కువ ఖర్చుతో కూడినది). -**Diff-aware, baseline-backed కాదు.** ఇది merge base వద్ద ఉన్న `en.json`ను working treeతో పోలుస్తుంది; ఆంగ్ల విలువ మారిన ప్రతి keyకి, ఇంకా మార్పులేని అనువాదాన్ని కలిగి ఉన్న ఏ locale అయినా staleగా పరిగణించబడుతుంది. ఇది ఉద్దేశపూర్వకంగా **ఇప్పటికే ఉన్న రుణాన్ని స్థిరపరుస్తుంది** — చాలా కాలంగా ఉన్న అనువాదం ఏ పాత ఆంగ్లం నుంచి వచ్చిందో diff వెల్లడించలేదు, కాబట్టి gate ప్రస్తుత మార్పు తాకిన వాటిని మాత్రమే పరిశీలిస్తుంది. ప్రత్యామ్నాయం (ప్రతి keyకి ఒక hash baseline) కోసం ~600 KB generated file అవసరమవుతుంది; ఇది ప్రస్తుతం ఉన్న అతిపెద్ద baseline కంటే 3× పెద్దది, అలాగే ప్రతి i18n PRలో మార్పులకు లోనవుతుంది. +**Diff-aware, baseline-backed కాదు.** ఇది merge base వద్ద ఉన్న `en.json`ను +working treeతో పోలుస్తుంది; ఇంగ్లీష్ విలువ మారిన ప్రతి key విషయంలో, ఇప్పటికీ మార్పు చేయని +అనువాదాన్ని కలిగి ఉన్న ఏ locale అయినా staleగా పరిగణించబడుతుంది. ఇది ఉద్దేశపూర్వకంగా **ముందే ఉన్న బకాయిని స్థిరపరుస్తుంది** — దీర్ఘకాలంగా ఉన్న అనువాదం ఏ పాత ఇంగ్లీష్ నుండి వచ్చిందో diff వెల్లడించలేదు, కాబట్టి gate +ప్రస్తుత మార్పు ప్రభావితం చేసిన వాటినే అంచనా వేస్తుంది. ప్రత్యామ్నాయమైన (ప్రతి-key hash baseline) కోసం +~600 KB generated file అవసరమవుతుంది; ఇది ప్రస్తుతం ఉన్న అతిపెద్ద baseline కంటే 3× పెద్దది, అలాగే ప్రతి i18n PRలో మారుతూ ఉంటుంది. -దీన్ని సంతృప్తిపరచడానికి రెండు మార్గాలు: +దీనిని సంతృప్తిపరచడానికి రెండు మార్గాలు: 1. ప్రభావితమైన అనువాదాలను నవీకరించండి, లేదా -2. వాటిని `__MISSING__:`గా సెట్ చేయండి — అప్పుడు runtime సరిచేసిన ఆంగ్లాన్ని అందిస్తుంది +2. వాటిని `__MISSING__:`గా సెట్ చేయండి — అప్పుడు runtime సరిచేసిన ఇంగ్లీష్ను అందిస్తుంది (`src/i18n/request.ts::deepMergeFallback`, #7258), అలాగే ఆ key అనువాదం కోసం queueలో చేరుతుంది. -string యొక్క **అర్థం** మారితే, **key పేరును మార్చడానికే** ప్రాధాన్యం ఇవ్వండి: కొత్త key stale అనువాదాన్ని వారసత్వంగా పొందలేదు. #8463 ఉపయోగించిన నమూనా ఇదే. +string యొక్క **అర్థం** మారితే, **key పేరు మార్చడానికి** ప్రాధాన్యం ఇవ్వండి: కొత్త key stale అనువాదాన్ని +వారసత్వంగా పొందలేదు. #8463 ఉపయోగించిన pattern ఇదే. ```bash -npm run i18n:check-value-drift # కఠినం (CI అమలు చేసేది) +npm run i18n:check-value-drift # కఠినమైనది (CI అమలు చేసేది) npm run i18n:check-value-drift:warn # నివేదిక మాత్రమే BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -base catalogను చదవలేనప్పుడు (base ref లేని shallow clone), `check-openapi-breaking`ను అనుసరిస్తూ `SKIP reason=base-unresolved`తో 0గా నిష్క్రమిస్తుంది. +base catalogను చదవలేనప్పుడు (base ref లేని shallow +clone), `check-openapi-breaking`ను అనుకరిస్తూ `SKIP reason=base-unresolved`తో 0 exit అవుతుంది. ### Job: `i18n` -పూర్తి i18n ధ్రువీకరణ matrix (ప్రతి localeకు ఒక job). మొత్తం job సలహాత్మకమైనది. +పూర్తి i18n validation matrix (ప్రతి localeకు ఒక job). మొత్తం job advisory మాత్రమే. -| Script | ధ్రువీకరించేది | నిరోధించేది | -| ------------------------------- | ------------------------------ | ------------------------------------------------------ | -| `validate_translation.py quick` | ప్రతి localeకు అనువాద సంపూర్ణత | **సలహాత్మకం** (మొత్తం jobపై `continue-on-error: true`) | +| Script | ధృవీకరించేది | Blocking | +| ------------------------------- | ------------------------------ | ----------------------------------------------------- | +| `validate_translation.py quick` | ప్రతి localeలో అనువాద సంపూర్ణత | **Advisory** (మొత్తం jobపై `continue-on-error: true`) | ### Job: `pr-test-policy` pull requestలపై మాత్రమే అమలవుతుంది. -| Script | ధ్రువీకరించేది | నిరోధించేది | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, లేదా `bin/`లోని production codeను మార్చే PRలు తప్పనిసరిగా testలను చేర్చాలి లేదా నవీకరించాలి (Hard Rule #8) | అవును | -| `check:test-masking` | మార్చిన test fileలు మొత్తం assert సంఖ్యను తగ్గించవు లేదా `assert.ok(true)` tautologyలను జోడించవు | అవును | -| `check:pr-evidence` | PR bodyలో మార్పుకు సంబంధించిన test/VPS ఆధారాలు పేర్కొనాలి (PR proseలో grep చేయడం ద్వారా Hard Rule #18ను యాంత్రీకరిస్తుంది — సున్నితమైనది, Backlog చూడండి) | అవును | +| Script | ధృవీకరించేది | Blocking | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`, లేదా `bin/`లో production codeను మార్చే PRలు తప్పనిసరిగా testలను చేర్చాలి లేదా నవీకరించాలి (Hard Rule #8) | అవును | +| `check:test-masking` | మార్చిన test fileలు మొత్తం assert countను తగ్గించవు లేదా `assert.ok(true)` tautologyలను జోడించవు | అవును | +| `check:pr-evidence` | మార్పు కోసం PR bodyలో test/VPS ఆధారాలను ప్రస్తావించాలి (PR proseను grep చేయడం ద్వారా Hard Rule #18ను యాంత్రీకరిస్తుంది — ఇది సున్నితమైనది, Backlog చూడండి) | అవును | ### Job: `test-vitest` `build` తర్వాత అమలవుతుంది. విఫలమైతే mergeను నిరోధిస్తుంది. -| Suite | ధ్రువీకరించేది | నిరోధించేది | -| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | అవును | -| `test:vitest:ui` | UI component testలు — vitest runner | **నిరోధిస్తుంది** — ఇప్పటికే ఉన్న వైఫల్యాలు `vitest.config.ts`లో స్పష్టంగా మినహాయించబడ్డాయి; కొత్త వైఫల్యాలు jobను విఫలం చేస్తాయి | +| Suite | ధృవీకరించేది | Blocking | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | అవును | +| `test:vitest:ui` | UI component testలు — vitest runner | **Blocking** — ముందే ఉన్న failureలు `vitest.config.ts`లో స్పష్టంగా మినహాయించబడ్డాయి; కొత్త failureలు jobను విఫలం చేస్తాయి | -### Nightly workflowలు (షెడ్యూల్ చేయబడినవి, సలహాత్మకమైనవి) +### Nightly workflowలు (షెడ్యూల్ చేయబడినవి, advisory) -ఇవి cron scheduleలో (మరియు `workflow_dispatch` ద్వారా) అమలవుతాయి, PRలపై ఎప్పుడూ అమలవవు. అన్నీ సలహాత్మకమైనవే. +ఇవి cron scheduleలో (మరియు `workflow_dispatch` ద్వారా) అమలవుతాయి, PRలపై ఎప్పుడూ అమలవవు. అన్నీ advisory మాత్రమే. -| Workflow | ధ్రువీకరించేది | నిరోధించేది | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `nightly-property` | random seed + అధిక run countతో fast-check property testలు | **సలహాత్మకం** | -| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **సలహాత్మకం** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probeలు (provider secret లేకుండా దాటవేయబడతాయి) | **సలహాత్మకం** | -| `nightly-schemathesis` | `docs/openapi.yaml`ను ఉపయోగించి live OmniRouteపై OpenAPI contract fuzzing (schemathesis) — spec ఉల్లంఘనలు / నిర్వహించని 500లను బయటపెడుతుంది (Fase 8 B.4) | **సలహాత్మకం** | -| `nightly-mutation` | వేగవంతమైన unit laneపై Stryker mutation-testing score — మిగిలిపోయిన mutantలు బలహీనమైన assertలను బయటపెడతాయి | **సలహాత్మకం** | -| `nightly-compat` | మద్దతు ఉన్న `engines.node` rangeలన్నింటిలో Node engine compatibility matrix | **సలహాత్మకం** | +| Workflow | ధృవీకరించేది | Blocking | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `nightly-property` | random seed + అధిక run countతో fast-check property testలు | **Advisory** | +| `nightly-resilience` | heap-growth gate, chaos fault-injection, k6 load/soak | **Advisory** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probeలు (provider secret లేకపోతే skip చేయబడతాయి) | **Advisory** | +| `nightly-schemathesis` | `docs/openapi.yaml`ను ఉపయోగించి live OmniRouteపై OpenAPI contract fuzzing (schemathesis) — spec ఉల్లంఘనలు / నిర్వహించని 500లను వెలికితీస్తుంది (Fase 8 B.4) | **Advisory** | +| `nightly-mutation` | వేగవంతమైన unit laneపై Stryker mutation-testing score — మనుగడలో ఉన్న mutantలు బలహీనమైన assertలను వెలికితీస్తాయి | **Advisory** | +| `nightly-compat` | మద్దతు ఉన్న `engines.node` rangeల అంతటా Node engine compatibility matrix | **Advisory** | --- @@ -534,41 +540,41 @@ TypeScript లాంగ్వేజ్ సర్వర్ను అందుబ ## హేతుబద్ధీకరణ బ్యాక్లాగ్ (ROI సమీక్ష — దశ 9 తరంగం 3) -ఈ జాబితాను 2026-06-17న `ci.yml`తో సరిచూశారు (మునుపటి సంస్కరణలో +ఈ ఇన్వెంటరీని 2026-06-17న `ci.yml`తో సరిపోల్చి సరిచేశారు (మునుపటి సంస్కరణలో `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` చేర్చబడలేదు). సరిచూసిన సమితిపై నిర్వహించిన ROI సమీక్ష -క్రింది హేతుబద్ధీకరణ అభ్యర్థులను గుర్తించింది. **విలీనాలు యాంత్రిక CI -మార్పులు; మార్పిడి/తొలగింపు నిర్ణయాలు ఆపరేటర్కు కేటాయించిన విధానపరమైన నిర్ణయాలు.** దిగువన ఉన్నవేవీ +`check:codeql-ratchet`, `check:pr-evidence` విస్మరించబడ్డాయి). సరిపోల్చిన సమితిపై నిర్వహించిన ROI సమీక్ష +కింది హేతుబద్ధీకరణ అభ్యర్థులను గుర్తించింది. **విలీనాలు యాంత్రిక CI +మార్పులు; మార్చడం/తొలగించడం అనేవి ఆపరేటర్కు కేటాయించిన విధానపరమైన నిర్ణయాలు.** దిగువన ఉన్నవేవీ ఇంకా వర్తింపజేయబడలేదు. **పైన డాక్యుమెంట్ చేయనివి కూడా ఉన్నాయి** (సలహాపూర్వకమైనవి, తక్కువ సంకేతం): `docs-lint` జాబ్ (markdownlint + Vale, మొత్తం జాబ్కు `continue-on-error`) మరియు స్వతంత్ర స్కానర్ వర్క్ఫ్లోలు -`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` అనేది -`quality-baseline.json`లో ఉంది, కానీ `ci.yml`లో బ్లాకింగ్ రాచెట్కు అనుసంధానించబడలేదు — ఈ మెట్రిక్ -ప్రస్తుతం అనాథగా ఉంది. +`semgrep.yml` / `codeql.yml` / `scorecard.yml`. `quality-baseline.json`లో +`semgrepFindings: 0` ఉంది, కానీ `ci.yml`లోని బ్లాకింగ్ రాచెట్కు అది అనుసంధానించబడలేదు — ప్రస్తుతం ఈ మెట్రిక్కు +ఏ అనుసంధానమూ లేదు. ### విలీనం / నకిలీల తొలగింపు (యాంత్రికం, తక్కువ ప్రమాదం) -ప్రతి అభ్యర్థిని 2026-06-17న అమలులో ఉన్న గేట్ స్థితితో పోల్చి ధృవీకరించారు (నమ్మండి-కానీ-ధృవీకరించండి); -"స్పష్టమైనవి"గా కనిపించిన అనేక విలీనాలు వాస్తవానికి సాంకేతిక ఋణాన్ని దాచిపెట్టాయని తేలింది మరియు అవి **శుభ్రమైన** ప్రత్యామ్నాయాలు కావు. +ప్రతి అభ్యర్థినీ 2026-06-17న ప్రత్యక్ష గేట్ స్థితితో పోల్చి ధ్రువీకరించారు (నమ్మండి-కానీ-ధ్రువీకరించండి); +"స్పష్టమైనవి" అనిపించిన అనేక విలీనాలు వాస్తవానికి సాంకేతిక రుణాన్ని దాచిపెట్టాయని తేలింది, కాబట్టి అవి **శుభ్రమైన** ప్రత్యామ్నాయాలు కావు. -- **`check:docs-sync` రెండుసార్లు నడుస్తుంది** — `lint` జాబ్లో స్వతంత్రంగా, అలాగే `check:docs-all` (`docs-sync-strict`) లోపల మరియు husky ప్రీ-కమిట్ హుక్లో మరోసారి. ✅ **పూర్తయింది** — స్వతంత్ర `lint` అమలు తొలగించబడింది. -- **CVE స్కానింగ్** — ❌ **శుభ్రమైన విలీనం కాదు.** ఏదైనా అధిక/క్రిటికల్ CVE ఉంటే `audit:deps` పూర్తిగా విఫలమవుతుంది; `check:vuln-ratchet` (osv) మాత్రం బేస్లైన్తో పోలిస్తే _తిరోగమనం_ ఉన్నప్పుడు మాత్రమే విఫలమవుతుంది (ప్రస్తుతం 1 MODERATE). అర్థాలు వేర్వేరు — `audit:deps`ను తొలగిస్తే సంపూర్ణ అధిక/క్రిటికల్ గేట్ పోతుంది. రెండింటినీ ఉంచండి. -- **సైకిల్ గుర్తింపు** — ❌ **శుభ్రమైన విలీనం కాదు.** `check:circular-deps` (dpdm) **91 సైకిళ్లను** నివేదిస్తుంది (అందుకే ఇది సలహాపూర్వకంగా ఉంది); మొదట వాటిని పరిష్కరించకుండా దీన్ని బ్లాకింగ్గా మార్చలేరు, అలాగే ఇది విజయవంతంగా ఉన్న, ఎంపిక చేసిన `check:cycles` కంటే విస్తృత పరిధిని కలిగి ఉంది. `check:cycles`ను బ్లాకింగ్గా ఉంచండి; 91 dpdm సైకిళ్ల పరిష్కారం ప్రత్యేక బ్యాక్లాగ్ అంశం. -- **సంక్లిష్టత** — ✅ **పూర్తయింది** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ఒక ESLint వాక్, ruleId ఆధారంగా లెక్కిస్తుంది కాబట్టి సైక్లోమాటిక్+గరిష్ఠ-లైన్లు మరియు కాగ్నిటివ్ బేస్లైన్లు స్వతంత్రంగా ఉంటాయి; స్థానిక `--update` కోసం విడివిడిగా ఉన్న `check:complexity` / `check:cognitive-complexity` అలాగే కొనసాగుతాయి. -- **`/api` యాంటీ-హాల్యూసినేషన్** — ✅ **పూర్తయింది** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` కోసం ఒక FS ఇన్వెంటరీ, openapi-routes + docs-symbols ఇప్పటికీ స్వతంత్రంగా నివేదిస్తాయి; స్థానిక అమలుల కోసం విడివిడిగా ఉన్నవి అలాగే కొనసాగుతాయి. -- **`check:node-runtime` 11 జాబ్లలో నడుస్తుంది** — ⚠️ **తక్కువ ROI.** ప్రతి ఒక్కటీ ప్రత్యేక రన్నర్ మరియు ఈ తనిఖీ <1s; చవకైన ప్రతి-జాబ్ రక్షణను కోల్పోవడంతో పోలిస్తే మొత్తం ఆదా ~10s మాత్రమే. ఈ మార్పుల కలకలం విలువైనది కాదు. -- **CI lintలో `typecheck:noimplicit:core`** — ✅ **lint జాబ్ నుండి తొలగించబడింది** (ఇది సలహాపూర్వక `continue-on-error`గా ఉండేది); బ్లాకింగ్ టైప్ ఉపరితలం `typecheck:core` + `check:type-coverage`. స్థానిక స్క్రిప్ట్ కొనసాగించబడింది. +- **`check:docs-sync` రెండుసార్లు నడుస్తుంది** — `lint` జాబ్లో స్వతంత్రంగా, అలాగే `check:docs-all` (`docs-sync-strict`)లో మరియు husky pre-commit హుక్లో మరోసారి. ✅ **పూర్తయింది** — స్వతంత్ర `lint` అమలు తొలగించబడింది. +- **CVE స్కానింగ్** — ❌ **శుభ్రమైన విలీనం కాదు.** ఏదైనా అధిక/క్రిటికల్ CVE ఉంటే `audit:deps` పూర్తిగా విఫలమవుతుంది; `check:vuln-ratchet` (osv) మాత్రం బేస్లైన్తో పోలిస్తే _తిరోగమనం_ ఉన్నప్పుడు మాత్రమే విఫలమవుతుంది (ప్రస్తుతం 1 MODERATE). అర్థాలు వేర్వేరు — `audit:deps`ను తొలగిస్తే సంపూర్ణ అధిక/క్రిటికల్ గేట్ కోల్పోతాం. రెండింటినీ ఉంచండి. +- **సైకిల్ గుర్తింపు** — ✅ **పూర్తయింది** (#15159 G-01/G-02). ఇక్కడి పాత పాఠ్యం `check:cycles`ను "గ్రీన్, జాగ్రత్తగా ఎంపిక చేసిన" గేట్గా పేర్కొని, `check:circular-deps` (dpdm) 91 సైకిళ్లను నివేదించినందున దానిని బ్లాకింగ్గా ఉంచడాన్ని సమర్థించింది. ఆ గ్రీన్ ఒక **తప్పుడు గ్రీన్**: `check:cycles` 5 ఉపడైరెక్టరీలను (450 ఫైళ్లు) స్కాన్ చేసింది, స్థిర `import|export … from`తో మాత్రమే సరిపోల్చింది, అలాగే ప్రతి `@/` మరియు `@omniroute/open-sse/` స్పెసిఫైయర్ను వదిలేసింది; అందువల్ల రిపోలో అధికంగా ఉన్న డైనమిక్-import + అలియాస్ సైకిళ్లను అది చూడలేకపోయింది. పరిష్కరించబడింది: ఇప్పుడు గేట్ `src` + `open-sse`లో సంచరిస్తుంది (5023 ఫైళ్లు), TypeScript AST నుంచి స్పెసిఫైయర్లను సేకరిస్తుంది (కాబట్టి `import("…")` లెక్కించబడుతుంది, కానీ టైప్-స్థానంలోని `typeof import("…")` లెక్కించబడదు), అలాగే tsconfig `paths`ను పరిష్కరిస్తుంది. ఇది 0 కాకుండా **14** సైకిళ్లను కనుగొంటుంది. ముందే ఉన్న 14 సైకిళ్లను గేట్ PRలో పరిష్కరించడం సాధ్యం కానందున, `check:cycles` ఇప్పుడు ఒక **రాచెట్** (`--ratchet`, `quality-baseline.json`లో పరిమితి `metrics.cycles.value = 14`, `direction: down`) — ఇది ఏదైనా _తిరోగమనాన్ని_ బ్లాక్ చేస్తుంది, కౌంట్ తగ్గడం మాత్రమే సాధ్యమవుతుంది. CI `npm run check:cycles:ratchet`ను నడుపుతుంది. తగ్గింపు ప్రక్రియ **A-01**తో కలిసి కొనసాగుతుంది. విస్తృతమైన రెండో అభిప్రాయంగా `check:circular-deps` (dpdm) సలహాపూర్వకంగానే ఉంటుంది. +- **సంక్లిష్టత** — ✅ **పూర్తయింది** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ఒక ESLint వాక్, ruleId ఆధారంగా లెక్కిస్తుంది కాబట్టి cyclomatic+max-lines మరియు cognitive బేస్లైన్లు స్వతంత్రంగా ఉంటాయి; స్థానిక `--update` కోసం విడివిడిగా ఉన్న `check:complexity` / `check:cognitive-complexity` అలాగే ఉంటాయి. +- **`/api` యాంటీ-హాల్యూసినేషన్** — ✅ **పూర్తయింది** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api`కు ఒకే FS ఇన్వెంటరీ, openapi-routes + docs-symbols ఇప్పటికీ విడివిడిగా నివేదిస్తాయి; స్థానిక అమలుల కోసం విడివిడిగా ఉన్నవి అలాగే ఉంటాయి. +- **`check:node-runtime` 11 జాబ్లలో నడుస్తుంది** — ⚠️ **తక్కువ ROI.** ప్రతి ఒక్కటీ ప్రత్యేక రన్నర్, అలాగే చెక్ <1s; చౌకైన ప్రతి-జాబ్ రక్షణను కోల్పోవడంతో పోలిస్తే మొత్తం ఆదా ~10s మాత్రమే. ఈ మార్పుల కలకలం విలువైనది కాదు. +- **CI lintలో `typecheck:noimplicit:core`** — ✅ **lint జాబ్ నుంచి తొలగించబడింది** (ఇది సలహాపూర్వక `continue-on-error`గా ఉండేది); బ్లాకింగ్ టైప్ సర్ఫేస్ `typecheck:core` + `check:type-coverage`. స్థానిక స్క్రిప్ట్ అలాగే ఉంచబడింది. ### మార్చడం / నిర్ణయించడం (ఆపరేటర్ విధానం) -- `check:openapi-security-tiers` (సలహాపూర్వకం) — ❌ **నేరుగా మార్చడం సాధ్యం కాదు.** ఇది 0తో నిష్క్రమిస్తుంది, కానీ `LOCAL_ONLY_API_PREFIXES` కింద ఉన్న అనేక `traffic-inspector` రూట్లలో `x-loopback-only: true` అనోటేషన్ లేదని హెచ్చరిస్తుంది. దీన్ని అమలు చేయడానికి ముందుగా ఆ అనోటేషన్లను `openapi.yaml`కు జోడించాలి. -- `typecheck:noimplicit:core` (సలహాపూర్వకం) — బ్లాకింగ్ `check:type-coverage` రాచెట్లో చాలావరకు ఇమిడిపోయింది. దీన్ని రాచెట్గా మార్చండి లేదా అనవసరంగా పునరావృతమయ్యే రెండవ `tsc` పాస్ను తొలగించండి. +- `check:openapi-security-tiers` (సలహాపూర్వకం) — ❌ **శుభ్రంగా మార్చడం సాధ్యం కాదు.** ఇది 0తో నిష్క్రమిస్తుంది, కానీ `LOCAL_ONLY_API_PREFIXES` కింద ఉన్న అనేక `traffic-inspector` రూట్లలో `x-loopback-only: true` అనోటేషన్ లేదని హెచ్చరిస్తుంది. దీన్ని అమలు చేయాలంటే ముందుగా ఆ అనోటేషన్లను `openapi.yaml`కు జోడించాలి. +- `typecheck:noimplicit:core` (సలహాపూర్వకం) — బ్లాకింగ్ `check:type-coverage` రాచెట్లో ఇది ఎక్కువగా అంతర్భాగమైంది. దీన్ని రాచెట్గా మార్చండి లేదా అనవసరంగా పునరావృతమయ్యే రెండో `tsc` పాస్ను తొలగించండి. - `test:vitest:ui` (ఇప్పుడు **బ్లాకింగ్**) — ముందే ఉన్న వైఫల్యాలు `vitest.config.ts`లో `// #8618` ట్రాకింగ్ వ్యాఖ్యలతో స్పష్టంగా మినహాయించబడ్డాయి; కొత్త వైఫల్యాలు జాబ్ను విఫలం చేస్తాయి. -- `check:secrets` (gitleaks, డాక్యుమెంట్ చేసిన 3 తప్పుడు-పాజిటివ్ల వద్ద స్థిరపరచిన బ్లాకింగ్ రాచెట్) — 0కు చేరుకోవడానికి ఆ 3ను అనుమతి జాబితాలో చేర్చండి లేదా సలహాపూర్వక స్థాయికి తగ్గించండి. GitHub స్థానిక సీక్రెట్-స్కానింగ్ + `check:public-creds`తో అతివ్యాప్తి చెందుతుంది. -- `check:pr-evidence` (బ్లాకింగ్, PR-బాడీ గద్యాన్ని greps చేస్తుంది) — తప్పుడు-పాజిటివ్ ప్రమాదం అధికం; తొలగిస్తే కఠిన నియమం #18 అమలు బలహీనమవుతుంది, కాబట్టి ఇది నిజమైన విధానపరమైన నిర్ణయం. -- `semgrep` (సలహాపూర్వక స్వతంత్రం) — OWASP కుటుంబాల విషయంలో CodeQLతో అతివ్యాప్తి చెందుతుంది; దాని బేస్లైన్ను రాచెట్కు అనుసంధానించండి లేదా తొలగించండి. +- `check:secrets` (gitleaks, డాక్యుమెంట్ చేసిన 3 తప్పుడు-పాజిటివ్ల వద్ద స్థిరపరచిన బ్లాకింగ్ రాచెట్) — 0కు చేరుకోవడానికి ఆ 3ను అనుమతి జాబితాలో చేర్చండి లేదా సలహాపూర్వక స్థాయికి తగ్గించండి. ఇది GitHub స్థానిక secret-scanning + `check:public-creds`తో అతివ్యాప్తి చెందుతుంది. +- `check:pr-evidence` (బ్లాకింగ్, PR-body గద్యాన్ని greps చేస్తుంది) — తప్పుడు-పాజిటివ్ ప్రమాదం అధికం; దీన్ని తొలగిస్తే Hard Rule #18 అమలు బలహీనపడుతుంది, కాబట్టి ఇది నిజమైన విధానపరమైన నిర్ణయం. +- `semgrep` (సలహాపూర్వక స్వతంత్ర అమలు) — OWASP వర్గాల విషయంలో CodeQLతో అతివ్యాప్తి చెందుతుంది; దాని బేస్లైన్ను రాచెట్కు అనుసంధానించండి లేదా తొలగించండి. --- diff --git a/docs/i18n/th/CONTRIBUTING.md b/docs/i18n/th/CONTRIBUTING.md index a4c6f3ded19..503a1d51b68 100644 --- a/docs/i18n/th/CONTRIBUTING.md +++ b/docs/i18n/th/CONTRIBUTING.md @@ -394,15 +394,15 @@ docs/ # Documentation - [ ] การ Build สำเร็จ (`npm run build`) - [ ] เพิ่ม TypeScript types สำหรับ public functions และ interfaces ใหม่แล้ว - [ ] ไม่มี secrets หรือ fallback values ที่ hardcode ไว้ -- [ ] Public upstream credentials ถูกฝังผ่าน `resolvePublicCred()` (ดู [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) และห้ามใช้เป็น literals +- [ ] ฝัง public upstream credentials ผ่าน `resolvePublicCred()` (ดู [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) และไม่ใช้ literals โดยเด็ดขาด - [ ] Error responses ส่งผ่าน `buildErrorBody()` / `sanitizeErrorMessage()` — ไม่มี raw stack traces ใน response bodies (ดู [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Shell commands (`exec` / `spawn`) ส่ง runtime values ผ่าน `env` ไม่ใช่ผ่าน string interpolation -- [ ] Inputs ทั้งหมดได้รับการตรวจสอบด้วย Zod schemas -- [ ] เพิ่ม **fragment** ของ Changelog ภายใต้ `changelog.d/{features|fixes|maintenance}/-.md` สำหรับการเปลี่ยนแปลงที่ส่งผลต่อผู้ใช้แล้ว (ดู [`changelog.d/README.md`](./changelog.d/README.md)) — **ห้าม** แก้ไข `CHANGELOG.md` โดยตรง; fragments จะถูกรวบรวมเมื่อออกรุ่น และจะไม่เกิดข้อขัดแย้งระหว่าง PRs +- [ ] ตรวจสอบ inputs ทั้งหมดด้วย Zod schemas +- [ ] เพิ่ม **fragment** ของ Changelog ภายใต้ `changelog.d/{features|fixes|maintenance}/-.md` สำหรับการเปลี่ยนแปลงที่ส่งผลต่อผู้ใช้ (ดู [`changelog.d/README.md`](./changelog.d/README.md)) — **ห้าม** แก้ไข `CHANGELOG.md` โดยตรง; fragments จะถูกรวบรวมเมื่อเผยแพร่ release และจะไม่เกิด conflict ระหว่าง PRs - [ ] อัปเดตเอกสารแล้ว (หากเกี่ยวข้อง) -- [ ] ไม่มี CodeQL / Secret-Scanning alerts ใหม่ หรือแต่ละรายการถูกปิดโดยมีเหตุผลเชิงเทคนิคที่อ้างอิงเอกสาร `docs/security/` ที่เกี่ยวข้อง -- [ ] Routes ที่ spawn child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) ถูกจัดประเภทเป็น `isLocalOnlyPath()` ใน `src/server/authz/routeGuard.ts` — ดู [กฎเคร่งครัด #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] ไม่มี trailers `Co-Authored-By` ใน commit messages — commits ต้องแสดงภายใต้ Git identity ของเจ้าของ repository เท่านั้น (กฎเคร่งครัด #16) +- [ ] ไม่มี CodeQL / Secret-Scanning alerts ใหม่ หรือแต่ละรายการถูก dismiss พร้อมเหตุผลทางเทคนิคที่อ้างอิงเอกสาร `docs/security/` ที่เกี่ยวข้อง +- [ ] Routes ที่ spawn child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) ถูกจัดประเภทเป็น `isLocalOnlyPath()` ใน `src/server/authz/routeGuard.ts` — ดู [กฎบังคับ #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] ไม่มี trailers `Co-authored-by` ของ AI/bot ใน commit messages (กฎบังคับ #16) — human collaborators ที่นำผลงานมาใช้จะได้รับเครดิตด้วย trailers มาตรฐาน `Co-authored-by: Name ` --- diff --git a/docs/i18n/th/docs/architecture/QUALITY_GATES.md b/docs/i18n/th/docs/architecture/QUALITY_GATES.md index e86575f8303..febebab693f 100644 --- a/docs/i18n/th/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/th/docs/architecture/QUALITY_GATES.md @@ -15,264 +15,264 @@ --- -## รายการเกตและโปรไฟล์การดำเนินงาน +## รายการเกตและโปรไฟล์การดำเนินการ ### การรับแคนดิเดต เวิร์กโฟลว์ CI และ Quality Gates ต่างให้ผลตัดสินที่คงที่ ได้แก่ `Gate / CI` และ -`Gate / Quality` นโยบายการรับเข้าแบบมีเวอร์ชันของเวิร์กโฟลว์เหล่านี้ระบุงานต้นทางทุกงาน -ว่าเป็นงานที่จำเป็นหรืองานเชิงแนะนำ งานที่จำเป็นและมีผลบังคับใช้ต้องสำเร็จ: ผลลัพธ์ที่หายไป -ถูกยกเลิก ถูกข้าม อยู่ระหว่างดำเนินการ หรือไม่ทราบ ไม่สามารถใช้ยืนยัน PASS ได้ การจัดประเภท -เฉพาะเอกสารหรือเฉพาะแค็ตตาล็อกที่ถูกต้องอาจทำให้เลนโค้ดไม่มีผลบังคับใช้ได้ -แต่ PR แบบร่างไม่ถือเป็นแคนดิเดตที่ได้รับการยอมรับ ป้ายกำกับ `hotfix` ไม่ได้ยกเว้นข้อกำหนดด้านหลักฐาน - -ทั้งสองเวิร์กโฟลว์ครอบคลุม PR และการพุชไปยังสาขา main/release, การสั่งทำงานด้วยตนเอง และ -เหตุการณ์ merge-group การพุช การสั่งทำงาน และ merge-group จะเรียกใช้ชุดการตรวจสอบทั้งหมด Fork -และ merge group ใช้รันเนอร์แบบโฮสต์สำหรับงานที่ในกรณีอื่นจะเลือกรันเนอร์แบบโฮสต์เอง -โดยต้องตรวจสอบว่ามีความจุแบบโฮสต์เพียงพอก่อนเปิดใช้งาน - -ใบรับรอง JSON แต่ละรายการระบุ SHA ที่เช็กเอาต์ การรันเวิร์กโฟลว์ และความพยายามในการรัน -CLI จะปฏิเสธเมื่อ SHA ของการเช็กเอาต์และเหตุการณ์ไม่ตรงกัน การทดสอบเวิร์กโฟลว์จะผูกสมาชิกของนโยบาย -เข้ากับรายการ `needs` ของงานที่ตัดสินผล เพื่อไม่ให้เลนที่เพิ่มใหม่หรือถูกลบหายไปโดยไม่มีการแจ้งเตือน -ใบรับรองครอบคลุมเฉพาะเวิร์กโฟลว์ของตนเอง ไม่ครอบคลุมการเผยแพร่ การปรับใช้ หรือการทำงานภายใน -ของสแกนเนอร์เชิงแนะนำที่มีอยู่ การเปิดใช้ชื่อการตรวจสอบทั้งสองชื่อในกฎของสาขาเป็น -การเปลี่ยนแปลงด้านการดูแลระบบที่แยกต่างหาก การเพิ่มงานเหล่านี้ไม่ได้ปกป้องสาขาโดยตัวมันเอง - -### รายการการสแกนแบบสถิต - -รายการ npm-alias แบบมีเวอร์ชันและสมาชิกของการสแกนแบบสถิตอยู่ใน -`config/quality/gate-manifest.json` เรียกใช้ `npm run check:gate-manifest` เพื่อตรวจสอบ -ชื่อสคริปต์และคำสั่งที่ตรงกันทุกประการกับ `package.json`; การเพิ่ม การลบ และ -การเปลี่ยนแปลงของคำสั่งจะทำให้ทั้งฮุกภายในเครื่องและงานจัดประเภทการเปลี่ยนแปลงใน CI ล้มเหลว -alias ไม่ใช่งานเวิร์กโฟลว์ อินสแตนซ์เมทริกซ์ หรือกรณีทดสอบ: ห้ามนำจำนวนเหล่านี้ -มาแสดงราวกับว่าสามารถใช้แทนกันได้ +`Gate / Quality` นโยบายการรับที่มีการกำหนดเวอร์ชันของแต่ละเวิร์กโฟลว์ระบุทุกงานต้นทาง +ว่าเป็นงานบังคับหรืองานให้คำแนะนำ งานบังคับที่เกี่ยวข้องต้องสำเร็จ โดยผลลัพธ์ที่หายไป +ถูกยกเลิก ถูกข้าม อยู่ระหว่างดำเนินการ หรือไม่ทราบสถานะ ไม่สามารถยืนยัน PASS ได้ การจัดประเภท +docs-only หรือ catalog-only ที่ถูกต้องอาจทำให้เลนโค้ดไม่เกี่ยวข้องได้ +แต่ PR แบบร่างไม่ถือเป็นแคนดิเดตที่ยอมรับได้ ป้ายกำกับ `hotfix` ไม่ได้ยกเว้นข้อกำหนดด้านหลักฐาน + +ทั้งสองเวิร์กโฟลว์ครอบคลุม PR และการพุชไปยังบรานช์ main/release การสั่งทำงานด้วยตนเอง และ +เหตุการณ์ merge-group การพุช การสั่งทำงาน และ merge-group จะรันชุดการตรวจสอบทั้งหมด Fork +และ merge group ใช้ hosted runner สำหรับงานที่โดยปกติจะเลือก self-hosted runner +โดยต้องตรวจสอบว่ามีขีดความสามารถของ hosted runner เพียงพอก่อนเปิดใช้งาน + +ใบรับรอง JSON แต่ละรายการระบุ SHA ที่ checkout, workflow run และ attempt +CLI จะปฏิเสธเมื่อ SHA ของ checkout/event ไม่ตรงกัน การทดสอบเวิร์กโฟลว์ผูกสมาชิกของนโยบาย +เข้ากับรายการ `needs` ของงานตัดสินผล เพื่อไม่ให้เลนที่เพิ่มใหม่หรือถูกลบหายไปโดยไม่มีการแจ้งเตือน +ใบรับรองครอบคลุมเฉพาะเวิร์กโฟลว์ของตนเอง ไม่ครอบคลุมการเผยแพร่ การดีพลอย หรือรายละเอียดภายใน +ของ advisory scanner ที่มีอยู่ การเปิดใช้งานชื่อการตรวจสอบทั้งสองในกฎของบรานช์เป็น +การเปลี่ยนแปลงด้านการดูแลระบบที่แยกต่างหาก การเพิ่มงานเหล่านี้ไม่ได้ปกป้องบรานช์โดยอัตโนมัติ + +### รายการ static scan + +รายการ npm-alias ที่มีการกำหนดเวอร์ชันและสมาชิกของ static-scan อยู่ใน +`config/quality/gate-manifest.json` รัน `npm run check:gate-manifest` เพื่อตรวจสอบ +ชื่อสคริปต์และคำสั่งที่ตรงกันทุกประการเทียบกับ `package.json` การเพิ่ม การลบ และ +การเปลี่ยนแปลงคำสั่งจะทำให้ทั้ง local hook และงานจำแนกการเปลี่ยนแปลงใน CI ล้มเหลว +alias ไม่ใช่งานเวิร์กโฟลว์ matrix instance หรือ test case ดังนั้นต้องไม่แสดงจำนวนเหล่านี้ +ราวกับว่าสามารถใช้แทนกันได้ ใช้ `npm run quality:scan -- --list` หรือ `npm run quality:scan:fast -- --list` -เพื่อตรวจสอบ alias ที่เลือกโดยไม่เรียกใช้งาน รันเนอร์จะเรียกใช้ -จุดเริ่มต้นของ npm ดังนั้นรันไทม์ของจุดเริ่มต้นดังกล่าว (รวมถึง Bun ในตำแหน่งที่กำหนดค่าไว้) จึงยังคงเดิม -แมนิเฟสต์จะบันทึก alias ที่อยู่นอกโปรไฟล์เหล่านั้นว่าเรียกใช้แยกต่างหาก และ -ห้ามใช้คำสั่งบำรุงรักษาในโปรไฟล์การสแกนแบบอ่านอย่างเดียว - -โปรไฟล์เหล่านี้ครอบคลุมเฉพาะการสแกนแบบสถิต โดยไม่ได้รับรองการทดสอบผลิตภัณฑ์ -ความครอบคลุม การแพ็กเกจ การตรวจสอบภายนอก หรือการยอมรับแคนดิเดตสำหรับรีลีสอย่างครบถ้วน -การรับเข้าโดยเวิร์กโฟลว์ใช้ `config/quality/admission-policy.json` ที่เชื่อมโยงไว้และ +เพื่อตรวจสอบ alias ที่เลือกโดยไม่เรียกใช้งาน runner จะเรียกผ่าน +npm entrypoint ดังนั้น runtime ของรายการดังกล่าว (รวมถึง Bun เมื่อกำหนดค่าไว้) จะยังคงเดิม +manifest บันทึก alias ที่อยู่นอกโปรไฟล์เหล่านี้ว่าเป็นรายการที่เรียกแยกต่างหาก และ +ห้ามใช้คำสั่งบำรุงรักษาในโปรไฟล์สแกนแบบอ่านอย่างเดียว + +โปรไฟล์เหล่านี้ครอบคลุมเฉพาะ static scan เท่านั้น ไม่ได้รับรองการทดสอบผลิตภัณฑ์ +coverage, packaging, การตรวจสอบภายนอก หรือการยอมรับแคนดิเดตสำหรับรีลีสอย่างครบถ้วน +การรับของเวิร์กโฟลว์ใช้ `config/quality/admission-policy.json` ที่เชื่อมโยงไว้และ `scripts/quality/admission-verdict.mjs` โปรไฟล์ release-observer ยังคงแยกต่างหาก -ให้ตรวจสอบการตรวจเช็กและใบรับรองที่มีผลบังคับใช้ของโปรไฟล์เหล่านั้นโดยอิสระ ข้อมูลรายการ -แบบข้อความด้านล่างนี้มีไว้ใช้อ้างอิง ไม่ใช่หลักฐานว่าเกตได้ทำงานจริง +ให้ตรวจสอบการตรวจเช็กและใบรับรองที่เกี่ยวข้องของโปรไฟล์เหล่านั้นโดยอิสระ รายการแบบร้อยแก้ว +ด้านล่างเป็นข้อมูลอ้างอิง ไม่ใช่หลักฐานว่าเกตได้ทำงานจริง -สคริปต์อยู่ภายใต้ `scripts/check/` (เกตตามนโยบาย) และ `scripts/quality/` (กลไก ratchet) +สคริปต์อยู่ภายใต้ `scripts/check/` (เกตนโยบาย) และ `scripts/quality/` (กลไก ratchet) แหล่งข้อมูลจริงของ CI คือ `.github/workflows/ci.yml` ### เส้นทางด่วนสำหรับ Release PR (`quality.yml`) -`.github/workflows/quality.yml` เสริมการทำงานของ CI สำหรับ PR ของ main/release, -การพุชไปยังสาขาที่ได้รับการปกป้อง การสั่งทำงาน และ merge group โดย PR จะใช้การตรวจสอบแบบรวดเร็ว -ที่กรองตามพาธ บิลด์ซ้ำที่ปิดใช้งานอย่างถาวรถูกลบออกแล้ว ส่วนการตรวจสอบบิลด์/แพ็กเกจ/การบูตจริงยังคงอยู่ใน CI +`.github/workflows/quality.yml` ทำงานเสริม CI สำหรับ PR ของ main/release, การพุชไปยังบรานช์ +ที่ได้รับการปกป้อง การสั่งทำงาน และ merge group โดย PR จะใช้การตรวจสอบแบบเร็วที่กรองตาม path +การ build ซ้ำที่ถูกปิดใช้งานอย่างถาวรถูกลบแล้ว ส่วนการตรวจสอบ build/package/boot จริงยังคงอยู่ใน CI -| งาน | ขอบเขต | มีผลบล็อก | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `Docs Gates (fast-path)` | PR ด้านเอกสาร/โค้ด; การอ้างอิงเอกสาร API และเอกสารทั้งหมด | ใช่ | -| `Fast Quality Gates` | PR ด้านโค้ด; การตรวจสอบแบบสถิต, typecheck, typecheck ของแดชบอร์ด, การทดสอบหน่วยที่ได้รับผลกระทบ | ใช่ | -| `Forgotten sibling tests` | PR ด้านโค้ด; ติดตามโมดูลที่เปลี่ยนแปลงไปยังผู้ใช้แบบสถิตและการทดสอบ sibling ที่เป็นไปได้; มีการรายงานพาธของ barrel และ dynamic-import เป็นการวินิจฉัยเชิงแนะนำ พร้อมข้อยกเว้นใน allowlist ที่อ้างอิงไว้ | **เชิงแนะนำ** | -| `Vitest (fast-path)` | PR ด้านโค้ด; ชุดทดสอบ vitest แบบรวดเร็ว | ใช่ | -| `Unit Tests fast-path` | PR ด้านโค้ด; ชุดทดสอบหน่วยแบบ 4 shard | ใช่ | -| `No new ESLint warnings` | PR ด้านโค้ด; การ์ด lint ที่รับรู้ suppression | ใช่ รวมถึง fork | -| `Merge integrity (changelog + generated skills)` | PR ที่ไม่ใช่แบบร่าง; การซิงค์ changelog และ skill ที่สร้างขึ้น | ใช่ รวมถึง fork | +| งาน | ขอบเขต | การบล็อก | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `Docs Gates (fast-path)` | PR ของเอกสาร/โค้ด; การอ้างอิงเอกสาร API และ docs-all | ใช่ | +| `Fast Quality Gates` | PR ของโค้ด; การตรวจสอบแบบ static, typecheck, typecheck ของแดชบอร์ด และ unit test ที่ได้รับผลกระทบ | ใช่ | +| `Forgotten sibling tests` | PR ของโค้ด; ติดตามโมดูลที่เปลี่ยนแปลงไปยัง static consumer และ sibling test ที่เป็นไปได้ โดยรายงานเส้นทางผ่าน barrel และ dynamic-import เป็นการวินิจฉัยเชิงคำแนะนำ พร้อมข้อยกเว้น allowlist ที่อ้างอิงไว้ | **ให้คำแนะนำ** | +| `Vitest (fast-path)` | PR ของโค้ด; ชุดทดสอบ vitest แบบเร็ว | ใช่ | +| `Unit Tests fast-path` | PR ของโค้ด; ชุด unit test แบบ 4 shard | ใช่ | +| `No new ESLint warnings` | PR ของโค้ด; ตัวป้องกัน lint ที่คำนึงถึง suppression | ใช่ รวมถึง fork | +| `Merge integrity (changelog + generated skills)` | PR ที่ไม่ใช่แบบร่าง; การซิงค์ changelog และ skill ที่สร้างขึ้น | ใช่ รวมถึง fork | -#### รายงานการทดสอบ sibling ที่ถูกลืม +#### รายงาน Forgotten sibling tests -`npm run check:forgotten-sibling-tests` ใช้ตัวแก้ไข import ที่อยู่เบื้องหลังแมปผลกระทบต่อการทดสอบซ้ำ +`npm run check:forgotten-sibling-tests` ใช้ import resolver ที่อยู่เบื้องหลังแผนที่ผลกระทบต่อการทดสอบซ้ำ สำหรับทุกโมดูล production ที่เปลี่ยนแปลง ระบบจะรายงานสายโซ่ -`changed module/symbol -> static consumer -> candidate sibling test` แบบกำหนดผลได้ เมื่อการทดสอบ -ที่เป็นไปได้นั้นไม่มีอยู่ใน diff ของ pull request ข้อมูลสรุป Markdown และผลลัพธ์ JSON จะถูกเก็บไว้เป็น -อาร์ติแฟกต์เวิร์กโฟลว์ `forgotten-sibling-tests` เพื่อการปรับเทียบก่อนเปิดใช้งานให้มีผลบล็อกใดๆ - -การ re-export ผ่าน barrel และ dynamic import ใช้เพื่อวินิจฉัยการ resolve เท่านั้น โดยจะไม่ก่อให้เกิด -ผลการตรวจสอบที่บล็อกการดำเนินการ ข้อยกเว้นที่ผ่านการตรวจสอบแล้วอยู่ใน -`config/quality/forgotten-sibling-allowlist.json` แต่ละรายการต้องระบุ consumer และการทดสอบที่เป็น -candidate ให้เหตุผลที่เฉพาะเจาะจง และลิงก์ไปยัง GitHub issue หรือ pull request รายการที่มีรูปแบบไม่ถูกต้องจะ -ถูกปฏิเสธโดยค่าเริ่มต้น ข้อยกเว้นไม่สามารถระงับกรณีที่การทดสอบ candidate ถูกลบ หรือ diff ที่เพิ่ม `.skip`/`.todo`; -การลดความเข้มงวดของ assertion และการปกปิดปัญหาในรูปแบบอื่นยังคงอยู่ภายใต้ความรับผิดชอบของเกต -`check:test-masking` ซึ่งบล็อกอย่างเป็นอิสระ +`changed module/symbol -> static consumer -> candidate sibling test` ที่ให้ผลลัพธ์แบบกำหนดแน่นอน +เมื่อการเปลี่ยนแปลงของ pull request ไม่มีการทดสอบที่เป็นไปได้ดังกล่าว สรุป Markdown และผลลัพธ์ JSON +จะถูกเก็บไว้เป็นอาร์ติแฟกต์เวิร์กโฟลว์ `forgotten-sibling-tests` เพื่อใช้ปรับเทียบก่อนเปิดใช้การบล็อกใดๆ + +การส่งออกซ้ำผ่าน barrel และ dynamic imports เป็นเพียงการวินิจฉัยการ resolve เท่านั้น โดยจะไม่ก่อให้เกิด +ผลการตรวจที่บล็อกการดำเนินการ ข้อยกเว้นที่ผ่านการตรวจสอบแล้วอยู่ใน +`config/quality/forgotten-sibling-allowlist.json` แต่ละรายการต้องระบุ consumer และ candidate +test ให้เหตุผลที่เฉพาะเจาะจง และลิงก์ไปยัง GitHub issue หรือ pull request รายการที่มีรูปแบบไม่ถูกต้องจะล้มเหลว +แบบปิด ข้อยกเว้นไม่สามารถระงับ candidate test ที่ถูกลบหรือ diff ที่เพิ่ม `.skip`/`.todo` +ได้ ส่วนการทำให้ assertion อ่อนลงและการปกปิดรูปแบบอื่น ๆ ยังคงอยู่ภายใต้ gate +`check:test-masking` ซึ่งบล็อกการดำเนินการโดยอิสระ ### งาน: `lint` -ทำงานกับทุก PR ที่ส่งไปยัง `main` และบล็อกการ merge เมื่อดำเนินการไม่สำเร็จ - -| สคริปต์ (`npm run ...`) | สิ่งที่ตรวจสอบ | บล็อกหรือไม่ | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | -| `check:node-runtime` | เวอร์ชัน Node.js อยู่ภายในช่วงที่รองรับ | ใช่ | -| `check:cycles` | Circular import — โมดูลทั้งหมดใน `src/` + `open-sse/` | ใช่ | -| `check:route-validation:t06` | มี Zod schema ในทุก route (นโยบาย Tier 6) | ใช่ | -| `check:any-budget:t11` | จำนวน `@ts-expect-error // any` ไม่เกินงบประมาณที่กำหนด (catraca ระดับ Tier 11) | ใช่ | -| `check:provider-consistency` | ผู้ให้บริการทุกรายใน `providers.ts` มีรายการที่ตรงกันใน `providerRegistry.ts` (และในทางกลับกัน ภายใน allowlist) | ใช่ | -| `check:model-lifecycle` | ตารางการกำหนดเส้นทางสามตารางที่ดูแลด้วยตนเองยังคงสอดคล้องกับสแนปช็อตวงจรชีวิตที่เช็กอินไว้ (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ไม่ให้คะแนน id ที่เลิกใช้งานแล้วซึ่ง `REGISTRY` สามารถกำหนดเส้นทางได้; เป้าหมายของ `BUILT_IN_ALIASES` ทุกรายการมีอยู่ใน `REGISTRY` และไม่อยู่ในสแนปช็อต id ที่เลิกใช้งานแล้ว; id ที่เลิกใช้งานแล้วทุกรายการซึ่งยังอยู่ใน `REGISTRY` จะถูกส่งต่อหรือระบุไว้ใน `allowedRetiredInCatalog`; และไม่มีต้นทางหรือปลายทางของ `DEFAULT_DEGRADATION_MAP` รายการใดปรากฏว่าเลิกใช้งานแล้วในสแนปช็อตดังกล่าว ทั้งนี้ไม่ได้พิสูจน์ว่าโมเดลกำลังให้บริการโดย upstream ที่ใช้งานอยู่ในปัจจุบัน ทำงานแบบออฟไลน์ — เปรียบเทียบกับ `config/quality/model-lifecycle.json` ซึ่งรีเฟรชด้วยตนเองโดยใช้ `npm run quality:refresh-model-lifecycle` (ใช้เครือข่าย; ไม่ได้เชื่อมเข้ากับ CI) `allowedRetiredInCatalog` เป็นกลไก ratchet สำหรับทยอยลดจำนวน: เพิ่มรายการได้เฉพาะเมื่อมี issue สำหรับติดตามเท่านั้น | ใช่ | -| `check:fetch-targets` | `fetch("/api/...")` ทุกรายการใน `src/` ฝั่งไคลเอนต์ชี้ไปยัง `route.ts` ที่มีอยู่จริง | ใช่ | -| `check:deps` | dependency ทั้งหมดที่ติดตั้งได้ด้วย `npm install` จาก `package.json` ทุกไฟล์ใน repo อยู่ใน `dependency-allowlist.json`; แพ็กเกจใหม่ที่ไม่ได้ตรึงเวอร์ชันหรืออาจเป็น slopsquatting จะถูกแจ้งเตือน | ใช่ | -| `audit:deps` | `npm audit` (root + electron) — ไม่มีคำเตือนระดับสูง/วิกฤต (ซ้ำซ้อนกับ OSV `check:vuln-ratchet`; ดู Rationalization Backlog) | ใช่ | -| `check:lockfile` | ความถูกต้องสมบูรณ์ของ `package-lock.json` — ใช้รีจิสทรี HTTPS, มีแฮชตรวจสอบความถูกต้อง และไม่มีการแทนที่โฮสต์ | ใช่ | -| `check:licenses` | รายการอนุญาตไลเซนส์ SPDX สำหรับ dependencies ที่ใช้ใน production | ใช่ | -| `check:tracked-artifacts` | ไม่มี build artifacts / symlinks ของ `node_modules` ที่ถูก commit (ทำงานใน husky pre-commit ด้วย; pre-push ถูกออกแบบให้ทำงานแบบเบา — #6716) | ใช่ | -| `check:ai-attribution` | ไม่มี trailer `Co-Authored-By` ของ AI/บอต หรือ footer ที่ระบุการสร้างโดย AI ใน commits, title หรือ body ของ PR — กฎเข้มงวดข้อที่ 16 (อยู่ในลูป fast-gates ของ `quality.yml` สำหรับ PR→`release/**` — อ่าน event payload และไม่ดำเนินการใดๆ หากไม่ใช่ PR — และเป็นขั้นตอนสำหรับ PR เท่านั้นใน lint ของ `ci.yml` สำหรับ PR→`main`; รวมถึง hook `commit-msg` ของ husky ด้วย; อนุญาตผู้เขียนร่วมที่เป็นมนุษย์; #14436) | -| `check:vitest-exclusions` | ทุก exclusion ของ Vitest ต้องระบุ tracking issue และปรากฏใน `config/quality/vitest-exclusions.json` (#13204) | ใช่ | -| `check:file-size` | ไม่มี source file ใดมีขนาดเกินขีดจำกัดของแต่ละนามสกุลไฟล์ (ratchet: ไฟล์ขนาดใหญ่ที่ตรึงไว้ในรายการ `frozen`) | ใช่ | -| `check:error-helper` | การตอบกลับข้อผิดพลาดใน executors/handlers ใช้ `buildErrorBody()` / `sanitizeErrorMessage()` (กฎเข้มงวดข้อที่ 12) | ใช่ | -| `check:migration-numbering` | ไฟล์ Migration SQL มีการกำหนดหมายเลขเรียงตามลำดับ โดยไม่มีหมายเลขขาดหายหรือซ้ำกัน | ใช่ | -| `check:public-creds` | ไม่มี OAuth `client_id`/`client_secret` แบบค่าตรงตัวหรือคีย์ Firebase Web อยู่นอก `publicCreds.ts` (กฎบังคับ #11) | ใช่ | -| `check:db-rules` | ไม่มี SQL ดิบอยู่นอกโมดูล `src/lib/db/`; ไม่มีการนำเข้าแบบ barrel จาก `localDb.ts` (กฎบังคับ #2/#5) | ใช่ | -| `check:known-symbols` | ตัวดำเนินการของผู้ให้บริการ กลยุทธ์การกำหนดเส้นทาง และตัวแปลที่ลงทะเบียนในตาราง dispatch ของตนตรงกับไฟล์บนดิสก์ — ไม่มีสัญลักษณ์ที่ไม่มีการใช้งานหรือไม่ได้ประกาศ | ใช่ | -| `check:route-guard-membership` | ทุกเส้นทางที่สร้างโปรเซสลูกได้รับการจัดประเภทโดย `isLocalOnlyPath()` (กฎบังคับ #15/#17) | ใช่ | -| `check:test-discovery` | ไฟล์ `*.test.ts` / `*.spec.ts` ทุกไฟล์ใน repo ถูกรวบรวมโดย test runner อย่างน้อยหนึ่งตัว (ratchet: รายการไฟล์ที่ไม่มีตัวรวบรวมใน `test-discovery-baseline.json` ลดลงได้เท่านั้น) | ใช่ | -| `check:agent-skills-sync` | อาร์ติแฟกต์ agent-skills ที่สร้างขึ้นตรงกับแค็ตตาล็อกต้นทาง (ไม่มีความคลาดเคลื่อน) | -| `check:provider-asset-provenance` | โลโก้/แอสเซ็ตของผู้ให้บริการมีรายการแหล่งที่มาที่บันทึกไว้ | -| `lint:json` | ไฟล์กำหนดค่า JSON สามารถแยกวิเคราะห์ได้และเป็นไปตามกฎ lint ของ repo | -| `typecheck:core` | คอมไพล์ TypeScript โดยไม่มีข้อผิดพลาด (มีเฉพาะคำเตือนเชิงแนะนำ) | ใช่ | -| `typecheck:noimplicit:core` | `noImplicitAny` แบบเข้มงวด — สำหรับการปรับปรุงในอนาคต; จุดเรียกใช้งานเดิมจำนวนมากยังคงต้องเพิ่มคำอธิบายชนิด | **เชิงแนะนำ** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` ที่จำกัดขอบเขตไว้เฉพาะ `src/app/(dashboard)/**` (#7033) — รายการอนุญาต 27 ไฟล์ที่คัดสรรไว้ของ `typecheck:core` ไม่มี TSX ของแดชบอร์ดรวมอยู่เลย และ `next build` ก็ไม่เคยตรวจสอบชนิดของไฟล์เหล่านั้นเช่นกัน (`next.config.mjs` ตั้งค่า `ignoreBuildErrors: true`) ดังนั้นการถดถอยจากตัวระบุที่ไม่มีการอ้างอิงในบริเวณนั้น (#6625/#6909) จึงไม่ปรากฏต่อ CI โดยจะเปรียบเทียบความแตกต่างกับค่าฐานจำนวนข้อผิดพลาดที่ตรึงไว้แยกตามไฟล์/รหัส TS (`config/quality/dashboard-typecheck-baseline.json` ซึ่งใช้รูปแบบการบังคับใช้กับโค้ดที่ค้างอยู่เช่นเดียวกับ `check:known-symbols`) — เฉพาะข้อผิดพลาดใหม่ที่เกินจำนวนในค่าฐานเท่านั้นที่จะทำให้เกตล้มเหลว; ลดค่าฐานลงด้วย `--update` เมื่อแก้ไขข้อผิดพลาดเดิมได้ | ใช่ | +ทำงานกับทุก PR ที่ส่งไปยัง `main` และบล็อกการ merge เมื่อเกิดความล้มเหลว + +| สคริปต์ (`npm run ...`) | สิ่งที่ตรวจสอบ | การบล็อก | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `check:node-runtime` | เวอร์ชัน Node.js อยู่ภายในช่วงที่รองรับ | ใช่ | +| `check:cycles` | การ import แบบวนรอบทั่วทั้ง `src/` + `open-sse/` (อิง AST และ resolve `paths` ของ tsconfig แล้ว) โหมดปกติ = ให้คำแนะนำและแสดงรายการวงจร `check:cycles:ratchet` (ซึ่งเป็นสิ่งที่ CI เรียกใช้) จะบล็อกเมื่อจำนวนเกินเพดาน `metrics.cycles` ใน `quality-baseline.json` — ปัจจุบันคือ 14 โดยมี `direction: down` ดังนั้นค่าจึงลดลงได้เท่านั้น (#15159 G-01/G-02) | ใช่ (ratchet) | +| `check:route-validation:t06` | มี Zod schemas อยู่ในทุก route (นโยบาย Tier 6) | ใช่ | +| `check:any-budget:t11` | จำนวน `@ts-expect-error // any` ไม่เกินงบประมาณ (catraca ระดับ Tier 11) | ใช่ | +| `check:provider-consistency` | ผู้ให้บริการทุกรายใน `providers.ts` มีรายการที่ตรงกันใน `providerRegistry.ts` (และในทางกลับกัน ภายใน allowlist) | ใช่ | +| `check:model-lifecycle` | ตารางการกำหนดเส้นทางทั้งสามรายการที่ดูแลด้วยตนเองยังคงสอดคล้องกับสแนปช็อตวงจรชีวิตที่เช็กอินไว้ (#11503): `FITNESS_TABLE` (`taskFitness.ts`) ไม่ให้คะแนน id ที่เลิกใช้งานแล้วซึ่ง `REGISTRY` สามารถกำหนดเส้นทางไปถึงได้; เป้าหมายทั้งหมดของ `BUILT_IN_ALIASES` มีอยู่ใน `REGISTRY` และไม่มีอยู่ในสแนปช็อต id ที่เลิกใช้งานแล้ว; id ที่เลิกใช้งานแล้วทุกรายการซึ่งยังอยู่ใน `REGISTRY` จะถูกส่งต่อหรือระบุไว้ใน `allowedRetiredInCatalog`; และไม่มีต้นทางหรือปลายทางของ `DEFAULT_DEGRADATION_MAP` ที่ปรากฏว่าเลิกใช้งานแล้วในสแนปช็อตดังกล่าว การตรวจสอบนี้ไม่ได้พิสูจน์ว่าโมเดลหนึ่งกำลังให้บริการโดยต้นทางที่ใช้งานจริงอยู่ในปัจจุบัน ทำงานแบบออฟไลน์ — เปรียบเทียบกับ `config/quality/model-lifecycle.json` ซึ่งรีเฟรชด้วยตนเองโดยใช้ `npm run quality:refresh-model-lifecycle` (ใช้เครือข่าย; ไม่ได้เชื่อมเข้ากับ CI) `allowedRetiredInCatalog` เป็นกลไก ratchet เพื่อลดจำนวนรายการ: ให้เพิ่มรายการเฉพาะเมื่อมี issue สำหรับติดตามเท่านั้น | ใช่ | +| `check:fetch-targets` | ทุก `fetch("/api/...")` ใน `src/` ฝั่งไคลเอ็นต์สามารถชี้ไปยัง `route.ts` ที่มีอยู่จริงได้ | ใช่ | +| `check:deps` | dependency ทั้งหมดที่ติดตั้งได้ด้วย `npm install` จากทุกไฟล์ `package.json` ใน repo ต้องอยู่ใน `dependency-allowlist.json`; package ใหม่ที่ไม่ได้ตรึงเวอร์ชันหรืออาจเป็น slopsquatting จะถูกแจ้งเตือน | ใช่ | +| `audit:deps` | `npm audit` (รูท + electron) — ไม่มีคำแนะนำด้านความปลอดภัยระดับสูง/วิกฤต (ทับซ้อนกับ osv `check:vuln-ratchet`; ดู Rationalization Backlog) | ใช่ | +| `check:lockfile` | ความถูกต้องของ `package-lock.json` — รีจิสทรี https, แฮชตรวจสอบความสมบูรณ์, ไม่มีการเขียนทับโฮสต์ | ใช่ | +| `check:licenses` | รายการที่อนุญาตของใบอนุญาต SPDX สำหรับ dependencies ที่ใช้ใน production | ใช่ | +| `check:tracked-artifacts` | ไม่มี artifacts จากการ build / symlinks ของ `node_modules` ที่ถูก commit (ทำงานใน husky pre-commit ด้วย; pre-push ถูกตั้งใจให้ทำงานเพียงเล็กน้อย — #6716) | ใช่ | +| `check:ai-attribution` | ไม่มี trailer `Co-Authored-By` ของ AI/บอต หรือ footer ที่ระบุการสร้างโดย AI ใน commits, ชื่อ หรือเนื้อหาของ PR — กฎเคร่งครัด #16 (อยู่ในลูป fast-gates ของ `quality.yml` สำหรับ PR→`release/**` — อ่าน event payload และไม่ดำเนินการเมื่อไม่ใช่ PR — และขั้นตอนเฉพาะ PR ใน lint ของ `ci.yml` สำหรับ PR→`main`; รวมถึง hook `commit-msg` ของ husky; อนุญาตผู้เขียนร่วมที่เป็นมนุษย์; #14436) | +| `check:vitest-exclusions` | ข้อยกเว้น Vitest ทุกรายการต้องระบุ tracking issue และปรากฏอยู่ใน `config/quality/vitest-exclusions.json` (#13204) | ใช่ | +| `check:file-size` | ไม่มีไฟล์ source ใดเกินขีดจำกัดของนามสกุลนั้น (ratchet: ไฟล์ขนาดใหญ่ที่ถูกตรึงอยู่ในรายการ `frozen`) | ใช่ | +| `check:error-helper` | การตอบกลับข้อผิดพลาดใน executors/handlers ใช้ `buildErrorBody()` / `sanitizeErrorMessage()` (กฎเคร่งครัด #12) | ใช่ | +| `check:migration-numbering` | ไฟล์ Migration SQL มีหมายเลขเรียงตามลำดับ โดยไม่มีหมายเลขขาดหายหรือซ้ำกัน | ใช่ | +| `check:public-creds` | ไม่มีค่า OAuth `client_id`/`client_secret` หรือคีย์ Firebase Web แบบค่าคงที่อยู่นอก `publicCreds.ts` (กฎเคร่งครัด #11) | ใช่ | +| `check:db-rules` | ไม่มี SQL ดิบอยู่นอกโมดูล `src/lib/db/`; ไม่มีการนำเข้าแบบ barrel จาก `localDb.ts` (กฎเคร่งครัด #2/#5) | ใช่ | +| `check:known-symbols` | ตัวดำเนินการของผู้ให้บริการ กลยุทธ์การกำหนดเส้นทาง และตัวแปลที่ลงทะเบียนในตาราง dispatch ของตน สอดคล้องกับไฟล์บนดิสก์ — ไม่มีสัญลักษณ์ที่ไม่ได้ถูกอ้างอิงหรือไม่ได้ประกาศ | ใช่ | +| `check:route-guard-membership` | ทุกเส้นทางที่สร้างโพรเซสลูกได้รับการจัดประเภทโดย `isLocalOnlyPath()` (กฎเคร่งครัด #15/#17) | ใช่ | +| `check:test-discovery` | ทุกไฟล์ `*.test.ts` / `*.spec.ts` ใน repo ถูกรวบรวมโดยตัวรันการทดสอบอย่างน้อยหนึ่งตัว (ratchet: รายการไฟล์ที่ไม่ถูกรวบรวมใน `test-discovery-baseline.json` ทำได้เพียงลดลงเท่านั้น) | ใช่ | +| `check:agent-skills-sync` | อาร์ติแฟกต์ agent-skills ที่สร้างขึ้นตรงกับแค็ตตาล็อกต้นทาง (ไม่มีความคลาดเคลื่อน) | +| `check:provider-asset-provenance` | โลโก้/แอสเซ็ตของผู้ให้บริการมีรายการบันทึกแหล่งที่มา | +| `lint:json` | ไฟล์การกำหนดค่า JSON สามารถแยกวิเคราะห์ได้และเป็นไปตามกฎ lint ของรีโพ | +| `typecheck:core` | คอมไพล์ TypeScript โดยไม่มีข้อผิดพลาด (มีเพียงคำเตือนเชิงแนะนำ) | ใช่ | +| `typecheck:noimplicit:core` | ใช้ `noImplicitAny` แบบเข้มงวด — เป็นแนวทางสำหรับอนาคต โดยจุดเรียกใช้งานเดิมจำนวนมากยังคงต้องเพิ่มคำอธิบายชนิดข้อมูล | **เชิงแนะนำ** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` ที่จำกัดขอบเขตไว้เฉพาะ `src/app/(dashboard)/**` (#7033) — รายการอนุญาต 27 ไฟล์ที่คัดสรรไว้ของ `typecheck:core` ไม่มี TSX ของแดชบอร์ดรวมอยู่เลย และ `next build` ก็ไม่เคยตรวจสอบชนิดข้อมูลของไฟล์เหล่านั้นเช่นกัน (`next.config.mjs` ตั้งค่า `ignoreBuildErrors: true`) ดังนั้นรีเกรสชันของตัวระบุที่ไม่มีการอ้างอิงในส่วนนั้น (#6625/#6909) จึงไม่ปรากฏให้ CI ตรวจพบ เปรียบเทียบความแตกต่างกับค่าฐานจำนวนข้อผิดพลาดต่อไฟล์/ต่อรหัส TS ที่ตรึงไว้ (`config/quality/dashboard-typecheck-baseline.json` โดยใช้รูปแบบการบังคับใช้กับรายการที่ล้าสมัยเช่นเดียวกับ `check:known-symbols`) — เฉพาะข้อผิดพลาดใหม่ที่เกินกว่าจำนวนในค่าฐานเท่านั้นที่จะทำให้เกตล้มเหลว ให้ปรับค่าฐานลดลงด้วย `--update` เมื่อแก้ไขข้อผิดพลาดเดิมแล้ว | ใช่ | ### งาน: `quality-gate` ทำงานหลังจาก `test-coverage` และบล็อกการผสานเมื่อเกิดความล้มเหลว -| สคริปต์ | ตรวจสอบ | บล็อกการดำเนินการ | +| สคริปต์ | ตรวจสอบความถูกต้อง | การบล็อก | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `quality:collect` | สร้าง `quality-metrics.json` (จำนวนคำเตือน ESLint, coverage จากรายงาน shard ที่รวมแล้ว) | ใช่ (ทำงานก่อน ratchet) | -| `quality:ratchet` | แต่ละเมตริกใน `quality-baseline.json` ต้องไม่ถดถอย (คำเตือน ESLint ≤ baseline; coverage ≥ baseline) | ใช่ | +| `quality:collect` | สร้าง `quality-metrics.json` (จำนวนคำเตือน ESLint, coverage จากรายงาน shard ที่ผสานแล้ว) | ใช่ (ทำงานก่อน ratchet) | +| `quality:ratchet` | แต่ละ metric ใน `quality-baseline.json` ต้องไม่ถดถอย (คำเตือน ESLint ≤ baseline; coverage ≥ baseline) | ใช่ | | `check:duplication` | การทำซ้ำของโค้ด (jscpd@4) ต้องไม่เกิน baseline ใน `quality-baseline.json` | ใช่ | -| `check:complexity` | ความซับซ้อนเชิงวัฏจักรระดับไฟล์ต้องไม่เกินขีดจำกัด (กฎหลักของ ESLint `complexity` + `max-lines-per-function`) | ใช่ | -| `check:cognitive-complexity` | ratchet ความซับซ้อนเชิงการรับรู้ (`eslint-plugin-sonarjs`) — ทำงานเป็น ESLint pass แยกต่างหาก; CI เรียกใช้ทั้งสองแบบรวมเป็นขั้นตอนเดียวคือ `check:complexity-ratchets` | ใช่ | -| `check:dead-code` | ratchet สำหรับ exports / ไฟล์ที่ไม่ได้ใช้ (knip) ต้องไม่ถดถอยเมื่อเทียบกับ baseline | ใช่ | -| `check:compression-budget` | งบประมาณเบนช์มาร์กการบีบอัด — ค่าขั้นต่ำของการประหยัด token ต่อ engine ต้องไม่ถดถอย | ใช่ | -| `check:type-coverage` | ratchet เปอร์เซ็นต์โค้ดที่ระบุ type (`type-coverage`) ต้องไม่ถดถอย; โดยส่วนใหญ่ครอบคลุม `typecheck:noimplicit:core` | ใช่ | -| `check:codeql-ratchet` | จำนวนการแจ้งเตือน CodeQL ที่เปิดอยู่ต้องไม่ถดถอย (อ่านผ่าน `gh api`; ข้ามอย่างปลอดภัยเมื่อไม่มี token) — รอบการรีเฟรชและการทริกเกอร์ด้วยตนเอง: ดู "CodeQL ratchet" ด้านล่าง | ใช่ | +| `check:complexity` | cyclomatic complexity ระดับไฟล์ต้องไม่เกินเพดาน (กฎหลัก `complexity` + `max-lines-per-function` ของ ESLint) | ใช่ | +| `check:cognitive-complexity` | ratchet ของ cognitive complexity (`eslint-plugin-sonarjs`) — รัน ESLint แยกต่างหาก; CI รันทั้งสองแบบรวมเป็นขั้นตอนเดียว `check:complexity-ratchets` | ใช่ | +| `check:dead-code` | ratchet ของ export / ไฟล์ที่ไม่ได้ใช้ (knip) ต้องไม่ถดถอยเมื่อเทียบกับ baseline | ใช่ | +| `check:compression-budget` | งบประมาณ benchmark การบีบอัด — ค่าขั้นต่ำของการประหยัด token ต่อ engine ต้องไม่ถดถอย | ใช่ | +| `check:type-coverage` | ratchet ของเปอร์เซ็นต์ที่ระบุ type (`type-coverage`) ต้องไม่ถดถอย; โดยส่วนใหญ่ครอบคลุม `typecheck:noimplicit:core` | ใช่ | +| `check:codeql-ratchet` | จำนวน alert ของ CodeQL ที่ยังเปิดอยู่ต้องไม่ถดถอย (อ่านผ่าน `gh api`; ข้ามอย่างเหมาะสมเมื่อไม่มี token) — รอบการรีเฟรชและการเรียกใช้ด้วยตนเอง: ดู "CodeQL ratchet" ด้านล่าง | ใช่ | ### งาน: `quality-extended` -งานทั้งหมดเป็นเพียงคำแนะนำ (`continue-on-error: true`) ratchet ที่ใช้ npm จะทำงาน -จริง ส่วน scanner ภายนอกจะติดตั้งผ่าน `gh release download` และข้ามการทำงานเอง (exit 0) -เมื่อยังไม่พบ binary +งานทั้งหมดมีไว้เพื่อให้คำแนะนำ (`continue-on-error: true`) ratchet ที่ใช้ npm จะรันจริง +ส่วน scanner ภายนอกจะติดตั้งผ่าน `gh release download` และข้ามตัวเอง (exit 0) +เมื่อยังไม่มี binary -| สคริปต์ | ตรวจสอบ | บล็อกการดำเนินการ | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `check:circular-deps` | ไม่มี dependency แบบวนรอบ (dpdm) | **คำแนะนำ** | -| `check:bundle-size` | ขนาด bundle ต้องไม่เกินขีดจำกัด | **คำแนะนำ** | -| `check:secrets` | การสแกน secret (gitleaks) — ข้ามหากไม่พบ binary | **คำแนะนำ** | -| `check:vuln-ratchet` | ช่องโหว่ของ dependency (osv-scanner) ต้องไม่ถดถอย — ข้ามหากไม่พบ binary | **คำแนะนำ** | -| `check:workflows` | การ lint workflow (actionlint + zizmor); scanner ที่ไม่มีหรือเสีย รายงานที่ไม่ถูกต้อง หรือ baseline ของ ratchet ที่หายไปจะล้มเหลวด้วยสถานะ INCOMPLETE ส่วนสิ่งที่ตรวจพบอย่างถูกต้องจะเป็นไปตามนโยบาย strict/advisory/ratchet ที่เลือก | จำเป็นต้องดำเนินการ; zizmor ratchet บล็อก CI | -| `check:openapi-breaking` | การเปลี่ยนแปลงที่ทำให้สัญญา public API (`openapi.yaml`) ใช้งานร่วมกันไม่ได้ เมื่อเทียบกับ branch ฐาน (oasdiff) — สร้าง `openapiBreaking=N`; ข้ามหากไม่พบ oasdiff หรือไม่สามารถ resolve spec ฐานได้ | **คำแนะนำ** | +| สคริปต์ | ตรวจสอบความถูกต้อง | การบล็อก | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `check:circular-deps` | ไม่มี dependency แบบวนเป็นวงกลม (dpdm) | **คำแนะนำ** | +| `check:bundle-size` | ขนาด bundle ต้องไม่เกินเพดาน | **คำแนะนำ** | +| `check:secrets` | การสแกน secret (gitleaks) — ข้ามหากไม่มี binary | **คำแนะนำ** | +| `check:vuln-ratchet` | ช่องโหว่ของ dependency (osv-scanner) ต้องไม่ถดถอย — ข้ามหากไม่มี binary | **คำแนะนำ** | +| `check:workflows` | การ lint workflow (actionlint + zizmor); scanner ที่ไม่มี/ใช้งานไม่ได้ รายงานที่ไม่ถูกต้อง หรือ ratchet baseline ที่หายไป จะล้มเหลวด้วยสถานะ INCOMPLETE ส่วนสิ่งที่ตรวจพบซึ่งถูกต้องจะเป็นไปตามนโยบาย strict/advisory/ratchet ที่เลือก | ต้องดำเนินการ; zizmor ratchet บล็อกใน CI | +| `check:openapi-breaking` | การเปลี่ยนแปลงที่ทำให้สัญญา public API (`openapi.yaml`) ใช้งานร่วมกันไม่ได้เมื่อเทียบกับ base branch (oasdiff) — สร้าง `openapiBreaking=N`; ข้ามหากไม่มี oasdiff หรือไม่สามารถ resolve base spec ได้ | **คำแนะนำ** | ### งาน: `docs-sync-strict` -ทำงานกับทุก PR ที่ส่งไปยัง `main` และบล็อกการ merge เมื่อทำงานล้มเหลว - -| สคริปต์ | ตรวจสอบความถูกต้อง | มีผลบล็อก | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `check:docs-all` | เมตาเกตที่เรียกใช้เกตย่อยทั้ง 6 รายการด้านล่างตามลำดับ | ใช่ | -| ↳ `check:docs-sync` | ความสอดคล้องของเวอร์ชันระหว่าง CHANGELOG / OpenAPI / llm.txt | ใช่ | -| ↳ `check:docs-counts` | จำนวนที่ระบุในข้อความอธิบาย (จำนวนผู้ให้บริการ จำนวนการย้ายข้อมูล เป็นต้น) อยู่ภายในช่วง ratchet ของจำนวนจริง | ใช่ | -| ↳ `check:env-doc-sync` | ตัวแปรสภาพแวดล้อมทุกตัวใน `.env.example` มีการบันทึกไว้ในตารางเอกสาร และในทางกลับกัน | ใช่ | -| ↳ `check:deprecated-versions` | ไม่มีสตริงเวอร์ชันที่เลิกใช้แล้วในเอกสาร | ใช่ | -| ↳ `check:doc-links` | ลิงก์ markdown ภายในเอกสารชี้ไปยังไฟล์ที่มีอยู่จริง (รูปแบบ `[ข้อความ]`/`(path)`) | ใช่ | -| ↳ `check:fabricated-docs` | เส้นทาง ตัวแปรสภาพแวดล้อม คำสั่ง CLI ชื่อ hook และพาธไฟล์ที่อ้างถึงในเอกสารมีอยู่จริงในฐานโค้ด เป็นเกตบังคับเมื่อใช้ `--strict`; ล้มเหลวแบบไม่บล็อกหากไม่มีแฟล็กนี้ | ใช่ (ผ่าน `--strict` ใน CI) | -| `check:cli-i18n` | สตริงคำสั่ง CLI มีอยู่ในไฟล์ locale ของ i18n ทุกไฟล์ | ใช่ | -| `check:openapi-coverage` | ข้อกำหนด OpenAPI ครอบคลุมเส้นทางจริงอย่างน้อยตามค่าขั้นต่ำที่กำหนดด้วย ratchet | ใช่ | -| `check:openapi-security-tiers` | คำอธิบายประกอบระดับความปลอดภัยใน `openapi.yaml` สอดคล้องกับการจัดประเภทใน `routeGuard.ts` | **คำแนะนำ** | -| `check:openapi-routes` | ทุกพาธใน `openapi.yaml` เชื่อมโยงไปยัง `route.ts` ที่มีอยู่จริง (ป้องกันข้อมูลที่ถูกแต่งขึ้น) | ใช่ | -| `check:docs-symbols` | การอ้างอิง `/api/...` ทุกรายการใน `docs/**/*.md` เชื่อมโยงไปยัง `route.ts` ที่มีอยู่จริง (ป้องกันข้อมูลที่ถูกแต่งขึ้น) | ใช่ | -| `i18n translation drift` | คีย์ที่ยังไม่ได้แปลในไฟล์ locale ของ i18n — แสดงคำเตือนเท่านั้น | **คำแนะนำ** | +รันในทุก PR ที่ส่งไปยัง `main` และบล็อกการ merge เมื่อล้มเหลว + +| สคริปต์ | สิ่งที่ตรวจสอบความถูกต้อง | การบล็อก | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `check:docs-all` | เมตาเกตที่เรียกใช้เกตย่อยทั้ง 6 รายการด้านล่างตามลำดับ | ใช่ | +| ↳ `check:docs-sync` | ความสอดคล้องของเวอร์ชันระหว่าง CHANGELOG / OpenAPI / llm.txt | ใช่ | +| ↳ `check:docs-counts` | จำนวนที่ระบุในเนื้อหา (จำนวนผู้ให้บริการ จำนวนการย้ายข้อมูล ฯลฯ) อยู่ภายในช่วง ratchet ของจำนวนจริง | ใช่ | +| ↳ `check:env-doc-sync` | ตัวแปรสภาพแวดล้อมทุกตัวใน `.env.example` มีการบันทึกไว้ในตารางเอกสาร และในทางกลับกัน | ใช่ | +| ↳ `check:deprecated-versions` | ไม่มีสตริงเวอร์ชันที่เลิกใช้แล้วในเอกสาร | ใช่ | +| ↳ `check:doc-links` | ลิงก์ markdown ภายในเอกสารชี้ไปยังไฟล์ที่มีอยู่จริง (รูปแบบ `[text]`/`(path)`) | ใช่ | +| ↳ `check:fabricated-docs` | เส้นทาง ตัวแปรสภาพแวดล้อม คำสั่ง CLI ชื่อ hook และพาธไฟล์ที่อ้างถึงในเอกสารมีอยู่จริงในฐานโค้ด เป็นเกตแบบบังคับผ่าน `--strict`; หากไม่มีแฟล็กจะล้มเหลวแบบไม่บล็อก | ใช่ (ผ่าน `--strict` ใน CI) | +| `check:cli-i18n` | สตริงคำสั่ง CLI มีอยู่ในไฟล์โลเคล i18n ทั้งหมด | ใช่ | +| `check:openapi-coverage` | ข้อกำหนด OpenAPI ครอบคลุมเส้นทางจริงอย่างน้อยตามค่าขั้นต่ำที่กำหนดแบบ ratchet | ใช่ | +| `check:openapi-security-tiers` | คำอธิบายประกอบระดับความปลอดภัยใน `openapi.yaml` สอดคล้องกับการจัดประเภทใน `routeGuard.ts` | **คำแนะนำ** | +| `check:openapi-routes` | ทุกพาธใน `openapi.yaml` เชื่อมโยงไปยัง `route.ts` ที่มีอยู่จริง (ป้องกันการสร้างข้อมูลเท็จ) | ใช่ | +| `check:docs-symbols` | ทุกการอ้างอิง `/api/...` ใน `docs/**/*.md` เชื่อมโยงไปยัง `route.ts` ที่มีอยู่จริง (ป้องกันการสร้างข้อมูลเท็จ) | ใช่ | +| `i18n translation drift` | คีย์ที่ยังไม่ได้แปลในไฟล์โลเคล i18n — แสดงคำเตือนเท่านั้น | **คำแนะนำ** | ### งาน: `i18n-ui-coverage` -| สคริปต์ | ตรวจสอบความถูกต้อง | มีผลบล็อก | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check-ui-keys-coverage` (inline) | ความครอบคลุมของคีย์ i18n สำหรับ UI อยู่ที่ ≥ 65% | ใช่ | -| `check-ui-value-drift` (inline) | เมื่อมีการเขียน **ค่า** ภาษาอังกฤษใหม่ ต้องไม่มีคำแปลเก่าค้างอยู่ | ใช่ | -| `check-new-key-coverage` (inline) | คีย์ภาษาอังกฤษ **ใหม่** ได้รับการแปลในทุก locale — ไม่อนุญาตให้มีเครื่องหมาย `__MISSING__:` | ใช่ | -| `check-translation-ratio` | อัตราส่วนคำแปลจริงต่อ locale (ค่าที่เหมือนภาษาอังกฤษ / ตัวแทนข้อความ / คีย์ที่ขาดหายซึ่งอยู่นอก allowlist) ต้องไม่เกิน `config/quality/i18n-translation-baseline.json` + ค่าผ่อนผัน | **คำแนะนำ** | +| สคริปต์ | สิ่งที่ตรวจสอบความถูกต้อง | การบล็อก | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (inline) | ความครอบคลุมของคีย์ i18n สำหรับ UI ≥ 65% | ใช่ | +| `check-ui-value-drift` (inline) | เมื่อเขียน **ค่า** ภาษาอังกฤษใหม่ จะต้องไม่มีคำแปลเก่าที่ยังคงหลงเหลืออยู่ | ใช่ | +| `check-new-key-coverage` (inline) | คีย์ภาษาอังกฤษ **ใหม่** ต้องได้รับการแปลในทุกโลเคล — เครื่องหมาย `__MISSING__:` จะถูกปฏิเสธ | ใช่ | +| `check-translation-ratio` | อัตราส่วนคำแปลจริงต่อโลเคล (รายการที่เหมือนกับภาษาอังกฤษ / เป็นตัวยึดตำแหน่ง / ขาดหายไปซึ่งอยู่นอกรายการอนุญาต) ต้องไม่เกิน `config/quality/i18n-translation-baseline.json` + ค่าผ่อนผัน | **คำแนะนำ** | -ต้องใช้ `fetch-depth: 0` — เกตตรวจจับความคลาดเคลื่อนของค่าใช้ diff ระหว่าง `en.json` กับ merge base +ต้องใช้ `fetch-depth: 0` — เกต value-drift จะเปรียบเทียบความแตกต่างของ `en.json` กับฐานการผสาน -#### `check-ui-value-drift` — เกตตรวจจับคำแปลเก่าค้าง +#### `check-ui-value-drift` — เกตตรวจจับคำแปลที่ล้าสมัย -ตรวจจับการถดถอยของ i18n รูปแบบหนึ่งที่เกตอื่นไม่สามารถตรวจพบได้ในเชิงโครงสร้าง: ค่า -ภาษาอังกฤษถูกเขียนใหม่ แต่คำแปลที่อิงจากภาษาอังกฤษเวอร์ชัน_ก่อนหน้า_ยังคงอยู่ ทำให้ -ผู้ใช้ที่ไม่ได้ใช้ภาษาอังกฤษยังคงอ่านข้อความที่เขียนอย่างมั่นใจแต่ไม่ถูกต้องอีกต่อไป +ตรวจจับการถดถอยของ i18n รูปแบบหนึ่งที่เกตอื่นไม่สามารถตรวจพบได้ในเชิงโครงสร้าง กล่าวคือ เมื่อค่า +ภาษาอังกฤษถูกเขียนใหม่ แต่คำแปลที่อ้างอิงจากภาษาอังกฤษฉบับ_ก่อนหน้า_ยังคงอยู่ ทำให้ +ผู้ใช้ที่ไม่ได้ใช้ภาษาอังกฤษยังคงอ่านข้อความที่ดูน่าเชื่อถือแต่ไม่ถูกต้องอีกต่อไป -ปัญหานี้เคยถูกปล่อยใช้งานจริง `oauthModal.googleOAuthWarning` ถูกเขียนใหม่เมื่อเพิ่มตัวช่วย -เข้าสู่ระบบ Antigravity (#5203); **39 จาก 43 locale** ยังคงมีข้อความที่บอกผู้ดูแลระบบให้ "คัดลอก -URL แบบเต็มแล้ววางไว้ด้านล่าง" — ขั้นตอนที่ไม่สามารถดำเนินการจนเสร็จสำหรับผู้ให้บริการรายนั้น ปัญหานี้ -ไม่มีใครสังเกตเห็นจนถึง #8463 เนื่องจาก: +ปัญหานี้เกิดขึ้นจริงในรุ่นที่เผยแพร่ `oauthModal.googleOAuthWarning` ถูกเขียนใหม่เมื่อมีการเพิ่มตัวช่วย +เข้าสู่ระบบ Antigravity (#5203); **39 จาก 43 โลเคล** ยังคงมีข้อความที่บอกผู้ดูแลให้ "คัดลอก +URL แบบเต็มแล้ววางไว้ด้านล่าง" — ซึ่งเป็นขั้นตอนที่ไม่สามารถดำเนินการจนเสร็จสิ้นสำหรับผู้ให้บริการรายนั้นได้ ปัญหานี้ +ไม่มีใครสังเกตเห็นจนกระทั่ง #8463 เนื่องจาก: -- `sync-ui-keys` เติมเฉพาะคีย์ที่ **ไม่มีอยู่** เท่านั้น ไม่เคยเติมคีย์ที่ **ล้าสมัย**; -- `check-ui-keys-coverage` นับเพียงว่า _มี_ คีย์อยู่หรือไม่ ดังนั้นคำแปลเก่าค้างจึงถูกนับว่าครอบคลุมแล้ว; +- `sync-ui-keys` เติมคีย์ย้อนหลังเฉพาะคีย์ที่ **ไม่มีอยู่** เท่านั้น ไม่ใช่คีย์ที่ **ล้าสมัย**; +- `check-ui-keys-coverage` นับการ_มีอยู่_ของคีย์ ดังนั้นคำแปลที่ล้าสมัยจึงถูกนับว่าครอบคลุมแล้ว; - `check-translation-drift` ติดตามสำเนาเอกสาร `docs/i18n//**.md` — - แต่ไม่เคยอ่าน `src/i18n/messages/*.json` เป็นเกตบังคับในงาน `docs-sync-strict` ตั้งแต่การ - ซิงค์ใหม่เมื่อ 2026-09: แก้ไขเอกสารหลัก → `npm run i18n:run -- --files=` (ระดับส่วน ประหยัดทรัพยากร) + แต่ไม่เคยอ่าน `src/i18n/messages/*.json` บล็อกในงาน `docs-sync-strict` ตั้งแต่การซิงค์ใหม่ + 2026-09: แก้ไขเอกสารหลัก → `npm run i18n:run -- --files=` (ระดับส่วน ประหยัดทรัพยากร) -**ตรวจจับความแตกต่างโดยไม่อิง baseline** ระบบจะเปรียบเทียบ `en.json` ณ merge base กับ -working tree สำหรับทุกคีย์ที่ค่าภาษาอังกฤษเปลี่ยนแปลง locale ใดก็ตามที่ยังคงมี -คำแปลเดิมซึ่งไม่ได้รับการแก้ไขจะถือว่าล้าสมัย วิธีนี้จงใจ **ตรึงหนี้เดิมที่มีอยู่** — diff -ไม่สามารถบอกได้ว่าคำแปลที่มีมานานนั้นมาจากข้อความภาษาอังกฤษเก่าเวอร์ชันใด ดังนั้น gate จึงตรวจสอบ -เฉพาะสิ่งที่การเปลี่ยนแปลงปัจจุบันแตะต้องเท่านั้น ทางเลือกอื่น (baseline แบบแฮชต่อคีย์) จะทำให้ต้องมี -ไฟล์ที่สร้างขึ้นขนาดประมาณ 600 KB ซึ่งใหญ่กว่า baseline ที่มีอยู่และใหญ่ที่สุดถึง 3 เท่า และจะเปลี่ยนแปลงในทุก i18n PR +**รับรู้ความแตกต่าง ไม่ได้อิง baseline** โดยจะเปรียบเทียบ `en.json` ณ merge base กับ +working tree สำหรับทุก key ที่ค่า English เปลี่ยนแปลง locale ใดก็ตามที่ยังคงมี +คำแปลเดิมที่ไม่ได้แก้ไขจะถือว่าล้าสมัย วิธีนี้ตั้งใจ **ตรึงหนี้เดิมที่มีอยู่** — diff +ไม่สามารถระบุได้ว่าคำแปลที่มีมานานแปลมาจาก English เวอร์ชันเก่าใด ดังนั้น gate จึงตรวจสอบ +เฉพาะสิ่งที่การเปลี่ยนแปลงปัจจุบันแตะต้องเท่านั้น ทางเลือกอื่น (baseline แบบ hash ต่อ key) จะทำให้ต้องมี +ไฟล์ที่สร้างขึ้นขนาดประมาณ 600 KB ซึ่งใหญ่กว่า baseline ที่มีอยู่ขนาดใหญ่ที่สุด 3 เท่า และเปลี่ยนแปลงทุกครั้งที่มี i18n PR มีสองวิธีที่จะทำให้ผ่าน: 1. อัปเดตคำแปลที่ได้รับผลกระทบ หรือ -2. ตั้งค่าเป็น `__MISSING__:` — จากนั้น runtime จะส่งคืนข้อความภาษาอังกฤษที่แก้ไขแล้ว - (`src/i18n/request.ts::deepMergeFallback`, #7258) และคีย์นั้นจะถูกเพิ่มเข้าคิวเพื่อรอการแปล +2. ตั้งค่าเป็น `__MISSING__:` — จากนั้น runtime จะให้บริการ English ที่แก้ไขแล้ว + (`src/i18n/request.ts::deepMergeFallback`, #7258) และนำ key เข้าคิวเพื่อรอการแปล -หาก **ความหมาย** ของข้อความเปลี่ยนไป ควรเลือก **เปลี่ยนชื่อคีย์**: คีย์ใหม่จะไม่สามารถรับช่วง +หาก **ความหมาย** ของ string เปลี่ยนไป ควรเลือก **เปลี่ยนชื่อ key**: key ใหม่ไม่สามารถรับช่วง คำแปลที่ล้าสมัยได้ นี่คือรูปแบบที่ #8463 ใช้ ```bash -npm run i18n:check-value-drift # เข้มงวด (แบบที่ CI เรียกใช้) +npm run i18n:check-value-drift # เข้มงวด (สิ่งที่ CI เรียกใช้) npm run i18n:check-value-drift:warn # รายงานเท่านั้น BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -จบการทำงานด้วยรหัส 0 พร้อม `SKIP reason=base-unresolved` เมื่อไม่สามารถอ่านแค็ตตาล็อกฐานได้ (shallow +ออกด้วยสถานะ 0 พร้อม `SKIP reason=base-unresolved` เมื่อไม่สามารถอ่าน catalog ฐานได้ (shallow clone ที่ไม่มี base ref) ซึ่งสอดคล้องกับ `check-openapi-breaking` ### งาน: `i18n` -เมทริกซ์การตรวจสอบ i18n แบบเต็ม (หนึ่งงานต่อ locale) ทั้งงานมีสถานะเป็นคำแนะนำ +เมทริกซ์การตรวจสอบ i18n แบบเต็ม (หนึ่งงานต่อ locale) งานทั้งหมดเป็นเพียงคำแนะนำ -| สคริปต์ | สิ่งที่ตรวจสอบ | การบล็อก | -| ------------------------------- | ----------------------------- | -------------------------------------------------- | -| `validate_translation.py quick` | ความครบถ้วนของคำแปลต่อ locale | **คำแนะนำ** (`continue-on-error: true` กับทั้งงาน) | +| สคริปต์ | ตรวจสอบ | การบล็อก | +| ------------------------------- | --------------------------------- | ----------------------------------------------------- | +| `validate_translation.py quick` | ความครบถ้วนของคำแปลในแต่ละ locale | **คำแนะนำ** (`continue-on-error: true` สำหรับทั้งงาน) | ### งาน: `pr-test-policy` -ทำงานเฉพาะใน pull request +ทำงานเฉพาะบน pull request -| สคริปต์ | สิ่งที่ตรวจสอบ | การบล็อก | +| สคริปต์ | ตรวจสอบ | การบล็อก | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | PR ที่เปลี่ยนแปลงโค้ด production ใน `src/`, `open-sse/`, `electron/` หรือ `bin/` ต้องเพิ่มหรืออัปเดตการทดสอบ (กฎบังคับ #8) | ใช่ | -| `check:test-masking` | ไฟล์ทดสอบที่เปลี่ยนแปลงต้องไม่ลดจำนวน assert สุทธิหรือเพิ่มสัจนิรันดร์ `assert.ok(true)` | ใช่ | -| `check:pr-evidence` | เนื้อหา PR ต้องอ้างอิงหลักฐานการทดสอบ/VPS สำหรับการเปลี่ยนแปลง (ทำให้กฎบังคับ #18 เป็นระบบอัตโนมัติด้วยการ grep ข้อความใน PR — เปราะบาง โปรดดู Backlog) | ใช่ | +| `check:pr-test-policy` | PR ที่เปลี่ยน production code ใน `src/`, `open-sse/`, `electron/` หรือ `bin/` ต้องเพิ่มหรืออัปเดต test (กฎตายตัว #8) | ใช่ | +| `check:test-masking` | ไฟล์ test ที่เปลี่ยนแปลงต้องไม่ลดจำนวน assert สุทธิหรือเพิ่ม tautology แบบ `assert.ok(true)` | ใช่ | +| `check:pr-evidence` | เนื้อหา PR อ้างอิงหลักฐานจาก test/VPS สำหรับการเปลี่ยนแปลงนั้น (ทำให้กฎตายตัว #18 เป็นกลไกอัตโนมัติด้วยการ grep ข้อความใน PR — เปราะบาง โปรดดู Backlog) | ใช่ | ### งาน: `test-vitest` ทำงานหลัง `build` และบล็อกการ merge เมื่อล้มเหลว -| ชุดการทดสอบ | สิ่งที่ตรวจสอบ | การบล็อก | -| ---------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | เซิร์ฟเวอร์ MCP (110 เครื่องมือ), autoCombo, แคช — ตัวรัน vitest | ใช่ | -| `test:vitest:ui` | การทดสอบคอมโพเนนต์ UI — ตัวรัน vitest | **บล็อก** — ความล้มเหลวที่มีอยู่ก่อนแล้วถูกยกเว้นไว้อย่างชัดเจนใน `vitest.config.ts`; ความล้มเหลวใหม่จะทำให้งานล้มเหลว | +| ชุดทดสอบ | ตรวจสอบ | การบล็อก | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP server (110 tools), autoCombo, cache — ตัวรัน vitest | ใช่ | +| `test:vitest:ui` | test สำหรับ UI component — ตัวรัน vitest | **บล็อก** — failure ที่มีอยู่ก่อนถูกยกเว้นไว้อย่างชัดเจนใน `vitest.config.ts`; failure ใหม่จะทำให้งานล้มเหลว | -### เวิร์กโฟลว์รายคืน (ตามกำหนดเวลา, เป็นคำแนะนำ) +### Workflow รายคืน (ตามกำหนดเวลา, เป็นคำแนะนำ) -เวิร์กโฟลว์เหล่านี้ทำงานตามกำหนดเวลา cron (และ `workflow_dispatch`) โดยจะไม่ทำงานใน PR ทั้งหมดมีสถานะเป็นคำแนะนำ +รายการเหล่านี้ทำงานตามกำหนดเวลา cron (และ `workflow_dispatch`) โดยไม่ทำงานบน PR และทั้งหมดเป็นเพียงคำแนะนำ -| เวิร์กโฟลว์ | สิ่งที่ตรวจสอบ | การบล็อก | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `nightly-property` | การทดสอบ property ด้วย fast-check โดยใช้ seed แบบสุ่มและจำนวนรอบสูง | **คำแนะนำ** | -| `nightly-resilience` | gate ตรวจสอบการเติบโตของ heap, การฉีดความผิดพลาดแบบ chaos, การทดสอบโหลด/soak ด้วย k6 | **คำแนะนำ** | -| `nightly-llm-security` | การป้องกัน injection ด้วย promptfoo (โหมดบล็อก) + โพรบ garak (ข้ามเมื่อไม่มี provider secret) | **คำแนะนำ** | -| `nightly-schemathesis` | การ fuzz สัญญา OpenAPI (schemathesis) กับ OmniRoute ที่ทำงานอยู่โดยใช้ `docs/openapi.yaml` — เปิดเผยการละเมิดข้อกำหนด / ข้อผิดพลาด 500 ที่ไม่ได้รับการจัดการ (ระยะ 8 B.4) | **คำแนะนำ** | -| `nightly-mutation` | คะแนนการทดสอบ mutation ของ Stryker บนเลน unit ที่รวดเร็ว — mutant ที่รอดเผยให้เห็น assert ที่อ่อนแอ | **คำแนะนำ** | -| `nightly-compat` | เมทริกซ์ความเข้ากันได้ของ Node engine ครอบคลุมช่วง `engines.node` ที่รองรับ | **คำแนะนำ** | +| Workflow | ตรวจสอบ | การบล็อก | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| `nightly-property` | property test ด้วย fast-check โดยใช้ seed แบบสุ่มและจำนวนรอบการทำงานสูง | **คำแนะนำ** | +| `nightly-resilience` | gate ตรวจการเติบโตของ heap, การฉีด fault แบบ chaos, การทดสอบ load/soak ด้วย k6 | **คำแนะนำ** | +| `nightly-llm-security` | ตัวป้องกัน injection ของ promptfoo (โหมด block) + probe ของ garak (ข้ามเมื่อไม่มี provider secret) | **คำแนะนำ** | +| `nightly-schemathesis` | การ fuzz สัญญา OpenAPI (schemathesis) กับ OmniRoute ที่ทำงานอยู่ โดยใช้ `docs/openapi.yaml` — เปิดเผยการละเมิด spec / 500 ที่ไม่ได้รับการจัดการ (Fase 8 B.4) | **คำแนะนำ** | +| `nightly-mutation` | คะแนน mutation testing ของ Stryker บน lane unit แบบเร็ว — mutant ที่รอดเผยให้เห็น assert ที่อ่อนแอ | **คำแนะนำ** | +| `nightly-compat` | เมทริกซ์ความเข้ากันได้ของ Node engine ครอบคลุมช่วง `engines.node` ที่รองรับ | **คำแนะนำ** | --- @@ -535,43 +535,43 @@ allowlist ที่เพิ่มขึ้นเรื่อย ๆ เป็ --- -## รายการงานค้างสำหรับการปรับให้มีเหตุผล (การทบทวน ROI — ระยะ 9 รอบ 3) +## รายการงานค้างสำหรับการปรับปรุงให้มีเหตุผล (การทบทวน ROI — ระยะ 9 รอบ 3) -รายการนี้ได้รับการตรวจสอบเทียบกับ `ci.yml` เมื่อ 2026-06-17 (เวอร์ชันก่อนหน้านี้ไม่ได้รวม +รายการนี้ได้รับการตรวจสอบเทียบกับ `ci.yml` เมื่อ 2026-06-17 (เวอร์ชันก่อนหน้านี้ไม่ได้ระบุ `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`) การทบทวน ROI ของชุดที่ตรวจสอบแล้ว -ระบุรายการที่อาจปรับให้มีเหตุผลดังต่อไปนี้ **การรวมเป็นการเปลี่ยนแปลง CI -เชิงกล ส่วนการสลับ/นำออกเป็นการตัดสินใจเชิงนโยบายที่สงวนไว้ให้ผู้ดำเนินการ** ขณะนี้ยังไม่มีการนำ -รายการด้านล่างไปใช้ +`check:codeql-ratchet`, `check:pr-evidence`) การทบทวน ROI ของชุดรายการที่ตรวจสอบแล้ว +พบตัวเลือกสำหรับการปรับปรุงให้มีเหตุผลดังต่อไปนี้ **การรวมเป็นการเปลี่ยนแปลง CI +เชิงกล ส่วนการสลับ/ยกเลิกเป็นการตัดสินใจเชิงนโยบายที่สงวนไว้สำหรับผู้ปฏิบัติการ** รายการด้านล่าง +ยังไม่มีการนำไปใช้ -**รายการที่ยังไม่ได้จัดทำเอกสารไว้ข้างต้นเช่นกัน** (เป็นเพียงคำแนะนำ สัญญาณต่ำ): งาน `docs-lint` +**รายการที่ยังไม่ได้บันทึกไว้ข้างต้นด้วย** (เชิงแนะนำ, สัญญาณต่ำ): งาน `docs-lint` (markdownlint + Vale โดยทั้งงานตั้งค่า `continue-on-error`) และเวิร์กโฟลว์สแกนเนอร์แบบแยกเดี่ยว `semgrep.yml` / `codeql.yml` / `scorecard.yml` ค่า `semgrepFindings: 0` อยู่ใน -`quality-baseline.json` แต่ยังไม่ได้เชื่อมเข้ากับ ratchet แบบบล็อกใน `ci.yml` — ปัจจุบันเมตริกนี้ -ไม่ได้ถูกใช้งาน - -### รวม / ขจัดรายการซ้ำ (เชิงกล ความเสี่ยงต่ำกว่า) - -แต่ละรายการได้รับการตรวจสอบกับสถานะ gate ที่ใช้งานจริงเมื่อ 2026-06-17 (เชื่อใจแต่ต้องตรวจสอบ); -การรวมหลายรายการที่ดู “ชัดเจน” กลับพบว่าซ่อนหนี้ทางเทคนิคไว้ และ **ไม่สามารถนำมาแทนที่ได้อย่างเรียบร้อย** - -- **`check:docs-sync` ทำงานสองครั้ง** — ทำงานแบบแยกเดี่ยวในงาน `lint` และทำงานอีกครั้งภายใน `check:docs-all` (`docs-sync-strict`) รวมถึงใน husky pre-commit hook ✅ **เสร็จสิ้น** — นำการเรียกใช้แบบแยกเดี่ยวใน `lint` ออกแล้ว -- **การสแกน CVE** — ❌ **ไม่สามารถรวมได้อย่างเรียบร้อย** `audit:deps` จะล้มเหลวทันทีเมื่อพบ CVE ระดับ high/critical; `check:vuln-ratchet` (osv) จะล้มเหลวเฉพาะเมื่อเกิด _การถดถอย_ เมื่อเทียบกับ baseline (ปัจจุบันมีระดับ MODERATE 1 รายการ) ความหมายแตกต่างกัน — การนำ `audit:deps` ออกจะทำให้สูญเสีย gate แบบสัมบูรณ์สำหรับระดับ high/critical ให้คงทั้งสองรายการไว้ -- **การตรวจหาวงจร** — ❌ **ไม่สามารถรวมได้อย่างเรียบร้อย** `check:circular-deps` (dpdm) รายงาน **91 วงจร** (นี่คือสาเหตุที่เป็นเพียงคำแนะนำ); ไม่สามารถเลื่อนให้เป็นแบบบล็อกได้โดยไม่แก้ไขวงจรเหล่านั้นก่อน และมีขอบเขตกว้างกว่า `check:cycles` ที่ได้รับการคัดสรรและมีสถานะผ่าน ให้คง `check:cycles` เป็นแบบบล็อกไว้ ส่วนการแก้ไขวงจร dpdm ทั้ง 91 รายการเป็นงานค้างอีกชุดหนึ่ง -- **ความซับซ้อน** — ✅ **เสร็จสิ้น** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): เดินตรวจ ESLint เพียงรอบเดียว นับตาม ruleId เพื่อให้ baseline ของ cyclomatic+max-lines และ cognitive ยังคงแยกจากกัน; ยังคงเก็บ `check:complexity` / `check:cognitive-complexity` แต่ละรายการไว้สำหรับ `--update` ในเครื่อง -- **การป้องกันการสร้างข้อมูลเท็จของ `/api`** — ✅ **เสร็จสิ้น** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): จัดทำบัญชีรายการ FS ของ `src/app/api` เพียงครั้งเดียว โดย openapi-routes + docs-symbols ยังคงรายงานแยกจากกัน; ยังคงเก็บแต่ละรายการไว้สำหรับการเรียกใช้ในเครื่อง -- **`check:node-runtime` ทำงานใน 11 งาน** — ⚠️ **ROI ต่ำ** แต่ละงานอยู่บน runner แยกกัน และการตรวจสอบใช้เวลาน้อยกว่า 1 วินาที; ประหยัดเวลารวมได้ประมาณ 10 วินาที แต่ต้องแลกกับการสูญเสียตัวป้องกันราคาถูกในแต่ละงาน ไม่คุ้มกับความวุ่นวายจากการเปลี่ยนแปลง -- **`typecheck:noimplicit:core` ใน CI lint** — ✅ **นำออกจากงาน lint แล้ว** (เดิมเป็นคำแนะนำโดยตั้งค่า `continue-on-error`); พื้นผิวประเภทข้อมูลแบบบล็อกคือ `typecheck:core` + `check:type-coverage` ยังคงเก็บสคริปต์ในเครื่องไว้ - -### สลับ / ตัดสินใจ (นโยบายของผู้ดำเนินการ) - -- `check:openapi-security-tiers` (คำแนะนำ) — ❌ **ไม่สามารถสลับได้อย่างเรียบร้อย** คำสั่งจบการทำงานด้วยค่า 0 แต่เตือนว่า route ของ `traffic-inspector` หลายรายการภายใต้ `LOCAL_ONLY_API_PREFIXES` ไม่มี annotation `x-loopback-only: true` การบังคับใช้จำเป็นต้องเพิ่ม annotation เหล่านั้นใน `openapi.yaml` ก่อน -- `typecheck:noimplicit:core` (คำแนะนำ) — ถูกแทนที่โดย ratchet แบบบล็อก `check:type-coverage` ไปแล้วเป็นส่วนใหญ่ ให้สลับเป็น ratchet หรือนำการรัน `tsc` รอบที่สองซึ่งซ้ำซ้อนออก -- `test:vitest:ui` (ขณะนี้ **เป็นแบบบล็อก**) — failure ที่มีอยู่ก่อนถูกยกเว้นไว้อย่างชัดเจนใน `vitest.config.ts` พร้อมความคิดเห็นติดตาม `// #8618`; failure ใหม่จะทำให้งานล้มเหลว -- `check:secrets` (gitleaks, ratchet แบบบล็อกซึ่งตรึงไว้ที่ false-positive ที่มีเอกสารกำกับ 3 รายการ) — เพิ่มทั้ง 3 รายการใน allowlist เพื่อให้เหลือ 0 หรือลดระดับเป็นคำแนะนำ ซ้ำซ้อนกับ secret-scanning แบบเนทีฟของ GitHub + `check:public-creds` -- `check:pr-evidence` (แบบบล็อก, grep ข้อความร้อยแก้วใน PR body) — มีความเสี่ยงเกิด false-positive สูง; หากนำออกจะทำให้การบังคับใช้ Hard Rule #18 อ่อนแอลง ดังนั้นนี่จึงเป็นการตัดสินใจเชิงนโยบายอย่างแท้จริง -- `semgrep` (คำแนะนำแบบแยกเดี่ยว) — ซ้ำซ้อนกับ CodeQL สำหรับกลุ่ม OWASP; เชื่อม baseline เข้ากับ ratchet หรือนำออก +`quality-baseline.json` แต่ยังไม่ได้เชื่อมต่อกับ ratchet แบบบล็อกใน `ci.yml` — ปัจจุบันเมตริกนี้ +ไม่มีการใช้งาน + +### รวม / ขจัดความซ้ำซ้อน (เชิงกล, ความเสี่ยงต่ำกว่า) + +ตัวเลือกแต่ละรายการได้รับการตรวจสอบกับสถานะ gate ที่ใช้งานจริงเมื่อ 2026-06-17 (เชื่อใจแต่ต้องตรวจสอบ) +การรวมหลายรายการที่ดู “ชัดเจน” กลับพบว่าซ่อนหนี้ทางเทคนิคไว้ และ **ไม่ใช่** การแทนที่ที่ทำได้โดยตรงอย่างปลอดภัย + +- **`check:docs-sync` ทำงานสองครั้ง** — ทำงานแยกเดี่ยวในงาน `lint` และทำงานอีกครั้งภายใน `check:docs-all` (`docs-sync-strict`) รวมถึงใน husky pre-commit hook ✅ **เสร็จแล้ว** — นำการเรียกใช้แบบแยกเดี่ยวใน `lint` ออกแล้ว +- **การสแกน CVE** — ❌ **ไม่ใช่การรวมที่ทำได้โดยตรงอย่างปลอดภัย** `audit:deps` ล้มเหลวทันทีเมื่อพบ CVE ระดับสูง/วิกฤตใด ๆ ส่วน `check:vuln-ratchet` (osv) จะล้มเหลวเฉพาะเมื่อมี _การถดถอย_ เมื่อเทียบกับ baseline (ปัจจุบันมีระดับ MODERATE 1 รายการ) ความหมายต่างกัน — การนำ `audit:deps` ออกจะทำให้สูญเสีย gate แบบค่าสัมบูรณ์สำหรับระดับสูง/วิกฤต ให้คงทั้งสองรายการไว้ +- **การตรวจจับวงจร** — ✅ **เสร็จแล้ว** (#15159 G-01/G-02) ข้อความเดิมในส่วนนี้เรียก `check:cycles` ว่าเป็น gate ที่ “ผ่านและคัดสรรมาแล้ว” และให้เหตุผลว่าควรคงการบล็อกไว้ เนื่องจาก `check:circular-deps` (dpdm) รายงานวงจร 91 รายการ แต่การผ่านนั้นเป็น **ผลผ่านลวง**: `check:cycles` สแกนไดเรกทอรีย่อย 5 รายการ (450 ไฟล์) จับคู่เฉพาะ `import|export … from` แบบสแตติก และตัด specifier ที่เป็น `@/` และ `@omniroute/open-sse/` ทั้งหมดออก จึงไม่สามารถตรวจพบวงจรจาก dynamic import + alias ซึ่งเป็นวงจรส่วนใหญ่ใน repo ได้ แก้ไขแล้ว: ขณะนี้ gate ตรวจไล่ผ่าน `src` + `open-sse` (5023 ไฟล์), รวบรวม specifier จาก TypeScript AST (ดังนั้น `import("…")` จะถูกนับ แต่ `typeof import("…")` ในตำแหน่งประเภทจะไม่ถูกนับ) และ resolve `paths` ของ tsconfig โดยพบวงจร **14** รายการ ไม่ใช่ 0 เนื่องจากไม่สามารถแก้ไขวงจรเดิมทั้ง 14 รายการใน gate PR ได้ ขณะนี้ `check:cycles` จึงเป็น **ratchet** (`--ratchet`, เพดาน `metrics.cycles.value = 14` ใน `quality-baseline.json`, `direction: down`) — โดยจะบล็อก _การถดถอย_ ใด ๆ และจำนวนวงจรจะลดลงได้เท่านั้น CI เรียกใช้ `npm run check:cycles:ratchet` การทยอยลดจำนวนจะดำเนินไปพร้อมกับ **A-01** ส่วน `check:circular-deps` (dpdm) ยังคงเป็นรายการเชิงแนะนำเพื่อใช้เป็นความเห็นที่สองในขอบเขตที่กว้างกว่า +- **ความซับซ้อน** — ✅ **เสร็จแล้ว** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ตรวจไล่ด้วย ESLint เพียงรอบเดียว และนับตาม ruleId เพื่อให้ baseline ของ cyclomatic+max-lines และ cognitive ยังคงเป็นอิสระจากกัน ส่วน `check:complexity` / `check:cognitive-complexity` แต่ละรายการยังคงไว้สำหรับ `--update` ภายในเครื่อง +- **การป้องกันข้อมูลหลอนของ `/api`** — ✅ **เสร็จแล้ว** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): จัดทำรายการ FS ของ `src/app/api` เพียงครั้งเดียว โดย openapi-routes + docs-symbols ยังคงรายงานแยกกัน และยังคงรายการแต่ละรายการไว้สำหรับการเรียกใช้ภายในเครื่อง +- **`check:node-runtime` ทำงานใน 11 งาน** — ⚠️ **ROI ต่ำ** แต่ละงานใช้ runner แยกกันและการตรวจสอบใช้เวลาน้อยกว่า 1 วินาที เวลาที่ประหยัดได้รวมประมาณ 10 วินาที ซึ่งไม่คุ้มกับการสูญเสียตัวป้องกันราคาถูกในแต่ละงานและความวุ่นวายจากการเปลี่ยนแปลง +- **`typecheck:noimplicit:core` ใน CI lint** — ✅ **นำออกจากงาน lint แล้ว** (เดิมเป็นเชิงแนะนำโดยใช้ `continue-on-error`) พื้นผิวประเภทที่บล็อกคือ `typecheck:core` + `check:type-coverage` โดยยังคงสคริปต์สำหรับใช้งานภายในเครื่องไว้ + +### สลับ / ตัดสินใจ (นโยบายของผู้ปฏิบัติการ) + +- `check:openapi-security-tiers` (เชิงแนะนำ) — ❌ **ไม่สามารถสลับได้โดยตรงอย่างปลอดภัย** แม้จะจบการทำงานด้วย 0 แต่เตือนว่า route หลายรายการของ `traffic-inspector` ภายใต้ `LOCAL_ONLY_API_PREFIXES` ไม่มี annotation `x-loopback-only: true` การบังคับใช้จำเป็นต้องเพิ่ม annotation เหล่านั้นใน `openapi.yaml` ก่อน +- `typecheck:noimplicit:core` (เชิงแนะนำ) — ถูกแทนที่โดย ratchet `check:type-coverage` ที่บล็อกอยู่เป็นส่วนใหญ่แล้ว ให้สลับเป็น ratchet หรือนำการรัน `tsc` รอบที่สองซึ่งซ้ำซ้อนออก +- `test:vitest:ui` (ขณะนี้ **บล็อก**) — ความล้มเหลวที่มีอยู่เดิมถูกยกเว้นไว้อย่างชัดเจนใน `vitest.config.ts` พร้อมความคิดเห็นติดตาม `// #8618` ส่วนความล้มเหลวใหม่จะทำให้งานล้มเหลว +- `check:secrets` (gitleaks ซึ่งเป็น ratchet แบบบล็อกที่ตรึงไว้ที่ผลบวกลวงที่มีเอกสารกำกับ 3 รายการ) — เพิ่มทั้ง 3 รายการลงใน allowlist เพื่อให้เหลือ 0 หรือลดระดับเป็นเชิงแนะนำ มีขอบเขตทับซ้อนกับการสแกน secret แบบเนทีฟของ GitHub + `check:public-creds` +- `check:pr-evidence` (บล็อก โดยค้นหาข้อความในเนื้อหา PR ด้วย grep) — มีความเสี่ยงสูงที่จะเกิดผลบวกลวง หากนำออกจะทำให้การบังคับใช้กฎตายตัวข้อที่ 18 อ่อนแอลง ดังนั้นนี่จึงเป็นการตัดสินใจเชิงนโยบายอย่างแท้จริง +- `semgrep` (แบบแยกเดี่ยวเชิงแนะนำ) — มีขอบเขตทับซ้อนกับ CodeQL สำหรับกลุ่ม OWASP ให้เชื่อม baseline ของมันเข้ากับ ratchet หรือนำออก --- diff --git a/docs/i18n/tr/CONTRIBUTING.md b/docs/i18n/tr/CONTRIBUTING.md index 5e61fa1b471..c25d111a5a3 100644 --- a/docs/i18n/tr/CONTRIBUTING.md +++ b/docs/i18n/tr/CONTRIBUTING.md @@ -397,19 +397,19 @@ Model tanımlarını `open-sse/config/providerRegistry.ts` dosyasına ekleyin. ## Pull Request Kontrol Listesi - [ ] Testler geçiyor (`npm test`) -- [ ] Lint denetimleri geçiyor (`npm run lint`) +- [ ] Lint denetimi geçiyor (`npm run lint`) - [ ] Derleme başarıyla tamamlanıyor (`npm run build`) -- [ ] Yeni herkese açık işlevler ve arayüzler için TypeScript türleri eklendi +- [ ] Yeni genel kullanıma açık fonksiyonlar ve arayüzler için TypeScript türleri eklendi - [ ] Sabit kodlanmış gizli bilgiler veya geri dönüş değerleri yok -- [ ] Herkese açık üst sağlayıcı kimlik bilgileri, sabit değerler olarak değil, `resolvePublicCred()` aracılığıyla gömüldü (bkz. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) -- [ ] Hata yanıtları `buildErrorBody()` / `sanitizeErrorMessage()` üzerinden yönlendiriliyor — yanıt gövdelerinde ham yığın izleri yok (bkz. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Kabuk komutları (`exec` / `spawn`), çalışma zamanı değerlerini dize enterpolasyonu aracılığıyla değil `env` üzerinden iletiyor -- [ ] Tüm girdiler Zod şemalarıyla doğrulanıyor -- [ ] Kullanıcıya yönelik değişiklikler için `changelog.d/{features|fixes|maintenance}/-.md` altına değişiklik günlüğü **parçası** eklendi (bkz. [`changelog.d/README.md`](./changelog.d/README.md)) — `CHANGELOG.md` dosyasını doğrudan **düzenlemeyin**; parçalar sürüm yayımlanırken birleştirilir ve PR'ler arasında hiçbir zaman çakışmaz -- [ ] Belgeler güncellendi (geçerliyse) -- [ ] Yeni CodeQL / Secret-Scanning uyarısı açılmadı veya her biri ilgili `docs/security/` belgesine atıfta bulunan teknik bir gerekçeyle kapatıldı -- [ ] Alt süreç başlatan rotalar (`/api/mcp/`, `/api/cli-tools/runtime/`), `src/server/authz/routeGuard.ts` içinde `isLocalOnlyPath()` olarak sınıflandırıldı — bkz. [Kesin Kural #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Commit mesajlarında `Co-Authored-By` alt bilgileri yok — commit'ler yalnızca depo sahibinin Git kimliği altında görünmelidir (Kesin Kural #16) +- [ ] Genel kullanıma açık üst kaynak kimlik bilgileri değişmez değer olarak değil, `resolvePublicCred()` aracılığıyla gömüldü (bkz. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)) +- [ ] Hata yanıtları `buildErrorBody()` / `sanitizeErrorMessage()` üzerinden yönlendiriliyor — yanıt gövdelerinde işlenmemiş yığın izleri yok (bkz. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Kabuk komutları (`exec` / `spawn`), çalışma zamanı değerlerini dize interpolasyonu yoluyla değil `env` aracılığıyla iletiyor +- [ ] Tüm girdiler Zod şemalarıyla doğrulandı +- [ ] Kullanıcıya yönelik değişiklikler için `changelog.d/{features|fixes|maintenance}/-.md` altında değişiklik günlüğü **parçası** eklendi (bkz. [`changelog.d/README.md`](./changelog.d/README.md)) — `CHANGELOG.md` dosyasını doğrudan düzenlemeyin; parçalar sürüm yayımlanırken birleştirilir ve PR'lar arasında hiçbir zaman çakışmaz +- [ ] Dokümantasyon güncellendi (uygunsa) +- [ ] Yeni CodeQL / Secret-Scanning uyarısı açılmadı veya her biri ilgili `docs/security/` belgesine atıfta bulunan teknik bir gerekçeyle reddedildi +- [ ] Alt süreç başlatan rotalar (`/api/mcp/`, `/api/cli-tools/runtime/`), `src/server/authz/routeGuard.ts` içindeki `isLocalOnlyPath()` kapsamında sınıflandırıldı — bkz. [Kesin Kural #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Commit mesajlarında AI/bot `Co-authored-by` son bilgileri yok (Kesin Kural #16) — çalışmalarından yararlanılan insan iş ortaklarına standart `Co-authored-by: Name ` son bilgileriyle atıfta bulunuldu --- diff --git a/docs/i18n/tr/docs/architecture/QUALITY_GATES.md b/docs/i18n/tr/docs/architecture/QUALITY_GATES.md index 29777480513..85cb9cfb044 100644 --- a/docs/i18n/tr/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/tr/docs/architecture/QUALITY_GATES.md @@ -19,217 +19,219 @@ sınıflandırması ve araçtan bağımsız çoğaltma planı için ### Aday kabulü -CI ve Quality Gates iş akışlarının her biri kararlı bir karar üretir: `Gate / CI` ve +CI ve Quality Gates iş akışlarının her biri kararlı bir sonuç üretir: `Gate / CI` ve `Gate / Quality`. Bunların sürümlendirilmiş kabul politikası, her üst akış işini zorunlu veya tavsiye niteliğinde olarak listeler. Uygulanabilir bir zorunlu iş başarılı olmalıdır: eksik, iptal edilmiş, atlanmış, beklemede olan ve bilinmeyen sonuçlar PASS -durumunu sağlayamaz. Geçerli bir yalnızca dokümantasyon veya yalnızca katalog sınıflandırması, -bir kod hattını uygulanamaz hâle getirebilir; taslak bir PR kabul edilmiş bir aday değildir. -`hotfix` etiketi kanıt gerekliliğini ortadan kaldırmaz. +durumunu sağlayamaz. Geçerli bir yalnızca dokümantasyon veya yalnızca katalog +sınıflandırması, bir kod hattını uygulanamaz hâle getirebilir; taslak PR kabul edilen +bir aday değildir. `hotfix` etiketi kanıt gerekliliğini ortadan kaldırmaz. Her iki iş akışı da PR'ları ve main/release dallarına gönderimleri, manuel tetiklemeyi ve -birleştirme grubu olaylarını kapsar. Gönderim, tetikleme ve birleştirme grubu, tam seçimi -çalıştırır. Fork'lar ve birleştirme grupları, normalde self-hosted çalıştırıcıları seçen işler -için hosted çalıştırıcıları kullanır; kullanıma sunmadan önce yeterli hosted kapasitesi -doğrulanmalıdır. - -Her JSON makbuzu, checkout yapılan SHA'yı, iş akışı çalıştırmasını ve denemesini tanımlar. -CLI, checkout/olay SHA uyuşmazlığını reddeder. İş akışı testleri, politika üyeliğini karar -işinin `needs` listesine bağlar; böylece yeni veya kaldırılmış bir hat sessizce ortadan -kaybolamaz. Makbuzlar kendi iş akışlarını kapsar; yayınlamayı, dağıtımı veya mevcut bir -tavsiye niteliğindeki tarayıcının iç işleyişini kapsamaz. Her iki kontrol adını dal -kurallarında etkinleştirmek ayrı bir idari değişikliktir; bu işlerin eklenmesi tek başına -bir dalı korumaz. +birleştirme grubu olaylarını kapsar. Gönderim, tetikleme ve birleştirme grubu tam seçimi +çalıştırır. Fork'lar ve birleştirme grupları, aksi durumda kendi kendine barındırılan +çalıştırıcıları seçecek işler için barındırılan çalıştırıcıları kullanır; kullanıma +almadan önce yeterli barındırılan kapasite doğrulanmalıdır. + +Her JSON makbuzu, kullanıma alınan SHA'yı, iş akışı çalıştırmasını ve denemeyi tanımlar. +CLI, kullanıma alınan SHA ile olay SHA'sı arasındaki uyuşmazlığı reddeder. İş akışı +testleri, politika üyeliğini sonuç işinin `needs` listesine bağlar; böylece yeni veya +kaldırılmış bir hat sessizce ortadan kaybolamaz. Makbuzlar kendi iş akışlarını kapsar; +yayınlamayı, dağıtımı veya mevcut bir tavsiye tarayıcısının iç işleyişini kapsamaz. +Dal kurallarında her iki kontrol adını etkinleştirmek ayrı bir idari değişikliktir; +bu işlerin eklenmesi tek başına bir dalı korumaz. ### Statik tarama envanteri -Sürümlendirilmiş npm takma adı envanteri ve statik tarama üyeliği +Sürümlendirilmiş npm alias envanteri ve statik tarama üyeliği `config/quality/gate-manifest.json` içinde bulunur. Betik adlarını ve tam komutları -`package.json` ile karşılaştırarak doğrulamak için `npm run check:gate-manifest` komutunu -çalıştırın; eklemeler, kaldırmalar ve komut sapmaları hem yerel kancanın hem de CI'daki -değişiklik sınıflandırma işlerinin başarısız olmasına neden olur. Bir takma ad; iş akışı işi, -matris örneği veya test vakası değildir: bu sayılar birbirinin yerine kullanılabilirmiş gibi -sunulmamalıdır. - -Seçilen takma adları çalıştırmadan incelemek için `npm run quality:scan -- --list` veya -`npm run quality:scan:fast -- --list` kullanın. Çalıştırıcı npm giriş noktasını çağırır; -dolayısıyla çalışma zamanı (yapılandırılmışsa Bun dâhil) korunur. Manifest, bu profillerin -dışındaki takma adları ayrı olarak çağrılanlar şeklinde kaydeder ve salt okunur tarama +`package.json` ile karşılaştırarak doğrulamak için `npm run check:gate-manifest` +komutunu çalıştırın; eklemeler, kaldırmalar ve komut sapmaları hem yerel hook'un hem +de CI'daki değişiklik sınıflandırma işlerinin başarısız olmasına neden olur. +Bir alias; iş akışı işi, matris örneği veya test vakası değildir: bu sayılar birbirinin +yerine kullanılabilirmiş gibi sunulmamalıdır. + +Seçilen alias'ları çalıştırmadan incelemek için +`npm run quality:scan -- --list` veya `npm run quality:scan:fast -- --list` +komutunu kullanın. Çalıştırıcı npm giriş noktasını çağırır; böylece çalışma zamanı +(yapılandırıldığı yerlerde Bun dâhil) korunur. Manifest, bu profillerin dışındaki +alias'ları ayrı olarak çağrılanlar şeklinde kaydeder ve salt okunur tarama profillerinde bakım komutları yasaktır. -Bu profiller yalnızca statik taramayı kapsar. Ürün testlerini, kapsamı, paketlemeyi, harici -kontrolleri veya bir adayın tam sürüm kabulünü doğrulamazlar. İş akışı kabulü, bağlantılı -`config/quality/admission-policy.json` ve `scripts/quality/admission-verdict.mjs` dosyalarını -kullanır. Sürüm gözlemcisi profilleri ayrı kalır; bunların uygulanabilir kontrollerini ve -makbuzlarını bağımsız olarak inceleyin. Aşağıdaki metinsel envanter bir referanstır; bir -geçidin gerçekten çalıştığının kanıtı değildir. +Bu profiller yalnızca statik taramayı kapsar. Ürün testlerini, kapsamı, paketlemeyi, +harici kontrolleri veya bir adayın tam sürüm kabulünü onaylamazlar. İş akışı kabulü, +bağlantılı `config/quality/admission-policy.json` ile +`scripts/quality/admission-verdict.mjs` dosyalarını kullanır. Release-observer +profilleri ayrı kalır; bunların uygulanabilir kontrollerini ve makbuzlarını bağımsız +olarak inceleyin. Aşağıdaki açıklamalı envanter bir referanstır; bir geçidin gerçekten +çalıştığının kanıtı değildir. -Betikler `scripts/check/` (politika geçitleri) ve `scripts/quality/` (ratchet motoru) altında -bulunur. CI için doğruluğun kaynağı `.github/workflows/ci.yml` dosyasıdır. +Betikler `scripts/check/` (politika geçitleri) ve `scripts/quality/` (ratchet motoru) +altında bulunur. CI için doğruluğun kaynağı `.github/workflows/ci.yml` dosyasıdır. ### Sürüm PR'ı hızlı yolu (`quality.yml`) -`.github/workflows/quality.yml`; main/release PR'larında, korumalı dal gönderimlerinde, -tetiklemelerde ve birleştirme gruplarında CI'ı tamamlar. PR'lar, yol filtreli hızlı kontroller -kullanır. Kalıcı olarak devre dışı bırakılmış yinelenen derleme kaldırılmıştır; gerçek -derleme/paketleme/önyükleme kontrolleri CI'da kalır. +`.github/workflows/quality.yml`; main/release PR'larında, korumalı dal +gönderimlerinde, tetiklemelerde ve birleştirme gruplarında CI'ı tamamlar. PR'lar, +yol filtreli hızlı kontrolleri kullanır. Kalıcı olarak devre dışı bırakılmış yinelenen +derleme kaldırılmıştır; gerçek derleme/paketleme/önyükleme kontrolleri CI'da kalır. | İş | Kapsam | Engelleyici | | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `Docs Gates (fast-path)` | Dokümantasyon/kod PR'ları; API dokümantasyonu referansları ve tüm dokümantasyon | Evet | -| `Fast Quality Gates` | Kod PR'ları; statik kontroller, tür denetimi, dashboard tür denetimi, etkilenen birim testleri | Evet | +| `Fast Quality Gates` | Kod PR'ları; statik kontroller, tür kontrolü, pano tür kontrolü, etkilenen birim testleri | Evet | | `Forgotten sibling tests` | Kod PR'ları; statik tüketicilere ve aday kardeş testlere kadar izlenen değiştirilmiş modüller; barrel ve dinamik içe aktarma yolları, referans verilen izin listesi istisnalarıyla birlikte tavsiye niteliğinde tanılar olarak raporlanır | **Tavsiye niteliğinde** | | `Vitest (fast-path)` | Kod PR'ları; hızlı vitest paketi | Evet | | `Unit Tests fast-path` | Kod PR'ları; 4 parçalı birim testi paketi | Evet | -| `No new ESLint warnings` | Kod PR'ları; bastırmaları dikkate alan lint koruması | Evet, fork'lar dâhil | -| `Merge integrity (changelog + generated skills)` | Taslak olmayan PR'lar; değişiklik günlüğü ve oluşturulan becerilerin eşitlemesi | Evet, fork'lar dâhil | +| `No new ESLint warnings` | Kod PR'ları; bastırma farkındalıklı lint koruması | Evet, fork'lar dâhil | +| `Merge integrity (changelog + generated skills)` | Taslak olmayan PR'lar; değişiklik günlüğü ve oluşturulan skill'lerin senkronizasyonu | Evet, fork'lar dâhil | #### Unutulan kardeş testler raporu `npm run check:forgotten-sibling-tests`, test etki haritasının arkasındaki içe aktarma çözümleyicisini yeniden kullanır. Değiştirilen her üretim modülü için, aday test -pull-request farkında bulunmadığında deterministik -`değiştirilen modül/sembol -> statik tüketici -> aday kardeş test` zincirlerini raporlar. -Markdown özeti ve JSON sonucu, herhangi bir engelleyici kullanıma sunma işleminden önce -kalibrasyon amacıyla `forgotten-sibling-tests` iş akışı yapıtı olarak saklanır. +pull request farkında bulunmadığında belirlenebilir +`değiştirilen modül/sembol -> statik tüketici -> aday kardeş test` zincirlerini +raporlar. Markdown özeti ve JSON sonucu, engelleyici nitelikte herhangi bir kullanıma +alma öncesindeki kalibrasyon için `forgotten-sibling-tests` iş akışı artifact'i olarak +saklanır. Barrel yeniden dışa aktarımları ve dinamik içe aktarımlar yalnızca çözümleme tanılamalarıdır; hiçbir zaman engelleyici bir bulgu oluşturmazlar. İncelenmiş istisnalar -`config/quality/forgotten-sibling-allowlist.json` içinde bulunur. Her girdi, tüketiciyi ve aday -testi belirtmeli, belirli bir gerekçe sunmalı ve bir GitHub issue'suna veya pull request'e bağlantı vermelidir. Hatalı biçimlendirilmiş girdiler -kapalı şekilde başarısız olur. İstisnalar, silinmiş bir aday testi veya `.skip`/`.todo` ekleyen bir diff'i baskılayamaz; +`config/quality/forgotten-sibling-allowlist.json` içinde bulunur. Her girdi, tüketici ve aday +testi adlandırmalı, belirli bir gerekçe sunmalı ve bir GitHub issue veya pull request bağlantısı içermelidir. Hatalı biçimlendirilmiş girdiler +kapalı durumda başarısız olur. İstisnalar, silinmiş bir aday testi veya `.skip`/`.todo` ekleyen bir diff'i bastıramaz; assertion zayıflatma ve diğer maskeleme işlemleri, bağımsız olarak engelleyici olan `check:test-masking` geçidinin sorumluluğunda kalır. ### İş: `lint` -`main` dalına yönelik her PR'da çalışır. Başarısızlık durumunda birleştirmeyi engeller. - -| Betik (`npm run ...`) | Doğruladığı | Engelleyici | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | -| `check:node-runtime` | Node.js sürümünün desteklenen aralıkta olması | Evet | -| `check:cycles` | Döngüsel içe aktarımlar — tüm `src/` + `open-sse/` modülleri | Evet | -| `check:route-validation:t06` | Tüm rotalarda Zod şemalarının bulunması (Tier 6 politikası) | Evet | -| `check:any-budget:t11` | `@ts-expect-error // any` sayısının bütçeyi aşmaması (Tier 11 catraca) | Evet | -| `check:provider-consistency` | `providers.ts` içindeki her sağlayıcının `providerRegistry.ts` içinde eşleşen bir girdisi vardır (ve izin listesi dahilinde bunun tersi de geçerlidir) | Evet | -| `check:model-lifecycle` | Elle sürdürülen üç yönlendirme tablosu, depoya kaydedilmiş yaşam döngüsü anlık görüntüsüyle (#11503) tutarlı kalır: `FITNESS_TABLE` (`taskFitness.ts`), `REGISTRY` tarafından yönlendirilebilen kullanımdan kaldırılmış hiçbir kimliğe puan vermez; her `BUILT_IN_ALIASES` hedefi `REGISTRY` içinde bulunur ve kullanımdan kaldırılmış kimliklerin anlık görüntüsünde yer almaz; hâlâ `REGISTRY` içinde bulunan kullanımdan kaldırılmış her kimlik yönlendirilir veya `allowedRetiredInCatalog` içinde listelenir; ayrıca hiçbir `DEFAULT_DEGRADATION_MAP` kaynağı veya hedefi bu anlık görüntüde kullanımdan kaldırılmış olarak görünmez. Bu, bir modelin şu anda çalışan bir yukarı akış tarafından sunulduğunu kanıtlamaz. Çevrimdışı — elle `npm run quality:refresh-model-lifecycle` (ağ gerektirir; CI'a bağlı değildir) komutuyla yenilenen `config/quality/model-lifecycle.json` ile karşılaştırır. `allowedRetiredInCatalog`, yalnızca azalan yönde ilerleyen bir mandaldır: yalnızca bir takip kaydıyla birlikte girdi ekleyin. | Evet | -| `check:fetch-targets` | İstemci tarafındaki `src/` içinde bulunan her `fetch("/api/...")`, gerçek bir `route.ts` dosyasına çözümlenir | Evet | -| `check:deps` | Depodaki her `package.json` genelinde `npm install` ile kurulabilen tüm bağımlılıklar `dependency-allowlist.json` içindedir; sabitlenmemiş veya yazım benzerliğinden yararlanılarak kötü niyetle adlandırılmış yeni paketler işaretlenir | Evet | -| `audit:deps` | `npm audit` (kök + electron) — yüksek/kritik düzeyde güvenlik bildirimi yoktur (osv `check:vuln-ratchet` ile örtüşür; Rationalization Backlog bölümüne bakın) | Evet | -| `check:lockfile` | `package-lock.json` bütünlüğü — https kayıt defteri, bütünlük karmaları, ana makine geçersiz kılmaları yoktur | Evet | -| `check:licenses` | Üretim bağımlılıkları için SPDX lisans izin listesi | Evet | -| `check:tracked-artifacts` | Derleme artefaktları / commit edilmiş `node_modules` sembolik bağlantıları yok (husky pre-commit sırasında da çalışır; pre-push kasıtlı olarak hafiftir — #6716) | Evet | -| `check:ai-attribution` | PR commit'lerinde, başlığında veya gövdesinde AI/bot `Co-Authored-By` son bilgisi ya da AI tarafından oluşturma alt bilgisi yok — Kesin Kural #16 (`quality.yml` içindeki PR→`release/**` hızlı kontrol döngüsünde — olay yükünü okur, PR dışında işlem yapmaz — ve PR→`main` için `ci.yml` lint işlemindeki yalnızca PR'lara özel bir adımda; ayrıca husky `commit-msg` kancasında; insan ortak yazarlarına izin verilir; #14436) | -| `check:vitest-exclusions` | Her Vitest hariç tutma kaydı bir takip sorununu belirtir ve `config/quality/vitest-exclusions.json` içinde yer alır (#13204) | Evet | -| `check:file-size` | Hiçbir kaynak dosyası uzantı başına sınırı aşmaz (kademeli sıkılaştırma: büyük dosyalar `frozen` listesinde dondurulmuştur) | Evet | -| `check:error-helper` | Yürütücülerdeki/işleyicilerdeki hata yanıtları `buildErrorBody()` / `sanitizeErrorMessage()` kullanır (Kesin Kural #12) | Evet | -| `check:migration-numbering` | Migration SQL dosyaları boşluk veya yinelenen numara olmadan sıralı biçimde numaralandırılmıştır | Evet | -| `check:public-creds` | `publicCreds.ts` dışında değişmez OAuth `client_id`/`client_secret` veya Firebase Web anahtarı yoktur (Kesin Kural #11) | Evet | -| `check:db-rules` | `src/lib/db/` modülleri dışında ham SQL yoktur; `localDb.ts` üzerinden barrel import kullanılmaz (Kesin Kurallar #2/#5) | Evet | -| `check:known-symbols` | Dağıtım tablolarına kaydedilen sağlayıcı yürütücüleri, yönlendirme stratejileri ve dönüştürücüler diskteki dosyalarla eşleşir — sahipsiz veya bildirilmemiş sembol yoktur | Evet | -| `check:route-guard-membership` | Alt süreç başlatan her rota `isLocalOnlyPath()` tarafından sınıflandırılır (Kesin Kurallar #15/#17) | Evet | -| `check:test-discovery` | Depodaki her `*.test.ts` / `*.spec.ts` dosyası en az bir test çalıştırıcısı tarafından toplanır (kademeli sıkılaştırma: `test-discovery-baseline.json` içindeki sahipsiz dosyalar listesi yalnızca küçülebilir) | Evet | -| `check:agent-skills-sync` | Oluşturulan agent-skills yapıtları kaynak kataloglarıyla eşleşir (sapma yok) | -| `check:provider-asset-provenance` | Sağlayıcı logoları/varlıkları kayıtlı bir kaynak bilgisi girdisi taşır | -| `lint:json` | JSON yapılandırma dosyaları ayrıştırılır ve depo lint kurallarını karşılar | -| `typecheck:core` | Hatasız TypeScript derlemesi (yalnızca bilgilendirme amaçlı uyarılar) | Evet | -| `typecheck:noimplicit:core` | Katı `noImplicitAny` — ileriye dönük; önceden mevcut birçok çağrı noktasının hâlâ ek açıklamalara ihtiyacı var | **Bilgilendirme amaçlı** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` ile sınırlandırılmış `tsc` (#7033) — `typecheck:core`'un özenle seçilmiş 27 dosyalık izin listesi hiçbir dashboard TSX dosyasını içermiyor ve `next build` de bunların tür denetimini hiçbir zaman yapmıyor (`next.config.mjs`, `ignoreBuildErrors: true` olarak ayarlıyor); dolayısıyla buradaki sahipsiz tanımlayıcı regresyonları (#6625/#6909) CI tarafından görülemiyordu. Sabitlenmiş dosya başına/TS kodu başına hata sayısı temel çizgisiyle (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ile aynı eskime denetimi modeli) karşılaştırma yapar — yalnızca temel çizgideki sayıyı aşan YENİ hatalar geçidin başarısız olmasına neden olur; önceden mevcut bir hata düzeltildiğinde `--update` ile temel çizgiyi aşağı çekin. | Evet | +`main` dalına gönderilen her PR'da çalışır. Başarısızlık durumunda birleştirmeyi engeller. + +| Betik (`npm run ...`) | Doğruladığı | Engelleyici | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | +| `check:node-runtime` | Node.js sürümünün desteklenen aralıkta olduğunu | Evet | +| `check:cycles` | `src/` + `open-sse/` genelindeki döngüsel içe aktarımlar (AST tabanlı, tsconfig `paths` çözümlenir). Temel sürüm tavsiye niteliğindedir ve döngüleri listeler. `check:cycles:ratchet` (CI'ın çalıştırdığı), sayı `quality-baseline.json` içindeki `metrics.cycles` üst sınırını aştığında engeller — şu anda 14, `direction: down`; dolayısıyla yalnızca düşebilir (#15159 G-01/G-02) | Evet (ratchet) | +| `check:route-validation:t06` | Tüm route'larda Zod şemalarının bulunduğunu (Tier 6 politikası) | Evet | +| `check:any-budget:t11` | `@ts-expect-error // any` sayısının bütçeyi aşmadığını (Tier 11 catraca) | Evet | +| `check:provider-consistency` | `providers.ts` içindeki her sağlayıcının `providerRegistry.ts` içinde eşleşen bir girdisi vardır (ve izin verilenler listesi kapsamında bunun tersi de geçerlidir) | Evet | +| `check:model-lifecycle` | Elle sürdürülen üç yönlendirme tablosu, depoya kaydedilmiş yaşam döngüsü anlık görüntüsüyle (#11503) tutarlı kalır: `FITNESS_TABLE` (`taskFitness.ts`), `REGISTRY` tarafından yönlendirilebilen kullanımdan kaldırılmış hiçbir kimliğe puan vermez; her `BUILT_IN_ALIASES` hedefi `REGISTRY` içinde bulunur ve kullanımdan kaldırılmış kimliklerin anlık görüntüsünde bulunmaz; `REGISTRY` içinde hâlâ bulunan kullanımdan kaldırılmış her kimlik başka bir yere yönlendirilir veya `allowedRetiredInCatalog` içinde listelenir; ayrıca hiçbir `DEFAULT_DEGRADATION_MAP` kaynağı veya hedefi bu anlık görüntüde kullanımdan kaldırılmış olarak görünmez. Bu, bir modelin şu anda canlı bir yukarı akış tarafından sunulduğunu kanıtlamaz. Çevrimdışı — elle `npm run quality:refresh-model-lifecycle` (ağ erişimi gerektirir; CI'a bağlı değildir) kullanılarak yenilenen `config/quality/model-lifecycle.json` ile karşılaştırır. `allowedRetiredInCatalog`, kademeli azaltma mandalıdır: yalnızca bir takip kaydıyla birlikte girdi ekleyin. | Evet | +| `check:fetch-targets` | İstemci tarafındaki `src/` içinde yer alan her `fetch("/api/...")`, gerçek bir `route.ts` dosyasına çözümlenir | Evet | +| `check:deps` | Depodaki her `package.json` genelinde `npm install` ile kurulabilen tüm bağımlılıklar `dependency-allowlist.json` içindedir; yeni sabitlenmemiş veya yazım hatasıyla taklit edilmiş paketler işaretlenir | Evet | +| `audit:deps` | `npm audit` (kök + electron) — yüksek/kritik önem derecesinde güvenlik bildirimi yoktur (osv `check:vuln-ratchet` ile örtüşür; Rationalization Backlog'a bakın) | Evet | +| `check:lockfile` | `package-lock.json` bütünlüğü — https kayıt deposu, bütünlük karmaları, ana makine geçersiz kılmaları yok | Evet | +| `check:licenses` | Üretim bağımlılıkları için SPDX lisans izin listesi | Evet | +| `check:tracked-artifacts` | Derleme çıktıları / commit'lenmiş `node_modules` sembolik bağlantıları yok (husky pre-commit sırasında da çalışır; pre-push kasıtlı olarak hafiftir — #6716) | Evet | +| `check:ai-attribution` | PR commit'lerinde, başlığında veya gövdesinde AI/bot `Co-Authored-By` son bilgisi ya da AI üretimi alt bilgisi yok — Kesin Kural #16 (`release/**` hedefli PR'ler için `quality.yml` hızlı kontrol döngüsünde — olay yükünü okur, PR dışında işlem yapmaz — ve `main` hedefli PR'ler için `ci.yml` lint işlemindeki yalnızca PR'ye özel bir adımda; ayrıca husky `commit-msg` kancasında; insan ortak yazarlarına izin verilir; #14436) | +| `check:vitest-exclusions` | Her Vitest hariç tutma kaydı bir takip sorunu belirtir ve `config/quality/vitest-exclusions.json` içinde yer alır (#13204) | Evet | +| `check:file-size` | Hiçbir kaynak dosyası, uzantı başına belirlenen sınırı aşmaz (mandal: büyük dosyalar `frozen` listesinde dondurulur) | Evet | +| `check:error-helper` | Yürütücülerdeki/işleyicilerdeki hata yanıtları `buildErrorBody()` / `sanitizeErrorMessage()` kullanır (Kesin Kural #12) | Evet | +| `check:migration-numbering` | Migration SQL dosyaları boşluk veya yinelenen numara olmadan sıralı şekilde numaralandırılmıştır | Evet | +| `check:public-creds` | `publicCreds.ts` dışında değişmez OAuth `client_id`/`client_secret` veya Firebase Web anahtarları yoktur (Kesin Kural #11) | Evet | +| `check:db-rules` | `src/lib/db/` modülleri dışında ham SQL yoktur; `localDb.ts` dosyasından barrel import kullanılmaz (Kesin Kurallar #2/#5) | Evet | +| `check:known-symbols` | Dağıtım tablolarına kaydedilen sağlayıcı yürütücüleri, yönlendirme stratejileri ve dönüştürücüler diskteki dosyalarla eşleşir — sahipsiz veya bildirilmemiş sembol yoktur | Evet | +| `check:route-guard-membership` | Alt süreç başlatan her rota `isLocalOnlyPath()` tarafından sınıflandırılır (Kesin Kurallar #15/#17) | Evet | +| `check:test-discovery` | Depodaki her `*.test.ts` / `*.spec.ts` dosyası en az bir test çalıştırıcısı tarafından toplanır (mandal: `test-discovery-baseline.json` içindeki sahipsizler listesi yalnızca küçülebilir) | Evet | +| `check:agent-skills-sync` | Oluşturulan agent-skills yapıtları kaynak kataloglarıyla eşleşir (sapma yok) | +| `check:provider-asset-provenance` | Sağlayıcı logoları/varlıkları kayıtlı bir kaynak bilgisi girdisi taşır | +| `lint:json` | JSON yapılandırma dosyaları ayrıştırılır ve depo lint kurallarını karşılar | +| `typecheck:core` | Hatasız TypeScript derlemesi (yalnızca bilgilendirme amaçlı uyarılar) | Evet | +| `typecheck:noimplicit:core` | Katı `noImplicitAny` — ileriye dönük; önceden var olan birçok çağrı noktasının hâlâ ek açıklamalara ihtiyacı var | **Bilgilendirme amaçlı** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` kapsamındaki `tsc` (#7033) — `typecheck:core`'un özenle seçilmiş 27 dosyalık izin listesi hiçbir dashboard TSX dosyasını içermiyor ve `next build` de bunların tür denetimini hiçbir zaman yapmıyor (`next.config.mjs`, `ignoreBuildErrors: true` olarak ayarlanmış), bu nedenle buradaki sahipsiz tanımlayıcı regresyonları (#6625/#6909) CI tarafından görülemiyordu. Sabitlenmiş dosya başına/TS kodu başına hata sayısı temel çizgisiyle (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` ile aynı eskime denetimi kalıbı) karşılaştırma yapılır — yalnızca temel çizgideki sayıyı aşan YENİ hatalar geçidi başarısız kılar; önceden var olan bir hata düzeltildiğinde `--update` ile temel çizgiyi aşağı çekin. | Evet | ### İş: `quality-gate` -`test-coverage` sonrasında çalışır. Başarısız olması durumunda birleştirmeyi engeller. +`test-coverage` sonrasında çalışır. Başarısızlık durumunda birleştirmeyi engeller. -| Betik | Doğruladığı | Engelleyici | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | -| `quality:collect` | `quality-metrics.json` dosyasını oluşturur (ESLint uyarı sayısı, birleştirilmiş parça raporundaki kapsam) | Evet (mandalın ön koşulu) | -| `quality:ratchet` | `quality-baseline.json` içindeki hiçbir metrik gerilememiştir (ESLint uyarıları ≤ temel değer; kapsam ≥ temel değer) | Evet | -| `check:duplication` | Kod yinelemesi (jscpd@4), `quality-baseline.json` içindeki temel değeri aşmaz | Evet | -| `check:complexity` | Dosya düzeyindeki döngüsel karmaşıklık üst sınırı aşmaz (temel ESLint `complexity` + `max-lines-per-function`) | Evet | -| `check:cognitive-complexity` | Bilişsel karmaşıklık mandalı (`eslint-plugin-sonarjs`) — ayrı ESLint geçişi; CI, her ikisini tek bir `check:complexity-ratchets` adımı olarak birleştirip çalıştırır | Evet | -| `check:dead-code` | Kullanılmayan dışa aktarımlar / dosyalar mandalı (knip), temel değere kıyasla gerilemez | Evet | -| `check:compression-budget` | Sıkıştırma karşılaştırma testi bütçesi — motor başına token tasarrufu alt sınırları gerilememelidir | Evet | -| `check:type-coverage` | Tür atanmış kod yüzdesi mandalı (`type-coverage`) gerilemez; `typecheck:noimplicit:core` kontrolünü büyük ölçüde kapsar | Evet | -| `check:codeql-ratchet` | Açık CodeQL uyarılarının sayısı gerilemez (`gh api` aracılığıyla okunur; token olmadan sorunsuzca atlanır) — yenileme sıklığı ve manuel tetikleme için aşağıdaki "CodeQL mandalı" bölümüne bakın | Evet | +| Betik | Doğruladığı | Engelleyici | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `quality:collect` | `quality-metrics.json` üretir (ESLint uyarı sayısı, birleştirilmiş parça raporundan kapsam) | Evet (ratchet'ın ön koşulu) | +| `quality:ratchet` | `quality-baseline.json` içindeki her metriğin gerilemediğini doğrular (ESLint uyarıları ≤ temel değer; kapsam ≥ temel değer) | Evet | +| `check:duplication` | Kod tekrarının (jscpd@4) `quality-baseline.json` içindeki temel değeri aşmadığını doğrular | Evet | +| `check:complexity` | Dosya düzeyindeki döngüsel karmaşıklığın üst sınırı aşmadığını doğrular (temel ESLint `complexity` + `max-lines-per-function`) | Evet | +| `check:cognitive-complexity` | Bilişsel karmaşıklık ratchet'ı (`eslint-plugin-sonarjs`) — ayrı ESLint geçişi; CI, her ikisini tek bir `check:complexity-ratchets` adımı olarak birleştirip çalıştırır | Evet | +| `check:dead-code` | Kullanılmayan dışa aktarımlar / dosyalar ratchet'ının (knip) temel değere kıyasla gerilemediğini doğrular | Evet | +| `check:compression-budget` | Sıkıştırma karşılaştırma testi bütçesi — motor başına token tasarrufu alt sınırlarının gerilemediğini doğrular | Evet | +| `check:type-coverage` | Türlendirilmiş yüzde ratchet'ının (`type-coverage`) gerilemediğini doğrular; büyük ölçüde `typecheck:noimplicit:core` kapsamını içerir | Evet | +| `check:codeql-ratchet` | Açık CodeQL uyarılarının sayısının artmadığını doğrular (`gh api` üzerinden okur; token olmadan sorunsuzca atlar) — yenileme sıklığı ve manuel tetikleme için aşağıdaki "CodeQL ratchet" bölümüne bakın | Evet | ### İş: `quality-extended` -İşin tamamı tavsiye niteliğindedir (`continue-on-error: true`). npm tabanlı mandallar -gerçek anlamda çalışır; harici tarayıcılar `gh release download` aracılığıyla kurulur ve -ikili dosya hâlâ mevcut değilse kendilerini atlar (çıkış kodu 0). +İşin tamamı bilgilendirme amaçlıdır (`continue-on-error: true`). npm tabanlı ratchet'lar +gerçekten çalışır; harici tarayıcılar `gh release download` aracılığıyla yüklenir ve bir +ikili dosya hâlâ yoksa kendilerini atlar (çıkış kodu 0). -| Betik | Doğruladığı | Engelleyici | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | -| `check:circular-deps` | Döngüsel bağımlılık yoktur (dpdm) | **Tavsiye niteliğinde** | -| `check:bundle-size` | Paket boyutu üst sınırı aşmaz | **Tavsiye niteliğinde** | -| `check:secrets` | Gizli bilgi taraması (gitleaks) — ikili dosya yoksa atlanır | **Tavsiye niteliğinde** | -| `check:vuln-ratchet` | Bağımlılık güvenlik açıkları (osv-scanner) gerilemez — ikili dosya yoksa atlanır | **Tavsiye niteliğinde** | -| `check:workflows` | İş akışı lint denetimi (actionlint + zizmor); eksik/bozuk tarayıcılar, geçersiz raporlar veya eksik mandal temel değeri INCOMPLETE olarak başarısız olur. Geçerli bulgular, seçilen katı/tavsiye/mandal politikasını izler | Çalıştırılması zorunludur; zizmor mandalı CI'da engelleyicidir | -| `check:openapi-breaking` | Temel dala kıyasla genel API sözleşmesindeki (`openapi.yaml`) geriye dönük uyumsuz değişiklikler (oasdiff) — `openapiBreaking=N` çıktısını üretir; oasdiff yoksa veya temel belirtim çözümlenemiyorsa atlanır | **Tavsiye niteliğinde** | +| Betik | Doğruladığı | Engelleyici | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `check:circular-deps` | Döngüsel bağımlılık olmadığını doğrular (dpdm) | **Bilgilendirme amaçlı** | +| `check:bundle-size` | Paket boyutunun üst sınırı aşmadığını doğrular | **Bilgilendirme amaçlı** | +| `check:secrets` | Gizli bilgi taraması (gitleaks) — ikili dosya yoksa atlanır | **Bilgilendirme amaçlı** | +| `check:vuln-ratchet` | Bağımlılık güvenlik açıklarının (osv-scanner) artmadığını doğrular — ikili dosya yoksa atlanır | **Bilgilendirme amaçlı** | +| `check:workflows` | İş akışı lint denetimi (actionlint + zizmor); eksik/bozuk tarayıcılar, geçersiz raporlar veya eksik ratchet temel değeri INCOMPLETE olarak başarısız olur. Geçerli bulgular seçilen katı/bilgilendirme/ratchet politikasını izler | Çalıştırılması zorunludur; zizmor ratchet'ı CI'da engelleyicidir | +| `check:openapi-breaking` | Genel API sözleşmesindeki (`openapi.yaml`) temel dala kıyasla geriye dönük uyumsuz değişiklikleri doğrular (oasdiff) — `openapiBreaking=N` üretir; oasdiff yoksa veya temel belirtim çözümlenemiyorsa atlanır | **Bilgilendirme amaçlı** | ### İş: `docs-sync-strict` -`main` dalına yönelik her PR'da çalışır. Başarısızlık durumunda birleştirmeyi engeller. - -| Betik | Doğruladığı | Engelleyici | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `check:docs-all` | Aşağıdaki 6 alt geçidi sırayla çalıştıran meta geçit | Evet | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt sürüm tutarlılığı | Evet | -| ↳ `check:docs-counts` | Düzyazıdaki sayılar (sağlayıcı sayısı, geçiş sayısı vb.) gerçek sayıların mandallı aralığı içindedir | Evet | -| ↳ `check:env-doc-sync` | `.env.example` içindeki her ortam değişkeni bir dokümantasyon tablosunda belgelenmiştir ve bunun tersi de geçerlidir | Evet | -| ↳ `check:deprecated-versions` | Dokümantasyonda kullanımdan kaldırılmış sürüm dizeleri yoktur | Evet | -| ↳ `check:doc-links` | Dokümantasyondaki dahili markdown bağlantıları gerçek dosyalara çözümlenir (`[metin]`/`(yol)` biçimi) | Evet | -| ↳ `check:fabricated-docs` | Dokümantasyonda belirtilen rotalar, ortam değişkenleri, CLI komutları, kanca adları ve dosya yolları kod tabanında mevcuttur. `--strict` ile katı geçit; bayrak olmadan esnek hata. | Evet (CI'da `--strict` aracılığıyla) | -| `check:cli-i18n` | CLI komut dizeleri tüm i18n yerel ayar dosyalarında mevcuttur | Evet | -| `check:openapi-coverage` | OpenAPI belirtimi, gerçek rotaların en az mandallanmış alt sınırını kapsar | Evet | -| `check:openapi-security-tiers` | `openapi.yaml` içindeki güvenlik katmanı ek açıklamaları `routeGuard.ts` sınıflandırmalarıyla tutarlıdır | **Öneri niteliğinde** | -| `check:openapi-routes` | `openapi.yaml` içindeki her yol gerçek bir `route.ts` dosyasına çözümlenir (halüsinasyon önleme) | Evet | -| `check:docs-symbols` | `docs/**/*.md` içindeki her `/api/...` başvurusu gerçek bir `route.ts` dosyasına çözümlenir (halüsinasyon önleme) | Evet | -| `i18n translation drift` | i18n yerel ayar dosyalarındaki çevrilmemiş anahtarlar — yalnızca uyarı | **Öneri niteliğinde** | +`main` dalına gönderilen her PR'da çalışır. Başarısızlık durumunda birleştirmeyi engeller. + +| Betik | Doğruladığı | Engelleyici | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| `check:docs-all` | Aşağıdaki 6 alt geçidi sıralı olarak çalıştıran meta geçit | Evet | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt sürüm tutarlılığı | Evet | +| ↳ `check:docs-counts` | Düzyazıdaki sayılar (sağlayıcı sayısı, geçiş sayısı vb.) gerçek sayıların mandallı aralığı içindedir | Evet | +| ↳ `check:env-doc-sync` | `.env.example` içindeki her ortam değişkeni bir dokümantasyon tablosunda belgelenmiştir ve bunun tersi de geçerlidir | Evet | +| ↳ `check:deprecated-versions` | Dokümantasyonda kullanım dışı bırakılmış sürüm dizeleri yoktur | Evet | +| ↳ `check:doc-links` | Dokümantasyondaki dahili markdown bağlantıları gerçek dosyalara çözümlenir (`[metin]`/`(yol)` biçimi) | Evet | +| ↳ `check:fabricated-docs` | Dokümantasyonda belirtilen rotalar, ortam değişkenleri, CLI komutları, kanca adları ve dosya yolları kod tabanında mevcuttur. `--strict` ile katı geçit; bayrak olmadan hata yalnızca uyarı niteliğindedir. | Evet (CI'da `--strict` aracılığıyla) | +| `check:cli-i18n` | CLI komut dizeleri tüm i18n yerel ayar dosyalarında mevcuttur | Evet | +| `check:openapi-coverage` | OpenAPI belirtimi, gerçek rotalar için en az mandallı bir alt sınırı kapsar | Evet | +| `check:openapi-security-tiers` | `openapi.yaml` içindeki güvenlik katmanı ek açıklamaları `routeGuard.ts` sınıflandırmalarıyla tutarlıdır | **Tavsiye niteliğinde** | +| `check:openapi-routes` | `openapi.yaml` içindeki her yol gerçek bir `route.ts` dosyasına çözümlenir (halüsinasyon önleme) | Evet | +| `check:docs-symbols` | `docs/**/*.md` içindeki her `/api/...` referansı gerçek bir `route.ts` dosyasına çözümlenir (halüsinasyon önleme) | Evet | +| `i18n translation drift` | i18n yerel ayar dosyalarındaki çevrilmemiş anahtarlar — yalnızca uyarı | **Tavsiye niteliğinde** | ### İş: `i18n-ui-coverage` -| Betik | Doğruladığı | Engelleyici | -| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `check-ui-keys-coverage` (satır içi) | UI i18n anahtar kapsamı ≥ %65'tir | Evet | -| `check-ui-value-drift` (satır içi) | Yeniden yazılmış bir İngilizce **değer**, geride eski çeviri bırakmaz | Evet | -| `check-new-key-coverage` (satır içi) | **Yeni** bir İngilizce anahtar her yerel ayarda çevrilmiştir — `__MISSING__:` işareti reddedilir | Evet | -| `check-translation-ratio` | Yerel ayar başına gerçek çeviri oranı (izin verilenler listesinin dışındaki İngilizceyle aynı / yer tutucu / eksik yapraklar) `config/quality/i18n-translation-baseline.json` + tolerans değerini aşmamalıdır | **Öneri niteliğinde** | +| Betik | Doğruladığı | Engelleyici | +| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `check-ui-keys-coverage` (satır içi) | UI i18n anahtar kapsamı ≥ %65'tir | Evet | +| `check-ui-value-drift` (satır içi) | Yeniden yazılmış bir İngilizce **değer**, geride güncelliğini yitirmiş çeviri bırakmaz | Evet | +| `check-new-key-coverage` (satır içi) | **Yeni** bir İngilizce anahtar her yerel ayarda çevrilmiştir — `__MISSING__:` işaretçisi reddedilir | Evet | +| `check-translation-ratio` | Yerel ayar başına gerçek çeviri oranı (izin verilenler listesinin dışındaki İngilizceyle aynı / yer tutucu / eksik yapraklar) `config/quality/i18n-translation-baseline.json` + tolerans değerini aşmamalıdır | **Tavsiye niteliğinde** | `fetch-depth: 0` gerektirir — değer sapması geçidi, `en.json` dosyasını birleştirme tabanıyla karşılaştırır. -#### `check-ui-value-drift` — eski çeviri geçidi +#### `check-ui-value-drift` — güncelliğini yitirmiş çeviri geçidi -Diğer geçitlerin yapısal olarak göremediği tek i18n gerilemesini yakalar: İngilizce bir değer -yeniden yazılır ancak _önceki_ İngilizceden türetilen çeviriler geride kalır; böylece -İngilizce konuşmayan kullanıcılar kendinden emin bir dille yazılmış, artık yanlış olan metni okumaya devam eder. +Diğer geçitlerin yapısal olarak göremediği i18n gerilemesini yakalar: İngilizce bir değer +yeniden yazılırken _önceki_ İngilizce metinden türetilen çeviriler geride kalır; dolayısıyla +İngilizce dışındaki dilleri kullanan kullanıcılar kendinden emin bir dille yazılmış, artık yanlış olan metni okumaya devam eder. Bu gerçekten yayımlandı. Antigravity oturum açma yardımcısı eklendiğinde (#5203) -`oauthModal.googleOAuthWarning` yeniden yazıldı; **43 yerel ayarın 39'u**, operatörlere "tam -URL'yi kopyalayıp aşağıya yapıştırmalarını" söyleyen metni korudu — bu sağlayıcı için +`oauthModal.googleOAuthWarning` yeniden yazıldı; **43 yerel ayarın 39'u**, operatörlere +"tam URL'yi kopyalayıp aşağıya yapıştırmalarını" söyleyen metni korudu — bu sağlayıcıda tamamlanması mümkün olmayan bir akış. Şu nedenlerle #8463'e kadar fark edilmedi: -- `sync-ui-keys` yalnızca **bulunmayan** anahtarları geriye dönük doldurur, **eskimiş** olanları asla doldurmaz; -- `check-ui-keys-coverage` anahtar _varlığını_ sayar, dolayısıyla eski bir çeviri kapsanmış olarak puanlanır; +- `sync-ui-keys` yalnızca **bulunmayan** anahtarları tamamlar, **güncelliğini yitirmiş** olanları hiçbir zaman güncellemez; +- `check-ui-keys-coverage` anahtar _varlığını_ sayar; dolayısıyla güncelliğini yitirmiş bir çeviri, kapsam dâhilinde olarak değerlendirilir; - `check-translation-drift`, `docs/i18n//**.md` dokümantasyon yansımalarını izler — - `src/i18n/messages/*.json` dosyalarını asla okumaz. 2026-09 yeniden eşitlemesinden bu yana - `docs-sync-strict` işinde engelleyicidir: temel bir belgeyi düzenleyin → `npm run i18n:run -- --files=` (bölüm düzeyinde, düşük maliyetli). + `src/i18n/messages/*.json` dosyalarını hiçbir zaman okumaz. 2026-09 yeniden senkronizasyonundan beri `docs-sync-strict` işinde engelleyicidir: temel bir dokümanı düzenleyin → `npm run i18n:run -- --files=` (bölüm düzeyinde, düşük maliyetli). -**Fark duyarlı, temel sürüm destekli değil.** Birleştirme tabanındaki `en.json` ile -çalışma ağacındaki sürümü karşılaştırır; İngilizce değeri değişen her anahtar için hâlâ -dokunulmamış çeviriyi içeren yerel ayar güncelliğini yitirmiş sayılır. Bu, kasıtlı olarak -**önceden var olan borcu dondurur** — bir fark, uzun süredir mevcut olan bir çevirinin hangi -eski İngilizce metinden geldiğini ortaya çıkaramaz; bu nedenle geçit yalnızca mevcut -değişikliğin dokunduğu öğeleri değerlendirir. Alternatif yöntem (anahtar başına karma temel -sürümü), mevcut en büyük temel sürümün 3 katı olan yaklaşık 600 KB boyutunda üretilmiş bir -dosya gerektirir ve her i18n PR'ında dosyanın değişmesine yol açardı. +**Fark duyarlı, temel durum destekli değil.** Birleştirme tabanındaki `en.json` dosyasını +çalışma ağacıyla karşılaştırır; İngilizce değeri değişen her anahtar için hâlâ +değiştirilmemiş çeviriyi tutan tüm yerel ayarlar güncelliğini yitirmiş sayılır. Bu yaklaşım, +önceden var olan borcu bilinçli olarak **dondurur** — bir fark, uzun süredir kullanılan bir +çevirinin hangi eski İngilizce metinden geldiğini gösteremez; bu nedenle geçit yalnızca +mevcut değişikliğin dokunduğu öğeleri değerlendirir. Alternatif yaklaşım (anahtar başına +karma taban çizgisi), mevcut en büyük taban çizgisinin 3 katı büyüklüğünde, yaklaşık 600 KB'lık +oluşturulmuş bir dosya gerektirir ve her i18n PR'ında gereksiz değişiklik üretirdi. -Bunu karşılamanın iki yolu vardır: +Bunu sağlamanın iki yolu vardır: -1. etkilenen çevirileri güncelleyin veya -2. bunları `__MISSING__:` olarak ayarlayın — çalışma zamanı daha sonra düzeltilmiş - İngilizce metni sunar (`src/i18n/request.ts::deepMergeFallback`, #7258) ve anahtar çeviri - kuyruğuna alınır. +1. etkilenen çevirileri güncellemek veya +2. bunları `__MISSING__:` olarak ayarlamak — çalışma zamanı daha sonra düzeltilmiş + İngilizce metni sunar (`src/i18n/request.ts::deepMergeFallback`, #7258) ve anahtarı çeviri + kuyruğuna ekler. Dizenin **anlamı** değiştiyse **anahtarı yeniden adlandırmayı** tercih edin: yeni bir anahtar, güncelliğini yitirmiş bir çeviriyi devralamaz. #8463'te kullanılan kalıp budur. @@ -241,48 +243,48 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` Temel katalog okunamadığında (temel ref olmadan sığ klon), `check-openapi-breaking` -davranışını yansıtacak şekilde `SKIP reason=base-unresolved` ile 0 koduyla çıkar. +davranışını yansıtarak `SKIP reason=base-unresolved` ile 0 çıkış kodu döndürür. ### İş: `i18n` Tam i18n doğrulama matrisi (yerel ayar başına bir iş). İşin tamamı tavsiye niteliğindedir. -| Betik | Doğruladığı | Engelleyici | -| ------------------------------- | ---------------------------------- | ------------------------------------------------------------ | -| `validate_translation.py quick` | Yerel ayar başına çeviri bütünlüğü | **Tavsiye niteliğinde** (tüm işte `continue-on-error: true`) | +| Betik | Doğruladığı | Engelleyici | +| ------------------------------- | ------------------------------------- | ------------------------------------------------------------ | +| `validate_translation.py quick` | Yerel ayar başına çeviri eksiksizliği | **Tavsiye niteliğinde** (tüm işte `continue-on-error: true`) | ### İş: `pr-test-policy` -Yalnızca pull request'lerde çalışır. +Yalnızca çekme isteklerinde çalışır. | Betik | Doğruladığı | Engelleyici | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` veya `bin/` içindeki üretim kodunu değiştiren PR'lar test eklemeli veya güncellemelidir (Katı Kural #8) | Evet | -| `check:test-masking` | Değiştirilen test dosyaları net assert sayısını azaltmaz veya `assert.ok(true)` totolojileri eklemez | Evet | -| `check:pr-evidence` | PR gövdesi, değişiklik için test/VPS kanıtına atıfta bulunur (PR metnini grep ile tarayarak Katı Kural #18'i mekanikleştirir — kırılgandır, bkz. Backlog) | Evet | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` veya `bin/` içindeki üretim kodunu değiştiren PR'lar testleri içermeli veya güncellemelidir (Katı Kural #8) | Evet | +| `check:test-masking` | Değiştirilen test dosyaları net doğrulama sayısını azaltmaz veya `assert.ok(true)` totolojileri eklemez | Evet | +| `check:pr-evidence` | PR açıklaması değişiklik için test/VPS kanıtlarına atıfta bulunur (PR metnini grep'leyerek Katı Kural #18'i otomatikleştirir — kırılgandır, bkz. Backlog) | Evet | ### İş: `test-vitest` -`build` sonrasında çalışır. Başarısız olduğunda birleştirmeyi engeller. +`build` işleminden sonra çalışır. Başarısız olduğunda birleştirmeyi engeller. -| Paket | Doğruladığı | Engelleyici | -| ---------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP sunucusu (110 araç), autoCombo, önbellek — vitest çalıştırıcısı | Evet | -| `test:vitest:ui` | UI bileşen testleri — vitest çalıştırıcısı | **Engelleyici** — önceden var olan hatalar `vitest.config.ts` içinde açıkça hariç tutulur; yeni hatalar işi başarısız kılar | +| Test paketi | Doğruladığı | Engelleyici | +| ---------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP sunucusu (110 araç), autoCombo, önbellek — vitest çalıştırıcısı | Evet | +| `test:vitest:ui` | UI bileşen testleri — vitest çalıştırıcısı | **Engelleyici** — önceden var olan başarısızlıklar `vitest.config.ts` içinde açıkça hariç tutulur; yeni başarısızlıklar işi başarısız kılar | ### Gecelik iş akışları (zamanlanmış, tavsiye niteliğinde) -Bunlar bir cron zamanlamasıyla (ve `workflow_dispatch` ile) çalışır; PR'larda hiçbir zaman +Bunlar cron zamanlamasında (ve `workflow_dispatch` ile) çalışır; PR'larda hiçbir zaman çalışmaz. Tümü tavsiye niteliğindedir. -| İş akışı | Doğruladığı | Engelleyici | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `nightly-property` | Rastgele seed ve yüksek çalıştırma sayısıyla fast-check özellik testleri | **Tavsiye niteliğinde** | -| `nightly-resilience` | Heap büyüme geçidi, kaos hata enjeksiyonu, k6 yük/dayanıklılık testi | **Tavsiye niteliğinde** | -| `nightly-llm-security` | promptfoo enjeksiyon koruması (engelleme modu) + garak probları (sağlayıcı sırrı olmadan atlanır) | **Tavsiye niteliğinde** | -| `nightly-schemathesis` | `docs/openapi.yaml` kullanarak çalışan bir OmniRoute'a karşı OpenAPI sözleşme fuzz testi (schemathesis) — spesifikasyon ihlallerini / işlenmemiş 500 hatalarını ortaya çıkarır (Aşama 8 B.4) | **Tavsiye niteliğinde** | -| `nightly-mutation` | Hızlı birim test hattı üzerinde Stryker mutasyon testi puanı — hayatta kalan mutantlar zayıf assert'leri ortaya çıkarır | **Tavsiye niteliğinde** | -| `nightly-compat` | Desteklenen `engines.node` aralıkları genelinde Node motoru uyumluluk matrisi | **Tavsiye niteliğinde** | +| İş akışı | Doğruladığı | Engelleyici | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `nightly-property` | Rastgele tohum ve yüksek çalıştırma sayısıyla fast-check özellik testleri | **Tavsiye niteliğinde** | +| `nightly-resilience` | Bellek yığını büyüme geçidi, kaos hata enjeksiyonu, k6 yük/dayanıklılık testleri | **Tavsiye niteliğinde** | +| `nightly-llm-security` | promptfoo enjeksiyon koruması (engelleme modu) + garak probları (sağlayıcı gizli değeri yoksa atlanır) | **Tavsiye niteliğinde** | +| `nightly-schemathesis` | `docs/openapi.yaml` kullanılarak çalışan bir OmniRoute'a karşı OpenAPI sözleşme fuzz testi (schemathesis) — spesifikasyon ihlallerini / işlenmeyen 500 hatalarını ortaya çıkarır (Fase 8 B.4) | **Tavsiye niteliğinde** | +| `nightly-mutation` | Hızlı birim hattında Stryker mutasyon testi puanı — hayatta kalan mutantlar zayıf doğrulamaları ortaya çıkarır | **Tavsiye niteliğinde** | +| `nightly-compat` | Desteklenen `engines.node` aralıkları genelinde Node motoru uyumluluk matrisi | **Tavsiye niteliğinde** | --- @@ -544,43 +546,43 @@ bağlantı hatasını günlüğe kaydeder ve oturumları hiçbir zaman bozmaz. --- -## Rasyonalizasyon İş Listesi (ROI incelemesi — Aşama 9 Dalga 3) +## Rasyonalizasyon İş Listesi (ROI incelemesi — Faz 9 Dalga 3) -Bu envanter, 2026-06-17 tarihinde `ci.yml` ile karşılaştırılarak mutabık hâle getirildi (önceki sürümde +Bu envanter, 2026-06-17 tarihinde `ci.yml` ile karşılaştırılarak uzlaştırıldı (önceki sürümde `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` yer almıyordu). Mutabık hâle getirilen kümenin ROI incelemesi, +`check:codeql-ratchet`, `check:pr-evidence` yer almıyordu). Uzlaştırılmış kümenin ROI incelemesi aşağıdaki rasyonalizasyon adaylarını belirledi. **Birleştirmeler mekanik CI -değişiklikleridir; etkinleştirme/kaldırma kararları ise operatöre bırakılmış politika kararlarıdır.** Aşağıdakilerin hiçbiri -henüz uygulanmadı. +değişiklikleridir; etkinleştirme/kaldırma işlemleri ise operatöre bırakılmış politika kararlarıdır.** Aşağıdakilerin hiçbiri +henüz uygulanmamıştır. **Yukarıda ayrıca belgelenmemiş olanlar** (tavsiye niteliğinde, düşük sinyalli): `docs-lint` işi (markdownlint + Vale, işin tamamında `continue-on-error`) ve bağımsız tarayıcı iş akışları `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0`, -`quality-baseline.json` içinde yer alıyor ancak `ci.yml` içinde engelleyici bir mandala bağlı değil — metrik -şu anda sahipsiz. +`quality-baseline.json` içinde yer almaktadır ancak `ci.yml` içinde engelleyici bir ratchet'a +bağlı değildir — metrik şu anda sahipsizdir. ### Birleştirme / tekilleştirme (mekanik, daha düşük risk) -Her aday, 2026-06-17 tarihinde canlı eşik durumuna göre doğrulandı (güven ama doğrula); -"bariz" görünen birkaç birleştirmenin aslında teknik borcu gizlediği ortaya çıktı ve bunlar **doğrudan uygulanabilecek temiz değişiklikler değildir**. +Her aday, 2026-06-17 tarihinde canlı gate durumuna karşı doğrulandı (güven ama doğrula); +“bariz” görünen bazı birleştirmelerin borç gizlediği ortaya çıktı ve bunlar **temiz birer doğrudan ikame değildir**. -- **`check:docs-sync` iki kez çalışıyor** — `lint` işi içinde bağımsız olarak, ayrıca `check:docs-all` (`docs-sync-strict`) ve husky pre-commit kancası içinde tekrar çalışıyor. ✅ **TAMAMLANDI** — bağımsız `lint` çağrısı kaldırıldı. -- **CVE taraması** — ❌ **Temiz bir birleştirme DEĞİL.** `audit:deps`, herhangi bir yüksek/kritik CVE durumunda kesin olarak başarısız olur; `check:vuln-ratchet` (osv) ise yalnızca referans çizgisine kıyasla bir _gerileme_ olduğunda başarısız olur (şu anda 1 MODERATE). Anlamları farklıdır — `audit:deps` kaldırılırsa mutlak yüksek/kritik eşiği kaybedilir. Her ikisini de koruyun. -- **Döngü tespiti** — ❌ **Temiz bir birleştirme DEĞİL.** `check:circular-deps` (dpdm) **91 döngü** bildiriyor (tavsiye niteliğinde olmasının nedeni bu); bunlar önce çözülmeden engelleyici hâle getirilemez ve yeşil durumda olan, özenle seçilmiş `check:cycles` denetiminden daha geniş bir kapsama sahiptir. `check:cycles` engelleyici olarak kalsın; 91 dpdm döngüsünün çözülmesi ayrı bir iş listesidir. -- **Karmaşıklık** — ✅ **TAMAMLANDI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): tek bir ESLint geçişi, ruleId bazında sayım yapar; böylece çevrimsel karmaşıklık+max-lines ve bilişsel referans çizgileri bağımsız kalır; ayrı `check:complexity` / `check:cognitive-complexity` komutları yerel `--update` kullanımı için korunur. -- **`/api` halüsinasyon önleme** — ✅ **TAMAMLANDI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` için tek bir FS envanteri; openapi-routes + docs-symbols hâlâ bağımsız raporlama yapar; ayrı komutlar yerel çalıştırmalar için korunur. -- **`check:node-runtime` 11 işte çalışıyor** — ⚠️ **düşük ROI.** Her biri ayrı bir çalıştırıcıdır ve denetim <1 sn sürer; ucuz bir iş başına korumanın kaybedilmesine karşılık toplam tasarruf ~10 sn'dir. Değişiklik zahmetine değmez. -- **CI lint üzerindeki `typecheck:noimplicit:core`** — ✅ **lint işinden kaldırıldı** (tavsiye niteliğinde `continue-on-error` idi); engelleyici tür yüzeyi `typecheck:core` + `check:type-coverage` ile sağlanır. Yerel betik korundu. +- **`check:docs-sync` iki kez çalışıyor** — `lint` işi içinde bağımsız olarak ve ayrıca `check:docs-all` (`docs-sync-strict`) ile husky pre-commit hook'u içinde. ✅ **TAMAMLANDI** — bağımsız `lint` çağrısı kaldırıldı. +- **CVE taraması** — ❌ **Temiz bir birleştirme DEĞİL.** `audit:deps`, herhangi bir yüksek/kritik CVE olduğunda kesin olarak başarısız olur; `check:vuln-ratchet` (osv) ise yalnızca baseline'a kıyasla bir _gerileme_ olduğunda başarısız olur (şu anda 1 MODERATE). Semantikleri farklıdır — `audit:deps` kaldırılırsa mutlak yüksek/kritik gate kaybedilir. İkisini de koruyun. +- **Döngü tespiti** — ✅ **TAMAMLANDI** (#15159 G-01/G-02). Buradaki eski metin, `check:cycles` için “yeşil, özenle seçilmiş” gate ifadesini kullanıyor ve `check:circular-deps` (dpdm) 91 döngü bildirdiği için bunun engelleyici olarak tutulmasını gerekçelendiriyordu. Bu yeşil durum **yalancı yeşildi**: `check:cycles` 5 alt dizini (450 dosya) tarıyor, yalnızca statik `import|export … from` ifadelerini eşleştiriyor ve tüm `@/` ile `@omniroute/open-sse/` belirticilerini eliyordu; dolayısıyla depoda baskın olan dinamik import + alias döngülerini göremiyordu. Düzeltildi: gate artık `src` + `open-sse` dizinlerini (5023 dosya) dolaşıyor, belirticileri TypeScript AST'sinden topluyor (böylece `import("…")` sayılırken tür konumundaki `typeof import("…")` sayılmıyor) ve tsconfig `paths` değerlerini çözümlüyor. 0 değil, **14** döngü buluyor. Önceden var olan 14 döngü bir gate PR'ında düzeltilemeyeceğinden `check:cycles` artık bir **ratchet**'tır (`--ratchet`, `quality-baseline.json` içinde tavan `metrics.cycles.value = 14`, `direction: down`) — herhangi bir _gerilemeyi_ engeller ve sayı yalnızca azalabilir. CI, `npm run check:cycles:ratchet` komutunu çalıştırır. Azaltma çalışmaları **A-01** ile birlikte yürütülür. `check:circular-deps` (dpdm), daha geniş kapsamlı ikinci görüş olarak tavsiye niteliğinde kalır. +- **Karmaşıklık** — ✅ **TAMAMLANDI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): tek bir ESLint taraması, cyclomatic+max-lines ve cognitive baseline'larının bağımsız kalması için ruleId bazında sayım yapar; ayrı `check:complexity` / `check:cognitive-complexity` komutları yerel `--update` işlemleri için korunur. +- **`/api` anti-halüsinasyon** — ✅ **TAMAMLANDI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` için tek bir FS envanteri; openapi-routes + docs-symbols hâlâ bağımsız olarak rapor verir; ayrı komutlar yerel çalıştırmalar için korunur. +- **`check:node-runtime` 11 işte çalışıyor** — ⚠️ **düşük ROI.** Her biri ayrı bir runner'dır ve kontrol <1 sn sürer; ucuz bir iş başına korumanın kaybedilmesine karşılık toplam tasarruf ~10 sn'dir. Bu değişikliğe değmez. +- **CI lint'te `typecheck:noimplicit:core`** — ✅ **lint işinden kaldırıldı** (tavsiye niteliğinde `continue-on-error` idi); engelleyici tür yüzeyi `typecheck:core` + `check:type-coverage` şeklindedir. Yerel script korundu. ### Etkinleştirme / karar verme (operatör politikası) -- `check:openapi-security-tiers` (tavsiye niteliğinde) — ❌ **Temiz şekilde etkinleştirilemez.** 0 ile çıkar ancak `LOCAL_ONLY_API_PREFIXES` altındaki birkaç `traffic-inspector` rotasında `x-loopback-only: true` ek açıklamasının bulunmadığı konusunda uyarır. Bunu zorunlu kılmak için önce bu ek açıklamaların `openapi.yaml` dosyasına eklenmesi gerekir. -- `typecheck:noimplicit:core` (tavsiye niteliğinde) — büyük ölçüde engelleyici `check:type-coverage` mandalı tarafından kapsanıyor. Bir mandala dönüştürün veya gereksiz ikinci `tsc` geçişini kaldırın. -- `test:vitest:ui` (artık **engelleyici**) — önceden var olan hatalar, `vitest.config.ts` içinde `// #8618` takip yorumlarıyla açıkça hariç tutulmuştur; yeni hatalar işin başarısız olmasına neden olur. -- `check:secrets` (gitleaks, belgelenmiş 3 yanlış pozitif değerinde dondurulmuş engelleyici mandal) — 0'a ulaşmak için bu 3 öğeyi izin verilenler listesine ekleyin veya denetimi tavsiye niteliğine indirin. GitHub'ın yerleşik gizli bilgi taraması + `check:public-creds` ile örtüşür. -- `check:pr-evidence` (engelleyici, PR gövdesindeki metni grep ile tarar) — yanlış pozitif riski yüksektir; kaldırılması Katı Kural #18'in uygulanmasını zayıflatır, dolayısıyla bu gerçek bir politika kararıdır. -- `semgrep` (tavsiye niteliğinde bağımsız iş akışı) — OWASP aileleri açısından CodeQL ile örtüşür; referans çizgisini bir mandala bağlayın veya kaldırın. +- `check:openapi-security-tiers` (tavsiye niteliğinde) — ❌ **Temiz biçimde etkinleştirilemez.** 0 koduyla çıkar ancak `LOCAL_ONLY_API_PREFIXES` altındaki bazı `traffic-inspector` route'larında `x-loopback-only: true` annotation'ının eksik olduğu konusunda uyarır. Bunu zorunlu kılmak için önce söz konusu annotation'ların `openapi.yaml` dosyasına eklenmesi gerekir. +- `typecheck:noimplicit:core` (tavsiye niteliğinde) — büyük ölçüde engelleyici `check:type-coverage` ratchet'ı tarafından kapsanır. Bir ratchet'a dönüştürün veya yinelenen ikinci `tsc` geçişini kaldırın. +- `test:vitest:ui` (artık **engelleyici**) — önceden var olan hatalar, `vitest.config.ts` içinde `// #8618` takip yorumlarıyla açıkça hariç tutulmuştur; yeni hatalar işi başarısız kılar. +- `check:secrets` (gitleaks, belgelenmiş 3 false-positive değerinde dondurulmuş engelleyici ratchet) — 0'a ulaşmak için bu 3 öğeyi allowlist'e ekleyin veya tavsiye niteliğine düşürün. GitHub'ın yerleşik secret-scanning özelliği + `check:public-creds` ile örtüşür. +- `check:pr-evidence` (engelleyici, PR gövdesindeki düzyazıda grep yapar) — false-positive riski yüksektir; kaldırılması Hard Rule #18 uygulamasını zayıflatır, dolayısıyla bu gerçek bir politika kararıdır. +- `semgrep` (tavsiye niteliğinde bağımsız iş akışı) — OWASP aileleri bakımından CodeQL ile örtüşür; baseline'ını bir ratchet'a bağlayın veya kaldırın. --- diff --git a/docs/i18n/uk-UA/CONTRIBUTING.md b/docs/i18n/uk-UA/CONTRIBUTING.md index 95bf0e19d6c..18e40058f7b 100644 --- a/docs/i18n/uk-UA/CONTRIBUTING.md +++ b/docs/i18n/uk-UA/CONTRIBUTING.md @@ -386,18 +386,18 @@ docs/ # Documentation - [ ] Тести проходять (`npm test`) - [ ] Перевірка лінтером проходить (`npm run lint`) -- [ ] Збірка виконується успішно (`npm run build`) +- [ ] Збірка успішна (`npm run build`) - [ ] Додано типи TypeScript для нових публічних функцій та інтерфейсів - [ ] Немає жорстко закодованих секретів або резервних значень -- [ ] Публічні облікові дані вбудовано через `resolvePublicCred()` (див. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), а не задано як літерали +- [ ] Публічні облікові дані upstream-сервісів вбудовано через `resolvePublicCred()` (див. [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), а не як літерали - [ ] Відповіді з помилками проходять через `buildErrorBody()` / `sanitizeErrorMessage()` — у тілах відповідей немає необроблених трасувань стека (див. [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Команди оболонки (`exec` / `spawn`) передають значення середовища виконання через `env`, а не через інтерполяцію рядків +- [ ] Команди оболонки (`exec` / `spawn`) передають значення часу виконання через `env`, а не через інтерполяцію рядків - [ ] Усі вхідні дані перевіряються за допомогою схем Zod - [ ] Для змін, видимих користувачам, додано **фрагмент** журналу змін у `changelog.d/{features|fixes|maintenance}/-.md` (див. [`changelog.d/README.md`](./changelog.d/README.md)) — **не** редагуйте `CHANGELOG.md` безпосередньо; фрагменти об’єднуються під час випуску й ніколи не спричиняють конфліктів між PR - [ ] Документацію оновлено (якщо застосовно) - [ ] Не створено нових сповіщень CodeQL / Secret-Scanning або кожне з них відхилено з технічним обґрунтуванням і посиланням на відповідний документ у `docs/security/` -- [ ] Маршрути, які запускають дочірні процеси (`/api/mcp/`, `/api/cli-tools/runtime/`), класифіковано як `isLocalOnlyPath()` у `src/server/authz/routeGuard.ts` — див. [жорстке правило №15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] У повідомленнях комітів немає завершальних рядків `Co-Authored-By` — коміти мають відображатися виключно під Git-ідентичністю власника репозиторію (жорстке правило №16) +- [ ] Маршрути, що запускають дочірні процеси (`/api/mcp/`, `/api/cli-tools/runtime/`), класифіковано як `isLocalOnlyPath()` у `src/server/authz/routeGuard.ts` — див. [Жорстке правило №15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] У повідомленнях комітів немає трейлерів AI/ботів `Co-authored-by` (Жорстке правило №16) — людей-співавторів, чию роботу повторно використано, зазначено стандартними трейлерами `Co-authored-by: Name ` --- diff --git a/docs/i18n/uk-UA/docs/architecture/QUALITY_GATES.md b/docs/i18n/uk-UA/docs/architecture/QUALITY_GATES.md index 75fc87e39cf..dcb4ccb2433 100644 --- a/docs/i18n/uk-UA/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/uk-UA/docs/architecture/QUALITY_GATES.md @@ -19,229 +19,224 @@ ### Допуск кандидата -Кожен із робочих процесів CI та Quality Gates формує стабільний вердикт: `Gate / CI` і -`Gate / Quality`. Їхня версіонована політика допуску визначає кожне завдання верхнього рівня +Робочі процеси CI і Quality Gates створюють стабільні вердикти: `Gate / CI` і +`Gate / Quality`. Їхня версіонована політика допуску визначає кожне попереднє завдання як обов’язкове або рекомендаційне. Застосовне обов’язкове завдання має завершитися успішно: -відсутні, скасовані, пропущені, незавершені й невідомі результати не можуть підтвердити PASS. -Коректна класифікація «лише документація» або «лише каталог» може зробити гілку перевірок коду незастосовною; -чернетка PR не вважається прийнятним кандидатом. Мітка `hotfix` не скасовує вимоги щодо доказів. +відсутні, скасовані, пропущені, незавершені та невідомі результати не можуть підтвердити PASS. +Коректна класифікація docs-only або catalog-only може зробити гілку виконання коду незастосовною; +чернетка PR не вважається прийнятним кандидатом. Мітка `hotfix` не скасовує вимогу щодо доказів. -Обидва робочі процеси охоплюють PR і надсилання змін до гілок main/release, ручний запуск і -події групи злиття. Для надсилання змін, ручного запуску та групи злиття виконується повний набір перевірок. Форки -та групи злиття використовують розміщені виконавці для завдань, які за інших умов вибирають самостійно розміщені -виконавці; перед розгортанням необхідно перевірити достатність ресурсів розміщених виконавців. +Обидва робочі процеси охоплюють PR і пуші до гілок main/release, ручний запуск і +події merge-group. Для пушів, ручних запусків і merge-group виконується повний набір. +Форки та групи злиття використовують розміщені ранери для завдань, які за інших умов вибирають +самостійно розміщені ранери; перед розгортанням необхідно перевірити достатню місткість розміщених ранерів. Кожна JSON-квитанція ідентифікує SHA отриманої версії, запуск робочого процесу та спробу. -CLI відхиляє невідповідність між SHA отриманої версії та події. Тести робочого процесу пов’язують належність до політики -зі списком `needs` завдання, що формує вердикт, тому нова або видалена гілка перевірок не може непомітно зникнути. -Квитанції охоплюють лише власний робочий процес, а не публікацію, розгортання чи внутрішню логіку -наявного рекомендаційного сканера. Активація обох назв перевірок у правилах гілок є +CLI відхиляє невідповідність SHA отриманої версії та події. Тести робочого процесу пов’язують належність до політики +зі списком `needs` завдання вердикту, щоб нова або видалена гілка виконання не могла непомітно зникнути. +Квитанції охоплюють власний робочий процес, а не публікацію, розгортання чи внутрішню логіку +наявного рекомендаційного сканера. Активація обох назв перевірок у правилах гілки є окремою адміністративною зміною; додавання цих завдань саме по собі не захищає гілку. ### Інвентаризація статичного сканування -Версіонована інвентаризація псевдонімів npm і склад статичного сканування містяться у +Версіонований реєстр npm-псевдонімів і склад статичного сканування містяться у `config/quality/gate-manifest.json`. Запустіть `npm run check:gate-manifest`, щоб перевірити назви скриптів і точні команди за `package.json`; додавання, видалення та -розбіжності команд спричиняють помилку як у локальному хуку, так і в завданнях класифікації змін у CI. -Псевдонім не є завданням робочого процесу, екземпляром матриці чи тестовим випадком: ці показники +розбіжності команд призводять до невдачі як локального хука, так і завдань класифікації змін у CI. +Псевдонім не є завданням робочого процесу, екземпляром матриці чи тестовим випадком: ці кількості не можна подавати як взаємозамінні. Використовуйте `npm run quality:scan -- --list` або `npm run quality:scan:fast -- --list`, -щоб переглянути вибрані псевдоніми без їх виконання. Виконавець запускає +щоб переглянути вибрані псевдоніми без їх виконання. Ранер викликає точку входу npm, тому її середовище виконання (включно з Bun, де його налаштовано) зберігається. -Маніфест позначає псевдоніми поза цими профілями як такі, що запускаються окремо, а +Маніфест реєструє псевдоніми поза цими профілями як такі, що викликаються окремо, а команди обслуговування заборонені у профілях сканування лише для читання. Ці профілі охоплюють лише статичне сканування. Вони не сертифікують тести продукту, покриття, пакування, зовнішні перевірки чи повний допуск кандидата до випуску. Для допуску в робочому процесі використовуються пов’язані `config/quality/admission-policy.json` і -`scripts/quality/admission-verdict.mjs`. Профілі спостереження за випуском залишаються окремими; +`scripts/quality/admission-verdict.mjs`. Профілі спостерігача за випуском залишаються окремими; перевіряйте їхні застосовні перевірки та квитанції незалежно. Наведена нижче текстова -інвентаризація є довідковою інформацією, а не доказом того, що гейт фактично виконувався. +інвентаризація є довідковою, а не доказом фактичного виконання гейта. -Скрипти містяться в `scripts/check/` (гейти політики) і `scripts/quality/` (рушій поетапного підвищення вимог). +Скрипти містяться в `scripts/check/` (гейти політик) і `scripts/quality/` (рушій ратчету). Джерелом істини для CI є `.github/workflows/ci.yml`. -### Швидкий шлях для PR випуску (`quality.yml`) +### Швидкий шлях PR випуску (`quality.yml`) -`.github/workflows/quality.yml` доповнює CI для PR до гілок main/release, надсилання змін -до захищених гілок, ручного запуску та груп злиття. Для PR використовуються швидкі перевірки з фільтрацією за шляхами. Назавжди +`.github/workflows/quality.yml` доповнює CI для PR у main/release, пушів до захищених гілок, +ручних запусків і груп злиття. PR використовують швидкі перевірки з фільтрацією за шляхами. Постійно вимкнену дублювальну збірку видалено; фактичні перевірки збірки, пакування та запуску залишаються в CI. -| Завдання | Область застосування | Блокування | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -| `Docs Gates (fast-path)` | PR документації/коду; посилання в документації API та вся документація | Так | -| `Fast Quality Gates` | PR коду; статичні перевірки, перевірка типів, перевірка типів панелі керування, відповідні модульні тести | Так | -| `Forgotten sibling tests` | PR коду; змінені модулі зіставляються зі статичними споживачами та потенційними сусідніми тестами; шляхи через агрегувальні модулі та динамічний імпорт подаються як рекомендаційна діагностика з указаними винятками зі списку дозволів | **Рекомендаційне** | -| `Vitest (fast-path)` | PR коду; швидкий набір тестів vitest | Так | -| `Unit Tests fast-path` | PR коду; набір модульних тестів у 4 сегментах | Так | -| `No new ESLint warnings` | PR коду; перевірка lint з урахуванням приглушень | Так, включно з форками | -| `Merge integrity (changelog + generated skills)` | PR, що не є чернетками; синхронізація журналу змін і згенерованих навичок | Так, включно з форками | - -#### Звіт про забуті сусідні тести - -`npm run check:forgotten-sibling-tests` повторно використовує засіб визначення імпортів, що лежить в основі карти впливу тестів. -Для кожного зміненого робочого модуля він формує детерміновані ланцюжки -`змінений модуль/символ -> статичний споживач -> потенційний сусідній тест`, якщо потенційний -тест відсутній у різниці pull request. Підсумок Markdown і результат JSON зберігаються як -артефакт робочого процесу `forgotten-sibling-tests` для калібрування перед будь-яким запровадженням блокування. - -Повторні експорти через barrel-файли та динамічні імпорти використовуються лише для діагностики розв’язання залежностей; вони ніколи не створюють -блокувального результату перевірки. Перевірені винятки зберігаються у -`config/quality/forgotten-sibling-allowlist.json`. Кожен запис має вказувати споживача та тест-кандидат, -містити конкретне обґрунтування й посилання на issue або pull request у GitHub. Некоректно сформовані записи призводять -до блокування. Винятки не можуть приховати видалений тест-кандидат або diff, який додає `.skip`/`.todo`; -послаблення перевірок та інші способи маскування залишаються сферою відповідальності незалежного блокувального -гейта `check:test-masking`. +| Завдання | Область | Блокування | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `Docs Gates (fast-path)` | PR документації/коду; посилання на документацію API та повна документація | Так | +| `Fast Quality Gates` | PR коду; статичні перевірки, перевірка типів, перевірка типів панелі керування, заторкнуті модульні тести | Так | +| `Forgotten sibling tests` | PR коду; змінені модулі, простежені до статичних споживачів і потенційних споріднених тестів; шляхи barrel-файлів і динамічного імпорту подаються як рекомендаційна діагностика із зазначеними винятками зі списку дозволів | **Рекомендаційне** | +| `Vitest (fast-path)` | PR коду; швидкий набір vitest | Так | +| `Unit Tests fast-path` | PR коду; набір модульних тестів із 4 шардів | Так | +| `No new ESLint warnings` | PR коду; перевірка lint з урахуванням придушень | Так, включно з форками | +| `Merge integrity (changelog + generated skills)` | PR, що не є чернетками; синхронізація журналу змін і згенерованих навичок | Так, включно з форками | + +#### Звіт про забуті споріднені тести + +`npm run check:forgotten-sibling-tests` повторно використовує розпізнавач імпортів, що лежить в основі карти впливу тестів. +Для кожного зміненого робочого модуля він повідомляє детерміновані ланцюжки +`змінений модуль/символ -> статичний споживач -> потенційний споріднений тест`, коли потенційний +тест відсутній у diff запиту на злиття. Зведення Markdown і результат JSON зберігаються як +артефакт робочого процесу `forgotten-sibling-tests` для калібрування перед будь-яким розгортанням блокування. + +Барельні реекспорти та динамічні іморти використовуються лише для діагностики розв’язання; вони ніколи не створюють +блокувального результату. Перевірені винятки містяться у +`config/quality/forgotten-sibling-allowlist.json`. Кожен запис має вказувати споживача й тест-кандидат, +містити конкретне обґрунтування та посилання на issue або pull request у GitHub. Некоректно сформовані записи +призводять до блокування. Винятки не можуть приховати видалений тест-кандидат або diff, що додає `.skip`/`.todo`; +послаблення перевірок та інше маскування залишаються у сфері відповідальності незалежного блокувального +шлюзу `check:test-masking`. ### Завдання: `lint` Запускається для кожного PR до `main`. У разі невдачі блокує злиття. -| Скрипт (`npm run ...`) | Перевіряє | Блокувальний | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | -| `check:node-runtime` | Версія Node.js перебуває в межах підтримуваного діапазону | Так | -| `check:cycles` | Циклічні імпорти — усі модулі `src/` + `open-sse/` | Так | -| `check:route-validation:t06` | Наявність схем Zod для всіх маршрутів (політика рівня 6) | Так | -| `check:any-budget:t11` | Кількість `@ts-expect-error // any` не перевищує бюджет (catraca рівня 11) | Так | -| `check:provider-consistency` | Кожен провайдер у `providers.ts` має відповідний запис у `providerRegistry.ts` (і навпаки, у межах списку дозволених) | Так | -| `check:model-lifecycle` | Три вручну підтримувані таблиці маршрутизації залишаються узгодженими із зафіксованим у репозиторії знімком життєвого циклу (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не оцінює жоден виведений з експлуатації ідентифікатор, який може маршрутизувати `REGISTRY`; кожна ціль `BUILT_IN_ALIASES` наявна в `REGISTRY` і відсутня у знімку виведених з експлуатації ідентифікаторів; кожен виведений з експлуатації ідентифікатор, який усе ще є в `REGISTRY`, перенаправляється або вказаний у `allowedRetiredInCatalog`; і жодне джерело чи ціль `DEFAULT_DEGRADATION_MAP` не позначені як виведені з експлуатації в цьому знімку. Це не доводить, що модель наразі обслуговується активним зовнішнім сервісом. Перевірка виконується офлайн — шляхом порівняння з `config/quality/model-lifecycle.json`, який оновлюється вручну за допомогою `npm run quality:refresh-model-lifecycle` (потребує мережі; не інтегровано в CI). `allowedRetiredInCatalog` — це храповий механізм поступового скорочення: додавайте запис лише за наявності завдання для відстеження. | Так | -| `check:fetch-targets` | Кожен `fetch("/api/...")` у клієнтській частині `src/` відповідає реальному `route.ts` | Так | -| `check:deps` | Усі залежності, які можна встановити за допомогою `npm install`, у кожному `package.json` репозиторію наявні в `dependency-allowlist.json`; нові незакріплені або слопсквотингові пакети позначаються | Так | -| `audit:deps` | `npm audit` (кореневий каталог + electron) — немає попереджень високого/критичного рівня (частково дублює osv `check:vuln-ratchet`; див. список завдань із раціоналізації) | Так | -| `check:lockfile` | Цілісність `package-lock.json` — реєстр https, хеші цілісності, відсутність перевизначень хостів | Так | -| `check:licenses` | Список дозволених ліцензій SPDX для виробничих залежностей | Так | -| `check:tracked-artifacts` | Відсутні артефакти збірки / закомічені символічні посилання `node_modules` (також запускається в husky pre-commit; pre-push навмисно полегшений — #6716) | Так | -| `check:ai-attribution` | Відсутні трейлер AI/бота `Co-Authored-By` або примітка про генерацію ШІ в комітах, заголовку чи описі PR — жорстке правило №16 (у циклі швидких перевірок `quality.yml` для PR→`release/**` — читає дані події, не виконує жодних дій поза PR — і на кроці лише для PR у lint-перевірці `ci.yml` для PR→`main`; також у хуку husky `commit-msg`; співавтори-люди дозволені; #14436) | -| `check:vitest-exclusions` | Кожне виключення Vitest містить посилання на задачу для відстеження та наявне в `config/quality/vitest-exclusions.json` (#13204) | Так | -| `check:file-size` | Жоден файл вихідного коду не перевищує обмеження для відповідного розширення (храповий механізм: зафіксовані великі файли у списку `frozen`) | Так | -| `check:error-helper` | Відповіді з помилками у виконавцях/обробниках використовують `buildErrorBody()` / `sanitizeErrorMessage()` (жорстке правило №12) | Так | -| `check:migration-numbering` | SQL-файли міграцій пронумеровані послідовно, без пропусків і дублікатів | Так | -| `check:public-creds` | Жодних літеральних OAuth `client_id`/`client_secret` або вебключів Firebase поза `publicCreds.ts` (жорстке правило №11) | Так | -| `check:db-rules` | Жодного необробленого SQL поза модулями `src/lib/db/`; жодних імпортів із реекспортних модулів з `localDb.ts` (жорсткі правила №2/№5) | Так | -| `check:known-symbols` | Виконавці провайдерів, стратегії маршрутизації та транслятори, зареєстровані у відповідних таблицях диспетчеризації, відповідають файлам на диску — без осиротілих або неоголошених символів | Так | -| `check:route-guard-membership` | Кожен маршрут, що породжує дочірній процес, класифікований за допомогою `isLocalOnlyPath()` (жорсткі правила №15/№17) | Так | -| `check:test-discovery` | Кожен файл `*.test.ts` / `*.spec.ts` у репозиторії збирається принаймні одним засобом запуску тестів (храповий механізм: список осиротілих тестів у `test-discovery-baseline.json` може лише скорочуватися) | Так | -| `check:agent-skills-sync` | Згенеровані артефакти навичок агентів відповідають їхньому вихідному каталогу (без розбіжностей) | -| `check:provider-asset-provenance` | Логотипи/ресурси провайдерів мають зареєстрований запис про походження | -| `lint:json` | Файли конфігурації JSON успішно аналізуються та відповідають правилам лінтингу репозиторію | -| `typecheck:core` | Компіляція TypeScript без помилок (лише рекомендаційні попередження) | Так | -| `typecheck:noimplicit:core` | Суворий режим `noImplicitAny` — орієнтований на майбутнє; багато наявних місць виклику все ще потребують анотацій | **Рекомендаційна перевірка** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc`, обмежений областю `src/app/(dashboard)/**` (#7033) — ретельно відібраний список дозволених 27 файлів у `typecheck:core` не містить жодного TSX-файлу панелі керування, а `next build` також ніколи не перевіряє її типи (`next.config.mjs` задає `ignoreBuildErrors: true`), тому регресії з ідентифікаторами без оголошення (#6625/#6909) залишалися непомітними для CI. Відмінності порівнюються із зафіксованим базовим рівнем кількості помилок для кожного файлу та коду TS (`config/quality/dashboard-typecheck-baseline.json`, той самий шаблон перевірки застарілості, що й у `check:known-symbols`) — лише НОВІ помилки понад базову кількість спричиняють невиконання перевірки; знижуйте базовий рівень за допомогою `--update`, коли наявну помилку виправлено. | Так | +| Скрипт (`npm run ...`) | Що перевіряє | Блокувальний | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:node-runtime` | Версія Node.js перебуває в межах підтримуваного діапазону | Так | +| `check:cycles` | Циклічні імпорти в усіх `src/` + `open-sse/` (на основі AST, із розв’язанням `paths` із tsconfig). Базовий режим = рекомендаційний, виводить список циклів. `check:cycles:ratchet` (режим, який запускає CI) блокує, коли кількість перевищує граничне значення `metrics.cycles` у `quality-baseline.json` — наразі 14, `direction: down`, тому воно може лише зменшуватися (#15159 G-01/G-02) | Так (ratchet) | +| `check:route-validation:t06` | Наявність схем Zod у всіх маршрутах (політика рівня 6) | Так | +| `check:any-budget:t11` | Кількість `@ts-expect-error // any` не перевищує бюджет (catraca рівня 11) | Так | +| `check:provider-consistency` | Кожен провайдер у `providers.ts` має відповідний запис у `providerRegistry.ts` (і навпаки, у межах списку дозволених) | Так | +| `check:model-lifecycle` | Три таблиці маршрутизації, що підтримуються вручну, залишаються узгодженими зі збереженим у репозиторії знімком життєвого циклу (#11503): `FITNESS_TABLE` (`taskFitness.ts`) не оцінює жоден виведений з експлуатації ідентифікатор, який може маршрутизувати `REGISTRY`; кожна ціль `BUILT_IN_ALIASES` присутня в `REGISTRY` і відсутня у знімку виведених з експлуатації ідентифікаторів; кожен виведений з експлуатації ідентифікатор, який досі є в `REGISTRY`, перенаправляється або зазначений у `allowedRetiredInCatalog`; і жодне джерело чи ціль `DEFAULT_DEGRADATION_MAP` не позначені як виведені з експлуатації в цьому знімку. Це не доводить, що модель наразі обслуговується активним зовнішнім постачальником. Автономна перевірка — порівнює з `config/quality/model-lifecycle.json`, який оновлюється вручну за допомогою `npm run quality:refresh-model-lifecycle` (потребує мережі; не інтегровано в CI). `allowedRetiredInCatalog` — це механізм поступового скорочення: додавайте запис лише за наявності задачі для відстеження. | Так | +| `check:fetch-targets` | Кожен `fetch("/api/...")` у клієнтському коді `src/` веде до реального `route.ts` | Так | +| `check:deps` | Усі залежності, які можна встановити через `npm install`, у кожному `package.json` репозиторію присутні в `dependency-allowlist.json`; нові залежності без зафіксованої версії або пакети з назвами, схожими на назви інших пакетів, позначаються | Так | +| `audit:deps` | `npm audit` (кореневий каталог + electron) — немає рекомендацій високого/критичного рівня (частково збігається з osv `check:vuln-ratchet`; див. перелік завдань із раціоналізації) | Так | +| `check:lockfile` | Цілісність `package-lock.json` — реєстр https, хеші цілісності, відсутність перевизначень хостів | Так | +| `check:licenses` | Список дозволених ліцензій SPDX для робочих залежностей | Так | +| `check:tracked-artifacts` | Відсутність артефактів збірки / зафіксованих символічних посилань `node_modules` (також запускається в husky pre-commit; pre-push навмисно спрощений — #6716) | Так | +| `check:ai-attribution` | Відсутність трейлера AI/бота `Co-Authored-By` або примітки про генерацію ШІ в комітах, заголовку чи описі PR — жорстке правило №16 (у циклі швидких перевірок `quality.yml` для PR→`release/**` — читає дані події, нічого не робить поза PR — і на кроці лише для PR у перевірці lint у `ci.yml` для PR→`main`; також у хуку husky `commit-msg`; співавтори-люди дозволені; #14436) | +| `check:vitest-exclusions` | Кожне виключення Vitest містить посилання на задачу для відстеження та наявне в `config/quality/vitest-exclusions.json` (#13204) | Так | +| `check:file-size` | Жоден файл вихідного коду не перевищує обмеження для відповідного розширення (храповий механізм: зафіксовані великі файли у списку `frozen`) | Так | +| `check:error-helper` | Для відповідей про помилки у виконавцях/обробниках використовуються `buildErrorBody()` / `sanitizeErrorMessage()` (жорстке правило №12) | Так | +| `check:migration-numbering` | SQL-файли міграцій мають послідовну нумерацію без пропусків або дублікатів | Так | +| `check:public-creds` | Немає літеральних OAuth `client_id`/`client_secret` або вебключів Firebase поза `publicCreds.ts` (Жорстке правило №11) | Так | +| `check:db-rules` | Немає необробленого SQL поза модулями `src/lib/db/`; немає імпортів через барель із `localDb.ts` (Жорсткі правила №2/№5) | Так | +| `check:known-symbols` | Виконавці провайдерів, стратегії маршрутизації та перекладачі, зареєстровані у відповідних таблицях диспетчеризації, відповідають файлам на диску — без осиротілих або неоголошених символів | Так | +| `check:route-guard-membership` | Кожен маршрут, який запускає дочірній процес, класифіковано за допомогою `isLocalOnlyPath()` (Жорсткі правила №15/№17) | Так | +| `check:test-discovery` | Кожен файл `*.test.ts` / `*.spec.ts` у репозиторії виявляється принаймні одним засобом запуску тестів (храповий механізм: список осиротілих файлів у `test-discovery-baseline.json` може лише скорочуватися) | Так | +| `check:agent-skills-sync` | Згенеровані артефакти навичок агентів відповідають їхньому вихідному каталогу (без розбіжностей) | +| `check:provider-asset-provenance` | Логотипи/ресурси постачальників мають зафіксований запис про походження | +| `lint:json` | Файли конфігурації JSON успішно аналізуються та відповідають правилам перевірки репозиторію | +| `typecheck:core` | Компіляція TypeScript без помилок (лише рекомендаційні попередження) | Так | +| `typecheck:noimplicit:core` | Суворий режим `noImplicitAny` — орієнтований на майбутнє; багато наявних місць виклику все ще потребують анотацій | **Рекомендаційно** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc`, обмежений областю `src/app/(dashboard)/**` (#7033), — сформований вручну список дозволених 27 файлів у `typecheck:core` не містить жодного TSX-файлу панелі керування, а `next build` також ніколи не перевіряє їхні типи (`next.config.mjs` задає `ignoreBuildErrors: true`), тому регресії з осиротілими ідентифікаторами в них (#6625/#6909) були невидимими для CI. Відмінності порівнюються із зафіксованою базовою кількістю помилок для кожного файлу й кожного коду TypeScript (`config/quality/dashboard-typecheck-baseline.json`, за тим самим принципом контролю застарілості, що й `check:known-symbols`) — перевірка завершується невдало лише за наявності НОВИХ помилок понад базову кількість; зменшуйте базове значення за допомогою `--update`, коли наявну помилку виправлено. | Так | ### Завдання: `quality-gate` -Запускається після `test-coverage`. У разі невиконання блокує злиття. +Запускається після `test-coverage`. У разі невдачі блокує злиття. -| Скрипт | Що перевіряє | Блокування | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| `quality:collect` | Створює `quality-metrics.json` (кількість попереджень ESLint, покриття з об’єднаного звіту сегментів) | Так (передує ratchet-перевірці) | -| `quality:ratchet` | Жодна метрика в `quality-baseline.json` не погіршилася (попередження ESLint ≤ базового рівня; покриття ≥ базового рівня) | Так | -| `check:duplication` | Дублювання коду (jscpd@4) не перевищує базовий рівень у `quality-baseline.json` | Так | -| `check:complexity` | Цикломатична складність на рівні файлу не перевищує граничного значення (базові правила ESLint `complexity` + `max-lines-per-function`) | Так | -| `check:cognitive-complexity` | Ratchet-перевірка когнітивної складності (`eslint-plugin-sonarjs`) — окремий прохід ESLint; CI запускає обидві перевірки разом як єдиний крок `check:complexity-ratchets` | Так | -| `check:dead-code` | Ratchet-перевірка невикористовуваних експортів / файлів (knip) не погіршилася порівняно з базовим рівнем | Так | -| `check:compression-budget` | Бюджет бенчмарку стиснення — мінімальні пороги економії токенів для кожного рушія не повинні погіршуватися | Так | -| `check:type-coverage` | Ratchet-перевірка відсотка типізованого коду (`type-coverage`) не погіршилася; значною мірою охоплює `typecheck:noimplicit:core` | Так | -| `check:codeql-ratchet` | Кількість відкритих сповіщень CodeQL не збільшилася (зчитується через `gh api`; коректний пропуск без токена) — періодичність оновлення та ручний запуск: див. «Ratchet-перевірка CodeQL» нижче | Так | +| Скрипт | Перевіряє | Блокування | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `quality:collect` | Створює `quality-metrics.json` (кількість попереджень ESLint, покриття з об’єднаного звіту сегментів) | Так (передує ratchet) | +| `quality:ratchet` | Жодна метрика в `quality-baseline.json` не погіршилася (попередження ESLint ≤ базового рівня; покриття ≥ базового рівня) | Так | +| `check:duplication` | Дублювання коду (jscpd@4) не перевищує базовий рівень у `quality-baseline.json` | Так | +| `check:complexity` | Цикломатична складність на рівні файлу не перевищує граничного значення (основні правила ESLint `complexity` + `max-lines-per-function`) | Так | +| `check:cognitive-complexity` | Ratchet когнітивної складності (`eslint-plugin-sonarjs`) — окремий прохід ESLint; CI запускає обидві перевірки разом як єдиний крок `check:complexity-ratchets` | Так | +| `check:dead-code` | Ratchet невикористаних експортів / файлів (knip) не погіршується порівняно з базовим рівнем | Так | +| `check:compression-budget` | Бюджет бенчмарку стиснення — мінімальні значення економії токенів для кожного рушія не повинні погіршуватися | Так | +| `check:type-coverage` | Ratchet відсотка типізованого коду (`type-coverage`) не погіршується; значною мірою охоплює `typecheck:noimplicit:core` | Так | +| `check:codeql-ratchet` | Кількість відкритих сповіщень CodeQL не збільшується (зчитується через `gh api`; коректний пропуск без токена) — частоту оновлення та ручний запуск див. у розділі «CodeQL ratchet» нижче | Так | ### Завдання: `quality-extended` Усе завдання має рекомендаційний характер (`continue-on-error: true`). Ratchet-перевірки на основі npm -виконуються повноцінно; зовнішні сканери встановлюються через `gh release download` і самостійно пропускають перевірку (exit 0), -якщо бінарний файл усе ще відсутній. - -| Скрипт | Що перевіряє | Блокування | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | -| `check:circular-deps` | Відсутність циклічних залежностей (dpdm) | **Рекомендаційне** | -| `check:bundle-size` | Розмір бандла не перевищує граничного значення | **Рекомендаційне** | -| `check:secrets` | Сканування секретів (gitleaks) — пропускається, якщо бінарний файл відсутній | **Рекомендаційне** | -| `check:vuln-ratchet` | Вразливості залежностей (osv-scanner) не збільшилися — пропускається, якщо бінарний файл відсутній | **Рекомендаційне** | -| `check:workflows` | Лінтинг робочих процесів (actionlint + zizmor); відсутні/несправні сканери, недійсні звіти або відсутній базовий рівень ratchet-перевірки призводять до стану INCOMPLETE. Дійсні знахідки обробляються відповідно до вибраної суворої/рекомендаційної/ratchet-політики | Виконання обов’язкове; ratchet-перевірка zizmor блокує в CI | -| `check:openapi-breaking` | Несумісні зміни публічного контракту API (`openapi.yaml`) порівняно з базовою гілкою (oasdiff) — створює `openapiBreaking=N`; пропускається, якщо oasdiff відсутній або базову специфікацію неможливо отримати | **Рекомендаційне** | +виконуються фактично; зовнішні сканери встановлюються через `gh release download` і самостійно пропускають +перевірку (exit 0), якщо виконуваний файл усе ще відсутній. + +| Скрипт | Перевіряє | Блокування | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| `check:circular-deps` | Відсутність циклічних залежностей (dpdm) | **Рекомендаційне** | +| `check:bundle-size` | Розмір пакета не перевищує граничного значення | **Рекомендаційне** | +| `check:secrets` | Сканування секретів (gitleaks) — пропускається, якщо виконуваний файл відсутній | **Рекомендаційне** | +| `check:vuln-ratchet` | Вразливості залежностей (osv-scanner) не збільшуються — пропускається, якщо виконуваний файл відсутній | **Рекомендаційне** | +| `check:workflows` | Лінтинг робочих процесів (actionlint + zizmor); відсутні/несправні сканери, недійсні звіти або відсутня базова лінія ratchet спричиняють стан INCOMPLETE. Чинні знахідки обробляються відповідно до вибраної суворої/рекомендаційної/ratchet-політики | Виконання обов’язкове; ratchet zizmor блокує в CI | +| `check:openapi-breaking` | Несумісні зміни публічного контракту API (`openapi.yaml`) порівняно з базовою гілкою (oasdiff) — виводить `openapiBreaking=N`; пропускається, якщо oasdiff відсутній або базову специфікацію неможливо отримати | **Рекомендаційне** | ### Завдання: `docs-sync-strict` -Запускається для кожного PR до `main`. У разі невдачі блокує злиття. - -| Скрипт | Що перевіряє | Блокувальний | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `check:docs-all` | Мета-шлюз, який послідовно запускає 6 наведених нижче підшлюзів | Так | -| ↳ `check:docs-sync` | Узгодженість версій у CHANGELOG / OpenAPI / llm.txt | Так | -| ↳ `check:docs-counts` | Числові дані в тексті (кількість провайдерів, міграцій тощо) перебувають у межах вікна храповика відносно фактичних значень | Так | -| ↳ `check:env-doc-sync` | Кожна змінна середовища в `.env.example` задокументована в таблиці документації і навпаки | Так | -| ↳ `check:deprecated-versions` | У документації немає рядків із застарілими версіями | Так | -| ↳ `check:doc-links` | Внутрішні markdown-посилання в документації ведуть до реальних файлів (у форматі `[text]`/`(path)`) | Так | -| ↳ `check:fabricated-docs` | Маршрути, змінні середовища, команди CLI, назви хуків і шляхи до файлів, згадані в документації, існують у кодовій базі. Жорсткий шлюз із `--strict`; без прапорця помилка не блокує. | Так (через `--strict` у CI) | -| `check:cli-i18n` | Рядки команд CLI наявні в усіх файлах локалей i18n | Так | -| `check:openapi-coverage` | Специфікація OpenAPI охоплює щонайменше порогову кількість реальних маршрутів, визначену храповиком | Так | -| `check:openapi-security-tiers` | Анотації рівнів безпеки в `openapi.yaml` узгоджуються з класифікаціями в `routeGuard.ts` | **Рекомендаційний** | -| `check:openapi-routes` | Кожен шлях у `openapi.yaml` відповідає реальному `route.ts` (захист від галюцинацій) | Так | -| `check:docs-symbols` | Кожне посилання `/api/...` у `docs/**/*.md` відповідає реальному `route.ts` (захист від галюцинацій) | Так | -| `i18n translation drift` | Неперекладені ключі у файлах локалей i18n — лише попередження | **Рекомендаційний** | +Запускається для кожного PR до `main`. У разі помилки блокує злиття. + +| Скрипт | Перевіряє | Блокувальний | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | +| `check:docs-all` | Мета-перевірка, яка послідовно запускає 6 наведених нижче підперевірок | Так | +| ↳ `check:docs-sync` | Узгодженість версій у CHANGELOG / OpenAPI / llm.txt | Так | +| ↳ `check:docs-counts` | Числові дані в тексті (кількість провайдерів, міграцій тощо) перебувають у межах допустимого порога відносно фактичних значень | Так | +| ↳ `check:env-doc-sync` | Кожна змінна середовища з `.env.example` задокументована в таблиці документації, і навпаки | Так | +| ↳ `check:deprecated-versions` | У документації немає рядків із застарілими версіями | Так | +| ↳ `check:doc-links` | Внутрішні markdown-посилання в документації ведуть до реальних файлів (у форматі `[текст]`/`(шлях)`) | Так | +| ↳ `check:fabricated-docs` | Маршрути, змінні середовища, команди CLI, назви хуків і шляхи до файлів, згадані в документації, існують у кодовій базі. Жорстка перевірка через `--strict`; без прапорця помилка є некритичною. | Так (через `--strict` у CI) | +| `check:cli-i18n` | Рядки команд CLI наявні в усіх файлах локалей i18n | Так | +| `check:openapi-coverage` | Специфікація OpenAPI охоплює щонайменше порогову кількість реальних маршрутів | Так | +| `check:openapi-security-tiers` | Анотації рівнів безпеки в `openapi.yaml` узгоджені з класифікаціями в `routeGuard.ts` | **Рекомендаційна** | +| `check:openapi-routes` | Кожен шлях у `openapi.yaml` відповідає реальному `route.ts` (захист від галюцинацій) | Так | +| `check:docs-symbols` | Кожне посилання `/api/...` у `docs/**/*.md` відповідає реальному `route.ts` (захист від галюцинацій) | Так | +| `i18n translation drift` | Неперекладені ключі у файлах локалей i18n — лише попередження | **Рекомендаційна** | ### Завдання: `i18n-ui-coverage` -| Скрипт | Що перевіряє | Блокувальний | -| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `check-ui-keys-coverage` (вбудований) | Покриття ключів i18n інтерфейсу становить ≥ 65% | Так | -| `check-ui-value-drift` (вбудований) | Після переписування англійського **значення** не залишається застарілих перекладів | Так | -| `check-new-key-coverage` (вбудований) | **Новий** англійський ключ перекладено в кожній локалі — маркер `__MISSING__:` відхиляється | Так | -| `check-translation-ratio` | Частка справжніх перекладів для кожної локалі (ідентичні англійським / заповнювачі / відсутні кінцеві вузли поза списком дозволених) не повинна перевищувати `config/quality/i18n-translation-baseline.json` + допустиме відхилення | **Рекомендаційний** | +| Скрипт | Перевіряє | Блокувальний | +| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `check-ui-keys-coverage` (вбудовано) | Покриття ключів i18n інтерфейсу становить ≥ 65% | Так | +| `check-ui-value-drift` (вбудовано) | Після зміни англійського **значення** не залишається застарілого перекладу | Так | +| `check-new-key-coverage` (вбудовано) | **Новий** англійський ключ перекладено в кожній локалі — маркер `__MISSING__:` не допускається | Так | +| `check-translation-ratio` | Частка справжніх перекладів для кожної локалі (елементи, ідентичні англійським / заповнювачі / відсутні елементи поза списком дозволених винятків) не повинна перевищувати `config/quality/i18n-translation-baseline.json` + допустимий запас | **Рекомендаційна** | -Потребує `fetch-depth: 0` — шлюз розбіжностей значень порівнює `en.json` із базою злиття. +Потребує `fetch-depth: 0` — перевірка змін значень порівнює `en.json` із базою злиття. -#### `check-ui-value-drift` — шлюз застарілих перекладів +#### `check-ui-value-drift` — перевірка застарілих перекладів -Виявляє єдину регресію i18n, яку інші шлюзи структурно не можуть побачити: англійське значення -переписано, а переклади, створені на основі _попереднього_ англійського тексту, залишилися, тож -неангломовні користувачі продовжують читати впевнено сформульований, але вже неправильний текст. +Виявляє одну регресію i18n, яку інші перевірки структурно не здатні помітити: англійське значення +переписано, а переклади, створені на основі _попереднього_ англійського тексту, залишаються, через що +неангломовні користувачі й надалі читають упевнено сформульований, але вже неправильний текст. -Це справді потрапило у випуск. `oauthModal.googleOAuthWarning` було переписано після додавання -помічника входу Antigravity (#5203); у **39 із 43 локалей** залишився текст, який указував операторам -«скопіювати повну URL-адресу та вставити її нижче» — процес, який неможливо завершити для цього -провайдера. Це залишалося непоміченим до #8463, оскільки: +Це справді потрапило у випуск. `oauthModal.googleOAuthWarning` було переписано після появи допоміжного +засобу входу Antigravity (#5203); у **39 із 43 локалей** залишився текст, який вказував операторам «скопіювати +повну URL-адресу та вставити її нижче» — процес, який неможливо завершити для цього провайдера. Це +залишалося непоміченим до #8463, оскільки: -- `sync-ui-keys` додає лише **відсутні** ключі, але ніколи не оновлює **застарілі**; +- `sync-ui-keys` додає лише **відсутні** ключі й ніколи не оновлює **застарілі**; - `check-ui-keys-coverage` враховує _наявність_ ключа, тому застарілий переклад вважається покритим; -- `check-translation-drift` відстежує дзеркала документації `docs/i18n//**.md` — - він ніколи не читає `src/i18n/messages/*.json`. Блокує в завданні `docs-sync-strict` після - повторної синхронізації 2026-09: відредагуйте основний документ → `npm run i18n:run -- --files=` (на рівні розділу, швидко). +- `check-translation-drift` відстежує дзеркальні копії документації `docs/i18n//**.md` — + він ніколи не читає `src/i18n/messages/*.json`. Перевірка є блокувальною в завданні `docs-sync-strict` після + повторної синхронізації 2026-09: змініть основний документ → `npm run i18n:run -- --files=` (на рівні розділу, швидко). -**Враховує різницю, а не базову лінію.** Він порівнює `en.json` у базі злиття з -робочим деревом; для кожного ключа, англійське значення якого змінилося, будь-яка локаль, -що все ще містить незмінену версію перекладу, вважається застарілою. Це навмисно -**заморожує наявний борг** — за різницею неможливо визначити, з якої старої англійської -версії походить давній переклад, тому перевірка оцінює лише те, чого торкається поточна -зміна. Альтернатива (базова лінія хешів для кожного ключа) потребувала б створення -згенерованого файла розміром ~600 КБ, утричі більшого за найбільшу наявну базову лінію, -який змінювався б у кожному PR з інтернаціоналізації. +**Враховує diff, а не спирається на базовий стан.** Перевірка порівнює `en.json` у базовій точці злиття з +робочим деревом; для кожного ключа, англійське значення якого змінилося, будь-яка локаль, що досі містить +незміненний переклад, вважається застарілою. Це навмисно **фіксує вже наявний технічний борг** — diff +не може показати, з якої старої англійської версії походить давній переклад, тому перевірка оцінює +лише те, чого торкається поточна зміна. Альтернатива (базовий стан із хешем для кожного ключа) потребувала б +згенерованого файла розміром близько 600 КБ, утричі більшого за найбільший наявний базовий файл, який змінювався б у кожному i18n PR. -Є два способи пройти перевірку: +Виконати вимогу можна двома способами: 1. оновити відповідні переклади або -2. задати для них значення `__MISSING__:` — тоді середовище виконання - повертає виправлений англійський текст (`src/i18n/request.ts::deepMergeFallback`, #7258), - а ключ додається до черги на переклад. +2. установити для них значення `__MISSING__:<нова англійська версія>` — тоді під час виконання повертається виправлений англійський текст + (`src/i18n/request.ts::deepMergeFallback`, #7258), а ключ додається до черги на переклад. -Якщо змінився **зміст** рядка, краще **перейменувати ключ**: новий ключ не може -успадкувати застарілий переклад. Саме цей підхід було використано в #8463. +Якщо змінився **зміст** рядка, краще **перейменувати ключ**: новий ключ не може успадкувати +застарілий переклад. Саме цей підхід використано в #8463. ```bash -npm run i18n:check-value-drift # суворий режим (виконується в CI) +npm run i18n:check-value-drift # суворий режим (використовується в CI) npm run i18n:check-value-drift:warn # лише звіт BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Завершується з кодом 0 і повідомленням `SKIP reason=base-unresolved`, якщо базовий каталог -не вдається прочитати (поверхневий клон без базового посилання), аналогічно до -`check-openapi-breaking`. +Завершується з кодом 0 і повідомленням `SKIP reason=base-unresolved`, якщо базовий каталог неможливо прочитати (поверхневе +клонування без базового ref), аналогічно до `check-openapi-breaking`. ### Завдання: `i18n` -Повна матриця перевірки інтернаціоналізації (одне завдання на локаль). Усе завдання має -рекомендаційний характер. +Повна матриця перевірки i18n (одне завдання для кожної локалі). Усе завдання має рекомендаційний характер. | Скрипт | Що перевіряє | Блокування | | ------------------------------- | ----------------------------------- | ------------------------------------------------------------------ | @@ -249,36 +244,35 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ### Завдання: `pr-test-policy` -Виконується лише для запитів на злиття. +Виконується лише для pull request. -| Скрипт | Що перевіряє | Блокування | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check:pr-test-policy` | PR, які змінюють робочий код у `src/`, `open-sse/`, `electron/` або `bin/`, мають містити або оновлювати тести (жорстке правило №8) | Так | -| `check:test-masking` | Змінені файли тестів не зменшують загальну кількість перевірок і не додають тавтологій `assert.ok(true)` | Так | -| `check:pr-evidence` | Опис PR містить підтвердження тестування/VPS для зміни (автоматизує жорстке правило №18 через пошук у тексті PR — ненадійно, див. беклог) | Так | +| Скрипт | Що перевіряє | Блокування | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check:pr-test-policy` | PR, які змінюють робочий код у `src/`, `open-sse/`, `electron/` або `bin/`, мають додавати чи оновлювати тести (жорстке правило №8) | Так | +| `check:test-masking` | Змінені тестові файли не зменшують загальну кількість перевірок і не додають тавтологій `assert.ok(true)` | Так | +| `check:pr-evidence` | Текст PR містить свідчення тестування/VPS для зміни (автоматизує жорстке правило №18 за допомогою grep тексту PR — ненадійно, див. Backlog) | Так | ### Завдання: `test-vitest` Виконується після `build`. У разі невдачі блокує злиття. -| Набір | Що перевіряє | Блокування | -| ---------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | Сервер MCP (110 інструментів), autoCombo, кеш — рушій vitest | Так | -| `test:vitest:ui` | Тести компонентів інтерфейсу — рушій vitest | **Блокує** — наявні раніше збої явно виключено у `vitest.config.ts`; нові збої спричиняють невиконання завдання | +| Набір тестів | Що перевіряє | Блокування | +| ---------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | Сервер MCP (110 інструментів), autoCombo, кеш — засіб запуску vitest | Так | +| `test:vitest:ui` | Тести компонентів UI — засіб запуску vitest | **Блокує** — наявні раніше збої явно виключено у `vitest.config.ts`; нові збої призводять до невиконання завдання | -### Нічні робочі процеси (за розкладом, рекомендаційні) +### Щонічні робочі процеси (за розкладом, рекомендаційні) -Вони виконуються за розкладом cron (і через `workflow_dispatch`), але ніколи не виконуються -для PR. Усі вони мають рекомендаційний характер. +Вони виконуються за розкладом cron (і через `workflow_dispatch`), але ніколи не виконуються для PR. Усі вони мають рекомендаційний характер. -| Робочий процес | Що перевіряє | Блокування | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `nightly-property` | Тести властивостей fast-check із випадковим початковим значенням і великою кількістю запусків | **Рекомендаційне** | -| `nightly-resilience` | Перевірку зростання купи, хаотичне внесення збоїв, навантажувальне/тривале тестування k6 | **Рекомендаційне** | -| `nightly-llm-security` | Захист від ін'єкцій promptfoo (режим блокування) + перевірки garak (пропускаються без секрету постачальника) | **Рекомендаційне** | -| `nightly-schemathesis` | Фаззинг контракту OpenAPI (schemathesis) на активному OmniRoute з використанням `docs/openapi.yaml` — виявляє порушення специфікації / необроблені помилки 500 (етап 8 B.4) | **Рекомендаційне** | -| `nightly-mutation` | Оцінку мутаційного тестування Stryker для швидкого набору модульних тестів — уцілілі мутанти виявляють слабкі перевірки | **Рекомендаційне** | -| `nightly-compat` | Матрицю сумісності рушія Node для підтримуваних діапазонів `engines.node` | **Рекомендаційне** | +| Робочий процес | Що перевіряє | Блокування | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `nightly-property` | Тести властивостей fast-check із випадковим початковим значенням і великою кількістю запусків | **Рекомендаційне** | +| `nightly-resilience` | Перевірку зростання купи, хаотичне внесення відмов, навантажувальне/тривале тестування k6 | **Рекомендаційне** | +| `nightly-llm-security` | Захист від ін’єкцій promptfoo (режим блокування) і зондування garak (пропускається без секрету постачальника) | **Рекомендаційне** | +| `nightly-schemathesis` | Фаззинг контракту OpenAPI (schemathesis) на запущеному OmniRoute з використанням `docs/openapi.yaml` — виявляє порушення специфікації / необроблені помилки 500 (Fase 8 B.4) | **Рекомендаційне** | +| `nightly-mutation` | Показник мутаційного тестування Stryker для швидкого набору модульних тестів — мутанти, що вижили, виявляють слабкі перевірки | **Рекомендаційне** | +| `nightly-compat` | Матрицю сумісності рушія Node для підтримуваних діапазонів `engines.node` | **Рекомендаційне** | --- @@ -548,43 +542,43 @@ push (`release-green`); пакетно виконується лише фікс --- -## Беклог раціоналізації (перегляд ROI — Фаза 9 Хвиля 3) +## Беклог раціоналізації (огляд ROI — Фаза 9 Хвиля 3) Цей перелік було звірено з `ci.yml` 2026-06-17 (у попередній версії було пропущено `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Перегляд ROI звіреного набору -виявив наведені нижче кандидатури для раціоналізації. **Об’єднання є механічними змінами CI; -перемикання/видалення є політичними рішеннями, зарезервованими за оператором.** Наразі нічого -з наведеного нижче не застосовано. +`check:codeql-ratchet`, `check:pr-evidence`). Огляд ROI звіреного набору +виявив наведені нижче кандидатури для раціоналізації. **Об’єднання є механічними змінами +CI; увімкнення/видалення є політичними рішеннями, зарезервованими за оператором.** Нічого +з наведеного нижче ще не застосовано. -**Також не задокументовано вище** (рекомендаційне, низька інформативність): завдання `docs-lint` -(markdownlint + Vale, усе завдання з `continue-on-error`) та окремі робочі процеси сканерів +**Також не задокументовано вище** (рекомендаційні перевірки, слабкий сигнал): завдання `docs-lint` +(markdownlint + Vale, для всього завдання встановлено `continue-on-error`) та окремі робочі процеси сканерів `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` міститься у -`quality-baseline.json`, але не підключено до блокувального храповика в `ci.yml` — метрика -наразі не використовується. - -### Об’єднання / усунення дублювання (механічне, нижчий ризик) - -Кожного кандидата було перевірено на відповідність актуальному стану шлюзів 2026-06-17 (довіряй, але перевіряй); -виявилося, що кілька «очевидних» об’єднань приховують технічний борг і **не** є готовими прямими замінами. - -- **`check:docs-sync` запускається двічі** — окремо в завданні `lint` і ще раз усередині `check:docs-all` (`docs-sync-strict`) та хука husky pre-commit. ✅ **ВИКОНАНО** — окремий виклик у `lint` видалено. -- **Сканування CVE** — ❌ **НЕ є простим об’єднанням.** `audit:deps` завершується жорсткою помилкою за будь-якої CVE високої/критичної важливості; `check:vuln-ratchet` (osv) завершується помилкою лише в разі _регресії_ відносно базового рівня (наразі 1 MODERATE). Семантика різна — видалення `audit:deps` призвело б до втрати абсолютного шлюзу для високої/критичної важливості. Залишити обидва. -- **Виявлення циклів** — ❌ **НЕ є простим об’єднанням.** `check:circular-deps` (dpdm) повідомляє про **91 цикл** (саме тому він має рекомендаційний статус); його не можна зробити блокувальним, не усунувши їх спочатку, і він має ширше охоплення, ніж успішний, ретельно підібраний `check:cycles`. Залишити `check:cycles` блокувальним; усунення 91 циклу dpdm є окремим пунктом беклогу. -- **Складність** — ✅ **ВИКОНАНО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): один прохід ESLint, підрахунок за ruleId, щоб базові рівні цикломатичної складності+максимальної кількості рядків і когнітивної складності залишалися незалежними; окремі `check:complexity` / `check:cognitive-complexity` збережено для локального `--update`. -- **Антигалюцинація `/api`** — ✅ **ВИКОНАНО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): один перелік FS для `src/app/api`, openapi-routes + docs-symbols і надалі звітують незалежно; окремі перевірки збережено для локальних запусків. -- **`check:node-runtime` запускається в 11 завданнях** — ⚠️ **низький ROI.** Кожне виконується на окремому runner, а перевірка триває <1с; загальна економія ~10с ціною втрати дешевого запобіжника для кожного завдання. Не варте супутніх змін. -- **`typecheck:noimplicit:core` у lint CI** — ✅ **видалено із завдання lint** (мало рекомендаційний статус `continue-on-error`); блокувальна поверхня типів — `typecheck:core` + `check:type-coverage`. Локальний скрипт збережено. - -### Перемкнути / вирішити (політика оператора) - -- `check:openapi-security-tiers` (рекомендаційний) — ❌ **НЕ можна просто перемкнути.** Він завершується з кодом 0, але попереджає, що в кількох маршрутах `traffic-inspector` у `LOCAL_ONLY_API_PREFIXES` немає анотації `x-loopback-only: true`. Для примусового застосування спочатку потрібно додати ці анотації до `openapi.yaml`. -- `typecheck:noimplicit:core` (рекомендаційний) — значною мірою охоплюється блокувальним храповиком `check:type-coverage`. Перетворити на храповик або видалити надлишковий другий прохід `tsc`. -- `test:vitest:ui` (тепер **блокувальний**) — попередньо наявні збої явно виключено у `vitest.config.ts` за допомогою коментарів відстеження `// #8618`; нові збої спричиняють падіння завдання. -- `check:secrets` (gitleaks, блокувальний храповик, зафіксований на рівні 3 задокументованих хибнопозитивних спрацювань) — додати ці 3 випадки до списку дозволів, щоб досягти 0, або понизити до рекомендаційного статусу. Перетинається з нативним скануванням секретів GitHub + `check:public-creds`. -- `check:pr-evidence` (блокувальний, виконує grep у прозовому тексті тіла PR) — високий ризик хибнопозитивних спрацювань; видалення послабить забезпечення виконання Жорсткого правила №18, тож це справді політичне рішення. -- `semgrep` (окремий рекомендаційний процес) — перетинається з CodeQL для сімейств OWASP; підключити його базовий рівень до храповика або видалити. +`quality-baseline.json`, але не підключено до блокувального храповика в `ci.yml` — наразі +ця метрика осиротіла. + +### Об’єднання / усунення дублювання (механічні зміни, нижчий ризик) + +Кожну кандидатуру було перевірено проти актуального стану шлюзів 2026-06-17 (довіряй, але перевіряй); +виявилося, що кілька «очевидних» об’єднань приховують борг і **не** є готовими безпечними замінами. + +- **`check:docs-sync` запускається двічі** — окремо в завданні `lint` і ще раз усередині `check:docs-all` (`docs-sync-strict`) та в husky-хуку перед комітом. ✅ **ВИКОНАНО** — окремий виклик у `lint` видалено. +- **Сканування CVE** — ❌ **НЕ є простим об’єднанням.** `audit:deps` жорстко завершується помилкою за будь-якої CVE високої/критичної серйозності; `check:vuln-ratchet` (osv) завершується помилкою лише в разі _регресії_ відносно базового рівня (наразі 1 MODERATE). Семантика різна — видалення `audit:deps` призвело б до втрати абсолютного шлюзу для високих/критичних вразливостей. Залишити обидві перевірки. +- **Виявлення циклів** — ✅ **ВИКОНАНО** (#15159 G-01/G-02). У старому тексті тут `check:cycles` називався «зеленим, вибірковим» шлюзом, а збереження його блокувальним обґрунтовувалося тим, що `check:circular-deps` (dpdm) повідомляв про 91 цикл. Цей зелений статус був **хибно зеленим**: `check:cycles` сканував 5 підкаталогів (450 файлів), зіставляв лише статичні `import|export … from` і відкидав усі специфікатори `@/` та `@omniroute/open-sse/`, тому не міг побачити цикли з динамічним імпортом і псевдонімами, які переважали в репозиторії. Виправлено: тепер шлюз обходить `src` + `open-sse` (5023 файли), збирає специфікатори з AST TypeScript (тому `import("…")` враховується, а `typeof import("…")` у позиції типу — ні) та розпізнає `paths` із tsconfig. Він знаходить **14** циклів, а не 0. Оскільки 14 наявних циклів неможливо виправити в PR зі зміною шлюзу, `check:cycles` тепер є **храповиком** (`--ratchet`, верхня межа `metrics.cycles.value = 14` у `quality-baseline.json`, `direction: down`) — він блокує будь-яку _регресію_, і кількість може лише зменшуватися. CI запускає `npm run check:cycles:ratchet`. Поступове скорочення виконується разом з **A-01**. `check:circular-deps` (dpdm) залишається рекомендаційною ширшою другою думкою. +- **Складність** — ✅ **ВИКОНАНО** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): один обхід ESLint, підрахунок за ruleId, завдяки чому базові рівні цикломатичної складності+максимальної кількості рядків і когнітивної складності залишаються незалежними; окремі `check:complexity` / `check:cognitive-complexity` збережено для локального `--update`. +- **Захист від галюцинацій щодо `/api`** — ✅ **ВИКОНАНО** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): одна інвентаризація `src/app/api` у файловій системі, openapi-routes + docs-symbols усе ще звітують незалежно; окремі перевірки збережено для локальних запусків. +- **`check:node-runtime` запускається в 11 завданнях** — ⚠️ **низький ROI.** Кожне завдання виконується на окремому раннері, а перевірка триває <1 с; загальна економія становить ~10 с ціною втрати дешевого захисного механізму для кожного завдання. Не варте зайвих змін. +- **`typecheck:noimplicit:core` у lint CI** — ✅ **видалено із завдання lint** (було рекомендаційним із `continue-on-error`); блокувальна поверхня типів — `typecheck:core` + `check:type-coverage`. Локальний скрипт збережено. + +### Увімкнути / вирішити (політика оператора) + +- `check:openapi-security-tiers` (рекомендаційна перевірка) — ❌ **НЕ можна просто зробити блокувальною.** Вона завершується з кодом 0, але попереджає, що в кількох маршрутах `traffic-inspector` під `LOCAL_ONLY_API_PREFIXES` відсутня анотація `x-loopback-only: true`. Для її примусового застосування спочатку потрібно додати ці анотації до `openapi.yaml`. +- `typecheck:noimplicit:core` (рекомендаційна перевірка) — значною мірою перекривається блокувальним храповиком `check:type-coverage`. Перетворити на храповик або видалити надлишковий другий прохід `tsc`. +- `test:vitest:ui` (тепер **блокувальна перевірка**) — наявні збої явно виключено у `vitest.config.ts` за допомогою коментарів відстеження `// #8618`; нові збої спричиняють помилку завдання. +- `check:secrets` (gitleaks, блокувальний храповик, зафіксований на рівні 3 задокументованих хибнопозитивних результатів) — додати ці 3 результати до списку дозволених, щоб досягти 0, або понизити до рекомендаційної перевірки. Перекривається з нативним скануванням секретів GitHub + `check:public-creds`. +- `check:pr-evidence` (блокувальна перевірка, що шукає шаблони в прозі тіла PR) — високий ризик хибнопозитивних результатів; її видалення послабить дотримання Hard Rule #18, тому це справжнє політичне рішення. +- `semgrep` (окрема рекомендаційна перевірка) — перекривається з CodeQL щодо сімейств OWASP; підключити її базовий рівень до храповика або видалити. --- diff --git a/docs/i18n/ur/CONTRIBUTING.md b/docs/i18n/ur/CONTRIBUTING.md index c187e9a6857..4ebb91f1798 100644 --- a/docs/i18n/ur/CONTRIBUTING.md +++ b/docs/i18n/ur/CONTRIBUTING.md @@ -388,20 +388,20 @@ OAuth اسناد `src/lib/oauth/constants/oauth.ts` میں اور سروس `src/ ## پُل ریکویسٹ چیک لسٹ -- [ ] ٹیسٹ کامیاب ہوں (`npm test`) -- [ ] لنٹنگ کامیاب ہو (`npm run lint`) -- [ ] بلڈ کامیاب ہو (`npm run build`) -- [ ] نئے پبلک فنکشنز اور انٹرفیسز کے لیے TypeScript ٹائپس شامل کی گئی ہوں -- [ ] کوئی ہارڈ کوڈ کردہ راز یا فال بیک ویلیوز نہ ہوں -- [ ] پبلک اپ اسٹریم اسناد `resolvePublicCred()` کے ذریعے شامل کی گئی ہوں ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) دیکھیں)، کبھی بھی لٹریلز کی صورت میں نہیں -- [ ] خرابی کے جوابات `buildErrorBody()` / `sanitizeErrorMessage()` کے ذریعے بھیجے جائیں — جوابی باڈیز میں کوئی خام اسٹیک ٹریس نہ ہو ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) دیکھیں) -- [ ] شیل کمانڈز (`exec` / `spawn`) رن ٹائم ویلیوز کو اسٹرنگ انٹرپولیشن کے بجائے `env` کے ذریعے پاس کریں +- [ ] ٹیسٹس کامیاب ہوں (`npm test`) +- [ ] لِنٹنگ کامیاب ہو (`npm run lint`) +- [ ] بِلڈ کامیاب ہو (`npm run build`) +- [ ] نئے عوامی فنکشنز اور انٹرفیسز کے لیے TypeScript ٹائپس شامل کی گئی ہوں +- [ ] کوئی ہارڈ کوڈ شدہ راز یا فال بیک اقدار نہ ہوں +- [ ] عوامی اپ اسٹریم اسناد `resolvePublicCred()` کے ذریعے شامل کی گئی ہوں ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) دیکھیں)، کبھی بھی لِٹرلز کے طور پر نہیں +- [ ] خرابی کے جوابات `buildErrorBody()` / `sanitizeErrorMessage()` کے ذریعے بھیجے جائیں — جوابی باڈیز میں خام اسٹیک ٹریسز نہ ہوں ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) دیکھیں) +- [ ] شیل کمانڈز (`exec` / `spawn`) رن ٹائم اقدار کو اسٹرنگ انٹرپولیشن کے بجائے `env` کے ذریعے منتقل کریں - [ ] تمام اِن پٹس کی Zod اسکیماؤں کے ذریعے توثیق کی گئی ہو -- [ ] صارف کو متاثر کرنے والی تبدیلیوں کے لیے `changelog.d/{features|fixes|maintenance}/-.md` کے تحت چینج لاگ **فریگمنٹ** شامل کیا گیا ہو ([`changelog.d/README.md`](./changelog.d/README.md) دیکھیں) — `CHANGELOG.md` میں براہِ راست ترمیم **نہ** کریں؛ فریگمنٹس کو ریلیز کے وقت یکجا کیا جاتا ہے اور ان میں مختلف PRs کے درمیان کبھی تصادم نہیں ہوتا +- [ ] صارف کو نظر آنے والی تبدیلیوں کے لیے `changelog.d/{features|fixes|maintenance}/-.md` کے تحت چینج لاگ **فریگمنٹ** شامل کیا گیا ہو ([`changelog.d/README.md`](./changelog.d/README.md) دیکھیں) — `CHANGELOG.md` میں براہِ راست ترمیم **نہ** کریں؛ فریگمنٹس کو ریلیز کے وقت یکجا کیا جاتا ہے اور ان میں مختلف پُل ریکویسٹس کے درمیان کبھی تنازع نہیں ہوتا - [ ] دستاویزات اپ ڈیٹ کی گئی ہوں (اگر قابلِ اطلاق ہو) -- [ ] کوئی نیا CodeQL / Secret-Scanning الرٹ نہ کھولا گیا ہو، یا ہر الرٹ کو متعلقہ `docs/security/` دستاویز کا حوالہ دینے والی تکنیکی توجیہ کے ساتھ مسترد کیا گیا ہو +- [ ] کوئی نیا CodeQL / Secret-Scanning الرٹ نہ کھلا ہو، یا ہر الرٹ کو متعلقہ `docs/security/` دستاویز کا حوالہ دیتے ہوئے تکنیکی جواز کے ساتھ مسترد کیا گیا ہو - [ ] چائلڈ پراسیسز شروع کرنے والے روٹس (`/api/mcp/`، `/api/cli-tools/runtime/`) کو `src/server/authz/routeGuard.ts` میں `isLocalOnlyPath()` کے طور پر درجہ بند کیا گیا ہو — [سخت اصول #15](docs/security/ROUTE_GUARD_TIERS.md) دیکھیں -- [ ] کمٹ پیغامات میں `Co-Authored-By` ٹریلرز نہ ہوں — کمٹس صرف ریپوزٹری مالک کی Git شناخت کے تحت ظاہر ہونے چاہییں (سخت اصول #16) +- [ ] کمٹ پیغامات میں AI/بوٹ کے `Co-authored-by` ٹریلرز نہ ہوں (سخت اصول #16) — جن انسانی معاونین کا کام دوبارہ استعمال کیا گیا ہو، انہیں معیاری `Co-authored-by: Name ` ٹریلرز کے ذریعے کریڈٹ دیا جائے --- diff --git a/docs/i18n/ur/docs/architecture/QUALITY_GATES.md b/docs/i18n/ur/docs/architecture/QUALITY_GATES.md index fd353d881d1..f9898e4956a 100644 --- a/docs/i18n/ur/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/ur/docs/architecture/QUALITY_GATES.md @@ -15,53 +15,53 @@ ratchet baseline یا pass/fail پالیسی استعمال کرتا ہے، او --- -## گیٹس کی فہرست اور نفاذی پروفائلز +## گیٹس کی فہرست اور عمل درآمد کی پروفائلز ### امیدوار کی منظوری CI اور Quality Gates ورک فلوز میں سے ہر ایک ایک مستحکم فیصلہ جاری کرتا ہے: `Gate / CI` اور -`Gate / Quality`۔ ان کی ورژن شدہ منظوری پالیسی ہر upstream job کو لازمی یا مشاورتی -کے طور پر درج کرتی ہے۔ قابلِ اطلاق لازمی job کا کامیاب ہونا ضروری ہے: غائب، -منسوخ، نظر انداز شدہ، زیرِ التوا اور نامعلوم نتائج PASS ثابت نہیں کر سکتے۔ صرف -دستاویزات یا صرف کیٹلاگ کی درست درجہ بندی کسی code lane کو ناقابلِ اطلاق بنا سکتی ہے؛ -draft PR قابلِ قبول امیدوار نہیں ہے۔ `hotfix` لیبل ثبوت کی شرط ختم نہیں کرتا۔ +`Gate / Quality`۔ ان کی ورژن شدہ منظوری پالیسی ہر upstream job کو +لازمی یا مشاورتی کے طور پر درج کرتی ہے۔ کسی قابل اطلاق لازمی job کا کامیاب ہونا ضروری ہے: غیر موجود، +منسوخ شدہ، چھوڑے گئے، زیر التوا اور نامعلوم نتائج PASS ثابت نہیں کر سکتے۔ صرف docs +یا صرف catalog کی درست درجہ بندی کسی code lane کو ناقابل اطلاق بنا سکتی ہے؛ +draft PR قابل قبول امیدوار نہیں ہے۔ `hotfix` لیبل شواہد کی ضرورت ختم نہیں کرتا۔ دونوں ورک فلوز PRs اور main/release برانچز پر pushes، manual dispatch اور merge-group events کا احاطہ کرتے ہیں۔ Push، dispatch اور merge-group مکمل انتخاب چلاتے ہیں۔ Forks -اور merge groups ان jobs کے لیے hosted runners استعمال کرتے ہیں جو بصورتِ دیگر self-hosted -runners منتخب کرتے؛ rollout سے پہلے کافی hosted capacity کی تصدیق ضروری ہے۔ +اور merge groups ان jobs کے لیے hosted runners استعمال کرتے ہیں جو بصورت دیگر self-hosted +runners منتخب کرتے؛ rollout سے پہلے hosted capacity کی کفایت کی تصدیق ضروری ہے۔ -ہر JSON رسید checked-out SHA، workflow run اور attempt کی شناخت کرتی ہے۔ -CLI checkout/event SHA کے عدم مطابقت کو مسترد کرتا ہے۔ Workflow tests پالیسی کی رکنیت کو +ہر JSON receipt چیک آؤٹ شدہ SHA، workflow run اور attempt کی شناخت کرتی ہے۔ +CLI checkout/event SHA کے عدم تطابق کو مسترد کرتا ہے۔ Workflow tests پالیسی کی رکنیت کو verdict job کی `needs` فہرست سے منسلک کرتے ہیں تاکہ کوئی نئی یا حذف شدہ lane خاموشی سے غائب نہ ہو سکے۔ -رسیدیں اپنے متعلقہ workflow کا احاطہ کرتی ہیں، publication، deployment، یا کسی موجودہ -مشاورتی scanner کے اندرونی حصوں کا نہیں۔ Branch rules میں دونوں check names فعال کرنا ایک -علیحدہ انتظامی تبدیلی ہے؛ ان jobs کو شامل کرنا بذاتِ خود کسی branch کو محفوظ نہیں کرتا۔ +Receipts اپنے workflow کا احاطہ کرتی ہیں، publication، deployment یا کسی موجودہ +مشاورتی scanner کے اندرونی حصوں کا نہیں۔ Branch rules میں دونوں check names کو فعال کرنا +ایک الگ انتظامی تبدیلی ہے؛ ان jobs کو شامل کرنا بذات خود کسی branch کو محفوظ نہیں کرتا۔ ### Static scan کی فہرست -ورژن شدہ npm-alias فہرست اور static-scan رکنیت +ورژن شدہ npm-alias فہرست اور static-scan کی رکنیت `config/quality/gate-manifest.json` میں موجود ہیں۔ Script names اور عین commands کو `package.json` کے مقابل validate کرنے کے لیے `npm run check:gate-manifest` چلائیں؛ اضافے، اخراج اور command drift مقامی hook اور CI میں change-classification jobs دونوں کو ناکام کر دیتے ہیں۔ -کوئی alias، workflow job، matrix instance یا test case نہیں ہوتا: ان کی تعداد کو -باہم قابلِ تبادلہ کے طور پر پیش نہیں کیا جانا چاہیے۔ +کوئی alias، workflow job، matrix instance یا test case نہیں ہوتا: ان اعداد کو +باہم قابل تبادلہ کے طور پر پیش نہیں کیا جانا چاہیے۔ -منتخب aliases کو چلائے بغیر دیکھنے کے لیے `npm run quality:scan -- --list` یا +منتخب aliases کو چلائے بغیر ان کا جائزہ لینے کے لیے `npm run quality:scan -- --list` یا `npm run quality:scan:fast -- --list` استعمال کریں۔ Runner، -npm entrypoint کو invoke کرتا ہے، اس لیے اس کا runtime (بشمول Bun، جہاں configure کیا گیا ہو) برقرار رہتا ہے۔ -Manifest ان profiles سے باہر موجود aliases کو علیحدہ طور پر invoke کیے جانے والے aliases کے طور پر درج کرتا ہے، اور +npm entrypoint کو چلاتا ہے، اس لیے اس کا runtime (بشمول ان مقامات کے جہاں Bun ترتیب دیا گیا ہو) برقرار رہتا ہے۔ +Manifest ان profiles سے باہر کے aliases کو الگ سے چلائے جانے والے aliases کے طور پر درج کرتا ہے، اور read-only scan profiles میں maintenance commands ممنوع ہیں۔ -یہ profiles صرف static scan کا احاطہ کرتے ہیں۔ یہ product tests، -coverage، packaging، external checks یا کسی امیدوار کی مکمل release acceptance کی تصدیق نہیں کرتے۔ +یہ profiles صرف static scan کا احاطہ کرتی ہیں۔ یہ product tests، +coverage، packaging، external checks یا کسی امیدوار کی مکمل release acceptance کی تصدیق نہیں کرتیں۔ Workflow admission منسلک `config/quality/admission-policy.json` اور -`scripts/quality/admission-verdict.mjs` استعمال کرتا ہے۔ Release-observer profiles علیحدہ رہتے ہیں؛ -ان کے قابلِ اطلاق checks اور receipts کا آزادانہ معائنہ کریں۔ ذیل کی نثری +`scripts/quality/admission-verdict.mjs` استعمال کرتی ہے۔ Release-observer profiles الگ رہتی ہیں؛ +ان کے قابل اطلاق checks اور receipts کا آزادانہ جائزہ لیں۔ ذیل میں دی گئی نثری فہرست ایک حوالہ ہے، اس بات کا ثبوت نہیں کہ کوئی gate حقیقتاً چلا تھا۔ Scripts، `scripts/check/` (policy gates) اور `scripts/quality/` (ratchet engine) کے تحت موجود ہیں۔ -CI کا حتمی ماخذ `.github/workflows/ci.yml` ہے۔ +CI کے لیے اصل ماخذ `.github/workflows/ci.yml` ہے۔ ### Release PR کا تیز راستہ (`quality.yml`) @@ -69,154 +69,154 @@ CI کا حتمی ماخذ `.github/workflows/ci.yml` ہے۔ pushes، dispatch اور merge groups پر CI کی تکمیل کرتا ہے۔ PRs، path-filtered تیز checks استعمال کرتے ہیں۔ مستقل طور پر غیر فعال duplicate build ہٹا دیا گیا؛ حقیقی build/package/boot checks بدستور CI میں موجود ہیں۔ -| Job | دائرۂ کار | مسدود کنندہ | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | Docs/code PRs؛ API docs refs اور docs-all | ہاں | -| `Fast Quality Gates` | Code PRs؛ static checks، typecheck، dashboard typecheck، متاثرہ unit tests | ہاں | -| `Forgotten sibling tests` | Code PRs؛ تبدیل شدہ modules کو static consumers اور ممکنہ sibling tests تک trace کیا جاتا ہے؛ barrel اور dynamic-import paths کو مشاورتی diagnostics کے طور پر رپورٹ کیا جاتا ہے، جن میں حوالہ شدہ allowlist exceptions شامل ہیں | **مشاورتی** | -| `Vitest (fast-path)` | Code PRs؛ تیز vitest suite | ہاں | -| `Unit Tests fast-path` | Code PRs؛ 4-shard unit suite | ہاں | -| `No new ESLint warnings` | Code PRs؛ suppressions-aware lint guard | ہاں، بشمول forks | -| `Merge integrity (changelog + generated skills)` | Non-draft PRs؛ changelog اور generated skill sync | ہاں، بشمول forks | +| Job | دائرۂ کار | Blocking | +| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `Docs Gates (fast-path)` | Docs/code PRs؛ API docs refs اور docs-all | ہاں | +| `Fast Quality Gates` | Code PRs؛ static checks، typecheck، dashboard typecheck، متاثرہ unit tests | ہاں | +| `Forgotten sibling tests` | Code PRs؛ تبدیل شدہ modules سے static consumers اور ممکنہ sibling tests تک سراغ؛ barrel اور dynamic-import کے راستے مشاورتی تشخیصی معلومات کے طور پر رپورٹ کیے جاتے ہیں، جن میں حوالہ شدہ allowlist استثنا شامل ہیں | **مشاورتی** | +| `Vitest (fast-path)` | Code PRs؛ تیز vitest suite | ہاں | +| `Unit Tests fast-path` | Code PRs؛ 4-shard unit suite | ہاں | +| `No new ESLint warnings` | Code PRs؛ suppressions-aware lint guard | ہاں، forks سمیت | +| `Merge integrity (changelog + generated skills)` | غیر draft PRs؛ changelog اور generated skill sync | ہاں، forks سمیت | #### بھولے ہوئے sibling tests کی رپورٹ -`npm run check:forgotten-sibling-tests`، test-impact map کے پسِ پشت import resolver کو دوبارہ استعمال کرتا ہے۔ +`npm run check:forgotten-sibling-tests`، test-impact map کے پس منظر میں موجود import resolver کو دوبارہ استعمال کرتا ہے۔ ہر تبدیل شدہ production module کے لیے، جب ممکنہ test، pull-request diff میں موجود نہ ہو تو یہ قطعی -`changed module/symbol -> static consumer -> candidate sibling test` سلسلوں کی رپورٹ دیتا ہے۔ Markdown summary اور JSON result کو -کسی بھی blocking rollout سے پہلے calibration کے لیے `forgotten-sibling-tests` workflow artifact کے طور پر محفوظ رکھا جاتا ہے۔ - -Barrel ری ایکسپورٹس اور ڈائنامک امپورٹس صرف ریزولوشن کی تشخیص کے لیے ہیں؛ یہ کبھی بھی -بلاک کرنے والی نشاندہی پیدا نہیں کرتے۔ نظرثانی شدہ استثنا -`config/quality/forgotten-sibling-allowlist.json` میں موجود ہیں۔ ہر اندراج میں صارف اور امیدوار -ٹیسٹ کا نام، ایک مخصوص وجہ، اور GitHub issue یا pull request کا لنک ہونا ضروری ہے۔ ناقص اندراجات -بند حالت میں ناکام ہوتے ہیں۔ استثنا حذف شدہ امیدوار ٹیسٹ یا ایسی diff کو نظرانداز نہیں کر سکتے جو `.skip`/`.todo` -شامل کرتی ہو؛ assertions کو کمزور کرنا اور دیگر پردہ پوشی بدستور آزادانہ طور پر بلاک کرنے والے -`check:test-masking` گیٹ کی ذمہ داری ہیں۔ - -### جاب: `lint` - -`main` کے لیے ہر PR پر چلتا ہے۔ ناکامی کی صورت میں مرج کو بلاک کرتا ہے۔ - -| اسکرپٹ (`npm run ...`) | توثیق | بلاک کرنے والا | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Node.js کا ورژن معاونت یافتہ حد کے اندر ہے | ہاں | -| `check:cycles` | سرکلر امپورٹس — تمام `src/` + `open-sse/` ماڈیولز | ہاں | -| `check:route-validation:t06` | تمام روٹس پر Zod اسکیمے موجود ہیں (درجہ 6 کی پالیسی) | ہاں | -| `check:any-budget:t11` | `@ts-expect-error // any` کی تعداد بجٹ سے زیادہ نہیں ہے (درجہ 11 catraca) | ہاں | -| `check:provider-consistency` | `providers.ts` میں موجود ہر provider کا `providerRegistry.ts` میں مماثل اندراج موجود ہے (اور اس کے برعکس بھی، allowlist کے اندر) | ہاں | -| `check:model-lifecycle` | ہاتھ سے برقرار رکھی جانے والی تین routing tables، checked-in lifecycle snapshot (#11503) کے ساتھ ہم آہنگ رہتی ہیں: `FITNESS_TABLE` (`taskFitness.ts`) کسی ایسے retired id کو score نہیں کرتی جسے `REGISTRY` route کر سکتی ہو؛ ہر `BUILT_IN_ALIASES` target، `REGISTRY` میں موجود اور retired-id snapshot سے غیر موجود ہے؛ `REGISTRY` میں اب بھی موجود ہر retired id کو forward کیا جاتا ہے یا `allowedRetiredInCatalog` میں درج کیا جاتا ہے؛ اور کوئی بھی `DEFAULT_DEGRADATION_MAP` source یا target اس snapshot میں retired ظاہر نہیں ہوتا۔ اس سے یہ ثابت نہیں ہوتا کہ کوئی model فی الحال live upstream کے ذریعے فراہم کیا جا رہا ہے۔ Offline — `config/quality/model-lifecycle.json` کے ساتھ موازنہ کرتا ہے، جسے `npm run quality:refresh-model-lifecycle` کے ذریعے دستی طور پر تازہ کیا جاتا ہے (network؛ CI میں شامل نہیں)۔ `allowedRetiredInCatalog` ایک burn-down ratchet ہے: کوئی اندراج صرف tracking issue کے ساتھ شامل کریں۔ | ہاں | -| `check:fetch-targets` | client-side `src/` میں موجود ہر `fetch("/api/...")` ایک حقیقی `route.ts` تک resolve ہوتا ہے | ہاں | -| `check:deps` | repo میں موجود ہر `package.json` کی تمام `npm install` کے قابل deps، `dependency-allowlist.json` میں موجود ہیں؛ نئے unpinned یا slopsquatted packages کو flag کیا جاتا ہے | ہاں | -| `audit:deps` | `npm audit` (root + electron) — کوئی high/critical advisory نہیں (osv `check:vuln-ratchet` کے ساتھ overlap؛ Rationalization Backlog دیکھیں) | ہاں | -| `check:lockfile` | `package-lock.json` کی integrity — https registry، integrity hashes، کوئی host overrides نہیں | ہاں | -| `check:licenses` | پروڈکشن dependencies کے لیے SPDX license allowlist | ہاں | -| `check:tracked-artifacts` | کوئی build artifacts / committed `node_modules` symlinks نہیں (husky pre-commit میں بھی چلتا ہے؛ pre-push کو جان بوجھ کر ہلکا رکھا گیا ہے — #6716) | ہاں | -| `check:ai-attribution` | PR commits، title یا body میں کوئی AI/bot `Co-Authored-By` trailer یا AI-generation footer نہیں — سخت اصول #16 (`quality.yml` کے PR→`release/**` fast-gates loop میں — event payload پڑھتا ہے، PRs کے علاوہ no-op رہتا ہے — اور PR→`main` کے لیے `ci.yml` lint میں صرف PR والا step؛ نیز husky `commit-msg` hook؛ انسانی co-authors کی اجازت ہے؛ #14436) | -| `check:vitest-exclusions` | ہر Vitest exclusion میں tracking issue درج ہو اور وہ `config/quality/vitest-exclusions.json` میں موجود ہو (#13204) | ہاں | -| `check:file-size` | کوئی source file فی-extension حد سے تجاوز نہ کرے (ratchet: بڑی منجمد files، `frozen` list میں) | ہاں | -| `check:error-helper` | executors/handlers میں error responses، `buildErrorBody()` / `sanitizeErrorMessage()` استعمال کریں (سخت اصول #12) | ہاں | -| `check:migration-numbering` | Migration SQL فائلیں مسلسل نمبروں کے ساتھ ہوں، کوئی خلا یا نقل شدہ نمبر نہ ہو | ہاں | -| `check:public-creds` | `publicCreds.ts` کے علاوہ کہیں بھی OAuth کے لفظی `client_id`/`client_secret` یا Firebase Web keys موجود نہ ہوں (سخت اصول #11) | ہاں | -| `check:db-rules` | `src/lib/db/` ماڈیولز کے علاوہ کہیں بھی خام SQL موجود نہ ہو؛ `localDb.ts` سے کوئی barrel-imports نہ ہوں (سخت اصول #2/#5) | ہاں | -| `check:known-symbols` | اپنی dispatch tables میں رجسٹر شدہ provider executors، routing strategies، اور translators ڈسک پر موجود فائلوں سے مطابقت رکھتے ہوں — کوئی غیر منسلک یا غیر اعلان شدہ symbols نہ ہوں | ہاں | -| `check:route-guard-membership` | child process شروع کرنے والا ہر route، `isLocalOnlyPath()` کے ذریعے درجہ بند کیا گیا ہو (سخت اصول #15/#17) | ہاں | -| `check:test-discovery` | repo میں موجود ہر `*.test.ts` / `*.spec.ts` فائل کم از کم ایک test runner کے ذریعے جمع کی جائے (ratchet: `test-discovery-baseline.json` میں orphan list صرف کم ہو سکتی ہے) | ہاں | -| `check:agent-skills-sync` | تیار کردہ agent-skills artifacts اپنے ماخذ catalog سے مطابقت رکھتے ہیں (کوئی drift نہیں) | -| `check:provider-asset-provenance` | Provider logos/assets کے ساتھ provenance کا اندراج ریکارڈ شدہ ہے | -| `lint:json` | JSON config files parse ہوتی ہیں اور repo کے lint rules کو پورا کرتی ہیں | -| `typecheck:core` | TypeScript compilation بغیر errors کے (صرف advisory warnings) | ہاں | -| `typecheck:noimplicit:core` | سخت `noImplicitAny` — مستقبل کو مدنظر رکھنے والا؛ پہلے سے موجود بہت سی call sites کو اب بھی annotations درکار ہیں | **مشاورتی** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` کا دائرہ `src/app/(dashboard)/**` تک محدود ہے (#7033) — `typecheck:core` کی منتخب کردہ 27-file allowlist میں کوئی dashboard TSX شامل نہیں، اور `next build` بھی کبھی اس کی type-checking نہیں کرتا (`next.config.mjs` میں `ignoreBuildErrors: true` مقرر ہے)، اس لیے وہاں orphaned-identifier regressions (#6625/#6909) CI کو نظر نہیں آتی تھیں۔ ایک منجمد، فی file/فی TS-code count baseline (`config/quality/dashboard-typecheck-baseline.json`، وہی stale-enforcement pattern جو `check:known-symbols` میں ہے) کے مقابلے میں diffs — صرف baseline میں موجود count سے زیادہ نئے errors gate کو ناکام کرتے ہیں؛ پہلے سے موجود error درست ہونے پر `--update` کے ذریعے اسے بتدریج کم کریں۔ | ہاں | +`changed module/symbol -> static consumer -> candidate sibling test` سلسلے رپورٹ کرتا ہے۔ Markdown summary اور JSON result کو +کسی blocking rollout سے پہلے calibration کے لیے `forgotten-sibling-tests` workflow artifact کے طور پر برقرار رکھا جاتا ہے۔ + +Barrel re-exports اور dynamic imports صرف resolution diagnostics ہیں؛ یہ کبھی بھی +blocking finding پیدا نہیں کرتے۔ جائزہ شدہ استثنا +`config/quality/forgotten-sibling-allowlist.json` میں موجود ہوتے ہیں۔ ہر اندراج میں consumer اور candidate +test کا نام، ایک مخصوص توجیہ، اور GitHub issue یا pull request کا لنک لازماً ہونا چاہیے۔ ناقص اندراجات +fail closed ہوتے ہیں۔ استثنا کسی حذف شدہ candidate test یا `.skip`/`.todo` شامل کرنے والے diff کو suppress نہیں کر سکتے؛ +assertion weakening اور دیگر masking بدستور آزادانہ طور پر blocking +`check:test-masking` gate کے دائرۂ اختیار میں رہتے ہیں۔ + +### Job: `lint` + +`main` کے ہر PR پر چلتا ہے۔ ناکامی کی صورت میں merge کو روکتا ہے۔ + +| Script (`npm run ...`) | توثیق کرتا ہے | Blocking | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Node.js کا version معاونت یافتہ range کے اندر ہے | ہاں | +| `check:cycles` | پورے `src/` + `open-sse/` میں circular imports (AST پر مبنی، tsconfig کے `paths` resolve کیے جاتے ہیں)۔ Bare = advisory، cycles کی فہرست دکھاتا ہے۔ `check:cycles:ratchet` (جسے CI چلاتا ہے) اس وقت block کرتا ہے جب تعداد `quality-baseline.json` میں `metrics.cycles` کی حد سے تجاوز کرے — فی الحال 14، `direction: down`، لہٰذا یہ صرف کم ہو سکتی ہے (#15159 G-01/G-02) | ہاں (ratchet) | +| `check:route-validation:t06` | تمام routes پر Zod schemas موجود ہیں (Tier 6 policy) | ہاں | +| `check:any-budget:t11` | `@ts-expect-error // any` کی تعداد budget سے تجاوز نہیں کرتی (Tier 11 catraca) | ہاں | +| `check:provider-consistency` | `providers.ts` میں موجود ہر provider کے لیے `providerRegistry.ts` میں مماثل اندراج موجود ہے (اور اس کے برعکس بھی، allowlist کے اندر) | ہاں | +| `check:model-lifecycle` | ہاتھ سے برقرار رکھی گئی تین routing tables، checked-in lifecycle snapshot (#11503) کے ساتھ مطابقت رکھتی ہیں: `FITNESS_TABLE` (`taskFitness.ts`) کسی ایسے retired id کو اسکور نہیں کرتی جسے `REGISTRY` route کر سکتی ہو؛ ہر `BUILT_IN_ALIASES` target، `REGISTRY` میں موجود اور retired-id snapshot میں غیر موجود ہے؛ `REGISTRY` میں اب بھی موجود ہر retired id کو forward کیا گیا ہے یا وہ `allowedRetiredInCatalog` میں درج ہے؛ اور کوئی `DEFAULT_DEGRADATION_MAP` source یا target اس snapshot میں retired نظر نہیں آتا۔ اس سے یہ ثابت نہیں ہوتا کہ کوئی model فی الحال کسی live upstream کے ذریعے فراہم کیا جا رہا ہے۔ Offline — `config/quality/model-lifecycle.json` کے ساتھ موازنہ کرتا ہے، جسے `npm run quality:refresh-model-lifecycle` کے ذریعے دستی طور پر refresh کیا جاتا ہے (network؛ CI سے منسلک نہیں)۔ `allowedRetiredInCatalog` ایک burn-down ratchet ہے: کوئی اندراج صرف tracking issue کے ساتھ شامل کریں۔ | ہاں | +| `check:fetch-targets` | client-side `src/` میں موجود ہر `fetch("/api/...")` ایک حقیقی `route.ts` تک resolve ہوتا ہے | ہاں | +| `check:deps` | repo میں موجود ہر `package.json` کی تمام `npm install` کے قابل deps، `dependency-allowlist.json` میں موجود ہیں؛ نئے unpinned یا slopsquatted packages کو نشان زد کیا جاتا ہے | ہاں | +| `audit:deps` | `npm audit` (root + electron) — کوئی high/critical advisory نہیں (osv کے `check:vuln-ratchet` کے ساتھ overlap کرتا ہے؛ Rationalization Backlog دیکھیں) | ہاں | +| `check:lockfile` | `package-lock.json` کی سالمیت — https registry، integrity hashes، کوئی host override نہیں | ہاں | +| `check:licenses` | پروڈکشن dependencies کے لیے SPDX license allowlist | ہاں | +| `check:tracked-artifacts` | کوئی build artifacts / committed `node_modules` symlinks نہیں (husky pre-commit میں بھی چلتا ہے؛ pre-push کو دانستہ طور پر ہلکا رکھا گیا ہے — #6716) | ہاں | +| `check:ai-attribution` | PR commits، title یا body میں کوئی AI/bot `Co-Authored-By` trailer یا AI-generation footer نہیں — سخت اصول #16 (`quality.yml` کے fast-gates loop میں PR→`release/**` کے لیے — event payload پڑھتا ہے، PRs کے علاوہ کوئی کارروائی نہیں کرتا — اور `ci.yml` lint میں PR→`main` کے لیے صرف PR والا مرحلہ؛ نیز husky `commit-msg` hook؛ انسانی co-authors کی اجازت ہے؛ #14436) | +| `check:vitest-exclusions` | ہر Vitest exclusion میں tracking issue درج ہو اور وہ `config/quality/vitest-exclusions.json` میں موجود ہو (#13204) | ہاں | +| `check:file-size` | کوئی source file فی-extension مقررہ حد سے تجاوز نہ کرے (ratchet: بڑی frozen files، `frozen` فہرست میں) | ہاں | +| `check:error-helper` | executors/handlers میں error responses، `buildErrorBody()` / `sanitizeErrorMessage()` استعمال کریں (سخت اصول #12) | ہاں | +| `check:migration-numbering` | مائیگریشن SQL فائلیں تسلسل کے ساتھ نمبر شدہ ہیں، ان میں کوئی خلا یا تکرار نہیں | ہاں | +| `check:public-creds` | `publicCreds.ts` سے باہر کوئی لفظی OAuth `client_id`/`client_secret` یا Firebase Web کلیدیں موجود نہیں (سخت اصول #11) | ہاں | +| `check:db-rules` | `src/lib/db/` ماڈیولز سے باہر کوئی خام SQL موجود نہیں؛ `localDb.ts` سے کوئی barrel-imports نہیں (سخت اصول #2/#5) | ہاں | +| `check:known-symbols` | اپنی dispatch tables میں رجسٹر شدہ provider executors، routing strategies، اور translators ڈسک پر موجود فائلوں سے مطابقت رکھتے ہیں — کوئی غیر منسلک یا غیر اعلان شدہ symbols نہیں | ہاں | +| `check:route-guard-membership` | child process شروع کرنے والا ہر route، `isLocalOnlyPath()` کے ذریعے درجہ بند ہے (سخت اصول #15/#17) | ہاں | +| `check:test-discovery` | repo میں موجود ہر `*.test.ts` / `*.spec.ts` فائل کم از کم ایک test runner کے ذریعے اکٹھی کی جاتی ہے (ratchet: `test-discovery-baseline.json` میں orphan list صرف کم ہو سکتی ہے) | ہاں | +| `check:agent-skills-sync` | تیار کردہ agent-skills آرٹیفیکٹس اپنے ماخذ کیٹلاگ سے مطابقت رکھتے ہیں (کوئی انحراف نہیں) | +| `check:provider-asset-provenance` | فراہم کنندہ کے لوگوز/اثاثوں کے ساتھ ماخذ کی ایک ریکارڈ شدہ اندراج موجود ہے | +| `lint:json` | JSON کنفیگریشن فائلیں درست طور پر پارس ہوتی ہیں اور repo کے lint قواعد پر پورا اترتی ہیں | +| `typecheck:core` | TypeScript کی بغیر خامیوں کے compilation (صرف مشاورتی انتباہات) | ہاں | +| `typecheck:noimplicit:core` | سخت `noImplicitAny` — مستقبل پر مرکوز؛ پہلے سے موجود بہت سے call sites کو اب بھی annotations درکار ہیں | **مشاورتی** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` کا دائرہ `src/app/(dashboard)/**` (#7033) تک محدود ہے — `typecheck:core` کی منتخب کردہ 27 فائلوں کی allowlist میں dashboard کی کوئی TSX فائل شامل نہیں، اور `next build` بھی کبھی اس کی type-checking نہیں کرتا (`next.config.mjs` میں `ignoreBuildErrors: true` مقرر ہے)، اس لیے وہاں orphaned-identifier regressions (#6625/#6909) CI کو دکھائی نہیں دیتی تھیں۔ ایک منجمد فی فائل/فی TS-code تعداد کی baseline (`config/quality/dashboard-typecheck-baseline.json`، وہی stale-enforcement طرز جو `check:known-symbols` میں ہے) کے مقابلے میں diffs — baseline تعداد سے زیادہ صرف نئی خامیاں gate کو ناکام کرتی ہیں؛ پہلے سے موجود خامی درست ہونے پر `--update` کے ذریعے baseline کم کریں۔ | ہاں | ### Job: `quality-gate` `test-coverage` کے بعد چلتا ہے۔ ناکامی کی صورت میں merge کو روکتا ہے۔ -| اسکرپٹ | توثیق کرتا ہے | بلاک کرنے والا | -| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `quality:collect` | `quality-metrics.json` تیار کرتا ہے (ESLint انتباہات کی تعداد، ضم شدہ shard رپورٹ سے کوریج) | ہاں (ratchet سے پہلے) | -| `quality:ratchet` | `quality-baseline.json` میں ہر میٹرک میں تنزلی نہیں ہوئی (ESLint انتباہات ≤ baseline؛ کوریج ≥ baseline) | ہاں | -| `check:duplication` | کوڈ کی نقل (jscpd@4) `quality-baseline.json` میں موجود baseline سے تجاوز نہیں کرتی | ہاں | -| `check:complexity` | فائل کی سطح کی cyclomatic complexity مقررہ حد سے تجاوز نہیں کرتی (بنیادی ESLint `complexity` + `max-lines-per-function`) | ہاں | -| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — علیحدہ ESLint مرحلہ؛ CI دونوں کو واحد `check:complexity-ratchets` مرحلے کے طور پر ضم کر کے چلاتا ہے | ہاں | -| `check:dead-code` | غیر استعمال شدہ exports / فائلوں کا ratchet (knip)، baseline کے مقابلے میں تنزلی نہیں کرتا | ہاں | -| `check:compression-budget` | کمپریشن benchmark بجٹ — ہر engine کے token-savings کی کم از کم حدوں میں تنزلی نہیں ہونی چاہیے | ہاں | -| `check:type-coverage` | ٹائپ شدہ فیصد کا ratchet (`type-coverage`) تنزلی نہیں کرتا؛ بڑی حد تک `typecheck:noimplicit:core` کو شامل کر لیتا ہے | ہاں | -| `check:codeql-ratchet` | کھلے CodeQL alerts کی تعداد میں اضافہ نہیں ہوتا (`gh api` کے ذریعے پڑھتا ہے؛ token کے بغیر بحفاظت نظرانداز کرتا ہے) — تازہ کاری کی مدت اور دستی trigger کے لیے: ذیل میں "CodeQL ratchet" دیکھیں | ہاں | +| اسکرپٹ | توثیق | رکاوٹ بننے والا | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- | +| `quality:collect` | `quality-metrics.json` بناتا ہے (ESLint انتباہات کی تعداد، ضم شدہ shard رپورٹ سے کوریج) | ہاں (ratchet سے پہلے) | +| `quality:ratchet` | `quality-baseline.json` میں ہر میٹرک میں تنزلی نہیں ہوئی (ESLint انتباہات ≤ baseline؛ کوریج ≥ baseline) | ہاں | +| `check:duplication` | کوڈ کی نقل (jscpd@4) `quality-baseline.json` میں موجود baseline سے تجاوز نہیں کرتی | ہاں | +| `check:complexity` | فائل کی سطح کی cyclomatic complexity مقررہ حد سے تجاوز نہیں کرتی (بنیادی ESLint `complexity` + `max-lines-per-function`) | ہاں | +| `check:cognitive-complexity` | Cognitive complexity ratchet (`eslint-plugin-sonarjs`) — علیحدہ ESLint مرحلہ؛ CI دونوں کو ایک `check:complexity-ratchets` مرحلے کے طور پر ضم کر کے چلاتا ہے | ہاں | +| `check:dead-code` | غیر استعمال شدہ exports / فائلوں کا ratchet (knip)، baseline کے مقابلے میں تنزلی کا شکار نہیں ہوتا | ہاں | +| `check:compression-budget` | Compression benchmark کا بجٹ — ہر engine کے لیے token-savings کی کم از کم حدود میں تنزلی نہیں ہونی چاہیے | ہاں | +| `check:type-coverage` | فیصدی typed ratchet (`type-coverage`) میں تنزلی نہیں ہوتی؛ بڑی حد تک `typecheck:noimplicit:core` کا احاطہ کرتا ہے | ہاں | +| `check:codeql-ratchet` | کھلے CodeQL alerts کی تعداد میں اضافہ نہیں ہوتا (`gh api` کے ذریعے پڑھتا ہے؛ token کے بغیر مناسب طور پر skip کرتا ہے) — تازہ کاری کی مدت اور دستی trigger: ذیل میں "CodeQL ratchet" دیکھیں | ہاں | ### جاب: `quality-extended` -پوری جاب مشاورتی ہے (`continue-on-error: true`)۔ npm پر مبنی ratchets حقیقی طور پر -چلتے ہیں؛ بیرونی scanners، `gh release download` کے ذریعے انسٹال ہوتے ہیں اور جب -binary پھر بھی موجود نہ ہو تو خود بخود نظرانداز ہو جاتے ہیں (exit 0)۔ +مکمل جاب مشاورتی ہے (`continue-on-error: true`)۔ npm پر مبنی ratchets حقیقتاً +چلتے ہیں؛ بیرونی scanners، `gh release download` کے ذریعے install ہوتے ہیں اور جب +binary پھر بھی موجود نہ ہو تو خود skip ہو جاتے ہیں (exit 0)۔ -| اسکرپٹ | توثیق کرتا ہے | بلاک کرنے والا | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| `check:circular-deps` | کوئی circular dependencies نہیں (dpdm) | **مشاورتی** | -| `check:bundle-size` | bundle کا حجم مقررہ حد سے تجاوز نہیں کرتا | **مشاورتی** | -| `check:secrets` | secrets کی scanning (gitleaks) — binary موجود نہ ہو تو نظرانداز کرتا ہے | **مشاورتی** | -| `check:vuln-ratchet` | dependencies کی vulnerabilities (osv-scanner) میں اضافہ نہیں ہوتا — binary موجود نہ ہو تو نظرانداز کرتا ہے | **مشاورتی** | -| `check:workflows` | workflow lint (actionlint + zizmor)؛ غائب/خراب scanners، غیر درست رپورٹس یا غائب ratchet baseline کو INCOMPLETE کے طور پر ناکام کرتے ہیں۔ درست نتائج منتخب کردہ strict/advisory/ratchet پالیسی کی پیروی کرتے ہیں | چلانا لازمی ہے؛ CI میں zizmor ratchet بلاک کرنے والا ہے | -| `check:openapi-breaking` | بنیادی branch کے مقابلے میں عوامی API contract (`openapi.yaml`) میں breaking changes (oasdiff) — `openapiBreaking=N` خارج کرتا ہے؛ oasdiff موجود نہ ہو یا بنیادی spec قابلِ حل نہ ہو تو نظرانداز کرتا ہے | **مشاورتی** | +| اسکرپٹ | توثیق | رکاوٹ بننے والا | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `check:circular-deps` | کوئی circular dependencies نہیں (dpdm) | **مشاورتی** | +| `check:bundle-size` | Bundle کا حجم مقررہ حد سے تجاوز نہیں کرتا | **مشاورتی** | +| `check:secrets` | Secrets کی scanning (gitleaks) — binary موجود نہ ہو تو skip کرتا ہے | **مشاورتی** | +| `check:vuln-ratchet` | Dependency vulnerabilities (osv-scanner) میں اضافہ نہیں ہوتا — binary موجود نہ ہو تو skip کرتا ہے | **مشاورتی** | +| `check:workflows` | Workflow lint (actionlint + zizmor)؛ غائب/خراب scanners، نامعتبر reports یا غائب ratchet baseline کی صورت میں INCOMPLETE کے طور پر ناکام ہوتا ہے۔ درست نتائج منتخب کردہ strict/advisory/ratchet پالیسی پر عمل کرتے ہیں | چلانا لازمی ہے؛ CI میں zizmor ratchet رکاوٹ بننے والا ہے | +| `check:openapi-breaking` | بنیادی branch کے مقابلے میں عوامی API contract (`openapi.yaml`) میں breaking changes (oasdiff) — `openapiBreaking=N` خارج کرتا ہے؛ oasdiff غائب ہو یا بنیادی spec قابلِ حل نہ ہو تو skip کرتا ہے | **مشاورتی** | ### جاب: `docs-sync-strict` -`main` کی ہر PR پر چلتی ہے۔ ناکامی کی صورت میں merge کو روکتی ہے۔ +`main` کے ہر PR پر چلتا ہے۔ ناکامی کی صورت میں merge کو روکتا ہے۔ -| اسکرپٹ | توثیق کرتا ہے | رکاوٹ بننے والا | +| اسکرپٹ | توثیق | مسدود کنندہ | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -| `check:docs-all` | میٹا گیٹ جو ذیل کے 6 ذیلی گیٹس کو ترتیب وار چلاتا ہے | ہاں | +| `check:docs-all` | میٹا گیٹ جو ذیل کے 6 ذیلی گیٹس کو یکے بعد دیگرے چلاتا ہے | ہاں | | ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt کے ورژنز میں مطابقت | ہاں | -| ↳ `check:docs-counts` | نثری متن میں دی گئی تعدادیں (provider کی تعداد، migration کی تعداد، وغیرہ) حقیقی تعدادوں کی ratchet ونڈو کے اندر ہوں | ہاں | -| ↳ `check:env-doc-sync` | `.env.example` میں موجود ہر env var دستاویزات کے کسی جدول میں درج ہو، اور اس کے برعکس بھی | ہاں | -| ↳ `check:deprecated-versions` | دستاویزات میں فرسودہ ورژن اسٹرنگز موجود نہ ہوں | ہاں | -| ↳ `check:doc-links` | دستاویزات میں داخلی markdown لنکس حقیقی فائلوں تک پہنچیں (`[text]`/`(path)` فارم) | ہاں | -| ↳ `check:fabricated-docs` | دستاویزات میں مذکور routes، env vars، CLI کمانڈز، hook نام، اور فائل پاتھ codebase میں موجود ہوں۔ `--strict` کے ذریعے سخت گیٹ؛ فلیگ کے بغیر soft-fail۔ | ہاں (CI میں `--strict` کے ذریعے) | -| `check:cli-i18n` | CLI کمانڈ اسٹرنگز تمام i18n locale فائلوں میں موجود ہوں | ہاں | -| `check:openapi-coverage` | OpenAPI spec حقیقی routes کی کم از کم ratcheted حد کا احاطہ کرے | ہاں | -| `check:openapi-security-tiers` | `openapi.yaml` میں security tier annotations، `routeGuard.ts` کی classifications سے مطابقت رکھیں | **مشاورتی** | -| `check:openapi-routes` | `openapi.yaml` میں ہر path ایک حقیقی `route.ts` تک پہنچے (خیالی مواد کی روک تھام) | ہاں | -| `check:docs-symbols` | `docs/**/*.md` میں ہر `/api/...` حوالہ ایک حقیقی `route.ts` تک پہنچے (خیالی مواد کی روک تھام) | ہاں | +| ↳ `check:docs-counts` | نثری متن میں دی گئی تعدادیں (فراہم کنندگان کی تعداد، مائیگریشنز کی تعداد، وغیرہ) حقیقی تعدادوں کی ratchet ونڈو کے اندر ہیں | ہاں | +| ↳ `check:env-doc-sync` | `.env.example` میں موجود ہر env var دستاویزات کے کسی ٹیبل میں درج ہے، اور اس کے برعکس بھی | ہاں | +| ↳ `check:deprecated-versions` | دستاویزات میں کوئی متروک ورژن اسٹرنگ موجود نہیں | ہاں | +| ↳ `check:doc-links` | دستاویزات میں اندرونی markdown لنکس حقیقی فائلوں تک پہنچتے ہیں (`[text]`/`(path)` فارمیٹ) | ہاں | +| ↳ `check:fabricated-docs` | دستاویزات میں مذکور routes، env vars، CLI کمانڈز، hook نام، اور فائل پاتھ codebase میں موجود ہیں۔ `--strict` کے ذریعے سخت گیٹ؛ فلیگ کے بغیر soft-fail۔ | ہاں (CI میں `--strict` کے ذریعے) | +| `check:cli-i18n` | CLI کمانڈ اسٹرنگز تمام i18n locale فائلوں میں موجود ہیں | ہاں | +| `check:openapi-coverage` | OpenAPI spec حقیقی routes کی کم از کم ratcheted حد کا احاطہ کرتی ہے | ہاں | +| `check:openapi-security-tiers` | `openapi.yaml` میں سیکیورٹی درجے کی annotations، `routeGuard.ts` کی classifications سے مطابقت رکھتی ہیں | **مشاورتی** | +| `check:openapi-routes` | `openapi.yaml` میں ہر path کسی حقیقی `route.ts` تک پہنچتا ہے (اینٹی ہیلوسینیشن) | ہاں | +| `check:docs-symbols` | `docs/**/*.md` میں ہر `/api/...` حوالہ کسی حقیقی `route.ts` تک پہنچتا ہے (اینٹی ہیلوسینیشن) | ہاں | | `i18n translation drift` | i18n locale فائلوں میں غیر ترجمہ شدہ keys — صرف انتباہ | **مشاورتی** | ### جاب: `i18n-ui-coverage` -| اسکرپٹ | توثیق کرتا ہے | رکاوٹ بننے والا | -| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (inline) | UI i18n key coverage ≥ 65% ہو | ہاں | -| `check-ui-value-drift` (inline) | دوبارہ لکھی گئی انگریزی **value** اپنے پیچھے کوئی فرسودہ ترجمہ نہ چھوڑے | ہاں | -| `check-new-key-coverage` (inline) | ایک **نئی** انگریزی key کا ہر locale میں ترجمہ ہو — `__MISSING__:` marker مسترد کر دیا جاتا ہے | ہاں | -| `check-translation-ratio` | ہر locale کے لیے حقیقی ترجمے کا تناسب (allowlist سے باہر انگریزی سے یکساں / placeholder / missing leaves) `config/quality/i18n-translation-baseline.json` + slack سے متجاوز نہ ہو | **مشاورتی** | +| اسکرپٹ | توثیق | مسدود کنندہ | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `check-ui-keys-coverage` (inline) | UI i18n key کوریج ≥ 65% ہے | ہاں | +| `check-ui-value-drift` (inline) | دوبارہ لکھی گئی انگریزی **value** اپنے پیچھے کوئی فرسودہ ترجمہ نہیں چھوڑتی | ہاں | +| `check-new-key-coverage` (inline) | ایک **نئی** انگریزی key ہر locale میں ترجمہ شدہ ہے — `__MISSING__:` مارکر مسترد کر دیا جاتا ہے | ہاں | +| `check-translation-ratio` | فی locale حقیقی ترجمے کا تناسب (allowlist سے باہر انگریزی سے مماثل / placeholder / غائب leaves) `config/quality/i18n-translation-baseline.json` + slack سے تجاوز نہیں کرنا چاہیے | **مشاورتی** | -`fetch-depth: 0` درکار ہے — value-drift گیٹ merge base کے مقابلے میں `en.json` کا diff لیتا ہے۔ +`fetch-depth: 0` درکار ہے — value-drift گیٹ، merge base کے مقابلے میں `en.json` کا diff لیتا ہے۔ #### `check-ui-value-drift` — فرسودہ ترجمے کا گیٹ -یہ اس واحد i18n regression کو پکڑتا ہے جسے دوسرے گیٹس ساختی طور پر نہیں دیکھ سکتے: کسی انگریزی value کو -دوبارہ لکھا جاتا ہے اور _پچھلی_ انگریزی سے اخذ کردہ تراجم باقی رہ جاتے ہیں، جس کے نتیجے میں -غیر انگریزی صارفین پراعتماد انداز میں لکھا ہوا، مگر اب غلط متن پڑھتے رہتے ہیں۔ +یہ اس واحد i18n regression کو پکڑتا ہے جسے دیگر گیٹس ساختی طور پر نہیں دیکھ سکتے: ایک انگریزی value +دوبارہ لکھی جاتی ہے اور _سابقہ_ انگریزی سے اخذ کردہ تراجم برقرار رہتے ہیں، لہٰذا +غیر انگریزی صارفین پُراعتماد انداز میں لکھی ہوئی، مگر اب غلط عبارت پڑھتے رہتے ہیں۔ یہ مسئلہ حقیقتاً ریلیز ہوا تھا۔ جب Antigravity -login helper شامل کیا گیا (#5203) تو `oauthModal.googleOAuthWarning` دوبارہ لکھا گیا؛ **43 میں سے 39 locales** میں ایسا متن برقرار رہا جو operators کو "مکمل -URL کاپی کر کے اسے نیچے پیسٹ کرنے" کو کہتا تھا — ایسا flow جو اس provider کے لیے مکمل ہی نہیں ہو سکتا۔ یہ +لاگ اِن helper شامل کیا گیا (#5203) تو `oauthModal.googleOAuthWarning` دوبارہ لکھا گیا؛ **43 میں سے 39 locales** میں وہ متن برقرار رہا جو آپریٹرز کو "مکمل +URL کاپی کر کے ذیل میں پیسٹ کریں" کہتا تھا — ایسا فلو جو اس provider کے لیے مکمل نہیں ہو سکتا۔ یہ #8463 تک نظر انداز رہا، کیونکہ: -- `sync-ui-keys` صرف **غائب** keys کو backfill کرتا ہے، **فرسودہ** keys کو کبھی نہیں؛ -- `check-ui-keys-coverage` key کی _موجودگی_ شمار کرتا ہے، اس لیے فرسودہ ترجمہ بھی covered شمار ہوتا ہے؛ -- `check-translation-drift`، `docs/i18n//**.md` کی documentation mirrors کو track کرتا ہے — - یہ کبھی `src/i18n/messages/*.json` نہیں پڑھتا۔ 2026-09 re-sync کے بعد سے job `docs-sync-strict` میں blocking ہے: کسی core doc میں ترمیم کریں → `npm run i18n:run -- --files=` (section-level، کم خرچ)۔ +- `sync-ui-keys` صرف ان keys کو backfill کرتا ہے جو **غائب** ہوں، ان کو کبھی نہیں جو **فرسودہ** ہوں؛ +- `check-ui-keys-coverage` key کی _موجودگی_ شمار کرتا ہے، لہٰذا فرسودہ ترجمہ covered شمار ہوتا ہے؛ +- `check-translation-drift`، `docs/i18n//**.md` دستاویزی mirrors کو ٹریک کرتا ہے — + یہ کبھی `src/i18n/messages/*.json` نہیں پڑھتا۔ 2026-09 re-sync سے جاب `docs-sync-strict` میں مسدود کنندہ ہے: بنیادی دستاویز میں ترمیم کریں → `npm run i18n:run -- --files=` (section-level، کم خرچ)۔ -**Diff سے باخبر، baseline پر منحصر نہیں۔** یہ merge base پر موجود `en.json` کا working tree سے موازنہ کرتا ہے؛ ہر اُس key کے لیے جس کی انگریزی value تبدیل ہوئی ہو، کوئی بھی locale جس میں اب بھی غیر تبدیل شدہ ترجمہ موجود ہو، فرسودہ تصور کیا جاتا ہے۔ یہ دانستہ طور پر **پہلے سے موجود قرض کو منجمد رکھتا ہے** — کوئی diff یہ ظاہر نہیں کر سکتا کہ ایک طویل عرصے سے موجود ترجمہ کس پرانی انگریزی سے آیا تھا، اس لیے gate صرف اسی چیز کا جائزہ لیتا ہے جسے موجودہ تبدیلی چھوتی ہے۔ متبادل (فی key hash baseline) کے لیے تقریباً 600 KB کی generated file درکار ہوگی، جو موجودہ سب سے بڑے baseline سے 3× بڑی ہے، اور ہر i18n PR پر تبدیل ہوگی۔ +**Diff سے آگاہ، baseline پر منحصر نہیں۔** یہ merge base پر موجود `en.json` کا working tree سے موازنہ کرتا ہے؛ ہر اُس key کے لیے جس کی انگریزی value تبدیل ہوئی ہو، ایسا کوئی بھی locale جس میں اب بھی غیر تبدیل شدہ ترجمہ موجود ہو، فرسودہ سمجھا جاتا ہے۔ یہ جان بوجھ کر **پہلے سے موجود قرض کو منجمد رکھتا ہے** — diff یہ ظاہر نہیں کر سکتا کہ کوئی دیرینہ ترجمہ کس پرانی انگریزی سے اخذ ہوا تھا، اس لیے gate صرف اُن چیزوں کا فیصلہ کرتا ہے جنہیں موجودہ تبدیلی چھوتی ہے۔ متبادل (فی key hash baseline) کے لیے تقریباً 600 KB کی generated file درکار ہوتی، جو موجودہ سب سے بڑے baseline سے 3× بڑی ہوتی اور ہر i18n PR پر تبدیل ہوتی۔ -اسے پورا کرنے کے دو طریقے ہیں: +اسے مطمئن کرنے کے دو طریقے ہیں: 1. متاثرہ تراجم کو اپ ڈیٹ کریں، یا 2. انہیں `__MISSING__:` پر سیٹ کریں — پھر runtime درست انگریزی پیش کرتا ہے - (`src/i18n/request.ts::deepMergeFallback`, #7258) اور key ترجمے کے لیے قطار میں شامل ہو جاتی ہے۔ + (`src/i18n/request.ts::deepMergeFallback`، #7258) اور key ترجمے کی قطار میں شامل ہو جاتی ہے۔ -اگر string کا **مفہوم** تبدیل ہوا ہے تو **key کا نام تبدیل کرنے** کو ترجیح دیں: نئی key کسی فرسودہ ترجمے کو وراثت میں نہیں لے سکتی۔ #8463 میں یہی pattern استعمال کیا گیا تھا۔ +اگر string کا **مفہوم** تبدیل ہوا ہے، تو **key کا نام تبدیل کرنے** کو ترجیح دیں: نئی key کسی فرسودہ ترجمے کو وراثت میں نہیں لے سکتی۔ #8463 میں یہی pattern استعمال ہوا تھا۔ ```bash npm run i18n:check-value-drift # سخت (جو CI چلاتا ہے) @@ -224,47 +224,47 @@ npm run i18n:check-value-drift:warn # صرف رپورٹ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -جب base catalog پڑھا نہ جا سکے (base ref کے بغیر shallow clone)، تو `SKIP reason=base-unresolved` کے ساتھ 0 پر exit کرتا ہے، جو `check-openapi-breaking` کے طرزِ عمل کی عکاسی کرتا ہے۔ +جب base catalog پڑھا نہ جا سکے (base ref کے بغیر shallow clone)، تو `SKIP reason=base-unresolved` کے ساتھ 0 پر exit کرتا ہے، بالکل `check-openapi-breaking` کی طرح۔ ### Job: `i18n` -مکمل i18n validation matrix (ہر locale کے لیے ایک job)۔ پوری job مشاورتی ہے۔ +مکمل i18n validation matrix (ہر locale کے لیے ایک job)۔ پورا job مشاورتی ہے۔ -| Script | توثیق کرتا ہے | Blocking | -| ------------------------------- | --------------------------- | --------------------------------------------------- | -| `validate_translation.py quick` | ہر locale کے ترجمے کی تکمیل | **مشاورتی** (پوری job پر `continue-on-error: true`) | +| Script | کیا validate کرتا ہے | Blocking | +| ------------------------------- | ------------------------------- | --------------------------------------------------- | +| `validate_translation.py quick` | ہر locale کے لیے ترجمے کی تکمیل | **مشاورتی** (پورے job پر `continue-on-error: true`) | ### Job: `pr-test-policy` صرف pull requests پر چلتا ہے۔ -| Script | توثیق کرتا ہے | Blocking | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/`، یا `bin/` میں production code تبدیل کرنے والے PRs میں tests شامل یا اپ ڈیٹ ہونے چاہییں (Hard Rule #8) | ہاں | -| `check:test-masking` | تبدیل شدہ test files، asserts کی مجموعی تعداد کم نہیں کرتیں یا `assert.ok(true)` جیسی tautologies شامل نہیں کرتیں | ہاں | -| `check:pr-evidence` | PR body میں تبدیلی کے لیے test/VPS شواہد کا حوالہ موجود ہو (PR کے نثری متن کو grep کر کے Hard Rule #18 کو خودکار بناتا ہے — نازک، Backlog دیکھیں) | ہاں | +| Script | کیا validate کرتا ہے | Blocking | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | وہ PRs جو `src/`، `open-sse/`، `electron/`، یا `bin/` میں production code تبدیل کرتے ہیں، لازماً tests شامل یا اپ ڈیٹ کریں (Hard Rule #8) | ہاں | +| `check:test-masking` | تبدیل شدہ test files مجموعی assert count کم نہ کریں اور `assert.ok(true)` جیسی tautologies شامل نہ کریں | ہاں | +| `check:pr-evidence` | PR body میں تبدیلی کے لیے test/VPS evidence کا حوالہ ہو (PR prose کو grep کر کے Hard Rule #18 کو خودکار بناتا ہے — نازک، Backlog دیکھیں) | ہاں | ### Job: `test-vitest` `build` کے بعد چلتا ہے۔ ناکامی کی صورت میں merge کو روکتا ہے۔ -| Suite | توثیق کرتا ہے | Blocking | -| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 tools)، autoCombo، cache — vitest runner | ہاں | -| `test:vitest:ui` | UI component tests — vitest runner | **Blocking** — پہلے سے موجود ناکامیوں کو `vitest.config.ts` میں واضح طور پر خارج کیا گیا ہے؛ نئی ناکامیاں job کو ناکام کر دیتی ہیں | +| Suite | کیا validate کرتا ہے | Blocking | +| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 tools)، autoCombo، cache — vitest runner | ہاں | +| `test:vitest:ui` | UI component tests — vitest runner | **Blocking** — پہلے سے موجود failures کو `vitest.config.ts` میں واضح طور پر خارج کیا گیا ہے؛ نئی failures job کو ناکام کرتی ہیں | -### Nightly workflows (طے شدہ، مشاورتی) +### Nightly workflows (scheduled، مشاورتی) -یہ cron schedule (اور `workflow_dispatch`) پر چلتے ہیں، PRs پر کبھی نہیں۔ سبھی مشاورتی ہیں۔ +یہ cron schedule پر (اور `workflow_dispatch` کے ذریعے) چلتے ہیں، PRs پر کبھی نہیں۔ سب مشاورتی ہیں۔ -| Workflow | توثیق کرتا ہے | Blocking | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `nightly-property` | random seed اور زیادہ run count کے ساتھ fast-check property tests | **مشاورتی** | -| `nightly-resilience` | heap-growth gate، chaos fault-injection، k6 load/soak | **مشاورتی** | -| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret کے بغیر چھوڑ دیے جاتے ہیں) | **مشاورتی** | -| `nightly-schemathesis` | `docs/openapi.yaml` استعمال کرتے ہوئے live OmniRoute کے خلاف OpenAPI contract fuzzing (schemathesis) — spec کی خلاف ورزیوں / غیر سنبھالی گئی 500s کو نمایاں کرتا ہے (مرحلہ 8 B.4) | **مشاورتی** | -| `nightly-mutation` | تیز unit lane پر Stryker mutation-testing score — بچ جانے والے mutants کمزور asserts کو نمایاں کرتے ہیں | **مشاورتی** | -| `nightly-compat` | معاونت یافتہ `engines.node` ranges میں Node engine compatibility matrix | **مشاورتی** | +| Workflow | کیا validate کرتا ہے | Blocking | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| `nightly-property` | random seed اور زیادہ run count کے ساتھ fast-check property tests | **مشاورتی** | +| `nightly-resilience` | heap-growth gate، chaos fault-injection، k6 load/soak | **مشاورتی** | +| `nightly-llm-security` | promptfoo injection guard (block mode) + garak probes (provider secret نہ ہونے پر skip ہوتے ہیں) | **مشاورتی** | +| `nightly-schemathesis` | `docs/openapi.yaml` استعمال کرتے ہوئے live OmniRoute کے خلاف OpenAPI contract fuzzing (schemathesis) — spec violations / unhandled 500s سامنے لاتا ہے (Fase 8 B.4) | **مشاورتی** | +| `nightly-mutation` | تیز unit lane پر Stryker mutation-testing score — بچ جانے والے mutants کمزور asserts کو نمایاں کرتے ہیں | **مشاورتی** | +| `nightly-compat` | معاونت یافتہ `engines.node` ranges میں Node engine compatibility matrix | **مشاورتی** | --- @@ -527,41 +527,41 @@ CI گیٹس کے علاوہ، OmniRoute ایک **اختیاری** `agent-lsp` ا ## معقولیت سازی کا بیک لاگ (ROI جائزہ — مرحلہ 9 لہر 3) -اس فہرست کا 2026-06-17 کو `ci.yml` کے مقابل موازنہ کیا گیا تھا (پچھلے ورژن میں +اس فہرست کا 2026-06-17 کو `ci.yml` کے مقابل موازنہ کر کے تطبیق کی گئی (پچھلے ورژن میں `audit:deps`، `check:tracked-artifacts`، `check:lockfile`، `check:licenses`، `check:dead-code`، `check:cognitive-complexity`، `check:type-coverage`، -`check:codeql-ratchet`، `check:pr-evidence` شامل نہیں تھے)۔ ہم آہنگ کردہ مجموعے کے ROI جائزے -میں معقولیت سازی کے درج ذیل امیدواروں کی نشاندہی ہوئی۔ **انضمام محض میکانکی CI -تبدیلیاں ہیں؛ پلٹنے/ہٹانے کے فیصلے پالیسی سے متعلق ہیں جو آپریٹر کے لیے مختص ہیں۔** ذیل میں دی گئی -کوئی چیز ابھی لاگو نہیں کی گئی۔ +`check:codeql-ratchet`، `check:pr-evidence` شامل نہیں تھے)۔ تطبیق شدہ مجموعے کے ROI جائزے +نے معقولیت سازی کے درج ذیل امیدواروں کی نشاندہی کی۔ **انضمام محض میکانکی CI +تبدیلیاں ہیں؛ پلٹانا/حذف کرنا پالیسی فیصلے ہیں جو آپریٹر کے لیے محفوظ ہیں۔** ذیل میں سے کچھ بھی +ابھی لاگو نہیں کیا گیا۔ -**اوپر درج نہ ہونے والی چیزیں بھی** (مشاورتی، کمزور اشارہ): `docs-lint` جاب +**اوپر یہ بھی دستاویزی شکل میں درج نہیں** (مشاورتی، کم سگنل): `docs-lint` جاب (markdownlint + Vale، پوری جاب پر `continue-on-error`) اور علیحدہ اسکینر ورک فلوز `semgrep.yml` / `codeql.yml` / `scorecard.yml`۔ `semgrepFindings: 0` -`quality-baseline.json` میں موجود ہے، لیکن `ci.yml` میں کسی بلاک کرنے والے ریچیٹ سے منسلک نہیں — یہ میٹرک -فی الحال غیر منسلک ہے۔ +`quality-baseline.json` میں موجود ہے لیکن `ci.yml` میں کسی بلاکنگ ریچٹ سے منسلک نہیں — یہ میٹرک +فی الحال غیر مربوط ہے۔ ### انضمام / نقل کا خاتمہ (میکانکی، کم خطرہ) -ہر امیدوار کی 2026-06-17 کو فعال گیٹ کی حالت کے مقابل تصدیق کی گئی (اعتماد کریں، مگر تصدیق بھی کریں)؛ -کئی "ظاہری طور پر واضح" انضمامات دراصل چھپا ہوا تکنیکی قرض رکھتے تھے اور **بلا تبدیلی براہِ راست متبادل نہیں** ہیں۔ - -- **`check:docs-sync` دو مرتبہ چلتا ہے** — `lint` جاب میں علیحدہ طور پر، اور پھر `check:docs-all` (`docs-sync-strict`) اور husky pre-commit ہک کے اندر۔ ✅ **مکمل** — علیحدہ `lint` اجرا ہٹا دیا گیا۔ -- **CVE اسکیننگ** — ❌ **صاف انضمام نہیں۔** `audit:deps` کسی بھی high/critical CVE پر قطعی طور پر ناکام ہو جاتا ہے؛ `check:vuln-ratchet` (osv) صرف baseline کے مقابلے میں کسی _تنزلی_ پر ناکام ہوتا ہے (فی الحال 1 MODERATE)۔ مفہوم مختلف ہیں — `audit:deps` ہٹانے سے مطلق high/critical گیٹ ختم ہو جائے گا۔ دونوں برقرار رکھیں۔ -- **سائیکل کی شناخت** — ❌ **صاف انضمام نہیں۔** `check:circular-deps` (dpdm) **91 سائیکلز** رپورٹ کرتا ہے (اسی لیے یہ مشاورتی ہے)؛ پہلے ان کو حل کیے بغیر اسے بلاک کرنے والے درجے پر نہیں لایا جا سکتا، اور اس کا دائرۂ کار سبز، منتخب `check:cycles` سے زیادہ وسیع ہے۔ `check:cycles` کو بلاک کرنے والا رکھیں؛ 91 dpdm سائیکلز کو حل کرنا ایک علیحدہ بیک لاگ ہے۔ -- **پیچیدگی** — ✅ **مکمل** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ایک ESLint واک، `ruleId` کے لحاظ سے شمار کرتی ہے تاکہ cyclomatic+max-lines اور cognitive baselines آزاد رہیں؛ انفرادی `check:complexity` / `check:cognitive-complexity` مقامی `--update` کے لیے برقرار ہیں۔ -- **`/api` اینٹی ہیلوسینیشن** — ✅ **مکمل** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` کی ایک FS فہرست سازی، openapi-routes + docs-symbols بدستور آزادانہ رپورٹ کرتے ہیں؛ انفرادی چیکس مقامی اجرا کے لیے برقرار ہیں۔ -- **`check:node-runtime` 11 جابز میں چلتا ہے** — ⚠️ **کم ROI۔** ہر ایک علیحدہ runner ہے اور چیک <1s لیتا ہے؛ ایک سستے فی جاب حفاظتی چیک کو کھونے کے مقابلے میں کل بچت ~10s ہے۔ اس تبدیلی کی زحمت کے قابل نہیں۔ -- **CI lint پر `typecheck:noimplicit:core`** — ✅ **lint جاب سے ہٹا دیا گیا** (یہ مشاورتی `continue-on-error` تھا)؛ بلاک کرنے والی type surface اب `typecheck:core` + `check:type-coverage` ہے۔ مقامی اسکرپٹ برقرار رکھا گیا۔ - -### پلٹیں / فیصلہ کریں (آپریٹر پالیسی) - -- `check:openapi-security-tiers` (مشاورتی) — ❌ **اسے صاف طور پر پلٹا نہیں جا سکتا۔** یہ 0 کے ساتھ خارج ہوتا ہے، مگر متنبہ کرتا ہے کہ `LOCAL_ONLY_API_PREFIXES` کے تحت متعدد `traffic-inspector` روٹس میں `x-loopback-only: true` تشریح موجود نہیں۔ اسے نافذ کرنے کے لیے پہلے وہ تشریحات `openapi.yaml` میں شامل کرنا ضروری ہیں۔ -- `typecheck:noimplicit:core` (مشاورتی) — بڑی حد تک بلاک کرنے والے `check:type-coverage` ریچیٹ میں شامل ہے۔ اسے ریچیٹ میں بدلیں یا فالتو دوسرے `tsc` پاس کو ہٹا دیں۔ -- `test:vitest:ui` (اب **بلاک کرنے والا**) — پہلے سے موجود ناکامیاں `vitest.config.ts` میں `// #8618` ٹریکنگ تبصروں کے ساتھ واضح طور پر خارج کی گئی ہیں؛ نئی ناکامیاں جاب کو ناکام کر دیتی ہیں۔ -- `check:secrets` (gitleaks، 3 دستاویزی false-positives پر منجمد بلاک کرنے والا ریچیٹ) — 0 تک پہنچنے کے لیے ان 3 کو allowlist کریں، یا اسے مشاورتی درجے پر لے جائیں۔ یہ GitHub کی مقامی secret-scanning + `check:public-creds` سے متجاوز ہے۔ -- `check:pr-evidence` (بلاک کرنے والا، PR-body نثر میں greps کرتا ہے) — false-positive کا زیادہ خطرہ؛ اسے ہٹانے سے Hard Rule #18 کا نفاذ کمزور ہوتا ہے، لہٰذا یہ حقیقی پالیسی فیصلہ ہے۔ -- `semgrep` (مشاورتی علیحدہ ورک فلو) — OWASP خاندانوں کے لیے CodeQL سے متجاوز ہے؛ اس کے baseline کو ریچیٹ سے منسلک کریں یا اسے ہٹا دیں۔ +ہر امیدوار کی 2026-06-17 کو فعال گیٹ کی حالت کے مقابل توثیق کی گئی (اعتماد کریں مگر تصدیق بھی کریں)؛ +کئی "واضح" انضمامات میں چھپا ہوا قرض سامنے آیا اور وہ **صاف ستھرے براہِ راست متبادل نہیں** ہیں۔ + +- **`check:docs-sync` دو بار چلتا ہے** — `lint` جاب میں علیحدہ طور پر اور دوبارہ `check:docs-all` (`docs-sync-strict`) اور husky pre-commit ہک کے اندر۔ ✅ **مکمل** — علیحدہ `lint` اجرا ہٹا دیا گیا۔ +- **CVE اسکیننگ** — ❌ **صاف انضمام نہیں۔** `audit:deps` کسی بھی high/critical CVE پر قطعی طور پر ناکام ہو جاتا ہے؛ `check:vuln-ratchet` (osv) صرف بنیادی خط کے مقابل کسی _تنزلی_ پر ناکام ہوتا ہے (فی الحال 1 MODERATE)۔ معنویات مختلف ہیں — `audit:deps` حذف کرنے سے مطلق high/critical گیٹ ختم ہو جائے گا۔ دونوں برقرار رکھیں۔ +- **چکر کی کھوج** — ✅ **مکمل** (#15159 G-01/G-02)۔ یہاں موجود پرانے متن نے `check:cycles` کو "سبز، منتخب" گیٹ کہا تھا اور اسے بلاکنگ رکھنے کا جواز یہ دیا تھا کہ `check:circular-deps` (dpdm) نے 91 چکروں کی اطلاع دی۔ وہ سبز حالت ایک **غلط سبز حالت** تھی: `check:cycles` نے 5 ذیلی ڈائریکٹریاں (450 فائلیں) اسکین کیں، صرف جامد `import|export … from` سے مطابقت کی، اور ہر `@/` اور `@omniroute/open-sse/` تخصیص کار کو خارج کر دیا، اس لیے یہ ان dynamic-import + alias چکروں کو نہیں دیکھ سکتا تھا جو ریپو میں غالب تھے۔ درست کر دیا گیا: گیٹ اب `src` + `open-sse` (5023 فائلیں) میں چلتا ہے، TypeScript AST سے تخصیص کار جمع کرتا ہے (لہٰذا `import("…")` شمار ہوتا ہے جبکہ ٹائپ پوزیشن میں `typeof import("…")` شمار نہیں ہوتا)، اور tsconfig `paths` کو حل کرتا ہے۔ اسے 0 نہیں بلکہ **14** چکر ملتے ہیں۔ چونکہ گیٹ PR میں پہلے سے موجود 14 چکروں کو درست نہیں کیا جا سکتا، اس لیے `check:cycles` اب ایک **ریچٹ** ہے (`--ratchet`، `quality-baseline.json` میں حد `metrics.cycles.value = 14`، `direction: down`) — یہ کسی بھی _تنزلی_ کو روکتا ہے اور تعداد صرف کم ہو سکتی ہے۔ CI میں `npm run check:cycles:ratchet` چلتا ہے۔ مرحلہ وار کمی **A-01** کے ساتھ آگے بڑھے گی۔ `check:circular-deps` (dpdm) ایک وسیع تر ثانوی رائے کے طور پر مشاورتی رہے گا۔ +- **پیچیدگی** — ✅ **مکمل** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ایک ESLint واک، `ruleId` کے لحاظ سے شمار، تاکہ cyclomatic+max-lines اور cognitive بنیادی خطوط آزاد رہیں؛ انفرادی `check:complexity` / `check:cognitive-complexity` مقامی `--update` کے لیے برقرار ہیں۔ +- **`/api` اینٹی ہیلوسینیشن** — ✅ **مکمل** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` کی ایک FS فہرست سازی، openapi-routes + docs-symbols اب بھی آزادانہ طور پر رپورٹ کرتے ہیں؛ انفرادی چیکس مقامی اجرا کے لیے برقرار ہیں۔ +- **`check:node-runtime` 11 جابز میں چلتا ہے** — ⚠️ **کم ROI۔** ہر ایک الگ رنر ہے اور چیک <1s ہے؛ کل بچت ~10s ہے، جبکہ اس کے بدلے ہر جاب کا ایک سستا حفاظتی چیک ختم ہو جائے گا۔ اتنی تبدیلی کے قابل نہیں۔ +- **CI lint پر `typecheck:noimplicit:core`** — ✅ **lint جاب سے ہٹا دیا گیا** (یہ مشاورتی `continue-on-error` تھا)؛ بلاکنگ ٹائپ سطح `typecheck:core` + `check:type-coverage` ہے۔ مقامی اسکرپٹ برقرار رکھا گیا۔ + +### پلٹائیں / فیصلہ کریں (آپریٹر پالیسی) + +- `check:openapi-security-tiers` (مشاورتی) — ❌ **صاف طور پر پلٹنے کے قابل نہیں۔** یہ 0 کے ساتھ خارج ہوتا ہے لیکن خبردار کرتا ہے کہ `LOCAL_ONLY_API_PREFIXES` کے تحت کئی `traffic-inspector` روٹس میں `x-loopback-only: true` تشریح موجود نہیں۔ اسے نافذ کرنے کے لیے پہلے `openapi.yaml` میں یہ تشریحات شامل کرنا ضروری ہے۔ +- `typecheck:noimplicit:core` (مشاورتی) — بڑی حد تک بلاکنگ `check:type-coverage` ریچٹ میں شامل ہے۔ اسے ریچٹ میں تبدیل کریں یا فالتو دوسرے `tsc` پاس کو حذف کریں۔ +- `test:vitest:ui` (اب **بلاکنگ**) — پہلے سے موجود ناکامیاں `vitest.config.ts` میں `// #8618` ٹریکنگ تبصروں کے ساتھ واضح طور پر خارج کی گئی ہیں؛ نئی ناکامیاں جاب کو ناکام کر دیتی ہیں۔ +- `check:secrets` (gitleaks، 3 دستاویزی false-positives پر منجمد بلاکنگ ریچٹ) — 0 تک پہنچنے کے لیے ان 3 کو allowlist کریں، یا اسے مشاورتی درجے پر لے جائیں۔ یہ GitHub کی مقامی secret-scanning + `check:public-creds` سے متجاوز ہے۔ +- `check:pr-evidence` (بلاکنگ، PR-body نثر میں grep کرتا ہے) — false-positive کا زیادہ خطرہ؛ اسے حذف کرنے سے Hard Rule #18 کا نفاذ کمزور ہو جائے گا، اس لیے یہ حقیقی پالیسی فیصلہ ہے۔ +- `semgrep` (مشاورتی علیحدہ ورک فلو) — OWASP خاندانوں کے لیے CodeQL سے متجاوز ہے؛ اس کے بنیادی خط کو کسی ریچٹ سے منسلک کریں یا حذف کر دیں۔ --- diff --git a/docs/i18n/uz/CONTRIBUTING.md b/docs/i18n/uz/CONTRIBUTING.md index acc407c3d2c..3a4654458aa 100644 --- a/docs/i18n/uz/CONTRIBUTING.md +++ b/docs/i18n/uz/CONTRIBUTING.md @@ -399,22 +399,22 @@ Model taʼriflarini `open-sse/config/providerRegistry.ts` fayliga qoʻshing. --- -## Pull Request nazorat roʻyxati +## Pull Request tekshiruv roʻyxati - [ ] Testlar muvaffaqiyatli oʻtadi (`npm test`) -- [ ] Lint tekshiruvi muvaffaqiyatli oʻtadi (`npm run lint`) -- [ ] Yigʻish muvaffaqiyatli yakunlanadi (`npm run build`) +- [ ] Linting tekshiruvi muvaffaqiyatli oʻtadi (`npm run lint`) +- [ ] Build muvaffaqiyatli yakunlanadi (`npm run build`) - [ ] Yangi ommaviy funksiyalar va interfeyslar uchun TypeScript turlari qoʻshilgan -- [ ] Qattiq kodlangan maxfiy maʼlumotlar yoki zaxira qiymatlar mavjud emas -- [ ] Ommaviy yuqori oqim hisob maʼlumotlari `resolvePublicCred()` orqali joylashtirilgan ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) hujjatiga qarang), hech qachon literal sifatida emas -- [ ] Xato javoblari `buildErrorBody()` / `sanitizeErrorMessage()` orqali oʻtadi — javob tanalarida xom stek treyslari mavjud emas ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) hujjatiga qarang) +- [ ] Hardkodlangan maxfiy maʼlumotlar yoki zaxira qiymatlar mavjud emas +- [ ] Ommaviy upstream hisob maʼlumotlari literal qiymatlar sifatida emas, `resolvePublicCred()` orqali kiritilgan ([`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md) ga qarang) +- [ ] Xato javoblari `buildErrorBody()` / `sanitizeErrorMessage()` orqali yoʻnaltirilgan — javob tanalarida xom stack trace mavjud emas ([`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md) ga qarang) - [ ] Shell buyruqlari (`exec` / `spawn`) bajarilish vaqtidagi qiymatlarni satr interpolyatsiyasi orqali emas, `env` orqali uzatadi -- [ ] Barcha kiruvchi maʼlumotlar Zod sxemalari yordamida tekshirilgan -- [ ] Foydalanuvchiga taʼsir qiladigan oʻzgarishlar uchun `changelog.d/{features|fixes|maintenance}/-.md` ostiga oʻzgarishlar jurnali **fragmenti** qoʻshilgan ([`changelog.d/README.md`](./changelog.d/README.md) hujjatiga qarang) — `CHANGELOG.md` faylini bevosita tahrirlamang; fragmentlar reliz vaqtida birlashtiriladi va PRlar oʻrtasida hech qachon ziddiyat keltirib chiqarmaydi +- [ ] Barcha kirish maʼlumotlari Zod sxemalari bilan tekshirilgan +- [ ] Foydalanuvchiga taʼsir qiluvchi oʻzgarishlar uchun `changelog.d/{features|fixes|maintenance}/-.md` ostiga changelog **fragmenti** qoʻshilgan ([`changelog.d/README.md`](./changelog.d/README.md) ga qarang) — `CHANGELOG.md` faylini toʻgʻridan-toʻgʻri tahrirlamang; fragmentlar reliz vaqtida birlashtiriladi va PRlar oʻrtasida hech qachon ziddiyatga olib kelmaydi - [ ] Hujjatlar yangilangan (agar tegishli boʻlsa) -- [ ] Yangi CodeQL / Secret-Scanning ogohlantirishlari ochilmagan yoki ularning har biri tegishli `docs/security/` hujjatiga havola qiluvchi texnik asos bilan rad etilgan -- [ ] Ichki jarayonlarni ishga tushiradigan marshrutlar (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` faylida `isLocalOnlyPath()` sifatida tasniflangan — [15-qatʼiy qoida](docs/security/ROUTE_GUARD_TIERS.md)ga qarang -- [ ] Commit xabarlarida `Co-Authored-By` yakuniy satrlari mavjud emas — commitlar faqat repozitoriy egasining Git identifikatori ostida koʻrinishi kerak (16-qatʼiy qoida) +- [ ] Yangi CodeQL / Secret-Scanning ogohlantirishlari yaratilmagan yoki ularning har biri tegishli `docs/security/` hujjatiga havola qilingan texnik asos bilan rad etilgan +- [ ] Quyi jarayonlarni ishga tushiradigan marshrutlar (`/api/mcp/`, `/api/cli-tools/runtime/`) `src/server/authz/routeGuard.ts` ichida `isLocalOnlyPath()` sifatida tasniflangan — [Qatʼiy qoida #15](docs/security/ROUTE_GUARD_TIERS.md) ga qarang +- [ ] Commit xabarlarida AI/botga tegishli `Co-authored-by` treylerlari mavjud emas (Qatʼiy qoida #16) — ishidan qayta foydalanilgan inson hamkorlar standart `Co-authored-by: Name ` treylerlari bilan eʼtirof etiladi --- diff --git a/docs/i18n/uz/docs/architecture/QUALITY_GATES.md b/docs/i18n/uz/docs/architecture/QUALITY_GATES.md index bf893919888..8e5ef8e4923 100644 --- a/docs/i18n/uz/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/uz/docs/architecture/QUALITY_GATES.md @@ -16,220 +16,227 @@ va vositalarga bogʻliq boʻlmagan takrorlash rejasi uchun --- -## Nazoratlar inventari va bajarish profillari +## Geytlar roʻyxati va bajarish profillari ### Nomzodni qabul qilish CI va Quality Gates ish jarayonlarining har biri barqaror hukm chiqaradi: `Gate / CI` va `Gate / Quality`. Ularning versiyalangan qabul qilish siyosati har bir yuqori oqimdagi vazifani -majburiy yoki tavsiyaviy sifatida belgilaydi. Qoʻllanadigan majburiy vazifa muvaffaqiyatli -bajarilishi shart: mavjud boʻlmagan, bekor qilingan, oʻtkazib yuborilgan, kutilayotgan va nomaʼlum +majburiy yoki tavsiyaviy sifatida belgilaydi. Qoʻllaniladigan majburiy vazifa muvaffaqiyatli +yakunlanishi kerak: mavjud boʻlmagan, bekor qilingan, oʻtkazib yuborilgan, kutilayotgan va nomaʼlum natijalar PASS holatini tasdiqlay olmaydi. Faqat hujjatlarga yoki faqat katalogga tegishli haqiqiy -tasnif kod yoʻnalishini qoʻllanmaydigan qilishi mumkin; qoralama PR qabul qilinadigan nomzod emas. -`hotfix` yorligʻi dalil taqdim etish talabini bekor qilmaydi. - -Har ikkala ish jarayoni PRlarni va main/release shoxlariga pushlarni, qoʻlda ishga tushirishni hamda -merge-group hodisalarini qamrab oladi. Push, qoʻlda ishga tushirish va merge-group toʻliq tanlovni -bajaradi. Forklar va merge-grouplar odatda self-hosted runnerlarni tanlaydigan vazifalar uchun -hosted runnerlardan foydalanadi; joriy etishdan oldin yetarli hosted sigʻimi tekshirilishi kerak. - -Har bir JSON tasdiq yozuvi checkout qilingan SHA, ish jarayoni bajarilishi va urinishni aniqlaydi. -CLI checkout/event SHA nomuvofiqligini rad etadi. Ish jarayoni testlari siyosat aʼzoligini hukm -vazifasining `needs` roʻyxatiga bogʻlaydi, shunda yangi yoki olib tashlangan yoʻnalish sezdirmasdan -yoʻqolib qolmaydi. Tasdiq yozuvlari nashr qilish, joylashtirish yoki mavjud tavsiyaviy skanerning -ichki ishlashini emas, oʻz ish jarayonini qamrab oladi. Shox qoidalarida har ikkala tekshiruv nomini -faollashtirish alohida maʼmuriy oʻzgarishdir; bu vazifalarni qoʻshishning oʻzi shoxni himoyalamaydi. - -### Statik skanerlash inventari - -Versiyalangan npm aliaslari inventari va statik skanerlash aʼzoligi +tasnif kod yoʻnalishini qoʻllanilmaydigan qilishi mumkin; qoralama PR qabul qilinadigan nomzod emas. +`hotfix` yorligʻi dalillarni taqdim etish talabini bekor qilmaydi. + +Har ikkala ish jarayoni PRʼlarni va main/release shoxlariga push qilishni, qoʻlda ishga tushirishni +hamda merge-group hodisalarini qamrab oladi. Push, dispatch va merge-group toʻliq tanlovni ishga +tushiradi. Forklar va merge-grouplar aks holda self-hosted runnerlarni tanlaydigan vazifalar uchun +hosted runnerlardan foydalanadi; joriy etishdan oldin hosted runnerlarning yetarli sigʻimi +tekshirilishi kerak. + +Har bir JSON kvitansiyasi checkout qilingan SHA, ish jarayoni ishga tushirilishi va urinishni +aniqlaydi. CLI checkout/event SHA nomuvofiqligini rad etadi. Ish jarayoni testlari siyosat +aʼzoligini hukm vazifasining `needs` roʻyxatiga bogʻlaydi, shuning uchun yangi yoki olib tashlangan +yoʻnalish sezdirmasdan yoʻqolib qololmaydi. Kvitansiyalar nashr qilish, joylashtirish yoki mavjud +tavsiyaviy skanerning ichki qismlarini emas, faqat oʻz ish jarayonini qamrab oladi. Shox +qoidalarida ikkala tekshiruv nomini faollashtirish alohida maʼmuriy oʻzgarishdir; bu vazifalarni +qoʻshishning oʻzi shoxni himoya qilmaydi. + +### Statik skanerlash roʻyxati + +Versiyalangan npm-alias roʻyxati va statik skanerlash aʼzoligi `config/quality/gate-manifest.json` faylida joylashgan. Skript nomlari va aniq buyruqlarni `package.json` bilan solishtirib tekshirish uchun `npm run check:gate-manifest` buyrugʻini bajaring; -qoʻshishlar, olib tashlashlar va buyruqlardagi ogʻishlar ham mahalliy hook, ham CI dagi -oʻzgarishlarni tasniflash vazifalarini muvaffaqiyatsiz qiladi. Alias ish jarayoni vazifasi, matritsa -nusxasi yoki test holati emas: bu miqdorlarni oʻzaro teng deb koʻrsatmaslik kerak. +qoʻshishlar, olib tashlashlar va buyruqlardagi chetlanishlar ham lokal hook, ham CIʼdagi +oʻzgarishlarni tasniflash vazifalarini muvaffaqiyatsiz yakunlaydi. Alias ish jarayoni vazifasi, +matritsa nusxasi yoki test holati emas: bu miqdorlarni oʻzaro almashtiriladigan tarzda koʻrsatish +mumkin emas. Tanlangan aliaslarni bajarmasdan koʻrib chiqish uchun `npm run quality:scan -- --list` yoki `npm run quality:scan:fast -- --list` buyrugʻidan foydalaning. Runner npm kirish nuqtasini ishga tushiradi, shuning uchun uning bajarilish muhiti (jumladan, sozlangan joylarda Bun) saqlanadi. -Manifest ushbu profillardan tashqaridagi aliaslarni alohida ishga tushiriladigan sifatida qayd etadi -va faqat oʻqish uchun moʻljallangan skanerlash profillarida texnik xizmat buyruqlari taqiqlanadi. +Manifest ushbu profillardan tashqaridagi aliaslarni alohida ishga tushiriladigan sifatida qayd +etadi va faqat oʻqish uchun moʻljallangan skanerlash profillarida texnik xizmat buyruqlari +taqiqlanadi. Bu profillar faqat statik skanerlashni qamrab oladi. Ular mahsulot testlari, qamrov, paketlash, tashqi tekshiruvlar yoki nomzodning relizga toʻliq qabul qilinishini tasdiqlamaydi. Ish jarayoniga qabul qilish bogʻlangan `config/quality/admission-policy.json` va -`scripts/quality/admission-verdict.mjs` fayllaridan foydalanadi. Release-observer profillari alohida -qoladi; ularning qoʻllanadigan tekshiruvlari va tasdiq yozuvlarini mustaqil ravishda koʻrib chiqing. -Quyidagi matnli inventar maʼlumotnoma boʻlib, nazoratning amalda bajarilganiga dalil emas. - -Skriptlar `scripts/check/` (siyosat nazoratlari) va `scripts/quality/` (ratchet mexanizmi) ostida -joylashgan. CI uchun asosiy haqiqat manbasi `.github/workflows/ci.yml` hisoblanadi. - -### Reliz PR uchun tezkor yoʻl (`quality.yml`) - -`.github/workflows/quality.yml` main/release PRlarida, himoyalangan shoxlarga pushlarda, qoʻlda -ishga tushirishda va merge-grouplarda CI imkoniyatlarini toʻldiradi. PRlar yoʻl boʻyicha -filtrlangan tezkor tekshiruvlardan foydalanadi. Doimiy ravishda oʻchirib qoʻyilgan takroriy build -olib tashlandi; haqiqiy build/package/boot tekshiruvlari CI da saqlanib qolgan. - -| Vazifa | Qamrov | Bloklovchi | -| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `Docs Gates (fast-path)` | Hujjatlar/kod PRlari; API hujjatlari havolalari va barcha hujjatlar | Ha | -| `Fast Quality Gates` | Kod PRlari; statik tekshiruvlar, typecheck, dashboard typecheck, taʼsirlangan unit testlar | Ha | -| `Forgotten sibling tests` | Kod PRlari; oʻzgartirilgan modullar statik isteʼmolchilar va nomzod sibling testlargacha kuzatiladi; barrel va dynamic-import yoʻllari allowlistdagi istisnolarga havolalar bilan tavsiyaviy diagnostika sifatida xabar qilinadi | **Tavsiyaviy** | -| `Vitest (fast-path)` | Kod PRlari; tezkor vitest toʻplami | Ha | -| `Unit Tests fast-path` | Kod PRlari; 4-shardli unit testlar toʻplami | Ha | -| `No new ESLint warnings` | Kod PRlari; suppressions-aware lint nazorati | Ha, forklar ham | -| `Merge integrity (changelog + generated skills)` | Qoralama boʻlmagan PRlar; changelog va yaratilgan skilllar sinxronligi | Ha, forklar ham | +`scripts/quality/admission-verdict.mjs` fayllaridan foydalanadi. Release-observer profillari +alohida qoladi; ularning tegishli tekshiruvlari va kvitansiyalarini mustaqil ravishda koʻrib +chiqing. Quyidagi matnli roʻyxat maʼlumotnoma boʻlib, geyt haqiqatda ishga tushganining isboti +emas. + +Skriptlar `scripts/check/` (siyosat geytlari) va `scripts/quality/` (ratchet mexanizmi) ostida +joylashgan. CI uchun haqiqat manbasi `.github/workflows/ci.yml` hisoblanadi. + +### Reliz PRʼlari uchun tezkor yoʻl (`quality.yml`) + +`.github/workflows/quality.yml` main/release PRʼlari, himoyalangan shoxlarga push qilish, +dispatch va merge-grouplarda CIʼni toʻldiradi. PRʼlar yoʻl boʻyicha filtrlangan tezkor +tekshiruvlardan foydalanadi. Doimiy ravishda oʻchirib qoʻyilgan takroriy build olib tashlangan; +haqiqiy build/package/boot tekshiruvlari CIʼda qoladi. + +| Vazifa | Qamrov | Bloklovchi | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `Docs Gates (fast-path)` | Hujjatlar/kod PRʼlari; API hujjatlari havolalari va barcha hujjatlar | Ha | +| `Fast Quality Gates` | Kod PRʼlari; statik tekshiruvlar, typecheck, dashboard typecheck, taʼsirlangan unit testlar | Ha | +| `Forgotten sibling tests` | Kod PRʼlari; oʻzgargan modullardan statik isteʼmolchilar va nomzod sibling testlargacha kuzatish; barrel va dynamic-import yoʻllari allowlistdagi tegishli istisnolar bilan tavsiyaviy diagnostika sifatida xabar qilinadi | **Tavsiyaviy** | +| `Vitest (fast-path)` | Kod PRʼlari; tezkor vitest toʻplami | Ha | +| `Unit Tests fast-path` | Kod PRʼlari; 4-shardli unit testlar toʻplami | Ha | +| `No new ESLint warnings` | Kod PRʼlari; suppressionlarni hisobga oluvchi lint himoyasi | Ha, forklar ham kiradi | +| `Merge integrity (changelog + generated skills)` | Qoralama boʻlmagan PRʼlar; changelog va yaratilgan skill sinxronizatsiyasi | Ha, forklar ham kiradi | #### Unutilgan sibling testlar hisoboti -`npm run check:forgotten-sibling-tests` test taʼsiri xaritasi ortidagi import resolverdan qayta -foydalanadi. Har bir oʻzgartirilgan production moduli uchun, agar nomzod test pull-request diffida -boʻlmasa, u deterministik -`oʻzgartirilgan modul/simvol -> statik isteʼmolchi -> nomzod sibling test` zanjirlarini xabar qiladi. -Markdown xulosasi va JSON natijasi bloklovchi rejimni joriy etishdan oldin kalibrlash uchun -`forgotten-sibling-tests` ish jarayoni artefakti sifatida saqlanadi. +`npm run check:forgotten-sibling-tests` test taʼsiri xaritasi asosidagi import resolveridan qayta +foydalanadi. Har bir oʻzgartirilgan ishlab chiqarish moduli uchun nomzod test pull-request diffida +mavjud boʻlmaganda deterministik +`oʻzgartirilgan modul/belgi -> statik isteʼmolchi -> nomzod sibling test` zanjirlarini hisobotga +kiritadi. Markdown xulosasi va JSON natijasi har qanday bloklovchi joriy etishdan oldin kalibrlash +uchun `forgotten-sibling-tests` ish jarayoni artefakti sifatida saqlanadi. -Barrel qayta eksportlari va dinamik importlar faqat aniqlik diagnostikasi hisoblanadi; ular hech qachon +Barrel qayta eksportlari va dinamik importlar faqat rezolyutsiya diagnostikasi hisoblanadi; ular hech qachon bloklovchi topilma yaratmaydi. Koʻrib chiqilgan istisnolar `config/quality/forgotten-sibling-allowlist.json` faylida saqlanadi. Har bir yozuv isteʼmolchi va nomzod -testni koʻrsatishi, aniq asos keltirishi hamda GitHub muammosi yoki pull request’iga havola berishi kerak. Notoʻgʻri tuzilgan yozuvlar -yopiq holatda xatoga uchraydi. Istisnolar oʻchirilgan nomzod testni yoki `.skip`/`.todo` qoʻshadigan diff’ni yashira olmaydi; -assertion’larni zaiflashtirish va boshqa niqoblash usullari mustaqil ravishda bloklovchi -`check:test-masking` nazoratiga tegishli boʻlib qoladi. +testni koʻrsatishi, aniq asos keltirishi hamda GitHub muammosi yoki pull request’ga havola berishi kerak. Notoʻgʻri shakllantirilgan yozuvlar +yopiq holatda xatolik bilan yakunlanadi. Istisnolar oʻchirilgan nomzod testni yoki `.skip`/`.todo` qoʻshadigan diff’ni yashira olmaydi; +assertion’larni zaiflashtirish va boshqa niqoblash holatlari mustaqil ravishda bloklovchi +`check:test-masking` darvozasi nazoratida qoladi. ### Vazifa: `lint` `main` uchun har bir PR’da ishga tushadi. Xatolik yuz bersa, birlashtirishni bloklaydi. -| Skript (`npm run ...`) | Tekshiradi | Bloklovchi | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `check:node-runtime` | Node.js versiyasi qoʻllab-quvvatlanadigan diapazonda ekanini | Ha | -| `check:cycles` | Siklik importlar — barcha `src/` + `open-sse/` modullari | Ha | -| `check:route-validation:t06` | Zod sxemalari barcha route’larda mavjudligini (Tier 6 siyosati) | Ha | -| `check:any-budget:t11` | `@ts-expect-error // any` soni belgilangan limitdan oshmasligini (Tier 11 catraca) | Ha | -| `check:provider-consistency` | `providers.ts` ichidagi har bir provayder `providerRegistry.ts` ichida mos yozuvga ega (va aksincha, ruxsat berilganlar roʻyxati doirasida) | Ha | -| `check:model-lifecycle` | Qoʻlda yuritiladigan uchta marshrutlash jadvali repozitoriyga kiritilgan hayot sikli surati (#11503) bilan muvofiq qoladi: `FITNESS_TABLE` (`taskFitness.ts`) `REGISTRY` marshrutlay oladigan, foydalanishdan chiqarilgan hech bir id uchun ball bermaydi; har bir `BUILT_IN_ALIASES` maqsadi `REGISTRY` ichida mavjud va foydalanishdan chiqarilgan id lar suratida yoʻq; `REGISTRY` ichida hamon mavjud boʻlgan har bir foydalanishdan chiqarilgan id boshqa joyga yoʻnaltiriladi yoki `allowedRetiredInCatalog` ichida keltiriladi; shuningdek, `DEFAULT_DEGRADATION_MAP` dagi hech bir manba yoki maqsad ushbu suratda foydalanishdan chiqarilgan deb koʻrsatilmagan. Bu modelga ayni paytda faol yuqori oqim xizmati tomonidan xizmat koʻrsatilayotganini isbotlamaydi. Oflayn — `config/quality/model-lifecycle.json` bilan taqqoslaydi; u `npm run quality:refresh-model-lifecycle` yordamida qoʻlda yangilanadi (tarmoq talab etiladi; CI tizimiga ulanmagan). `allowedRetiredInCatalog` — bosqichma-bosqich qisqartirish mexanizmi: yozuvni faqat kuzatuv masalasi bilan birga qoʻshing. | Ha | -| `check:fetch-targets` | Mijoz tomonidagi `src/` ichidagi har bir `fetch("/api/...")` haqiqiy `route.ts` fayliga yechiladi | Ha | -| `check:deps` | Repozitoriydagi har bir `package.json` boʻylab `npm install` orqali oʻrnatiladigan barcha bogʻliqliklar `dependency-allowlist.json` ichida mavjud; versiyasi mahkamlanmagan yoki slopsquattingga uchragan yangi paketlar belgilab qoʻyiladi | Ha | -| `audit:deps` | `npm audit` (ildiz + electron) — yuqori/kritik darajadagi tavsiyalar yoʻq (osv `check:vuln-ratchet` bilan qisman takrorlanadi; Ratsionalizatsiya beklogiga qarang) | Ha | -| `check:lockfile` | `package-lock.json` yaxlitligi — https reyestri, yaxlitlik xeshlari, xost almashtirishlari yoʻq | Ha | -| `check:licenses` | Ishlab chiqarish bogʻliqliklari uchun SPDX litsenziyalari ruxsat etilgan roʻyxati | Ha | -| `check:tracked-artifacts` | Build artefaktlari / commit qilingan `node_modules` ramziy havolalari yoʻq (husky pre-commit jarayonida ham ishga tushadi; pre-push ataylab yengil — #6716) | Ha | -| `check:ai-attribution` | PR commitlari, sarlavhasi yoki matnida AI/bot `Co-Authored-By` treyleri yoki AI tomonidan yaratilganlik futeri yoʻq — Qatʼiy qoida #16 (`quality.yml` faylidagi PR→`release/**` uchun fast-gates siklida — hodisa payloadini oʻqiydi, PRlardan tashqarida hech qanday amal bajarmaydi — hamda `ci.yml` faylidagi PR→`main` uchun lint jarayonining faqat PRga oid bosqichida; shuningdek, husky `commit-msg` hookida; inson hammualliflariga ruxsat beriladi; #14436) | -| `check:vitest-exclusions` | Har bir Vitest istisnosi kuzatuv issuesini koʻrsatadi va `config/quality/vitest-exclusions.json` faylida mavjud (#13204) | Ha | -| `check:file-size` | Hech bir manba fayli kengaytma boʻyicha belgilangan limitdan oshmaydi (ratchet: katta hajmli muzlatilgan fayllar `frozen` roʻyxatida) | Ha | -| `check:error-helper` | Executorlar/handlerlardagi xato javoblari `buildErrorBody()` / `sanitizeErrorMessage()` dan foydalanadi (Qatʼiy qoida #12) | Ha | -| `check:migration-numbering` | Migratsiya SQL fayllari ketma-ket raqamlangan, bo‘shliqlar yoki takrorlanishlar yo‘q | Ha | -| `check:public-creds` | `publicCreds.ts` faylidan tashqarida literal OAuth `client_id`/`client_secret` yoki Firebase Web kalitlari yo‘q (Qat’iy qoida #11) | Ha | -| `check:db-rules` | `src/lib/db/` modullaridan tashqarida xom SQL yo‘q; `localDb.ts` faylidan barrel-importlar yo‘q (Qat’iy qoidalar #2/#5) | Ha | -| `check:known-symbols` | Dispetcherlik jadvallarida ro‘yxatdan o‘tkazilgan provayder ijrochilari, marshrutlash strategiyalari va tarjimonlar diskdagi fayllarga mos keladi — yetim yoki e’lon qilinmagan simvollar yo‘q | Ha | -| `check:route-guard-membership` | Ichki jarayonni ishga tushiradigan har bir marshrut `isLocalOnlyPath()` tomonidan tasniflangan (Qat’iy qoidalar #15/#17) | Ha | -| `check:test-discovery` | Repodagi har bir `*.test.ts` / `*.spec.ts` fayli kamida bitta test ishga tushirgichi tomonidan aniqlanadi (xrapovik: `test-discovery-baseline.json` ichidagi yetimlar ro‘yxati faqat qisqarishi mumkin) | Ha | -| `check:agent-skills-sync` | Yaratilgan agent-skills artefaktlari ularning manba katalogiga mos keladi (tafovut yoʻq) | -| `check:provider-asset-provenance` | Provayder logotiplari/aktivlari uchun qayd etilgan kelib chiqish yozuvi mavjud | -| `lint:json` | JSON konfiguratsiya fayllari tahlildan muvaffaqiyatli oʻtadi va repo lint qoidalariga javob beradi | -| `typecheck:core` | TypeScript xatolarsiz kompilyatsiya qilinadi (faqat tavsiyaviy ogohlantirishlar) | Ha | -| `typecheck:noimplicit:core` | Qatʼiy `noImplicitAny` — kelajakka yoʻnaltirilgan; avvaldan mavjud koʻplab chaqiruv joylari hali ham annotatsiyalarni talab qiladi | **Tavsiyaviy** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `src/app/(dashboard)/**` doirasidagi `tsc` (#7033) — `typecheck:core`ning saralangan 27 faylli ruxsat roʻyxati hech qanday dashboard TSX faylini oʻz ichiga olmaydi, `next build` esa uni umuman tur tekshiruvidan oʻtkazmaydi (`next.config.mjs` faylida `ignoreBuildErrors: true` oʻrnatilgan), shu sababli u yerdagi yetim identifikator regressiyalari (#6625/#6909) CI uchun koʻrinmas edi. Har bir fayl/TS kodi boʻyicha muzlatilgan xatolar soni bazaviy koʻrsatkichi (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` bilan bir xil eskirganlikni nazorat qilish andozasi) bilan farqlar tekshiriladi — faqat bazaviy sondan ortiq YANGI xatolar tekshiruvdan oʻtolmaslikka sabab boʻladi; avvaldan mavjud xato tuzatilganda `--update` bilan bazaviy koʻrsatkichni pasaytiring. | Ha | +| Skript (`npm run ...`) | Tekshiradi | Bloklovchi | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `check:node-runtime` | Node.js versiyasi qoʻllab-quvvatlanadigan diapazonda ekanini | Ha | +| `check:cycles` | Butun `src/` + `open-sse/` boʻylab siklik importlarni (AST asosida, tsconfig `paths` rezolyutsiya qilingan). Oddiy ishga tushirish = tavsiyaviy, sikllarni roʻyxatlaydi. `check:cycles:ratchet` (CI ishga tushiradigan variant) sikllar soni `quality-baseline.json` faylidagi `metrics.cycles` chegarasidan oshganda bloklaydi — hozir 14, `direction: down`, shu sababli u faqat kamayishi mumkin (#15159 G-01/G-02) | Ha (ratchet) | +| `check:route-validation:t06` | Barcha routelarda Zod sxemalari mavjudligini (Tier 6 siyosati) | Ha | +| `check:any-budget:t11` | `@ts-expect-error // any` soni budjetdan oshmasligini (Tier 11 catraca) | Ha | +| `check:provider-consistency` | `providers.ts` ichidagi har bir provayder `providerRegistry.ts` ichida mos yozuvga ega (va aksincha, ruxsat etilgan roʻyxat doirasida) | Ha | +| `check:model-lifecycle` | Qoʻlda yuritiladigan uchta marshrutlash jadvali repozitoriyga kiritilgan hayotiy sikl surati (#11503) bilan muvofiq qoladi: `FITNESS_TABLE` (`taskFitness.ts`) `REGISTRY` marshrutlay oladigan, foydalanishdan chiqarilgan hech bir id uchun ball bermaydi; har bir `BUILT_IN_ALIASES` maqsadi `REGISTRY` ichida mavjud va foydalanishdan chiqarilgan id lar suratida yoʻq; `REGISTRY` ichida hamon mavjud boʻlgan har bir foydalanishdan chiqarilgan id boshqa manzilga yoʻnaltirilgan yoki `allowedRetiredInCatalog` ichida koʻrsatilgan; va `DEFAULT_DEGRADATION_MAP` ichidagi hech bir manba yoki maqsad ushbu suratda foydalanishdan chiqarilgan sifatida koʻrinmaydi. Bu modelga hozirda faol yuqori oqim tomonidan xizmat koʻrsatilayotganini isbotlamaydi. Oflayn — qoʻlda `npm run quality:refresh-model-lifecycle` (tarmoq; CI ga ulanmagan) orqali yangilanadigan `config/quality/model-lifecycle.json` bilan taqqoslaydi. `allowedRetiredInCatalog` — bosqichma-bosqich qisqartirish mexanizmi: yozuvni faqat kuzatuv muammosi bilan birga qoʻshing. | Ha | +| `check:fetch-targets` | Mijoz tomonidagi `src/` ichidagi har bir `fetch("/api/...")` haqiqiy `route.ts` fayliga mos keladi | Ha | +| `check:deps` | Repozitoriydagi har bir `package.json` boʻylab `npm install` orqali oʻrnatiladigan barcha bogʻliqliklar `dependency-allowlist.json` ichida mavjud; yangi aniq versiyaga mahkamlanmagan yoki slopsquattingga uchragan paketlar belgilanadi | Ha | +| `audit:deps` | `npm audit` (ildiz + electron) — yuqori/kritik darajadagi tavsiyalar yoʻq (osv `check:vuln-ratchet` bilan ustma-ust tushadi; Ratsionalizatsiya beklogiga qarang) | Ha | +| `check:lockfile` | `package-lock.json` yaxlitligi — https reyestri, yaxlitlik xeshlari, xost almashtirishlari yoʻq | Ha | +| `check:licenses` | Ishlab chiqarish bogʻliqliklari uchun ruxsat etilgan SPDX litsenziyalari roʻyxati | Ha | +| `check:tracked-artifacts` | Build artefaktlari / repozitoriyga commit qilingan `node_modules` ramziy havolalari mavjud emas (husky pre-commit jarayonida ham ishga tushadi; pre-push ataylab yengil qoldirilgan — #6716) | Ha | +| `check:ai-attribution` | PR commitlari, sarlavhasi yoki matnida AI/bot `Co-Authored-By` treyleri yoki AI tomonidan yaratilganlik futeri mavjud emas — Qatʼiy qoida #16 (`quality.yml` faylidagi PR→`release/**` uchun fast-gates siklida — hodisa payloadini oʻqiydi, PR boʻlmaganda hech narsa qilmaydi — va `ci.yml` lint jarayonidagi PR→`main` uchun faqat PRga tegishli qadamda; shuningdek, husky `commit-msg` hukida; inson hammualliflariga ruxsat beriladi; #14436) | +| `check:vitest-exclusions` | Har bir Vitest istisnosi kuzatuv muammosini koʻrsatadi va `config/quality/vitest-exclusions.json` faylida mavjud (#13204) | Ha | +| `check:file-size` | Hech bir manba fayli kengaytma uchun belgilangan limitdan oshmaydi (ratchet: katta fayllar `frozen` roʻyxatida muzlatilgan) | Ha | +| `check:error-helper` | Ijrochi va ishlov beruvchilardagi xato javoblari `buildErrorBody()` / `sanitizeErrorMessage()` dan foydalanadi (Qatʼiy qoida #12) | Ha | +| `check:migration-numbering` | Migratsiya SQL fayllari bo‘shliqlar va takrorlanishlarsiz ketma-ket raqamlangan | Ha | +| `check:public-creds` | `publicCreds.ts` faylidan tashqarida literal OAuth `client_id`/`client_secret` yoki Firebase Web kalitlari mavjud emas (Qat’iy qoida #11) | Ha | +| `check:db-rules` | `src/lib/db/` modullaridan tashqarida bevosita SQL mavjud emas; `localDb.ts` faylidan barrel-importlar mavjud emas (Qat’iy qoidalar #2/#5) | Ha | +| `check:known-symbols` | Dispetcher jadvallarida ro‘yxatdan o‘tkazilgan provayder ijrochilari, marshrutlash strategiyalari va tarjimonlar diskdagi fayllarga mos keladi — yetim yoki e’lon qilinmagan belgilar mavjud emas | Ha | +| `check:route-guard-membership` | Ichki jarayonni ishga tushiradigan har bir marshrut `isLocalOnlyPath()` tomonidan tasniflanadi (Qat’iy qoidalar #15/#17) | Ha | +| `check:test-discovery` | Repodagi har bir `*.test.ts` / `*.spec.ts` fayli kamida bitta test ishga tushiruvchisi tomonidan aniqlanadi (ratchet: `test-discovery-baseline.json` faylidagi yetimlar ro‘yxati faqat qisqarishi mumkin) | Ha | +| `check:agent-skills-sync` | Yaratilgan agent-skills artefaktlari ularning manba katalogiga mos keladi (tafovut yoʻq) | +| `check:provider-asset-provenance` | Provayder logotiplari/aktivlari uchun qayd etilgan kelib chiqish yozuvi mavjud | +| `lint:json` | JSON konfiguratsiya fayllari muvaffaqiyatli tahlil qilinadi va repo lint qoidalariga mos keladi | +| `typecheck:core` | TypeScript xatolarsiz kompilyatsiya qilinadi (faqat tavsiyaviy ogohlantirishlar) | Ha | +| `typecheck:noimplicit:core` | Qatʼiy `noImplicitAny` — kelajakka yoʻnaltirilgan; avvaldan mavjud koʻplab chaqiruv joylari hali ham annotatsiyalarni talab qiladi | **Tavsiyaviy** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `src/app/(dashboard)/**` doirasidagi `tsc` (#7033) — `typecheck:core`ning saralangan 27 faylli ruxsat roʻyxati hech qanday dashboard TSX faylini oʻz ichiga olmaydi, `next build` esa uni umuman tur tekshiruvidan oʻtkazmaydi (`next.config.mjs` faylida `ignoreBuildErrors: true` oʻrnatilgan), shu sababli u yerdagi yetim identifikator regressiyalari (#6625/#6909) CI uchun koʻrinmas edi. Har bir fayl va har bir TS kodi boʻyicha muzlatilgan xatolar soni bazaviy koʻrsatkichi (`config/quality/dashboard-typecheck-baseline.json`, `check:known-symbols` bilan bir xil eskirganlikni tekshirish andozasi) bilan farqlar solishtiriladi — faqat bazaviy koʻrsatkichdagi sondan ortiq YANGI xatolar tekshiruvni muvaffaqiyatsiz qiladi; avvaldan mavjud xato tuzatilganda `--update` orqali bazaviy koʻrsatkichni pasaytiring. | Ha | ### Vazifa: `quality-gate` `test-coverage`dan keyin ishga tushadi. Muvaffaqiyatsizlik yuz bersa, birlashtirishni bloklaydi. -| Skript | Tekshiradi | Bloklovchi | -| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| `quality:collect` | `quality-metrics.json` faylini yaratadi (ESLint ogohlantirishlari soni, birlashtirilgan shard hisobotidan qamrov) | Ha (ratchetdan oldin) | -| `quality:ratchet` | `quality-baseline.json` faylidagi har bir metrika yomonlashmagan (ESLint ogohlantirishlari ≤ bazaviy qiymat; qamrov ≥ bazaviy qiymat) | Ha | -| `check:duplication` | Kod takrorlanishi (jscpd@4) `quality-baseline.json` faylidagi bazaviy qiymatdan oshmaydi | Ha | -| `check:complexity` | Fayl darajasidagi siklomatik murakkablik chegaradan oshmaydi (asosiy ESLint `complexity` + `max-lines-per-function`) | Ha | -| `check:cognitive-complexity` | Kognitiv murakkablik ratcheti (`eslint-plugin-sonarjs`) — alohida ESLint tekshiruvi; CI ikkalasini yagona `check:complexity-ratchets` bosqichi sifatida birlashtirib ishga tushiradi | Ha | -| `check:dead-code` | Ishlatilmaydigan eksportlar / fayllar ratcheti (knip) bazaviy qiymatga nisbatan yomonlashmaydi | Ha | -| `check:compression-budget` | Siqish benchmarki byudjeti — har bir engine uchun token tejashning quyi chegaralari yomonlashmasligi kerak | Ha | -| `check:type-coverage` | Tiplashtirilganlik foizi ratcheti (`type-coverage`) yomonlashmaydi; asosan `typecheck:noimplicit:core` o‘rnini bosadi | Ha | -| `check:codeql-ratchet` | Ochiq CodeQL ogohlantirishlari soni yomonlashmaydi (`gh api` orqali o‘qiydi; token bo‘lmasa, xatosiz o‘tkazib yuboradi) — yangilash davriyligi va qo‘lda ishga tushirish: quyidagi "CodeQL ratchet" bo‘limiga qarang | Ha | +| Skript | Tekshiradi | Bloklovchi | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `quality:collect` | `quality-metrics.json` faylini yaratadi (ESLint ogohlantirishlari soni, birlashtirilgan shard hisobotidan qamrov) | Ha (ratchetdan oldingi bosqich) | +| `quality:ratchet` | `quality-baseline.json` ichidagi har bir metrika yomonlashmagan (ESLint ogohlantirishlari ≤ bazaviy qiymat; qamrov ≥ bazaviy qiymat) | Ha | +| `check:duplication` | Kod takrorlanishi (jscpd@4) `quality-baseline.json` ichidagi bazaviy qiymatdan oshmaydi | Ha | +| `check:complexity` | Fayl darajasidagi siklomatik murakkablik chegaradan oshmaydi (asosiy ESLint `complexity` + `max-lines-per-function`) | Ha | +| `check:cognitive-complexity` | Kognitiv murakkablik ratcheti (`eslint-plugin-sonarjs`) — alohida ESLint tekshiruvi; CI ikkalasini yagona `check:complexity-ratchets` bosqichi sifatida birlashtirib ishga tushiradi | Ha | +| `check:dead-code` | Ishlatilmaydigan eksportlar/fayllar ratcheti (knip) bazaviy qiymatga nisbatan yomonlashmaydi | Ha | +| `check:compression-budget` | Siqish benchmarki byudjeti — har bir mexanizm uchun token tejashning minimal chegaralari yomonlashmasligi kerak | Ha | +| `check:type-coverage` | Tiplashtirilgan kod foizi ratcheti (`type-coverage`) yomonlashmaydi; asosan `typecheck:noimplicit:core` o‘rnini bosadi | Ha | +| `check:codeql-ratchet` | Ochiq CodeQL ogohlantirishlari soni yomonlashmaydi (`gh api` orqali o‘qiydi; token bo‘lmasa, xatosiz o‘tkazib yuboradi) — yangilash davriyligi va qo‘lda ishga tushirish: quyidagi «CodeQL ratcheti» bo‘limiga qarang | Ha | ### Vazifa: `quality-extended` Butun vazifa tavsiyaviy (`continue-on-error: true`). npm asosidagi ratchetlar amalda ishga tushadi; tashqi skanerlar `gh release download` orqali o‘rnatiladi va binar fayl -hali ham mavjud bo‘lmasa, o‘zini o‘zi o‘tkazib yuboradi (exit 0). +hali ham mavjud bo‘lmasa, o‘zini o‘zi o‘tkazib yuboradi (0 kodi bilan chiqadi). -| Skript | Tekshiradi | Bloklovchi | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -| `check:circular-deps` | Siklik bog‘liqliklar yo‘q (dpdm) | **Tavsiyaviy** | -| `check:bundle-size` | Bundle hajmi chegaradan oshmaydi | **Tavsiyaviy** | -| `check:secrets` | Sirlarni skanerlash (gitleaks) — binar fayl bo‘lmasa, o‘tkazib yuboradi | **Tavsiyaviy** | -| `check:vuln-ratchet` | Bog‘liqliklardagi zaifliklar (osv-scanner) yomonlashmaydi — binar fayl bo‘lmasa, o‘tkazib yuboradi | **Tavsiyaviy** | -| `check:workflows` | Workflow lintingi (actionlint + zizmor); yo‘q yoki buzilgan skanerlar, yaroqsiz hisobotlar yoxud mavjud bo‘lmagan ratchet bazaviy qiymati tekshiruvni INCOMPLETE holatida muvaffaqiyatsiz qiladi. Haqiqiy topilmalar tanlangan qat’iy/tavsiyaviy/ratchet siyosatiga amal qiladi | Bajarilishi shart; zizmor ratcheti CI’da bloklovchi | -| `check:openapi-breaking` | Ommaviy API shartnomasidagi (`openapi.yaml`) asosiy branchga nisbatan moslikni buzuvchi o‘zgarishlar (oasdiff) — `openapiBreaking=N` chiqaradi; oasdiff mavjud bo‘lmasa yoki asosiy spetsifikatsiyani aniqlab bo‘lmasa, o‘tkazib yuboradi | **Tavsiyaviy** | +| Skript | Tekshiradi | Bloklovchi | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | +| `check:circular-deps` | Siklik bog‘liqliklar yo‘q (dpdm) | **Tavsiyaviy** | +| `check:bundle-size` | To‘plam hajmi chegaradan oshmaydi | **Tavsiyaviy** | +| `check:secrets` | Sirlarni skanerlash (gitleaks) — binar fayl mavjud bo‘lmasa, o‘tkazib yuboradi | **Tavsiyaviy** | +| `check:vuln-ratchet` | Bog‘liqliklardagi zaifliklar (osv-scanner) yomonlashmaydi — binar fayl mavjud bo‘lmasa, o‘tkazib yuboradi | **Tavsiyaviy** | +| `check:workflows` | Ish jarayonlarini lint tekshiruvidan o‘tkazish (actionlint + zizmor); mavjud bo‘lmagan/ishlamaydigan skanerlar, yaroqsiz hisobotlar yoki mavjud bo‘lmagan ratchet bazaviy qiymati INCOMPLETE sifatida muvaffaqiyatsiz tugaydi. Haqiqiy topilmalar tanlangan qat’iy/tavsiyaviy/ratchet siyosatiga amal qiladi | Bajarilishi shart; zizmor ratcheti CI’da bloklaydi | +| `check:openapi-breaking` | Ommaviy API shartnomasidagi (`openapi.yaml`) asosiy tarmoqqa nisbatan buzuvchi o‘zgarishlar (oasdiff) — `openapiBreaking=N` chiqaradi; oasdiff mavjud bo‘lmasa yoki asosiy spetsifikatsiyani aniqlab bo‘lmasa, o‘tkazib yuboradi | **Tavsiyaviy** | ### Vazifa: `docs-sync-strict` -`main` branchiga yuborilgan har bir PR uchun ishga tushadi. Muvaffaqiyatsizlik yuz bersa, birlashtirishni bloklaydi. - -| Skript | Tekshiradi | Bloklovchi | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `check:docs-all` | Quyidagi 6 ta quyi tekshiruvni ketma-ket ishga tushiradigan meta-tekshiruv | Ha | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versiyalarining muvofiqligi | Ha | -| ↳ `check:docs-counts` | Matndagi sonlar (provayderlar soni, migratsiyalar soni va hokazo) haqiqiy sonlarning ratchet oynasi doirasida ekanini | Ha | -| ↳ `check:env-doc-sync` | `.env.example` ichidagi har bir muhit o‘zgaruvchisi hujjatlardagi jadvalda qayd etilgani va aksincha ekanini | Ha | -| ↳ `check:deprecated-versions` | Hujjatlarda eskirgan versiya satrlari yo‘qligini | Ha | -| ↳ `check:doc-links` | Hujjatlardagi ichki markdown havolalari haqiqiy fayllarga olib borishini (`[text]`/`(path)` shakli) | Ha | -| ↳ `check:fabricated-docs` | Hujjatlarda keltirilgan marshrutlar, muhit o‘zgaruvchilari, CLI buyruqlari, hook nomlari va fayl yo‘llari kod bazasida mavjudligini. `--strict` orqali qat’iy tekshiruv; bayroqsiz — yumshoq xatolik. | Ha (CI ichida `--strict` orqali) | -| `check:cli-i18n` | CLI buyruq satrlari barcha i18n lokal fayllarida mavjudligini | Ha | -| `check:openapi-coverage` | OpenAPI spetsifikatsiyasi haqiqiy marshrutlarning kamida ratchet orqali belgilangan minimal miqdorini qamrab olishini | Ha | -| `check:openapi-security-tiers` | `openapi.yaml` ichidagi xavfsizlik darajasi annotatsiyalari `routeGuard.ts` tasniflariga mos kelishini | **Tavsiyaviy** | -| `check:openapi-routes` | `openapi.yaml` ichidagi har bir yo‘l haqiqiy `route.ts` fayliga mos kelishini (gallyutsinatsiyaga qarshi) | Ha | -| `check:docs-symbols` | `docs/**/*.md` ichidagi har bir `/api/...` havolasi haqiqiy `route.ts` fayliga mos kelishini (gallyutsinatsiyaga qarshi) | Ha | -| `i18n translation drift` | i18n lokal fayllaridagi tarjima qilinmagan kalitlar — faqat ogohlantirish | **Tavsiyaviy** | +`main` tarmog‘iga yuborilgan har bir PR uchun ishga tushadi. Muvaffaqiyatsizlikda birlashtirishni bloklaydi. + +| Skript | Tekshiradi | Bloklovchi | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `check:docs-all` | Quyidagi 6 ta quyi tekshiruvni ketma-ket ishga tushiradigan meta-tekshiruv | Ha | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt versiyalarining muvofiqligi | Ha | +| ↳ `check:docs-counts` | Matndagi sonlar (provayderlar soni, migratsiyalar soni va hokazo) haqiqiy sonlarning ratchet oraligʻida ekanligi | Ha | +| ↳ `check:env-doc-sync` | `.env.example` ichidagi har bir muhit oʻzgaruvchisi hujjatlardagi jadvalda qayd etilgani va aksincha | Ha | +| ↳ `check:deprecated-versions` | Hujjatlarda eskirgan versiya satrlari yoʻqligi | Ha | +| ↳ `check:doc-links` | Hujjatlardagi ichki markdown havolalari haqiqiy fayllarga olib borishi (`[matn]`/`(yoʻl)` shakli) | Ha | +| ↳ `check:fabricated-docs` | Hujjatlarda keltirilgan marshrutlar, muhit oʻzgaruvchilari, CLI buyruqlari, hook nomlari va fayl yoʻllari kod bazasida mavjudligi. `--strict` orqali qatʼiy tekshiruv; bayroqsiz yumshoq xato. | Ha (CI ichida `--strict` orqali) | +| `check:cli-i18n` | CLI buyruq satrlari barcha i18n lokal fayllarida mavjudligi | Ha | +| `check:openapi-coverage` | OpenAPI spetsifikatsiyasi haqiqiy marshrutlarning kamida ratchet orqali belgilangan minimal miqdorini qamrab olishi | Ha | +| `check:openapi-security-tiers` | `openapi.yaml` ichidagi xavfsizlik darajasi annotatsiyalari `routeGuard.ts` tasniflariga mosligi | **Maslahat** | +| `check:openapi-routes` | `openapi.yaml` ichidagi har bir yoʻl haqiqiy `route.ts` fayliga olib borishi (gallyutsinatsiyaga qarshi) | Ha | +| `check:docs-symbols` | `docs/**/*.md` ichidagi har bir `/api/...` havolasi haqiqiy `route.ts` fayliga olib borishi (gallyutsinatsiyaga qarshi) | Ha | +| `i18n translation drift` | i18n lokal fayllaridagi tarjima qilinmagan kalitlar — faqat ogohlantirish | **Maslahat** | ### Vazifa: `i18n-ui-coverage` -| Skript | Tekshiradi | Bloklovchi | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `check-ui-keys-coverage` (inline) | UI i18n kalitlarining qamrovi ≥ 65% ekanini | Ha | -| `check-ui-value-drift` (inline) | Qayta yozilgan inglizcha **qiymat** ortida eskirgan tarjima qolmasligini | Ha | -| `check-new-key-coverage` (inline) | **Yangi** inglizcha kalit har bir lokalda tarjima qilinganini — `__MISSING__:` belgisi qabul qilinmaydi | Ha | -| `check-translation-ratio` | Har bir lokal uchun haqiqiy tarjimalar nisbati (ruxsat etilganlar ro‘yxatidan tashqaridagi inglizcha bilan bir xil / o‘rinbosar / yetishmayotgan qismlar) `config/quality/i18n-translation-baseline.json` + ruxsat etilgan og‘ishdan oshmasligi kerak | **Tavsiyaviy** | +| Skript | Tekshiradi | Bloklovchi | +| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `check-ui-keys-coverage` (ichki) | UI i18n kalitlari qamrovi ≥ 65% | Ha | +| `check-ui-value-drift` (ichki) | Qayta yozilgan inglizcha **qiymat** ortida eskirgan tarjima qolmasligi | Ha | +| `check-new-key-coverage` (ichki) | **Yangi** inglizcha kalit har bir lokalda tarjima qilingan boʻlishi — `__MISSING__:` belgisi rad etiladi | Ha | +| `check-translation-ratio` | Har bir lokal uchun haqiqiy tarjimalar nisbati (ruxsat etilganlar roʻyxatidan tashqaridagi inglizcha bilan bir xil / toʻldiruvchi / yetishmayotgan qiymatlar) `config/quality/i18n-translation-baseline.json` + ruxsat etilgan ogʻishdan oshmasligi kerak | **Maslahat** | -`fetch-depth: 0` talab qilinadi — qiymatlar o‘zgarishini tekshirish jarayoni `en.json` faylini birlashtirish bazasi bilan solishtiradi. +`fetch-depth: 0` talab qilinadi — qiymat ogʻishi tekshiruvi `en.json` faylini birlashtirish bazasi bilan taqqoslaydi. -#### `check-ui-value-drift` — eskirgan tarjimalarni tekshirish +#### `check-ui-value-drift` — eskirgan tarjimalar tekshiruvi Boshqa tekshiruvlar tuzilmaviy jihatdan aniqlay olmaydigan i18n regressiyasini aniqlaydi: inglizcha qiymat -qayta yoziladi, ammo _avvalgi_ inglizcha matndan olingan tarjimalar o‘zgarishsiz qoladi, natijada -ingliz tilidan boshqa tildagi foydalanuvchilar ishonchli ohangda yozilgan, ammo endi noto‘g‘ri bo‘lgan matnni o‘qishda davom etadi. - -Bu muammo amalda relizga chiqib ketgan. Antigravity tizimiga kirish yordamchisi qo‘shilganda (#5203) -`oauthModal.googleOAuthWarning` qayta yozilgan; **43 ta lokaldan 39 tasida** operatorlarga «to‘liq -URL manzilini nusxalab, quyidagi maydonga joylashtirish» kerakligini aytuvchi matn saqlanib qolgan — -bu provayder uchun bunday jarayonni yakunlab bo‘lmaydi. Muammo #8463 gacha aniqlanmagan, chunki: - -- `sync-ui-keys` faqat **mavjud bo‘lmagan** kalitlarni avtomatik to‘ldiradi, **eskirganlarini** esa hech qachon yangilamaydi; -- `check-ui-keys-coverage` kalitning _mavjudligini_ hisoblaydi, shu sababli eskirgan tarjima qamrab olingan deb baholanadi; -- `check-translation-drift` `docs/i18n//**.md` hujjat ko‘zgularini kuzatadi — - u `src/i18n/messages/*.json` fayllarini hech qachon o‘qimaydi. 2026-09 qayta sinxronlashidan beri `docs-sync-strict` vazifasida bloklovchi: asosiy hujjatni tahrirlang → `npm run i18n:run -- --files=` (bo‘lim darajasida, tezkor). - -**Diffni hisobga oladi, bazaviy holatga tayanmaydi.** U birlashtirish bazasidagi `en.json` faylini +qayta yoziladi, ammo _avvalgi_ inglizcha matn asosida yaratilgan tarjimalar oʻzgarishsiz qoladi, natijada +ingliz tilida soʻzlashmaydigan foydalanuvchilar ishonchli ohangda yozilgan, ammo endi notoʻgʻri matnni oʻqishda davom etadilar. + +Bu holat amalda relizga chiqib ketgan. Antigravity tizimiga kirish yordamchisi qoʻshilganda (#5203) +`oauthModal.googleOAuthWarning` qayta yozilgan; **43 ta lokaldan 39 tasi** operatorlarga «toʻliq +URL manzilini nusxalab, uni quyiga joylashtirish» kerakligini aytuvchi matnni saqlab qolgan — bu provayder +uchun yakunlab boʻlmaydigan jarayon. Quyidagi sabablarga koʻra bu holat #8463 gacha +sezilmagan: + +- `sync-ui-keys` faqat **mavjud boʻlmagan** kalitlarni toʻldiradi, **eskirganlarini** esa hech qachon yangilamaydi; +- `check-ui-keys-coverage` kalitning _mavjudligini_ hisoblaydi, shuning uchun eskirgan tarjima qamrab olingan deb hisoblanadi; +- `check-translation-drift` `docs/i18n//**.md` hujjat nusxalarini kuzatadi — + u hech qachon `src/i18n/messages/*.json` fayllarini oʻqimaydi. 2026-09 qayta sinxronlashdan beri + `docs-sync-strict` vazifasida bloklovchi: asosiy hujjatni tahrirlang → `npm run i18n:run -- --files=` (boʻlim darajasida, kam xarajatli). + +**Farqlarni hisobga oladi, boshlangʻich holatga tayanmaydi.** U birlashtirish bazasidagi `en.json` faylini ishchi daraxt bilan taqqoslaydi; inglizcha qiymati oʻzgargan har bir kalit uchun hali ham -oʻzgartirilmagan tarjimani saqlayotgan har qanday lokal eskirgan hisoblanadi. Bu ataylab -**avvaldan mavjud qarzdorlikni muzlatadi** — diff uzoq vaqtdan beri mavjud tarjima qaysi eski -inglizcha matndan kelib chiqqanini aniqlay olmaydi, shuning uchun tekshiruv faqat joriy -oʻzgarish taʼsir qilgan qismlarni baholaydi. Muqobil yechim (har bir kalit uchun xesh bazaviy -holati) ~600 KB hajmdagi generatsiya qilingan faylni talab qiladi, bu mavjud eng katta bazaviy -fayldan 3× katta boʻlib, har bir i18n PRda qayta-qayta oʻzgaradi. +oʻzgartirilmagan tarjimani saqlayotgan har qanday lokalizatsiya eskirgan hisoblanadi. Bu ataylab +**avvaldan mavjud qarzdorlikni muzlatadi** — farq uzoq vaqtdan beri mavjud tarjima qaysi eski +inglizcha matndan kelib chiqqanini aniqlay olmaydi, shuning uchun toʻsiq faqat joriy oʻzgarish +tegadigan qismlarni baholaydi. Muqobil yechim (har bir kalit uchun xesh boshlangʻich holati) +taxminan 600 KB hajmdagi generatsiya qilingan faylni talab qilardi; bu mavjud eng katta +boshlangʻich holatdan 3 baravar katta va har bir i18n PRda oʻzgarib turardi. -Undan oʻtishning ikki yoʻli bor: +Uni qanoatlantirishning ikki yoʻli bor: 1. taʼsirlangan tarjimalarni yangilash yoki -2. ularni `__MISSING__:` qiymatiga oʻrnatish — shunda bajarilish muhiti tuzatilgan - inglizcha matnni taqdim etadi (`src/i18n/request.ts::deepMergeFallback`, #7258) va kalit - tarjima navbatiga qoʻshiladi. +2. ularni `__MISSING__:` qiymatiga oʻrnatish — shunda bajarilish muhiti + tuzatilgan inglizcha matnni taqdim etadi (`src/i18n/request.ts::deepMergeFallback`, #7258) + va kalit tarjima navbatiga qoʻshiladi. -Agar satrning **maʼnosi** oʻzgargan boʻlsa, **kalit nomini oʻzgartirishni** afzal koʻring: -yangi kalit eskirgan tarjimani meros qilib ololmaydi. #8463 aynan shu andozadan foydalangan. +Agar satrning **maʼnosi** oʻzgargan boʻlsa, **kalit nomini oʻzgartirish** afzal: yangi kalit +eskirgan tarjimani meros qilib ololmaydi. #8463 aynan shu andozadan foydalangan. ```bash npm run i18n:check-value-drift # qatʼiy (CI ishga tushiradigan variant) @@ -238,15 +245,16 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` Bazaviy katalogni oʻqib boʻlmaganda (bazaviy refsiz sayoz klon) `SKIP reason=base-unresolved` -bilan 0 kodida yakunlanadi va `check-openapi-breaking` xatti-harakatini takrorlaydi. +bilan 0 kodida yakunlanadi; bu `check-openapi-breaking` xatti-harakatiga mos keladi. ### Vazifa: `i18n` -Toʻliq i18n tekshiruv matritsasi (har bir lokal uchun bittadan vazifa). Butun vazifa tavsiyaviy. +Toʻliq i18n tekshiruv matritsasi (har bir lokalizatsiya uchun bittadan vazifa). Butun vazifa +tavsiyaviy hisoblanadi. -| Skript | Tekshiradi | Bloklash | -| ------------------------------- | -------------------------------------- | --------------------------------------------------------- | -| `validate_translation.py quick` | Har bir lokal tarjimasining toʻliqligi | **Tavsiyaviy** (butun vazifada `continue-on-error: true`) | +| Skript | Tekshiradi | Bloklash | +| ------------------------------- | ---------------------------------------------- | --------------------------------------------------------- | +| `validate_translation.py quick` | Har bir lokalizatsiya tarjimasining toʻliqligi | **Tavsiyaviy** (butun vazifada `continue-on-error: true`) | ### Vazifa: `pr-test-policy` @@ -254,32 +262,32 @@ Faqat pull requestlarda ishga tushadi. | Skript | Tekshiradi | Bloklash | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` yoki `bin/` ichidagi ishlab chiqarish kodini oʻzgartiruvchi PRlar testlarni qoʻshishi yoki yangilashi shart (Qatʼiy qoida #8) | Ha | -| `check:test-masking` | Oʻzgartirilgan test fayllari tasdiqlar sof sonini kamaytirmaydi yoki `assert.ok(true)` tavtologiyalarini qoʻshmaydi | Ha | -| `check:pr-evidence` | PR tavsifida oʻzgarish uchun test/VPS dalillari keltirilgan (PR matnini grep orqali tekshirib, Qatʼiy qoida #18ni mexanizatsiyalaydi — moʻrt, Backlogga qarang) | Ha | +| `check:pr-test-policy` | `src/`, `open-sse/`, `electron/` yoki `bin/` ichidagi ishlab chiqarish kodini oʻzgartiradigan PRlar testlarni qoʻshishi yoki yangilashi shart (Qatʼiy qoida #8) | Ha | +| `check:test-masking` | Oʻzgartirilgan test fayllari tasdiqlar umumiy sonini kamaytirmaydi yoki `assert.ok(true)` tavtologiyalarini qoʻshmaydi | Ha | +| `check:pr-evidence` | PR matnida oʻzgarish uchun test/VPS dalillari keltirilgan (PR matnini grep qilish orqali Qatʼiy qoida #18ni avtomatlashtiradi — moʻrt, Backlogga qarang) | Ha | ### Vazifa: `test-vitest` `build`dan keyin ishga tushadi. Xatolik yuz bersa, birlashtirishni bloklaydi. -| Toʻplam | Tekshiradi | Bloklash | -| ---------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP serveri (110 ta vosita), autoCombo, kesh — vitest ishga tushiruvchisi | Ha | -| `test:vitest:ui` | UI komponent testlari — vitest ishga tushiruvchisi | **Bloklaydi** — avvaldan mavjud xatoliklar `vitest.config.ts`da aniq istisno qilingan; yangi xatoliklar vazifaning bajarilmasligiga olib keladi | +| Toʻplam | Tekshiradi | Bloklash | +| ---------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP serveri (110 ta vosita), autoCombo, kesh — vitest test ijrochisi | Ha | +| `test:vitest:ui` | UI komponent testlari — vitest test ijrochisi | **Bloklaydi** — avvaldan mavjud xatoliklar `vitest.config.ts`da aniq istisno qilingan; yangi xatoliklar vazifani yiqitadi | ### Tungi ish jarayonlari (rejalashtirilgan, tavsiyaviy) -Ular cron jadvali boʻyicha (va `workflow_dispatch` orqali) ishga tushadi, PRlarda esa hech qachon -ishga tushmaydi. Ularning barchasi tavsiyaviy. +Ular cron jadvali boʻyicha (va `workflow_dispatch` orqali) ishga tushadi, PRlarda esa hech +qachon ishga tushmaydi. Ularning barchasi tavsiyaviy. -| Ish jarayoni | Tekshiradi | Bloklash | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `nightly-property` | tasodifiy seed va koʻp sonli ishga tushirishlar bilan fast-check xususiyat testlari | **Tavsiyaviy** | -| `nightly-resilience` | heap oʻsishi nazorati, tartibsizlik asosidagi xatolik kiritish, k6 yuklama/uzoq muddatli yuklama sinovi | **Tavsiyaviy** | -| `nightly-llm-security` | promptfoo inʼeksiya himoyasi (bloklash rejimi) + garak zondlari (provayder siri boʻlmasa oʻtkazib yuboriladi) | **Tavsiyaviy** | -| `nightly-schemathesis` | `docs/openapi.yaml` yordamida ishlayotgan OmniRoutega qarshi OpenAPI shartnomasini fuzzing qilish (schemathesis) — spetsifikatsiya buzilishlari / qayta ishlanmagan 500 xatolarini yuzaga chiqaradi (Fase 8 B.4) | **Tavsiyaviy** | -| `nightly-mutation` | tezkor unit yoʻnalishidagi Stryker mutatsion testlash bali — omon qolgan mutantlar zaif tasdiqlarni yuzaga chiqaradi | **Tavsiyaviy** | -| `nightly-compat` | qoʻllab-quvvatlanadigan `engines.node` diapazonlari boʻylab Node mexanizmi moslik matritsasi | **Tavsiyaviy** | +| Ish jarayoni | Tekshiradi | Bloklash | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `nightly-property` | tasodifiy boshlangʻich qiymat va koʻp sonli ishga tushirishlar bilan fast-check xususiyat testlari | **Tavsiyaviy** | +| `nightly-resilience` | heap oʻsishi toʻsigʻi, nosozliklarni xaotik kiritish, k6 yuklama/uzoq muddatli yuklama sinovlari | **Tavsiyaviy** | +| `nightly-llm-security` | promptfoo inyeksiya himoyasi (bloklash rejimi) + garak tekshiruvlari (provayder siri boʻlmasa oʻtkazib yuboriladi) | **Tavsiyaviy** | +| `nightly-schemathesis` | `docs/openapi.yaml` yordamida ishlayotgan OmniRoutega qarshi OpenAPI shartnomasini fuzzing qilish (schemathesis) — spetsifikatsiya buzilishlari / qayta ishlanmagan 500 xatolarini aniqlaydi (Fase 8 B.4) | **Tavsiyaviy** | +| `nightly-mutation` | tezkor modul testlari yoʻlagi boʻyicha Stryker mutatsion testlash bahosi — saqlanib qolgan mutantlar zaif tasdiqlarni koʻrsatadi | **Tavsiyaviy** | +| `nightly-compat` | qoʻllab-quvvatlanadigan `engines.node` diapazonlari boʻyicha Node dvigateli moslik matritsasi | **Tavsiyaviy** | --- @@ -551,43 +559,43 @@ hech qachon seanslarni buzmaydi. --- -## Ratsionalizatsiya uchun vazifalar roʻyxati (ROI tahlili — 9-bosqich, 3-toʻlqin) +## Ratsionalizatsiya uchun vazifalar roʻyxati (ROI koʻrib chiqishi — 9-bosqich, 3-toʻlqin) -Ushbu inventar 2026-06-17 kuni `ci.yml` bilan solishtirilib muvofiqlashtirildi (oldingi versiyada +Ushbu inventar 2026-06-17 sanasida `ci.yml` bilan solishtirib muvofiqlashtirildi (avvalgi versiyada `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence` keltirilmagan edi). Muvofiqlashtirilgan toʻplamning ROI tahlili +`check:codeql-ratchet`, `check:pr-evidence` tushirib qoldirilgan edi). Muvofiqlashtirilgan toʻplamning ROI tahlili quyidagi ratsionalizatsiya nomzodlarini aniqladi. **Birlashtirishlar mexanik CI -oʻzgarishlaridir; yoqish/oʻchirish va olib tashlashlar esa operator vakolatidagi siyosiy qarorlardir.** Quyidagilarning hech biri +oʻzgarishlaridir; holatni almashtirish/oʻchirish esa operator ixtiyoridagi siyosiy qarorlardir.** Quyidagilarning hech biri hali qoʻllanmagan. -**Yuqorida hujjatlashtirilmagan yana bir jihat** (tavsiyaviy, signal darajasi past): `docs-lint` vazifasi +**Yuqorida hujjatlashtirilmagan boshqa elementlar ham bor** (tavsiyaviy, signal darajasi past): `docs-lint` vazifasi (markdownlint + Vale, butun vazifa uchun `continue-on-error`) va alohida skaner ish jarayonlari `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` -`quality-baseline.json` ichida mavjud, ammo `ci.yml` dagi bloklovchi ratchet bilan bogʻlanmagan — metrika +`quality-baseline.json` ichida mavjud, ammo `ci.yml` ichidagi bloklovchi ratchet’ga ulanmagan — metrika hozirda yetim qolgan. -### Birlashtirish / takrorlanishni bartaraf etish (mexanik, xavfi pastroq) +### Birlashtirish / takrorlarni yoʻqotish (mexanik, xavfi pastroq) -Har bir nomzod 2026-06-17 kuni amaldagi gate holatiga nisbatan tekshirildi (ishon, ammo tekshir); -bir nechta «yaqqol» birlashtirishlar aslida yashirin qarzdorlikni oʻz ichiga olishi aniqlandi va ular **tayyor holda almashtirishga** yaramaydi. +Har bir nomzod 2026-06-17 sanasidagi amaldagi gate holatiga nisbatan tekshirildi (ishoning, ammo tekshiring); +bir nechta «ravshan» birlashtirishlar aslida yashirin texnik qarzni berkitishi aniqlandi va ular **toʻgʻridan-toʻgʻri qoʻllashga** yaroqli emas. -- **`check:docs-sync` ikki marta ishga tushadi** — `lint` vazifasida alohida va yana `check:docs-all` (`docs-sync-strict`) hamda husky pre-commit hook ichida. ✅ **BAJARILDI** — `lint` ichidagi alohida chaqiruv olib tashlandi. -- **CVE skanerlash** — ❌ **Toza birlashtirish EMAS.** `audit:deps` har qanday yuqori/kritik CVE holatida qatʼiy xato bilan yakunlanadi; `check:vuln-ratchet` (osv) esa faqat boshlangʻich koʻrsatkichga nisbatan _regressiya_ yuz berganda xato beradi (hozirda 1 ta MODERATE). Semantikalari turlicha — `audit:deps` olib tashlansa, mutlaq yuqori/kritik darajadagi gate yoʻqoladi. Ikkalasi ham saqlansin. -- **Sikllarni aniqlash** — ❌ **Toza birlashtirish EMAS.** `check:circular-deps` (dpdm) **91 ta sikl** haqida xabar beradi (shu sababli u tavsiyaviy); avval ularni bartaraf etmasdan uni bloklovchi holatga oʻtkazib boʻlmaydi va uning qamrovi yashil holatdagi, saralangan `check:cycles` dan kengroq. `check:cycles` bloklovchi boʻlib qolsin; 91 ta dpdm siklini bartaraf etish alohida vazifalar roʻyxatidir. -- **Murakkablik** — ✅ **BAJARILDI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): bitta ESLint oʻtishi, cyclomatic+max-lines va cognitive boshlangʻich koʻrsatkichlari mustaqil qolishi uchun hisoblash `ruleId` boʻyicha amalga oshiriladi; alohida `check:complexity` / `check:cognitive-complexity` mahalliy `--update` uchun saqlanib qoladi. -- **`/api` anti-gallyutsinatsiyasi** — ✅ **BAJARILDI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` uchun bitta FS inventarizatsiyasi, openapi-routes + docs-symbols hali ham mustaqil hisobot beradi; alohida tekshiruvlar mahalliy ishga tushirish uchun saqlanadi. -- **`check:node-runtime` 11 ta vazifada ishga tushadi** — ⚠️ **ROI past.** Har biri alohida runner va tekshiruv <1s davom etadi; jami tejash ~10s, evaziga esa har bir vazifa uchun arzon himoya yoʻqoladi. Bunday oʻzgarishga arzimaydi. -- **CI lint ichidagi `typecheck:noimplicit:core`** — ✅ **lint vazifasidan olib tashlandi** (avval tavsiyaviy `continue-on-error` edi); bloklovchi tip yuzasi — `typecheck:core` + `check:type-coverage`. Mahalliy skript saqlab qolindi. +- **`check:docs-sync` ikki marta ishga tushadi** — `lint` vazifasida alohida va yana `check:docs-all` (`docs-sync-strict`) ichida hamda husky pre-commit hook’ida. ✅ **BAJARILDI** — alohida `lint` chaqiruvi olib tashlandi. +- **CVE skanerlash** — ❌ **Toza birlashtirish EMAS.** `audit:deps` har qanday high/critical CVE’da qatʼiy xato bilan toʻxtaydi; `check:vuln-ratchet` (osv) esa faqat boshlangʻich koʻrsatkichga nisbatan _regressiya_ boʻlganda xato beradi (hozirda 1 MODERATE). Semantikasi turlicha — `audit:deps` olib tashlansa, mutlaq high/critical gate yoʻqoladi. Ikkalasini ham saqlang. +- **Sikllarni aniqlash** — ✅ **BAJARILDI** (#15159 G-01/G-02). Bu yerdagi eski matnda `check:cycles` «yashil, saralangan» gate deb atalgan va `check:circular-deps` (dpdm) 91 ta sikl haqida xabar bergani sababli uni bloklovchi sifatida saqlash asoslangan edi. Bu yashil holat **soxta yashil** edi: `check:cycles` 5 ta quyi katalogni (450 ta fayl) skanerlagan, faqat statik `import|export … from` bilan moslikni topgan va barcha `@/` hamda `@omniroute/open-sse/` spetsifikatorlarini tashlab yuborgan, shu sababli repozitoriyda ustun boʻlgan dinamik import + alias sikllarini koʻra olmagan. Tuzatildi: gate endi `src` + `open-sse` boʻylab yuradi (5023 ta fayl), spetsifikatorlarni TypeScript AST’dan yigʻadi (shuning uchun `import("…")` hisobga olinadi, tur pozitsiyasidagi `typeof import("…")` esa olinmaydi) va tsconfig `paths` qiymatlarini aniqlaydi. U 0 emas, **14** ta sikl topadi. Avvaldan mavjud 14 ta siklni gate PR ichida tuzatib boʻlmagani sababli `check:cycles` endi **ratchet** (`--ratchet`, `quality-baseline.json` ichida yuqori chegara `metrics.cycles.value = 14`, `direction: down`) — u har qanday _regressiya_ ni bloklaydi va son faqat kamayishi mumkin. CI `npm run check:cycles:ratchet` buyrugʻini ishga tushiradi. Bosqichma-bosqich kamaytirish **A-01** bilan birga olib boriladi. `check:circular-deps` (dpdm) kengroq ikkinchi xulosa sifatida tavsiyaviy holatda qoladi. +- **Murakkablik** — ✅ **BAJARILDI** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): bitta ESLint oʻtishi, hisoblash ruleId boʻyicha amalga oshiriladi, shuning uchun cyclomatic+max-lines va cognitive boshlangʻich koʻrsatkichlari mustaqil qoladi; alohida `check:complexity` / `check:cognitive-complexity` lokal `--update` uchun saqlanadi. +- **`/api` anti-gallyutsinatsiyasi** — ✅ **BAJARILDI** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): `src/app/api` uchun yagona FS inventari, openapi-routes + docs-symbols hamon mustaqil hisobot beradi; alohida tekshiruvlar lokal ishga tushirishlar uchun saqlanadi. +- **`check:node-runtime` 11 ta vazifada ishga tushadi** — ⚠️ **ROI past.** Har biri alohida runner va tekshiruv <1s davom etadi; umumiy tejash ~10s, buning evaziga har bir vazifa uchun arzon himoya yoʻqoladi. Bunday oʻzgartirishlar bilan bogʻliq ortiqcha tashvishga arzimaydi. +- **CI lint’dagi `typecheck:noimplicit:core`** — ✅ **lint vazifasidan olib tashlandi** (tavsiyaviy `continue-on-error` edi); bloklovchi tur yuzasi `typecheck:core` + `check:type-coverage` hisoblanadi. Lokal script saqlab qolindi. -### Yoqish/oʻchirish / qaror qilish (operator siyosati) +### Holatni almashtirish / qaror qabul qilish (operator siyosati) -- `check:openapi-security-tiers` (tavsiyaviy) — ❌ **Toʻgʻridan-toʻgʻri bloklovchi qilib boʻlmaydi.** U 0 kodi bilan yakunlanadi, ammo `LOCAL_ONLY_API_PREFIXES` ostidagi bir nechta `traffic-inspector` marshrutlarida `x-loopback-only: true` annotatsiyasi yoʻqligi haqida ogohlantiradi. Uni majburiy qilish uchun avval ushbu annotatsiyalarni `openapi.yaml` fayliga qoʻshish kerak. -- `typecheck:noimplicit:core` (tavsiyaviy) — asosan bloklovchi `check:type-coverage` ratcheti bilan qamrab olingan. Uni ratchetga aylantiring yoki takroriy ikkinchi `tsc` oʻtishini olib tashlang. -- `test:vitest:ui` (hozir **bloklovchi**) — avvaldan mavjud xatolar `vitest.config.ts` ichida `// #8618` kuzatuv izohlari bilan aniq istisno qilingan; yangi xatolar vazifani muvaffaqiyatsiz yakunlaydi. -- `check:secrets` (gitleaks, hujjatlashtirilgan 3 ta yolgʻon musbat natijada qotirilgan bloklovchi ratchet) — 0 ga tushirish uchun ushbu 3 tasini ruxsat etilganlar roʻyxatiga kiriting yoki tavsiyaviy darajaga tushiring. GitHub’ning ichki secret-scanning funksiyasi + `check:public-creds` bilan ustma-ust tushadi. -- `check:pr-evidence` (bloklovchi, PR matnidagi nasrni grep orqali tekshiradi) — yolgʻon musbat natijalar xavfi yuqori; olib tashlansa, Hard Rule #18 ijrosi zaiflashadi, shuning uchun bu haqiqiy siyosiy qarordir. -- `semgrep` (alohida tavsiyaviy tekshiruv) — OWASP oilalari boʻyicha CodeQL bilan ustma-ust tushadi; uning boshlangʻich koʻrsatkichini ratchetga ulang yoki olib tashlang. +- `check:openapi-security-tiers` (tavsiyaviy) — ❌ **Toza tarzda almashtirib boʻlmaydi.** U 0 kodi bilan yakunlanadi, ammo `LOCAL_ONLY_API_PREFIXES` ostidagi bir nechta `traffic-inspector` marshrutlarida `x-loopback-only: true` annotatsiyasi yoʻqligi haqida ogohlantiradi. Uni majburiy qilish uchun avval ushbu annotatsiyalarni `openapi.yaml` fayliga qoʻshish kerak. +- `typecheck:noimplicit:core` (tavsiyaviy) — asosan bloklovchi `check:type-coverage` ratchet’i bilan qamrab olingan. Uni ratchet’ga aylantiring yoki takroriy ikkinchi `tsc` oʻtishini olib tashlang. +- `test:vitest:ui` (hozir **bloklovchi**) — avvaldan mavjud nosozliklar `vitest.config.ts` ichida `// #8618` kuzatuv izohlari bilan ochiq tarzda istisno qilingan; yangi nosozliklar vazifani muvaffaqiyatsiz yakunlaydi. +- `check:secrets` (gitleaks, hujjatlashtirilgan 3 ta yolgʻon ijobiy natijada muzlatilgan bloklovchi ratchet) — 0 ga yetkazish uchun ushbu 3 tasini ruxsat etilganlar roʻyxatiga kiriting yoki tavsiyaviy darajaga tushiring. GitHub’ning ichki secret-scanning funksiyasi + `check:public-creds` bilan ustma-ust tushadi. +- `check:pr-evidence` (bloklovchi, PR-body matnini grep orqali qidiradi) — yolgʻon ijobiy natija xavfi yuqori; olib tashlansa, Hard Rule #18 ijrosi zaiflashadi, shuning uchun bu haqiqiy siyosiy qarordir. +- `semgrep` (alohida tavsiyaviy) — OWASP oilalari boʻyicha CodeQL bilan ustma-ust tushadi; uning boshlangʻich koʻrsatkichini ratchet’ga ulang yoki olib tashlang. --- diff --git a/docs/i18n/vi/CONTRIBUTING.md b/docs/i18n/vi/CONTRIBUTING.md index 816871fdbf3..9b7114f958c 100644 --- a/docs/i18n/vi/CONTRIBUTING.md +++ b/docs/i18n/vi/CONTRIBUTING.md @@ -389,20 +389,20 @@ Viết các kiểm thử đơn vị trong `tests/unit/`, tối thiểu bao gồm ## Danh sách kiểm tra Pull Request -- [ ] Các bài kiểm thử đều vượt qua (`npm test`) -- [ ] Quá trình kiểm tra lint vượt qua (`npm run lint`) -- [ ] Quá trình build thành công (`npm run build`) +- [ ] Các bài kiểm thử đều đạt (`npm test`) +- [ ] Kiểm tra lint đạt (`npm run lint`) +- [ ] Build thành công (`npm run build`) - [ ] Đã thêm kiểu TypeScript cho các hàm và interface công khai mới -- [ ] Không có secret hoặc giá trị dự phòng được mã hóa cứng -- [ ] Thông tin xác thực upstream công khai được nhúng thông qua `resolvePublicCred()` (xem [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), tuyệt đối không dùng giá trị literal -- [ ] Phản hồi lỗi được xử lý thông qua `buildErrorBody()` / `sanitizeErrorMessage()` — không đưa stack trace thô vào nội dung phản hồi (xem [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Các lệnh shell (`exec` / `spawn`) truyền giá trị runtime qua `env`, không thông qua nội suy chuỗi +- [ ] Không có secret hoặc giá trị dự phòng được hardcode +- [ ] Thông tin xác thực upstream công khai được nhúng qua `resolvePublicCred()` (xem [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), tuyệt đối không dùng giá trị literal +- [ ] Các phản hồi lỗi được xử lý qua `buildErrorBody()` / `sanitizeErrorMessage()` — không đưa stack trace thô vào nội dung phản hồi (xem [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Các lệnh shell (`exec` / `spawn`) truyền giá trị tại thời điểm chạy qua `env`, không dùng phép nội suy chuỗi - [ ] Tất cả đầu vào đều được xác thực bằng schema Zod -- [ ] Đã thêm **fragment** changelog vào `changelog.d/{features|fixes|maintenance}/-.md` cho các thay đổi ảnh hưởng đến người dùng (xem [`changelog.d/README.md`](./changelog.d/README.md)) — **không** chỉnh sửa trực tiếp `CHANGELOG.md`; các fragment được tổng hợp khi phát hành và không bao giờ xung đột giữa các PR +- [ ] Đã thêm **fragment** changelog vào `changelog.d/{features|fixes|maintenance}/-.md` đối với các thay đổi ảnh hưởng đến người dùng (xem [`changelog.d/README.md`](./changelog.d/README.md)) — **không** chỉnh sửa trực tiếp `CHANGELOG.md`; các fragment được tổng hợp khi phát hành và không bao giờ gây xung đột giữa các PR - [ ] Đã cập nhật tài liệu (nếu áp dụng) -- [ ] Không tạo cảnh báo CodeQL / Secret-Scanning mới, hoặc mỗi cảnh báo đã được loại bỏ kèm lý do kỹ thuật có tham chiếu đến tài liệu `docs/security/` liên quan -- [ ] Các route tạo tiến trình con (`/api/mcp/`, `/api/cli-tools/runtime/`) được phân loại là `isLocalOnlyPath()` trong `src/server/authz/routeGuard.ts` — xem [Quy tắc bắt buộc #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Không có trailer `Co-Authored-By` trong thông điệp commit — các commit phải chỉ hiển thị danh tính Git của chủ sở hữu repository (Quy tắc bắt buộc #16) +- [ ] Không phát sinh cảnh báo CodeQL / Secret-Scanning mới, hoặc mỗi cảnh báo đều đã được loại bỏ kèm giải thích kỹ thuật có tham chiếu đến tài liệu liên quan trong `docs/security/` +- [ ] Các route khởi chạy tiến trình con (`/api/mcp/`, `/api/cli-tools/runtime/`) được phân loại là `isLocalOnlyPath()` trong `src/server/authz/routeGuard.ts` — xem [Quy tắc bắt buộc #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] Không có trailer `Co-authored-by` của AI/bot trong thông điệp commit (Quy tắc bắt buộc #16) — các cộng tác viên là con người có công việc được tái sử dụng phải được ghi nhận bằng trailer `Co-authored-by: Name ` tiêu chuẩn --- diff --git a/docs/i18n/vi/docs/architecture/QUALITY_GATES.md b/docs/i18n/vi/docs/architecture/QUALITY_GATES.md index 6c5052ee3e4..04de89f1a8a 100644 --- a/docs/i18n/vi/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/vi/docs/architecture/QUALITY_GATES.md @@ -20,209 +20,211 @@ tái triển khai không phụ thuộc công cụ của cùng hệ thống này, ### Tiếp nhận ứng viên Mỗi workflow CI và Quality Gates đều đưa ra một phán quyết ổn định: `Gate / CI` và -`Gate / Quality`. Chính sách tiếp nhận được quản lý theo phiên bản của chúng liệt kê mọi job -thượng nguồn là bắt buộc hoặc mang tính tư vấn. Một job bắt buộc có áp dụng phải thành công: -các kết quả bị thiếu, bị hủy, bị bỏ qua, đang chờ xử lý và không xác định không thể thiết lập PASS. Một -phân loại hợp lệ chỉ dành cho tài liệu hoặc chỉ dành cho danh mục có thể khiến một lane mã không áp dụng; -PR nháp không phải là ứng viên được chấp nhận. Nhãn `hotfix` không miễn trừ yêu cầu bằng chứng. - -Cả hai workflow đều bao phủ PR và các lần push lên nhánh main/release, kích hoạt thủ công và +`Gate / Quality`. Chính sách tiếp nhận có phiên bản của chúng liệt kê mọi job thượng nguồn +là bắt buộc hoặc mang tính tư vấn. Một job bắt buộc có áp dụng phải thành công: các kết quả +bị thiếu, bị hủy, bị bỏ qua, đang chờ xử lý và không xác định không thể xác lập PASS. Một +phân loại hợp lệ chỉ dành cho tài liệu hoặc chỉ dành cho danh mục có thể khiến một lane mã +không áp dụng; PR nháp không phải là ứng viên được chấp nhận. Nhãn `hotfix` không miễn trừ +yêu cầu về bằng chứng. + +Cả hai workflow đều bao phủ PR và các lần push đến nhánh main/release, kích hoạt thủ công và sự kiện merge-group. Push, dispatch và merge-group chạy toàn bộ lựa chọn. Các fork -và merge group sử dụng runner được lưu trữ cho những job vốn chọn runner -tự lưu trữ; phải xác minh có đủ năng lực runner được lưu trữ trước khi triển khai. +và merge group sử dụng runner được lưu trữ cho những job vốn chọn runner tự lưu trữ; +phải xác minh có đủ dung lượng runner được lưu trữ trước khi triển khai. Mỗi biên nhận JSON xác định SHA đã checkout, lần chạy workflow và lần thử. -CLI từ chối trường hợp SHA của checkout/sự kiện không khớp. Các kiểm thử workflow ràng buộc tư cách thành viên trong chính sách -với danh sách `needs` của job phán quyết để một lane mới hoặc bị xóa không thể âm thầm biến mất. -Các biên nhận chỉ bao phủ chính workflow của chúng, không bao gồm việc phát hành, triển khai hoặc hoạt động nội bộ -của một trình quét tư vấn hiện có. Kích hoạt cả hai tên kiểm tra trong quy tắc nhánh là một -thay đổi quản trị riêng biệt; việc thêm các job này tự nó không bảo vệ nhánh. +CLI từ chối khi SHA của checkout/sự kiện không khớp. Các kiểm thử workflow ràng buộc tư cách thành viên trong chính sách +với danh sách `needs` của job phán quyết, để một lane mới hoặc bị loại bỏ không thể âm thầm biến mất. +Các biên nhận bao phủ chính workflow tương ứng, không bao gồm việc xuất bản, triển khai hoặc phần nội bộ +của một trình quét tư vấn hiện có. Việc kích hoạt cả hai tên kiểm tra trong quy tắc nhánh là một +thay đổi quản trị riêng biệt; việc thêm các job này tự nó không bảo vệ một nhánh. ### Danh mục quét tĩnh -Danh mục npm-alias được quản lý theo phiên bản và tư cách thành viên quét tĩnh nằm trong +Danh mục npm-alias có phiên bản và tư cách thành viên quét tĩnh nằm trong `config/quality/gate-manifest.json`. Chạy `npm run check:gate-manifest` để xác thực -tên script và lệnh chính xác đối chiếu với `package.json`; các mục thêm, xóa và -sai lệch lệnh sẽ khiến cả hook cục bộ lẫn các job phân loại thay đổi trong CI thất bại. -Một alias không phải là job workflow, phiên bản matrix hoặc ca kiểm thử: không được -trình bày các số lượng này như thể có thể hoán đổi cho nhau. +tên script và lệnh chính xác dựa trên `package.json`; việc thêm, xóa và +sai lệch lệnh sẽ làm thất bại cả hook cục bộ lẫn các job phân loại thay đổi trong CI. +Một alias không phải là job workflow, thực thể ma trận hoặc ca kiểm thử: không được +trình bày các số lượng này như thể chúng có thể hoán đổi cho nhau. Sử dụng `npm run quality:scan -- --list` hoặc `npm run quality:scan:fast -- --list` để kiểm tra các alias đã chọn mà không thực thi chúng. Runner gọi -điểm vào npm, do đó môi trường runtime của nó (bao gồm Bun ở nơi được cấu hình) được giữ nguyên. -Manifest ghi lại các alias bên ngoài những hồ sơ này là được gọi riêng biệt, và +điểm vào npm, nên môi trường runtime của nó (bao gồm Bun tại nơi được cấu hình) được giữ nguyên. +Manifest ghi lại các alias nằm ngoài những hồ sơ này là được gọi riêng biệt, và các lệnh bảo trì bị cấm trong hồ sơ quét chỉ đọc. -Các hồ sơ này chỉ bao phủ quá trình quét tĩnh. Chúng không chứng nhận kiểm thử sản phẩm, -độ bao phủ, đóng gói, kiểm tra bên ngoài hoặc toàn bộ tiêu chí chấp nhận phát hành của ứng viên. -Quy trình tiếp nhận workflow sử dụng `config/quality/admission-policy.json` được liên kết và -`scripts/quality/admission-verdict.mjs`. Các hồ sơ release-observer vẫn độc lập; -hãy kiểm tra riêng các mục kiểm tra và biên nhận áp dụng của chúng. Danh mục -diễn giải bên dưới là tài liệu tham khảo, không phải bằng chứng rằng một gate đã thực sự chạy. +Các hồ sơ này chỉ bao phủ quét tĩnh. Chúng không chứng nhận kiểm thử sản phẩm, +độ bao phủ, đóng gói, kiểm tra bên ngoài hoặc việc chấp nhận phát hành đầy đủ của ứng viên. +Việc tiếp nhận trong workflow sử dụng `config/quality/admission-policy.json` được liên kết và +`scripts/quality/admission-verdict.mjs`. Các hồ sơ release-observer vẫn tách biệt; +hãy kiểm tra độc lập các phép kiểm tra và biên nhận áp dụng cho chúng. Danh mục +mô tả bên dưới là tài liệu tham khảo, không phải bằng chứng rằng một gate thực sự đã chạy. -Các script nằm trong `scripts/check/` (gate chính sách) và `scripts/quality/` (bộ máy ratchet). -Nguồn thông tin chính xác của CI là `.github/workflows/ci.yml`. +Các script nằm trong `scripts/check/` (gate chính sách) và `scripts/quality/` (công cụ ratchet). +Nguồn chân lý của CI là `.github/workflows/ci.yml`. ### Đường dẫn nhanh cho PR phát hành (`quality.yml`) -`.github/workflows/quality.yml` bổ sung cho CI trên các PR main/release, các lần push lên -nhánh được bảo vệ, dispatch và merge group. Các PR sử dụng kiểm tra nhanh được lọc theo đường dẫn. Bản build trùng lặp -bị vô hiệu hóa vĩnh viễn đã được loại bỏ; các bước kiểm tra build/package/boot thực sự vẫn nằm trong CI. +`.github/workflows/quality.yml` bổ trợ CI trên các PR main/release, các lần push đến nhánh +được bảo vệ, dispatch và merge group. PR sử dụng các phép kiểm tra nhanh được lọc theo đường dẫn. +Bản build trùng lặp bị vô hiệu hóa vĩnh viễn đã được loại bỏ; các phép kiểm tra build/package/boot thực sự vẫn nằm trong CI. -| Job | Phạm vi | Chặn | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `Docs Gates (fast-path)` | PR tài liệu/mã; tham chiếu tài liệu API và toàn bộ tài liệu | Có | -| `Fast Quality Gates` | PR mã; kiểm tra tĩnh, kiểm tra kiểu, kiểm tra kiểu dashboard, kiểm thử đơn vị bị ảnh hưởng | Có | -| `Forgotten sibling tests` | PR mã; lần theo các module đã thay đổi đến consumer tĩnh và kiểm thử sibling ứng viên; các đường dẫn barrel và dynamic-import được báo cáo dưới dạng chẩn đoán tư vấn, kèm các ngoại lệ trong allowlist được tham chiếu | **Tư vấn** | -| `Vitest (fast-path)` | PR mã; bộ kiểm thử vitest nhanh | Có | -| `Unit Tests fast-path` | PR mã; bộ kiểm thử đơn vị gồm 4 shard | Có | -| `No new ESLint warnings` | PR mã; cơ chế bảo vệ lint có nhận biết suppression | Có, bao gồm fork | -| `Merge integrity (changelog + generated skills)` | PR không phải bản nháp; đồng bộ changelog và skill được tạo | Có, bao gồm fork | +| Job | Phạm vi | Chặn | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `Docs Gates (fast-path)` | PR tài liệu/mã; tham chiếu tài liệu API và toàn bộ tài liệu | Có | +| `Fast Quality Gates` | PR mã; kiểm tra tĩnh, kiểm tra kiểu, kiểm tra kiểu dashboard, kiểm thử đơn vị bị ảnh hưởng | Có | +| `Forgotten sibling tests` | PR mã; các mô-đun đã thay đổi được truy vết tới consumer tĩnh và kiểm thử sibling ứng viên; các đường dẫn barrel và dynamic-import được báo cáo dưới dạng chẩn đoán tư vấn, với các ngoại lệ allowlist được tham chiếu | **Tư vấn** | +| `Vitest (fast-path)` | PR mã; bộ vitest nhanh | Có | +| `Unit Tests fast-path` | PR mã; bộ kiểm thử đơn vị 4 shard | Có | +| `No new ESLint warnings` | PR mã; biện pháp bảo vệ lint có nhận biết suppression | Có, bao gồm fork | +| `Merge integrity (changelog + generated skills)` | PR không phải bản nháp; đồng bộ changelog và skill được tạo | Có, bao gồm fork | #### Báo cáo kiểm thử sibling bị bỏ quên `npm run check:forgotten-sibling-tests` tái sử dụng trình phân giải import phía sau bản đồ tác động kiểm thử. -Đối với mỗi module production đã thay đổi, lệnh này báo cáo các chuỗi xác định +Đối với mọi mô-đun production đã thay đổi, lệnh này báo cáo các chuỗi xác định `changed module/symbol -> static consumer -> candidate sibling test` khi kiểm thử ứng viên -không có trong phần diff của pull request. Bản tóm tắt Markdown và kết quả JSON được lưu giữ dưới dạng -artifact workflow `forgotten-sibling-tests` để hiệu chỉnh trước mọi đợt triển khai có tính chặn. - -Các hoạt động tái xuất qua barrel và import động chỉ là chẩn đoán phân giải; chúng không bao giờ tạo ra một phát hiện chặn. Các ngoại lệ đã được xem xét nằm trong -`config/quality/forgotten-sibling-allowlist.json`. Mỗi mục phải nêu tên test tiêu thụ và test ứng viên, -đưa ra lý do cụ thể và liên kết đến một issue hoặc pull request trên GitHub. Các mục không đúng định dạng sẽ bị từ chối -theo cơ chế đóng. Ngoại lệ không thể bỏ qua một test ứng viên đã bị xóa hoặc một diff thêm `.skip`/`.todo`; +không có trong diff của pull request. Bản tóm tắt Markdown và kết quả JSON được lưu giữ dưới dạng +artifact workflow `forgotten-sibling-tests` để hiệu chỉnh trước bất kỳ đợt triển khai chặn nào. + +Các tái xuất barrel và import động chỉ là chẩn đoán phân giải; chúng không bao giờ tạo ra một +phát hiện có tính chặn. Các ngoại lệ đã được xem xét nằm trong +`config/quality/forgotten-sibling-allowlist.json`. Mỗi mục phải nêu tên bài kiểm thử phía sử dụng và bài kiểm thử +ứng viên, đưa ra lý do cụ thể và liên kết đến một issue hoặc pull request trên GitHub. Các mục sai định dạng sẽ +bị từ chối theo nguyên tắc đóng. Ngoại lệ không thể bỏ qua một bài kiểm thử ứng viên đã bị xóa hoặc một diff thêm `.skip`/`.todo`; việc làm yếu assertion và các hình thức che giấu khác vẫn thuộc phạm vi của cổng chặn độc lập `check:test-masking`. -### Job: `lint` +### Công việc: `lint` Chạy trên mọi PR vào `main`. Chặn hợp nhất khi thất bại. -| Script (`npm run ...`) | Xác thực | Chặn | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:node-runtime` | Phiên bản Node.js nằm trong phạm vi được hỗ trợ | Có | -| `check:cycles` | Import vòng — tất cả module trong `src/` + `open-sse/` | Có | -| `check:route-validation:t06` | Schema Zod hiện diện trên tất cả route (chính sách Tier 6) | Có | -| `check:any-budget:t11` | Số lượng `@ts-expect-error // any` không vượt quá ngân sách (catraca Tier 11) | Có | -| `check:provider-consistency` | Mọi provider trong `providers.ts` đều có mục tương ứng trong `providerRegistry.ts` (và ngược lại, trong phạm vi allowlist) | Có | -| `check:model-lifecycle` | Ba bảng định tuyến được duy trì thủ công luôn nhất quán với ảnh chụp nhanh vòng đời đã được đưa vào kho mã nguồn (#11503): `FITNESS_TABLE` (`taskFitness.ts`) không chấm điểm bất kỳ id đã ngừng hoạt động nào mà `REGISTRY` có thể định tuyến; mọi đích của `BUILT_IN_ALIASES` đều có trong `REGISTRY` và không có trong ảnh chụp nhanh id đã ngừng hoạt động; mọi id đã ngừng hoạt động nhưng vẫn còn trong `REGISTRY` đều được chuyển tiếp hoặc được liệt kê trong `allowedRetiredInCatalog`; và không có nguồn hoặc đích nào của `DEFAULT_DEGRADATION_MAP` xuất hiện dưới dạng đã ngừng hoạt động trong ảnh chụp nhanh đó. Điều này không chứng minh rằng một mô hình hiện đang được cung cấp bởi upstream đang hoạt động. Ngoại tuyến — so sánh với `config/quality/model-lifecycle.json`, được làm mới thủ công bằng `npm run quality:refresh-model-lifecycle` (cần mạng; không được tích hợp vào CI). `allowedRetiredInCatalog` là một cơ chế siết giảm dần: chỉ thêm mục khi có issue theo dõi. | Có | -| `check:fetch-targets` | Mọi `fetch("/api/...")` trong `src/` phía client đều phân giải tới một `route.ts` thực sự | Có | -| `check:deps` | Tất cả các dependency có thể cài đặt bằng `npm install` trong mọi `package.json` của repo đều có trong `dependency-allowlist.json`; các package mới không được ghim phiên bản hoặc có dấu hiệu slopsquatting sẽ bị gắn cờ | Có | -| `audit:deps` | `npm audit` (thư mục gốc + electron) — không có cảnh báo mức cao/nghiêm trọng (trùng lặp với osv `check:vuln-ratchet`; xem Rationalization Backlog) | Có | -| `check:lockfile` | Tính toàn vẹn của `package-lock.json` — registry HTTPS, hàm băm toàn vẹn, không ghi đè host | Có | -| `check:licenses` | Danh sách cho phép giấy phép SPDX đối với các phần phụ thuộc dùng trong môi trường production | Có | -| `check:tracked-artifacts` | Không có artifact bản dựng / symlink `node_modules` đã được commit (cũng chạy trong pre-commit của husky; pre-push được chủ ý giữ nhẹ — #6716) | Có | -| `check:ai-attribution` | Không có trailer `Co-Authored-By` của AI/bot hoặc footer về việc tạo bằng AI trong các commit, tiêu đề hoặc nội dung PR — Quy tắc cứng #16 (trong vòng lặp cổng kiểm tra nhanh `quality.yml` cho PR→`release/**` — đọc payload sự kiện, không thực hiện gì ngoài PR — và một bước chỉ dành cho PR trong tác vụ lint của `ci.yml` đối với PR→`main`; đồng thời có hook `commit-msg` của husky; cho phép đồng tác giả là con người; #14436) | -| `check:vitest-exclusions` | Mỗi mục loại trừ Vitest đều nêu một issue theo dõi và xuất hiện trong `config/quality/vitest-exclusions.json` (#13204) | Có | -| `check:file-size` | Không có tệp nguồn nào vượt quá giới hạn theo phần mở rộng (cơ chế ratchet: các tệp lớn được cố định trong danh sách `frozen`) | Có | -| `check:error-helper` | Các phản hồi lỗi trong executor/handler sử dụng `buildErrorBody()` / `sanitizeErrorMessage()` (Quy tắc cứng #12) | Có | -| `check:migration-numbering` | Các tệp SQL migration được đánh số tuần tự, không có khoảng trống hoặc số trùng lặp | Có | -| `check:public-creds` | Không có giá trị OAuth `client_id`/`client_secret` dạng literal hoặc khóa Firebase Web bên ngoài `publicCreds.ts` (Quy tắc bắt buộc #11) | Có | -| `check:db-rules` | Không có SQL thô bên ngoài các mô-đun `src/lib/db/`; không import qua barrel từ `localDb.ts` (Quy tắc bắt buộc #2/#5) | Có | -| `check:known-symbols` | Các executor của provider, chiến lược định tuyến và trình chuyển đổi được đăng ký trong bảng điều phối tương ứng phải khớp với các tệp trên đĩa — không có symbol mồ côi hoặc chưa được khai báo | Có | -| `check:route-guard-membership` | Mọi route khởi tạo tiến trình con đều được phân loại bởi `isLocalOnlyPath()` (Quy tắc bắt buộc #15/#17) | Có | -| `check:test-discovery` | Mọi tệp `*.test.ts` / `*.spec.ts` trong repo đều được ít nhất một trình chạy kiểm thử thu thập (cơ chế ratchet: danh sách tệp mồ côi trong `test-discovery-baseline.json` chỉ có thể thu hẹp) | Có | -| `check:agent-skills-sync` | Các artifact agent-skills được tạo khớp với danh mục nguồn tương ứng (không có sai lệch) | -| `check:provider-asset-provenance` | Logo/asset của nhà cung cấp có mục xuất xứ được ghi lại | -| `lint:json` | Các file cấu hình JSON được phân tích cú pháp thành công và đáp ứng các quy tắc lint của repo | -| `typecheck:core` | Biên dịch TypeScript không có lỗi (chỉ có cảnh báo mang tính khuyến nghị) | Có | -| `typecheck:noimplicit:core` | `noImplicitAny` nghiêm ngặt — hướng tới tương lai; nhiều vị trí gọi đã tồn tại từ trước vẫn cần chú thích | **Khuyến nghị** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` được giới hạn trong `src/app/(dashboard)/**` (#7033) — danh sách cho phép gồm 27 file được tuyển chọn của `typecheck:core` không bao gồm bất kỳ TSX nào của dashboard, và `next build` cũng không bao giờ kiểm tra kiểu cho chúng (`next.config.mjs` đặt `ignoreBuildErrors: true`), vì vậy các lỗi hồi quy về định danh mồ côi tại đó (#6625/#6909) không được CI phát hiện. So sánh chênh lệch với đường cơ sở cố định về số lượng theo từng file/mã TS (`config/quality/dashboard-typecheck-baseline.json`, cùng mẫu thực thi đối với dữ liệu cũ như `check:known-symbols`) — chỉ các lỗi MỚI vượt quá số lượng trong đường cơ sở mới khiến cổng kiểm tra thất bại; điều chỉnh giảm bằng `--update` khi một lỗi tồn tại từ trước được sửa. | Có | +| Script (`npm run ...`) | Xác thực | Chặn | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | +| `check:node-runtime` | Phiên bản Node.js nằm trong phạm vi được hỗ trợ | Có | +| `check:cycles` | Các import vòng trong toàn bộ `src/` + `open-sse/` (dựa trên AST, phân giải `paths` của tsconfig). Chế độ thuần túy = tư vấn, liệt kê các chu trình. `check:cycles:ratchet` (chế độ CI chạy) sẽ chặn khi số lượng vượt quá ngưỡng `metrics.cycles` trong `quality-baseline.json` — hiện là 14, `direction: down`, vì vậy giá trị này chỉ có thể giảm (#15159 G-01/G-02) | Có (ratchet) | +| `check:route-validation:t06` | Các schema Zod hiện diện trên tất cả các route (chính sách Tier 6) | Có | +| `check:any-budget:t11` | Số lượng `@ts-expect-error // any` không vượt quá ngân sách (catraca Tier 11) | Có | +| `check:provider-consistency` | Mọi nhà cung cấp trong `providers.ts` đều có một mục tương ứng trong `providerRegistry.ts` (và ngược lại, trong phạm vi danh sách cho phép) | Có | +| `check:model-lifecycle` | Ba bảng định tuyến được duy trì thủ công luôn nhất quán với bản chụp vòng đời đã được đưa vào kho mã nguồn (#11503): `FITNESS_TABLE` (`taskFitness.ts`) không chấm điểm bất kỳ id đã ngừng hoạt động nào mà `REGISTRY` có thể định tuyến; mọi đích của `BUILT_IN_ALIASES` đều có trong `REGISTRY` và không có trong bản chụp id đã ngừng hoạt động; mọi id đã ngừng hoạt động vẫn còn trong `REGISTRY` đều được chuyển tiếp hoặc được liệt kê trong `allowedRetiredInCatalog`; và không có nguồn hoặc đích nào của `DEFAULT_DEGRADATION_MAP` xuất hiện dưới dạng đã ngừng hoạt động trong bản chụp đó. Điều này không chứng minh rằng một mô hình hiện đang được cung cấp bởi một hệ thống thượng nguồn đang hoạt động. Ngoại tuyến — so sánh với `config/quality/model-lifecycle.json`, được làm mới thủ công bằng `npm run quality:refresh-model-lifecycle` (cần mạng; không được tích hợp vào CI). `allowedRetiredInCatalog` là cơ chế siết chặt dần để giảm tồn đọng: chỉ thêm mục khi có vấn đề theo dõi tương ứng. | Có | +| `check:fetch-targets` | Mọi `fetch("/api/...")` trong `src/` phía máy khách đều phân giải tới một `route.ts` thực sự tồn tại | Có | +| `check:deps` | Tất cả các phần phụ thuộc có thể cài đặt bằng `npm install` trên mọi `package.json` trong kho mã nguồn đều có trong `dependency-allowlist.json`; các gói mới không được ghim phiên bản hoặc có dấu hiệu slopsquatting sẽ bị gắn cờ | Có | +| `audit:deps` | `npm audit` (thư mục gốc + electron) — không có cảnh báo mức cao/nghiêm trọng (trùng lặp với `check:vuln-ratchet` của osv; xem Danh sách tồn đọng cần hợp lý hóa) | Có | +| `check:lockfile` | Tính toàn vẹn của `package-lock.json` — registry https, hàm băm toàn vẹn, không ghi đè máy chủ | Có | +| `check:licenses` | Danh sách cho phép giấy phép SPDX đối với các phụ thuộc production | Có | +| `check:tracked-artifacts` | Không có artifact bản dựng / symlink `node_modules` được commit (cũng chạy trong husky pre-commit; pre-push được cố ý giữ nhẹ — #6716) | Có | +| `check:ai-attribution` | Không có trailer `Co-Authored-By` của AI/bot hoặc footer cho biết nội dung do AI tạo trong các commit, tiêu đề hoặc nội dung PR — Quy tắc cứng #16 (trong vòng lặp fast-gates của `quality.yml` cho PR→`release/**` — đọc payload sự kiện, không thực hiện gì ngoài PR — và một bước chỉ dành cho PR trong tác vụ lint của `ci.yml` đối với PR→`main`; cũng áp dụng trong hook husky `commit-msg`; cho phép đồng tác giả là con người; #14436) | +| `check:vitest-exclusions` | Mỗi mục loại trừ Vitest phải nêu một issue theo dõi và xuất hiện trong `config/quality/vitest-exclusions.json` (#13204) | Có | +| `check:file-size` | Không có tệp nguồn nào vượt quá giới hạn theo phần mở rộng (ratchet: các tệp lớn bị đóng băng trong danh sách `frozen`) | Có | +| `check:error-helper` | Phản hồi lỗi trong các executor/handler sử dụng `buildErrorBody()` / `sanitizeErrorMessage()` (Quy tắc cứng #12) | Có | +| `check:migration-numbering` | Các tệp SQL migration được đánh số tuần tự, không có khoảng trống hoặc số trùng lặp | Có | +| `check:public-creds` | Không có giá trị OAuth `client_id`/`client_secret` dạng literal hoặc khóa Firebase Web bên ngoài `publicCreds.ts` (Quy tắc bắt buộc #11) | Có | +| `check:db-rules` | Không có SQL thô bên ngoài các mô-đun `src/lib/db/`; không barrel-import từ `localDb.ts` (Quy tắc bắt buộc #2/#5) | Có | +| `check:known-symbols` | Các trình thực thi provider, chiến lược định tuyến và trình chuyển đổi được đăng ký trong bảng điều phối tương ứng phải khớp với các tệp trên đĩa — không có symbol mồ côi hoặc chưa được khai báo | Có | +| `check:route-guard-membership` | Mọi route tạo tiến trình con đều được phân loại bởi `isLocalOnlyPath()` (Quy tắc bắt buộc #15/#17) | Có | +| `check:test-discovery` | Mọi tệp `*.test.ts` / `*.spec.ts` trong repo đều được ít nhất một test runner thu thập (ratchet: danh sách tệp mồ côi trong `test-discovery-baseline.json` chỉ có thể thu hẹp) | Có | +| `check:agent-skills-sync` | Các artifact agent-skills được tạo khớp với catalog nguồn của chúng (không có sai lệch) | +| `check:provider-asset-provenance` | Logo/asset của nhà cung cấp có mục xuất xứ được ghi nhận | +| `lint:json` | Các tệp cấu hình JSON có thể được phân tích cú pháp và đáp ứng các quy tắc lint của repo | +| `typecheck:core` | Biên dịch TypeScript không có lỗi (chỉ có cảnh báo mang tính tư vấn) | Có | +| `typecheck:noimplicit:core` | `noImplicitAny` nghiêm ngặt — hướng đến tương lai; nhiều vị trí gọi có sẵn vẫn cần chú thích | **Tư vấn** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` giới hạn trong `src/app/(dashboard)/**` (#7033) — danh sách cho phép gồm 27 tệp được tuyển chọn của `typecheck:core` không bao gồm bất kỳ tệp TSX nào của dashboard, và `next build` cũng không bao giờ kiểm tra kiểu cho chúng (`next.config.mjs` đặt `ignoreBuildErrors: true`), vì vậy các lỗi hồi quy về định danh không tồn tại tại đó (#6625/#6909) không bị CI phát hiện. So sánh với đường cơ sở cố định về số lượng lỗi theo từng tệp/từng mã TS (`config/quality/dashboard-typecheck-baseline.json`, cùng mẫu thực thi đối với dữ liệu lỗi thời như `check:known-symbols`) — chỉ các lỗi MỚI vượt quá số lượng trong đường cơ sở mới khiến cổng kiểm tra thất bại; điều chỉnh giảm dần bằng `--update` khi một lỗi có sẵn được khắc phục. | Có | ### Job: `quality-gate` Chạy sau `test-coverage`. Chặn hợp nhất khi thất bại. -| Script | Xác thực | Chặn | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | -| `quality:collect` | Xuất `quality-metrics.json` (số lượng cảnh báo ESLint, độ bao phủ từ báo cáo phân đoạn đã hợp nhất) | Có (trước bước ratchet) | -| `quality:ratchet` | Mỗi chỉ số trong `quality-baseline.json` không bị suy giảm (cảnh báo ESLint ≤ đường cơ sở; độ bao phủ ≥ đường cơ sở) | Có | -| `check:duplication` | Mức độ trùng lặp mã (jscpd@4) không vượt quá đường cơ sở trong `quality-baseline.json` | Có | -| `check:complexity` | Độ phức tạp cyclomatic ở cấp độ tệp không vượt quá giới hạn (quy tắc `complexity` cốt lõi của ESLint + `max-lines-per-function`) | Có | -| `check:cognitive-complexity` | Ratchet độ phức tạp nhận thức (`eslint-plugin-sonarjs`) — lượt chạy ESLint riêng biệt; CI chạy cả hai và hợp nhất thành một bước `check:complexity-ratchets` duy nhất | Có | -| `check:dead-code` | Ratchet các export / tệp không được sử dụng (knip) không bị suy giảm so với đường cơ sở | Có | -| `check:compression-budget` | Ngân sách benchmark nén — ngưỡng tối thiểu về mức tiết kiệm token cho từng engine không được suy giảm | Có | -| `check:type-coverage` | Ratchet tỷ lệ phần trăm được định kiểu (`type-coverage`) không bị suy giảm; phần lớn bao hàm `typecheck:noimplicit:core` | Có | -| `check:codeql-ratchet` | Số lượng cảnh báo CodeQL đang mở không bị tăng (đọc qua `gh api`; bỏ qua an toàn khi không có token) — nhịp làm mới và kích hoạt thủ công: xem "CodeQL ratchet" bên dưới | Có | - -### Công việc: `quality-extended` - -Toàn bộ công việc mang tính tư vấn (`continue-on-error: true`). Các ratchet dựa trên npm được chạy +| Script | Xác thực | Chặn | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `quality:collect` | Xuất `quality-metrics.json` (số lượng cảnh báo ESLint, độ bao phủ từ báo cáo shard đã hợp nhất) | Có (thượng nguồn của ratchet) | +| `quality:ratchet` | Mỗi chỉ số trong `quality-baseline.json` không bị suy giảm (cảnh báo ESLint ≤ đường cơ sở; độ bao phủ ≥ đường cơ sở) | Có | +| `check:duplication` | Mức độ trùng lặp mã (jscpd@4) không vượt quá đường cơ sở trong `quality-baseline.json` | Có | +| `check:complexity` | Độ phức tạp cyclomatic ở cấp độ tệp không vượt quá giới hạn (quy tắc ESLint cốt lõi `complexity` + `max-lines-per-function`) | Có | +| `check:cognitive-complexity` | Ratchet độ phức tạp nhận thức (`eslint-plugin-sonarjs`) — lượt chạy ESLint riêng biệt; CI chạy cả hai và hợp nhất thành một bước `check:complexity-ratchets` duy nhất | Có | +| `check:dead-code` | Ratchet các tệp / export không được sử dụng (knip) không suy giảm so với đường cơ sở | Có | +| `check:compression-budget` | Ngân sách benchmark nén — mức sàn tiết kiệm token cho từng engine không được suy giảm | Có | +| `check:type-coverage` | Ratchet tỷ lệ phần trăm được định kiểu (`type-coverage`) không suy giảm; phần lớn bao hàm `typecheck:noimplicit:core` | Có | +| `check:codeql-ratchet` | Số lượng cảnh báo CodeQL đang mở không tăng (đọc qua `gh api`; bỏ qua an toàn khi không có token) — về chu kỳ làm mới và kích hoạt thủ công: xem "CodeQL ratchet" bên dưới | Có | + +### Job: `quality-extended` + +Toàn bộ job mang tính tư vấn (`continue-on-error: true`). Các ratchet dựa trên npm được chạy thực tế; các trình quét bên ngoài được cài đặt qua `gh release download` và tự bỏ qua (exit 0) -khi vẫn chưa có tệp nhị phân. - -| Script | Xác thực | Chặn | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -| `check:circular-deps` | Không có phụ thuộc vòng (dpdm) | **Tư vấn** | -| `check:bundle-size` | Kích thước bundle không vượt quá giới hạn | **Tư vấn** | -| `check:secrets` | Quét bí mật (gitleaks) — bỏ qua nếu không có tệp nhị phân | **Tư vấn** | -| `check:vuln-ratchet` | Các lỗ hổng phụ thuộc (osv-scanner) không bị tăng — bỏ qua nếu không có tệp nhị phân | **Tư vấn** | -| `check:workflows` | Kiểm tra workflow (actionlint + zizmor); trình quét bị thiếu/hỏng, báo cáo không hợp lệ hoặc thiếu đường cơ sở ratchet sẽ thất bại với trạng thái INCOMPLETE. Các phát hiện hợp lệ tuân theo chính sách nghiêm ngặt/tư vấn/ratchet đã chọn | Bắt buộc thực thi; ratchet zizmor chặn trong CI | -| `check:openapi-breaking` | Các thay đổi phá vỡ hợp đồng API công khai (`openapi.yaml`) so với nhánh cơ sở (oasdiff) — xuất `openapiBreaking=N`; bỏ qua nếu không có oasdiff hoặc không thể phân giải đặc tả cơ sở | **Tư vấn** | - -### Công việc: `docs-sync-strict` - -Chạy trên mọi PR tới `main`. Chặn hợp nhất nếu thất bại. - -| Script | Xác thực | Chặn | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| `check:docs-all` | Cổng tổng hợp chạy tuần tự 6 cổng con bên dưới | Có | -| ↳ `check:docs-sync` | Tính nhất quán về phiên bản giữa CHANGELOG / OpenAPI / llm.txt | Có | -| ↳ `check:docs-counts` | Các số liệu trong nội dung (số lượng nhà cung cấp, số lượng migration, v.v.) nằm trong khoảng ratchet của số liệu thực tế | Có | -| ↳ `check:env-doc-sync` | Mọi biến môi trường trong `.env.example` đều được ghi lại trong một bảng tài liệu và ngược lại | Có | -| ↳ `check:deprecated-versions` | Không có chuỗi phiên bản đã ngừng hỗ trợ trong tài liệu | Có | -| ↳ `check:doc-links` | Các liên kết markdown nội bộ trong tài liệu phân giải thành tệp có thật (dạng `[text]`/`(path)`) | Có | -| ↳ `check:fabricated-docs` | Các route, biến môi trường, lệnh CLI, tên hook và đường dẫn tệp được đề cập trong tài liệu phải tồn tại trong codebase. Cổng cứng qua `--strict`; lỗi mềm nếu không có cờ. | Có (qua `--strict` trong CI) | -| `check:cli-i18n` | Các chuỗi lệnh CLI có mặt trong tất cả các tệp locale i18n | Có | -| `check:openapi-coverage` | Đặc tả OpenAPI bao phủ ít nhất mức sàn được ratchet của các route thực tế | Có | -| `check:openapi-security-tiers` | Các chú thích cấp độ bảo mật trong `openapi.yaml` nhất quán với các phân loại trong `routeGuard.ts` | **Khuyến nghị** | -| `check:openapi-routes` | Mọi đường dẫn trong `openapi.yaml` phân giải thành một `route.ts` có thật (chống bịa đặt) | Có | -| `check:docs-symbols` | Mọi tham chiếu `/api/...` trong `docs/**/*.md` phân giải thành một `route.ts` có thật (chống bịa đặt) | Có | -| `i18n translation drift` | Các khóa chưa được dịch trong tệp locale i18n — chỉ cảnh báo | **Khuyến nghị** | - -### Tác vụ: `i18n-ui-coverage` - -| Script | Xác thực | Chặn | -| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `check-ui-keys-coverage` (nội tuyến) | Độ bao phủ khóa i18n của UI là ≥ 65% | Có | -| `check-ui-value-drift` (nội tuyến) | Một **giá trị** tiếng Anh được viết lại không để sót bản dịch cũ nào | Có | -| `check-new-key-coverage` (nội tuyến) | Một khóa tiếng Anh **mới** được dịch trong mọi locale — marker `__MISSING__:` sẽ bị từ chối | Có | -| `check-translation-ratio` | Tỷ lệ bản dịch thực tế theo từng locale (các mục giống hệt tiếng Anh / placeholder / bị thiếu ngoài allowlist) không được vượt quá `config/quality/i18n-translation-baseline.json` + biên dư | **Khuyến nghị** | - -Yêu cầu `fetch-depth: 0` — cổng value-drift so sánh khác biệt của `en.json` với merge base. +khi vẫn không có binary. + +| Script | Xác thực | Chặn | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `check:circular-deps` | Không có phụ thuộc vòng (dpdm) | **Tư vấn** | +| `check:bundle-size` | Kích thước bundle không vượt quá giới hạn | **Tư vấn** | +| `check:secrets` | Quét bí mật (gitleaks) — bỏ qua nếu không có binary | **Tư vấn** | +| `check:vuln-ratchet` | Các lỗ hổng phụ thuộc (osv-scanner) không tăng — bỏ qua nếu không có binary | **Tư vấn** | +| `check:workflows` | Lint workflow (actionlint + zizmor); trình quét bị thiếu/hỏng, báo cáo không hợp lệ hoặc thiếu đường cơ sở ratchet sẽ thất bại với trạng thái INCOMPLETE. Các phát hiện hợp lệ tuân theo chính sách nghiêm ngặt/tư vấn/ratchet đã chọn | Bắt buộc thực thi; ratchet zizmor chặn trong CI | +| `check:openapi-breaking` | Các thay đổi gây phá vỡ hợp đồng API công khai (`openapi.yaml`) so với nhánh cơ sở (oasdiff) — xuất `openapiBreaking=N`; bỏ qua nếu không có oasdiff hoặc không thể phân giải đặc tả cơ sở | **Tư vấn** | + +### Job: `docs-sync-strict` + +Chạy trên mọi PR vào `main`. Chặn hợp nhất khi thất bại. + +| Script | Xác thực | Chặn | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `check:docs-all` | Cổng meta chạy tuần tự 6 cổng con bên dưới | Có | +| ↳ `check:docs-sync` | Tính nhất quán về phiên bản giữa CHANGELOG / OpenAPI / llm.txt | Có | +| ↳ `check:docs-counts` | Các số liệu trong nội dung (số lượng nhà cung cấp, số lượng migration, v.v.) nằm trong cửa sổ ratchet của số liệu thực tế | Có | +| ↳ `check:env-doc-sync` | Mọi biến môi trường trong `.env.example` đều được ghi lại trong một bảng tài liệu và ngược lại | Có | +| ↳ `check:deprecated-versions` | Không có chuỗi phiên bản đã ngừng hỗ trợ trong tài liệu | Có | +| ↳ `check:doc-links` | Các liên kết markdown nội bộ trong tài liệu phân giải tới tệp thực (`[text]`/`(path)` form) | Có | +| ↳ `check:fabricated-docs` | Các route, biến môi trường, lệnh CLI, tên hook và đường dẫn tệp được viện dẫn trong tài liệu phải tồn tại trong codebase. Cổng cứng qua `--strict`; thất bại mềm khi không có cờ. | Có (qua `--strict` trong CI) | +| `check:cli-i18n` | Các chuỗi lệnh CLI hiện diện trong tất cả các tệp locale i18n | Có | +| `check:openapi-coverage` | Đặc tả OpenAPI bao phủ ít nhất ngưỡng sàn được ratchet của các route thực tế | Có | +| `check:openapi-security-tiers` | Các chú thích cấp độ bảo mật trong `openapi.yaml` nhất quán với các phân loại trong `routeGuard.ts` | **Khuyến nghị** | +| `check:openapi-routes` | Mọi path trong `openapi.yaml` phân giải tới một `route.ts` thực (chống bịa đặt) | Có | +| `check:docs-symbols` | Mọi tham chiếu `/api/...` trong `docs/**/*.md` phân giải tới một `route.ts` thực (chống bịa đặt) | Có | +| `i18n translation drift` | Các key chưa được dịch trong tệp locale i18n — chỉ cảnh báo | **Khuyến nghị** | + +### Job: `i18n-ui-coverage` + +| Script | Xác thực | Chặn | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `check-ui-keys-coverage` (inline) | Độ bao phủ key i18n của UI là ≥ 65% | Có | +| `check-ui-value-drift` (inline) | Một **value** tiếng Anh được viết lại không để lại bản dịch lỗi thời nào | Có | +| `check-new-key-coverage` (inline) | Một key tiếng Anh **mới** được dịch trong mọi locale — marker `__MISSING__:` sẽ bị từ chối | Có | +| `check-translation-ratio` | Tỷ lệ bản dịch thực tế theo từng locale (các leaf giống tiếng Anh / placeholder / bị thiếu nằm ngoài allowlist) không được vượt quá `config/quality/i18n-translation-baseline.json` + slack | **Khuyến nghị** | + +Cần `fetch-depth: 0` — cổng value-drift so sánh khác biệt của `en.json` với merge base. #### `check-ui-value-drift` — cổng phát hiện bản dịch lỗi thời -Phát hiện một dạng hồi quy i18n mà các cổng khác không thể nhận biết về mặt cấu trúc: một giá trị tiếng Anh -được viết lại nhưng các bản dịch bắt nguồn từ phiên bản tiếng Anh _trước đó_ vẫn còn nguyên, khiến -người dùng không dùng tiếng Anh tiếp tục đọc nội dung có vẻ chắc chắn nhưng giờ đã sai. +Phát hiện một dạng hồi quy i18n mà các cổng khác về mặt cấu trúc không thể nhận ra: một value tiếng Anh +được viết lại nhưng các bản dịch bắt nguồn từ tiếng Anh _trước đó_ vẫn còn nguyên, khiến +người dùng không sử dụng tiếng Anh tiếp tục đọc nội dung có vẻ đầy chắc chắn nhưng nay đã sai. -Lỗi này thực sự đã được phát hành. `oauthModal.googleOAuthWarning` được viết lại khi trình hỗ trợ đăng nhập -Antigravity được bổ sung (#5203); **39 trong số 43 locale** vẫn giữ nội dung yêu cầu người vận hành "sao chép -toàn bộ URL và dán vào bên dưới" — một quy trình không thể hoàn tất đối với nhà cung cấp đó. Lỗi này +Điều này đã thực sự được phát hành. `oauthModal.googleOAuthWarning` đã được viết lại khi trình trợ giúp đăng nhập +Antigravity được đưa vào (#5203); **39 trong số 43 locale** vẫn giữ nội dung yêu cầu người vận hành "sao chép +URL đầy đủ và dán vào bên dưới" — một luồng không thể hoàn tất đối với nhà cung cấp đó. Vấn đề này không được phát hiện cho đến #8463 vì: -- `sync-ui-keys` chỉ điền bổ sung các khóa **không tồn tại**, không bao giờ cập nhật các khóa **lỗi thời**; -- `check-ui-keys-coverage` đếm _sự hiện diện_ của khóa, nên một bản dịch lỗi thời vẫn được tính là đã bao phủ; +- `sync-ui-keys` chỉ điền bù các key **không tồn tại**, không bao giờ xử lý các key **lỗi thời**; +- `check-ui-keys-coverage` đếm _sự hiện diện_ của key, vì vậy một bản dịch lỗi thời vẫn được tính là đã bao phủ; - `check-translation-drift` theo dõi các bản sao tài liệu `docs/i18n//**.md` — - nó không bao giờ đọc `src/i18n/messages/*.json`. Bị chặn trong tác vụ `docs-sync-strict` kể từ lần - đồng bộ lại 2026-09: chỉnh sửa tài liệu cốt lõi → `npm run i18n:run -- --files=` (theo từng phần, chi phí thấp). + nó không bao giờ đọc `src/i18n/messages/*.json`. Có tính chặn trong job `docs-sync-strict` kể từ lần + đồng bộ lại 2026-09: chỉnh sửa tài liệu cốt lõi → `npm run i18n:run -- --files=` (theo từng phần, ít tốn kém). **Nhận biết diff, không dựa trên baseline.** Cơ chế này so sánh `en.json` tại merge base với -working tree; với mỗi khóa có giá trị tiếng Anh đã thay đổi, mọi locale vẫn giữ bản dịch -chưa được cập nhật đều bị xem là lỗi thời. Điều này có chủ đích **đóng băng khoản nợ tồn đọng** — diff +working tree; với mỗi key có giá trị tiếng Anh thay đổi, bất kỳ locale nào vẫn giữ bản +dịch chưa được cập nhật đều bị coi là lỗi thời. Điều này chủ ý **đóng băng khoản nợ tồn đọng** — một diff không thể cho biết một bản dịch lâu đời bắt nguồn từ phiên bản tiếng Anh cũ nào, vì vậy cổng kiểm tra -chỉ đánh giá những gì thay đổi hiện tại tác động đến. Phương án thay thế (baseline hash theo từng khóa) sẽ tạo ra -một tệp sinh tự động khoảng 600 KB, lớn gấp 3 lần baseline lớn nhất hiện có và thay đổi trong mọi PR i18n. +chỉ đánh giá những gì thay đổi hiện tại tác động đến. Phương án thay thế (baseline hash theo từng key) sẽ cần +một file được tạo có dung lượng ~600 KB, lớn gấp 3 lần baseline lớn nhất hiện có và thay đổi liên tục trong mỗi PR i18n. Có hai cách để đáp ứng yêu cầu: 1. cập nhật các bản dịch bị ảnh hưởng, hoặc -2. đặt chúng thành `__MISSING__:` — khi đó runtime sẽ cung cấp bản tiếng Anh đã sửa - (`src/i18n/request.ts::deepMergeFallback`, #7258) và đưa khóa vào hàng đợi dịch. +2. đặt chúng thành `__MISSING__:` — khi đó runtime sẽ cung cấp nội dung tiếng Anh đã sửa + (`src/i18n/request.ts::deepMergeFallback`, #7258) và key sẽ được đưa vào hàng đợi dịch thuật. -Nếu **ý nghĩa** của chuỗi thay đổi, nên ưu tiên **đổi tên khóa**: khóa mới không thể kế thừa -bản dịch lỗi thời. Đây là mẫu mà #8463 đã sử dụng. +Nếu **ý nghĩa** của chuỗi đã thay đổi, hãy ưu tiên **đổi tên key**: một key mới không thể kế thừa +bản dịch lỗi thời. Đây là mẫu được sử dụng trong #8463. ```bash npm run i18n:check-value-drift # nghiêm ngặt (chế độ CI chạy) @@ -230,48 +232,48 @@ npm run i18n:check-value-drift:warn # chỉ báo cáo BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Thoát với mã 0 cùng `SKIP reason=base-unresolved` khi không thể đọc catalog cơ sở (shallow -clone không có base ref), tương tự `check-openapi-breaking`. +Thoát với mã 0 kèm `SKIP reason=base-unresolved` khi không thể đọc catalog cơ sở (bản sao nông +không có ref cơ sở), tương tự `check-openapi-breaking`. ### Job: `i18n` -Ma trận xác thực i18n đầy đủ (mỗi locale một job). Toàn bộ job chỉ mang tính khuyến nghị. +Ma trận xác thực i18n đầy đủ (một job cho mỗi locale). Toàn bộ job mang tính tham khảo. -| Script | Nội dung xác thực | Khả năng chặn | -| ------------------------------- | ------------------------------------------ | ------------------------------------------------------------ | -| `validate_translation.py quick` | Mức độ hoàn chỉnh của bản dịch theo locale | **Khuyến nghị** (`continue-on-error: true` trên toàn bộ job) | +| Script | Xác thực | Chặn | +| ------------------------------- | ------------------------------------------ | ---------------------------------------------------------- | +| `validate_translation.py quick` | Mức độ hoàn chỉnh của bản dịch theo locale | **Tham khảo** (`continue-on-error: true` trên toàn bộ job) | ### Job: `pr-test-policy` -Chỉ chạy trên pull request. +Chỉ chạy trên các pull request. -| Script | Nội dung xác thực | Khả năng chặn | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `check:pr-test-policy` | Các PR thay đổi mã production trong `src/`, `open-sse/`, `electron/` hoặc `bin/` phải thêm hoặc cập nhật test (Quy tắc cứng #8) | Có | -| `check:test-masking` | Các tệp test đã thay đổi không làm giảm tổng số assert ròng hoặc thêm các mệnh đề hiển nhiên `assert.ok(true)` | Có | -| `check:pr-evidence` | Nội dung PR trích dẫn bằng chứng test/VPS cho thay đổi (cơ giới hóa Quy tắc cứng #18 bằng cách grep văn bản PR — mong manh, xem Backlog) | Có | +| Script | Xác thực | Chặn | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---- | +| `check:pr-test-policy` | Các PR thay đổi mã production trong `src/`, `open-sse/`, `electron/` hoặc `bin/` phải bao gồm hoặc cập nhật test (Quy tắc cứng #8) | Có | +| `check:test-masking` | Các file test đã thay đổi không làm giảm tổng số assert ròng hoặc thêm các mệnh đề hiển nhiên `assert.ok(true)` | Có | +| `check:pr-evidence` | Nội dung PR trích dẫn bằng chứng test/VPS cho thay đổi (cơ giới hóa Quy tắc cứng #18 bằng cách grep văn bản PR — dễ lỗi, xem Backlog) | Có | ### Job: `test-vitest` -Chạy sau `build`. Chặn merge khi thất bại. +Chạy sau `build`. Chặn merge nếu thất bại. -| Suite | Nội dung xác thực | Khả năng chặn | -| ---------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 công cụ), autoCombo, cache — trình chạy vitest | Có | -| `test:vitest:ui` | Test thành phần UI — trình chạy vitest | **Chặn** — các lỗi tồn tại từ trước được loại trừ rõ ràng trong `vitest.config.ts`; lỗi mới khiến job thất bại | +| Bộ test | Xác thực | Chặn | +| ---------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | +| `test:vitest` | MCP server (110 công cụ), autoCombo, cache — trình chạy vitest | Có | +| `test:vitest:ui` | Test thành phần UI — trình chạy vitest | **Chặn** — các lỗi tồn tại từ trước được loại trừ rõ ràng trong `vitest.config.ts`; lỗi mới sẽ làm job thất bại | -### Workflow chạy hằng đêm (theo lịch, mang tính khuyến nghị) +### Workflow hằng đêm (theo lịch, mang tính tham khảo) -Các workflow này chạy theo lịch cron (và `workflow_dispatch`), không bao giờ chạy trên PR. Tất cả đều mang tính khuyến nghị. +Các workflow này chạy theo lịch cron (và `workflow_dispatch`), không bao giờ chạy trên PR. Tất cả đều mang tính tham khảo. -| Workflow | Nội dung xác thực | Khả năng chặn | -| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `nightly-property` | Test thuộc tính fast-check với seed ngẫu nhiên + số lượt chạy cao | **Khuyến nghị** | -| `nightly-resilience` | Cổng kiểm tra tăng trưởng heap, chèn lỗi hỗn loạn, tải/ngâm tải bằng k6 | **Khuyến nghị** | -| `nightly-llm-security` | Bộ bảo vệ chống prompt injection của promptfoo (chế độ chặn) + các phép dò garak (bỏ qua khi không có provider secret) | **Khuyến nghị** | -| `nightly-schemathesis` | Fuzzing hợp đồng OpenAPI (schemathesis) trên OmniRoute đang chạy bằng `docs/openapi.yaml` — phát hiện vi phạm đặc tả / lỗi 500 chưa được xử lý (Giai đoạn 8 B.4) | **Khuyến nghị** | -| `nightly-mutation` | Điểm mutation testing của Stryker trên luồng unit test nhanh — các mutant sống sót cho thấy assert yếu | **Khuyến nghị** | -| `nightly-compat` | Ma trận tương thích Node engine trên các dải `engines.node` được hỗ trợ | **Khuyến nghị** | +| Workflow | Xác thực | Chặn | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `nightly-property` | Các property test bằng fast-check với seed ngẫu nhiên + số lượt chạy cao | **Tham khảo** | +| `nightly-resilience` | Cổng kiểm tra tăng trưởng heap, chèn lỗi hỗn loạn, kiểm thử tải/soak bằng k6 | **Tham khảo** | +| `nightly-llm-security` | Cơ chế bảo vệ khỏi injection bằng promptfoo (chế độ chặn) + các probe garak (bỏ qua khi không có secret của provider) | **Tham khảo** | +| `nightly-schemathesis` | Fuzzing hợp đồng OpenAPI (schemathesis) trên một OmniRoute đang chạy bằng `docs/openapi.yaml` — phát hiện vi phạm đặc tả / lỗi 500 chưa được xử lý (Giai đoạn 8 B.4) | **Tham khảo** | +| `nightly-mutation` | Điểm kiểm thử đột biến Stryker trên lane unit test nhanh — các mutant sống sót cho thấy assert yếu | **Tham khảo** | +| `nightly-compat` | Ma trận tương thích Node engine trên các dải `engines.node` được hỗ trợ | **Tham khảo** | --- @@ -534,43 +536,43 @@ lỗi kết nối và không bao giờ làm gián đoạn các phiên làm việ --- -## Danh sách tồn đọng cần hợp lý hóa (đánh giá ROI — Giai đoạn 9 Đợt 3) +## Danh sách tồn đọng cần hợp lý hóa (rà soát ROI — Giai đoạn 9 Đợt 3) -Danh mục này đã được đối soát với `ci.yml` vào ngày 2026-06-17 (phiên bản trước đã bỏ sót +Danh mục này đã được đối chiếu với `ci.yml` vào ngày 2026-06-17 (phiên bản trước đã bỏ sót `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Một đợt đánh giá ROI đối với tập hợp đã đối soát -đã xác định các ứng viên hợp lý hóa sau đây. **Các thao tác hợp nhất là những thay đổi CI -mang tính cơ học; việc chuyển đổi/loại bỏ là các quyết định chính sách dành cho người vận hành.** Chưa có nội dung nào -dưới đây được áp dụng. +`check:codeql-ratchet`, `check:pr-evidence`). Quá trình rà soát ROI của tập hợp đã đối chiếu +xác định các ứng viên hợp lý hóa sau đây. **Các mục hợp nhất là thay đổi CI mang tính +cơ học; việc chuyển đổi/loại bỏ là các quyết định chính sách dành cho người vận hành.** Chưa có +nội dung nào dưới đây được áp dụng. -**Ngoài ra chưa được ghi lại ở trên** (mang tính khuyến nghị, tín hiệu thấp): job `docs-lint` -(markdownlint + Vale, toàn bộ job dùng `continue-on-error`) và các workflow quét độc lập +**Ngoài ra còn chưa được ghi lại ở trên** (mang tính tư vấn, tín hiệu thấp): tác vụ `docs-lint` +(markdownlint + Vale, toàn bộ tác vụ dùng `continue-on-error`) và các quy trình quét độc lập `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` có trong -`quality-baseline.json` nhưng chưa được nối với một cơ chế chốt chặn tăng dần có tính bắt buộc trong `ci.yml` — chỉ số này +`quality-baseline.json` nhưng chưa được kết nối với một cơ chế chốt chặn tăng dần có tính ngăn chặn trong `ci.yml` — chỉ số này hiện đang bị bỏ rời. -### Hợp nhất / loại bỏ trùng lặp (cơ học, rủi ro thấp hơn) +### Hợp nhất / khử trùng lặp (mang tính cơ học, rủi ro thấp hơn) -Mỗi ứng viên đã được xác thực dựa trên trạng thái cổng kiểm soát thực tế vào ngày 2026-06-17 (tin tưởng nhưng vẫn xác minh); -một số thao tác hợp nhất “hiển nhiên” hóa ra lại che giấu nợ kỹ thuật và **không** thể thay thế trực tiếp một cách an toàn. +Mỗi ứng viên đã được xác thực dựa trên trạng thái cổng kiểm soát thực tế vào ngày 2026-06-17 (tin tưởng nhưng phải xác minh); +một số phép hợp nhất “hiển nhiên” hóa ra lại che giấu nợ kỹ thuật và **không** thể thay thế trực tiếp một cách an toàn. -- **`check:docs-sync` chạy hai lần** — chạy độc lập trong job `lint` và chạy lại bên trong `check:docs-all` (`docs-sync-strict`) cũng như hook pre-commit của husky. ✅ **HOÀN TẤT** — đã xóa lần gọi độc lập trong `lint`. -- **Quét CVE** — ❌ **KHÔNG thể hợp nhất trực tiếp một cách an toàn.** `audit:deps` thất bại cứng khi có bất kỳ CVE mức high/critical nào; `check:vuln-ratchet` (osv) chỉ thất bại khi có _sự suy giảm_ so với đường cơ sở (hiện là 1 MODERATE). Ngữ nghĩa khác nhau — việc loại bỏ `audit:deps` sẽ làm mất cổng kiểm soát tuyệt đối cho mức high/critical. Giữ cả hai. -- **Phát hiện chu trình** — ❌ **KHÔNG thể hợp nhất trực tiếp một cách an toàn.** `check:circular-deps` (dpdm) báo cáo **91 chu trình** (đó là lý do nó chỉ mang tính khuyến nghị); không thể chuyển nó thành bắt buộc nếu chưa xử lý các chu trình này trước, và phạm vi của nó rộng hơn `check:cycles` đã được tuyển chọn và đang ở trạng thái đạt. Giữ `check:cycles` ở trạng thái bắt buộc; việc xử lý 91 chu trình dpdm là một hạng mục tồn đọng riêng. -- **Độ phức tạp** — ✅ **HOÀN TẤT** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): một lượt duyệt ESLint, đếm theo ruleId để các đường cơ sở cyclomatic+max-lines và cognitive vẫn độc lập; các lệnh riêng lẻ `check:complexity` / `check:cognitive-complexity` vẫn được giữ lại để cập nhật cục bộ bằng `--update`. -- **Chống ảo giác `/api`** — ✅ **HOÀN TẤT** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): một lần kiểm kê FS đối với `src/app/api`, openapi-routes + docs-symbols vẫn báo cáo độc lập; các lệnh riêng lẻ vẫn được giữ lại để chạy cục bộ. -- **`check:node-runtime` chạy trong 11 job** — ⚠️ **ROI thấp.** Mỗi job dùng một runner riêng và phép kiểm tra mất <1 giây; tổng thời gian tiết kiệm khoảng 10 giây, đổi lại là mất một lớp bảo vệ rẻ trên từng job. Không đáng để gây xáo trộn. -- **`typecheck:noimplicit:core` trong CI lint** — ✅ **đã xóa khỏi job lint** (trước đây mang tính khuyến nghị với `continue-on-error`); bề mặt kiểu bắt buộc là `typecheck:core` + `check:type-coverage`. Script cục bộ vẫn được giữ lại. +- **`check:docs-sync` chạy hai lần** — chạy độc lập trong tác vụ `lint` và chạy lại bên trong `check:docs-all` (`docs-sync-strict`) cũng như hook pre-commit của husky. ✅ **ĐÃ XONG** — đã loại bỏ lệnh gọi độc lập trong `lint`. +- **Quét CVE** — ❌ **KHÔNG thể hợp nhất một cách an toàn.** `audit:deps` dừng với lỗi cứng khi có bất kỳ CVE mức cao/nghiêm trọng nào; `check:vuln-ratchet` (osv) chỉ thất bại khi có _hồi quy_ so với đường cơ sở (hiện có 1 MODERATE). Ngữ nghĩa khác nhau — loại bỏ `audit:deps` sẽ làm mất cổng kiểm soát tuyệt đối cho mức cao/nghiêm trọng. Giữ cả hai. +- **Phát hiện chu trình** — ✅ **ĐÃ XONG** (#15159 G-01/G-02). Nội dung cũ ở đây gọi `check:cycles` là cổng kiểm soát “xanh, được tuyển chọn” và biện minh cho việc duy trì trạng thái ngăn chặn của nó vì `check:circular-deps` (dpdm) báo cáo 91 chu trình. Trạng thái xanh đó là **xanh giả**: `check:cycles` quét 5 thư mục con (450 tệp), chỉ khớp với `import|export … from` tĩnh và loại bỏ mọi specifier `@/` cùng `@omniroute/open-sse/`, nên không thể thấy các chu trình dynamic-import + alias chiếm ưu thế trong kho mã. Đã khắc phục: cổng kiểm soát giờ duyệt `src` + `open-sse` (5023 tệp), thu thập các specifier từ TypeScript AST (do đó `import("…")` được tính còn `typeof import("…")` ở vị trí kiểu thì không) và phân giải `paths` của tsconfig. Nó tìm thấy **14** chu trình, không phải 0. Vì 14 chu trình tồn tại từ trước không thể được khắc phục trong một PR cổng kiểm soát, `check:cycles` hiện là một **cơ chế chốt chặn tăng dần** (`--ratchet`, mức trần `metrics.cycles.value = 14` trong `quality-baseline.json`, `direction: down`) — nó chặn mọi _hồi quy_ và số lượng chỉ có thể giảm. CI chạy `npm run check:cycles:ratchet`. Việc giảm dần được thực hiện cùng với **A-01**. `check:circular-deps` (dpdm) vẫn mang tính tư vấn như một ý kiến thứ hai có phạm vi rộng hơn. +- **Độ phức tạp** — ✅ **ĐÃ XONG** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): một lượt duyệt ESLint, đếm theo ruleId để các đường cơ sở cyclomatic+max-lines và cognitive vẫn độc lập; từng lệnh `check:complexity` / `check:cognitive-complexity` vẫn được giữ lại cho `--update` cục bộ. +- **Chống ảo giác `/api`** — ✅ **ĐÃ XONG** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): một lần kiểm kê hệ thống tệp của `src/app/api`, openapi-routes + docs-symbols vẫn báo cáo độc lập; các lệnh riêng lẻ vẫn được giữ lại để chạy cục bộ. +- **`check:node-runtime` chạy trong 11 tác vụ** — ⚠️ **ROI thấp.** Mỗi tác vụ dùng một runner riêng và phép kiểm tra mất <1 giây; tổng mức tiết kiệm khoảng 10 giây, nhưng đổi lại sẽ mất một cơ chế bảo vệ rẻ tiền cho từng tác vụ. Không đáng để gây xáo trộn. +- **`typecheck:noimplicit:core` trong lint CI** — ✅ **đã loại bỏ khỏi tác vụ lint** (trước đây mang tính tư vấn với `continue-on-error`); bề mặt kiểu có tính ngăn chặn là `typecheck:core` + `check:type-coverage`. Script cục bộ vẫn được giữ lại. ### Chuyển đổi / quyết định (chính sách của người vận hành) -- `check:openapi-security-tiers` (khuyến nghị) — ❌ **KHÔNG thể chuyển sang bắt buộc một cách an toàn ngay lập tức.** Nó thoát với mã 0 nhưng cảnh báo rằng một số route `traffic-inspector` thuộc `LOCAL_ONLY_API_PREFIXES` thiếu chú thích `x-loopback-only: true`. Muốn thực thi bắt buộc thì trước tiên phải thêm các chú thích đó vào `openapi.yaml`. -- `typecheck:noimplicit:core` (khuyến nghị) — phần lớn đã được cơ chế chốt chặn tăng dần bắt buộc `check:type-coverage` bao phủ. Chuyển thành cơ chế chốt chặn tăng dần hoặc loại bỏ lượt chạy `tsc` thứ hai bị dư thừa. -- `test:vitest:ui` (hiện **bắt buộc**) — các lỗi có từ trước được loại trừ rõ ràng trong `vitest.config.ts` bằng các chú thích theo dõi `// #8618`; các lỗi mới sẽ làm job thất bại. -- `check:secrets` (gitleaks, cơ chế chốt chặn tăng dần bắt buộc được cố định ở 3 kết quả dương tính giả đã ghi nhận) — đưa 3 trường hợp này vào allowlist để đạt 0, hoặc hạ xuống mức khuyến nghị. Trùng lặp với tính năng quét bí mật gốc của GitHub + `check:public-creds`. -- `check:pr-evidence` (bắt buộc, dùng grep trên văn bản trong phần thân PR) — rủi ro dương tính giả cao; việc loại bỏ sẽ làm suy yếu khả năng thực thi Quy tắc Cứng #18, vì vậy đây thực sự là một quyết định chính sách. -- `semgrep` (workflow độc lập mang tính khuyến nghị) — trùng lặp với CodeQL đối với các nhóm OWASP; nối đường cơ sở của nó với một cơ chế chốt chặn tăng dần hoặc loại bỏ. +- `check:openapi-security-tiers` (mang tính tư vấn) — ❌ **KHÔNG thể chuyển đổi trực tiếp một cách an toàn.** Nó thoát với mã 0 nhưng cảnh báo rằng một số route `traffic-inspector` bên dưới `LOCAL_ONLY_API_PREFIXES` thiếu chú thích `x-loopback-only: true`. Muốn thực thi bắt buộc, trước tiên phải thêm các chú thích đó vào `openapi.yaml`. +- `typecheck:noimplicit:core` (mang tính tư vấn) — phần lớn đã được cơ chế chốt chặn tăng dần có tính ngăn chặn `check:type-coverage` bao hàm. Chuyển thành cơ chế chốt chặn tăng dần hoặc loại bỏ lượt chạy `tsc` thứ hai bị trùng lặp. +- `test:vitest:ui` (hiện **có tính ngăn chặn**) — các lỗi tồn tại từ trước được loại trừ rõ ràng trong `vitest.config.ts` bằng các chú thích theo dõi `// #8618`; lỗi mới sẽ khiến tác vụ thất bại. +- `check:secrets` (gitleaks, cơ chế chốt chặn tăng dần có tính ngăn chặn được cố định ở 3 trường hợp dương tính giả đã được ghi lại) — đưa 3 trường hợp này vào danh sách cho phép để đạt 0, hoặc hạ xuống thành tư vấn. Trùng lặp với tính năng quét bí mật gốc của GitHub + `check:public-creds`. +- `check:pr-evidence` (có tính ngăn chặn, dùng grep trên văn bản phần thân PR) — nguy cơ dương tính giả cao; nếu loại bỏ sẽ làm suy yếu việc thực thi Quy tắc Cứng #18, vì vậy đây thực sự là một quyết định chính sách. +- `semgrep` (quy trình độc lập mang tính tư vấn) — trùng lặp với CodeQL đối với các nhóm OWASP; kết nối đường cơ sở của nó với một cơ chế chốt chặn tăng dần hoặc loại bỏ. --- diff --git a/docs/i18n/yo/CONTRIBUTING.md b/docs/i18n/yo/CONTRIBUTING.md index 365960e574f..72ef872d420 100644 --- a/docs/i18n/yo/CONTRIBUTING.md +++ b/docs/i18n/yo/CONTRIBUTING.md @@ -400,19 +400,19 @@ Kọ àwọn unit test sínú `tests/unit/` tí yóò kéré tán bo: ## Àtòjọ Àyẹ̀wò Pull Request - [ ] Àwọn ìdánwò kọjá (`npm test`) -- [ ] Linting kọjá (`npm run lint`) -- [ ] Build ṣàṣeyọrí (`npm run build`) -- [ ] A fi àwọn type TypeScript kún un fún àwọn function àti interface gbogbogbò tuntun -- [ ] Kò sí secret tàbí iye fallback tí a kọ sínú kóòdù -- [ ] A fi àwọn ẹ̀rí ìdánimọ̀ upstream gbogbogbò sínú kóòdù nípasẹ̀ `resolvePublicCred()` (wo [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), kì í ṣe gẹ́gẹ́ bí literal láé -- [ ] Àwọn ìdáhùn àṣìṣe gba inú `buildErrorBody()` / `sanitizeErrorMessage()` kọjá — kò sí stack trace aláìṣe-àtúnṣe nínú body ìdáhùn (wo [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Àwọn àṣẹ shell (`exec` / `spawn`) ń fi àwọn iye runtime ránṣẹ́ nípasẹ̀ `env`, kì í ṣe nípasẹ̀ string interpolation -- [ ] A fìdí gbogbo àwọn input múlẹ̀ pẹ̀lú schema Zod -- [ ] A fi **fragment** changelog kún abẹ́ `changelog.d/{features|fixes|maintenance}/-.md` fún àwọn àyípadà tí olumulo yóò rí (wo [`changelog.d/README.md`](./changelog.d/README.md)) — **má ṣe** ṣàtúnṣe `CHANGELOG.md` ní tààrà; a máa ń kó àwọn fragment jọ nígbà release, wọn kì í sì í fa ìtakora láàárín àwọn PR láé -- [ ] A ṣe àfikún sí àkọsílẹ̀ ìtọ́sọ́nà (bí ó bá yẹ) -- [ ] Kò sí ìkìlọ̀ CodeQL / Secret-Scanning tuntun tí a ṣí, tàbí a kọ ọ̀kọ̀ọ̀kan sílẹ̀ pẹ̀lú ìdáláre ìmọ̀-ẹ̀rọ tó tọ́ka sí doc tó bá a mu nínú `docs/security/` +- [ ] Àyẹ̀wò lint kọjá (`npm run lint`) +- [ ] Ìkọ́lé ṣàṣeyọrí (`npm run build`) +- [ ] Àwọn irú TypeScript ti jẹ́ àfikún fún àwọn iṣẹ́ àti àwọn interface tuntun tí ó wà fún gbogbo ènìyàn +- [ ] Kò sí àwọn àṣírí tàbí iye àfẹ́yìntì tí a kọ sínú kóòdù ní tààrà +- [ ] Àwọn ẹ̀rí ìdánimọ̀ upstream tí ó wà fún gbogbo ènìyàn ni a fi sínú rẹ̀ nípasẹ̀ `resolvePublicCred()` (wo [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), kì í ṣe gẹ́gẹ́ bí literal láé +- [ ] Àwọn ìdáhùn àṣìṣe ń gba `buildErrorBody()` / `sanitizeErrorMessage()` kọjá — kò sí àwọn stack trace aise nínú ara ìdáhùn (wo [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Àwọn àṣẹ shell (`exec` / `spawn`) ń fi àwọn iye runtime ránṣẹ́ nípasẹ̀ `env`, kì í ṣe nípasẹ̀ ìṣọ̀kan ọ̀rọ̀ +- [ ] Gbogbo àwọn input ni a fìdí rẹ̀ múlẹ̀ pẹ̀lú àwọn schema Zod +- [ ] A ti ṣàfikún **àjákù** changelog sí abẹ́ `changelog.d/{features|fixes|maintenance}/-.md` fún àwọn ìyípadà tí àwọn aṣàmúlò lè rí (wo [`changelog.d/README.md`](./changelog.d/README.md)) — **má ṣe** ṣàtúnṣe `CHANGELOG.md` ní tààrà; a máa ń kó àwọn àjákù jọ ní àkókò ìtújáde, wọn kì í sì í forí gbárí láàárín àwọn PR +- [ ] A ti mú àwọn ìwé àlàyé dọ́gba (bí ó bá yẹ) +- [ ] Kò sí ìkìlọ̀ CodeQL / Secret-Scanning tuntun tí a ṣí, tàbí a ti kọ ọ̀kọ̀ọ̀kan sílẹ̀ pẹ̀lú ìdáláre ìmọ̀ ẹ̀rọ tí ó tọ́ka sí ìwé `docs/security/` tó yẹ - [ ] Àwọn route tí ń dá child process sílẹ̀ (`/api/mcp/`, `/api/cli-tools/runtime/`) ni a pín sí `isLocalOnlyPath()` nínú `src/server/authz/routeGuard.ts` — wo [Òfin Líle #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] Kò sí trailer `Co-Authored-By` nínú àwọn ìfiránṣẹ́ commit — àwọn commit gbọ́dọ̀ farahàn lábẹ́ Git identity olówó repository nìkan (Òfin Líle #16) +- [ ] Kò sí trailer `Co-authored-by` ti AI/bot nínú àwọn ọ̀rọ̀ commit (Òfin Líle #16) — àwọn alábàáṣiṣẹ́ ènìyàn tí a tún lo iṣẹ́ wọn ni a fún ní ìkànsí pẹ̀lú àwọn trailer boṣewa `Co-authored-by: Name ` --- diff --git a/docs/i18n/yo/docs/architecture/QUALITY_GATES.md b/docs/i18n/yo/docs/architecture/QUALITY_GATES.md index 9e140c4cdeb..ba51afb6329 100644 --- a/docs/i18n/yo/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/yo/docs/architecture/QUALITY_GATES.md @@ -15,264 +15,262 @@ tí kò sinmi lé irinṣẹ́ kan pàtó fún ètò kan náà, wo --- -## Àkójọ àwọn gẹ́ẹ̀tì àti àwọn prófáìlì ìṣiṣẹ́ +## Àkójọ àwọn ẹnubodè àti àwọn prófáìlì ìṣiṣẹ́ -### Gbígba olùdíje wọlé +### Gbigba olùdíje -Àwọn ìṣàn iṣẹ́ CI àti Quality Gates kọ̀ọ̀kan ń ṣe ìdájọ́ tó dúró ṣinṣin jáde: `Gate / CI` àti -`Gate / Quality`. Ìlànà gbígba wọlé tí a fi ẹ̀yà ṣe rẹ̀ ṣe àtòjọ gbogbo iṣẹ́ orísun gẹ́gẹ́ bí ohun -tí a nílò tàbí ohun ìmọ̀ràn. Iṣẹ́ tí a nílò, tí ó sì kan ọ̀ràn náà, gbọ́dọ̀ ṣàṣeyọrí: àwọn èsì -tí ó sọnù, tí a fagilé, tí a fo kọjá, tí ó ṣì ń dúró àti tí a kò mọ̀ kò lè fi ìpinnu PASS múlẹ̀. Ìṣètò -docs-nìkan tàbí catalog-nìkan tó péye lè mú kí ọ̀nà kóòdù kan má ṣe kan ọ̀ràn náà; -PR àkọsílẹ̀ kì í ṣe olùdíje tí a gbà. Àmì `hotfix` kì í yọ ohun tí a nílò láti fi ẹ̀rí hàn kúrò. +Àwọn ìṣàn-iṣẹ́ CI àti Quality Gates kọ̀ọ̀kan ń ṣe àbájáde ìdájọ́ tó dúró ṣinṣin: `Gate / CI` àti +`Gate / Quality`. Ìlànà gbigba wọn tí a ní ẹ̀yà rẹ̀ ṣe àkójọ gbogbo iṣẹ́ ìpele-òkè +gẹ́gẹ́ bí èyí tí a nílò tàbí èyí tó jẹ́ ìmọ̀ràn. Iṣẹ́ tí a nílò, tí ó sì kàn, gbọ́dọ̀ ṣàṣeyọrí: +àbájáde tí kò sí, tí a fagilé, tí a fo, tí ó ṣì ń dúró tàbí tí a kò mọ̀ kò lè fi ìdánilójú PASS múlẹ̀. +Ìsọ̀rí docs-only tàbí catalog-only tó fẹsẹ̀ múlẹ̀ lè mú kí ọ̀nà kóòdù kan má ṣe kàn; +PR tó ṣì jẹ́ àkọsílẹ̀ kì í ṣe olùdíje tí a gbà. Àmì `hotfix` kò yọ ìbéèrè ẹ̀rí kúrò. -Àwọn ìṣàn iṣẹ́ méjèèjì bo àwọn PR àti ìfiránṣẹ́ sí àwọn ẹ̀ka main/release, ìpilẹ̀ṣẹ̀ ọwọ́ àti -àwọn ìṣẹ̀lẹ̀ merge-group. Push, dispatch àti merge-group máa ń lo gbogbo àṣàyàn náà. Forks -àti àwọn merge groups máa ń lo àwọn runner tí a gbàlejò fún àwọn iṣẹ́ tí ì bá yan àwọn runner -tí a gbàlejò fúnra ẹni; a gbọ́dọ̀ ṣàyẹ̀wò pé agbára ìgbàlejò tó pọ̀ tó wà kí a tó tú u jáde. +Àwọn ìṣàn-iṣẹ́ méjèèjì bo àwọn PR àti àwọn ìfìránṣẹ́ sí àwọn ẹ̀ka main/release, ìbẹ̀rẹ̀ afọwọ́ṣe àti +àwọn ìṣẹ̀lẹ̀ merge-group. Push, dispatch àti merge-group máa ń ṣiṣẹ́ gbogbo àṣàyàn náà. Àwọn fork +àti merge group máa ń lo àwọn runner tí a gbalejo fún àwọn iṣẹ́ tí yóò máa yan àwọn runner +tí a gbalejo fúnra wa ní ọ̀nà míì; a gbọ́dọ̀ ṣàyẹ̀wò pé agbára ìgbalejo tó tó wà ṣáájú ìmújáde. -Ìwé ẹ̀rí JSON kọ̀ọ̀kan ń tọ́ka SHA tí a checkout, ìṣiṣẹ́ ìṣàn iṣẹ́ àti ìgbìyànjú rẹ̀. -CLI máa kọ àìbáramu láàárín SHA checkout àti ti ìṣẹ̀lẹ̀. Àwọn àyẹ̀wò ìṣàn iṣẹ́ so jíjẹ́ ọmọ ẹgbẹ́ ìlànà -mọ́ àtòjọ `needs` ti iṣẹ́ ìdájọ́ náà, kí ọ̀nà tuntun tàbí èyí tí a yọ má bàa pòórá ní ìkọ̀kọ̀. -Àwọn ìwé ẹ̀rí náà bo ìṣàn iṣẹ́ tiwọn, kì í ṣe ìtẹ̀jáde, ìmúṣiṣẹ́, tàbí àwọn ìlànà inú -ẹ̀rọ àyẹ̀wò ìmọ̀ràn tó ti wà tẹ́lẹ̀. Mímú orúkọ àyẹ̀wò méjèèjì ṣiṣẹ́ nínú àwọn òfin ẹ̀ka jẹ́ -ìyípadà ìṣàkóso lọ́tọ̀; fífi àwọn iṣẹ́ wọ̀nyí kún un kò dáàbò bo ẹ̀ka kan fúnra rẹ̀. +Gbogbo ìwé-ẹ̀rí JSON ń ṣe ìdánimọ̀ SHA tí a checkout, ìṣiṣẹ́ ìṣàn-iṣẹ́ àti ìgbìyànjú. +CLI kọ ìyàtọ̀ láàárín SHA checkout àti SHA ìṣẹ̀lẹ̀. Àwọn ìdánwò ìṣàn-iṣẹ́ so ọmọ ẹgbẹ́ ìlànà +mọ́ àtòjọ `needs` ti iṣẹ́ ìdájọ́, kí ọ̀nà tuntun tàbí ọ̀nà tí a yọ má bàa lè pòórá láìsí ìkìlọ̀. +Àwọn ìwé-ẹ̀rí náà bo ìṣàn-iṣẹ́ tiwọn nìkan, kì í ṣe títẹ̀jáde, ìmúṣiṣẹ́, tàbí àwọn ìlànà inú +scanner ìmọ̀ràn tó ti wà. Mímú orúkọ check méjèèjì ṣiṣẹ́ nínú àwọn òfin ẹ̀ka jẹ́ +àtúnṣe ìṣàkóso ọ̀tọ̀; fífi àwọn iṣẹ́ wọ̀nyí kún un kò dáàbò bo ẹ̀ka kan fúnra rẹ̀. -### Àkójọ àyẹ̀wò aimi +### Àkójọ scan aláìyípadà -Àkójọ npm-alias tí a fi ẹ̀yà ṣe àti jíjẹ́ ọmọ ẹgbẹ́ àyẹ̀wò aimi wà nínú +Àkójọ npm-alias tí a ní ẹ̀yà rẹ̀ àti ọmọ ẹgbẹ́ static-scan wà nínú `config/quality/gate-manifest.json`. Ṣiṣe `npm run check:gate-manifest` láti fìdí -àwọn orúkọ script àti àwọn àṣẹ gangan múlẹ̀ ní ìfiwéra pẹ̀lú `package.json`; àfikún, ìyọkúrò àti -yíyí àṣẹ padà yóò mú kí hook agbègbè àti àwọn iṣẹ́ ìṣètò-irú-ìyípadà nínú CI kùnà. -Alias kì í ṣe iṣẹ́ ìṣàn iṣẹ́, matrix instance tàbí test case: a kò gbọ́dọ̀ fi iye àwọn wọ̀nyí -hàn bí ẹni pé wọ́n lè paarọ̀ ara wọn. +àwọn orúkọ script àti àwọn àṣẹ gangan múlẹ̀ ní ìbámu pẹ̀lú `package.json`; àwọn àfikún, ìyọkúrò àti +ìyípadà àṣẹ máa ń mú kí hook agbègbè àti àwọn iṣẹ́ ìsọ̀rí àyípadà nínú CI kùnà. +Alias kì í ṣe iṣẹ́ ìṣàn-iṣẹ́, àpẹẹrẹ matrix tàbí test case: a kò gbọ́dọ̀ gbé àwọn iye wọ̀nyí kalẹ̀ +bí ohun tí a lè fi rọ́pò ara wọn. Lo `npm run quality:scan -- --list` tàbí `npm run quality:scan:fast -- --list` -láti ṣàyẹ̀wò àwọn alias tí a yàn láì ṣiṣẹ́ wọn. Runner náà ń pe +láti ṣàyẹ̀wò àwọn alias tí a yàn láìṣe wọn. Runner náà pe npm entrypoint, nítorí náà runtime rẹ̀ (pẹ̀lú Bun níbi tí a ti ṣètò rẹ̀) ni a pa mọ́. -Manifest náà ṣàkọsílẹ̀ àwọn alias tí kò sí nínú àwọn prófáìlì wọ̀nyí gẹ́gẹ́ bí èyí tí a pè lọ́tọ̀, àti pé -a kò gba àwọn àṣẹ ìtọ́jú láàyè nínú àwọn prófáìlì àyẹ̀wò kíkà-nìkan. +Manifest náà ṣàkọsílẹ̀ àwọn alias tí kò sí nínú àwọn prófáìlì wọ̀nyí gẹ́gẹ́ bí èyí tí a pè lọ́tọ̀ọ̀tọ̀, àti pé +a kò gba àwọn àṣẹ ìtọju láàyè nínú àwọn prófáìlì scan kíkà-nìkan. -Àwọn prófáìlì wọ̀nyí bo àyẹ̀wò aimi nìkan. Wọn kò jẹ́rìí sí àwọn àyẹ̀wò ọjà, -coverage, packaging, àwọn àyẹ̀wò òde tàbí gbogbo ìtẹ́wọ́gbà ìtújáde olùdíje kan. -Gbígba wọlé nípasẹ̀ ìṣàn iṣẹ́ ń lo `config/quality/admission-policy.json` tí a so pọ̀ àti +Àwọn prófáìlì wọ̀nyí bo static scan nìkan. Wọn kì í jẹ́rìí àwọn ìdánwò ọjà, +coverage, packaging, àwọn check òde tàbí gbogbo ìfọwọ́sí ìtújáde olùdíje kan. +Gbigba ìṣàn-iṣẹ́ lo `config/quality/admission-policy.json` tí a sopọ̀ mọ́ àti `scripts/quality/admission-verdict.mjs`. Àwọn prófáìlì release-observer ṣì wà lọ́tọ̀; -ṣàyẹ̀wò àwọn àyẹ̀wò àti ìwé ẹ̀rí tí ó kan wọn lọ́tọ̀. Àkójọ àlàyé -tó wà nísàlẹ̀ jẹ́ ìtọ́kasí, kì í ṣe ẹ̀rí pé gẹ́ẹ̀tì kan ṣiṣẹ́ ní tòótọ́. +ṣàyẹ̀wò àwọn check àti ìwé-ẹ̀rí wọn tó kàn lọ́tọ̀ọ̀tọ̀. Àkójọ àlàyé +ní ìsàlẹ̀ jẹ́ ìtọ́kasí, kì í ṣe ẹ̀rí pé ẹnubodè kan ṣiṣẹ́ ní tòótọ́. -Àwọn script wà lábẹ́ `scripts/check/` (àwọn gẹ́ẹ̀tì ìlànà) àti `scripts/quality/` (ẹ̀rọ ratchet). +Àwọn script wà lábẹ́ `scripts/check/` (àwọn ẹnubodè ìlànà) àti `scripts/quality/` (ẹ́ńjìnnì ratchet). Orísun òtítọ́ CI ni `.github/workflows/ci.yml`. ### Ọ̀nà yíyára fún PR ìtújáde (`quality.yml`) -`.github/workflows/quality.yml` ń ṣe àfikún CI lórí àwọn PR main/release, àwọn -ìfiránṣẹ́ sí ẹ̀ka tí a dáàbò bo, dispatch àti merge groups. Àwọn PR máa ń lo àwọn àyẹ̀wò yíyára tí a fi path yàn. -A ti yọ duplicate build tí a pa títí láé kúrò; àwọn àyẹ̀wò build/package/boot gidi ṣì wà nínú CI. +`.github/workflows/quality.yml` ṣe àfikún CI lórí àwọn PR main/release, àwọn push sí ẹ̀ka tí a dáàbò bo, +dispatch àti merge group. Àwọn PR lo àwọn check yíyára tí a fi path ṣe àlẹ́mọ́. A yọ duplicate build +tí a ti pa títí láé kúrò; àwọn check build/package/boot gidi ṣì wà nínú CI. -| Iṣẹ́ | Ìwọ̀n | Dídènà | -| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `Docs Gates (fast-path)` | Àwọn PR docs/kóòdù; àwọn ìtọ́kasí docs API àti docs-all | Bẹ́ẹ̀ ni | -| `Fast Quality Gates` | Àwọn PR kóòdù; àwọn àyẹ̀wò aimi, typecheck, dashboard typecheck, àwọn unit test tí ìyípadà kan | Bẹ́ẹ̀ ni | -| `Forgotten sibling tests` | Àwọn PR kóòdù; a tọpa àwọn module tí a yí padà sí àwọn static consumer àti àwọn candidate sibling test; àwọn path barrel àti dynamic-import ni a máa ń jọ̀wọ́ gẹ́gẹ́ bí ìwádìí ìmọ̀ràn, pẹ̀lú àwọn àyọkúrò allowlist tí a tọ́ka sí | **Ìmọ̀ràn** | -| `Vitest (fast-path)` | Àwọn PR kóòdù; fast vitest suite | Bẹ́ẹ̀ ni | -| `Unit Tests fast-path` | Àwọn PR kóòdù; 4-shard unit suite | Bẹ́ẹ̀ ni | -| `No new ESLint warnings` | Àwọn PR kóòdù; suppressions-aware lint guard | Bẹ́ẹ̀ ni, pẹ̀lú forks | -| `Merge integrity (changelog + generated skills)` | Àwọn PR tí kì í ṣe àkọsílẹ̀; ìbámu changelog àti generated skill | Bẹ́ẹ̀ ni, pẹ̀lú forks | +| Iṣẹ́ | Ààlà | Dídènà | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `Docs Gates (fast-path)` | Àwọn PR docs/kóòdù; àwọn ìtọ́kasí API docs àti docs-all | Bẹ́ẹ̀ ni | +| `Fast Quality Gates` | Àwọn PR kóòdù; àwọn static check, typecheck, dashboard typecheck, àwọn unit test tí ó ní ipa | Bẹ́ẹ̀ ni | +| `Forgotten sibling tests` | Àwọn PR kóòdù; a tọpa àwọn module tí ó yí padà sí àwọn static consumer àti àwọn candidate sibling test; àwọn ipa ọ̀nà barrel àti dynamic-import ni a máa ń jọ̀wọ́ gẹ́gẹ́ bí àyẹ̀wò ìmọ̀ràn, pẹ̀lú àwọn àyọkà allowlist tí a tọ́ka sí | **Ìmọ̀ràn** | +| `Vitest (fast-path)` | Àwọn PR kóòdù; àkójọpọ̀ vitest yíyára | Bẹ́ẹ̀ ni | +| `Unit Tests fast-path` | Àwọn PR kóòdù; àkójọpọ̀ unit ológe mẹ́rin | Bẹ́ẹ̀ ni | +| `No new ESLint warnings` | Àwọn PR kóòdù; olùṣọ́ lint tó mọ̀ nípa suppression | Bẹ́ẹ̀ ni, pẹ̀lú àwọn fork | +| `Merge integrity (changelog + generated skills)` | Àwọn PR tí kì í ṣe àkọsílẹ̀; ìmúdójúìwọ̀n changelog àti generated skill | Bẹ́ẹ̀ ni, pẹ̀lú àwọn fork | #### Ìròyìn àwọn sibling test tí a gbàgbé -`npm run check:forgotten-sibling-tests` tún máa ń lo import resolver tó wà lẹ́yìn test-impact map. -Fún gbogbo production module tí a yí padà, ó máa ń jọ̀wọ́ àwọn ẹ̀wọ̀n -`changed module/symbol -> static consumer -> candidate sibling test` tó ṣeé tún ṣe lọ́nà kan náà nígbà tí candidate -test náà kò sí nínú diff pull-request. A pa àkótán Markdown àti èsì JSON mọ́ gẹ́gẹ́ bí -artifact ìṣàn iṣẹ́ `forgotten-sibling-tests` fún ìṣètò ìwọ̀n kí ìtújáde dídènà èyíkéyìí tó bẹ̀rẹ̀. +`npm run check:forgotten-sibling-tests` tún lo import resolver tó wà lẹ́yìn test-impact map. +Fún gbogbo production module tí ó yí padà, ó máa ń ròyìn àwọn ẹ̀wọ̀n +`changed module/symbol -> static consumer -> candidate sibling test` tí àbájáde wọn kò yí padà +nígbà tí candidate test náà kò bá sí nínú diff pull-request. A máa ń pa àkótán Markdown àti àbájáde JSON mọ́ gẹ́gẹ́ bí +artifact ìṣàn-iṣẹ́ `forgotten-sibling-tests` fún ìṣètò ìwọ̀n ṣáájú ìmújáde dídènà èyíkéyìí. -Àwọn àtún-gbejáde barrel àti àwọn ìgbéwọlé aláyípadà jẹ́ fún ìṣàwárí ìṣòro ìyànjú nìkan; wọn kì í dá -àbájáde ìdènà sílẹ̀ láé. Àwọn àfikún tí a ti ṣàyẹ̀wò wà nínú -`config/quality/forgotten-sibling-allowlist.json`. Gbogbo àkọsílẹ̀ gbọ́dọ̀ dárúkọ test olùlò àti test -olùdíje, sọ ìdí pàtó kan, kí ó sì tọ́ka sí issue tàbí pull request GitHub kan. Àwọn àkọsílẹ̀ tí ìṣètò wọn kò pé máa ń -kùnà ní ọ̀nà tí ó ní ààbò. Àwọn àfikún kò lè fi test olùdíje tí a ti pa rẹ́ tàbí diff kan tí ó ṣàfikún `.skip`/`.todo` pamọ́; -dídẹkun agbára assertion àti àwọn ọ̀nà ìbòjú mìíràn ṣì jẹ́ ojúṣe ẹnu-ọ̀nà -`check:test-masking` tí ń dí lọ́tọ̀. +Àwọn àtúndásílẹ̀ láti inú barrel àti àwọn dynamic imports jẹ́ fún àyẹ̀wò ìṣàwárí nìkan; wọn kì í dá +àbájáde tí ń díwọ̀ sílẹ̀ láéláé. Àwọn ìyọkúrò tí a ti ṣàyẹ̀wò wà nínú +`config/quality/forgotten-sibling-allowlist.json`. Gbogbo àkọsílẹ̀ gbọ́dọ̀ dárúkọ consumer àti candidate +test, ṣàlàyé ìdí pàtó, kí ó sì sopọ̀ mọ́ GitHub issue tàbí pull request. Àwọn àkọsílẹ̀ tí kò tọ́ máa ń +kọ̀ láìfàyè gba nǹkan. Àwọn ìyọkúrò kò lè fi candidate test tí a ti parẹ́ pamọ́ tàbí diff tí ó ṣàfikún `.skip`/`.todo`; +dídín agbára assertion kù àti àwọn ìbòjú mìíràn ṣì jẹ́ ojúṣe gate +`check:test-masking` tí ń díwọ̀ lọ́tọ̀. ### Iṣẹ́: `lint` -Ó máa ń ṣiṣẹ́ lórí gbogbo PR sí `main`. Ó máa ń dènà merge bí ó bá kùnà. - -| Script (`npm run ...`) | Ohun tí ó ń fìdí rẹ̀ múlẹ̀ | Ṣé ó ń dí merge? | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| `check:node-runtime` | Ẹ̀yà Node.js wà láàárín ìwọ̀n tí a ṣe àtìlẹ́yìn fún | Bẹ́ẹ̀ni | -| `check:cycles` | Àwọn ìgbéwọlé aláyíká — gbogbo àwọn module `src/` + `open-sse/` | Bẹ́ẹ̀ni | -| `check:route-validation:t06` | Àwọn schema Zod wà lórí gbogbo route (ìlànà Tier 6) | Bẹ́ẹ̀ni | -| `check:any-budget:t11` | Iye `@ts-expect-error // any` kò kọjá budget (catraca Tier 11) | Bẹ́ẹ̀ni | -| `check:provider-consistency` | Gbogbo olùpèsè inú `providers.ts` ní àkọsílẹ̀ tó bá a mu nínú `providerRegistry.ts` (àti ní ìdàkejì, láàárín allowlist) | Bẹ́ẹ̀ni | -| `check:model-lifecycle` | Àwọn tábìlì ìdarí mẹ́ta tí a ń tọ́jú lọ́wọ́ dúró ní ìbámu pẹ̀lú àwòrán ìgbésí-ayé tí a ti fi sínú ibi ìpamọ́ (#11503): `FITNESS_TABLE` (`taskFitness.ts`) kò fún id tí a ti dáwọ́ dúró, tí `REGISTRY` lè darí sí, ní àmì; gbogbo ibi-afẹ́ `BUILT_IN_ALIASES` wà nínú `REGISTRY`, wọn kò sì sí nínú àwòrán àwọn id tí a ti dáwọ́ dúró; gbogbo id tí a ti dáwọ́ dúró tí ó ṣì wà nínú `REGISTRY` ni a darí sí ibòmíràn tàbí tí a ṣe àkójọ rẹ̀ nínú `allowedRetiredInCatalog`; kò sì sí orísun tàbí ibi-afẹ́ `DEFAULT_DEGRADATION_MAP` kankan tó hàn gẹ́gẹ́ bí èyí tí a ti dáwọ́ dúró nínú àwòrán náà. Èyí kò fi ẹ̀rí múlẹ̀ pé upstream tó ń ṣiṣẹ́ ń pèsè model kan lọ́wọ́lọ́wọ́. Aisinipo — ó ń fi wé `config/quality/model-lifecycle.json`, tí a ń sọ di tuntun lọ́wọ́ pẹ̀lú `npm run quality:refresh-model-lifecycle` (nẹ́tíwọ́ọ̀kì; a kò so mọ́ CI). `allowedRetiredInCatalog` jẹ́ ratchet ìdínkù díẹ̀díẹ̀: fi àkọsílẹ̀ kan kún un nìkan tí issue ìtọ́pasẹ̀ bá wà. | Bẹ́ẹ̀ni | -| `check:fetch-targets` | Gbogbo `fetch("/api/...")` nínú `src/` ẹ̀gbẹ́ client ń yanjú sí `route.ts` gidi kan | Bẹ́ẹ̀ni | -| `check:deps` | Gbogbo deps tí a lè fi `npm install` sí láti inú gbogbo `package.json` inú repo wà nínú `dependency-allowlist.json`; a máa sàmì sí àwọn package tuntun tí a kò pin mọ́ version tàbí tí a slopsquat | Bẹ́ẹ̀ni | -| `audit:deps` | `npm audit` (root + electron) — kò sí ìkìlọ̀ ewu gíga/pàtàkì (ó fara pọ̀ mọ́ osv `check:vuln-ratchet`; wo Àkójọ Iṣẹ́ Ìṣètò Ìdáláre) | Bẹ́ẹ̀ni | -| `check:lockfile` | ìdúróṣinṣin `package-lock.json` — registry https, hash ìdúróṣinṣin, kò sí ìkọjá host | Bẹ́ẹ̀ni | -| `check:licenses` | Àtòjọ ìyọ̀ǹda ìwé-àṣẹ SPDX fún àwọn dependency production | Bẹ́ẹ̀ni | -| `check:tracked-artifacts` | Kò gbọdọ̀ sí àwọn artifact build / àwọn symlink `node_modules` tí a commit (ó tún ń ṣiṣẹ́ nínú husky pre-commit; a mọ̀ọ́mọ̀ jẹ́ kí pre-push fẹ́ẹ́rẹ́ — #6716) | Bẹ́ẹ̀ni | -| `check:ai-attribution` | Kò gbọdọ̀ sí trailer AI/bot `Co-Authored-By` tàbí footer ìṣẹ̀dá AI nínú àwọn commit PR, àkọlé tàbí body — Òfin Líle #16 (nínú loop fast-gates `quality.yml` fún PR→`release/**` — ó ń ka event payload, kò sì ṣe ohunkóhun níta àwọn PR — àti ìgbésẹ̀ PR-nìkan nínú lint `ci.yml` fún PR→`main`; pẹ̀lú hook husky `commit-msg`; a gba àwọn alábàáṣèkọ̀wé ènìyàn láàyè; #14436) | -| `check:vitest-exclusions` | Gbogbo exclusion Vitest gbọdọ̀ dárúkọ issue ìtọ́pasẹ̀ kan, kí ó sì wà nínú `config/quality/vitest-exclusions.json` (#13204) | Bẹ́ẹ̀ni | -| `check:file-size` | Kò sí fáìlì source kankan tí ó gbọdọ̀ kọjá òpin fún extension kọ̀ọ̀kan (ratchet: àwọn fáìlì ńlá tí a ti dì mọ́lẹ̀ nínú àtòjọ `frozen`) | Bẹ́ẹ̀ni | -| `check:error-helper` | Àwọn response error nínú executors/handlers máa ń lo `buildErrorBody()` / `sanitizeErrorMessage()` (Òfin Líle #12) | Bẹ́ẹ̀ni | -| `check:migration-numbering` | Àwọn fáìlì Migration SQL ní nọ́ńbà tó tẹ̀lé ara wọn, láìsí àlàfo tàbí nọ́ńbà àtúnṣe | Bẹ́ẹ̀ni | -| `check:public-creds` | Kò sí OAuth `client_id`/`client_secret` tàbí àwọn kọ́kọ́rọ́ Firebase Web tí a kọ ní tààrà níta `publicCreds.ts` (Òfin Líle #11) | Bẹ́ẹ̀ni | -| `check:db-rules` | Kò sí SQL àìṣe-láàárín níta àwọn module `src/lib/db/`; kò sí àwọn barrel-import láti `localDb.ts` (Àwọn Òfin Líle #2/#5) | Bẹ́ẹ̀ni | -| `check:known-symbols` | Àwọn executor provider, àwọn ìlànà routing, àti àwọn translator tí a forúkọsílẹ̀ sínú àwọn tábìlì dispatch wọn bá àwọn fáìlì tó wà lórí disiki mu — kò sí àwọn àmì tí kò ní olùtọ́jú tàbí tí a kò kéde | Bẹ́ẹ̀ni | -| `check:route-guard-membership` | Gbogbo route tó ń dá process ọmọ sílẹ̀ ni a pín sí ẹ̀ka nípasẹ̀ `isLocalOnlyPath()` (Àwọn Òfin Líle #15/#17) | Bẹ́ẹ̀ni | -| `check:test-discovery` | Gbogbo fáìlì `*.test.ts` / `*.spec.ts` inú repo ni ó kéré tán test runner kan ń kó jọ (ratchet: àkójọ orphan inú `test-discovery-baseline.json` lè dín kù nìkan) | Bẹ́ẹ̀ni | -| `check:agent-skills-sync` | Àwọn artifact agent-skills tí a ṣe jáde bá katalọ́ọ̀gù orísun wọn mu (kò sí ìyapa) | -| `check:provider-asset-provenance` | Àwọn àmì ilé-iṣẹ́/dúkìá olùpèsè ní àkọsílẹ̀ ìpilẹ̀ṣẹ̀ tí a ti ṣàkọsílẹ̀ | -| `lint:json` | Àwọn fáìlì àtúnṣe JSON ṣe parse, wọ́n sì tẹ̀lé àwọn òfin lint repo náà | -| `typecheck:core` | Ìṣàkójọpọ̀ TypeScript láìsí àṣìṣe (àwọn ìkìlọ̀ ìmọ̀ràn nìkan) | Bẹ́ẹ̀ ni | -| `typecheck:noimplicit:core` | `noImplicitAny` tó muna — fún ọjọ́ iwájú; ọ̀pọ̀ ibi ìpè tó ti wà tẹ́lẹ̀ ṣì nílò àwọn àlàyé irú | **Ìmọ̀ràn** (`continue-on-error: true`) | -| `check:dashboard-typecheck` | `tsc` tí a fi ààlà sí `src/app/(dashboard)/**` (#7033) — àtòjọ ìyọ̀ǹda fáìlì 27 tí a ti yan fún `typecheck:core` kò ní TSX dashboard kankan, àti pé `next build` kì í ṣe àyẹ̀wò irú rẹ̀ pẹ̀lú (`next.config.mjs` ṣètò `ignoreBuildErrors: true`), nítorí náà àwọn ìpadàsẹ́yìn ìdánimọ̀ aláìní-olùtọ́jú níbẹ̀ (#6625/#6909) kò hàn sí CI. Ó ń ṣe ìfiwéra pẹ̀lú ìpìlẹ̀ iye àṣìṣe tí a ti dì fún fáìlì kọ̀ọ̀kan/kóòdù TS kọ̀ọ̀kan (`config/quality/dashboard-typecheck-baseline.json`, àpẹẹrẹ ìfipámú ohun tí ó ti gbó kan náà bí `check:known-symbols`) — àwọn àṣìṣe TUNTUN tó kọjá iye ìpìlẹ̀ nìkan ni yóò mú kí ẹnubodè náà kùnà; dín ìpìlẹ̀ náà kù pẹ̀lú `--update` nígbà tí a bá tún àṣìṣe tó ti wà tẹ́lẹ̀ ṣe. | Bẹ́ẹ̀ ni | +Ó máa ń ṣiṣẹ́ lórí gbogbo PR sí `main`. Ó máa ń dí ìdàpọ̀ tí ó bá kùnà. + +| Script (`npm run ...`) | Ohun tí ó ń fìdí rẹ̀ múlẹ̀ | Ìdíwọ̀ | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `check:node-runtime` | Ẹ̀dà Node.js wà láàárín ààlà tí a ṣe àtìlẹ́yìn fún | Bẹ́ẹ̀ ni | +| `check:cycles` | Àwọn import oníyípo jákèjádò gbogbo `src/` + `open-sse/` (ó dá lórí AST, a sì ti yanjú `paths` ti tsconfig). Bare = ìmọ̀ràn, ó máa ń ṣe àtòjọ àwọn cycle náà. `check:cycles:ratchet` (èyí tí CI ń ṣiṣẹ́) máa ń díwọ̀ nígbà tí iye náà bá kọjá òrùlé `metrics.cycles` nínú `quality-baseline.json` — lọ́wọ́lọ́wọ́ 14, `direction: down`, nítorí náà ó lè dín kù nìkan (#15159 G-01/G-02) | Bẹ́ẹ̀ ni (ratchet) | +| `check:route-validation:t06` | Àwọn schema Zod wà lórí gbogbo route (ìlànà Tier 6) | Bẹ́ẹ̀ ni | +| `check:any-budget:t11` | Iye `@ts-expect-error // any` kò kọjá budget (Tier 11 catraca) | Bẹ́ẹ̀ ni | +| `check:provider-consistency` | Gbogbo olupèsè inú `providers.ts` ní àkọsílẹ̀ tó bá a mu nínú `providerRegistry.ts` (àti ní òdìkejì, láàárín allowlist) | Bẹ́ẹ̀ ni | +| `check:model-lifecycle` | Àwọn tábìlì ìtọ́sọ́nà mẹ́ta tí a ń tọ́jú pẹ̀lú ọwọ́ dúró ní ìbámu pẹ̀lú àwòrán lifecycle tí a ti fi sínú ibi ìpamọ́ (#11503): `FITNESS_TABLE` (`taskFitness.ts`) kò fún retired id kankan tí `REGISTRY` lè darí ní score; gbogbo target `BUILT_IN_ALIASES` wà nínú `REGISTRY`, wọn kò sì sí nínú àwòrán retired-id; gbogbo retired id tí ó ṣì wà nínú `REGISTRY` ni a forward tàbí tí a ṣe àkójọ rẹ̀ sínú `allowedRetiredInCatalog`; bẹ́ẹ̀ sì ni kò sí source tàbí target `DEFAULT_DEGRADATION_MAP` kankan tó hàn gẹ́gẹ́ bí retired nínú àwòrán náà. Èyí kò fi hàn pé upstream tó ń ṣiṣẹ́ ń pèsè model kan lọ́wọ́lọ́wọ́. Offline — ó ń fi wé `config/quality/model-lifecycle.json`, tí a ń sọ di tuntun pẹ̀lú ọwọ́ nípasẹ̀ `npm run quality:refresh-model-lifecycle` (network; a kò so mọ́ CI). `allowedRetiredInCatalog` jẹ́ burn-down ratchet: fi àkọsílẹ̀ kún un kìkì pẹ̀lú tracking issue. | Bẹ́ẹ̀ ni | +| `check:fetch-targets` | Gbogbo `fetch("/api/...")` nínú `src/` ti ẹ̀gbẹ́ client ń tọ́ka sí `route.ts` gidi kan | Bẹ́ẹ̀ ni | +| `check:deps` | Gbogbo deps tí `npm install` lè fi sórí ẹ̀rọ káàkiri gbogbo `package.json` inú repo wà nínú `dependency-allowlist.json`; a máa samì sí àwọn package tuntun tí a kò pin sí version pàtó tàbí tí a slopsquat | Bẹ́ẹ̀ ni | +| `audit:deps` | `npm audit` (root + electron) — kò sí ìkìlọ̀ high/critical (ó fara pọ̀ mọ́ osv `check:vuln-ratchet`; wo Rationalization Backlog) | Bẹ́ẹ̀ ni | +| `check:lockfile` | Ìdúróṣinṣin `package-lock.json` — https registry, integrity hashes, kò sí host overrides | Bẹ́ẹ̀ ni | +| `check:licenses` | Àtòjọ ìyọ̀nda àwọn ìwé-àṣẹ SPDX fún àwọn ìgbẹ́kẹ̀lé production | Bẹ́ẹ̀ni | +| `check:tracked-artifacts` | Kò sí àwọn artifact build / àwọn symlink `node_modules` tí a commit (ó tún ń ṣiṣẹ́ nínú husky pre-commit; pre-push jẹ́ fífẹ́ẹ́rẹ́ pẹ̀lú ìmọ̀ọ́mọ̀ — #6716) | Bẹ́ẹ̀ni | +| `check:ai-attribution` | Kò sí trailer `Co-Authored-By` ti AI/bot tàbí footer ìpilẹ̀ṣẹ̀ AI nínú àwọn commit PR, àkọlé tàbí ara — Òfin Líle #16 (nínú loop fast-gates `quality.yml` fún PR→`release/**` — ó ń ka payload event, kò sì ṣe ohunkóhun nígbà tí kì í ṣe PR — àti ìgbésẹ̀ PR-nìkan nínú lint `ci.yml` fún PR→`main`; àti hook husky `commit-msg`; àwọn olùkọ̀wé alábàáṣiṣẹ́ ènìyàn jẹ́ ìyọ̀nda; #14436) | +| `check:vitest-exclusions` | Gbogbo ìyọkúrò Vitest gbọ́dọ̀ sọ issue ìtọ́pasẹ̀ kan, kí ó sì fara hàn nínú `config/quality/vitest-exclusions.json` (#13204) | Bẹ́ẹ̀ni | +| `check:file-size` | Kò sí fáìlì source kankan tó kọjá òpin fún extension kọ̀ọ̀kan (ratchet: àwọn fáìlì ńlá tí a ti di mọ́ inú àtòjọ `frozen`) | Bẹ́ẹ̀ni | +| `check:error-helper` | Àwọn response àṣìṣe nínú executors/handlers máa ń lo `buildErrorBody()` / `sanitizeErrorMessage()` (Òfin Líle #12) | Bẹ́ẹ̀ni | +| `check:migration-numbering` | Àwọn fáìlì Migration SQL ní nọ́ńbà tó tẹ̀ lé ara wọn, kò sí àlàfo tàbí nọ́ńbà àdáwòkọ | Bẹ́ẹ̀ ni | +| `check:public-creds` | Kò sí OAuth `client_id`/`client_secret` tàbí àwọn kọ́kọ́rọ́ Firebase Web tí a kọ ní tààrà níta `publicCreds.ts` (Òfin Líle #11) | Bẹ́ẹ̀ ni | +| `check:db-rules` | Kò sí raw SQL níta àwọn module `src/lib/db/`; kò sí barrel-import láti `localDb.ts` (Àwọn Òfin Líle #2/#5) | Bẹ́ẹ̀ ni | +| `check:known-symbols` | Àwọn executor provider, àwọn ọgbọ́n routing, àti àwọn translator tí a forúkọsílẹ̀ sínú àwọn tábìlì dispatch wọn bá àwọn fáìlì tó wà lórí disk mu — kò sí symbol tí kò ní ìbáṣepọ̀ tàbí tí a kò kéde | Bẹ́ẹ̀ ni | +| `check:route-guard-membership` | Gbogbo route tó dá child process sílẹ̀ ni a pín sí ẹ̀ka pẹ̀lú `isLocalOnlyPath()` (Àwọn Òfin Líle #15/#17) | Bẹ́ẹ̀ ni | +| `check:test-discovery` | Gbogbo fáìlì `*.test.ts` / `*.spec.ts` inú repo ni ó kéré tán test runner kan ń kó jọ (ratchet: àkójọ orphan inú `test-discovery-baseline.json` lè dín kù nìkan) | Bẹ́ẹ̀ ni | +| `check:agent-skills-sync` | Àwọn artifact agent-skills tí a ṣẹ̀dá bá katalogi orísun wọn mu (kò sí ìyapa) | +| `check:provider-asset-provenance` | Àwọn àmì/asset olùpèsè ní àkọsílẹ̀ provenance tí a ti ṣàkọsílẹ̀ | +| `lint:json` | Àwọn fáìlì config JSON lè ṣe parse, wọ́n sì tẹ̀lé àwọn òfin lint repo náà | +| `typecheck:core` | Ìṣàkójọ TypeScript láìsí àṣìṣe (ìkìlọ̀ ìmọ̀ràn nìkan) | Bẹ́ẹ̀ ni | +| `typecheck:noimplicit:core` | `noImplicitAny` tó muna — èyí ń wo ọjọ́ iwájú; ọ̀pọ̀ àwọn ibi ìpè tó ti wà tẹ́lẹ̀ ṣì nílò àwọn àlàyé irú | **Ìmọ̀ràn** (`continue-on-error: true`) | +| `check:dashboard-typecheck` | `tsc` tí a fi ààlà sí `src/app/(dashboard)/**` (#7033) — àkójọ ìyọ̀ǹda fáìlì 27 tí a ti yan fún `typecheck:core` kò ní TSX dashboard kankan, `next build` kò sì ṣe àyẹ̀wò irú rẹ̀ rárá (`next.config.mjs` ṣètò `ignoreBuildErrors: true`), nítorí náà àwọn ìpadàsẹ́yìn identifier aláìní olùtọ́jú níbẹ̀ (#6625/#6909) kò hàn sí CI. Ó ń fi àwọn ìyàtọ̀ wé ìpìlẹ̀ iye tó di dídì fún fáìlì kọ̀ọ̀kan/kóòdù TS kọ̀ọ̀kan (`config/quality/dashboard-typecheck-baseline.json`, àpẹẹrẹ ìmúṣẹ́ ohun tó ti pẹ́ kan náà bí `check:known-symbols`) — àwọn àṣìṣe TUNTUN tí ó kọjá iye tó wà nínú ìpìlẹ̀ nìkan ló máa mú kí ẹnubodè náà kùnà; dín iye náà kù pẹ̀lú `--update` nígbà tí a bá ṣàtúnṣe àṣìṣe tó ti wà tẹ́lẹ̀. | Bẹ́ẹ̀ ni | ### Iṣẹ́: `quality-gate` -Ó máa ń ṣiṣẹ́ lẹ́yìn `test-coverage`. Ó máa ń dí ìdàpọ̀ dúró bí ó bá kùnà. +Ó máa ń ṣiṣẹ́ lẹ́yìn `test-coverage`. Ó máa ń dènà ìdapọ̀ bí ó bá kùnà. -| Script | Ohun tí ó ṣàyẹ̀wò | Dídènà | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | -| `quality:collect` | Ṣẹ̀dá `quality-metrics.json` (iye ìkìlọ̀ ESLint, àpapọ̀ ìdánwò láti inú ìròyìn shard tí a dapọ̀) | Bẹ́ẹ̀ ni (ṣáájú ratchet) | -| `quality:ratchet` | Metric kọ̀ọ̀kan nínú `quality-baseline.json` kò ti sẹ́yìn (àwọn ìkìlọ̀ ESLint ≤ baseline; àpapọ̀ ìdánwò ≥ baseline) | Bẹ́ẹ̀ ni | -| `check:duplication` | Àtúnṣe kóòdù kan náà (jscpd@4) kò kọjá baseline nínú `quality-baseline.json` | Bẹ́ẹ̀ ni | -| `check:complexity` | Ìṣòro cyclomatic ní ìpele fáìlì kò kọjá òpin (ESLint `complexity` àkọ́kọ́ + `max-lines-per-function`) | Bẹ́ẹ̀ ni | -| `check:cognitive-complexity` | Ratchet ìṣòro ìrònú (`eslint-plugin-sonarjs`) — ìṣiṣẹ́ ESLint ọ̀tọ̀; CI ń ṣiṣẹ́ àwọn méjèèjì tí a dapọ̀ gẹ́gẹ́ bí ìgbésẹ̀ `check:complexity-ratchets` kan ṣoṣo | Bẹ́ẹ̀ ni | -| `check:dead-code` | Ratchet àwọn export / fáìlì tí a kò lò (knip) kò sẹ́yìn ní ìfiwéra pẹ̀lú baseline | Bẹ́ẹ̀ ni | -| `check:compression-budget` | Ìnáwó benchmark fún compression — àwọn ìwọ̀n token-savings tó kéré jù lọ fún engine kọ̀ọ̀kan kò gbọ́dọ̀ sẹ́yìn | Bẹ́ẹ̀ ni | -| `check:type-coverage` | Ratchet ìdá ọgọ́rùn-ún tí a fi type sí (`type-coverage`) kò sẹ́yìn; ó bo ọ̀pọ̀ jù lọ nínú `typecheck:noimplicit:core` | Bẹ́ẹ̀ ni | -| `check:codeql-ratchet` | Iye ìkìlọ̀ CodeQL tó ṣí kò sẹ́yìn (ń kà nípasẹ̀ `gh api`; yóò fo pẹ̀lẹ́pẹ̀lẹ́ láìsí token) — fún àkókò ìsọdọ̀tun àti ìmúṣiṣẹ́ ọwọ́: wo "CodeQL ratchet" ní ìsàlẹ̀ | Bẹ́ẹ̀ ni | +| Skripti | Ohun tí ó ń fọwọ́sí | Ìdènà | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `quality:collect` | Ṣẹ̀dá `quality-metrics.json` (iye ìkìlọ̀ ESLint, ìborí láti inú ìròyìn shard tí a ti dapọ̀) | Bẹ́ẹ̀ni (ṣáájú ratchet) | +| `quality:ratchet` | Mẹ́tríìkì kọ̀ọ̀kan nínú `quality-baseline.json` kò ti bàjẹ́ sẹ́yìn (àwọn ìkìlọ̀ ESLint ≤ baseline; ìborí ≥ baseline) | Bẹ́ẹ̀ni | +| `check:duplication` | Ìṣàtúnlò kóòdù (jscpd@4) kò kọjá baseline nínú `quality-baseline.json` | Bẹ́ẹ̀ni | +| `check:complexity` | Ìdíjú cyclomatic ní ìpele fáìlì kò kọjá òpin (ESLint `complexity` àkọ́kọ́ + `max-lines-per-function`) | Bẹ́ẹ̀ni | +| `check:cognitive-complexity` | Ratchet ìdíjú ìrònú (`eslint-plugin-sonarjs`) — ìṣiṣẹ́ ESLint ọ̀tọ̀; CI ń ṣiṣẹ́ àwọn méjèèjì tí a dapọ̀ gẹ́gẹ́ bí ìgbésẹ̀ `check:complexity-ratchets` kan ṣoṣo | Bẹ́ẹ̀ni | +| `check:dead-code` | Ratchet àwọn export / fáìlì tí a kò lò (knip) kò bàjẹ́ sẹ́yìn ní ìfiwéra pẹ̀lú baseline | Bẹ́ẹ̀ni | +| `check:compression-budget` | Ìnáwó àdánwò ìfisúnkí — àwọn ìpele kékeré jù fún ìfipamọ́ token fún engine kọ̀ọ̀kan kò gbọ́dọ̀ bàjẹ́ sẹ́yìn | Bẹ́ẹ̀ni | +| `check:type-coverage` | Ratchet ìdá ọgọ́rùn-ún tí a fi type sí (`type-coverage`) kò bàjẹ́ sẹ́yìn; ó bo ọ̀pọ̀ jù lọ ohun tí `typecheck:noimplicit:core` ń ṣe | Bẹ́ẹ̀ni | +| `check:codeql-ratchet` | Iye àwọn ìkìlọ̀ CodeQL tó ṣí kò bàjẹ́ sẹ́yìn (ń kà nípasẹ̀ `gh api`; yóò fo ní àìléwu láìsí token) — fún bí a ṣe ń sọ ọ́ dọ̀tun àti ìmúnṣiṣẹ́ afọwọ́ṣe: wo "CodeQL ratchet" ní ìsàlẹ̀ | Bẹ́ẹ̀ni | ### Iṣẹ́: `quality-extended` Gbogbo iṣẹ́ náà jẹ́ ìmọ̀ràn (`continue-on-error: true`). Àwọn ratchet tó dá lórí npm ń ṣiṣẹ́ -gan-an; àwọn scanner òde ń fi ara wọn sílẹ̀ nípasẹ̀ `gh release download`, wọ́n sì ń fo fúnra wọn (exit 0) -nígbà tí binary kan kò bá sí síbẹ̀. - -| Script | Ohun tí ó ṣàyẹ̀wò | Dídènà | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| `check:circular-deps` | Kò sí àwọn dependency tó ń yípo (dpdm) | **Ìmọ̀ràn** | -| `check:bundle-size` | Ìwọ̀n bundle kò kọjá òpin | **Ìmọ̀ràn** | -| `check:secrets` | Ṣíṣàyẹ̀wò àṣírí (gitleaks) — yóò fo bí binary kò bá sí | **Ìmọ̀ràn** | -| `check:vuln-ratchet` | Àwọn àìlera dependency (osv-scanner) kò sẹ́yìn — yóò fo bí binary kò bá sí | **Ìmọ̀ràn** | -| `check:workflows` | Lint workflow (actionlint + zizmor); scanner tí kò sí/tó bàjẹ́, ìròyìn tí kò péye tàbí baseline ratchet tí kò sí yóò kuna gẹ́gẹ́ bí INCOMPLETE. Àwọn àbájáde tó péye ń tẹ̀lé ìlànà strict/advisory/ratchet tí a yàn | Ìṣiṣẹ́ pọn dandan; ratchet zizmor ń dí CI | -| `check:openapi-breaking` | Àwọn àyípadà tó ń fọ́ àdéhùn API gbogbogbò (`openapi.yaml`) ní ìfiwéra pẹ̀lú ẹ̀ka ìpìlẹ̀ (oasdiff) — ń ṣẹ̀dá `openapiBreaking=N`; yóò fo bí oasdiff kò bá sí tàbí tí a kò lè tú base spec | **Ìmọ̀ràn** | +gan-an; àwọn scanner òde ń fi sórí ẹrọ nípasẹ̀ `gh release download`, wọ́n sì máa ń fo fúnra wọn (exit 0) +nígbà tí binary kò bá sí síbẹ̀. + +| Skripti | Ohun tí ó ń fọwọ́sí | Ìdènà | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| `check:circular-deps` | Kò sí àwọn dependency tó ń yí ká (dpdm) | **Ìmọ̀ràn** | +| `check:bundle-size` | Ìwọ̀n bundle kò kọjá òpin | **Ìmọ̀ràn** | +| `check:secrets` | Ṣíṣàyẹ̀wò ohun àṣírí (gitleaks) — yóò fo bí binary kò bá sí | **Ìmọ̀ràn** | +| `check:vuln-ratchet` | Àwọn àìlera dependency (osv-scanner) kò bàjẹ́ sẹ́yìn — yóò fo bí binary kò bá sí | **Ìmọ̀ràn** | +| `check:workflows` | Lint workflow (actionlint + zizmor); àwọn scanner tí kò sí/tó bàjẹ́, àwọn ìròyìn tí kò tọ́ tàbí baseline ratchet tí kò sí yóò kùnà gẹ́gẹ́ bí INCOMPLETE. Àwọn àbájáde tó tọ́ ń tẹ̀lé ìlànà strict/advisory/ratchet tí a yàn | Ìṣiṣẹ́ pọndandan; ratchet zizmor jẹ́ ìdènà ní CI | +| `check:openapi-breaking` | Àwọn àyípadà tó ń ba àdéhùn API gbogbogbò (`openapi.yaml`) jẹ́ ní ìfiwéra pẹ̀lú ẹ̀ka ìpìlẹ̀ (oasdiff) — ń ṣẹ̀dá `openapiBreaking=N`; yóò fo bí oasdiff kò bá sí tàbí tí spec ìpìlẹ̀ kò bá ṣeé yanjú | **Ìmọ̀ràn** | ### Iṣẹ́: `docs-sync-strict` -Ó ń ṣiṣẹ́ lórí gbogbo PR sí `main`. Ó ń dí ìdapọ̀ tí ìkùnà bá ṣẹlẹ̀. - -| Skripti | Ohun tí ó ń fìdí rẹ̀ múlẹ̀ | Dídènà | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | -| `check:docs-all` | Ẹnubodè-àpapọ̀ tí ń ṣiṣẹ́ àwọn ẹnubodè-kékeré mẹ́fà tó wà nísàlẹ̀ lọ́nà tẹ̀lé-tẹ̀lé | Bẹ́ẹ̀ ni | -| ↳ `check:docs-sync` | Ìbámu ẹ̀yà CHANGELOG / OpenAPI / llm.txt | Bẹ́ẹ̀ ni | -| ↳ `check:docs-counts` | Àwọn iye nínú àkọsílẹ̀ (iye olùpèsè, iye ìṣíkiri, àti bẹ́ẹ̀ bẹ́ẹ̀ lọ) wà láàárín fèrèsé ratchet ti àwọn iye gidi | Bẹ́ẹ̀ ni | -| ↳ `check:env-doc-sync` | Gbogbo env var inú `.env.example` ni a ṣàkọsílẹ̀ sínú tábìlì ìwé-àkọsílẹ̀, àti ní ọ̀nà ìdàkejì náà | Bẹ́ẹ̀ ni | -| ↳ `check:deprecated-versions` | Kò sí ọ̀rọ̀ ẹ̀yà tí a ti dáwọ́ dúró nínú ìwé-àkọsílẹ̀ | Bẹ́ẹ̀ ni | -| ↳ `check:doc-links` | Àwọn ọ̀nà asopọ̀ markdown inú ìwé-àkọsílẹ̀ tọ́ka sí àwọn fáìlì gidi (fọ́ọ̀mù `[text]`/`(path)`) | Bẹ́ẹ̀ ni | -| ↳ `check:fabricated-docs` | Àwọn route, env var, àṣẹ CLI, orúkọ hook, àti ọ̀nà fáìlì tí a tọ́ka sí nínú ìwé-àkọsílẹ̀ wà nínú ibi-kóòdù. Ẹnubodè líle nípasẹ̀ `--strict`; ìkùnà-rọrùn láìsí àsìá náà. | Bẹ́ẹ̀ ni (nípasẹ̀ `--strict` nínú CI) | -| `check:cli-i18n` | Àwọn ọ̀rọ̀ àṣẹ CLI wà nínú gbogbo fáìlì locale i18n | Bẹ́ẹ̀ ni | -| `check:openapi-coverage` | Àlàyé OpenAPI bo ó kéré tán ìpele ratchet kan ti àwọn route gidi | Bẹ́ẹ̀ ni | -| `check:openapi-security-tiers` | Àwọn àkọlé ìpele ààbò nínú `openapi.yaml` bá àwọn ìsọ̀rí `routeGuard.ts` mu | **Ìmọ̀ràn** | -| `check:openapi-routes` | Gbogbo path nínú `openapi.yaml` tọ́ka sí `route.ts` gidi kan (ìdènà ìrò-káàkiri) | Bẹ́ẹ̀ ni | -| `check:docs-symbols` | Gbogbo ìtọ́kasí `/api/...` nínú `docs/**/*.md` tọ́ka sí `route.ts` gidi kan (ìdènà ìrò-káàkiri) | Bẹ́ẹ̀ ni | -| `i18n translation drift` | Àwọn key tí a kò tíì túmọ̀ nínú àwọn fáìlì locale i18n — ìkìlọ̀ nìkan | **Ìmọ̀ràn** | +Ó ń ṣiṣẹ́ lórí gbogbo PR sí `main`. Ó ń dí ìdapọ̀ mọ́ bí ó bá kùnà. + +| Skripti | Ohun tí ó ń fìdí rẹ̀ múlẹ̀ | Dídènà | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `check:docs-all` | Ẹnubodè àpapọ̀ tó ń ṣiṣẹ́ àwọn ẹnubodè kékeré mẹ́fà tó wà nísàlẹ̀ ní ọ̀kọ̀ọ̀kan | Bẹ́ẹ̀ni | +| ↳ `check:docs-sync` | Ìbámu ẹ̀yà CHANGELOG / OpenAPI / llm.txt | Bẹ́ẹ̀ni | +| ↳ `check:docs-counts` | Àwọn iye nínú àlàyé (iye àwọn olùpèsè, iye àwọn ìṣíkiri, àti bẹ́ẹ̀ bẹ́ẹ̀ lọ) wà láàárín fèrèsé ratchet ti àwọn iye gidi | Bẹ́ẹ̀ni | +| ↳ `check:env-doc-sync` | Gbogbo env var inú `.env.example` ni a ṣàkọsílẹ̀ sínú tábìlì docs kan, bẹ́ẹ̀ sì ni ní òdìkejì | Bẹ́ẹ̀ni | +| ↳ `check:deprecated-versions` | Kò sí àwọn ọ̀rọ̀ ẹ̀yà tí a ti dáwọ́ lílò dúró nínú docs | Bẹ́ẹ̀ni | +| ↳ `check:doc-links` | Àwọn ìjápọ̀ markdown inú docs ń tọ́ka sí àwọn fáìlì gidi (fọ́ọ̀mù `[text]`/`(path)`) | Bẹ́ẹ̀ni | +| ↳ `check:fabricated-docs` | Àwọn ipa-ọ̀nà, env vars, àwọn àṣẹ CLI, àwọn orúkọ hook, àti àwọn ipa-ọ̀nà fáìlì tí a tọ́ka sí nínú docs wà nínú codebase. Ẹnubodè líle nípasẹ̀ `--strict`; ìkùnà rírọ̀ láìsí flag. | Bẹ́ẹ̀ni (nípasẹ̀ `--strict` nínú CI) | +| `check:cli-i18n` | Àwọn ọ̀rọ̀ àṣẹ CLI wà nínú gbogbo fáìlì locale i18n | Bẹ́ẹ̀ni | +| `check:openapi-coverage` | Sipesifikesonu OpenAPI bo ó kéré tán ìpele ìsàlẹ̀ ratchet ti àwọn ipa-ọ̀nà gidi | Bẹ́ẹ̀ni | +| `check:openapi-security-tiers` | Àwọn àkọsílẹ̀ ìpele ààbò nínú `openapi.yaml` bá àwọn ìpínsísọ̀rí `routeGuard.ts` mu | **Ìmọ̀ràn** | +| `check:openapi-routes` | Gbogbo path inú `openapi.yaml` ń tọ́ka sí `route.ts` gidi kan (ààbò lòdì sí ìpilẹ̀ṣẹ̀ ohun tí kò sí) | Bẹ́ẹ̀ni | +| `check:docs-symbols` | Gbogbo ìtọ́kasí `/api/...` nínú `docs/**/*.md` ń tọ́ka sí `route.ts` gidi kan (ààbò lòdì sí ìpilẹ̀ṣẹ̀ ohun tí kò sí) | Bẹ́ẹ̀ni | +| `i18n translation drift` | Àwọn key tí a kò túmọ̀ nínú àwọn fáìlì locale i18n — ìkìlọ̀ nìkan | **Ìmọ̀ràn** | ### Iṣẹ́: `i18n-ui-coverage` -| Skripti | Ohun tí ó ń fìdí rẹ̀ múlẹ̀ | Dídènà | -| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check-ui-keys-coverage` (nínú laini) | Ìborí key i18n UI jẹ́ ≥ 65% | Bẹ́ẹ̀ ni | -| `check-ui-value-drift` (nínú laini) | Àtúnkọ iye Gẹ̀ẹ́sì kan kò fi ìtumọ̀ àtijọ́ kankan sílẹ̀ | Bẹ́ẹ̀ ni | -| `check-new-key-coverage` (nínú laini) | Key Gẹ̀ẹ́sì **tuntun** kan ni a túmọ̀ ní gbogbo locale — a kọ àmì `__MISSING__:` | Bẹ́ẹ̀ ni | -| `check-translation-ratio` | Ìpín ìtumọ̀ gidi fún locale kọ̀ọ̀kan (èyí tó jọ Gẹ̀ẹ́sì / àfipò / àwọn ewé tó sọnù lẹ́yìn allowlist) kò gbọdọ̀ kọjá `config/quality/i18n-translation-baseline.json` + ààyè àfikún | **Ìmọ̀ràn** | +| Skripti | Ohun tí ó ń fìdí rẹ̀ múlẹ̀ | Dídènà | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check-ui-keys-coverage` (inline) | Ìborí key i18n UI jẹ́ ≥ 65% | Bẹ́ẹ̀ni | +| `check-ui-value-drift` (inline) | Àtúnkọ **value** èdè Gẹ̀ẹ́sì kò fi ìtumọ̀ àtijọ́ kankan sílẹ̀ | Bẹ́ẹ̀ni | +| `check-new-key-coverage` (inline) | A túmọ̀ key èdè Gẹ̀ẹ́sì **tuntun** nínú gbogbo locale — a kọ àmì `__MISSING__:` | Bẹ́ẹ̀ni | +| `check-translation-ratio` | Ìpín ìtumọ̀ gidi fún locale kọ̀ọ̀kan (èyí tó jọ èdè Gẹ̀ẹ́sì / placeholder / àwọn ewé tí ó sọnù lẹ́yìn allowlist) kò gbọ́dọ̀ kọjá `config/quality/i18n-translation-baseline.json` + àyè àfikún | **Ìmọ̀ràn** | Ó nílò `fetch-depth: 0` — ẹnubodè value-drift ń ṣe diff `en.json` pẹ̀lú merge base. -#### `check-ui-value-drift` — ẹnubodè ìtumọ̀-àtijọ́ +#### `check-ui-value-drift` — ẹnubodè ìtumọ̀ àtijọ́ -Ó ń mú àṣìṣe i18n kan ṣoṣo tí àwọn ẹnubodè yòókù kò lè rí nípa ìṣètò: a tún iye Gẹ̀ẹ́sì kan kọ -ṣùgbọ́n àwọn ìtumọ̀ tí a dá láti inú Gẹ̀ẹ́sì _tẹ́lẹ̀_ ṣì wà, nítorí náà -àwọn olumulo tí kì í lo Gẹ̀ẹ́sì ń bá a lọ láti ka ọ̀rọ̀ tó dáni lójú ṣùgbọ́n tí ó ti di àṣìṣe báyìí. +Ó ń ṣàwárí àṣìṣe i18n kan ṣoṣo tí àwọn ẹnubodè mìíràn kò lè rí nípa ìṣètò: a tún value èdè Gẹ̀ẹ́sì +kọ, ṣùgbọ́n àwọn ìtumọ̀ tí a dá láti inú èdè Gẹ̀ẹ́sì _ìṣáájú_ ṣì wà, nítorí náà +àwọn aṣàmúlò tí kì í ṣe ti èdè Gẹ̀ẹ́sì ń bá a lọ láti ka ọ̀rọ̀ tó dájú lójú ṣùgbọ́n tó ti di àṣìṣe. -Èyí ti wọ ẹ̀yà ìmúlò gidi rí. A tún `oauthModal.googleOAuthWarning` kọ nígbà tí olùrànlọ́wọ́ -wọlé Antigravity dé (#5203); **39 nínú locale 43** pa ọ̀rọ̀ tó ń sọ fún àwọn olùṣàkóso láti "ṣẹ̀dà -URL kíkún kí wọ́n sì lẹ̀ ẹ́ sísàlẹ̀" mọ́ — ìṣàn iṣẹ́ tí kò lè parí fún olùpèsè yẹn. A kò +Èyí ti dé sí ìmújáde ní ti gidi. A tún `oauthModal.googleOAuthWarning` kọ nígbà tí olùrànlọ́wọ́ ìwọlé Antigravity +dé (#5203); **39 nínú 43 locale** pa ọ̀rọ̀ tó sọ fún àwọn olùdarí láti “da URL kíkún náà kọ, kí wọ́n sì lẹ̀ ẹ́ sí ìsàlẹ̀” mọ́ — ìṣàn kan tí kò lè parí fún olùpèsè yẹn. A kò ṣàkíyèsí rẹ̀ títí di #8463 nítorí pé: -- `sync-ui-keys` ń fi àwọn key tí **kò sí** nìkan kún un, kì í ṣe àwọn tó ti **di àtijọ́**; -- `check-ui-keys-coverage` ń ka _wíwà_ key, nítorí náà ìtumọ̀ àtijọ́ kan gba àmì bí èyí tí a ti bo; -- `check-translation-drift` ń tọpinpin àwọn àwòrán-dídára ìwé-àkọsílẹ̀ `docs/i18n//**.md` — - kò ka `src/i18n/messages/*.json` láéláé. Ó ti ń dí iṣẹ́ dúró nínú job `docs-sync-strict` láti ìṣàmúdọ̀tun - 2026-09: ṣàtúnṣe core doc kan → `npm run i18n:run -- --files=` (ní ìpele abala, kò ná púpọ̀). +- `sync-ui-keys` máa ń ṣe àfikún àwọn key tí wọ́n **kò sí** nìkan, kì í ṣe àwọn tó ti **di àtijọ́**; +- `check-ui-keys-coverage` ń ka _wíwà_ key, nítorí náà ìtumọ̀ àtijọ́ máa ń gba àmì bí èyí tí a bo; +- `check-translation-drift` ń tọpa àwọn ẹ̀dà àkọsílẹ̀ `docs/i18n//**.md` — + kò ka `src/i18n/messages/*.json` rárá. Ó ti ń dí iṣẹ́ dúró nínú job `docs-sync-strict` láti ìmúdọ́gba 2026-09: ṣàtúnṣe doc pàtàkì kan → `npm run i18n:run -- --files=` (ní ìpele abala, kò ná púpọ̀). -**Ó mọ ìyàtọ̀ (diff), kò gbára lé baseline.** Ó ń fi `en.json` ní merge base wé +**Ó mọ ìyàtọ̀, kò gbára lé baseline.** Ó ń fi `en.json` ní merge base wé working tree; fún gbogbo key tí iye Gẹ̀ẹ́sì rẹ̀ yí padà, locale èyíkéyìí tí ó ṣì ní -ìtumọ̀ tí a kò fọwọ́ kàn ti di àtijọ́. Èyí mọ̀ọ́mọ̀ **ń dá gbèsè tó ti wà tẹ́lẹ̀ dúró** — diff -kò lè fi Gẹ̀ẹ́sì àtijọ́ tí ìtumọ̀ tó ti wà fún ìgbà pípẹ́ ti wá hàn, nítorí náà gate náà ń ṣàyẹ̀wò -ohun tí àyípadà lọ́wọ́lọ́wọ́ kàn nìkan. Yíyan ọ̀nà mìíràn (baseline hash kan fún key kọ̀ọ̀kan) yóò gba -fáìlì tí a ṣe jáde tó tó ~600 KB, ìlọ́po mẹ́ta baseline tó tóbi jù lọ tó wà, tí yóò sì máa yí padà lórí gbogbo PR i18n. +ìtumọ̀ tí a kò fọwọ́ kàn ti di àtijọ́. Èyí mọ̀ọ́mọ̀ **di gbèsè tó ti wà tẹ́lẹ̀ mú** — diff +kò lè fi Gẹ̀ẹ́sì àtijọ́ tí ìtumọ̀ kan tó ti wà fún ìgbà pípẹ́ ti wá hàn, nítorí náà gate náà +ń ṣe ìdájọ́ ohun tí àyípadà lọ́wọ́lọ́wọ́ bá fọwọ́ kàn nìkan. Àṣàyàn kejì (baseline hash fún key kọ̀ọ̀kan) yóò gba +fáìlì tí a ṣẹ̀dá tó tó ~600 KB, ìlọ́po mẹ́ta baseline tó tóbi jù lọ tó wà, tí yóò sì máa yí padà lórí gbogbo i18n PR. -Ọ̀nà méjì ló wà láti mú un ṣẹ: +Ọ̀nà méjì láti mú un ṣẹ: -1. ṣe ìmúdójúìwọ̀n àwọn ìtumọ̀ tí ọ̀ràn náà kàn, tàbí -2. ṣètò wọn sí `__MISSING__:` — runtime náà yóò wá fi Gẹ̀ẹ́sì tí a ti ṣàtúnṣe hàn +1. ṣe àfikún sí àwọn ìtumọ̀ tí ọ̀rọ̀ náà kàn, tàbí +2. ṣètò wọn sí `__MISSING__:` — runtime yóò wá fi Gẹ̀ẹ́sì tí a ti ṣàtúnṣe náà hàn (`src/i18n/request.ts::deepMergeFallback`, #7258), key náà yóò sì wọ ìlà fún ìtumọ̀. -Tí **ìtumọ̀ ọ̀rọ̀** string náà bá yí padà, ó dára kí o **sọ key náà lórúkọ tuntun**: key tuntun kò lè jogún -ìtumọ̀ àtijọ́. Àpẹẹrẹ yẹn ni #8463 lò. +Tí **ìtumọ̀ inú** string náà bá yí padà, ó dára jù láti **sọ key náà lórúkọ tuntun**: key tuntun kò lè jogún +ìtumọ̀ àtijọ́. Èyí ni àpẹẹrẹ tí #8463 lò. ```bash -npm run i18n:check-value-drift # líle (èyí tí CI ń ṣiṣẹ́) +npm run i18n:check-value-drift # tó muna (èyí tí CI ń ṣiṣẹ́) npm run i18n:check-value-drift:warn # ìròyìn nìkan BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -Ó jáde pẹ̀lú 0 àti `SKIP reason=base-unresolved` nígbà tí a kò bá lè ka catalog ìpìlẹ̀ (shallow +Ó máa jáde pẹ̀lú 0 àti `SKIP reason=base-unresolved` nígbà tí kò bá ṣeé ka catalog ìpìlẹ̀ (shallow clone tí kò ní base ref), gẹ́gẹ́ bí `check-openapi-breaking`. ### Iṣẹ́: `i18n` -Matrix ìfọwọ́sí i18n kíkún (iṣẹ́ kan fún locale kọ̀ọ̀kan). Gbogbo iṣẹ́ náà jẹ́ ìmọ̀ràn. +Matrix ìfọwọ́sí i18n kíkún (iṣẹ́ kan fún locale kọ̀ọ̀kan). Gbogbo iṣẹ́ náà jẹ́ àmọ̀ràn. | Script | Ohun tí ó ń fọwọ́sí | Dídènà | | ------------------------------- | ---------------------------- | ------------------------------------------------------ | -| `validate_translation.py quick` | Pípé ìtumọ̀ fún locale kọ̀ọ̀kan | **Ìmọ̀ràn** (`continue-on-error: true` lórí gbogbo iṣẹ́) | +| `validate_translation.py quick` | Pípé ìtumọ̀ fún locale kọ̀ọ̀kan | **Àmọ̀ràn** (`continue-on-error: true` lórí gbogbo iṣẹ́) | ### Iṣẹ́: `pr-test-policy` Ó ń ṣiṣẹ́ lórí pull requests nìkan. -| Script | Ohun tí ó ń fọwọ́sí | Dídènà | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | -| `check:pr-test-policy` | Àwọn PR tó yí production code padà nínú `src/`, `open-sse/`, `electron/`, tàbí `bin/` gbọ́dọ̀ fi test kún un tàbí ṣe ìmúdójúìwọ̀n rẹ̀ (Òfin Líle #8) | Bẹ́ẹ̀ ni | -| `check:test-masking` | Àwọn fáìlì test tí a yí padà kò dín àpapọ̀ iye assert kù, wọn kò sì ṣàfikún tautology `assert.ok(true)` | Bẹ́ẹ̀ ni | -| `check:pr-evidence` | Ara PR tọ́ka sí ẹ̀rí test/VPS fún àyípadà náà (ó sọ Òfin Líle #18 di aládàáṣiṣẹ́ nípa lílo grep lórí ọ̀rọ̀ PR — ó rọrùn láti bàjẹ́, wo Backlog) | Bẹ́ẹ̀ ni | +| Script | Ohun tí ó ń fọwọ́sí | Dídènà | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | +| `check:pr-test-policy` | Àwọn PR tí ó yí production code padà nínú `src/`, `open-sse/`, `electron/`, tàbí `bin/` gbọ́dọ̀ ní àwọn test tàbí kí wọ́n ṣe àfikún sí wọn (Òfin Líle #8) | Bẹ́ẹ̀ ni | +| `check:test-masking` | Àwọn fáìlì test tí a yí padà kò dín àpapọ̀ iye assert kù, wọn kò sì ṣàfikún àwọn tautology `assert.ok(true)` | Bẹ́ẹ̀ ni | +| `check:pr-evidence` | Ara PR tọ́ka sí ẹ̀rí test/VPS fún àyípadà náà (ó sọ Òfin Líle #18 di aládàáṣiṣẹ́ nípa lílo grep lórí ọ̀rọ̀ PR — ó rọrùn láti bàjẹ́, wo Backlog) | Bẹ́ẹ̀ ni | ### Iṣẹ́: `test-vitest` -Ó ń ṣiṣẹ́ lẹ́yìn `build`. Ó ń dènà merge tí ó bá kùnà. +Ó ń ṣiṣẹ́ lẹ́yìn `build`. Ó máa ń dí merge tí ó bá kùnà. -| Suite | Ohun tí ó ń fọwọ́sí | Dídènà | -| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| `test:vitest` | MCP server (110 tools), autoCombo, cache — vitest runner | Bẹ́ẹ̀ ni | -| `test:vitest:ui` | Àwọn test component UI — vitest runner | **Ó ń dènà** — a yọ àwọn ìkùnà tó ti wà tẹ́lẹ̀ kúrò ní pàtó nínú `vitest.config.ts`; àwọn ìkùnà tuntun yóò mú kí iṣẹ́ náà kùnà | +| Suite | Ohun tí ó ń fọwọ́sí | Dídènà | +| ---------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `test:vitest` | MCP server (irinṣẹ́ 110), autoCombo, cache — vitest runner | Bẹ́ẹ̀ ni | +| `test:vitest:ui` | Àwọn test component UI — vitest runner | **Ó ń díni** — àwọn ìkùnà tó ti wà tẹ́lẹ̀ ni a yọ kúrò ní pàtó nínú `vitest.config.ts`; àwọn ìkùnà tuntun yóò mú kí iṣẹ́ náà kùnà | -### Àwọn workflow alẹ́ (tí a ṣètò sí àkókò, ìmọ̀ràn) +### Àwọn workflow alẹ́ (tí a ṣètò sí àkókò, àmọ̀ràn) -Àwọn wọ̀nyí ń ṣiṣẹ́ lórí ìṣètò cron (àti `workflow_dispatch`), wọn kì í ṣiṣẹ́ lórí PR rárá. Gbogbo wọn jẹ́ ìmọ̀ràn. +Àwọn wọ̀nyí ń ṣiṣẹ́ lórí ìṣètò cron (àti `workflow_dispatch`), wọn kì í ṣiṣẹ́ lórí PR. Gbogbo wọn jẹ́ àmọ̀ràn. -| Workflow | Ohun tí ó ń fọwọ́sí | Dídènà | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | -| `nightly-property` | Àwọn property test fast-check pẹ̀lú seed aláìlétò + iye ìṣiṣẹ́ tó ga | **Ìmọ̀ràn** | -| `nightly-resilience` | gate ìdàgbàsókè heap, chaos fault-injection, load/soak k6 | **Ìmọ̀ràn** | -| `nightly-llm-security` | guard injection promptfoo (block mode) + àwọn probe garak (a máa foju kọ wọ́n láìsí provider secret) | **Ìmọ̀ràn** | -| `nightly-schemathesis` | OpenAPI contract fuzzing (schemathesis) sí OmniRoute tó ń ṣiṣẹ́ ní lílo `docs/openapi.yaml` — ó ń ṣí àwọn ìrúfin spec / àwọn 500 tí a kò bójú tó payá (Ìpele 8 B.4) | **Ìmọ̀ràn** | -| `nightly-mutation` | Àmì mutation-testing Stryker lórí fast unit lane — àwọn mutant tó yè ń ṣí àwọn assert aláìlágbára payá | **Ìmọ̀ràn** | -| `nightly-compat` | Matrix ìbámu engine Node káàkiri àwọn range `engines.node` tí a ṣe àtìlẹ́yìn fún | **Ìmọ̀ràn** | +| Workflow | Ohun tí ó ń fọwọ́sí | Dídènà | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `nightly-property` | Àwọn property test fast-check pẹ̀lú seed aláìlẹ́sẹ̀sẹ̀ + iye run tó ga | **Àmọ̀ràn** | +| `nightly-resilience` | gate ìdàgbàsókè heap, chaos fault-injection, load/soak k6 | **Àmọ̀ràn** | +| `nightly-llm-security` | olùṣọ́ injection promptfoo (block mode) + àwọn probe garak (a máa fò ó tí kò bá sí provider secret) | **Àmọ̀ràn** | +| `nightly-schemathesis` | OpenAPI contract fuzzing (schemathesis) lòdì sí OmniRoute tó ń ṣiṣẹ́ nípa lílo `docs/openapi.yaml` — ń fi àwọn ìrúfin spec / àwọn 500 tí a kò bójú tó hàn (Fase 8 B.4) | **Àmọ̀ràn** | +| `nightly-mutation` | Iye mutation-testing Stryker lórí fast unit lane — àwọn mutant tó yè ń fi àwọn assert aláìlágbára hàn | **Àmọ̀ràn** | +| `nightly-compat` | Matrix ìbámu engine Node káàkiri àwọn range `engines.node` tí a ṣe àtìlẹ́yìn fún | **Àmọ̀ràn** | --- @@ -536,43 +534,44 @@ kò gbé e wọlé láìfọwọ́ṣe (ìwọ ni yóò yan afárá MCP↔LSP t --- -## Àtòjọ Àwọn Iṣẹ́ Ìṣètòpadà (àgbéyẹ̀wò ROI — Ìpele 9 Ìgbì 3) +## Àtòjọ Àwọn Iṣẹ́ Ìṣàlàyé (àtúnyẹ̀wò ROI — Ìpele 9 Ìgbì 3) -A ṣe àfiwé àtòjọ yìí pẹ̀lú `ci.yml` ní 2026-06-17 (ẹ̀dà tó ṣáájú kò ní +A ṣe ìbámu àkójọ yìí pẹ̀lú `ci.yml` ní 2026-06-17 (ẹ̀yà àtẹ̀yìnwá kò ní `audit:deps`, `check:tracked-artifacts`, `check:lockfile`, `check:licenses`, `check:dead-code`, `check:cognitive-complexity`, `check:type-coverage`, -`check:codeql-ratchet`, `check:pr-evidence`). Àgbéyẹ̀wò ROI lórí àkójọpọ̀ tí a ti ṣe àtúnṣe rẹ̀ -ṣàfihàn àwọn olùdíje ìṣètòpadà wọ̀nyí. **Àwọn ìsopọ̀ náà jẹ́ àwọn àyípadà CI -aláìdíjú; àwọn ìyípadà/iparẹ́ jẹ́ ìpinnu ìlànà tí a fi sílẹ̀ fún olùṣiṣẹ́.** Kò sí ohun tó wà nísàlẹ̀ +`check:codeql-ratchet`, `check:pr-evidence`). Àtúnyẹ̀wò ROI lórí àkójọ tí a mú bá ara wọn mu +ṣàwárí àwọn olùdíje ìṣàlàyé wọ̀nyí. **Àwọn ìṣọ̀kan náà jẹ́ àwọn àyípadà CI +aláìlọ́gbọ́n-ọ̀nà; àwọn ìyípadà/iparẹ́ jẹ́ àwọn ìpinnu ìlànà tí a fi sílẹ̀ fún olùṣàkóso.** Kò sí ohunkóhun nísàlẹ̀ tí a ti lò síbẹ̀. -**Ohun mìíràn tí a kò ṣàkọsílẹ̀ lókè** (ìmọ̀ràn nìkan, àmì tí kò lágbára): iṣẹ́ `docs-lint` -(markdownlint + Vale, gbogbo iṣẹ́ náà ní `continue-on-error`) àti àwọn ìṣàn-iṣẹ́ ọlọ́jẹ̀ àdáṣo +**Ohun mìíràn tí a kò ṣàkọsílẹ̀ lókè** (ìmọ̀ràn, àmì aláìlágbára): iṣẹ́ `docs-lint` +(markdownlint + Vale, gbogbo iṣẹ́ náà jẹ́ `continue-on-error`) àti àwọn ìṣàn-iṣẹ́ aṣàyẹ̀wò olóminira `semgrep.yml` / `codeql.yml` / `scorecard.yml`. `semgrepFindings: 0` wà nínú -`quality-baseline.json` ṣùgbọ́n a kò so ó mọ́ ratchet ìdènà kan nínú `ci.yml` — metric náà -kò ní ohun tó ń lò ó lọ́wọ́lọ́wọ́. - -### Ìsopọ̀ / yíyọ àtúnṣe kúrò (aláìdíjú, ewu kéré) - -A fìdí olùdíje kọ̀ọ̀kan múlẹ̀ pẹ̀lú ipò gate tó ń ṣiṣẹ́ ní 2026-06-17 (gbọ́kànlé-ṣùgbọ́n-ṣàyẹ̀wò); -ọ̀pọ̀ ìsopọ̀ tó dà bíi pé ó “hàn gbangba” ló fi hàn pé gbèsè wà níbẹ̀, wọ́n sì **kì í ṣe** àròpò tààrà tó mọ́. - -- **`check:docs-sync` ń ṣiṣẹ́ lẹ́ẹ̀mejì** — ní àdáṣo nínú iṣẹ́ `lint` àti lẹ́ẹ̀kan sí i nínú `check:docs-all` (`docs-sync-strict`) àti husky pre-commit hook. ✅ **A TI ṢE É** — a yọ ìpè `lint` àdáṣo náà kúrò. -- **Ṣíṣàyẹ̀wò CVE** — ❌ **KÌ Í ṣe ìsopọ̀ tó mọ́.** `audit:deps` yóò kọ̀ láìfọ̀rọ̀ sábẹ́ ahọ́n sọ lórí CVE èyíkéyìí tó jẹ́ high/critical; `check:vuln-ratchet` (osv) yóò kùnà nìkan nígbà tí _ìfàsẹ́yìn_ bá wà ní ìfiwéra pẹ̀lú baseline (lọ́wọ́lọ́wọ́, MODERATE 1). Ìtumọ̀ wọn yàtọ̀ — pípa `audit:deps` rẹ́ yóò mú kí gate high/critical pípé náà sọnù. Jẹ́ kí àwọn méjèèjì dúró. -- **Ṣíṣàwárí cycle** — ❌ **KÌ Í ṣe ìsopọ̀ tó mọ́.** `check:circular-deps` (dpdm) ròyìn **cycle 91** (ìdí nìyẹn tí ó fi jẹ́ ìmọ̀ràn nìkan); a kò lè gbé e ga sí ìdènà láìkọ́kọ́ yanjú wọn, ó sì ní ààlà tó gbòòrò ju `check:cycles` aláwọ̀ ewé tí a fara balẹ̀ ṣètò lọ. Jẹ́ kí `check:cycles` máa dí ohun tí kò bá yẹ; yíyanjú àwọn cycle dpdm 91 náà jẹ́ iṣẹ́ àtòjọ tirẹ̀. -- **Ìdíjú** — ✅ **A TI ṢE É** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ìrìn ESLint kan ṣoṣo, ó ń ka gẹ́gẹ́ bí ruleId kí àwọn baseline cyclomatic+max-lines àti cognitive lè máa dúró lọ́tọ̀; `check:complexity` / `check:cognitive-complexity` kọ̀ọ̀kan ṣì wà fún `--update` agbègbè. -- **Ìdènà àròsọ èké `/api`** — ✅ **A TI ṢE É** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): àkójọ FS kan ṣoṣo ti `src/app/api`, openapi-routes + docs-symbols ṣì ń ròyìn lọ́tọ̀; àwọn ti ọ̀kọ̀ọ̀kan ṣì wà fún ìṣiṣẹ́ agbègbè. -- **`check:node-runtime` ń ṣiṣẹ́ nínú iṣẹ́ 11** — ⚠️ **ROI kéré.** Ọ̀kọ̀ọ̀kan jẹ́ runner ọ̀tọ̀, àyẹ̀wò náà sì jẹ́ <1s; àkókò àpapọ̀ tí a lè fipamọ́ jẹ́ ~10s, ní ìfiwéra pẹ̀lú pípàdánù olùṣọ́ olówó-pọ́ọ́kú fún iṣẹ́ kọ̀ọ̀kan. Kò yẹ kí a fa ìyípadà ńlá nítorí rẹ̀. -- **`typecheck:noimplicit:core` lórí lint CI** — ✅ **a yọ ọ́ kúrò nínú iṣẹ́ lint** (ó jẹ́ `continue-on-error` ìmọ̀ràn tẹ́lẹ̀); ààlà type tó ń dí ohun tí kò bá yẹ ni `typecheck:core` + `check:type-coverage`. A fi script agbègbè náà sílẹ̀. - -### Yípadà / pinnu (ìlànà olùṣiṣẹ́) - -- `check:openapi-security-tiers` (ìmọ̀ràn nìkan) — ❌ **A KÒ lè yí i padà ní mímọ́.** Ó parí pẹ̀lú 0 ṣùgbọ́n ó kìlọ̀ pé ọ̀pọ̀ route `traffic-inspector` lábẹ́ `LOCAL_ONLY_API_PREFIXES` kò ní annotation `x-loopback-only: true`. Fífipá mú un ṣiṣẹ́ béèrè pé kí a kọ́kọ́ fi àwọn annotation wọ̀nyẹn kún `openapi.yaml`. -- `typecheck:noimplicit:core` (ìmọ̀ràn nìkan) — ratchet `check:type-coverage` tó ń dí ohun tí kò bá yẹ ti bo ọ̀pọ̀ jù lọ nínú rẹ̀. Yí i padà sí ratchet tàbí yọ pass `tsc` kejì tó ṣe àtúnṣe iṣẹ́ kan náà kúrò. -- `test:vitest:ui` (tó ti ń **dí ohun tí kò bá yẹ** báyìí) — àwọn ìkùnà tó ti wà tẹ́lẹ̀ ni a yọ kúrò ní kedere nínú `vitest.config.ts` pẹ̀lú àwọn àsọyé ìtọ́pinpin `// #8618`; àwọn ìkùnà tuntun yóò mú kí iṣẹ́ náà kùnà. -- `check:secrets` (gitleaks, ratchet tó ń dí ohun tí kò bá yẹ, tí a dì mọ́ false-positive 3 tí a ti ṣàkọsílẹ̀) — fi àwọn 3 náà sí allowlist láti dé 0, tàbí sọ ọ́ kalẹ̀ sí ìmọ̀ràn nìkan. Ó ní àdàkọ iṣẹ́ pẹ̀lú secret-scanning abinibi GitHub + `check:public-creds`. -- `check:pr-evidence` (ó ń dí ohun tí kò bá yẹ, ó ń fi grep wá ọ̀rọ̀ inú PR-body) — ewu false-positive ga; pípa á rẹ́ yóò sọ ìfipá-mú Ìlànà Líle #18 di aláìlágbára, nítorí náà èyí jẹ́ ìpinnu ìlànà gidi. -- `semgrep` (àdáṣo ìmọ̀ràn nìkan) — ó ní àdàkọ iṣẹ́ pẹ̀lú CodeQL fún àwọn ẹbí OWASP; so baseline rẹ̀ mọ́ ratchet tàbí yọ ọ́ kúrò. +`quality-baseline.json` ṣùgbọ́n a kò so mọ́ ratchet ìdènà nínú `ci.yml` — òṣùwọ̀n náà +kò ní ohun tí ó ń lò ó lọ́wọ́lọ́wọ́. + +### Ṣọ̀kan / yọ àtúnsí kúrò (aláìlọ́gbọ́n-ọ̀nà, ewu kéré) + +A fìdí olùdíje kọ̀ọ̀kan múlẹ̀ pẹ̀lú ipò ẹnu-ọ̀nà tó ń ṣiṣẹ́ ní 2026-06-17 (gbọ́kànlé-ṣùgbọ́n-ṣàyẹ̀wò); +ọ̀pọ̀ àwọn ìṣọ̀kan tí ó dàbí ẹni pé ó “hàn gbangba” fi hàn pé wọ́n ń fi gbèsè pamọ́, wọn kò sì jẹ́ +àwọn àfidípò tààrà **rárá**. + +- **`check:docs-sync` ń ṣiṣẹ́ lẹ́ẹ̀mejì** — gẹ́gẹ́ bí ohun olóminira nínú iṣẹ́ `lint` àti lẹ́ẹ̀kan sí i nínú `check:docs-all` (`docs-sync-strict`) àti ìkọ̀ husky pre-commit. ✅ **TI PARÍ** — a yọ ìpè `lint` olóminira náà kúrò. +- **Àyẹ̀wò CVE** — ❌ **KÌ Í ṢE ìṣọ̀kan tó mọ́ tónítóní.** `audit:deps` máa ń kùnà pátápátá lórí CVE èyíkéyìí tó ga/pàtàkì; `check:vuln-ratchet` (osv) máa ń kùnà nìkan lórí _ìfàsẹ́yìn_ ní ìfiwéra pẹ̀lú baseline (lọ́wọ́lọ́wọ́ 1 MODERATE). Ìtumọ̀ wọn yàtọ̀ — píparẹ́ `audit:deps` yóò mú kí ẹnu-ọ̀nà pípé fún ga/pàtàkì pàdánù. Ẹ jẹ́ kí àwọn méjèèjì wà. +- **Ìṣàwárí cycle** — ✅ **TI PARÍ** (#15159 G-01/G-02). Ọ̀rọ̀ àtijọ́ níbí pe `check:cycles` ní ẹnu-ọ̀nà “aláwọ̀ ewé, tí a ṣàyàn pẹ̀lú ìṣọ́ra” ó sì ṣàlàyé pé kí ó máa dí iṣẹ́ lọ́nà nítorí `check:circular-deps` (dpdm) ròyìn cycle 91. Àwọ̀ ewé yẹn jẹ́ **àwọ̀ ewé èké**: `check:cycles` ṣàyẹ̀wò àwọn subdirectory 5 (fáìlì 450), ó bá `import|export … from` aimi nìkan mu, ó sì sọ gbogbo specifier `@/` àti `@omniroute/open-sse/` nù, nítorí náà kò lè rí àwọn cycle dynamic-import + alias tí ó pọ̀ jù nínú repo. A ti tún un ṣe: ẹnu-ọ̀nà náà ń rìn ká `src` + `open-sse` báyìí (fáìlì 5023), ó ń kó àwọn specifier láti TypeScript AST (nítorí náà `import("…")` wúlò ṣùgbọ́n `typeof import("…")` ní ipò type kò wúlò), ó sì ń yanjú `paths` tsconfig. Ó rí cycle **14**, kì í ṣe 0. Nítorí pé a kò lè tún àwọn cycle 14 tó ti wà tẹ́lẹ̀ ṣe nínú PR ẹnu-ọ̀nà kan, `check:cycles` ti di **ratchet** báyìí (`--ratchet`, òrùlé `metrics.cycles.value = 14` nínú `quality-baseline.json`, `direction: down`) — ó ń dí _ìfàsẹ́yìn_ èyíkéyìí, iye náà sì lè dín kù nìkan. CI ń ṣiṣẹ́ `npm run check:cycles:ratchet`. Ìdínkù díẹ̀díẹ̀ máa lọ pẹ̀lú **A-01**. `check:circular-deps` (dpdm) ṣì jẹ́ ìmọ̀ràn gẹ́gẹ́ bí èrò kejì tó gbòòrò. +- **Ìdíjú** — ✅ **TI PARÍ** (`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`): ìrìn ESLint kan ṣoṣo, ó ń ka nípasẹ̀ ruleId kí baseline cyclomatic+max-lines àti cognitive lè dúró lọ́tọ̀ọ̀tọ̀; `check:complexity` / `check:cognitive-complexity` kọ̀ọ̀kan ṣì wà fún `--update` agbègbè. +- **Ìdènà ìròsọ `/api`** — ✅ **TI PARÍ** (`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`): àkójọ FS kan ṣoṣo ti `src/app/api`, openapi-routes + docs-symbols ṣì ń ròyìn lọ́tọ̀ọ̀tọ̀; àwọn ti ẹnìkọ̀ọ̀kan ṣì wà fún ṣíṣiṣẹ́ agbègbè. +- **`check:node-runtime` ń ṣiṣẹ́ nínú iṣẹ́ 11** — ⚠️ **ROI kéré.** Ọ̀kọ̀ọ̀kan jẹ́ runner lọ́tọ̀, àyẹ̀wò náà sì jẹ́ <1s; àpapọ̀ àkókò tí a lè fipamọ́ ~10s, ní ìfiwéra pẹ̀lú pípàdánù olùṣọ́ olówó-pọ́ọ́kú fún iṣẹ́ kọ̀ọ̀kan. Kò tọ́ ìrúkèrúdò náà. +- **`typecheck:noimplicit:core` lórí lint CI** — ✅ **a ti yọ ọ́ kúrò nínú iṣẹ́ lint** (ó jẹ́ `continue-on-error` ìmọ̀ràn); àyè type tó ń dí iṣẹ́ ni `typecheck:core` + `check:type-coverage`. A dá script agbègbè sílẹ̀. + +### Yípadà / pinnu (ìlànà olùṣàkóso) + +- `check:openapi-security-tiers` (ìmọ̀ràn) — ❌ **KÒ ṢEÉ yípadà ní mímọ́.** Ó jáde pẹ̀lú 0 ṣùgbọ́n ó kìlọ̀ pé ọ̀pọ̀ àwọn route `traffic-inspector` lábẹ́ `LOCAL_ONLY_API_PREFIXES` kò ní àkọsílẹ̀ `x-loopback-only: true`. Fífi agbára mú un nílò fífi àwọn àkọsílẹ̀ yẹn kún `openapi.yaml` lákọ̀ọ́kọ́. +- `typecheck:noimplicit:core` (ìmọ̀ràn) — ratchet `check:type-coverage` tó ń dí iṣẹ́ ti bo ọ́ púpọ̀. Yí i padà sí ratchet tàbí pa ìrìn `tsc` kejì tó tún ara rẹ̀ ṣe rẹ́. +- `test:vitest:ui` (tó jẹ́ **olùdènà** báyìí) — àwọn ìkùnà tó ti wà tẹ́lẹ̀ ni a yọ kúrò ní pàtó nínú `vitest.config.ts` pẹ̀lú àwọn àlàyé ìtọ́pasẹ̀ `// #8618`; àwọn ìkùnà tuntun máa ń mú kí iṣẹ́ náà kùnà. +- `check:secrets` (gitleaks, ratchet olùdènà tí a dì mọ́ àwọn false-positive 3 tí a ṣàkọsílẹ̀) — fi àwọn 3 náà sí allowlist láti dé 0, tàbí sọ ọ́ kalẹ̀ sí ìmọ̀ràn. Ó ní àgbélébùú pẹ̀lú secret-scanning abinibi GitHub + `check:public-creds`. +- `check:pr-evidence` (olùdènà, ń lo grep lórí ọ̀rọ̀ inú PR-body) — ewu false-positive ga; píparẹ́ rẹ̀ máa sọ ìmúlò Hard Rule #18 di aláìlágbára, nítorí náà èyí jẹ́ ìpinnu ìlànà gidi. +- `semgrep` (olóminira ìmọ̀ràn) — ó ní àgbélébùú pẹ̀lú CodeQL fún àwọn ẹbí OWASP; so baseline rẹ̀ mọ́ ratchet kan tàbí pa á rẹ́. --- diff --git a/docs/i18n/zh-CN/CONTRIBUTING.md b/docs/i18n/zh-CN/CONTRIBUTING.md index b59033b30a0..729c42ad401 100644 --- a/docs/i18n/zh-CN/CONTRIBUTING.md +++ b/docs/i18n/zh-CN/CONTRIBUTING.md @@ -404,16 +404,16 @@ docs/ - [ ] 代码检查通过(`npm run lint`) - [ ] 构建成功(`npm run build`) - [ ] 已为新的公共函数和接口添加 TypeScript 类型 -- [ ] 不含硬编码密钥或回退值 -- [ ] 通过 `resolvePublicCred()` 嵌入上游公共凭据(参阅 [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)),绝不使用字面量 -- [ ] 错误响应通过 `buildErrorBody()` / `sanitizeErrorMessage()` 处理——响应正文中不含原始堆栈跟踪(参阅 [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell 命令(`exec` / `spawn`)通过 `env` 而非字符串插值传递运行时值 -- [ ] 所有输入均使用 Zod 模式验证 -- [ ] 对于面向用户的更改,已在 `changelog.d/{features|fixes|maintenance}/-.md` 下添加变更日志**片段**(参阅 [`changelog.d/README.md`](./changelog.d/README.md))——**不要**直接编辑 `CHANGELOG.md`;片段会在发布时聚合,且不同 PR 之间绝不会发生冲突 +- [ ] 不包含硬编码的密钥或回退值 +- [ ] 公共上游凭据通过 `resolvePublicCred()` 嵌入(参见 [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)),绝不使用字面量 +- [ ] 错误响应通过 `buildErrorBody()` / `sanitizeErrorMessage()` 处理——响应正文中不得包含原始堆栈跟踪(参见 [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell 命令(`exec` / `spawn`)通过 `env` 传递运行时值,而不是使用字符串插值 +- [ ] 所有输入均使用 Zod schema 进行验证 +- [ ] 对于面向用户的更改,已在 `changelog.d/{features|fixes|maintenance}/-.md` 下添加变更日志**片段**(参见 [`changelog.d/README.md`](./changelog.d/README.md))——请勿直接编辑 `CHANGELOG.md`;片段会在发布时聚合,并且不同 PR 之间绝不会发生冲突 - [ ] 文档已更新(如适用) -- [ ] 未产生新的 CodeQL / Secret-Scanning 警报,或者每个警报均已驳回,并提供引用相关 `docs/security/` 文档的技术理由 -- [ ] 会生成子进程的路由(`/api/mcp/`、`/api/cli-tools/runtime/`)已在 `src/server/authz/routeGuard.ts` 中归类为 `isLocalOnlyPath()`——参阅[硬性规则 #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] 提交消息中不含 `Co-Authored-By` 尾注——提交必须仅显示在仓库所有者的 Git 身份下(硬性规则 #16) +- [ ] 未引入新的 CodeQL / Secret-Scanning 警报,或者每个警报均已驳回,并提供了引用相关 `docs/security/` 文档的技术理由 +- [ ] 会生成子进程的路由(`/api/mcp/`、`/api/cli-tools/runtime/`)已在 `src/server/authz/routeGuard.ts` 中归类为 `isLocalOnlyPath()`——参见[硬性规则 #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] 提交消息中不包含 AI/机器人 `Co-authored-by` 尾注(硬性规则 #16)——若复用了人类协作者的工作,则使用标准的 `Co-authored-by: Name ` 尾注注明其贡献 --- diff --git a/docs/i18n/zh-CN/docs/architecture/QUALITY_GATES.md b/docs/i18n/zh-CN/docs/architecture/QUALITY_GATES.md index c44bc0b1dc9..57db2900417 100644 --- a/docs/i18n/zh-CN/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/zh-CN/docs/architecture/QUALITY_GATES.md @@ -12,197 +12,200 @@ --- -## 门禁清单与执行配置 +## 门禁清单和执行配置 ### 候选版本准入 -CI 和 Quality Gates 工作流各自都会生成一个稳定的判定结果:`Gate / CI` 和 -`Gate / Quality`。其版本化准入策略会将每个上游作业列为必需项或建议项。所有适用的 -必需作业都必须成功:缺失、已取消、已跳过、待处理和未知结果均不能确定为 PASS。有效的 -仅文档或仅目录分类可以使代码通道不适用;草稿 PR 不属于可接受的候选版本。`hotfix` -标签不能免除证据要求。 +CI 和 Quality Gates 工作流分别生成稳定的判定结果:`Gate / CI` 和 +`Gate / Quality`。其版本化准入策略会将每个上游作业列为必需或建议。 +所有适用的必需作业都必须成功:缺失、已取消、已跳过、待处理和未知结果均无法确立 PASS。 +有效的仅文档或仅目录分类可以使代码通道不适用; +草稿 PR 不会被接受为候选版本。`hotfix` 标签不能免除证据要求。 这两个工作流均涵盖 PR、向 main/release 分支的推送、手动触发以及 -merge-group 事件。推送、手动触发和 merge-group 会运行完整选择。对于原本选择 -self-hosted runner 的作业,fork 和 merge group 会改用 hosted runner;在推广之前, -必须验证 hosted runner 容量是否充足。 +合并组事件。推送、手动触发和合并组会运行完整选择。对于原本选择自托管 +运行器的作业,复刻仓库和合并组会使用托管运行器;在推出前必须验证 +托管容量是否充足。 -每份 JSON 回执都会标识检出的 SHA、工作流运行及尝试次数。 -CLI 会拒绝检出 SHA 与事件 SHA 不匹配的情况。工作流测试会将策略成员关系绑定到 -判定作业的 `needs` 列表,因此新增或移除的通道无法静默消失。 -这些回执仅覆盖其所属工作流,不涵盖发布、部署或现有建议型扫描器的内部机制。 -在分支规则中启用这两个检查名称是一项独立的管理变更;添加这些作业本身并不会保护分支。 +每份 JSON 收据都会标识签出的 SHA、工作流运行及其尝试次数。 +CLI 会拒绝签出 SHA 与事件 SHA 不匹配的情况。工作流测试会将策略成员关系 +绑定到判定作业的 `needs` 列表,因此新增或移除的通道不会悄然消失。 +这些收据涵盖其自身工作流,但不涵盖发布、部署,也不涵盖现有建议型扫描器的 +内部实现。在分支规则中启用这两个检查名称是一项单独的管理变更; +添加这些作业本身并不会保护分支。 ### 静态扫描清单 -版本化的 npm 别名清单和静态扫描成员关系位于 -`config/quality/gate-manifest.json`。运行 `npm run check:gate-manifest`,对照 -`package.json` 验证脚本名称和精确命令;新增、移除和命令偏移都会导致本地钩子和 CI -中的变更分类作业失败。别名并非工作流作业、矩阵实例或测试用例:不得将这些计数表述为可互换。 +版本化 npm 别名清单和静态扫描成员关系位于 +`config/quality/gate-manifest.json`。运行 `npm run check:gate-manifest`, +以对照 `package.json` 验证脚本名称和准确命令;任何新增、移除和 +命令漂移都会导致本地钩子以及 CI 中的变更分类作业失败。 +别名并非工作流作业、矩阵实例或测试用例:不得将这些计数视为可互换。 使用 `npm run quality:scan -- --list` 或 `npm run quality:scan:fast -- --list` -可以检查选中的别名而不执行它们。运行器调用 npm 入口点,因此会保留其运行时 -(包括已配置的 Bun)。清单会将这些配置之外的别名记录为单独调用,并且只读扫描配置中 +可以在不执行的情况下检查所选别名。运行器会调用 npm 入口点, +因此其运行时(包括已配置的 Bun)会得以保留。 +清单会将这些配置之外的别名记录为单独调用,并且只读扫描配置中 禁止使用维护命令。 -这些配置仅涵盖静态扫描。它们不对产品测试、覆盖率、打包、外部检查或候选版本的完整发布准入 -进行认证。工作流准入使用关联的 `config/quality/admission-policy.json` 和 -`scripts/quality/admission-verdict.mjs`。发布观察器配置仍保持独立; -请分别检查其适用的检查项和回执。下方的文字清单仅供参考,不能证明门禁实际运行过。 +这些配置仅涵盖静态扫描。它们不认证产品测试、覆盖率、打包、 +外部检查或候选版本的完整发布验收。工作流准入使用关联的 +`config/quality/admission-policy.json` 和 +`scripts/quality/admission-verdict.mjs`。发布观察器配置仍然独立; +请分别检查其适用检查项和收据。下方的文字清单仅供参考, +不能证明门禁实际运行过。 脚本位于 `scripts/check/`(策略门禁)和 `scripts/quality/`(棘轮引擎)下。 CI 的事实来源是 `.github/workflows/ci.yml`。 ### 发布 PR 快速路径(`quality.yml`) -`.github/workflows/quality.yml` 是 CI 的补充,适用于 main/release PR、向受保护分支的 -推送、手动触发和 merge group。PR 使用经过路径筛选的快速检查。已永久禁用的重复构建已被移除; -真正的构建、打包和启动检查仍保留在 CI 中。 +`.github/workflows/quality.yml` 为 main/release PR、受保护分支推送、 +手动触发和合并组补充 CI。PR 使用按路径筛选的快速检查。 +已移除永久禁用的重复构建;实际的构建/打包/启动检查仍保留在 CI 中。 -| 作业 | 范围 | 阻断性 | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ------------- | -| `Docs Gates (fast-path)` | 文档/代码 PR;API 文档引用和全部文档 | 是 | -| `Fast Quality Gates` | 代码 PR;静态检查、类型检查、仪表板类型检查、受影响的单元测试 | 是 | -| `Forgotten sibling tests` | 代码 PR;将已变更模块追踪到静态使用方和候选同级测试;barrel 和动态导入路径会作为建议性诊断报告,并包含引用的允许列表例外 | **建议性** | -| `Vitest (fast-path)` | 代码 PR;快速 vitest 测试套件 | 是 | -| `Unit Tests fast-path` | 代码 PR;4 分片单元测试套件 | 是 | -| `No new ESLint warnings` | 代码 PR;可识别抑制项的 lint 防护 | 是,包括 fork | -| `Merge integrity (changelog + generated skills)` | 非草稿 PR;变更日志和生成的 skill 同步 | 是,包括 fork | +| 作业 | 范围 | 阻断性 | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `Docs Gates (fast-path)` | 文档/代码 PR;API 文档引用和全部文档 | 是 | +| `Fast Quality Gates` | 代码 PR;静态检查、类型检查、仪表板类型检查、受影响的单元测试 | 是 | +| `Forgotten sibling tests` | 代码 PR;将已更改模块追踪到静态使用方和候选同级测试;桶文件和动态导入路径会作为建议性诊断报告,并包含引用的允许列表例外 | **建议性** | +| `Vitest (fast-path)` | 代码 PR;快速 vitest 测试套件 | 是 | +| `Unit Tests fast-path` | 代码 PR;4 分片单元测试套件 | 是 | +| `No new ESLint warnings` | 代码 PR;感知抑制规则的 lint 防护 | 是,包括复刻仓库 | +| `Merge integrity (changelog + generated skills)` | 非草稿 PR;变更日志和生成的技能同步 | 是,包括复刻仓库 | #### 遗漏的同级测试报告 -`npm run check:forgotten-sibling-tests` 会复用测试影响映射所使用的导入解析器。 -对于每个已变更的生产模块,当候选测试未出现在 pull request 差异中时,它会报告确定性的 -`已变更模块/符号 -> 静态使用方 -> 候选同级测试` 链。Markdown 摘要和 JSON 结果会作为 -`forgotten-sibling-tests` 工作流工件保留,用于在任何阻断性推广之前进行校准。 - -桶文件重导出和动态导入仅用于解析诊断;它们绝不会产生阻塞性发现。经审核的例外位于 -`config/quality/forgotten-sibling-allowlist.json`。每个条目都必须指定使用方和候选 -测试,给出具体理由,并链接至 GitHub issue 或 pull request。格式错误的条目将按失败处理。 -例外无法抑制已删除的候选测试,也无法抑制新增 `.skip`/`.todo` 的差异; -断言弱化及其他掩盖行为仍由独立阻塞的 +`npm run check:forgotten-sibling-tests` 会复用测试影响映射背后的导入解析器。 +对于每个已更改的生产模块,当候选测试未出现在拉取请求差异中时,它会报告确定性的 +`已更改模块/符号 -> 静态使用方 -> 候选同级测试` 链。 +Markdown 摘要和 JSON 结果会作为 `forgotten-sibling-tests` 工作流工件保留, +以便在任何阻断性推广之前进行校准。 + +桶式重导出和动态导入仅用于解析诊断;它们绝不会产生 +阻塞性发现。经审核的例外位于 +`config/quality/forgotten-sibling-allowlist.json`。每个条目都必须指明使用方和候选 +测试,提供具体理由,并链接到 GitHub issue 或 pull request。格式错误的条目将按拒绝处理。 +例外无法忽略已删除的候选测试,也无法忽略新增 `.skip`/`.todo` 的差异; +断言弱化和其他掩盖行为仍由独立阻塞的 `check:test-masking` 门禁负责。 ### 作业:`lint` 在每个提交到 `main` 的 PR 上运行。失败时阻止合并。 -| 脚本 (`npm run ...`) | 验证内容 | 是否阻塞 | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Node.js 版本是否在支持的范围内 | 是 | -| `check:cycles` | 循环导入 — 所有 `src/` + `open-sse/` 模块 | 是 | -| `check:route-validation:t06` | 所有路由上均存在 Zod schema(第 6 层策略) | 是 | -| `check:any-budget:t11` | `@ts-expect-error // any` 的数量不超过预算(第 11 层 catraca) | 是 | -| `check:provider-consistency` | `providers.ts` 中的每个提供者在 `providerRegistry.ts` 中都有匹配的条目(反之亦然,但仅限允许列表范围内) | 是 | -| `check:model-lifecycle` | 三个手工维护的路由表与已签入的生命周期快照(#11503)保持一致:`FITNESS_TABLE`(`taskFitness.ts`)不会为 `REGISTRY` 可路由的任何已停用 id 评分;每个 `BUILT_IN_ALIASES` 目标都存在于 `REGISTRY` 中,且不在已停用 id 快照中;`REGISTRY` 中仍存在的每个已停用 id 都会被转发或列入 `allowedRetiredInCatalog`;并且 `DEFAULT_DEGRADATION_MAP` 的源或目标均未在该快照中标记为已停用。这并不能证明某个模型当前正由在线上游提供服务。离线检查——与 `config/quality/model-lifecycle.json` 比较;该文件通过 `npm run quality:refresh-model-lifecycle` 手动刷新(需要网络;未接入 CI)。`allowedRetiredInCatalog` 是一种逐步清零的棘轮机制:仅在有关联的跟踪 issue 时才可添加条目。 | 是 | -| `check:fetch-targets` | 客户端 `src/` 中的每个 `fetch("/api/...")` 都会解析到真实存在的 `route.ts` | 是 | -| `check:deps` | 仓库中每个 `package.json` 内所有可通过 `npm install` 安装的依赖项都位于 `dependency-allowlist.json` 中;新增的未固定版本或疑似拼写抢注的软件包会被标记 | 是 | -| `audit:deps` | `npm audit`(根目录 + electron)——无高危/严重级别的安全公告(与 osv `check:vuln-ratchet` 重叠;请参阅合理化待办事项) | 是 | -| `check:lockfile` | `package-lock.json` 完整性——使用 https 注册表、包含完整性哈希、无主机覆盖 | 是 | -| `check:licenses` | 生产依赖项的 SPDX 许可证允许列表 | 是 | -| `check:tracked-artifacts` | 不允许存在构建产物或已提交的 `node_modules` 符号链接(也会在 husky pre-commit 中运行;pre-push 有意保持轻量——#6716) | 是 | -| `check:ai-attribution` | PR 提交、标题或正文中不得包含 AI/机器人 `Co-Authored-By` 尾注或 AI 生成页脚——硬性规则 #16(在针对 PR→`release/**` 的 `quality.yml` 快速门禁循环中——读取事件负载,在非 PR 情况下不执行任何操作——以及针对 PR→`main` 的 `ci.yml` lint 中仅限 PR 的步骤;也包括 husky `commit-msg` 钩子;允许人类共同作者;#14436) | -| `check:vitest-exclusions` | 每个 Vitest 排除项都必须注明一个跟踪议题,并出现在 `config/quality/vitest-exclusions.json` 中(#13204) | 是 | -| `check:file-size` | 任何源文件都不得超过其扩展名对应的上限(棘轮机制:大型文件冻结在 `frozen` 列表中) | 是 | -| `check:error-helper` | 执行器/处理程序中的错误响应须使用 `buildErrorBody()` / `sanitizeErrorMessage()`(硬性规则 #12) | 是 | -| `check:migration-numbering` | Migration SQL 文件按顺序编号,无缺号或重复编号 | 是 | -| `check:public-creds` | 除 `publicCreds.ts` 外,不得出现字面量 OAuth `client_id`/`client_secret` 或 Firebase Web 密钥(硬性规则 #11) | 是 | -| `check:db-rules` | `src/lib/db/` 模块之外不得出现原始 SQL;不得从 `localDb.ts` 进行桶导入(硬性规则 #2/#5) | 是 | -| `check:known-symbols` | 在各自分发表中注册的提供者执行器、路由策略和转换器必须与磁盘上的文件匹配——不得存在孤立或未声明的符号 | 是 | -| `check:route-guard-membership` | 每个会生成子进程的路由都必须由 `isLocalOnlyPath()` 进行分类(硬性规则 #15/#17) | 是 | -| `check:test-discovery` | 仓库中的每个 `*.test.ts` / `*.spec.ts` 文件都必须由至少一个测试运行器收集(棘轮机制:`test-discovery-baseline.json` 中的孤立文件列表只能缩短) | 是 | -| `check:agent-skills-sync` | 生成的 agent-skills 工件与其源目录一致(无偏移) | -| `check:provider-asset-provenance` | Provider 徽标/资源包含已记录的来源条目 | -| `lint:json` | JSON 配置文件可被解析,并符合仓库的 lint 规则 | -| `typecheck:core` | TypeScript 编译无错误(仅有建议性警告) | 是 | -| `typecheck:noimplicit:core` | 严格的 `noImplicitAny`——面向未来;许多已有调用点仍需添加注解 | **建议性**(`continue-on-error: true`) | -| `check:dashboard-typecheck` | 范围限定为 `src/app/(dashboard)/**` 的 `tsc`(#7033)——`typecheck:core` 精选的 27 文件允许列表不包含任何 dashboard TSX,而 `next build` 也从不对其进行类型检查(`next.config.mjs` 设置了 `ignoreBuildErrors: true`),因此其中的孤立标识符回归(#6625/#6909)对 CI 不可见。与按文件/TS 代码计数的冻结基线(`config/quality/dashboard-typecheck-baseline.json`,采用与 `check:known-symbols` 相同的过期强制检查模式)进行差异比较——只有超出基线计数的新增错误才会导致门禁失败;修复已有错误后,使用 `--update` 逐步下调基线。 | 是 | +| 脚本(`npm run ...`) | 验证内容 | 阻塞性 | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Node.js 版本位于支持的范围内 | 是 | +| `check:cycles` | 检查整个 `src/` + `open-sse/` 中的循环导入(基于 AST,并解析 tsconfig `paths`)。单独运行时仅提供建议,并列出循环。`check:cycles:ratchet`(CI 实际运行的命令)会在数量超过 `quality-baseline.json` 中的 `metrics.cycles` 上限时阻塞——当前上限为 14,`direction: down`,因此该值只能下降(#15159 G-01/G-02) | 是(棘轮式) | +| `check:route-validation:t06` | 所有路由都存在 Zod schema(第 6 层策略) | 是 | +| `check:any-budget:t11` | `@ts-expect-error // any` 的数量不超过预算(第 11 层棘轮机制) | 是 | +| `check:provider-consistency` | `providers.ts` 中的每个提供者在 `providerRegistry.ts` 中都有匹配的条目(反之亦然,但仅限允许列表范围内) | 是 | +| `check:model-lifecycle` | 三个人工维护的路由表与已签入的生命周期快照 (#11503) 保持一致:`FITNESS_TABLE` (`taskFitness.ts`) 不会为 `REGISTRY` 可路由的任何已停用 id 评分;每个 `BUILT_IN_ALIASES` 目标都存在于 `REGISTRY` 中,且不存在于已停用 id 快照中;`REGISTRY` 中仍存在的每个已停用 id 均已被转发或列入 `allowedRetiredInCatalog`;并且 `DEFAULT_DEGRADATION_MAP` 的源或目标都未在该快照中显示为已停用。这并不能证明某个模型当前正由在线上游提供服务。离线检查——与 `config/quality/model-lifecycle.json` 进行比较,该文件通过 `npm run quality:refresh-model-lifecycle` 手动刷新(需要网络;未接入 CI)。`allowedRetiredInCatalog` 是一个只减不增的棘轮机制:仅在有关联的跟踪 issue 时才添加条目。 | 是 | +| `check:fetch-targets` | 客户端 `src/` 中的每个 `fetch("/api/...")` 都会解析到真实的 `route.ts` | 是 | +| `check:deps` | 仓库中每个 `package.json` 里所有可通过 `npm install` 安装的依赖项均存在于 `dependency-allowlist.json` 中;新增的未固定版本或疑似拼写抢注的软件包会被标记 | 是 | +| `audit:deps` | `npm audit`(根目录 + electron)——无高危/严重级别的安全公告(与 osv `check:vuln-ratchet` 重叠;参见合理化待办事项) | 是 | +| `check:lockfile` | `package-lock.json` 完整性——使用 https 注册表、包含完整性哈希、无主机覆盖 | 是 | +| `check:licenses` | 生产依赖项的 SPDX 许可证允许列表 | 是 | +| `check:tracked-artifacts` | 不存在构建产物/已提交的 `node_modules` 符号链接(也在 husky pre-commit 中运行;pre-push 有意保持轻量 — #6716) | 是 | +| `check:ai-attribution` | PR 提交、标题或正文中不得包含 AI/机器人 `Co-Authored-By` 尾注或 AI 生成页脚 — 强制规则 #16(位于 `quality.yml` 针对 PR→`release/**` 的快速门禁循环中 — 读取事件负载,在非 PR 情况下不执行任何操作 — 以及 `ci.yml` lint 中仅针对 PR→`main` 的步骤;也包括 husky `commit-msg` 钩子;允许人类共同作者;#14436) | +| `check:vitest-exclusions` | 每个 Vitest 排除项都需注明跟踪 issue,并出现在 `config/quality/vitest-exclusions.json` 中(#13204) | 是 | +| `check:file-size` | 源文件不得超过各扩展名对应的大小上限(棘轮机制:`frozen` 列表中冻结的大文件) | 是 | +| `check:error-helper` | 执行器/处理器中的错误响应使用 `buildErrorBody()` / `sanitizeErrorMessage()`(强制规则 #12) | 是 | +| `check:migration-numbering` | Migration SQL 文件按顺序编号,无间断或重复 | 是 | +| `check:public-creds` | 除 `publicCreds.ts` 外,不得出现字面量 OAuth `client_id`/`client_secret` 或 Firebase Web 密钥(硬性规则 #11) | 是 | +| `check:db-rules` | `src/lib/db/` 模块之外不得出现原始 SQL;不得从 `localDb.ts` 进行桶式导入(硬性规则 #2/#5) | 是 | +| `check:known-symbols` | 在各自分派表中注册的提供者执行器、路由策略和转换器必须与磁盘上的文件匹配——不得存在孤立或未声明的符号 | 是 | +| `check:route-guard-membership` | 每个会生成子进程的路由都必须由 `isLocalOnlyPath()` 进行分类(硬性规则 #15/#17) | 是 | +| `check:test-discovery` | 仓库中的每个 `*.test.ts` / `*.spec.ts` 文件都必须由至少一个测试运行器收集(棘轮机制:`test-discovery-baseline.json` 中的孤立文件列表只能缩短) | 是 | +| `check:agent-skills-sync` | 生成的 agent-skills 构件与其源目录一致(无漂移) | +| `check:provider-asset-provenance` | Provider 徽标/资源具有已记录的来源条目 | +| `lint:json` | JSON 配置文件可成功解析并符合仓库的 lint 规则 | +| `typecheck:core` | TypeScript 编译无错误(仅有提示性警告) | 是 | +| `typecheck:noimplicit:core` | 严格执行 `noImplicitAny`——面向未来;许多既有调用点仍需添加注解 | **提示性**(`continue-on-error: true`) | +| `check:dashboard-typecheck` | 针对 `src/app/(dashboard)/**` 范围运行 `tsc`(#7033)——`typecheck:core` 精选的 27 个文件白名单不包含任何 dashboard TSX,且 `next build` 也从不对其进行类型检查(`next.config.mjs` 设置了 `ignoreBuildErrors: true`),因此其中的孤立标识符回归(#6625/#6909)对 CI 不可见。与按文件/TS 错误代码计数的冻结基线(`config/quality/dashboard-typecheck-baseline.json`,采用与 `check:known-symbols` 相同的陈旧项强制检查模式)进行差异比较——只有超出基线计数的新增错误才会导致门禁失败;修复既有错误后,使用 `--update` 逐步降低基线。 | 是 | ### 作业:`quality-gate` 在 `test-coverage` 之后运行。失败时阻止合并。 -| 脚本 | 验证内容 | 阻塞性 | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| `quality:collect` | 生成 `quality-metrics.json`(ESLint 警告数量、来自合并分片报告的覆盖率) | 是(ratchet 的上游步骤) | -| `quality:ratchet` | `quality-baseline.json` 中的每项指标均未退化(ESLint 警告数 ≤ 基线;覆盖率 ≥ 基线) | 是 | -| `check:duplication` | 代码重复度(jscpd@4)不超过 `quality-baseline.json` 中的基线 | 是 | -| `check:complexity` | 文件级圈复杂度不超过上限(核心 ESLint `complexity` + `max-lines-per-function`) | 是 | -| `check:cognitive-complexity` | 认知复杂度 ratchet(`eslint-plugin-sonarjs`)——单独执行 ESLint;CI 将两者合并为单个 `check:complexity-ratchets` 步骤运行 | 是 | -| `check:dead-code` | 未使用的导出/文件 ratchet(knip)相较基线未退化 | 是 | -| `check:compression-budget` | 压缩基准预算——各引擎的 token 节省量下限不得退化 | 是 | -| `check:type-coverage` | 类型标注百分比 ratchet(`type-coverage`)未退化;基本涵盖 `typecheck:noimplicit:core` | 是 | -| `check:codeql-ratchet` | 未解决的 CodeQL 警报数量未增加(通过 `gh api` 读取;无 token 时平稳跳过)——刷新频率和手动触发方式:请参阅下方的“CodeQL ratchet” | 是 | +| 脚本 | 验证内容 | 阻塞性 | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `quality:collect` | 生成 `quality-metrics.json`(ESLint 警告数、合并分片报告中的覆盖率) | 是(位于棘轮检查的上游) | +| `quality:ratchet` | `quality-baseline.json` 中的各项指标均未退化(ESLint 警告数 ≤ 基线;覆盖率 ≥ 基线) | 是 | +| `check:duplication` | 代码重复率(jscpd@4)不超过 `quality-baseline.json` 中的基线 | 是 | +| `check:complexity` | 文件级圈复杂度不超过上限(核心 ESLint `complexity` + `max-lines-per-function`) | 是 | +| `check:cognitive-complexity` | 认知复杂度棘轮检查(`eslint-plugin-sonarjs`)— 单独执行 ESLint;CI 将两项检查合并为单个 `check:complexity-ratchets` 步骤运行 | 是 | +| `check:dead-code` | 未使用的导出/文件棘轮检查(knip)相对于基线没有退化 | 是 | +| `check:compression-budget` | 压缩基准预算 — 各引擎的令牌节省下限不得退化 | 是 | +| `check:type-coverage` | 类型标注百分比棘轮检查(`type-coverage`)没有退化;基本涵盖 `typecheck:noimplicit:core` | 是 | +| `check:codeql-ratchet` | 未解决的 CodeQL 警报数量没有增加(通过 `gh api` 读取;无令牌时正常跳过)— 刷新频率和手动触发方式:参见下方的“CodeQL 棘轮检查” | 是 | ### 作业:`quality-extended` -整个作业均为建议性检查(`continue-on-error: true`)。基于 npm 的 ratchet 会实际运行; -外部扫描器通过 `gh release download` 安装,当二进制文件仍不存在时会自行跳过(退出码为 0)。 +整个作业仅提供建议(`continue-on-error: true`)。基于 npm 的棘轮检查会实际运行; +外部扫描器通过 `gh release download` 安装,并在二进制文件仍不存在时自行跳过(退出码为 0)。 -| 脚本 | 验证内容 | 阻塞性 | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:circular-deps` | 不存在循环依赖(dpdm) | **建议性** | -| `check:bundle-size` | 包体积不超过上限 | **建议性** | -| `check:secrets` | 密钥扫描(gitleaks)——二进制文件不存在时跳过 | **建议性** | -| `check:vuln-ratchet` | 依赖项漏洞(osv-scanner)未退化——二进制文件不存在时跳过 | **建议性** | -| `check:workflows` | 工作流 lint(actionlint + zizmor);扫描器缺失/损坏、报告无效或 ratchet 基线缺失时,将以 INCOMPLETE 状态失败。有效发现遵循所选的严格/建议性/ratchet 策略 | 必须执行;zizmor ratchet 在 CI 中具有阻塞性 | -| `check:openapi-breaking` | 公共 API 契约(`openapi.yaml`)相对于基础分支的破坏性变更(oasdiff)——生成 `openapiBreaking=N`;若 oasdiff 不存在或无法解析基础规范,则跳过 | **建议性** | +| 脚本 | 验证内容 | 阻塞性 | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| `check:circular-deps` | 不存在循环依赖(dpdm) | **建议性** | +| `check:bundle-size` | 包大小不超过上限 | **建议性** | +| `check:secrets` | 密钥扫描(gitleaks)— 二进制文件不存在时跳过 | **建议性** | +| `check:vuln-ratchet` | 依赖项漏洞(osv-scanner)没有增加 — 二进制文件不存在时跳过 | **建议性** | +| `check:workflows` | 工作流 lint 检查(actionlint + zizmor);扫描器缺失/损坏、报告无效或棘轮基线缺失时,以 INCOMPLETE 状态失败。有效发现遵循选定的严格/建议性/棘轮策略 | 必须执行;zizmor 棘轮检查在 CI 中具有阻塞性 | +| `check:openapi-breaking` | 检查公共 API 契约(`openapi.yaml`)相对于基础分支的破坏性变更(oasdiff)— 输出 `openapiBreaking=N`;oasdiff 不存在或基础规范无法解析时跳过 | **建议性** | ### 作业:`docs-sync-strict` -在每个提交到 `main` 的 PR 上运行。失败时阻止合并。 - -| 脚本 | 验证内容 | 阻断性 | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `check:docs-all` | 作为元门禁,依次运行下方 6 个子门禁 | 是 | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt 版本一致性 | 是 | -| ↳ `check:docs-counts` | 文档正文中的数量(提供者数量、迁移数量等)处于实际数量的棘轮窗口内 | 是 | -| ↳ `check:env-doc-sync` | `.env.example` 中的每个环境变量均记录在文档表格中,反之亦然 | 是 | -| ↳ `check:deprecated-versions` | 文档中不存在已弃用的版本字符串 | 是 | -| ↳ `check:doc-links` | 文档中的内部 markdown 链接可解析到实际文件(`[text]`/`(path)` 形式) | 是 | -| ↳ `check:fabricated-docs` | 文档中引用的路由、环境变量、CLI 命令、钩子名称和文件路径均存在于代码库中。使用 `--strict` 时为硬门禁;不使用该标志时允许软失败。 | 是(CI 中通过 `--strict`) | -| `check:cli-i18n` | 所有 i18n 区域设置文件中均存在 CLI 命令字符串 | 是 | -| `check:openapi-coverage` | OpenAPI 规范至少覆盖实际路由数量的棘轮下限 | 是 | -| `check:openapi-security-tiers` | `openapi.yaml` 中的安全层级注解与 `routeGuard.ts` 中的分类一致 | **建议性** | -| `check:openapi-routes` | `openapi.yaml` 中的每个路径都可解析到真实的 `route.ts`(防止臆造) | 是 | -| `check:docs-symbols` | `docs/**/*.md` 中的每个 `/api/...` 引用都可解析到真实的 `route.ts`(防止臆造) | 是 | -| `i18n translation drift` | i18n 区域设置文件中未翻译的键——仅警告 | **建议性** | +在每个以 `main` 为目标分支的 PR 上运行。失败时阻止合并。 + +| 脚本 | 验证内容 | 阻塞性 | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `check:docs-all` | 元门禁,依次运行下方 6 个子门禁 | 是 | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt 版本一致性 | 是 | +| ↳ `check:docs-counts` | 文本中的数量(提供者数量、迁移数量等)处于实际数量的棘轮窗口范围内 | 是 | +| ↳ `check:env-doc-sync` | `.env.example` 中的每个环境变量都记录在文档表格中,反之亦然 | 是 | +| ↳ `check:deprecated-versions` | 文档中不存在已弃用的版本字符串 | 是 | +| ↳ `check:doc-links` | 文档中的内部 markdown 链接可解析到实际文件(`[text]`/`(path)` 形式) | 是 | +| ↳ `check:fabricated-docs` | 文档中引用的路由、环境变量、CLI 命令、钩子名称和文件路径均存在于代码库中。使用 `--strict` 时为硬门禁;不带该标志时为软失败。 | 是(CI 中通过 `--strict`) | +| `check:cli-i18n` | 所有 i18n 区域设置文件中均存在 CLI 命令字符串 | 是 | +| `check:openapi-coverage` | OpenAPI 规范覆盖的实际路由数量至少达到棘轮式下限 | 是 | +| `check:openapi-security-tiers` | `openapi.yaml` 中的安全层级注解与 `routeGuard.ts` 的分类一致 | **建议性** | +| `check:openapi-routes` | `openapi.yaml` 中的每个路径都可解析到真实的 `route.ts`(防止虚构) | 是 | +| `check:docs-symbols` | `docs/**/*.md` 中的每个 `/api/...` 引用都可解析到真实的 `route.ts`(防止虚构) | 是 | +| `i18n translation drift` | i18n 区域设置文件中未翻译的键——仅警告 | **建议性** | ### 作业:`i18n-ui-coverage` -| 脚本 | 验证内容 | 阻断性 | -| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check-ui-keys-coverage`(内联) | UI i18n 键覆盖率 ≥ 65% | 是 | -| `check-ui-value-drift`(内联) | 重写英文**值**后,不会遗留过时的翻译 | 是 | -| `check-new-key-coverage`(内联) | **新增的**英文键在每个区域设置中均已翻译——拒绝 `__MISSING__:` 标记 | 是 | -| `check-translation-ratio` | 每个区域设置的真实翻译比例(与英文相同的内容 / 占位符 / 白名单之外的缺失叶节点)不得超过 `config/quality/i18n-translation-baseline.json` + 宽限值 | **建议性** | +| 脚本 | 验证内容 | 阻塞性 | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check-ui-keys-coverage`(内联) | UI i18n 键覆盖率 ≥ 65% | 是 | +| `check-ui-value-drift`(内联) | 重写后的英文**值**不会留下陈旧的翻译 | 是 | +| `check-new-key-coverage`(内联) | **新增的**英文键已在每个区域设置中翻译——拒绝 `__MISSING__:` 标记 | 是 | +| `check-translation-ratio` | 每个区域设置的真实翻译比率(允许列表之外与英文相同、占位符或缺失的叶节点)不得超过 `config/quality/i18n-translation-baseline.json` + 宽限值 | **建议性** | 需要 `fetch-depth: 0`——值漂移门禁会将 `en.json` 与合并基准进行差异比较。 -#### `check-ui-value-drift`——过时翻译门禁 +#### `check-ui-value-drift`——陈旧翻译门禁 -用于捕获其他门禁在结构上无法发现的一类 i18n 回归:英文值 -被重写,但基于_先前_英文内容生成的翻译仍然保留,导致 -非英语用户继续阅读措辞笃定、但现已错误的文案。 +它能够捕获其他门禁从结构上无法发现的一类 i18n 回归:英文值已被重写,但基于_先前_英文生成的翻译仍被保留下来,导致非英语用户继续阅读措辞笃定但现已错误的文案。 -这曾真实发布到生产环境中。Antigravity -登录辅助功能上线时(#5203),`oauthModal.googleOAuthWarning` 被重写;**43 个区域设置中有 39 个** -仍保留着提示运维人员“复制完整 URL 并粘贴到下方”的文本——对于该提供者,这一流程根本无法完成。直到 #8463 才发现该问题,原因如下: +这个问题确实曾发布到生产环境。引入 Antigravity 登录辅助工具(#5203)时,`oauthModal.googleOAuthWarning` 被重写;**43 个区域设置中有 39 个**仍保留着要求运维人员“复制完整 URL 并将其粘贴到下方”的文本——对于该提供者,此流程根本无法完成。直到 #8463 才发现这一问题,原因如下: -- `sync-ui-keys` 只补全**缺失**的键,从不处理**过时**的键; -- `check-ui-keys-coverage` 统计键是否_存在_,因此过时翻译仍会被计为已覆盖; +- `sync-ui-keys` 只会回填**缺失**的键,而不会处理**陈旧**的键; +- `check-ui-keys-coverage` 统计键是否_存在_,因此陈旧翻译仍会被计为已覆盖; - `check-translation-drift` 跟踪的是 `docs/i18n//**.md` 文档镜像—— - 它从不读取 `src/i18n/messages/*.json`。自 2026-09 重新同步以来,该检查在作业 `docs-sync-strict` 中具有阻断性:编辑核心文档 → `npm run i18n:run -- --files=`(按章节执行,开销较低)。 + 它从不读取 `src/i18n/messages/*.json`。自 2026-09 重新同步以来,它在作业 `docs-sync-strict` 中具有阻塞性:编辑核心文档 → `npm run i18n:run -- --files=`(按章节处理,开销较低)。 -**感知差异,而非依赖基线。** 它会比较合并基点处的 `en.json` 与工作树;对于英语值发生变化的每个键,任何仍保留未修改译文的语言区域都将被视为过时。这有意**冻结了既有债务**——差异无法揭示长期存在的译文源自哪个旧英语文本,因此该门禁只判断当前变更所涉及的内容。另一种方案(为每个键维护哈希基线)会产生一个约 600 KB 的生成文件,是现有最大基线的 3 倍,并且会在每个 i18n PR 中频繁变动。 +**感知差异,而非依赖基线。** 它会将合并基点处的 `en.json` 与工作树进行比较;对于英文值发生变化的每个键,任何仍保留未修改译文的语言区域都将被视为过期。此机制有意**冻结既有欠账**——差异无法揭示长期存在的译文源自哪个旧英文文本,因此该门禁仅判断当前变更所涉及的内容。另一种方案(逐键哈希基线)会产生一个约 600 KB 的生成文件,是现有最大基线的 3 倍,并且会在每个 i18n PR 中频繁变动。 -有两种方式可以满足要求: +有两种方式可满足此门禁: 1. 更新受影响的译文,或 -2. 将其设置为 `__MISSING__:`——随后运行时会提供修正后的英语文本 +2. 将其设置为 `__MISSING__:<新英文文本>`——随后运行时会提供修正后的英文文本 (`src/i18n/request.ts::deepMergeFallback`,#7258),并将该键加入待翻译队列。 -如果字符串的**含义**发生了变化,优先考虑**重命名该键**:新键不会继承过时的译文。这正是 #8463 所采用的模式。 +如果字符串的**含义**发生了变化,优先考虑**重命名键**:新键不会继承过期的译文。这正是 #8463 使用的模式。 ```bash npm run i18n:check-value-drift # 严格模式(CI 运行的模式) @@ -210,11 +213,11 @@ npm run i18n:check-value-drift:warn # 仅报告 BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -当无法读取基础目录(浅克隆中没有基础引用)时,以状态码 0 退出并输出 `SKIP reason=base-unresolved`,与 `check-openapi-breaking` 的行为一致。 +当无法读取基础目录时(浅克隆中没有基础引用),以状态码 0 退出并输出 `SKIP reason=base-unresolved`,与 `check-openapi-breaking` 的行为一致。 ### 作业:`i18n` -完整的 i18n 验证矩阵(每个语言区域一个作业)。整个作业均为建议性检查。 +完整的 i18n 验证矩阵(每个语言区域一个作业)。整个作业仅提供建议,不阻塞合并。 | 脚本 | 验证内容 | 是否阻塞 | | ------------------------------- | ------------------------ | ------------------------------------------------------ | @@ -224,33 +227,33 @@ BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift 仅在拉取请求上运行。 -| 脚本 | 验证内容 | 是否阻塞 | -| ---------------------- | ------------------------------------------------------------------------------------------------------ | -------- | -| `check:pr-test-policy` | 修改 `src/`、`open-sse/`、`electron/` 或 `bin/` 中生产代码的 PR 必须包含或更新测试(硬性规则 #8) | 是 | -| `check:test-masking` | 变更后的测试文件不会减少断言净数量,也不会添加 `assert.ok(true)` 这类恒真断言 | 是 | -| `check:pr-evidence` | PR 正文引用该变更的测试/VPS 证据(通过 grep 检索 PR 文本来自动执行硬性规则 #18——较脆弱,参见待办事项) | 是 | +| 脚本 | 验证内容 | 是否阻塞 | +| ---------------------- | -------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | 修改 `src/`、`open-sse/`、`electron/` 或 `bin/` 中生产代码的 PR 必须包含或更新测试(硬性规则 #8) | 是 | +| `check:test-masking` | 变更的测试文件不得减少断言净数量,也不得添加 `assert.ok(true)` 这类恒真断言 | 是 | +| `check:pr-evidence` | PR 正文需列出该变更的测试/VPS 证据(通过 grep PR 文本将硬性规则 #18 机制化——较脆弱,参见待办事项) | 是 | ### 作业:`test-vitest` 在 `build` 之后运行。失败时阻止合并。 -| 测试套件 | 验证内容 | 是否阻塞 | -| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------- | -| `test:vitest` | MCP 服务器(110 个工具)、autoCombo、缓存——vitest 运行器 | 是 | -| `test:vitest:ui` | UI 组件测试——vitest 运行器 | **阻塞**——`vitest.config.ts` 中已明确排除既有失败;新增失败会导致作业失败 | +| 测试套件 | 验证内容 | 是否阻塞 | +| ---------------- | -------------------------------------------------------- | ----------------------------------------------------------------------- | +| `test:vitest` | MCP 服务器(110 个工具)、autoCombo、缓存——vitest 运行器 | 是 | +| `test:vitest:ui` | UI 组件测试——vitest 运行器 | **阻塞**——`vitest.config.ts` 中明确排除了既有失败;新失败会导致作业失败 | -### 每夜工作流(定时运行,建议性) +### 夜间工作流(定时运行、建议性) -这些工作流按 cron 计划运行(也可通过 `workflow_dispatch` 运行),绝不会在 PR 上运行。所有工作流均为建议性。 +这些工作流按 cron 计划运行(也可通过 `workflow_dispatch` 运行),从不在 PR 上运行。它们均为建议性检查。 -| 工作流 | 验证内容 | 是否阻塞 | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `nightly-property` | 使用随机种子和高运行次数的 fast-check 属性测试 | **建议性** | -| `nightly-resilience` | 堆增长门禁、混沌故障注入、k6 负载/浸泡测试 | **建议性** | -| `nightly-llm-security` | promptfoo 注入防护(阻止模式)+ garak 探测(没有提供者密钥时跳过) | **建议性** | -| `nightly-schemathesis` | 使用 `docs/openapi.yaml` 针对实时 OmniRoute 进行 OpenAPI 契约模糊测试(schemathesis)——揭示规范违规/未处理的 500 错误(阶段 8 B.4) | **建议性** | -| `nightly-mutation` | 对快速单元测试通道执行 Stryker 变异测试评分——存活的变异体会暴露薄弱的断言 | **建议性** | -| `nightly-compat` | 跨受支持的 `engines.node` 范围执行 Node 引擎兼容性矩阵 | **建议性** | +| 工作流 | 验证内容 | 是否阻塞 | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `nightly-property` | 使用随机种子和高运行次数的 fast-check 属性测试 | **建议性** | +| `nightly-resilience` | 堆增长门禁、混沌故障注入、k6 负载/浸泡测试 | **建议性** | +| `nightly-llm-security` | promptfoo 注入防护(阻止模式)+ garak 探测(没有提供者密钥时跳过) | **建议性** | +| `nightly-schemathesis` | 使用 `docs/openapi.yaml` 对实时 OmniRoute 执行 OpenAPI 契约模糊测试(schemathesis)——暴露规范违规/未处理的 500 错误(阶段 8 B.4) | **建议性** | +| `nightly-mutation` | 对快速单元测试通道进行 Stryker 变异测试评分——存活的变异体会暴露薄弱的断言 | **建议性** | +| `nightly-compat` | 覆盖受支持 `engines.node` 范围的 Node 引擎兼容性矩阵 | **建议性** | --- @@ -496,42 +499,41 @@ JSON,十秒钟即可完成,也是解除红色 PR 阻塞的最快方式。** --- -## 合理化待办清单(ROI 审查 — 阶段 9 第 3 波) +## 合理化待办清单(ROI 审查 — 第 9 阶段第 3 波) -此清单已于 2026-06-17 根据 `ci.yml` 完成核对(先前版本遗漏了 +此清单已于 2026-06-17 与 `ci.yml` 核对(先前版本遗漏了 `audit:deps`、`check:tracked-artifacts`、`check:lockfile`、`check:licenses`、 `check:dead-code`、`check:cognitive-complexity`、`check:type-coverage`、 -`check:codeql-ratchet`、`check:pr-evidence`)。对核对后集合进行的 ROI 审查 -确定了以下合理化候选项。**合并属于机械性的 CI -变更;启用/移除则属于由操作方决定的策略决策。** 以下内容均尚未实施。 - -**上文还未记录的项目**(仅供参考、信号较弱):`docs-lint` 作业 -(markdownlint + Vale,整个作业设置 `continue-on-error`),以及独立的扫描器工作流 -`semgrep.yml` / `codeql.yml` / `scorecard.yml`。`quality-baseline.json` 中包含 -`semgrepFindings: 0`,但它未与 `ci.yml` 中的阻塞式棘轮机制关联——该指标 -目前处于孤立状态。 - -### 合并 / 去重(机械性操作,风险较低) - -每个候选项均已于 2026-06-17 根据实际门禁状态完成验证(先信任、后核实); -事实证明,若干“显而易见”的合并隐藏了技术债务,**不能**直接安全替换。 - -- **`check:docs-sync` 运行两次**——一次独立运行于 `lint` 作业中,另一次运行于 `check:docs-all`(`docs-sync-strict`)及 husky 的 pre-commit 钩子中。✅ **已完成**——已移除 `lint` 中的独立调用。 -- **CVE 扫描**——❌ **不能直接合并。** `audit:deps` 遇到任何高危/严重 CVE 都会硬性失败;`check:vuln-ratchet`(osv)仅在相较基线出现_回归_时失败(当前为 1 个 MODERATE)。两者语义不同——移除 `audit:deps` 将失去针对高危/严重漏洞的绝对门禁。两者均保留。 -- **循环依赖检测**——❌ **不能直接合并。** `check:circular-deps`(dpdm)报告了 **91 个循环**(这正是它仅作参考的原因);在解决这些循环之前,不能将其提升为阻塞项,而且其范围比当前通过的、经过筛选的 `check:cycles` 更广。保留 `check:cycles` 作为阻塞项;解决 91 个 dpdm 循环应作为单独的待办事项。 -- **复杂度**——✅ **已完成**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`):仅执行一次 ESLint 遍历,按 ruleId 计数,因此圈复杂度+最大行数与认知复杂度基线仍保持独立;单独的 `check:complexity` / `check:cognitive-complexity` 仍保留,供本地执行 `--update`。 -- **`/api` 防幻觉检查**——✅ **已完成**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`):仅对 `src/app/api` 执行一次文件系统清点,openapi-routes + docs-symbols 仍分别独立报告;单独检查仍保留,供本地运行。 -- **`check:node-runtime` 在 11 个作业中运行**——⚠️ **ROI 较低。** 每个作业都使用独立运行器,且该检查耗时不足 1 秒;总计仅节省约 10 秒,却会失去一个成本低廉的逐作业保护措施。不值得为此折腾。 -- **CI lint 中的 `typecheck:noimplicit:core`**——✅ **已从 lint 作业中移除**(此前通过 `continue-on-error` 设为仅供参考);阻塞式类型覆盖面由 `typecheck:core` + `check:type-coverage` 提供。保留本地脚本。 - -### 启用 / 决策(操作方策略) - -- `check:openapi-security-tiers`(仅供参考)——❌ **无法直接转为阻塞。** 它以状态码 0 退出,但会警告 `LOCAL_ONLY_API_PREFIXES` 下的若干 `traffic-inspector` 路由缺少 `x-loopback-only: true` 注解。强制执行前,必须先向 `openapi.yaml` 添加这些注解。 -- `typecheck:noimplicit:core`(仅供参考)——其作用大部分已被阻塞式 `check:type-coverage` 棘轮机制涵盖。应将其转为棘轮机制,或移除这个重复的第二次 `tsc` 检查。 -- `test:vitest:ui`(现已**阻塞**)——预先存在的失败已在 `vitest.config.ts` 中明确排除,并附有 `// #8618` 跟踪注释;新增失败将导致作业失败。 -- `check:secrets`(gitleaks,阻塞式棘轮机制固定在 3 个已记录的误报)——将这 3 个误报加入允许列表以降至 0,或将其降级为仅供参考。与 GitHub 原生机密扫描及 `check:public-creds` 存在重叠。 -- `check:pr-evidence`(阻塞式,使用 grep 检查 PR 正文)——误报风险较高;若移除,将削弱对硬性规则 #18 的执行,因此这确实需要作出策略决策。 -- `semgrep`(独立运行,仅供参考)——在 OWASP 类别上与 CodeQL 重叠;应将其基线接入棘轮机制,或将其移除。 +`check:codeql-ratchet`、`check:pr-evidence`)。对核对后的集合进行 ROI 审查后, +确定了以下合理化候选项。**合并属于机械性的 CI 变更;切换/移除则属于保留给操作者决定的策略事项。** +以下内容尚未应用。 + +**上文还未记录的项目**(建议性、低信号):`docs-lint` 作业 +(markdownlint + Vale,整个作业设置了 `continue-on-error`),以及独立的扫描器工作流 +`semgrep.yml` / `codeql.yml` / `scorecard.yml`。`semgrepFindings: 0` 位于 +`quality-baseline.json` 中,但尚未连接到 `ci.yml` 中的阻断式棘轮机制——该指标目前处于孤立状态。 + +### 合并/去重(机械性变更,风险较低) + +每个候选项均已于 2026-06-17 根据实际门禁状态进行验证(信任但要核实); +事实证明,若干“显而易见”的合并隐藏了技术债务,因而**不能**直接无缝替换。 + +- **`check:docs-sync` 运行两次**——一次独立运行于 `lint` 作业中,另一次运行于 `check:docs-all`(`docs-sync-strict`)和 husky pre-commit 钩子中。✅ **已完成**——已移除 `lint` 中的独立调用。 +- **CVE 扫描**——❌ **无法干净合并。** `audit:deps` 遇到任何高危/严重 CVE 都会硬失败;`check:vuln-ratchet`(osv)仅在相对于基线出现_回退_时失败(当前为 1 个 MODERATE)。两者语义不同——移除 `audit:deps` 将失去针对高危/严重漏洞的绝对门禁。两者均予以保留。 +- **循环检测**——✅ **已完成**(#15159 G-01/G-02)。此处旧文本将 `check:cycles` 称为“绿色、精心筛选的”门禁,并以 `check:circular-deps`(dpdm)报告 91 个循环为由,主张继续将其作为阻断门禁。这个绿色状态是一个**假绿**:`check:cycles` 仅扫描了 5 个子目录(450 个文件),只匹配静态 `import|export … from`,并丢弃了所有 `@/` 和 `@omniroute/open-sse/` 说明符,因此无法发现仓库中占主导地位的动态导入 + 别名循环。现已修复:该门禁现在遍历 `src` + `open-sse`(5023 个文件),从 TypeScript AST 收集说明符(因此 `import("…")` 会计入,而类型位置中的 `typeof import("…")` 不会计入),并解析 tsconfig `paths`。检测到的是 **14** 个循环,而非 0 个。由于无法在门禁 PR 中修复 14 个既有循环,`check:cycles` 现在采用**棘轮机制**(`--ratchet`,上限为 `quality-baseline.json` 中的 `metrics.cycles.value = 14`,`direction: down`)——它会阻止任何_回退_,且数量只能下降。CI 运行 `npm run check:cycles:ratchet`。消减工作随 **A-01** 一并推进。`check:circular-deps`(dpdm)继续作为范围更广的建议性第二意见。 +- **复杂度**——✅ **已完成**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`):一次 ESLint 遍历,按 ruleId 计数,因此圈复杂度 + 最大行数与认知复杂度的基线保持独立;单独的 `check:complexity` / `check:cognitive-complexity` 仍保留,供本地执行 `--update` 使用。 +- **`/api` 反幻觉检查**——✅ **已完成**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`):仅对 `src/app/api` 执行一次 FS 清点,openapi-routes + docs-symbols 仍独立报告;单独的检查仍保留,供本地运行。 +- **`check:node-runtime` 在 11 个作业中运行**——⚠️ **ROI 较低。** 每个作业使用独立的运行器,且该检查耗时不到 1 秒;总共节省约 10 秒,却会失去成本低廉的逐作业防护。不值得为此折腾。 +- **CI lint 中的 `typecheck:noimplicit:core`**——✅ **已从 lint 作业中移除**(此前为设置了 `continue-on-error` 的建议性检查);阻断式类型门禁由 `typecheck:core` + `check:type-coverage` 构成。本地脚本予以保留。 + +### 切换/决策(操作者策略) + +- `check:openapi-security-tiers`(建议性)——❌ **无法直接干净地切换。** 它以 0 退出,但会警告 `LOCAL_ONLY_API_PREFIXES` 下的若干 `traffic-inspector` 路由缺少 `x-loopback-only: true` 注解。若要强制执行,必须先将这些注解添加到 `openapi.yaml`。 +- `typecheck:noimplicit:core`(建议性)——已大体被阻断式 `check:type-coverage` 棘轮涵盖。可将其改为棘轮,或移除这个冗余的第二次 `tsc` 执行。 +- `test:vitest:ui`(现为**阻断式**)——既有失败已在 `vitest.config.ts` 中通过 `// #8618` 跟踪注释明确排除;新失败将导致作业失败。 +- `check:secrets`(gitleaks,阻断式棘轮,冻结于 3 个已记录的误报)——将这 3 项加入允许列表以降至 0,或将其降级为建议性检查。它与 GitHub 原生 secret-scanning + `check:public-creds` 重叠。 +- `check:pr-evidence`(阻断式,使用 grep 检查 PR 正文)——误报风险较高;若移除,将削弱对硬性规则 #18 的执行,因此这确实需要策略决策。 +- `semgrep`(独立的建议性检查)——在 OWASP 类别方面与 CodeQL 重叠;将其基线接入棘轮机制,或将其移除。 --- diff --git a/docs/i18n/zh-TW/CONTRIBUTING.md b/docs/i18n/zh-TW/CONTRIBUTING.md index 734d1868adf..2dd7ba08074 100644 --- a/docs/i18n/zh-TW/CONTRIBUTING.md +++ b/docs/i18n/zh-TW/CONTRIBUTING.md @@ -393,22 +393,22 @@ docs/ --- -## 提取要求檢查清單 +## Pull Request 檢查清單 - [ ] 測試通過(`npm test`) -- [ ] Linting 通過(`npm run lint`) +- [ ] Lint 檢查通過(`npm run lint`) - [ ] 建置成功(`npm run build`) -- [ ] 為新的公開函式與介面新增 TypeScript 類型 -- [ ] 沒有硬式編碼的機密或後備值 -- [ ] 公開上游認證資訊透過 `resolvePublicCred()` 嵌入(請參閱 [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)),絕不以常值形式 -- [ ] 錯誤回應會經過 `buildErrorBody()` / `sanitizeErrorMessage()` — 回應主體中沒有原始的堆疊追蹤(請參閱 [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) -- [ ] Shell 指令(`exec` / `spawn`)透過 `env` 傳遞執行階段值,而非透過字串插補 -- [ ] 所有輸入都使用 Zod schema 驗證 -- [ ] Changelog **片段** 新增於 `changelog.d/{features|fixes|maintenance}/-.md` 下,用於使用者可見的變更(請參閱 [`changelog.d/README.md`](./changelog.d/README.md))— **請勿**直接編輯 `CHANGELOG.md`;片段會在發佈時彙總,且永遠不會在 PR 之間發生衝突 -- [ ] 文件已更新(如適用) -- [ ] 沒有開啟新的 CodeQL / Secret-Scanning 警示,或者每個都已使用技術理由駁回,並參照相關的 `docs/security/` 文件 -- [ ] 會生成子處理程序的路由(`/api/mcp/`, `/api/cli-tools/runtime/`)在 `src/server/authz/routeGuard.ts` 中被歸類為 `isLocalOnlyPath()` — 請參閱 [硬性規則 #15](docs/security/ROUTE_GUARD_TIERS.md) -- [ ] 提交訊息中沒有 `Co-Authored-By` 尾標 — 提交必須僅以儲存庫擁有者的 Git 身分出現(硬性規則 #16) +- [ ] 已為新的公開函式與介面新增 TypeScript 類型 +- [ ] 沒有硬編碼的密鑰或備援值 +- [ ] 公開的上游憑證透過 `resolvePublicCred()` 嵌入(請參閱 [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)),絕不以字面值形式嵌入 +- [ ] 錯誤回應透過 `buildErrorBody()` / `sanitizeErrorMessage()` 處理——回應主體中不得包含原始堆疊追蹤(請參閱 [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) +- [ ] Shell 命令(`exec` / `spawn`)透過 `env` 傳遞執行階段值,而非使用字串插值 +- [ ] 所有輸入均使用 Zod schema 進行驗證 +- [ ] 若有面向使用者的變更,已在 `changelog.d/{features|fixes|maintenance}/-.md` 下新增變更日誌**片段**(請參閱 [`changelog.d/README.md`](./changelog.d/README.md))——請**勿**直接編輯 `CHANGELOG.md`;片段會在發布時彙整,且各 PR 之間永遠不會發生衝突 +- [ ] 已更新文件(如適用) +- [ ] 未新增任何 CodeQL / Secret-Scanning 警示,或每個警示均已附上引用相關 `docs/security/` 文件的技術理由並予以駁回 +- [ ] 會產生子行程的路由(`/api/mcp/`、`/api/cli-tools/runtime/`)已在 `src/server/authz/routeGuard.ts` 中分類為 `isLocalOnlyPath()`——請參閱[硬性規則 #15](docs/security/ROUTE_GUARD_TIERS.md) +- [ ] 提交訊息中不得包含 AI/機器人的 `Co-authored-by` 尾註(硬性規則 #16)——若重用了人類協作者的工作,應使用標準的 `Co-authored-by: Name ` 尾註予以署名 --- diff --git a/docs/i18n/zh-TW/docs/architecture/QUALITY_GATES.md b/docs/i18n/zh-TW/docs/architecture/QUALITY_GATES.md index b6a24c356c9..402cca1f712 100644 --- a/docs/i18n/zh-TW/docs/architecture/QUALITY_GATES.md +++ b/docs/i18n/zh-TW/docs/architecture/QUALITY_GATES.md @@ -17,202 +17,199 @@ ## 閘門清單與執行設定檔 -### 候選版本准入 +### 候選項目准入 -CI 與 Quality Gates 工作流程各自產生穩定的判定結果:`Gate / CI` 與 -`Gate / Quality`。其版本化准入政策會將每個上游作業列為必要或建議項目。每個適用的 -必要作業都必須成功:缺失、已取消、已略過、待處理及未知的結果皆無法確立為 PASS。 -有效的僅文件或僅目錄分類,可使程式碼執行路徑不適用;草稿 PR 不會被接受為候選版本。 -`hotfix` 標籤不會免除證據要求。 +CI 與 Quality Gates 工作流程各自產生一個穩定的判定結果:`Gate / CI` 與 +`Gate / Quality`。其版本化的准入政策會列舉每個上游工作,並將其標示為必要或建議。所有適用的必要工作都必須成功:缺失、 +已取消、已跳過、待處理及未知結果皆無法確立 PASS。有效的僅文件或僅目錄分類可使程式碼執行線不適用; +草稿 PR 不會被視為可接受的候選項目。`hotfix` 標籤不會免除證據要求。 -這兩個工作流程涵蓋 PR、推送至 main/release 分支、手動分派及 -合併群組事件。推送、分派及合併群組會執行完整選項。分支與合併群組會對原本選擇 -自架執行器的作業改用託管執行器;推出前必須確認有足夠的託管容量。 +這兩個工作流程皆涵蓋 PR、推送至 main/release 分支、手動分派及 +merge-group 事件。推送、分派及 merge-group 會執行完整選項。Fork +與 merge group 會對原本選用自託管執行器的工作改用託管執行器;在推出前,必須確認託管容量充足。 -每份 JSON 收據都會識別簽出的 SHA、工作流程執行及嘗試次數。 -CLI 會拒絕簽出 SHA 與事件 SHA 不符的情況。工作流程測試會將政策成員資格繫結至 -判定作業的 `needs` 清單,使新增或移除的執行路徑無法在未被察覺的情況下消失。 -收據涵蓋其自身工作流程,而不涵蓋發布、部署或現有建議性掃描器的內部作業。 -在分支規則中啟用這兩個檢查名稱屬於另一項獨立的管理變更;加入這些作業本身並不會保護分支。 +每份 JSON 收據都會識別已簽出的 SHA、工作流程執行及嘗試次數。 +CLI 會拒絕簽出 SHA 與事件 SHA 不相符的情況。工作流程測試會將政策成員資格 +繫結至判定工作的 `needs` 清單,使新增或移除的執行線無法悄然消失。 +這些收據僅涵蓋其自身的工作流程,不涵蓋發布、部署或現有建議性掃描器的內部運作。 +在分支規則中啟用這兩個檢查名稱是另一項獨立的管理變更;新增這些工作本身並不會保護分支。 ### 靜態掃描清單 版本化的 npm 別名清單與靜態掃描成員資格位於 -`config/quality/gate-manifest.json`。執行 `npm run check:gate-manifest`,以根據 -`package.json` 驗證指令碼名稱與確切命令;任何新增、移除或命令偏移,都會使本機掛鉤及 -CI 中的變更分類作業失敗。別名並不是工作流程作業、矩陣執行個體或測試案例:不得將這些數量 -視為可互換的數據。 +`config/quality/gate-manifest.json`。執行 `npm run check:gate-manifest`,以依據 +`package.json` 驗證指令碼名稱與確切命令;新增、移除及命令漂移都會使本機掛鉤與 CI 中的變更分類工作失敗。 +別名不是工作流程工作、矩陣執行個體或測試案例:這些數量不得被描述為可互換。 使用 `npm run quality:scan -- --list` 或 `npm run quality:scan:fast -- --list` -可在不執行的情況下檢查所選別名。執行器會叫用 npm 進入點,因此會保留其執行階段 -(包括已設定使用 Bun 的情況)。資訊清單會將這些設定檔以外的別名記錄為另行叫用, -而唯讀掃描設定檔中禁止使用維護命令。 - -這些設定檔僅涵蓋靜態掃描。它們不會驗證產品測試、涵蓋率、封裝、外部檢查或 -候選版本的完整發布驗收。工作流程准入使用連結的 -`config/quality/admission-policy.json` 與 -`scripts/quality/admission-verdict.mjs`。發布觀察器設定檔仍保持獨立; -請個別檢查其適用的檢查項目與收據。下方的文字清單僅供參考,不能證明閘門實際上已執行。 - -指令碼位於 `scripts/check/`(政策閘門)與 `scripts/quality/`(棘輪引擎)下。 +可在不執行的情況下檢查所選別名。執行器會呼叫 +npm 進入點,因此會保留其執行階段(包括已設定使用 Bun 的情況)。 +資訊清單會將這些設定檔之外的別名記錄為個別呼叫項目,且唯讀掃描設定檔中禁止使用維護命令。 + +這些設定檔僅涵蓋靜態掃描。它們不會認證產品測試、 +覆蓋率、封裝、外部檢查或候選項目的完整發布驗收。 +工作流程准入使用連結的 `config/quality/admission-policy.json` 與 +`scripts/quality/admission-verdict.mjs`。發布觀察器設定檔維持獨立; +請分別檢查其適用檢查與收據。下方的文字 +清單僅供參考,不能證明閘門實際執行過。 + +指令碼位於 `scripts/check/`(政策閘門)與 `scripts/quality/`(棘輪引擎)之下。 CI 的單一事實來源為 `.github/workflows/ci.yml`。 ### 發布 PR 快速路徑(`quality.yml`) -`.github/workflows/quality.yml` 在 main/release PR、受保護分支推送、 -分派及合併群組方面補充 CI。PR 會使用依路徑篩選的快速檢查。已移除永久停用的重複建置; -實際的建置/封裝/啟動檢查仍保留在 CI 中。 +`.github/workflows/quality.yml` 在 main/release PR、受保護分支 +推送、分派及 merge group 上補充 CI。PR 使用依路徑篩選的快速檢查。永久 +停用的重複建置已移除;實際的建置/封裝/啟動檢查仍保留在 CI 中。 -| 作業 | 範圍 | 阻擋性 | -| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ------------ | -| `Docs Gates (fast-path)` | 文件/程式碼 PR;API 文件參照及所有文件 | 是 | -| `Fast Quality Gates` | 程式碼 PR;靜態檢查、類型檢查、儀表板類型檢查、受影響的單元測試 | 是 | -| `Forgotten sibling tests` | 程式碼 PR;追蹤已變更模組的靜態取用端及候選同層測試;桶狀匯出與動態匯入路徑會回報為建議性診斷,並附上所參照的允許清單例外項目 | **建議性** | -| `Vitest (fast-path)` | 程式碼 PR;快速 vitest 測試套件 | 是 | -| `Unit Tests fast-path` | 程式碼 PR;4 分片單元測試套件 | 是 | -| `No new ESLint warnings` | 程式碼 PR;可辨識抑制設定的 lint 防護 | 是,包括分支 | -| `Merge integrity (changelog + generated skills)` | 非草稿 PR;變更記錄與產生技能的同步 | 是,包括分支 | +| 工作 | 範圍 | 阻擋性 | +| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `Docs Gates (fast-path)` | 文件/程式碼 PR;API 文件參照與全部文件 | 是 | +| `Fast Quality Gates` | 程式碼 PR;靜態檢查、類型檢查、儀表板類型檢查、受影響的單元測試 | 是 | +| `Forgotten sibling tests` | 程式碼 PR;將變更的模組追蹤至靜態使用端與候選同層測試;彙總模組與動態匯入路徑會回報為建議性診斷,並附帶所參照的允許清單例外 | **建議性** | +| `Vitest (fast-path)` | 程式碼 PR;快速 vitest 測試套件 | 是 | +| `Unit Tests fast-path` | 程式碼 PR;4 分片單元測試套件 | 是 | +| `No new ESLint warnings` | 程式碼 PR;可感知抑制設定的 lint 防護 | 是,包括 fork | +| `Merge integrity (changelog + generated skills)` | 非草稿 PR;變更日誌與產生的技能同步 | 是,包括 fork | #### 遺漏的同層測試報告 `npm run check:forgotten-sibling-tests` 會重複使用測試影響對應表背後的匯入解析器。 -對於每個已變更的正式環境模組,若候選測試未包含在提取要求的差異中,它會回報具確定性的 -`已變更模組/符號 -> 靜態取用端 -> 候選同層測試` 鏈結。Markdown 摘要與 JSON 結果會保留為 +對於每個已變更的正式環境模組,當候選測試不存在於 pull request 差異中時,它會回報具確定性的 +`變更的模組/符號 -> 靜態使用端 -> 候選同層測試` 鏈結。Markdown 摘要與 JSON 結果會保留為 `forgotten-sibling-tests` 工作流程成品,以便在任何阻擋性推出之前進行校準。 -Barrel 重新匯出與動態匯入僅用於解析診斷;它們絕不會產生阻擋性發現。 -已審核的例外位於 -`config/quality/forgotten-sibling-allowlist.json`。每個項目都必須指定使用方與候選 -測試、提供具體理由,並連結至 GitHub issue 或 pull request。格式錯誤的項目會以 -封閉方式失敗。例外無法抑制已刪除的候選測試,或新增 `.skip`/`.todo` 的差異; -弱化斷言與其他遮蔽行為仍由獨立阻擋的 +Barrel 重新匯出與動態匯入僅作為解析診斷;它們絕不會產生 +阻擋性發現。經審查的例外位於 +`config/quality/forgotten-sibling-allowlist.json`。每個項目都必須指明取用端與候選 +測試、提供具體理由,並連結至 GitHub issue 或 pull request。格式錯誤的項目會採取 +封閉式失敗。例外無法略過已刪除的候選測試,亦無法略過新增 `.skip`/`.todo` 的差異; +弱化斷言及其他遮蔽行為仍由獨立且具阻擋性的 `check:test-masking` 閘門負責。 ### 工作:`lint` -在每個提交至 `main` 的 PR 上執行。失敗時阻擋合併。 - -| 指令碼 (`npm run ...`) | 驗證內容 | 是否阻擋 | -| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -| `check:node-runtime` | Node.js 版本位於支援範圍內 | 是 | -| `check:cycles` | 循環匯入 — 所有 `src/` + `open-sse/` 模組 | 是 | -| `check:route-validation:t06` | 所有路由皆存在 Zod schema(Tier 6 政策) | 是 | -| `check:any-budget:t11` | `@ts-expect-error // any` 的數量未超過預算(Tier 11 catraca) | 是 | -| `check:provider-consistency` | `providers.ts` 中的每個提供者在 `providerRegistry.ts` 中都有相符的項目(反之亦然,但僅限允許清單內) | 是 | -| `check:model-lifecycle` | 三個手動維護的路由表會與簽入版本控制的生命週期快照(#11503)保持一致:`FITNESS_TABLE`(`taskFitness.ts`)不會為任何 `REGISTRY` 可路由的已退役 id 評分;每個 `BUILT_IN_ALIASES` 目標都存在於 `REGISTRY` 中,且不在已退役 id 快照中;`REGISTRY` 中仍存在的每個已退役 id 都會被轉送,或列於 `allowedRetiredInCatalog` 中;而且任何 `DEFAULT_DEGRADATION_MAP` 的來源或目標都不會在該快照中顯示為已退役。這無法證明某個模型目前仍由即時上游服務提供。離線作業 — 與 `config/quality/model-lifecycle.json` 比較;該檔案需使用 `npm run quality:refresh-model-lifecycle` 手動重新整理(需要網路;未接入 CI)。`allowedRetiredInCatalog` 是逐步清零的棘輪機制:只有在有追蹤議題時才能新增項目。 | 是 | -| `check:fetch-targets` | 用戶端 `src/` 中的每個 `fetch("/api/...")` 都會解析至實際存在的 `route.ts` | 是 | -| `check:deps` | 儲存庫中每個 `package.json` 內所有可透過 `npm install` 安裝的相依套件,都必須列於 `dependency-allowlist.json` 中;新增的未鎖定版本或疑似名稱搶註套件會被標記 | 是 | -| `audit:deps` | `npm audit`(根目錄 + electron)— 不得有高風險/重大風險公告(與 osv `check:vuln-ratchet` 重疊;請參閱合理化待辦清單) | 是 | -| `check:lockfile` | `package-lock.json` 完整性 — 使用 https 登錄庫、具備完整性雜湊,且無主機覆寫 | 是 | -| `check:licenses` | 正式環境相依套件的 SPDX 授權允許清單 | 是 | -| `check:tracked-artifacts` | 不得有建置產物/已提交的 `node_modules` 符號連結(也會在 husky pre-commit 中執行;pre-push 刻意保持輕量 — #6716) | 是 | -| `check:ai-attribution` | PR 提交、標題或內文中不得包含 AI/機器人的 `Co-Authored-By` 尾註或 AI 生成註腳 — 強制規則 #16(位於 `quality.yml` 中針對 PR→`release/**` 的快速閘門迴圈 — 讀取事件承載資料,非 PR 時不執行任何操作 — 以及 `ci.yml` lint 中僅針對 PR→`main` 的步驟;另包含 husky `commit-msg` 掛鉤;允許人類共同作者;#14436) | -| `check:vitest-exclusions` | 每個 Vitest 排除項目都必須註明追蹤議題,並列於 `config/quality/vitest-exclusions.json` 中(#13204) | 是 | -| `check:file-size` | 原始碼檔案不得超過各副檔名的上限(棘輪機制:大型凍結檔案列於 `frozen` 清單中) | 是 | -| `check:error-helper` | 執行器/處理常式中的錯誤回應須使用 `buildErrorBody()`/`sanitizeErrorMessage()`(強制規則 #12) | 是 | -| `check:migration-numbering` | Migration SQL 檔案依序編號,沒有缺號或重複編號 | 是 | -| `check:public-creds` | 除了 `publicCreds.ts` 之外,不得出現 OAuth `client_id`/`client_secret` 或 Firebase Web 金鑰的字面值(硬性規則 #11) | 是 | -| `check:db-rules` | `src/lib/db/` 模組之外不得出現原始 SQL;不得從 `localDb.ts` 進行 barrel import(硬性規則 #2/#5) | 是 | -| `check:known-symbols` | 已在各自分派表中註冊的提供者執行器、路由策略及轉譯器,必須與磁碟上的檔案相符,不得有孤立或未宣告的符號 | 是 | -| `check:route-guard-membership` | 每個會產生子行程的路由都必須由 `isLocalOnlyPath()` 分類(硬性規則 #15/#17) | 是 | -| `check:test-discovery` | 儲存庫中的每個 `*.test.ts` / `*.spec.ts` 檔案都必須由至少一個測試執行器收集(棘輪限制:`test-discovery-baseline.json` 中的孤立檔案清單只能縮減) | 是 | -| `check:agent-skills-sync` | 產生的 agent-skills 成品與其來源目錄相符(無偏差) | -| `check:provider-asset-provenance` | Provider 標誌/資產具有已記錄的來源資訊項目 | -| `lint:json` | JSON 設定檔可正確解析,且符合儲存庫的 lint 規則 | -| `typecheck:core` | TypeScript 編譯無錯誤(僅有提示性警告) | 是 | -| `typecheck:noimplicit:core` | 嚴格的 `noImplicitAny`——著眼未來;許多既有呼叫位置仍需加上類型註記 | **提示性**(`continue-on-error: true`) | -| `check:dashboard-typecheck` | 將 `tsc` 範圍限定於 `src/app/(dashboard)/**` (#7033)——`typecheck:core` 精選的 27 個檔案允許清單不包含任何儀表板 TSX,而 `next build` 也從不對其進行類型檢查(`next.config.mjs` 設定了 `ignoreBuildErrors: true`),因此其中的孤立識別碼迴歸問題 (#6625/#6909) 過去無法被 CI 偵測。與凍結的每檔案/每 TS 程式碼計數基準(`config/quality/dashboard-typecheck-baseline.json`,採用與 `check:known-symbols` 相同的過時強制執行模式)進行差異比較——只有超出基準計數的新增錯誤才會導致閘門失敗;修正既有錯誤時,使用 `--update` 逐步下調基準。 | 是 | - -### 工作:`quality-gate` +在每個針對 `main` 的 PR 上執行。失敗時阻擋合併。 + +| 指令碼(`npm run ...`) | 驗證內容 | 阻擋性 | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `check:node-runtime` | Node.js 版本是否位於支援範圍內 | 是 | +| `check:cycles` | 檢查整個 `src/` + `open-sse/` 中的循環匯入(基於 AST,並解析 tsconfig `paths`)。直接執行 = 僅提供建議並列出循環。`check:cycles:ratchet`(CI 實際執行的項目)會在數量超過 `quality-baseline.json` 中的 `metrics.cycles` 上限時阻擋;目前上限為 14,`direction: down`,因此只能下降(#15159 G-01/G-02) | 是(棘輪機制) | +| `check:route-validation:t06` | 所有路由上皆存在 Zod schema(第 6 級政策) | 是 | +| `check:any-budget:t11` | `@ts-expect-error // any` 的數量不超過預算(第 11 級 catraca) | 是 | +| `check:provider-consistency` | `providers.ts` 中的每個提供者都在 `providerRegistry.ts` 中有對應的項目(反之亦然,限允許清單內) | 是 | +| `check:model-lifecycle` | 三個手動維護的路由表會與已簽入版本控制的生命週期快照 (#11503) 保持一致:`FITNESS_TABLE` (`taskFitness.ts`) 不會為任何 `REGISTRY` 可路由的已退役 id 評分;每個 `BUILT_IN_ALIASES` 目標都存在於 `REGISTRY` 中,且不在已退役 id 快照中;`REGISTRY` 中仍存在的每個已退役 id 都會被轉送,或列於 `allowedRetiredInCatalog` 中;而且任何 `DEFAULT_DEGRADATION_MAP` 的來源或目標都不會在該快照中顯示為已退役。這並不能證明某個模型目前確實由正常運作的上游提供服務。離線作業——與 `config/quality/model-lifecycle.json` 比較;此檔案需透過 `npm run quality:refresh-model-lifecycle` 手動重新整理(需要網路;未整合至 CI)。`allowedRetiredInCatalog` 是一種逐步清零的棘輪機制:僅在有追蹤議題時才新增項目。 | 是 | +| `check:fetch-targets` | 用戶端 `src/` 中的每個 `fetch("/api/...")` 都會解析至實際存在的 `route.ts` | 是 | +| `check:deps` | 儲存庫中每個 `package.json` 內所有可透過 `npm install` 安裝的相依套件,都必須列於 `dependency-allowlist.json` 中;新增的未鎖定版本或疑似名稱仿冒套件會被標記 | 是 | +| `audit:deps` | `npm audit`(根目錄 + electron)——不得有高風險/嚴重等級的安全公告(與 osv `check:vuln-ratchet` 重疊;請參閱合理化待辦清單) | 是 | +| `check:lockfile` | `package-lock.json` 完整性——使用 https registry、具備完整性雜湊,且不得覆寫主機 | 是 | +| `check:licenses` | 正式環境相依套件的 SPDX 授權允許清單 | 是 | +| `check:tracked-artifacts` | 不得有建置產物/已提交的 `node_modules` 符號連結(也會在 husky pre-commit 中執行;pre-push 刻意維持輕量——#6716) | 是 | +| `check:ai-attribution` | PR 提交、標題或內文中不得有 AI/機器人的 `Co-Authored-By` 結尾標記或 AI 生成頁尾——強制規則 #16(位於 `quality.yml` 針對 PR→`release/**` 的 fast-gates 迴圈中——會讀取事件酬載,非 PR 時不執行任何操作——以及 `ci.yml` lint 中僅針對 PR→`main` 的步驟;另包含 husky `commit-msg` hook;允許人類共同作者;#14436) | +| `check:vitest-exclusions` | 每個 Vitest 排除項目都必須指定追蹤議題,並出現在 `config/quality/vitest-exclusions.json` 中(#13204) | 是 | +| `check:file-size` | 任何原始碼檔案皆不得超過各副檔名的上限(棘輪機制:大型檔案凍結於 `frozen` 清單中) | 是 | +| `check:error-helper` | 執行器/處理常式中的錯誤回應須使用 `buildErrorBody()`/`sanitizeErrorMessage()`(強制規則 #12) | 是 | +| `check:migration-numbering` | Migration SQL 檔案採用連續編號,沒有缺號或重複編號 | 是 | +| `check:public-creds` | 除了 `publicCreds.ts` 之外,不得出現 OAuth `client_id`/`client_secret` 或 Firebase Web 金鑰常值(硬性規則 #11) | 是 | +| `check:db-rules` | `src/lib/db/` 模組之外不得出現原始 SQL;不得從 `localDb.ts` 進行 barrel import(硬性規則 #2/#5) | 是 | +| `check:known-symbols` | 註冊於各自分派表中的提供者執行器、路由策略及轉譯器,必須與磁碟上的檔案相符,不得有孤立或未宣告的符號 | 是 | +| `check:route-guard-membership` | 每個會產生子行程的路由,都必須由 `isLocalOnlyPath()` 分類(硬性規則 #15/#17) | 是 | +| `check:test-discovery` | 儲存庫中的每個 `*.test.ts` / `*.spec.ts` 檔案,都必須由至少一個測試執行器收集(棘輪機制:`test-discovery-baseline.json` 中的孤立清單只能縮減) | 是 | +| `check:agent-skills-sync` | 產生的 agent-skills 成品與其來源目錄相符(無偏移) | +| `check:provider-asset-provenance` | 提供者標誌/資產具有已記錄的來源證明項目 | +| `lint:json` | JSON 設定檔可正確解析,且符合儲存庫的 lint 規則 | +| `typecheck:core` | TypeScript 編譯無錯誤(僅有提示性警告) | 是 | +| `typecheck:noimplicit:core` | 嚴格的 `noImplicitAny` — 前瞻性檢查;許多既有呼叫位置仍需補上類型註記 | **提示性**(`continue-on-error: true`) | +| `check:dashboard-typecheck` | 將 `tsc` 範圍限定為 `src/app/(dashboard)/**`(#7033)— `typecheck:core` 精選的 27 個檔案允許清單不包含任何儀表板 TSX,而 `next build` 也從不對其執行類型檢查(`next.config.mjs` 設定了 `ignoreBuildErrors: true`),因此其中的孤立識別碼迴歸問題(#6625/#6909)對 CI 而言不可見。此檢查會與凍結的「每個檔案/每個 TS 錯誤代碼」計數基準(`config/quality/dashboard-typecheck-baseline.json`,採用與 `check:known-symbols` 相同的過期強制執行模式)進行差異比較 — 只有超出基準計數的「新」錯誤才會使此閘門失敗;修正既有錯誤時,可使用 `--update` 逐步下調基準。 | 是 | + +### 作業:`quality-gate` 在 `test-coverage` 之後執行。失敗時會阻止合併。 -| 指令碼 | 驗證項目 | 阻擋性 | -| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `quality:collect` | 產生 `quality-metrics.json`(ESLint 警告數、來自合併分片報告的覆蓋率) | 是(棘輪檢查的上游) | -| `quality:ratchet` | `quality-baseline.json` 中的每個指標皆未退步(ESLint 警告數 ≤ 基準;覆蓋率 ≥ 基準) | 是 | -| `check:duplication` | 程式碼重複率(jscpd@4)未超過 `quality-baseline.json` 中的基準 | 是 | -| `check:complexity` | 檔案層級的循環複雜度未超過上限(核心 ESLint `complexity` + `max-lines-per-function`) | 是 | -| `check:cognitive-complexity` | 認知複雜度棘輪檢查(`eslint-plugin-sonarjs`)— 獨立的 ESLint 檢查流程;CI 將兩者合併為單一的 `check:complexity-ratchets` 步驟執行 | 是 | -| `check:dead-code` | 未使用的匯出項目/檔案棘輪檢查(knip)相較於基準未退步 | 是 | -| `check:compression-budget` | 壓縮基準測試預算 — 各引擎的 token 節省率下限不得退步 | 是 | -| `check:type-coverage` | 類型標註百分比棘輪檢查(`type-coverage`)未退步;大致涵蓋 `typecheck:noimplicit:core` | 是 | -| `check:codeql-ratchet` | 未解決的 CodeQL 警示數未退步(透過 `gh api` 讀取;無權杖時正常跳過)— 更新頻率與手動觸發方式:請參閱下方的「CodeQL 棘輪檢查」 | 是 | +| 指令碼 | 驗證項目 | 阻擋性 | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `quality:collect` | 產生 `quality-metrics.json`(ESLint 警告數量、來自合併分片報告的覆蓋率) | 是(棘輪檢查的上游) | +| `quality:ratchet` | `quality-baseline.json` 中的每項指標均未退步(ESLint 警告數 ≤ 基準;覆蓋率 ≥ 基準) | 是 | +| `check:duplication` | 程式碼重複(jscpd@4)未超過 `quality-baseline.json` 中的基準 | 是 | +| `check:complexity` | 檔案層級的循環複雜度未超過上限(核心 ESLint `complexity` + `max-lines-per-function`) | 是 | +| `check:cognitive-complexity` | 認知複雜度棘輪檢查(`eslint-plugin-sonarjs`)— 獨立的 ESLint 檢查流程;CI 將兩者合併為單一的 `check:complexity-ratchets` 步驟 | 是 | +| `check:dead-code` | 未使用的匯出項目/檔案棘輪檢查(knip)相較於基準未退步 | 是 | +| `check:compression-budget` | 壓縮基準測試預算 — 各引擎的 token 節省下限不得退步 | 是 | +| `check:type-coverage` | 類型覆蓋百分比棘輪檢查(`type-coverage`)未退步;大致涵蓋 `typecheck:noimplicit:core` | 是 | +| `check:codeql-ratchet` | 未解決的 CodeQL 警示數量未退步(透過 `gh api` 讀取;無權杖時正常略過)— 更新頻率與手動觸發方式:請參閱下方的「CodeQL 棘輪檢查」 | 是 | ### 工作:`quality-extended` -整個工作皆為建議性質(`continue-on-error: true`)。以 npm 為基礎的棘輪檢查會實際執行; -外部掃描器則透過 `gh release download` 安裝,若二進位檔仍不存在,將自行跳過(exit 0)。 +整個工作皆為建議性質(`continue-on-error: true`)。以 npm 為基礎的棘輪檢查會實際執行;外部掃描器則透過 `gh release download` 安裝,若二進位檔仍不存在,便會自行略過(exit 0)。 -| 指令碼 | 驗證項目 | 阻擋性 | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| `check:circular-deps` | 無循環相依性(dpdm) | **建議性** | -| `check:bundle-size` | 套件大小未超過上限 | **建議性** | -| `check:secrets` | 機密資訊掃描(gitleaks)— 若二進位檔不存在則跳過 | **建議性** | -| `check:vuln-ratchet` | 相依套件漏洞(osv-scanner)未退步 — 若二進位檔不存在則跳過 | **建議性** | -| `check:workflows` | 工作流程 lint(actionlint + zizmor);掃描器缺失/損壞、報告無效或棘輪基準缺失時,會以 INCOMPLETE 判定失敗。有效的發現項目則遵循所選的嚴格/建議/棘輪政策 | 必須執行;zizmor 棘輪檢查在 CI 中具有阻擋性 | -| `check:openapi-breaking` | 公開 API 合約(`openapi.yaml`)相較於基礎分支的破壞性變更(oasdiff)— 產生 `openapiBreaking=N`;若 oasdiff 不存在或無法解析基礎規格則跳過 | **建議性** | +| 指令碼 | 驗證項目 | 阻擋性 | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `check:circular-deps` | 無循環相依性(dpdm) | **建議性** | +| `check:bundle-size` | 套件組合大小未超過上限 | **建議性** | +| `check:secrets` | 機密資訊掃描(gitleaks)— 若二進位檔不存在則略過 | **建議性** | +| `check:vuln-ratchet` | 相依套件漏洞(osv-scanner)未退步 — 若二進位檔不存在則略過 | **建議性** | +| `check:workflows` | 工作流程 lint(actionlint + zizmor);掃描器缺失/故障、報告無效或缺少棘輪基準時,會以 INCOMPLETE 判定失敗。有效發現項目則遵循所選的嚴格/建議/棘輪政策 | 必須執行;zizmor 棘輪檢查在 CI 中具阻擋性 | +| `check:openapi-breaking` | 相較於基礎分支,公開 API 契約(`openapi.yaml`)的破壞性變更(oasdiff)— 產生 `openapiBreaking=N`;若 oasdiff 不存在或無法解析基礎規格則略過 | **建議性** | ### 工作:`docs-sync-strict` -每個針對 `main` 的 PR 都會執行。失敗時會阻擋合併。 - -| 指令碼 | 驗證內容 | 阻擋性 | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | -| `check:docs-all` | 依序執行下列 6 個子閘門的中繼閘門 | 是 | -| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt 的版本一致性 | 是 | -| ↳ `check:docs-counts` | 文章中的計數(提供者數量、遷移數量等)是否位於實際計數的棘輪容許範圍內 | 是 | -| ↳ `check:env-doc-sync` | `.env.example` 中的每個環境變數都有記錄在文件表格中,反之亦然 | 是 | -| ↳ `check:deprecated-versions` | 文件中沒有已棄用的版本字串 | 是 | -| ↳ `check:doc-links` | 文件中的內部 markdown 連結會解析至實際檔案(`[text]`/`(path)` 格式) | 是 | -| ↳ `check:fabricated-docs` | 文件中引用的路由、環境變數、CLI 命令、hook 名稱及檔案路徑皆存在於程式碼庫中。透過 `--strict` 作為硬性閘門;未使用該旗標時則為軟性失敗。 | 是(在 CI 中透過 `--strict`) | -| `check:cli-i18n` | CLI 命令字串存在於所有 i18n 語系檔案中 | 是 | -| `check:openapi-coverage` | OpenAPI 規格涵蓋的實際路由數至少達到棘輪式下限 | 是 | -| `check:openapi-security-tiers` | `openapi.yaml` 中的安全層級註解與 `routeGuard.ts` 的分類一致 | **建議性** | -| `check:openapi-routes` | `openapi.yaml` 中的每個路徑都會解析至實際的 `route.ts`(防止幻覺) | 是 | -| `check:docs-symbols` | `docs/**/*.md` 中的每個 `/api/...` 參照都會解析至實際的 `route.ts`(防止幻覺) | 是 | -| `i18n translation drift` | i18n 語系檔案中未翻譯的鍵值——僅警告 | **建議性** | +每個以 `main` 為目標的 PR 都會執行。失敗時會阻擋合併。 + +| 指令碼 | 驗證內容 | 阻擋性 | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- | +| `check:docs-all` | 依序執行下列 6 個子閘門的中繼閘門 | 是 | +| ↳ `check:docs-sync` | CHANGELOG / OpenAPI / llm.txt 的版本一致性 | 是 | +| ↳ `check:docs-counts` | 文字中的數量(提供者數量、遷移數量等)位於實際數量的棘輪允許範圍內 | 是 | +| ↳ `check:env-doc-sync` | `.env.example` 中的每個環境變數都記錄於文件表格中,反之亦然 | 是 | +| ↳ `check:deprecated-versions` | 文件中沒有已棄用的版本字串 | 是 | +| ↳ `check:doc-links` | 文件中的內部 markdown 連結會解析至實際檔案(`[text]`/`(path)` 格式) | 是 | +| ↳ `check:fabricated-docs` | 文件中引用的路由、環境變數、CLI 命令、掛鉤名稱及檔案路徑確實存在於程式碼庫中。使用 `--strict` 時為硬性閘門;不加此旗標時僅軟性失敗。 | 是(CI 中透過 `--strict`) | +| `check:cli-i18n` | CLI 命令字串存在於所有 i18n 語系檔案中 | 是 | +| `check:openapi-coverage` | OpenAPI 規格至少涵蓋依棘輪機制設定下限數量的實際路由 | 是 | +| `check:openapi-security-tiers` | `openapi.yaml` 中的安全層級註解與 `routeGuard.ts` 的分類一致 | **建議性** | +| `check:openapi-routes` | `openapi.yaml` 中的每個路徑都能解析至實際的 `route.ts`(防止虛構) | 是 | +| `check:docs-symbols` | `docs/**/*.md` 中的每個 `/api/...` 參照都能解析至實際的 `route.ts`(防止虛構) | 是 | +| `i18n translation drift` | i18n 語系檔案中未翻譯的鍵值——僅發出警告 | **建議性** | ### 工作:`i18n-ui-coverage` -| 指令碼 | 驗證內容 | 阻擋性 | -| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `check-ui-keys-coverage`(內嵌) | UI i18n 鍵值涵蓋率 ≥ 65% | 是 | -| `check-ui-value-drift`(內嵌) | 重寫英文**值**後,不會留下過時的翻譯 | 是 | -| `check-new-key-coverage`(內嵌) | **新增的**英文鍵值已翻譯至每個語系——不接受 `__MISSING__:` 標記 | 是 | -| `check-translation-ratio` | 各語系的實際翻譯比例(允許清單以外與英文相同/預留位置/缺漏的葉節點)不得超過 `config/quality/i18n-translation-baseline.json` + 鬆弛值 | **建議性** | +| 指令碼 | 驗證內容 | 阻擋性 | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `check-ui-keys-coverage`(內嵌) | UI i18n 鍵值涵蓋率 ≥ 65% | 是 | +| `check-ui-value-drift`(內嵌) | 改寫英文**值**後,不會留下過時的翻譯 | 是 | +| `check-new-key-coverage`(內嵌) | **新增的**英文鍵值已在每個語系中翻譯——拒絕 `__MISSING__:` 標記 | 是 | +| `check-translation-ratio` | 每個語系的實際翻譯比例(與英文相同/預留位置/缺漏的葉節點,不含允許清單內項目)不得超過 `config/quality/i18n-translation-baseline.json` + 寬限值 | **建議性** | -需要 `fetch-depth: 0`——值漂移閘門會將 `en.json` 與合併基底進行差異比較。 +需要 `fetch-depth: 0`——值漂移閘門會比較 `en.json` 與合併基準之間的差異。 #### `check-ui-value-drift`——過時翻譯閘門 -捕捉其他閘門在結構上無法發現的那一類 i18n 迴歸:英文值 -已被重寫,但從_先前_英文衍生的翻譯仍然保留,因此 -非英語使用者會繼續讀到語氣確定、但如今已不正確的文案。 +捕捉其他閘門在結構上無法發現的一種 i18n 迴歸:英文值已遭改寫, +但衍生自_先前_英文內容的翻譯仍被保留下來,導致非英語使用者繼續讀到語氣肯定、 +但如今已不正確的文案。 -這確實曾發佈至正式環境。Antigravity -登入輔助工具推出時(#5203),`oauthModal.googleOAuthWarning` 被重寫;**43 個語系中有 39 個** -仍保留文字,要求操作人員「複製完整 URL 並貼到下方」——對該提供者而言,此流程根本無法完成。直到 #8463 才被發現,原因如下: +這確實曾發布到正式環境。Antigravity 登入輔助工具上線時(#5203), +`oauthModal.googleOAuthWarning` 曾被改寫;**43 個語系中有 39 個**仍保留告知操作人員「複製完整 URL 並貼到下方」的文字——對該提供者而言,此流程根本無法完成。直到 #8463 才有人發現,原因如下: -- `sync-ui-keys` 只會回填**缺少**的鍵值,絕不處理**過時**的鍵值; -- `check-ui-keys-coverage` 計算鍵值是否_存在_,因此過時翻譯仍會被視為已涵蓋; +- `sync-ui-keys` 只會回填**不存在**的鍵值,絕不處理**過時**的鍵值; +- `check-ui-keys-coverage` 計算的是鍵值是否_存在_,因此過時翻譯仍會被視為已涵蓋; - `check-translation-drift` 追蹤的是 `docs/i18n//**.md` 文件鏡像—— - 它從不讀取 `src/i18n/messages/*.json`。自 2026-09 重新同步後,已在工作 `docs-sync-strict` 中設為阻擋性檢查:編輯核心文件 → `npm run i18n:run -- --files=`(章節層級,成本低)。 + 它從不讀取 `src/i18n/messages/*.json`。自 2026-09 重新同步起,在工作 `docs-sync-strict` 中具阻擋性:編輯核心文件 → `npm run i18n:run -- --files=`(以章節為單位,成本低)。 -**感知差異,而非以基準檔為依據。** 它會比較合併基準點的 `en.json` 與 -工作樹;對於英文值已變更的每個鍵,任何仍保留未修改翻譯的語系都會被視為過時。這會刻意 -**凍結既有債務**——差異無法揭示長期存在的翻譯源自哪個舊英文,因此此關卡 -只會判斷目前變更所觸及的內容。替代方案(每個鍵各自使用雜湊基準)將產生一個約 -600 KB 的生成檔案,是現有最大基準檔的 3 倍,且會在每個 i18n PR 中反覆變動。 +**感知差異,而非以基準為依據。** 它會比較合併基準點上的 `en.json` 與 +工作樹;對於每個英文值已變更的鍵,任何仍保留未修改翻譯的語系都會被視為過時。這刻意 +**凍結既有技術債**——差異無法顯示長期存在的翻譯源自哪個舊版英文,因此此閘門 +只判斷目前變更所觸及的內容。替代方案(每個鍵各自採用雜湊基準)將需要一個約 600 KB +的產生檔案,是目前最大基準檔案的 3 倍,且每個 i18n PR 都會造成大量變動。 -有兩種方式可以滿足此要求: +有兩種方式可滿足此要求: 1. 更新受影響的翻譯,或 -2. 將它們設為 `__MISSING__:`——執行階段之後會提供修正後的英文 - (`src/i18n/request.ts::deepMergeFallback`, #7258),並將該鍵排入翻譯佇列。 +2. 將它們設為 `__MISSING__:`——執行階段隨後會提供修正後的英文 + (`src/i18n/request.ts::deepMergeFallback`,#7258),並將該鍵排入翻譯佇列。 -如果字串的**含義**有所變更,請優先考慮**重新命名鍵**:新鍵不會繼承 -過時的翻譯。#8463 採用的就是這種模式。 +如果字串的**含義**已變更,請優先選擇**重新命名該鍵**:新鍵不會繼承 +過時的翻譯。#8463 採用的就是此模式。 ```bash npm run i18n:check-value-drift # 嚴格模式(CI 執行的模式) @@ -220,48 +217,48 @@ npm run i18n:check-value-drift:warn # 僅回報 BASE_REF=origin/release/vX.Y.Z npm run i18n:check-value-drift ``` -當無法讀取基準目錄時(淺層複製中沒有基準參照),會以 `SKIP reason=base-unresolved` -及狀態碼 0 結束,與 `check-openapi-breaking` 的行為一致。 +當無法讀取基礎目錄(未包含基礎參照的淺層複製)時,會以 0 結束並顯示 +`SKIP reason=base-unresolved`,與 `check-openapi-breaking` 的行為一致。 -### 作業:`i18n` +### 工作:`i18n` -完整的 i18n 驗證矩陣(每個語系各一個作業)。整個作業僅供參考。 +完整的 i18n 驗證矩陣(每個語系一個工作)。整個工作僅供參考。 | 指令碼 | 驗證內容 | 是否阻擋 | | ------------------------------- | ------------------ | -------------------------------------------------------- | -| `validate_translation.py quick` | 各語系的翻譯完整性 | **僅供參考**(整個作業皆設為 `continue-on-error: true`) | +| `validate_translation.py quick` | 各語系的翻譯完整性 | **僅供參考**(整個工作設定為 `continue-on-error: true`) | -### 作業:`pr-test-policy` +### 工作:`pr-test-policy` 僅在提取要求上執行。 -| 指令碼 | 驗證內容 | 是否阻擋 | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------- | -------- | -| `check:pr-test-policy` | 變更 `src/`、`open-sse/`、`electron/` 或 `bin/` 中正式環境程式碼的 PR,必須包含或更新測試(強制規則 #8) | 是 | -| `check:test-masking` | 變更的測試檔案不得減少斷言淨數量,亦不得新增 `assert.ok(true)` 恆真式 | 是 | -| `check:pr-evidence` | PR 內文必須引用此變更的測試/VPS 證據(透過 grep 搜尋 PR 文字,將強制規則 #18 機制化——此方式較脆弱,請參閱待辦清單) | 是 | +| 指令碼 | 驗證內容 | 是否阻擋 | +| ---------------------- | ----------------------------------------------------------------------------------------------------------- | -------- | +| `check:pr-test-policy` | 變更 `src/`、`open-sse/`、`electron/` 或 `bin/` 中正式環境程式碼的 PR,必須包含或更新測試(強制規則 #8) | 是 | +| `check:test-masking` | 已變更的測試檔案不得降低斷言淨數量,亦不得新增 `assert.ok(true)` 恆真式 | 是 | +| `check:pr-evidence` | PR 內文須引用此變更的測試/VPS 證據(透過搜尋 PR 文字將強制規則 #18 機械化——此方式並不穩健,請參閱待辦清單) | 是 | -### 作業:`test-vitest` +### 工作:`test-vitest` -在 `build` 後執行。失敗時會阻止合併。 +在 `build` 之後執行。失敗時會阻止合併。 -| 測試套件 | 驗證內容 | 是否阻擋 | -| ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------- | -| `test:vitest` | MCP 伺服器(110 個工具)、autoCombo、快取——vitest 執行器 | 是 | -| `test:vitest:ui` | UI 元件測試——vitest 執行器 | **會阻擋**——`vitest.config.ts` 中已明確排除既有失敗;新的失敗會導致作業失敗 | +| 測試套件 | 驗證內容 | 是否阻擋 | +| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------------------- | +| `test:vitest` | MCP 伺服器(110 個工具)、autoCombo、快取——vitest 執行器 | 是 | +| `test:vitest:ui` | UI 元件測試——vitest 執行器 | **阻擋**——既有失敗已在 `vitest.config.ts` 中明確排除;新的失敗會使工作失敗 | ### 每夜工作流程(排程執行,僅供參考) -這些工作流程會依 cron 排程執行(也可透過 `workflow_dispatch` 執行),絕不會在 PR 上執行。全部都僅供參考。 +這些工作流程依 cron 排程(以及 `workflow_dispatch`)執行,絕不會在 PR 上執行。全部僅供參考。 | 工作流程 | 驗證內容 | 是否阻擋 | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------ | | `nightly-property` | 使用隨機種子與高執行次數的 fast-check 屬性測試 | **僅供參考** | -| `nightly-resilience` | 堆積成長關卡、混沌故障注入、k6 負載/浸泡測試 | **僅供參考** | -| `nightly-llm-security` | promptfoo 注入防護(阻擋模式)+ garak 探測(沒有提供者密鑰時略過) | **僅供參考** | -| `nightly-schemathesis` | 針對即時 OmniRoute,使用 `docs/openapi.yaml` 進行 OpenAPI 合約模糊測試(schemathesis)——揭露規格違規/未處理的 500 錯誤(階段 8 B.4) | **僅供參考** | -| `nightly-mutation` | 對快速單元測試通道執行 Stryker 突變測試評分——存活的突變體可揭露薄弱的斷言 | **僅供參考** | -| `nightly-compat` | 跨受支援 `engines.node` 範圍的 Node 引擎相容性矩陣 | **僅供參考** | +| `nightly-resilience` | 堆積成長閘門、混沌故障注入、k6 負載/浸泡測試 | **僅供參考** | +| `nightly-llm-security` | promptfoo 注入防護(阻擋模式)+ garak 探測(沒有提供者密鑰時會略過) | **僅供參考** | +| `nightly-schemathesis` | 使用 `docs/openapi.yaml`,針對即時 OmniRoute 進行 OpenAPI 合約模糊測試(schemathesis)——揭露規格違規/未處理的 500 錯誤(階段 8 B.4) | **僅供參考** | +| `nightly-mutation` | 對快速單元測試通道進行 Stryker 突變測試評分——存活的突變體會揭露薄弱的斷言 | **僅供參考** | +| `nightly-compat` | 涵蓋受支援 `engines.node` 範圍的 Node 引擎相容性矩陣 | **僅供參考** | --- @@ -508,43 +505,42 @@ JSON,十秒即可完成,也是解除紅燈 PR 阻塞最快的方法。 --- -## 合理化待辦清單(ROI 審查 — 第 9 階段第 3 波) +## 合理化待辦清單(ROI 審查 — 階段 9 波次 3) -此清單已於 2026-06-17 依據 `ci.yml` 完成核對(先前版本遺漏了 +此清單已於 2026-06-17 依據 `ci.yml` 進行核對(先前版本遺漏了 `audit:deps`、`check:tracked-artifacts`、`check:lockfile`、`check:licenses`、 `check:dead-code`、`check:cognitive-complexity`、`check:type-coverage`、 -`check:codeql-ratchet`、`check:pr-evidence`)。對核對後集合進行的 ROI 審查 -找出了下列合理化候選項目。**合併屬於機械式 CI -變更;切換/移除則是保留給操作者決定的政策事項。** 以下內容 -尚未套用。 +`check:codeql-ratchet`、`check:pr-evidence`)。對核對後集合進行 ROI 審查, +找出了以下合理化候選項目。**合併屬於機械式 CI 變更;切換/移除則是保留給操作人員的政策決策。** +以下內容尚未套用。 -**上文亦未記載**(諮詢性質、訊號偏低):`docs-lint` 工作 -(markdownlint + Vale,整個工作設定 `continue-on-error`),以及獨立的掃描器工作流程 +**上方亦未記錄的項目**(建議性、訊號偏弱):`docs-lint` 工作 +(markdownlint + Vale,整個工作設定為 `continue-on-error`),以及獨立的掃描器工作流程 `semgrep.yml` / `codeql.yml` / `scorecard.yml`。`semgrepFindings: 0` 位於 -`quality-baseline.json` 中,但尚未連接至 `ci.yml` 內的阻擋式棘輪機制——此指標 +`quality-baseline.json` 中,但並未連接到 `ci.yml` 內具阻擋效果的棘輪機制——此指標 目前處於孤立狀態。 ### 合併/去重(機械式、風險較低) -每個候選項目都已於 2026-06-17 依照實際閘門狀態完成驗證(信任但須查證); -數個「顯而易見」的合併實際上隱藏了技術債,**並非**可直接替換的乾淨方案。 - -- **`check:docs-sync` 執行兩次**——在 `lint` 工作中獨立執行一次,並在 `check:docs-all`(`docs-sync-strict`)與 husky pre-commit hook 中再次執行。✅ **已完成**——已移除 `lint` 中的獨立呼叫。 -- **CVE 掃描**——❌ **無法乾淨合併。** `audit:deps` 遇到任何高風險/嚴重 CVE 時都會直接失敗;`check:vuln-ratchet`(osv)僅在相較基準線出現_退步_時失敗(目前為 1 個 MODERATE)。兩者語意不同——移除 `audit:deps` 將失去高風險/嚴重漏洞的絕對閘門。保留兩者。 -- **循環相依偵測**——❌ **無法乾淨合併。** `check:circular-deps`(dpdm)回報 **91 個循環**(這正是其僅具諮詢性質的原因);在先解決這些循環之前,無法將其提升為阻擋項目,而且其範圍比目前通過且經過篩選的 `check:cycles` 更廣。保留 `check:cycles` 的阻擋性;解決 91 個 dpdm 循環本身是另一項待辦事項。 -- **複雜度**——✅ **已完成**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`):單次 ESLint 掃描,依 ruleId 計數,使循環複雜度 + max-lines 與認知複雜度基準線維持獨立;個別的 `check:complexity` / `check:cognitive-complexity` 保留供本機使用 `--update`。 -- **`/api` 反幻覺檢查**——✅ **已完成**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`):對 `src/app/api` 進行單次 FS 清查,openapi-routes + docs-symbols 仍會各自回報;個別檢查保留供本機執行。 -- **`check:node-runtime` 在 11 個工作中執行**——⚠️ **ROI 偏低。** 每個工作都使用獨立 runner,且檢查耗時不到 1 秒;總計僅節省約 10 秒,代價卻是失去低成本的逐工作防護。不值得為此折騰。 -- **CI lint 上的 `typecheck:noimplicit:core`**——✅ **已從 lint 工作移除**(原為設定 `continue-on-error` 的諮詢性檢查);阻擋式類型介面由 `typecheck:core` + `check:type-coverage` 負責。本機腳本保留。 - -### 切換/決策(操作者政策) - -- `check:openapi-security-tiers`(諮詢性)——❌ **無法直接切換。** 它以 0 結束,但會警告 `LOCAL_ONLY_API_PREFIXES` 下數個 `traffic-inspector` 路由缺少 `x-loopback-only: true` 註解。若要強制執行,必須先將這些註解加入 `openapi.yaml`。 -- `typecheck:noimplicit:core`(諮詢性)——大致已由阻擋式 `check:type-coverage` 棘輪機制涵蓋。將其切換為棘輪機制,或移除重複的第二次 `tsc` 掃描。 -- `test:vitest:ui`(現在為**阻擋式**)——既有失敗已在 `vitest.config.ts` 中明確排除,並附上 `// #8618` 追蹤註解;新的失敗會使工作失敗。 -- `check:secrets`(gitleaks,阻擋式棘輪機制固定於 3 個已記錄的誤報)——將這 3 個項目加入允許清單以降至 0,或降級為諮詢性檢查。與 GitHub 原生秘密掃描 + `check:public-creds` 重疊。 -- `check:pr-evidence`(阻擋式,使用 grep 搜尋 PR 正文文字)——誤報風險高;若移除會削弱對強制規則 #18 的執行,因此這確實是一項政策決策。 -- `semgrep`(諮詢性獨立工作流程)——在 OWASP 類別方面與 CodeQL 重疊;將其基準線接入棘輪機制,或予以移除。 +每個候選項目都已於 2026-06-17 對照實際閘門狀態進行驗證(信任但要查證); +數個「顯而易見」的合併其實隱藏了技術債,**並非**可直接替換的乾淨方案。 + +- **`check:docs-sync` 執行兩次**——在 `lint` 工作中獨立執行一次,並於 `check:docs-all`(`docs-sync-strict`)和 husky pre-commit hook 中再次執行。✅ **已完成**——已移除 `lint` 中的獨立呼叫。 +- **CVE 掃描**——❌ **不是乾淨的合併。** `audit:deps` 遇到任何高/嚴重 CVE 時都會直接失敗;`check:vuln-ratchet`(osv)僅在相較基準發生_退步_時失敗(目前為 1 個 MODERATE)。兩者語意不同——移除 `audit:deps` 將失去絕對的高/嚴重風險閘門。兩者皆保留。 +- **循環偵測**——✅ **已完成**(#15159 G-01/G-02)。此處舊文字將 `check:cycles` 稱為「綠燈、經過篩選的」閘門,並因 `check:circular-deps`(dpdm)回報 91 個循環,而主張其應繼續作為阻擋閘門。該綠燈其實是**假綠燈**:`check:cycles` 僅掃描 5 個子目錄(450 個檔案)、只比對靜態的 `import|export … from`,並捨棄所有 `@/` 和 `@omniroute/open-sse/` 說明符,因此無法看見存放庫中占主導地位的動態匯入 + 別名循環。現已修正:閘門目前會遍歷 `src` + `open-sse`(5023 個檔案),從 TypeScript AST 收集說明符(因此 `import("…")` 會計入,而類型位置的 `typeof import("…")` 不會),並解析 tsconfig `paths`。它找出了 **14** 個循環,而非 0。由於無法在閘門 PR 中修正 14 個既有循環,`check:cycles` 現已改為**棘輪機制**(`--ratchet`,`quality-baseline.json` 中的上限為 `metrics.cycles.value = 14`,`direction: down`)——它會阻擋任何_退步_,且數量只能下降。CI 執行 `npm run check:cycles:ratchet`。逐步消減工作併入 **A-01**。`check:circular-deps`(dpdm)保留為涵蓋範圍更廣的建議性第二意見。 +- **複雜度**——✅ **已完成**(`check:complexity-ratchets` / `eslint.complexity-ratchets.config.mjs`):只進行一次 ESLint 遍歷,依 ruleId 計數,使循環複雜度 + 最大行數與認知複雜度的基準維持獨立;個別的 `check:complexity` / `check:cognitive-complexity` 則保留供本機使用 `--update`。 +- **`/api` 反幻覺**——✅ **已完成**(`check:api-docs-refs` + `scripts/check/lib/apiRoutes.mjs`):只對 `src/app/api` 進行一次 FS 清查,openapi-routes + docs-symbols 仍會各自獨立回報;個別檢查保留供本機執行。 +- **`check:node-runtime` 會在 11 個工作中執行**——⚠️ **ROI 偏低。** 每個工作皆使用獨立 runner,而此檢查耗時不到 1 秒;總共僅節省約 10 秒,代價卻是失去成本低廉的逐工作防護。不值得為此進行改動。 +- **CI lint 上的 `typecheck:noimplicit:core`**——✅ **已從 lint 工作中移除**(原本是建議性的 `continue-on-error`);具阻擋效果的類型檢查面為 `typecheck:core` + `check:type-coverage`。本機腳本則予以保留。 + +### 切換/決策(操作人員政策) + +- `check:openapi-security-tiers`(建議性)——❌ **無法直接切換。** 它會以 0 結束,但會警告 `LOCAL_ONLY_API_PREFIXES` 下有數個 `traffic-inspector` 路由缺少 `x-loopback-only: true` 註解。若要強制執行,必須先將這些註解新增至 `openapi.yaml`。 +- `typecheck:noimplicit:core`(建議性)——大致已由具阻擋效果的 `check:type-coverage` 棘輪機制涵蓋。可將其切換為棘輪機制,或移除重複的第二次 `tsc` 執行。 +- `test:vitest:ui`(目前**具阻擋效果**)——既有失敗已在 `vitest.config.ts` 中透過 `// #8618` 追蹤註解明確排除;新的失敗會使工作失敗。 +- `check:secrets`(gitleaks,具阻擋效果的棘輪機制,凍結於 3 個已記錄的誤報)——將這 3 個項目加入允許清單以降至 0,或降級為建議性。與 GitHub 原生秘密掃描 + `check:public-creds` 有重疊。 +- `check:pr-evidence`(具阻擋效果,對 PR 內文執行 grep)——誤報風險高;若移除,將削弱硬性規則 #18 的執行力,因此這是真正的政策決策。 +- `semgrep`(建議性的獨立工作)——在 OWASP 類別上與 CodeQL 重疊;將其基準連接至棘輪機制,或予以移除。 ---