@jantstack/adonis-authz 2.5.0-alpha.3 → 2.5.0-rc.1

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 (277) hide show
  1. package/README.md +437 -48
  2. package/build/commands/authz_catalog_diff.d.ts +0 -1
  3. package/build/commands/authz_catalog_diff.js +0 -1
  4. package/build/commands/authz_catalog_prune_orphans.d.ts +17 -3
  5. package/build/commands/authz_catalog_prune_orphans.js +28 -6
  6. package/build/commands/authz_catalog_sync.d.ts +0 -1
  7. package/build/commands/authz_catalog_sync.js +0 -1
  8. package/build/commands/authz_freeze.d.ts +0 -1
  9. package/build/commands/authz_freeze.js +0 -1
  10. package/build/commands/authz_reconcile.d.ts +0 -1
  11. package/build/commands/authz_reconcile.js +0 -1
  12. package/build/commands/authz_relations_reconcile.d.ts +0 -1
  13. package/build/commands/authz_relations_reconcile.js +56 -8
  14. package/build/commands/authz_scopes_relay.d.ts +0 -1
  15. package/build/commands/authz_scopes_relay.js +54 -6
  16. package/build/commands/authz_scopes_requeue.d.ts +0 -1
  17. package/build/commands/authz_scopes_requeue.js +16 -3
  18. package/build/commands/authz_unfreeze.d.ts +0 -1
  19. package/build/commands/authz_unfreeze.js +0 -1
  20. package/build/commands/main.d.ts +0 -1
  21. package/build/commands/main.js +0 -1
  22. package/build/commands/openfga_provision.d.ts +10 -1
  23. package/build/commands/openfga_provision.js +43 -3
  24. package/build/configure.d.ts +0 -1
  25. package/build/configure.js +0 -1
  26. package/build/index.d.ts +9 -7
  27. package/build/index.js +10 -3
  28. package/build/providers/authz_provider.d.ts +0 -1
  29. package/build/providers/authz_provider.js +0 -1
  30. package/build/services/main.d.ts +0 -1
  31. package/build/services/main.js +0 -1
  32. package/build/services/relations.d.ts +0 -1
  33. package/build/services/relations.js +0 -1
  34. package/build/src/catalog/catalog.d.ts +0 -1
  35. package/build/src/catalog/catalog.js +0 -1
  36. package/build/src/catalog/catalog_cache.d.ts +13 -1
  37. package/build/src/catalog/catalog_cache.js +27 -2
  38. package/build/src/clock.d.ts +0 -1
  39. package/build/src/clock.js +0 -1
  40. package/build/src/define_config.d.ts +0 -1
  41. package/build/src/define_config.js +24 -1
  42. package/build/src/drivers/database_driver.d.ts +60 -3
  43. package/build/src/drivers/database_driver.js +160 -25
  44. package/build/src/drivers/database_relations_driver.d.ts +11 -5
  45. package/build/src/drivers/database_relations_driver.js +115 -33
  46. package/build/src/drivers/openfga_driver.d.ts +159 -26
  47. package/build/src/drivers/openfga_driver.js +882 -199
  48. package/build/src/drivers/openfga_facts.d.ts +91 -1
  49. package/build/src/drivers/openfga_facts.js +277 -3
  50. package/build/src/drivers/openfga_relations_driver.d.ts +41 -13
  51. package/build/src/drivers/openfga_relations_driver.js +422 -228
  52. package/build/src/errors.d.ts +160 -1
  53. package/build/src/errors.js +161 -1
  54. package/build/src/expiry.d.ts +51 -2
  55. package/build/src/expiry.js +96 -2
  56. package/build/src/freeze.d.ts +0 -1
  57. package/build/src/freeze.js +0 -1
  58. package/build/src/hierarchical_resolver.d.ts +0 -1
  59. package/build/src/hierarchical_resolver.js +0 -1
  60. package/build/src/http/app_access_middleware.d.ts +0 -1
  61. package/build/src/http/app_access_middleware.js +0 -1
  62. package/build/src/http/resource_access_middleware.d.ts +0 -1
  63. package/build/src/http/resource_access_middleware.js +0 -1
  64. package/build/src/identity.d.ts +9 -2
  65. package/build/src/identity.js +33 -1
  66. package/build/src/manager.d.ts +24 -1
  67. package/build/src/manager.js +381 -85
  68. package/build/src/memoize_ancestors.d.ts +0 -1
  69. package/build/src/memoize_ancestors.js +0 -1
  70. package/build/src/models/authz_assignment.d.ts +5 -6
  71. package/build/src/models/authz_assignment.js +0 -1
  72. package/build/src/models/authz_deny.d.ts +5 -6
  73. package/build/src/models/authz_deny.js +0 -1
  74. package/build/src/models/authz_permission.d.ts +5 -6
  75. package/build/src/models/authz_permission.js +0 -1
  76. package/build/src/models/authz_role.d.ts +5 -6
  77. package/build/src/models/authz_role.js +0 -1
  78. package/build/src/models/authz_role_permission.d.ts +5 -6
  79. package/build/src/models/authz_role_permission.js +0 -1
  80. package/build/src/openfga.d.ts +2 -3
  81. package/build/src/openfga.js +4 -2
  82. package/build/src/reconcile.d.ts +0 -1
  83. package/build/src/reconcile.js +0 -1
  84. package/build/src/relation_partition_trigger.d.ts +0 -1
  85. package/build/src/relation_partition_trigger.js +0 -1
  86. package/build/src/relations/check_many.d.ts +0 -1
  87. package/build/src/relations/check_many.js +0 -1
  88. package/build/src/relations/define_relations_config.d.ts +25 -3
  89. package/build/src/relations/define_relations_config.js +8 -3
  90. package/build/src/relations/deny_reach.d.ts +102 -0
  91. package/build/src/relations/deny_reach.js +230 -0
  92. package/build/src/relations/group_depth.d.ts +215 -0
  93. package/build/src/relations/group_depth.js +453 -0
  94. package/build/src/relations/manager.d.ts +14 -7
  95. package/build/src/relations/manager.js +60 -15
  96. package/build/src/relations/page.d.ts +19 -0
  97. package/build/src/relations/page.js +74 -0
  98. package/build/src/relations/reconcile.d.ts +58 -4
  99. package/build/src/relations/reconcile.js +266 -12
  100. package/build/src/relations/tuple_key.d.ts +0 -1
  101. package/build/src/relations/tuple_key.js +0 -1
  102. package/build/src/relations/tuple_order.d.ts +5 -4
  103. package/build/src/relations/tuple_order.js +5 -4
  104. package/build/src/relations_config_store.d.ts +57 -2
  105. package/build/src/relations_config_store.js +155 -5
  106. package/build/src/relations_reconcile.d.ts +0 -1
  107. package/build/src/relations_reconcile.js +0 -1
  108. package/build/src/scope_outbox.d.ts +36 -3
  109. package/build/src/scope_outbox.js +78 -18
  110. package/build/src/shared/backend_guard.d.ts +52 -1
  111. package/build/src/shared/backend_guard.js +164 -2
  112. package/build/src/shared/sql_expiry.d.ts +0 -1
  113. package/build/src/shared/sql_expiry.js +0 -1
  114. package/build/src/shared/transaction_guard.d.ts +0 -1
  115. package/build/src/shared/transaction_guard.js +0 -1
  116. package/build/src/sql_descendants.d.ts +0 -1
  117. package/build/src/sql_descendants.js +0 -1
  118. package/build/src/testing/contract.d.ts +26 -3
  119. package/build/src/testing/contract.js +258 -20
  120. package/build/src/testing/main.d.ts +0 -1
  121. package/build/src/testing/main.js +0 -1
  122. package/build/src/testing/migration_contract.d.ts +0 -1
  123. package/build/src/testing/migration_contract.js +0 -1
  124. package/build/src/testing/relations_contract.d.ts +7 -1
  125. package/build/src/testing/relations_contract.js +174 -7
  126. package/build/src/testing/relations_reconcile_contract.d.ts +0 -1
  127. package/build/src/testing/relations_reconcile_contract.js +0 -1
  128. package/build/src/testing/scope_outbox_contract.d.ts +0 -1
  129. package/build/src/testing/scope_outbox_contract.js +0 -1
  130. package/build/src/testing/scope_tree.d.ts +0 -1
  131. package/build/src/testing/scope_tree.js +0 -1
  132. package/build/src/testing/test_clock.d.ts +0 -1
  133. package/build/src/testing/test_clock.js +0 -1
  134. package/build/src/traits/authz_scopes.d.ts +0 -1
  135. package/build/src/traits/authz_scopes.js +0 -1
  136. package/build/src/traits/has_uuid.d.ts +5 -6
  137. package/build/src/traits/has_uuid.js +0 -1
  138. package/build/src/types.d.ts +138 -14
  139. package/build/src/types.js +6 -1
  140. package/build/stubs/config/authorization.stub +22 -6
  141. package/build/stubs/main.d.ts +0 -1
  142. package/build/stubs/main.js +0 -1
  143. package/package.json +4 -3
  144. package/build/commands/authz_catalog_diff.d.ts.map +0 -1
  145. package/build/commands/authz_catalog_diff.js.map +0 -1
  146. package/build/commands/authz_catalog_prune_orphans.d.ts.map +0 -1
  147. package/build/commands/authz_catalog_prune_orphans.js.map +0 -1
  148. package/build/commands/authz_catalog_sync.d.ts.map +0 -1
  149. package/build/commands/authz_catalog_sync.js.map +0 -1
  150. package/build/commands/authz_freeze.d.ts.map +0 -1
  151. package/build/commands/authz_freeze.js.map +0 -1
  152. package/build/commands/authz_reconcile.d.ts.map +0 -1
  153. package/build/commands/authz_reconcile.js.map +0 -1
  154. package/build/commands/authz_relations_reconcile.d.ts.map +0 -1
  155. package/build/commands/authz_relations_reconcile.js.map +0 -1
  156. package/build/commands/authz_scopes_relay.d.ts.map +0 -1
  157. package/build/commands/authz_scopes_relay.js.map +0 -1
  158. package/build/commands/authz_scopes_requeue.d.ts.map +0 -1
  159. package/build/commands/authz_scopes_requeue.js.map +0 -1
  160. package/build/commands/authz_unfreeze.d.ts.map +0 -1
  161. package/build/commands/authz_unfreeze.js.map +0 -1
  162. package/build/commands/main.d.ts.map +0 -1
  163. package/build/commands/main.js.map +0 -1
  164. package/build/commands/openfga_provision.d.ts.map +0 -1
  165. package/build/commands/openfga_provision.js.map +0 -1
  166. package/build/configure.d.ts.map +0 -1
  167. package/build/configure.js.map +0 -1
  168. package/build/index.d.ts.map +0 -1
  169. package/build/index.js.map +0 -1
  170. package/build/providers/authz_provider.d.ts.map +0 -1
  171. package/build/providers/authz_provider.js.map +0 -1
  172. package/build/services/main.d.ts.map +0 -1
  173. package/build/services/main.js.map +0 -1
  174. package/build/services/relations.d.ts.map +0 -1
  175. package/build/services/relations.js.map +0 -1
  176. package/build/src/catalog/catalog.d.ts.map +0 -1
  177. package/build/src/catalog/catalog.js.map +0 -1
  178. package/build/src/catalog/catalog_cache.d.ts.map +0 -1
  179. package/build/src/catalog/catalog_cache.js.map +0 -1
  180. package/build/src/clock.d.ts.map +0 -1
  181. package/build/src/clock.js.map +0 -1
  182. package/build/src/define_config.d.ts.map +0 -1
  183. package/build/src/define_config.js.map +0 -1
  184. package/build/src/drivers/database_driver.d.ts.map +0 -1
  185. package/build/src/drivers/database_driver.js.map +0 -1
  186. package/build/src/drivers/database_relations_driver.d.ts.map +0 -1
  187. package/build/src/drivers/database_relations_driver.js.map +0 -1
  188. package/build/src/drivers/openfga_driver.d.ts.map +0 -1
  189. package/build/src/drivers/openfga_driver.js.map +0 -1
  190. package/build/src/drivers/openfga_facts.d.ts.map +0 -1
  191. package/build/src/drivers/openfga_facts.js.map +0 -1
  192. package/build/src/drivers/openfga_relations_driver.d.ts.map +0 -1
  193. package/build/src/drivers/openfga_relations_driver.js.map +0 -1
  194. package/build/src/errors.d.ts.map +0 -1
  195. package/build/src/errors.js.map +0 -1
  196. package/build/src/expiry.d.ts.map +0 -1
  197. package/build/src/expiry.js.map +0 -1
  198. package/build/src/freeze.d.ts.map +0 -1
  199. package/build/src/freeze.js.map +0 -1
  200. package/build/src/hierarchical_resolver.d.ts.map +0 -1
  201. package/build/src/hierarchical_resolver.js.map +0 -1
  202. package/build/src/http/app_access_middleware.d.ts.map +0 -1
  203. package/build/src/http/app_access_middleware.js.map +0 -1
  204. package/build/src/http/resource_access_middleware.d.ts.map +0 -1
  205. package/build/src/http/resource_access_middleware.js.map +0 -1
  206. package/build/src/identity.d.ts.map +0 -1
  207. package/build/src/identity.js.map +0 -1
  208. package/build/src/manager.d.ts.map +0 -1
  209. package/build/src/manager.js.map +0 -1
  210. package/build/src/memoize_ancestors.d.ts.map +0 -1
  211. package/build/src/memoize_ancestors.js.map +0 -1
  212. package/build/src/models/authz_assignment.d.ts.map +0 -1
  213. package/build/src/models/authz_assignment.js.map +0 -1
  214. package/build/src/models/authz_deny.d.ts.map +0 -1
  215. package/build/src/models/authz_deny.js.map +0 -1
  216. package/build/src/models/authz_permission.d.ts.map +0 -1
  217. package/build/src/models/authz_permission.js.map +0 -1
  218. package/build/src/models/authz_role.d.ts.map +0 -1
  219. package/build/src/models/authz_role.js.map +0 -1
  220. package/build/src/models/authz_role_permission.d.ts.map +0 -1
  221. package/build/src/models/authz_role_permission.js.map +0 -1
  222. package/build/src/openfga.d.ts.map +0 -1
  223. package/build/src/openfga.js.map +0 -1
  224. package/build/src/reconcile.d.ts.map +0 -1
  225. package/build/src/reconcile.js.map +0 -1
  226. package/build/src/relation_partition_trigger.d.ts.map +0 -1
  227. package/build/src/relation_partition_trigger.js.map +0 -1
  228. package/build/src/relations/check_many.d.ts.map +0 -1
  229. package/build/src/relations/check_many.js.map +0 -1
  230. package/build/src/relations/define_relations_config.d.ts.map +0 -1
  231. package/build/src/relations/define_relations_config.js.map +0 -1
  232. package/build/src/relations/manager.d.ts.map +0 -1
  233. package/build/src/relations/manager.js.map +0 -1
  234. package/build/src/relations/reconcile.d.ts.map +0 -1
  235. package/build/src/relations/reconcile.js.map +0 -1
  236. package/build/src/relations/tuple_key.d.ts.map +0 -1
  237. package/build/src/relations/tuple_key.js.map +0 -1
  238. package/build/src/relations/tuple_order.d.ts.map +0 -1
  239. package/build/src/relations/tuple_order.js.map +0 -1
  240. package/build/src/relations_config_store.d.ts.map +0 -1
  241. package/build/src/relations_config_store.js.map +0 -1
  242. package/build/src/relations_reconcile.d.ts.map +0 -1
  243. package/build/src/relations_reconcile.js.map +0 -1
  244. package/build/src/scope_outbox.d.ts.map +0 -1
  245. package/build/src/scope_outbox.js.map +0 -1
  246. package/build/src/shared/backend_guard.d.ts.map +0 -1
  247. package/build/src/shared/backend_guard.js.map +0 -1
  248. package/build/src/shared/sql_expiry.d.ts.map +0 -1
  249. package/build/src/shared/sql_expiry.js.map +0 -1
  250. package/build/src/shared/transaction_guard.d.ts.map +0 -1
  251. package/build/src/shared/transaction_guard.js.map +0 -1
  252. package/build/src/sql_descendants.d.ts.map +0 -1
  253. package/build/src/sql_descendants.js.map +0 -1
  254. package/build/src/testing/contract.d.ts.map +0 -1
  255. package/build/src/testing/contract.js.map +0 -1
  256. package/build/src/testing/main.d.ts.map +0 -1
  257. package/build/src/testing/main.js.map +0 -1
  258. package/build/src/testing/migration_contract.d.ts.map +0 -1
  259. package/build/src/testing/migration_contract.js.map +0 -1
  260. package/build/src/testing/relations_contract.d.ts.map +0 -1
  261. package/build/src/testing/relations_contract.js.map +0 -1
  262. package/build/src/testing/relations_reconcile_contract.d.ts.map +0 -1
  263. package/build/src/testing/relations_reconcile_contract.js.map +0 -1
  264. package/build/src/testing/scope_outbox_contract.d.ts.map +0 -1
  265. package/build/src/testing/scope_outbox_contract.js.map +0 -1
  266. package/build/src/testing/scope_tree.d.ts.map +0 -1
  267. package/build/src/testing/scope_tree.js.map +0 -1
  268. package/build/src/testing/test_clock.d.ts.map +0 -1
  269. package/build/src/testing/test_clock.js.map +0 -1
  270. package/build/src/traits/authz_scopes.d.ts.map +0 -1
  271. package/build/src/traits/authz_scopes.js.map +0 -1
  272. package/build/src/traits/has_uuid.d.ts.map +0 -1
  273. package/build/src/traits/has_uuid.js.map +0 -1
  274. package/build/src/types.d.ts.map +0 -1
  275. package/build/src/types.js.map +0 -1
  276. package/build/stubs/main.d.ts.map +0 -1
  277. package/build/stubs/main.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import type { NormalizedRoleQuery, RoleQuery, ScopeRef, SubjectRef } from './types.js';
