@jantstack/adonis-authz 2.0.0-alpha.1 → 2.4.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +693 -36
  2. package/build/commands/authz_catalog_diff.js +1 -1
  3. package/build/commands/authz_catalog_diff.js.map +1 -1
  4. package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
  5. package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
  6. package/build/commands/authz_catalog_prune_orphans.js +136 -0
  7. package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
  8. package/build/commands/authz_catalog_sync.d.ts +17 -0
  9. package/build/commands/authz_catalog_sync.d.ts.map +1 -1
  10. package/build/commands/authz_catalog_sync.js +27 -4
  11. package/build/commands/authz_catalog_sync.js.map +1 -1
  12. package/build/commands/authz_freeze.d.ts +44 -0
  13. package/build/commands/authz_freeze.d.ts.map +1 -0
  14. package/build/commands/authz_freeze.js +95 -0
  15. package/build/commands/authz_freeze.js.map +1 -0
  16. package/build/commands/authz_reconcile.d.ts +102 -0
  17. package/build/commands/authz_reconcile.d.ts.map +1 -0
  18. package/build/commands/authz_reconcile.js +294 -0
  19. package/build/commands/authz_reconcile.js.map +1 -0
  20. package/build/commands/authz_relations_reconcile.d.ts +97 -0
  21. package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
  22. package/build/commands/authz_relations_reconcile.js +313 -0
  23. package/build/commands/authz_relations_reconcile.js.map +1 -0
  24. package/build/commands/authz_scopes_relay.d.ts +47 -0
  25. package/build/commands/authz_scopes_relay.d.ts.map +1 -0
  26. package/build/commands/authz_scopes_relay.js +141 -0
  27. package/build/commands/authz_scopes_relay.js.map +1 -0
  28. package/build/commands/authz_unfreeze.d.ts +37 -0
  29. package/build/commands/authz_unfreeze.d.ts.map +1 -0
  30. package/build/commands/authz_unfreeze.js +92 -0
  31. package/build/commands/authz_unfreeze.js.map +1 -0
  32. package/build/commands/main.d.ts +6 -1
  33. package/build/commands/main.d.ts.map +1 -1
  34. package/build/commands/main.js +6 -1
  35. package/build/commands/main.js.map +1 -1
  36. package/build/commands/openfga_provision.d.ts +46 -4
  37. package/build/commands/openfga_provision.d.ts.map +1 -1
  38. package/build/commands/openfga_provision.js +90 -7
  39. package/build/commands/openfga_provision.js.map +1 -1
  40. package/build/configure.d.ts +11 -0
  41. package/build/configure.d.ts.map +1 -1
  42. package/build/configure.js +37 -1
  43. package/build/configure.js.map +1 -1
  44. package/build/index.d.ts +50 -10
  45. package/build/index.d.ts.map +1 -1
  46. package/build/index.js +45 -6
  47. package/build/index.js.map +1 -1
  48. package/build/providers/authz_provider.d.ts +26 -2
  49. package/build/providers/authz_provider.d.ts.map +1 -1
  50. package/build/providers/authz_provider.js +55 -2
  51. package/build/providers/authz_provider.js.map +1 -1
  52. package/build/services/relations.d.ts +14 -0
  53. package/build/services/relations.d.ts.map +1 -0
  54. package/build/services/relations.js +17 -0
  55. package/build/services/relations.js.map +1 -0
  56. package/build/src/{catalog.d.ts → catalog/catalog.d.ts} +41 -2
  57. package/build/src/catalog/catalog.d.ts.map +1 -0
  58. package/build/src/{catalog.js → catalog/catalog.js} +120 -14
  59. package/build/src/catalog/catalog.js.map +1 -0
  60. package/build/src/{catalog_cache.d.ts → catalog/catalog_cache.d.ts} +46 -22
  61. package/build/src/catalog/catalog_cache.d.ts.map +1 -0
  62. package/build/src/{catalog_cache.js → catalog/catalog_cache.js} +53 -43
  63. package/build/src/catalog/catalog_cache.js.map +1 -0
  64. package/build/src/define_config.d.ts +137 -3
  65. package/build/src/define_config.d.ts.map +1 -1
  66. package/build/src/define_config.js.map +1 -1
  67. package/build/src/drivers/database_driver.d.ts +128 -7
  68. package/build/src/drivers/database_driver.d.ts.map +1 -1
  69. package/build/src/drivers/database_driver.js +510 -24
  70. package/build/src/drivers/database_driver.js.map +1 -1
  71. package/build/src/drivers/database_relations_driver.d.ts +113 -0
  72. package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
  73. package/build/src/drivers/database_relations_driver.js +679 -0
  74. package/build/src/drivers/database_relations_driver.js.map +1 -0
  75. package/build/src/drivers/openfga_driver.d.ts +729 -122
  76. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  77. package/build/src/drivers/openfga_driver.js +2083 -476
  78. package/build/src/drivers/openfga_driver.js.map +1 -1
  79. package/build/src/drivers/openfga_facts.d.ts +384 -0
  80. package/build/src/drivers/openfga_facts.d.ts.map +1 -0
  81. package/build/src/drivers/openfga_facts.js +836 -0
  82. package/build/src/drivers/openfga_facts.js.map +1 -0
  83. package/build/src/drivers/openfga_relations_driver.d.ts +141 -0
  84. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
  85. package/build/src/drivers/openfga_relations_driver.js +590 -0
  86. package/build/src/drivers/openfga_relations_driver.js.map +1 -0
  87. package/build/src/errors.d.ts +290 -5
  88. package/build/src/errors.d.ts.map +1 -1
  89. package/build/src/errors.js +296 -7
  90. package/build/src/errors.js.map +1 -1
  91. package/build/src/freeze.d.ts +141 -0
  92. package/build/src/freeze.d.ts.map +1 -0
  93. package/build/src/freeze.js +217 -0
  94. package/build/src/freeze.js.map +1 -0
  95. package/build/src/http/app_access_middleware.d.ts.map +1 -0
  96. package/build/src/http/app_access_middleware.js.map +1 -0
  97. package/build/src/http/resource_access_middleware.d.ts +105 -0
  98. package/build/src/http/resource_access_middleware.d.ts.map +1 -0
  99. package/build/src/http/resource_access_middleware.js +81 -0
  100. package/build/src/http/resource_access_middleware.js.map +1 -0
  101. package/build/src/identity.d.ts +74 -1
  102. package/build/src/identity.d.ts.map +1 -1
  103. package/build/src/identity.js +100 -2
  104. package/build/src/identity.js.map +1 -1
  105. package/build/src/manager.d.ts +330 -4
  106. package/build/src/manager.d.ts.map +1 -1
  107. package/build/src/manager.js +1285 -188
  108. package/build/src/manager.js.map +1 -1
  109. package/build/src/models/authz_assignment.d.ts +7 -7
  110. package/build/src/models/authz_assignment.d.ts.map +1 -1
  111. package/build/src/models/authz_deny.d.ts +7 -7
  112. package/build/src/models/authz_deny.d.ts.map +1 -1
  113. package/build/src/models/authz_permission.d.ts +7 -7
  114. package/build/src/models/authz_permission.d.ts.map +1 -1
  115. package/build/src/models/authz_role.d.ts +7 -7
  116. package/build/src/models/authz_role.d.ts.map +1 -1
  117. package/build/src/models/authz_role_permission.d.ts +7 -7
  118. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  119. package/build/src/openfga.d.ts +18 -2
  120. package/build/src/openfga.d.ts.map +1 -1
  121. package/build/src/openfga.js +15 -1
  122. package/build/src/openfga.js.map +1 -1
  123. package/build/src/reconcile.d.ts +37 -0
  124. package/build/src/reconcile.d.ts.map +1 -0
  125. package/build/src/reconcile.js +69 -0
  126. package/build/src/reconcile.js.map +1 -0
  127. package/build/src/relation_partition_trigger.d.ts +8 -0
  128. package/build/src/relation_partition_trigger.d.ts.map +1 -0
  129. package/build/src/relation_partition_trigger.js +93 -0
  130. package/build/src/relation_partition_trigger.js.map +1 -0
  131. package/build/src/relations/define_relations_config.d.ts +75 -0
  132. package/build/src/relations/define_relations_config.d.ts.map +1 -0
  133. package/build/src/relations/define_relations_config.js +173 -0
  134. package/build/src/relations/define_relations_config.js.map +1 -0
  135. package/build/src/relations/manager.d.ts +60 -0
  136. package/build/src/relations/manager.d.ts.map +1 -0
  137. package/build/src/relations/manager.js +213 -0
  138. package/build/src/relations/manager.js.map +1 -0
  139. package/build/src/relations/reconcile.d.ts +111 -0
  140. package/build/src/relations/reconcile.d.ts.map +1 -0
  141. package/build/src/relations/reconcile.js +200 -0
  142. package/build/src/relations/reconcile.js.map +1 -0
  143. package/build/src/relations_config_store.d.ts +22 -0
  144. package/build/src/relations_config_store.d.ts.map +1 -0
  145. package/build/src/relations_config_store.js +74 -0
  146. package/build/src/relations_config_store.js.map +1 -0
  147. package/build/src/scope_outbox.d.ts +69 -0
  148. package/build/src/scope_outbox.d.ts.map +1 -0
  149. package/build/src/scope_outbox.js +298 -0
  150. package/build/src/scope_outbox.js.map +1 -0
  151. package/build/src/{drivers → shared}/backend_guard.d.ts +42 -0
  152. package/build/src/shared/backend_guard.d.ts.map +1 -0
  153. package/build/src/{drivers → shared}/backend_guard.js +78 -1
  154. package/build/src/shared/backend_guard.js.map +1 -0
  155. package/build/src/shared/sql_expiry.d.ts.map +1 -0
  156. package/build/src/shared/sql_expiry.js.map +1 -0
  157. package/build/src/shared/transaction_guard.d.ts +50 -0
  158. package/build/src/shared/transaction_guard.d.ts.map +1 -0
  159. package/build/src/shared/transaction_guard.js +60 -0
  160. package/build/src/shared/transaction_guard.js.map +1 -0
  161. package/build/src/sql_descendants.d.ts +47 -1
  162. package/build/src/sql_descendants.d.ts.map +1 -1
  163. package/build/src/sql_descendants.js +75 -1
  164. package/build/src/sql_descendants.js.map +1 -1
  165. package/build/src/testing/contract.d.ts +129 -4
  166. package/build/src/testing/contract.d.ts.map +1 -1
  167. package/build/src/testing/contract.js +912 -177
  168. package/build/src/testing/contract.js.map +1 -1
  169. package/build/src/testing/main.d.ts +8 -2
  170. package/build/src/testing/main.d.ts.map +1 -1
  171. package/build/src/testing/main.js +4 -1
  172. package/build/src/testing/main.js.map +1 -1
  173. package/build/src/testing/migration_contract.d.ts +284 -0
  174. package/build/src/testing/migration_contract.d.ts.map +1 -0
  175. package/build/src/testing/migration_contract.js +586 -0
  176. package/build/src/testing/migration_contract.js.map +1 -0
  177. package/build/src/testing/relations_contract.d.ts +73 -0
  178. package/build/src/testing/relations_contract.d.ts.map +1 -0
  179. package/build/src/testing/relations_contract.js +1069 -0
  180. package/build/src/testing/relations_contract.js.map +1 -0
  181. package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
  182. package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
  183. package/build/src/testing/relations_reconcile_contract.js +220 -0
  184. package/build/src/testing/relations_reconcile_contract.js.map +1 -0
  185. package/build/src/traits/authz_scopes.js +1 -1
  186. package/build/src/traits/authz_scopes.js.map +1 -1
  187. package/build/src/traits/has_uuid.d.ts +8 -8
  188. package/build/src/traits/has_uuid.d.ts.map +1 -1
  189. package/build/src/types.d.ts +1053 -83
  190. package/build/src/types.d.ts.map +1 -1
  191. package/build/src/types.js +10 -0
  192. package/build/src/types.js.map +1 -1
  193. package/build/stubs/config/authorization.stub +104 -4
  194. package/build/stubs/migration.stub +136 -0
  195. package/build/stubs/scopes_outbox_migration.stub +57 -0
  196. package/package.json +4 -2
  197. package/build/commands/openfga_import.d.ts +0 -34
  198. package/build/commands/openfga_import.d.ts.map +0 -1
  199. package/build/commands/openfga_import.js +0 -97
  200. package/build/commands/openfga_import.js.map +0 -1
  201. package/build/src/catalog.d.ts.map +0 -1
  202. package/build/src/catalog.js.map +0 -1
  203. package/build/src/catalog_cache.d.ts.map +0 -1
  204. package/build/src/catalog_cache.js.map +0 -1
  205. package/build/src/drivers/backend_guard.d.ts.map +0 -1
  206. package/build/src/drivers/backend_guard.js.map +0 -1
  207. package/build/src/drivers/sql_expiry.d.ts.map +0 -1
  208. package/build/src/drivers/sql_expiry.js.map +0 -1
  209. package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
  210. package/build/src/middleware/app_access_middleware.js.map +0 -1
  211. /package/build/src/{middleware → http}/app_access_middleware.d.ts +0 -0
  212. /package/build/src/{middleware → http}/app_access_middleware.js +0 -0
  213. /package/build/src/{drivers → shared}/sql_expiry.d.ts +0 -0
  214. /package/build/src/{drivers → shared}/sql_expiry.js +0 -0