1
+ import type { NormalizedRoleQuery, RoleQuery, ScopeRef, SnapshotReads, SubjectRef } from './types.js';
2
2
  /**
3
3
  * Validación de identidad del motor: holder, scope, rol y permiso.
4
4
  *
@@ -173,6 +173,8 @@ export declare function scopeSpellings(scope: ScopeRef): ScopeRef[];
173
173
  export declare function isDashlessUuid(value: unknown): value is string;
174
174
  /** La forma 8-4-4-4-12 de un uuid de 32 hex (la ortografía CANÓNICA). */
175
175
  export declare function dashedUuid(dashless: string): string;
176
+ /** ¿Es un uuid en su ortografía CANÓNICA (8-4-4-4-12, minúsculas)? (7.4: la forma del cursor de `enumerate*` de `database`.) */
177
+ export declare function isCanonicalUuid(value: unknown): value is string;
176
178
  /**
177
179
  * **¿Es una ortografía NO canónica de un uuid?** (D4 + cierre 🟠 A2 del
178
180
  * auditor del lote A, decisión del dueño 2026-10-15): todo valor que, sin
@@ -336,4 +338,9 @@ export interface IdentityParts {
336
338
  * cuesta una consulta ni deja rastro.
337
339
  */
338
340
  export declare function assertIdentity(parts: IdentityParts): void;
339
- //# sourceMappingURL=identity.d.ts.map
341
+ /**
342
+ * La forma de una pregunta a `readSnapshot` (rotación 2 · cierre 3): al menos una de las tres claves y ninguna más;
343
+ * `rolesInChain` un array de scopes válidos, `listScopes` un slug de permiso, `listDenies` exactamente `true`. Lo
344
+ * demás es 422 `E_AUTHZ_INVALID_IDENTITY` antes de tocar el backend. Devuelve la pregunta con las claves presentes.
345
+ */
346
+ export declare function assertSnapshotReads(reads: unknown): SnapshotReads;
@@ -306,6 +306,10 @@ export function dashedUuid(dashless) {
306
306
  /* ── Partición de RELACIONES (D4, plan 2.5 · lote A) ───────────────────── */
307
307
  /** La ortografía CANÓNICA de un uuid: exactamente 8-4-4-4-12, minúsculas. */
308
308
  const CANONICAL_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
309
+ /** ¿Es un uuid en su ortografía CANÓNICA (8-4-4-4-12, minúsculas)? (7.4: la forma del cursor de `enumerate*` de `database`.) */
310
+ export function isCanonicalUuid(value) {
311
+ return typeof value === 'string' && CANONICAL_UUID.test(value);
312
+ }
309
313
  /**
310
314
  * **¿Es una ortografía NO canónica de un uuid?** (D4 + cierre 🟠 A2 del
311
315
  * auditor del lote A, decisión del dueño 2026-10-15): todo valor que, sin
@@ -606,4 +610,32 @@ export function assertIdentity(parts) {
606
610
  if ('expiresAt' in parts)
607
611
  assertExpiresAt(parts.expiresAt);
608
612
  }
609
- //# sourceMappingURL=identity.js.map
613
+ /**
614
+ * La forma de una pregunta a `readSnapshot` (rotación 2 · cierre 3): al menos una de las tres claves y ninguna más;
615
+ * `rolesInChain` un array de scopes válidos, `listScopes` un slug de permiso, `listDenies` exactamente `true`. Lo
616
+ * demás es 422 `E_AUTHZ_INVALID_IDENTITY` antes de tocar el backend. Devuelve la pregunta con las claves presentes.
617
+ */
618
+ export function assertSnapshotReads(reads) {
619
+ if (reads === null || typeof reads !== 'object' || Array.isArray(reads)) {
620
+ throw new InvalidIdentityError(`readSnapshot: se esperaba un objeto { rolesInChain?, listScopes?, listDenies? } y llegó ${Array.isArray(reads) ? 'un array' : typeof reads}`);
621
+ }
622
+ const known = new Set(['rolesInChain', 'listScopes', 'listDenies']);
623
+ const present = Object.keys(reads).filter((key) => reads[key] !== undefined);
624
+ const unknown = present.filter((key) => !known.has(key));
625
+ if (unknown.length)
626
+ throw new InvalidIdentityError(`readSnapshot: clave desconocida ${unknown.map((k) => `'${k}'`).join(', ')}`);
627
+ if (present.length === 0)
628
+ throw new InvalidIdentityError('readSnapshot: no se pidió ninguna lectura');
629
+ const { rolesInChain, listScopes, listDenies } = reads;
630
+ if (rolesInChain !== undefined) {
631
+ if (!Array.isArray(rolesInChain))
632
+ throw new InvalidIdentityError('readSnapshot: rolesInChain tiene que ser un array de scopes');
633
+ for (const scope of rolesInChain)
634
+ assertScope(scope);
635
+ }
636
+ if (listScopes !== undefined)
637
+ assertIdentity({ permission: listScopes });
638
+ if (listDenies !== undefined && listDenies !== true)
639
+ throw new InvalidIdentityError('readSnapshot: listDenies solo admite true');
640
+ return { rolesInChain, listScopes, listDenies };
641
+ }
@@ -71,6 +71,12 @@ export declare const RELAY_LEASE_POLL_MS = 25;
71
71
  * reloj de pared: con `config.clock` fijo el sondeo por reloj no terminaba nunca.
72
72
  */
73
73
  export declare const RELAY_WAIT_LEASE_MAX_MS = 60000;
74
+ /**
75
+ * Por qué una pasada de `pruneOrphanRoles` tiene la firma de un resolutor ciego (3b-0b · AA2 + rotación 2 · R2-02):
76
+ * todos los owners huérfanos, más del 50 % de los roles locales, o huérfanos de más de un owner con alguno que todavía
77
+ * concede (o no se sabe).
78
+ */
79
+ export type MassPurgeReason = 'all-owners' | 'proportion' | 'granting-across-owners';
74
80
  export interface ForRequestOptions {
75
81
  /**
76
82
  * Milisegundos durante los que la vista puede LEER (default 30 000).
@@ -700,6 +706,21 @@ export declare class AuthorizationManager {
700
706
  * antes de su `purgeRole`; si ha vuelto, el rol se salta y se cuenta en
701
707
  * `skipped` con `reason: 'owner-came-back'`.
702
708
  *
709
+ * **Tercer disparador del seguro** (rotación 2 de M4 · R2-02, decisión del dueño 2026-10-22 (2)): la
710
+ * proporción la controla un TENANT —con la API de delegación legítima infla su catálogo local hasta que los
711
+ * huérfanos de los demás bajan del 50 %—, y la variante realista del resolutor ciego no es «`null` para todo»
712
+ * sino un contexto de tenant COLADO en el job de plataforma, que solo deja vivo a ese tenant. Así que, con
713
+ * `force`, si los huérfanos son de MÁS DE UN owner y ALGUNO todavía concede (`stillGranting === true`) o no se
714
+ * sabe (`undefined`: el driver no cuenta), también es 500 `E_AUTHZ_MASS_PURGE_REFUSED` antes de borrar nada,
715
+ * salvo `allowMassPurge`. Un solo owner huérfano con asignaciones vivas sigue pasando (es el caso normal de un
716
+ * tenant que se va, y el listado lo marca aparte). El `--dry-run` no lanza: lo marca en `massPurge` y dice por
717
+ * qué en `massPurgeReasons` (`'all-owners' | 'proportion' | 'granting-across-owners'`).
718
+ * - **Cota de lectura** (R2-04): `maxLocalRoles` (default `DEFAULT_MAX_LOCAL_ROLES`, `--max-local-roles` en el
719
+ * comando) acota la lectura del catálogo local; pasarla es 500 `E_AUTHZ_TOO_MANY_LOCAL_ROLES`, nunca una lista
720
+ * parcial. Hasta este cierre la opción no existía y el mensaje pedía «subir la cota» sin mando: un tenant con
721
+ * 10 001 roles locales dejaba `prune-orphans` muerto para todos. Un valor que no es un entero ≥ 1 es 500
722
+ * `E_AUTHZ_CONFIG` antes de leer nada.
723
+ *
703
724
  * Coste: una lectura del catálogo local + un `resolveChain` por OWNER
704
725
  * DISTINTO (memoizado) + UNA llamada a `countRoleAssignments` con los
705
726
  * uuids de los huérfanos (ninguna si no hay) + un `resolveChain` más por
@@ -710,6 +731,7 @@ export declare class AuthorizationManager {
710
731
  pruneOrphanRoles(options?: {
711
732
  force?: boolean;
712
733
  allowMassPurge?: boolean;
734
+ maxLocalRoles?: number;
713
735
  }): Promise<{
714
736
  orphans: Array<{
715
737
  role: CatalogRole;
@@ -725,6 +747,8 @@ export declare class AuthorizationManager {
725
747
  }>;
726
748
  /** ¿La pasada tiene la firma de un resolutor ciego? Con `force` exige `allowMassPurge`. */
727
749
  massPurge: boolean;
750
+ /** Qué disparó `massPurge` (vacío si no saltó): todos los owners, la proporción, o huérfanos de > 1 owner que conceden (R2-02). */
751
+ massPurgeReasons: MassPurgeReason[];
728
752
  dryRun: boolean;
729
753
  }>;
730
754
  /**
@@ -787,4 +811,3 @@ export declare class AuthorizationManager {
787
811
  maxScopes?: number;
788
812
  }): Promise<ScopeRef[]>;
789
813
  }
790
- //# sourceMappingURL=manager.d.ts.map