@@ -1,5 +1,6 @@
1
1
  import type { AuthorizationConfig } from './define_config.js';
2
- import type { AuthorizationDriver, AuthorizedScopes, CatalogRole, DenyOptions, DenyRef, ExcludedSubtree, GrantOptions, GrantOutcome, RoleQuery, ScopeDetachOutcome, ScopedRoleChanges, ScopedRoleSpec, ScopedWriteOptions, ScopeRef, ScopeType, SubjectRef } from './types.js';
2
+ import type { FreezeKind, FreezeToken } from './freeze.js';
3
+ import type { AuthorizationDriver, AuthorizedScopes, CatalogRole, CatalogRoleRef, DenyOptions, DenyRef, ExcludedSubtree, GrantOptions, GrantOutcome, RoleQuery, ScopedRoleChanges, ScopedRoleSpec, ReconcileOptions, ReconcileReport, ScopedWriteOptions, ScopeRelayReport, ScopeRef, ScopeTreeWriteOptions, ScopeType, SubjectRef } from './types.js';
3
4
  /**
4
5
  * Lo que devuelve `AuthorizationManager.forRequest()`: la misma API que el
5
6
  * manager (lecturas, escrituras, `scopes.*`), con los ancestros memoizados
@@ -25,6 +26,14 @@ export declare const DEFAULT_MAX_DESCENDANTS = 10000;
25
26
  * Una cota mayor es config rota (500), nunca una pregunta.
26
27
  */
27
28
  export declare const MAX_SCOPE_BOUND = 10000000;
29
+ /**
30
+ * Cotas por defecto de `authz:scopes:relay` (3b-2d). El lote es el tamaño de
31
+ * cada `pending()`; el límite, cuántos cambios aplica una pasada antes de
32
+ * volver (lo que quede sigue pendiente: drenar es reanudable por diseño y
33
+ * una pasada eterna no es reanudable).
34
+ */
35
+ export declare const DEFAULT_RELAY_BATCH = 100;
36
+ export declare const DEFAULT_RELAY_LIMIT = 10000;
28
37
  /** Vida por defecto de una vista de `forRequest()` para LEER (F9): un request, no un módulo. */
29
38
  export declare const DEFAULT_VIEW_MAX_AGE_MS = 30000;
30
39
  export interface ForRequestOptions {
@@ -45,6 +54,27 @@ export interface ForRequestOptions {
45
54
  */
46
55
  now?: () => number;
47
56
  }
57
+ /** Lo que `freezeStatus()` responde de un freeze VIVO (la fila, legible por cualquiera). */
58
+ export interface FreezeStatus {
59
+ reason: string;
60
+ holder: string;
61
+ kind: FreezeKind | 'unknown';
62
+ /** Instante (ms de pared) en el que el lease vence, o `null` si no caduca. */
63
+ untilMs: number | null;
64
+ fence: number;
65
+ }
66
+ /**
67
+ * Lo que `withFrozenWrites` le cuenta a la pasada que corre dentro (L-1 · J1):
68
+ * el fence de la ventana, su lease y si se PERDIÓ a mitad (`lapsed`), para
69
+ * que una pasada de plataforma ajena al manager publique la garantía en vez
70
+ * de suponerla (`report.frozen`).
71
+ */
72
+ export interface FrozenWindow {
73
+ fence: number;
74
+ leaseMs: number | null;
75
+ /** ¿Se perdió la ventana en algún momento? (renovación fallida, fila ajena o vencida). */
76
+ lapsed: () => Promise<boolean>;
77
+ }
48
78
  /**
49
79
  * Manager de autorización — la fachada que usan middleware, services y
50
80
  * seeders. Resuelve el driver activo del config y notifica cada escritura
@@ -91,6 +121,70 @@ export declare class AuthorizationManager {
91
121
  * sin `withClock` con `clock` declarado es 500 `E_AUTHZ_CONFIG`.
92
122
  */
93
123
  driver(): Promise<AuthorizationDriver>;
124
+ /**
125
+ * **Congela las ESCRITURAS del motor, DURABLE** (3b-7; decisión del dueño
126
+ * del 2026-08-31 (3b): B + E-analista). Operación de PLATAFORMA, como
127
+ * `driver()`: no se expone por HTTP.
128
+ *
129
+ * El estado ya NO vive en el proceso: vive en la fila `id = 2` de
130
+ * `authz_catalog_version`, así que alcanza a **todos los procesos que
131
+ * comparten las tablas `authz_*`** (invariante 14: el comando ace y los
132
+ * workers hablan con la misma base). Mientras el freeze está vivo, toda
133
+ * escritura del manager —las cuatro de hechos, las tres de árbol, la API
134
+ * de delegación, `pruneOrphanRoles({force})` y `relayScopeChanges`—
135
+ * responde 503 `E_AUTHZ_FROZEN` **reintentable** y no llega al driver; las
136
+ * LECTURAS siguen respondiendo con normalidad (la asimetría deliberada:
137
+ * `authorize` no se congela ni un milisegundo).
138
+ *
139
+ * Devuelve el **token del dueño** (`{ fence, holder }`): `unfreeze(token)`
140
+ * solo levanta el freeze cuyo token coincide — el `finally` de una ventana
141
+ * ajena o rezagada no puede levantar la tuya (auditor A1.3). Un freeze
142
+ * VIVO de otro dueño ⇒ 423 `E_AUTHZ_FREEZE_HELD`, nunca dos dueños.
143
+ *
144
+ * El **lease** (default 15 s) se renueva solo (`leaseMs / 3`, `unref()`)
145
+ * mientras este proceso vive; si el proceso muere (`SIGKILL`, OOM), el
146
+ * lease vence y la flota vuelve a escribir SOLA en ≤ `leaseMs` — nadie
147
+ * limpia nada a mano. `leaseMs: null` = sin caducidad: la ventana del
148
+ * OPERADOR (`authz:freeze`), que dura hasta su `authz:unfreeze`.
149
+ *
150
+ * Lo que el freeze **NO congela**, a propósito y documentado (auditor
151
+ * 🟠 5): `syncAuthzCatalog` (función libre que no ve al manager),
152
+ * `manager.driver()` (la salida documentada de TODAS las barreras) y el
153
+ * árbol SQL del consumidor (sus tablas, su SQL). Y lo que no puede
154
+ * prometer: una escritura que ya pasó su barrera cuando el freeze aterriza
155
+ * ENTRA (no hay atomicidad entre una fila SQL y un backend externo) — la
156
+ * promesa publicada es «otro proceso recibe 503», jamás «ninguna escritura
157
+ * entra en la ventana».
158
+ */
159
+ freeze(reason?: string, options?: {
160
+ leaseMs?: number | null;
161
+ kind?: FreezeKind;
162
+ }): Promise<FreezeToken>;
163
+ /**
164
+ * Levanta el freeze de ESTE token; uno ajeno o rezagado no toca nada (esa
165
+ * es toda la garantía del fence). Devuelve si de verdad lo levantó.
166
+ */
167
+ unfreeze(token: FreezeToken): Promise<boolean>;
168
+ /**
169
+ * ¿SOSTIENE este manager un freeze? (proceso-local: su token vive aquí.)
170
+ * Para saber si el MOTOR está congelado —por quien sea— pregunta
171
+ * `freezeStatus()`: eso es la fila, no la memoria.
172
+ */
173
+ get frozen(): boolean;
174
+ /** El freeze VIVO de la fila compartida, o `null`. Lo lee cualquiera; solo el token lo levanta. */
175
+ freezeStatus(): Promise<FreezeStatus | null>;
176
+ /**
177
+ * `freeze()` + `finally unfreeze(token)`. El `finally` es la parte que
178
+ * importa: una migración que revienta a la mitad no puede dejar la
179
+ * aplicación sin poder escribir (y si además el proceso muere sin
180
+ * `finally`, el lease vence solo). **El anidado corre DENTRO** (auditor
181
+ * A1.1/A1.3): si este manager ya sostiene el freeze, la ventana interior
182
+ * no toma otro ni lo levanta al salir — la exterior sigue en pie.
183
+ */
184
+ withFrozenWrites<T>(reason: string, fn: (window: FrozenWindow) => Promise<T>, options?: {
185
+ kind?: FreezeKind;
186
+ operatorAsContext?: boolean;
187
+ }): Promise<T>;
94
188
  /** Solo tests: fuerza re-resolución del driver. */
95
189
  clearCachedDriver(): void;
96
190
  /**
@@ -102,8 +196,21 @@ export declare class AuthorizationManager {
102
196
  * Espía: si la validación falla, cero llamadas al driver.
103
197
  */
104
198
  readonly scopes: {
105
- attached: (child: ScopeRef, parent: ScopeRef, options?: ScopedWriteOptions) => Promise<void>;
106
- moved: (child: ScopeRef, newParent: ScopeRef, options?: ScopedWriteOptions) => Promise<void>;
199
+ attached: (child: ScopeRef, parent: ScopeRef, options?: ScopeTreeWriteOptions) => Promise<void>;
200
+ /**
201
+ * `moved` NO vuelve a juzgar el catálogo, y no tiene por qué (3b-1 · D3,
202
+ * auditor 3G): mover un scope es un hecho del árbol, no una escritura de
203
+ * catálogo. Lo que hay que tener escrito es la consecuencia: la relación
204
+ * «A ensombrece a B» es función del árbol de HOY, así que un `moved` que
205
+ * mete un subárbol bajo un scope que ya tiene el homónimo **crea la
206
+ * sombra sin que se juzgue ningún rango en ninguna parte** — y el dueño
207
+ * del subárbol movido puede no poder repararla (su rango se mide en la
208
+ * cadena del owner de la sombra). Por eso «sobre un rol solo actúa quien
209
+ * lo supera en rango» (3G · W3) es una comprobación de ESCRITURA y no un
210
+ * invariante del sistema. Es ruidosa: `authz:catalog:diff` la lista como
211
+ * `shadowedByAncestor` (y `--fail-on-shadows` la cuenta como deriva).
212
+ */
213
+ moved: (child: ScopeRef, newParent: ScopeRef, options?: ScopeTreeWriteOptions) => Promise<void>;
107
214
  /**
108
215
  * Hechos primero (el driver demuestra cero o lanza), arista después
109
216
  * (S6): si la purga muere a medias, el subárbol sigue colgado y los
@@ -111,9 +218,116 @@ export declare class AuthorizationManager {
111
218
  * scope exista (el consumidor puede haber borrado ya su fila); con
112
219
  * `within` (2D · F2) el hijo tiene que seguir en el árbol para
113
220
  * contrastar su cadena: purga ANTES de borrar la fila.
221
+ *
222
+ * **Purga HECHOS y solo hechos** (invariante 11; 3b-0 · Z1). Entre 3D y
223
+ * 3G esta operación arrastraba además los roles LOCALES cuyo owner era
224
+ * ese scope (y, con `descendantsOf`, los de todo el subárbol), con su
225
+ * propia policy de rango, su degradación y un valor de retorno que
226
+ * contaba lo purgado. Cinco lotes la tocaron y TRES de las cuatro
227
+ * regresiones de la Fase 3 nacieron ahí, siempre por COMPOSICIÓN de
228
+ * piezas correctas por separado (3E · P3 + 3F · S1/S2 ⇒ 3G · W1). El
229
+ * requisito que lo pedía —un rol cuyo owner desaparece queda
230
+ * indeleteable y ocupa su `(slug, nivel)`— se resuelve más simple y
231
+ * fuera del camino de un tenant: el rol queda DORMIDO (no concede, no es
232
+ * membresía, no se asigna) y la PLATAFORMA lo retira con
233
+ * `authz:catalog:prune-orphans` (Z2). Así `scopes.detached` vuelve a ser
234
+ * O(1), sin rango que medir, sin árbol que enumerar y sin nada que
235
+ * declarar a medias.
114
236
  */
115
- detached: (child: ScopeRef, options?: ScopedWriteOptions) => Promise<ScopeDetachOutcome>;
237
+ detached: (child: ScopeRef, options?: ScopeTreeWriteOptions) => Promise<void>;
116
238
  };
239
+ /**
240
+ * **Drena la outbox del árbol y aplica los cambios al driver** (3b-2d).
241
+ * Es lo que hay detrás de `node ace authz:scopes:relay`.
242
+ *
243
+ * Operación de PLATAFORMA, como `pruneOrphanRoles`: se salta `requireActor`
244
+ * y `requireWithin` a propósito —la policy ya se juzgó al ENCOLAR, con el
245
+ * árbol y la sesión de aquel momento— así que **no se expone por HTTP**.
246
+ * Aquí solo se propaga lo que ya se validó.
247
+ *
248
+ * Reanudable y nunca silenciosa: el reporte dice QUÉ se aplicó (no un
249
+ * contador: la pasada no es atómica), qué falló, qué se aplazó y si queda
250
+ * trabajo.
251
+ *
252
+ * **El orden del árbol importa, pero solo entre cambios que se tocan**
253
+ * (3b-2h · 🔴 2, auditor R2). Hasta el 2h la pasada PARABA en el primer
254
+ * fallo, y eso convertía una entrada que ya no se puede aplicar —el padre
255
+ * del `attached` encolado se borró antes del relevo, la arista cerraría
256
+ * ahora un ciclo, el nodo acabó con dos padres— en un **tapón permanente
257
+ * para todos los tenants**: `pending()` devuelve lo no aplicado ordenado
258
+ * por id, así que la envenenada era la cabecera de la cola en TODAS las
259
+ * pasadas siguientes y ningún cambio del árbol volvía a llegar al store
260
+ * (medido: una unit nueva nunca recibía su arista `parent`, el deny de su
261
+ * organization nunca la alcanzaba y un `detached` posterior nunca purgaba).
262
+ * Ahora un fallo **contamina los scopes que nombra**: los cambios
263
+ * posteriores que tocan alguno de ellos se APLAZAN sin intentarse (y
264
+ * contaminan a su vez, así que la dependencia es transitiva), y los demás
265
+ * se aplican. El par ordenado que importaba —`attached(P, org)` antes que
266
+ * `attached(C, P)`, `moved` antes que `detached`— sigue respetado porque
267
+ * comparten scope; lo que ya no pasa es que el tenant A congele el árbol
268
+ * del tenant B.
269
+ *
270
+ * **Escritor ÚNICO** (3b-2h · 🟠 4): si la outbox sabe dar un lease
271
+ * (`acquire`), la pasada lo toma y una segunda pasada simultánea no hace
272
+ * nada y lo dice (`busy`). Sin lease, dos pasadas trabajan sobre el mismo
273
+ * lote —`pending()` no reserva y el lote no se relee— y la rezagada
274
+ * re-aplica cambios viejos sobre el árbol nuevo.
275
+ *
276
+ * Lo que esta pieza NO arregla, y va escrito en el README con estas
277
+ * palabras: entre el commit del consumidor y esta pasada hay un lag
278
+ * (segundos) durante el cual el backend decide con el árbol VIEJO. Es un
279
+ * **fail-open temporal** —el tenant antiguo conserva acceso tras un
280
+ * `moved`, los denies heredados no aplican tras un `attached`—. No hay
281
+ * 2PC; es el precio de tener el árbol en dos sitios.
282
+ */
283
+ relayScopeChanges(options?: {
284
+ limit?: number;
285
+ batchSize?: number;
286
+ dryRun?: boolean;
287
+ }): Promise<ScopeRelayReport>;
288
+ /**
289
+ * **`authz:reconcile --to=<driver>`** (3b-3a): la ÚNICA primitiva de
290
+ * migración y verificación del paquete, y el motivo de la fase entera —
291
+ * «todo en un driver o todo en otro, con una migración idempotente y
292
+ * bidireccional». Sustituye a `openfga:import`, que el 2k borró.
293
+ *
294
+ * Operación de PLATAFORMA, como `driver()` y `relayScopeChanges`: no lleva
295
+ * actor, no mide rangos y **no se expone por HTTP**.
296
+ *
297
+ * El driver de destino se resuelve **por nombre del registro**
298
+ * (`config.drivers[to]`), no por `config.default`: la migración de verdad
299
+ * es «el motor sigue corriendo con `database` mientras se llena el store de
300
+ * `openfga`», y con el default no habría forma de nombrar al destino. Un
301
+ * driver que no sabe reconstruirse lo dice (500 `E_AUTHZ_UNSUPPORTED`
302
+ * nombrando `reconcile`); el driver `database` es ese caso: sus tablas SON
303
+ * el origen y llenarlas desde un store es la otra dirección (3b-3b).
304
+ *
305
+ * Durante la pasada que ESCRIBE, las escrituras del motor están CONGELADAS
306
+ * (`withFrozenWrites`): un `grant` que aterrizara entre la lectura del
307
+ * origen y la escritura del destino no llegaría al destino y no aparecería
308
+ * en ningún contador. Las lecturas siguen. El `finally` descongela pase lo
309
+ * que pase.
310
+ *
311
+ * **`--dry-run` NO congela** (3b-6, panel 3 · juez §3). El verificador es
312
+ * read-only por contrato: no escribe nada, así que no tiene NADA que
313
+ * proteger, y congelar ahí sería apagar las escrituras a cambio de cero.
314
+ * Está publicado para correrlo en CI y en un cron, o sea justo el sitio
315
+ * desde el que un mecanismo de indisponibilidad se dispara solo — hoy
316
+ * contra el proceso del job, y contra la flota entera el día que el freeze
317
+ * sea durable. El único contraargumento posible —que congelar estabiliza
318
+ * sus números— no vale: los números de un verificador read-only no son una
319
+ * garantía de nada.
320
+ *
321
+ * Lo que añade el manager al reporte del driver es lo único que el driver
322
+ * no puede ver: **la ventana del relay** —los cambios del árbol encolados y
323
+ * sin aplicar, que son la deriva que el store todavía no conoce (decisión
324
+ * del dueño del 2026-08-30, consecuencia 4)— y las entradas APARCADAS, que
325
+ * no son una ventana sino una divergencia permanente.
326
+ */
327
+ reconcile(options: {
328
+ to: string;
329
+ from?: string;
330
+ } & ReconcileOptions): Promise<ReconcileReport>;
117
331
  /**
118
332
  * ¿`outer` contiene a `inner`? = `outer ∈ chain(inner)`, inclusive: un scope
119
333
  * se contiene a sí mismo y `APP_SCOPE` contiene todo. Un `inner` que el
@@ -184,6 +398,118 @@ export declare class AuthorizationManager {
184
398
  * su owner. Notifica `role_purged`. No necesita `listDenies`.
185
399
  */
186
400
  deleteScopedRole(actor: SubjectRef, roleUuid: string, options?: ScopedWriteOptions): Promise<void>;
401
+ /**
402
+ * Los roles LOCALES cuyo owner el árbol YA NO conoce, y —con `force`— su
403
+ * purga. Es el motor de `authz:catalog:prune-orphans` (3b-0 · Z2).
404
+ *
405
+ * Un rol así está DORMIDO, y «dormido» significa **exactamente** esto
406
+ * (3b-0b · AA1, auditor 3b-0): no es visible desde ningún scope vivo cuya
407
+ * cadena NO pase por su owner. No significa que no conceda. La regla única
408
+ * de visibilidad (invariante 18) pide que el owner esté en la cadena del
409
+ * scope preguntado, y **un descendiente vivo cuya ruta materializada sigue
410
+ * pasando por el owner la cumple**: ahí el rol concede, es membresía por
411
+ * los seis caminos de lectura y se puede ASIGNAR, por slug y por uuid.
412
+ * Ocurre en cuanto el consumidor borra la fila del owner sin borrar (o sin
413
+ * notificar) la de sus descendientes — el borrado en dos pasos y las rutas
414
+ * materializadas son lo normal. Por eso este barrido es destructivo de
415
+ * verdad y por eso `--dry-run` es el default: puede estar revocando
416
+ * permisos VIVOS, no recogiendo basura inerte. Lo que sí es seguro decir:
417
+ * un rol huérfano SIN asignaciones vigentes no concede nada, y ninguno
418
+ * concede en un scope cuya cadena no pase por el owner.
419
+ *
420
+ * Cada huérfano viene con `assignments` (hechos vigentes) y
421
+ * `stillGranting` (`assignments > 0`), que es la marca CONSERVADORA de
422
+ * «esto no es basura inerte»: cuenta hechos, no comprueba si el scope de
423
+ * cada uno sigue resolviendo. Falso ⇒ no concede seguro; verdadero ⇒
424
+ * míralo antes de `--force`.
425
+ *
426
+ * **Y esos hechos se los cuenta el DRIVER** (3b-2j, decisión del dueño del
427
+ * 2026-08-31 (3)), con `countRoleAssignments` del puerto. Hasta aquí los
428
+ * contaba el propio barrido en `authz_assignments` —la tabla del driver
429
+ * `database`—, así que con `openfga` en modo `facts`, donde los hechos
430
+ * viven en el store, `stillGranting` era SIEMPRE `false`: el barrido
431
+ * declaraba basura inerte, justo antes de un borrado destructivo, un rol
432
+ * que estaba concediendo (medido en el lote 2i). Un driver que no traiga
433
+ * el método deja los DOS campos en **`undefined`**, nunca en `false`: «no
434
+ * lo sé» no puede degradar a «no concede», que es exactamente el bug. Con
435
+ * `undefined` el rol no es demostrablemente inerte y el comando lo lista
436
+ * APARTE, igual que a los que sí conceden.
437
+ *
438
+ * Lo que el rol dormido sí hace en todo caso es ocupar su `(slug, nivel)`
439
+ * dentro del subárbol donde todavía se le vea, y `deleteScopedRole` no lo
440
+ * alcanza (resuelve el owner en fresco y responde 422
441
+ * `E_AUTHZ_UNKNOWN_SCOPE`). Hasta 3G esa limpieza la arrastraba
442
+ * `scopes.detached`, y ahí es donde nacieron tres de las cuatro
443
+ * regresiones de la Fase 3: la operación la dispara un TENANT, sobre un
444
+ * scope que ya no resuelve, así que hubo que inventarle una policy de
445
+ * rango sin cadena donde medirla, una enumeración del subárbol y una
446
+ * degradación — tres piezas que compuestas destruían roles de
447
+ * descendientes VIVOS. Aquí no hay nada de eso: es una operación de
448
+ * PLATAFORMA (una tarea de mantenimiento con acceso al catálogo, como
449
+ * `authz:catalog:sync`), no lleva actor y no mide rangos, exactamente como
450
+ * el `purgeRole` de último recurso que el README ya prometía. Es, junto a
451
+ * `driver()`, **API de plataforma**: se salta `requireActor` y
452
+ * `requireWithin` a propósito, así que no se expone a un controlador.
453
+ *
454
+ * `force: false` (el default, y el del comando: `--dry-run`) NO escribe:
455
+ * devuelve la lista para que un humano la mire. Con `force: true` cada rol
456
+ * se purga con `purgeRole` —atómico: asignaciones + vínculos + fila +
457
+ * versión del catálogo— y se notifica `role_purged` (sin `actor`). El
458
+ * conjunto no es atómico, y por eso el reporte dice QUÉ se purgó
459
+ * (`purged: CatalogRoleRef[]`, 3b-0b · AB3) y no cuántos: si un
460
+ * `purgeRole` falla a mitad, lo anterior ya está borrado —con el hallazgo
461
+ * de AA1 eso puede ser revocación parcial de permisos vivos— y quien
462
+ * recoge el 503 necesita la lista, no un contador. Una pasada
463
+ * interrumpida la recoge la siguiente (el orden es estable por uuid).
464
+ *
465
+ * **Dos seguros contra el barrido a ciegas**, que es el riesgo real
466
+ * (auditor 3b-0):
467
+ *
468
+ * - **Cota de purga masiva** (AA2): si TODOS los owners distintos
469
+ * resultan huérfanos, o si los huérfanos superan el 50 % de los roles
470
+ * locales, `force` es 500 `E_AUTHZ_MASS_PURGE_REFUSED` **antes de
471
+ * borrar nada**. Esa es la firma de un `resolveChain` filtrado por el
472
+ * tenant de la petición o corriendo sin contexto (comando, réplica
473
+ * atrasada): devuelve `null` para todo y la pasada se lleva el catálogo
474
+ * local de TODOS los tenants (medido: 2 de 2 roles vivos). Una poda
475
+ * grande de verdad pasa con `allowMassPurge: true`
476
+ * (`--allow-mass-purge`), que es una decisión humana. El `--dry-run` no
477
+ * lanza —es justo el diagnóstico que hay que poder mirar— pero lo
478
+ * marca en `massPurge`.
479
+ * - **Re-resolución justo antes de cada purga** (AA3): entre la lectura y
480
+ * el borrado cabe un `scopes.attached`/restore concurrente, y la
481
+ * ventana es TODA la pasada (N roles + N `resolveChain`), no un
482
+ * instante. Cada owner se vuelve a resolver en FRESCO inmediatamente
483
+ * antes de su `purgeRole`; si ha vuelto, el rol se salta y se cuenta en
484
+ * `skipped` con `reason: 'owner-came-back'`.
485
+ *
486
+ * Coste: una lectura del catálogo local + un `resolveChain` por OWNER
487
+ * DISTINTO (memoizado) + UNA llamada a `countRoleAssignments` con los
488
+ * uuids de los huérfanos (ninguna si no hay) + un `resolveChain` más por
489
+ * rol purgado (el de AA3). Es O(owners con roles locales) para mirar y
490
+ * O(roles purgados) para borrar, y corre en un comando, no en el camino de
491
+ * una petición.
492
+ */
493
+ pruneOrphanRoles(options?: {
494
+ force?: boolean;
495
+ allowMassPurge?: boolean;
496
+ }): Promise<{
497
+ orphans: Array<{
498
+ role: CatalogRole;
499
+ owner: ScopeRef;
500
+ permissions: string[];
501
+ assignments: number | undefined;
502
+ stillGranting: boolean | undefined;
503
+ }>;
504
+ purged: CatalogRoleRef[];
505
+ skipped: Array<{
506
+ role: CatalogRoleRef;
507
+ reason: 'owner-came-back';
508
+ }>;
509
+ /** ¿La pasada tiene la firma de un resolutor ciego? Con `force` exige `allowMassPurge`. */
510
+ massPurge: boolean;
511
+ dryRun: boolean;
512
+ }>;
187
513
  /**
188
514
  * Asigna un rol al holder en un scope. `role` es un `RoleQuery` (3D · M1):
189
515
  * un slug, `{ slug, scopeType }` o `{ uuid }` — esta última es la forma
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AA4C7D,OAAO,KAAK,EACV,mBAAmB,EAEnB,gBAAgB,EAGhB,WAAW,EAEX,WAAW,EACX,OAAO,EACP,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,SAAS,EAGT,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,UAAU,EAEX,MAAM,YAAY,CAAA;AAuBnB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,oBAAoB,EAClB,WAAW,GACX,SAAS,GACT,cAAc,GACd,YAAY,GACZ,WAAW,GACX,gBAAgB,GAChB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,sBAAsB,GACtB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,GACxB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,CACrB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAEhH;AAED,qGAAqG;AACrG,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AACvC,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAC7C;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,WAAa,CAAA;AACzC,gGAAgG;AAChG,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAE7C,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAKD;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;;gBAenB,MAAM,EAAE,mBAAmB;IAkCvC;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,iBAAiB;IAmB9D;;;;;;;;;;;;;;OAcG;IACG,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC;IA2B5C,mDAAmD;IACnD,iBAAiB,IAAI,IAAI;IAiCzB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM;0BAOW,QAAQ,UAAU,QAAQ,YAAY,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAAC;uBAS3E,QAAQ,aAAa,QAAQ,YAAY,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAAC;QAOhG;;;;;;;WAOG;0BACqB,QAAQ,YAAY,kBAAkB,KAAG,OAAO,CAAC,kBAAkB,CAAC;MA2C7F;IAyLD;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IA8H5D,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrF,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtF;;;;;;;;OAQG;IACG,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA0BpG,2GAA2G;IACrG,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAKrE,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKxE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKlE,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKpF,mHAAmH;IAC7G,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAM3E;;;;;;;OAOG;IACG,oBAAoB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiKnF;;;;;;;;;;;;;;;OAeG;IACG,gBAAgB,CACpB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,QAAQ,EACpB,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC;IA8FvB;;;;;;;;OAQG;IACG,gBAAgB,CACpB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC;IAsFvB;;;;;;OAMG;IACG,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqaxG;;;;;;OAMG;IACG,KAAK,CACT,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,QAAQ,EACf,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,YAAY,CAAC;IAyCxB;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1G,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IASpG,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IASvH;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,gBAAgB,CACpB,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,gBAAgB,CAAC;IAoE5B;;;;;;;OAOG;IACG,sBAAsB,CAC1B,QAAQ,EAAE,eAAe,EAAE,EAC3B,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,QAAQ,EAAE,CAAC;CAoNvB"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}