@aurorajs.dev/catalyst-cli 1.1.3 → 2.0.0

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 (1535) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/generate/index.js +2 -1
  3. package/dist/generator/domain/config.js +3 -3
  4. package/dist/generator/domain/custom-field-value.js +1 -1
  5. package/dist/generator/domain/display-field.d.ts +24 -0
  6. package/dist/generator/domain/display-field.js +42 -0
  7. package/dist/generator/domain/i18n-table.js +1 -1
  8. package/dist/generator/domain/model.d.ts +15 -1
  9. package/dist/generator/domain/property-filters.d.ts +100 -1
  10. package/dist/generator/domain/property-filters.js +163 -4
  11. package/dist/generator/domain/property-mappers.d.ts +3 -1
  12. package/dist/generator/domain/property-mappers.js +15 -5
  13. package/dist/generator/domain/property-predicates.d.ts +2 -1
  14. package/dist/generator/domain/property-predicates.js +2 -1
  15. package/dist/generator/domain/property-validators.js +9 -4
  16. package/dist/generator/domain/readonly-payload-types.d.ts +3 -3
  17. package/dist/generator/domain/readonly-payload-types.js +5 -5
  18. package/dist/generator/domain/relations-builder.d.ts +10 -0
  19. package/dist/generator/domain/relations-builder.js +13 -4
  20. package/dist/generator/domain/schema-loader.d.ts +41 -0
  21. package/dist/generator/domain/schema-loader.js +349 -2
  22. package/dist/generator/engine/code-writer/code-writer.d.ts +9 -5
  23. package/dist/generator/engine/code-writer/code-writer.js +102 -13
  24. package/dist/generator/handlers/back.handler.d.ts +27 -0
  25. package/dist/generator/handlers/back.handler.js +107 -5
  26. package/dist/generator/packages/installers/auditing.js +3 -3
  27. package/dist/generator/packages/installers/authorization-code.js +2 -5
  28. package/dist/generator/packages/installers/common.js +3 -3
  29. package/dist/generator/packages/installers/mcp.js +1 -1
  30. package/dist/generator/packages/installers/message.js +1 -1
  31. package/dist/generator/packages/installers/ms-email.js +1 -1
  32. package/dist/generator/packages/installers/ms-entra-id.js +3 -3
  33. package/dist/generator/packages/installers/queue-manager.js +1 -1
  34. package/dist/generator/packages/installers/storage-account-azure.js +2 -2
  35. package/dist/generator/packages/installers/storage-account.js +4 -4
  36. package/dist/generator/packages/installers/support.js +1 -1
  37. package/dist/generator/packages/installers/tools.js +1 -1
  38. package/dist/generator/packages/installers/whatsapp.js +1 -1
  39. package/dist/generator/packages/package-helpers.js +10 -10
  40. package/dist/generator/utils/code-gen.d.ts +5 -1
  41. package/dist/generator/utils/code-gen.js +5 -1
  42. package/dist/generator/utils/relations-file.js +62 -0
  43. package/dist/sheets/domain/types.d.ts +5 -1
  44. package/dist/sheets/domain/types.js +3 -0
  45. package/dist/sheets/sync/sheet-to-yaml.d.ts +2 -1
  46. package/dist/sheets/sync/sheet-to-yaml.js +101 -9
  47. package/dist/sheets/sync/yaml-to-sheet.js +6 -1
  48. package/dist/sheets/transformers/property-transformer.d.ts +39 -0
  49. package/dist/sheets/transformers/property-transformer.js +63 -2
  50. package/dist/templates/backend/application/.claude/skills/catalyst-backend-testing/SKILL.md +262 -241
  51. package/dist/templates/backend/application/.claude/skills/catalyst-cross-bounded-context-ports/SKILL.md +1 -1
  52. package/dist/templates/backend/application/.claude/skills/catalyst-field-schema/SKILL.md +12 -7
  53. package/dist/templates/backend/application/.claude/skills/catalyst-field-schema/references/field-schema-and-decorators.md +53 -42
  54. package/dist/templates/backend/application/.claude/skills/catalyst-field-schema/references/query-statement.md +19 -6
  55. package/dist/templates/backend/application/.claude/skills/catalyst-handler-composer/SKILL.md +4 -4
  56. package/dist/templates/backend/application/.claude/skills/catalyst-handler-composer/references/additional-apis-workflow.md +77 -18
  57. package/dist/templates/backend/application/.claude/skills/catalyst-handler-composer/references/create-handler.md +7 -5
  58. package/dist/templates/backend/application/.claude/skills/catalyst-handler-composer/references/update-handler.md +1 -1
  59. package/dist/templates/backend/application/.claude/skills/catalyst-nestjs-primitives/SKILL.md +145 -23
  60. package/dist/templates/backend/application/.claude/skills/catalyst-project-structure/SKILL.md +48 -5
  61. package/dist/templates/backend/application/.claude/skills/catalyst-provider-composition/SKILL.md +23 -20
  62. package/dist/templates/backend/application/.claude/skills/catalyst-schema-migrations/SKILL.md +158 -65
  63. package/dist/templates/backend/application/.oxlintrc.json +171 -0
  64. package/dist/templates/backend/application/CLAUDE.md +22 -0
  65. package/dist/templates/backend/application/nest-cli.json +3 -3
  66. package/dist/templates/backend/application/package.json +43 -75
  67. package/dist/templates/backend/application/scripts/db/check.ts +1 -1
  68. package/dist/templates/backend/application/scripts/db/generate.ts +1 -1
  69. package/dist/templates/backend/application/scripts/db/migrate.ts +2 -2
  70. package/dist/templates/backend/application/scripts/db/query.spec.ts +497 -0
  71. package/dist/templates/backend/application/scripts/db/query.ts +410 -0
  72. package/dist/templates/backend/application/scripts/iam/permissions-without-role.ts +9 -8
  73. package/dist/templates/backend/application/scripts/tz-pin.spec.ts +10 -0
  74. package/dist/templates/backend/application/src/@aurora/core.module.ts +2 -2
  75. package/dist/templates/backend/application/src/@aurora/decorators/auth.decorator.ts +0 -1
  76. package/dist/templates/backend/application/src/@aurora/decorators/index.ts +1 -1
  77. package/dist/templates/backend/application/src/@aurora/modules/authentication/authentication.module.spec.ts +7 -27
  78. package/dist/templates/backend/application/src/@aurora/modules/authentication/authentication.module.ts +11 -11
  79. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/anonymous-account.spec.ts +1 -1
  80. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/anonymous-account.ts +2 -1
  81. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/errors/index.ts +1 -1
  82. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/index.ts +1 -1
  83. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/ports/account-loader.port.ts +26 -0
  84. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/ports/authentication-strategy.port.ts +1 -1
  85. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/ports/index.ts +12 -12
  86. package/dist/templates/backend/application/src/@aurora/modules/authentication/domain/resolve-authentication-mode.spec.ts +1 -1
  87. package/dist/templates/backend/application/src/@aurora/modules/authentication/index.ts +5 -5
  88. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/factory/authentication-strategy.factory.spec.ts +14 -27
  89. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/factory/authentication-strategy.factory.ts +4 -4
  90. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/guards/authentication-jwt.guard.spec.ts +16 -17
  91. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/guards/authentication-jwt.guard.ts +2 -2
  92. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/guards/index.ts +2 -2
  93. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/providers/hub-session-manager.provider.ts +2 -2
  94. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/providers/jwt-signer.provider.ts +2 -2
  95. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/aurora-hub/aurora-hub-consumer.adapter.ts +3 -2
  96. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/aurora-hub/index.ts +1 -0
  97. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/authentication-cache-invalidator.adapter.spec.ts +6 -6
  98. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/authentication-cache-invalidator.adapter.ts +2 -2
  99. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/index.ts +1 -1
  100. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/jwt-passport.strategy.ts +1 -1
  101. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/anonymous-account-loader.adapter.spec.ts +2 -2
  102. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/anonymous-account-loader.adapter.ts +2 -2
  103. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/jwt-signer.adapter.spec.ts +7 -7
  104. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/jwt-signer.adapter.ts +3 -3
  105. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/local-provider-cache-invalidation.spec.ts +84 -0
  106. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/local-provider.adapter.spec.ts +10 -8
  107. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/strategies/local-provider/local-provider.adapter.ts +3 -3
  108. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/warnings/authentication-boot-warning.spec.ts +9 -8
  109. package/dist/templates/backend/application/src/@aurora/modules/authentication/infrastructure/warnings/authentication-boot-warning.ts +1 -1
  110. package/dist/templates/backend/application/src/@aurora/modules/criteria/index.ts +1 -1
  111. package/dist/templates/backend/application/src/@aurora/modules/graphql/graphql-config.module.ts +3 -3
  112. package/dist/templates/backend/application/src/@aurora/modules/graphql/guards/gql-throttler.guard.spec.ts +7 -6
  113. package/dist/templates/backend/application/src/@aurora/modules/graphql/index.ts +3 -3
  114. package/dist/templates/backend/application/src/@aurora/modules/graphql/schema-store.module.ts +1 -1
  115. package/dist/templates/backend/application/src/@aurora/modules/handler-registry/event-dispatcher.spec.ts +3 -3
  116. package/dist/templates/backend/application/src/@aurora/modules/handler-registry/event-dispatcher.ts +1 -1
  117. package/dist/templates/backend/application/src/@aurora/modules/handler-registry/handler-registry.module.ts +2 -2
  118. package/dist/templates/backend/application/src/@aurora/modules/handler-registry/index.ts +4 -4
  119. package/dist/templates/backend/application/src/@aurora/modules/handler-registry/keyed-handler-registry.spec.ts +2 -2
  120. package/dist/templates/backend/application/src/@aurora/modules/handler-registry/keyed-handler-registry.ts +1 -1
  121. package/dist/templates/backend/application/src/@aurora/modules/health/app-version.provider.spec.ts +1 -1
  122. package/dist/templates/backend/application/src/@aurora/modules/health/app-version.provider.ts +4 -3
  123. package/dist/templates/backend/application/src/@aurora/modules/health/health.controller.spec.ts +1 -1
  124. package/dist/templates/backend/application/src/@aurora/modules/health/health.controller.ts +1 -1
  125. package/dist/templates/backend/application/src/@aurora/modules/health/health.module.ts +2 -2
  126. package/dist/templates/backend/application/src/@aurora/modules/health/index.ts +3 -3
  127. package/dist/templates/backend/application/src/@aurora/modules/index.ts +10 -9
  128. package/dist/templates/backend/application/src/@aurora/modules/lang/core-get-fallback-lang-from-json.service.ts +5 -3
  129. package/dist/templates/backend/application/src/@aurora/modules/lang/core-get-langs-from-json.service.ts +2 -2
  130. package/dist/templates/backend/application/src/@aurora/modules/lang/core-langs.ts +1 -1
  131. package/dist/templates/backend/application/src/@aurora/modules/lang/index.ts +3 -3
  132. package/dist/templates/backend/application/src/@aurora/modules/mailer/index.ts +2 -2
  133. package/dist/templates/backend/application/src/@aurora/modules/mailer/mailer-client.module.spec.ts +41 -33
  134. package/dist/templates/backend/application/src/@aurora/modules/mailer/mailer-client.module.ts +2 -2
  135. package/dist/templates/backend/application/src/@aurora/modules/pdf/index.ts +7 -0
  136. package/dist/templates/backend/application/src/@aurora/modules/pdf/pdf-document.types.ts +48 -0
  137. package/dist/templates/backend/application/src/@aurora/modules/pdf/pdf-isolation.spec.ts +17 -0
  138. package/dist/templates/backend/application/src/@aurora/modules/pdf/pdf-renderer.service.ts +12 -0
  139. package/dist/templates/backend/application/src/@aurora/modules/pdf/pdfmake/index.ts +5 -0
  140. package/dist/templates/backend/application/src/@aurora/modules/pdf/pdfmake/pdfmake-renderer.service.spec.ts +58 -0
  141. package/dist/templates/backend/application/src/@aurora/modules/pdf/pdfmake/pdfmake-renderer.service.ts +123 -0
  142. package/dist/templates/backend/application/src/@aurora/modules/report-engine/execute-report.service.spec.ts +6 -6
  143. package/dist/templates/backend/application/src/@aurora/modules/report-engine/execute-report.service.ts +8 -8
  144. package/dist/templates/backend/application/src/@aurora/modules/report-engine/index.ts +20 -20
  145. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-cardinality.guard.spec.ts +2 -2
  146. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-cardinality.guard.ts +1 -1
  147. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-cube.validator.spec.ts +4 -4
  148. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-cube.validator.ts +3 -3
  149. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-db-pool.preflight.spec.ts +4 -4
  150. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-db-pool.provider.spec.ts +1 -1
  151. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-db-pool.provider.ts +1 -1
  152. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-engine.module.spec.ts +7 -8
  153. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-engine.module.ts +16 -17
  154. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-preflight.service.ts +1 -1
  155. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-query.builder.spec.ts +8 -5
  156. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-query.builder.ts +3 -3
  157. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-registry.spec.ts +17 -20
  158. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-registry.ts +2 -2
  159. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-selection.validator.spec.ts +2 -2
  160. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-selection.validator.ts +1 -1
  161. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-tenant.scoper.spec.ts +2 -2
  162. package/dist/templates/backend/application/src/@aurora/modules/report-engine/report-tenant.scoper.ts +1 -1
  163. package/dist/templates/backend/application/src/@aurora/modules/report-engine/result-modes/client-mode.spec.ts +6 -5
  164. package/dist/templates/backend/application/src/@aurora/modules/report-engine/result-modes/client-mode.ts +2 -2
  165. package/dist/templates/backend/application/src/@aurora/modules/report-engine/result-modes/server-mode.spec.ts +7 -6
  166. package/dist/templates/backend/application/src/@aurora/modules/report-engine/result-modes/server-mode.ts +9 -4
  167. package/dist/templates/backend/application/src/@aurora/modules/server-static/index.ts +1 -1
  168. package/dist/templates/backend/application/src/@aurora/services/index.ts +2 -2
  169. package/dist/templates/backend/application/src/@aurora/services/logger.service.ts +20 -6
  170. package/dist/templates/backend/application/src/@aurora/shared.module.ts +1 -2
  171. package/dist/templates/backend/application/src/@bridges/bridges.module.ts +8 -14
  172. package/dist/templates/backend/application/src/@bridges/production-planning/operator-account/index.ts +1 -1
  173. package/dist/templates/backend/application/src/@bridges/production-planning/operator-account/ports/index.ts +2 -2
  174. package/dist/templates/backend/application/src/@bridges/storage-account/file-manager/adapters/index.ts +1 -1
  175. package/dist/templates/backend/application/src/@bridges/storage-account/file-manager/adapters/storage-account-file-manager.adapter.spec.ts +6 -5
  176. package/dist/templates/backend/application/src/@bridges/storage-account/file-manager/adapters/storage-account-file-manager.adapter.ts +3 -3
  177. package/dist/templates/backend/application/src/@bridges/storage-account/file-manager/index.ts +1 -1
  178. package/dist/templates/backend/application/src/@bridges/storage-account/file-manager/ports/index.ts +2 -2
  179. package/dist/templates/backend/application/src/@bridges/storage-account/file-manager/ports/storage-account-file-manager.port.ts +2 -2
  180. package/dist/templates/backend/application/src/@bridges/storage-account/signed-url/adapters/index.ts +1 -1
  181. package/dist/templates/backend/application/src/@bridges/storage-account/signed-url/adapters/storage-account-signed-url.adapter.spec.ts +5 -4
  182. package/dist/templates/backend/application/src/@bridges/storage-account/signed-url/adapters/storage-account-signed-url.adapter.ts +2 -2
  183. package/dist/templates/backend/application/src/@bridges/storage-account/signed-url/index.ts +1 -1
  184. package/dist/templates/backend/application/src/@bridges/storage-account/signed-url/ports/index.ts +2 -2
  185. package/dist/templates/backend/application/src/@config/drizzle/aurora-drizzle-schema.spec.ts +29 -42
  186. package/dist/templates/backend/application/src/@config/drizzle/aurora-drizzle-schema.ts +15 -33
  187. package/dist/templates/backend/application/src/@config/drizzle/aurora-field-schemas.spec.ts +7 -9
  188. package/dist/templates/backend/application/src/@config/drizzle/aurora-field-schemas.ts +67 -91
  189. package/dist/templates/backend/application/src/@config/drizzle/drizzle-migrations.module.spec.ts +12 -11
  190. package/dist/templates/backend/application/src/@config/drizzle/drizzle-migrations.module.ts +11 -4
  191. package/dist/templates/backend/application/src/@config/drizzle/index.ts +3 -3
  192. package/dist/templates/backend/application/src/@config/index.ts +6 -5
  193. package/dist/templates/backend/application/src/@config/lang/index.ts +1 -1
  194. package/dist/templates/backend/application/src/@config/lang/lang.providers.ts +1 -1
  195. package/dist/templates/backend/application/src/@config/mailer/index.ts +1 -1
  196. package/dist/templates/backend/application/src/@config/mailer/mailer-transport.module.ts +1 -1
  197. package/dist/templates/backend/application/src/@config/pdf/index.ts +1 -0
  198. package/dist/templates/backend/application/src/@config/pdf/pdf-renderer.module.spec.ts +53 -0
  199. package/dist/templates/backend/application/src/@config/pdf/pdf-renderer.module.ts +17 -0
  200. package/dist/templates/backend/application/src/@config/storage-account/index.ts +1 -1
  201. package/dist/templates/backend/application/src/@config/storage-account/storage-account.providers.spec.ts +3 -3
  202. package/dist/templates/backend/application/src/@config/storage-account/storage-account.providers.ts +2 -2
  203. package/dist/templates/backend/application/src/app.controller.spec.ts +2 -2
  204. package/dist/templates/backend/application/src/app.controller.ts +1 -1
  205. package/dist/templates/backend/application/src/app.module.ts +12 -12
  206. package/dist/templates/backend/application/src/database/migrations/0004_remove_null_elements_from_array_columns.sql +37 -0
  207. package/dist/templates/backend/application/src/database/migrations/drizzle/20260914212920_add-biller-billing-cycle-master/migration.sql +79 -0
  208. package/dist/templates/backend/application/src/database/migrations/drizzle/20260914212920_add-biller-billing-cycle-master/snapshot.json +17983 -0
  209. package/dist/templates/backend/application/src/database/migrations/drizzle/20260915072010_add-biller-charge-billed-by-billing-run/migration.sql +11 -0
  210. package/dist/templates/backend/application/src/database/migrations/drizzle/20260915072010_add-biller-charge-billed-by-billing-run/snapshot.json +18017 -0
  211. package/dist/templates/backend/application/src/database/migrations/drizzle/20260915113209_add-iam-account-has-add-child-tenants/migration.sql +1 -0
  212. package/dist/templates/backend/application/src/database/migrations/drizzle/20260915113209_add-iam-account-has-add-child-tenants/snapshot.json +17760 -0
  213. package/dist/templates/backend/application/src/database/migrations/drizzle/20260916230702_date-columns-to-real-date/migration.sql +22 -0
  214. package/dist/templates/backend/application/src/database/migrations/drizzle/20260916230702_date-columns-to-real-date/snapshot.json +18031 -0
  215. package/dist/templates/backend/application/src/database/migrations/drizzle/20260918120918_drop-biller-tables/migration.sql +14 -0
  216. package/dist/templates/backend/application/src/database/migrations/drizzle/20260918120918_drop-biller-tables/snapshot.json +14217 -0
  217. package/dist/templates/backend/application/src/database/migrations/drizzle/20260918121214_purge-biller-rows/migration.sql +28 -0
  218. package/dist/templates/backend/application/src/database/migrations/drizzle/20260918121214_purge-biller-rows/snapshot.json +14217 -0
  219. package/dist/templates/backend/application/src/main.ts +14 -13
  220. package/dist/templates/backend/application/src/repl.ts +2 -2
  221. package/dist/templates/backend/application/test/app.e2e-spec.ts +1 -18
  222. package/dist/templates/backend/application/test/vitest-setup.ts +13 -0
  223. package/dist/templates/backend/application/tsconfig.build.json +3 -1
  224. package/dist/templates/backend/application/tsconfig.json +1 -0
  225. package/dist/templates/backend/application/vitest.config.e2e.ts +24 -0
  226. package/dist/templates/backend/application/vitest.config.ts +18 -0
  227. package/dist/templates/backend/env/.env +8 -0
  228. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/authorization-code.module.ts +3 -3
  229. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/controllers/auth.controller.spec.ts +19 -31
  230. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/controllers/auth.controller.ts +2 -2
  231. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/controllers/index.ts +1 -1
  232. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/pkce/index.ts +2 -2
  233. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/pkce/pkce-helpers.spec.ts +1 -1
  234. package/dist/templates/backend/packages/authorization-code/src/@api/authorization-code/pkce/pkce-verifier-store.service.spec.ts +1 -1
  235. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-create-app.controller.ts +3 -3
  236. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-delete-app-by-id.controller.ts +3 -3
  237. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-find-app-by-id.controller.ts +3 -3
  238. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-find-app.controller.ts +3 -3
  239. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-get-apps.controller.ts +4 -4
  240. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-my-preferences-app.controller.ts +3 -3
  241. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-paginate-apps.controller.ts +2 -2
  242. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-save-my-launchpad-layout-app.controller.ts +3 -3
  243. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-toggle-favorite-app.controller.ts +3 -3
  244. package/dist/templates/backend/packages/hub/src/@api/hub/app/controllers/hub-update-app-by-id.controller.ts +3 -3
  245. package/dist/templates/backend/packages/hub/src/@api/hub/app/dto/hub-app.dto.ts +3 -2
  246. package/dist/templates/backend/packages/hub/src/@api/hub/app/dto/index.ts +4 -4
  247. package/dist/templates/backend/packages/hub/src/@api/hub/app/index.ts +24 -24
  248. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-create-app.resolver.ts +3 -3
  249. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-delete-app-by-id.resolver.ts +3 -3
  250. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-find-app-by-id.resolver.ts +3 -3
  251. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-find-app.resolver.ts +3 -3
  252. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-get-apps.resolver.ts +3 -3
  253. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-my-preferences-app.resolver.ts +3 -3
  254. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-paginate-apps.resolver.ts +3 -3
  255. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-save-my-launchpad-layout-app.resolver.ts +3 -3
  256. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-toggle-favorite-app.resolver.ts +3 -3
  257. package/dist/templates/backend/packages/hub/src/@api/hub/app/resolvers/hub-update-app-by-id.resolver.ts +3 -3
  258. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-create-app-account.controller.ts +3 -3
  259. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-create-apps-accounts.controller.ts +3 -3
  260. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-delete-app-account-by-id.controller.ts +3 -3
  261. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-delete-apps-accounts.controller.ts +3 -3
  262. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-find-app-account-by-id.controller.ts +3 -3
  263. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-find-app-account.controller.ts +3 -3
  264. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-get-apps-accounts.controller.ts +3 -3
  265. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-paginate-apps-accounts.controller.ts +2 -2
  266. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/controllers/hub-update-app-account-by-id.controller.ts +3 -3
  267. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/dto/hub-app-account.dto.ts +5 -4
  268. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/dto/index.ts +4 -4
  269. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/graphql/hub-app-account.graphql +9 -2
  270. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/index.ts +22 -22
  271. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-create-app-account.resolver.ts +3 -3
  272. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-create-apps-accounts.resolver.ts +3 -3
  273. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-delete-app-account-by-id.resolver.ts +3 -3
  274. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-delete-apps-accounts.resolver.ts +3 -3
  275. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-find-app-account-by-id.resolver.ts +3 -3
  276. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-find-app-account.resolver.ts +3 -3
  277. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-get-apps-accounts.resolver.ts +3 -3
  278. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-paginate-apps-accounts.resolver.ts +3 -3
  279. package/dist/templates/backend/packages/hub/src/@api/hub/app-account/resolvers/hub-update-app-account-by-id.resolver.ts +3 -3
  280. package/dist/templates/backend/packages/hub/src/@api/hub/hub-per-app-permission.seeder.spec.ts +27 -25
  281. package/dist/templates/backend/packages/hub/src/@api/hub/hub-per-app-permission.seeder.ts +11 -11
  282. package/dist/templates/backend/packages/hub/src/@api/hub/hub.module.ts +6 -6
  283. package/dist/templates/backend/packages/hub/src/@api/hub/hub.seeder.ts +5 -5
  284. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/create/hub-create-app.handler.spec.ts +66 -49
  285. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/create/hub-create-app.handler.ts +12 -12
  286. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/create/hub-create-app.service.ts +2 -2
  287. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/delete/hub-delete-app-by-id.handler.spec.ts +65 -36
  288. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/delete/hub-delete-app-by-id.handler.ts +16 -11
  289. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/delete/hub-delete-app-by-id.service.ts +1 -1
  290. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/find/hub-find-app-by-id.handler.spec.ts +52 -19
  291. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/find/hub-find-app-by-id.handler.ts +7 -4
  292. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/find/hub-find-app-by-id.service.ts +5 -3
  293. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/find/hub-find-app.handler.spec.ts +83 -21
  294. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/find/hub-find-app.handler.ts +8 -4
  295. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/find/hub-find-app.service.ts +5 -3
  296. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/get/hub-get-apps.handler.spec.ts +84 -28
  297. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/get/hub-get-apps.handler.ts +8 -4
  298. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/get/hub-get-apps.service.ts +5 -3
  299. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/my-preferences/hub-my-preferences-app.handler.spec.ts +15 -15
  300. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/my-preferences/hub-my-preferences-app.handler.ts +2 -2
  301. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/paginate/hub-paginate-apps.handler.spec.ts +83 -20
  302. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/paginate/hub-paginate-apps.handler.ts +8 -4
  303. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/paginate/hub-paginate-apps.service.ts +5 -3
  304. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/save-my-launchpad-layout/hub-save-my-launchpad-layout-app.handler.spec.ts +14 -15
  305. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/save-my-launchpad-layout/hub-save-my-launchpad-layout-app.handler.ts +2 -2
  306. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/toggle-favorite/hub-toggle-favorite-app.handler.spec.ts +16 -17
  307. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/toggle-favorite/hub-toggle-favorite-app.handler.ts +2 -2
  308. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/update/hub-update-app-by-id.handler.spec.ts +30 -11
  309. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/update/hub-update-app-by-id.handler.ts +9 -5
  310. package/dist/templates/backend/packages/hub/src/@app/hub/app/application/update/hub-update-app-by-id.service.ts +2 -2
  311. package/dist/templates/backend/packages/hub/src/@app/hub/app/domain/hub-app.field-schema.ts +2 -2
  312. package/dist/templates/backend/packages/hub/src/@app/hub/app/domain/index.ts +2 -2
  313. package/dist/templates/backend/packages/hub/src/@app/hub/app/index.ts +42 -42
  314. package/dist/templates/backend/packages/hub/src/@app/hub/app/infrastructure/drizzle/hub-drizzle-app.repository.ts +2 -2
  315. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/functions/hub-assert-no-accounts-reference.function.spec.ts +230 -0
  316. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/functions/hub-assert-no-accounts-reference.function.ts +106 -0
  317. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/functions/hub-sanitize-eager-loads-vs-relation-order.spec.ts +3 -3
  318. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/functions/hub-sanitize-eager-loads.function.spec.ts +1 -1
  319. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/functions/hub-validate-redirect-uri.function.spec.ts +1 -1
  320. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/functions/index.ts +3 -2
  321. package/dist/templates/backend/packages/hub/src/@app/hub/app/shared/index.ts +1 -1
  322. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/create/hub-create-app-account.handler.ts +5 -4
  323. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/create/hub-create-app-account.service.ts +2 -2
  324. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/create/hub-create-apps-accounts.handler.ts +4 -4
  325. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/create/hub-create-apps-accounts.service.ts +2 -2
  326. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/delete/hub-delete-app-account-by-id.handler.ts +4 -3
  327. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/delete/hub-delete-app-account-by-id.service.ts +1 -1
  328. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/delete/hub-delete-apps-accounts.handler.ts +4 -3
  329. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/delete/hub-delete-apps-accounts.service.ts +1 -1
  330. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/find/hub-find-app-account-by-id.handler.ts +3 -3
  331. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/find/hub-find-app-account-by-id.service.ts +5 -3
  332. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/find/hub-find-app-account.handler.ts +3 -3
  333. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/find/hub-find-app-account.service.ts +5 -3
  334. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/get/hub-get-apps-accounts.handler.ts +3 -3
  335. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/get/hub-get-apps-accounts.service.ts +5 -3
  336. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/paginate/hub-paginate-apps-accounts.handler.ts +3 -3
  337. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/paginate/hub-paginate-apps-accounts.service.ts +5 -3
  338. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/update/hub-update-app-account-by-id.handler.ts +5 -5
  339. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/application/update/hub-update-app-account-by-id.service.ts +2 -2
  340. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/domain/hub-app-account.field-schema.ts +2 -2
  341. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/domain/index.ts +1 -1
  342. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/index.ts +44 -44
  343. package/dist/templates/backend/packages/hub/src/@app/hub/app-account/infrastructure/drizzle/hub-drizzle-app-account.repository.ts +2 -2
  344. package/dist/templates/backend/packages/hub/src/@app/hub/hub.relations.ts +2 -2
  345. package/dist/templates/backend/packages/hub/src/@app/hub/index.ts +3 -10
  346. package/dist/templates/backend/packages/hub/src/@bridges/providers/iam-bounded-context-writer.bridge.ts +2 -2
  347. package/dist/templates/backend/packages/hub/src/@bridges/providers/iam-permission-writer.bridge.ts +2 -2
  348. package/dist/templates/backend/packages/hub/src/@bridges/providers/o-auth-application-provisioner.bridge.ts +2 -2
  349. package/dist/templates/backend/packages/hub/test/acceptance/hub/hub-app-account-composite-key.e2e-spec.ts +4 -19
  350. package/dist/templates/backend/packages/hub/test/acceptance/hub/hub-app-deprovisioning.e2e-spec.ts +7 -23
  351. package/dist/templates/backend/packages/hub/test/acceptance/hub/hub-app-provisioning.e2e-spec.ts +11 -32
  352. package/dist/templates/backend/packages/hub/test/acceptance/hub/hub-per-app-access.e2e-spec.ts +9 -26
  353. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-check-password-me-account.controller.ts +3 -3
  354. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-check-unique-email-account.controller.ts +2 -2
  355. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-check-unique-username-account.controller.ts +2 -2
  356. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-count-account.controller.ts +2 -2
  357. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-create-account.controller.ts +4 -4
  358. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-delete-account-by-id.controller.ts +3 -3
  359. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-delete-accounts.controller.ts +3 -3
  360. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-find-account-by-id.controller.ts +3 -3
  361. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-find-account.controller.ts +3 -3
  362. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-get-accounts.controller.ts +3 -3
  363. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-me-account.controller.ts +4 -4
  364. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-paginate-accounts.controller.ts +2 -2
  365. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-paginate-with-tenant-constraint-accounts.controller.ts +3 -3
  366. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-update-account-by-id.controller.ts +4 -4
  367. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-update-accounts.controller.ts +3 -3
  368. package/dist/templates/backend/packages/iam/src/@api/iam/account/controllers/iam-update-me-account.controller.ts +3 -3
  369. package/dist/templates/backend/packages/iam/src/@api/iam/account/dto/iam-account.dto.ts +19 -10
  370. package/dist/templates/backend/packages/iam/src/@api/iam/account/dto/iam-create-account.dto.ts +9 -29
  371. package/dist/templates/backend/packages/iam/src/@api/iam/account/dto/iam-update-account-by-id.dto.ts +9 -29
  372. package/dist/templates/backend/packages/iam/src/@api/iam/account/dto/iam-update-accounts.dto.ts +9 -21
  373. package/dist/templates/backend/packages/iam/src/@api/iam/account/dto/index.ts +4 -4
  374. package/dist/templates/backend/packages/iam/src/@api/iam/account/graphql/iam-account.graphql +14 -13
  375. package/dist/templates/backend/packages/iam/src/@api/iam/account/index.ts +38 -38
  376. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-check-password-me-account.resolver.ts +3 -3
  377. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-check-unique-email-account.resolver.ts +2 -2
  378. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-check-unique-username-account.resolver.ts +2 -2
  379. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-count-account.resolver.ts +2 -2
  380. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-create-account.resolver.ts +3 -3
  381. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-delete-account-by-id.resolver.ts +3 -3
  382. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-delete-accounts.resolver.ts +3 -3
  383. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-find-account-by-id.resolver.ts +3 -3
  384. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-find-account.resolver.ts +3 -3
  385. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-get-accounts.resolver.ts +3 -3
  386. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-me-account.resolver.ts +3 -3
  387. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-paginate-accounts.resolver.ts +3 -3
  388. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-paginate-with-tenant-constraint-accounts.resolver.ts +3 -3
  389. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-update-account-by-id.resolver.ts +3 -3
  390. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-update-accounts.resolver.ts +3 -3
  391. package/dist/templates/backend/packages/iam/src/@api/iam/account/resolvers/iam-update-me-account.resolver.ts +3 -3
  392. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-create-bounded-context.controller.ts +3 -3
  393. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-create-bounded-contexts.controller.ts +3 -3
  394. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-delete-bounded-context-by-id.controller.ts +3 -3
  395. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-delete-bounded-contexts.controller.ts +3 -3
  396. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-find-bounded-context-by-id.controller.ts +3 -3
  397. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-find-bounded-context.controller.ts +3 -3
  398. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-get-bounded-contexts.controller.ts +3 -3
  399. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-paginate-bounded-contexts.controller.ts +2 -2
  400. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-update-bounded-context-by-id.controller.ts +3 -3
  401. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/controllers/iam-update-bounded-contexts.controller.ts +3 -3
  402. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/dto/iam-bounded-context.dto.ts +3 -2
  403. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/dto/index.ts +4 -4
  404. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/index.ts +24 -24
  405. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-create-bounded-context.resolver.ts +3 -3
  406. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-create-bounded-contexts.resolver.ts +3 -3
  407. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-delete-bounded-context-by-id.resolver.ts +3 -3
  408. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-delete-bounded-contexts.resolver.ts +3 -3
  409. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-find-bounded-context-by-id.resolver.ts +3 -3
  410. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-find-bounded-context.resolver.ts +3 -3
  411. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-get-bounded-contexts.resolver.ts +3 -3
  412. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-paginate-bounded-contexts.resolver.ts +3 -3
  413. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-update-bounded-context-by-id.resolver.ts +3 -3
  414. package/dist/templates/backend/packages/iam/src/@api/iam/bounded-context/resolvers/iam-update-bounded-contexts.resolver.ts +3 -3
  415. package/dist/templates/backend/packages/iam/src/@api/iam/iam-bootstrap.seeder.spec.ts +22 -22
  416. package/dist/templates/backend/packages/iam/src/@api/iam/iam-bootstrap.seeder.ts +16 -12
  417. package/dist/templates/backend/packages/iam/src/@api/iam/iam.module.ts +25 -19
  418. package/dist/templates/backend/packages/iam/src/@api/iam/iam.seeder.ts +3 -3
  419. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-create-permission.controller.ts +3 -3
  420. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-create-permissions.controller.ts +3 -3
  421. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-delete-permission-by-id.controller.ts +3 -3
  422. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-delete-permissions.controller.ts +3 -3
  423. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-find-permission-by-id.controller.ts +3 -3
  424. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-find-permission.controller.ts +3 -3
  425. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-get-permissions.controller.ts +3 -3
  426. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-paginate-permissions.controller.ts +2 -2
  427. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-update-permission-by-id.controller.ts +3 -3
  428. package/dist/templates/backend/packages/iam/src/@api/iam/permission/controllers/iam-update-permissions.controller.ts +3 -3
  429. package/dist/templates/backend/packages/iam/src/@api/iam/permission/dto/iam-permission.dto.ts +5 -4
  430. package/dist/templates/backend/packages/iam/src/@api/iam/permission/dto/index.ts +4 -4
  431. package/dist/templates/backend/packages/iam/src/@api/iam/permission/graphql/iam-permission.graphql +3 -12
  432. package/dist/templates/backend/packages/iam/src/@api/iam/permission/index.ts +24 -24
  433. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-create-permission.resolver.ts +3 -3
  434. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-create-permissions.resolver.ts +3 -3
  435. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-delete-permission-by-id.resolver.ts +3 -3
  436. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-delete-permissions.resolver.ts +3 -3
  437. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-find-permission-by-id.resolver.ts +3 -3
  438. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-find-permission.resolver.ts +3 -3
  439. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-get-permissions.resolver.ts +3 -3
  440. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-paginate-permissions.resolver.ts +3 -3
  441. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-update-permission-by-id.resolver.ts +3 -3
  442. package/dist/templates/backend/packages/iam/src/@api/iam/permission/resolvers/iam-update-permissions.resolver.ts +3 -3
  443. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-create-permission-role.controller.ts +3 -3
  444. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-create-permissions-roles.controller.ts +3 -3
  445. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-delete-permission-role-by-id.controller.ts +3 -3
  446. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-delete-permissions-roles.controller.ts +3 -3
  447. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-find-permission-role-by-id.controller.ts +3 -3
  448. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-find-permission-role.controller.ts +3 -3
  449. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-get-permissions-roles.controller.ts +3 -3
  450. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-paginate-permissions-roles.controller.ts +3 -3
  451. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-update-permission-role-by-id.controller.ts +3 -3
  452. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/controllers/iam-update-permissions-roles.controller.ts +3 -3
  453. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/dto/iam-permission-role.dto.ts +5 -4
  454. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/dto/index.ts +4 -4
  455. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/index.ts +24 -24
  456. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-create-permission-role.resolver.ts +3 -3
  457. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-create-permissions-roles.resolver.ts +3 -3
  458. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-delete-permission-role-by-id.resolver.ts +3 -3
  459. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-delete-permissions-roles.resolver.ts +3 -3
  460. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-find-permission-role-by-id.resolver.ts +3 -3
  461. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-find-permission-role.resolver.ts +3 -3
  462. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-get-permissions-roles.resolver.ts +3 -3
  463. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-paginate-permissions-roles.resolver.ts +3 -3
  464. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-update-permission-role-by-id.resolver.ts +3 -3
  465. package/dist/templates/backend/packages/iam/src/@api/iam/permission-role/resolvers/iam-update-permissions-roles.resolver.ts +3 -3
  466. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-create-role.controller.ts +3 -3
  467. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-create-roles.controller.ts +3 -3
  468. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-delete-role-by-id.controller.ts +3 -3
  469. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-delete-roles.controller.ts +3 -3
  470. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-find-role-by-id.controller.ts +3 -3
  471. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-find-role.controller.ts +3 -3
  472. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-get-roles.controller.ts +3 -3
  473. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-inherit-permissions-role-role.controller.ts +3 -3
  474. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-paginate-roles.controller.ts +2 -2
  475. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-update-role-by-id.controller.ts +3 -3
  476. package/dist/templates/backend/packages/iam/src/@api/iam/role/controllers/iam-update-roles.controller.ts +3 -3
  477. package/dist/templates/backend/packages/iam/src/@api/iam/role/dto/iam-role.dto.ts +5 -4
  478. package/dist/templates/backend/packages/iam/src/@api/iam/role/dto/index.ts +4 -4
  479. package/dist/templates/backend/packages/iam/src/@api/iam/role/graphql/iam-role.graphql +3 -12
  480. package/dist/templates/backend/packages/iam/src/@api/iam/role/index.ts +26 -26
  481. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-create-role.resolver.ts +3 -3
  482. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-create-roles.resolver.ts +3 -3
  483. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-delete-role-by-id.resolver.ts +3 -3
  484. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-delete-roles.resolver.ts +3 -3
  485. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-find-role-by-id.resolver.ts +3 -3
  486. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-find-role.resolver.ts +3 -3
  487. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-get-roles.resolver.ts +3 -3
  488. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-inherit-permissions-role-role.resolver.ts +3 -3
  489. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-paginate-roles.resolver.ts +3 -3
  490. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-update-role-by-id.resolver.ts +3 -3
  491. package/dist/templates/backend/packages/iam/src/@api/iam/role/resolvers/iam-update-roles.resolver.ts +3 -3
  492. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-create-role-account.controller.ts +3 -3
  493. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-create-roles-accounts.controller.ts +3 -3
  494. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-delete-role-account-by-id.controller.ts +3 -3
  495. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-delete-roles-accounts.controller.ts +3 -3
  496. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-find-role-account-by-id.controller.ts +3 -3
  497. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-find-role-account.controller.ts +3 -3
  498. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-get-roles-accounts.controller.ts +3 -3
  499. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-paginate-roles-accounts.controller.ts +2 -2
  500. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-update-role-account-by-id.controller.ts +3 -3
  501. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/controllers/iam-update-roles-accounts.controller.ts +3 -3
  502. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/dto/iam-role-account.dto.ts +5 -4
  503. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/dto/index.ts +4 -4
  504. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/graphql/iam-role-account.graphql +3 -13
  505. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/index.ts +24 -24
  506. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-create-role-account.resolver.ts +3 -3
  507. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-create-roles-accounts.resolver.ts +3 -3
  508. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-delete-role-account-by-id.resolver.ts +3 -3
  509. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-delete-roles-accounts.resolver.ts +3 -3
  510. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-find-role-account-by-id.resolver.ts +3 -3
  511. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-find-role-account.resolver.ts +3 -3
  512. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-get-roles-accounts.resolver.ts +3 -3
  513. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-paginate-roles-accounts.resolver.ts +3 -3
  514. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-update-role-account-by-id.resolver.ts +3 -3
  515. package/dist/templates/backend/packages/iam/src/@api/iam/role-account/resolvers/iam-update-roles-accounts.resolver.ts +3 -3
  516. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-create-tag.controller.ts +3 -3
  517. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-delete-tag-by-id.controller.ts +3 -3
  518. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-find-tag-by-id.controller.ts +3 -3
  519. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-find-tag.controller.ts +3 -3
  520. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-get-tags.controller.ts +3 -3
  521. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-paginate-tags.controller.ts +2 -2
  522. package/dist/templates/backend/packages/iam/src/@api/iam/tag/controllers/iam-update-tag-by-id.controller.ts +3 -3
  523. package/dist/templates/backend/packages/iam/src/@api/iam/tag/dto/index.ts +4 -4
  524. package/dist/templates/backend/packages/iam/src/@api/iam/tag/index.ts +18 -18
  525. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-create-tag.resolver.ts +3 -3
  526. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-delete-tag-by-id.resolver.ts +3 -3
  527. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-find-tag-by-id.resolver.ts +3 -3
  528. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-find-tag.resolver.ts +3 -3
  529. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-get-tags.resolver.ts +3 -3
  530. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-paginate-tags.resolver.ts +3 -3
  531. package/dist/templates/backend/packages/iam/src/@api/iam/tag/resolvers/iam-update-tag-by-id.resolver.ts +3 -3
  532. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-create-tenant.controller.ts +7 -5
  533. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-create-tenants.controller.ts +7 -5
  534. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-delete-tenant-by-id.controller.ts +3 -3
  535. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-delete-tenants.controller.ts +3 -3
  536. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-find-tenant-by-id.controller.ts +3 -3
  537. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-find-tenant.controller.ts +3 -3
  538. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-get-tenants.controller.ts +3 -3
  539. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-get-with-tenant-constraint-tenants.controller.ts +3 -3
  540. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-paginate-tenants.controller.ts +2 -2
  541. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-paginate-with-tenant-constraint-tenants.controller.ts +3 -3
  542. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-update-tenant-by-id.controller.ts +13 -5
  543. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/controllers/iam-update-tenants.controller.ts +13 -5
  544. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/dto/iam-tenant.dto.ts +4 -3
  545. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/dto/index.ts +4 -4
  546. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/graphql/iam-tenant.graphql +3 -12
  547. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/index.ts +28 -28
  548. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-create-tenant.resolver.ts +6 -5
  549. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-create-tenants.resolver.ts +6 -5
  550. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-delete-tenant-by-id.resolver.ts +3 -3
  551. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-delete-tenants.resolver.ts +3 -3
  552. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-find-tenant-by-id.resolver.ts +3 -3
  553. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-find-tenant.resolver.ts +3 -3
  554. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-get-tenants.resolver.ts +3 -3
  555. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-get-with-tenant-constraint-tenants.resolver.ts +3 -3
  556. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-paginate-tenants.resolver.ts +3 -3
  557. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-paginate-with-tenant-constraint-tenants.resolver.ts +3 -3
  558. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-update-tenant-by-id.resolver.ts +12 -5
  559. package/dist/templates/backend/packages/iam/src/@api/iam/tenant/resolvers/iam-update-tenants.resolver.ts +12 -5
  560. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-create-tenant-account.controller.ts +7 -5
  561. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-create-tenants-accounts.controller.ts +7 -5
  562. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-delete-tenant-account-by-id.controller.ts +3 -3
  563. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-delete-tenants-accounts.controller.ts +3 -3
  564. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-find-tenant-account-by-id.controller.ts +3 -3
  565. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-find-tenant-account.controller.ts +3 -3
  566. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-get-tenants-accounts.controller.ts +3 -3
  567. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-paginate-tenants-accounts.controller.ts +2 -2
  568. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-update-tenant-account-by-id.controller.ts +13 -5
  569. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/controllers/iam-update-tenants-accounts.controller.ts +13 -5
  570. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/dto/iam-tenant-account.dto.ts +5 -4
  571. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/dto/index.ts +4 -4
  572. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/index.ts +24 -24
  573. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-create-tenant-account.resolver.ts +6 -5
  574. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-create-tenants-accounts.resolver.ts +6 -5
  575. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-delete-tenant-account-by-id.resolver.ts +3 -3
  576. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-delete-tenants-accounts.resolver.ts +3 -3
  577. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-find-tenant-account-by-id.resolver.ts +3 -3
  578. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-find-tenant-account.resolver.ts +3 -3
  579. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-get-tenants-accounts.resolver.ts +3 -3
  580. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-paginate-tenants-accounts.resolver.ts +3 -3
  581. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-update-tenant-account-by-id.resolver.ts +12 -5
  582. package/dist/templates/backend/packages/iam/src/@api/iam/tenant-account/resolvers/iam-update-tenants-accounts.resolver.ts +12 -5
  583. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-count-user.controller.ts +2 -2
  584. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-delete-user-by-id.controller.ts +3 -3
  585. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-delete-users.controller.ts +3 -3
  586. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-find-user-by-id.controller.ts +3 -3
  587. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-find-user.controller.ts +3 -3
  588. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-forgot-password-user.controller.ts +3 -3
  589. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-get-users.controller.ts +3 -3
  590. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-paginate-users.controller.ts +2 -2
  591. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-reset-password-user.controller.ts +3 -3
  592. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-update-user-by-id.controller.ts +3 -3
  593. package/dist/templates/backend/packages/iam/src/@api/iam/user/controllers/iam-update-users.controller.ts +3 -3
  594. package/dist/templates/backend/packages/iam/src/@api/iam/user/dto/iam-user.dto.ts +3 -2
  595. package/dist/templates/backend/packages/iam/src/@api/iam/user/dto/index.ts +4 -4
  596. package/dist/templates/backend/packages/iam/src/@api/iam/user/index.ts +26 -26
  597. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-count-user.resolver.ts +2 -2
  598. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-delete-user-by-id.resolver.ts +3 -3
  599. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-delete-users.resolver.ts +3 -3
  600. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-find-user-by-id.resolver.ts +3 -3
  601. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-find-user.resolver.ts +3 -3
  602. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-forgot-password-user.resolver.ts +3 -3
  603. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-get-users.resolver.ts +3 -3
  604. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-paginate-users.resolver.ts +3 -3
  605. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-reset-password-user.resolver.ts +3 -3
  606. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-update-user-by-id.resolver.ts +3 -3
  607. package/dist/templates/backend/packages/iam/src/@api/iam/user/resolvers/iam-update-users.resolver.ts +3 -3
  608. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/check-password-me/iam-check-password-me-account.handler.ts +1 -1
  609. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/check-unique-email/iam-check-unique-email-account.handler.spec.ts +4 -4
  610. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/check-unique-email/iam-check-unique-email-account.handler.ts +1 -1
  611. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/check-unique-username/iam-check-unique-username-account.handler.spec.ts +4 -4
  612. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/check-unique-username/iam-check-unique-username-account.handler.ts +1 -1
  613. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/count/iam-count-account.handler.ts +1 -1
  614. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/count/iam-count-account.service.ts +1 -1
  615. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/create/iam-create-account.handler.spec.ts +196 -34
  616. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/create/iam-create-account.handler.ts +79 -34
  617. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/create/iam-create-account.service.ts +3 -3
  618. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/create/iam-create-accounts.service.ts +2 -2
  619. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/delete/iam-delete-account-by-id.handler.ts +4 -3
  620. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/delete/iam-delete-account-by-id.service.ts +1 -1
  621. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/delete/iam-delete-accounts.handler.ts +4 -3
  622. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/delete/iam-delete-accounts.service.ts +1 -1
  623. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/find/iam-find-account-by-id.handler.ts +3 -3
  624. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/find/iam-find-account-by-id.service.ts +5 -3
  625. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/find/iam-find-account.handler.ts +3 -3
  626. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/find/iam-find-account.service.ts +5 -3
  627. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/get/iam-get-accounts.handler.ts +3 -3
  628. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/get/iam-get-accounts.service.ts +5 -3
  629. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/iam-account.payload-types.ts +34 -0
  630. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/me/iam-me-account.handler.spec.ts +3 -3
  631. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/me/iam-me-account.handler.ts +1 -1
  632. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/paginate/iam-paginate-accounts.handler.ts +3 -3
  633. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/paginate/iam-paginate-accounts.service.ts +5 -3
  634. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/paginate-with-tenant-constraint/iam-paginate-with-tenant-constraint-accounts.handler.ts +1 -1
  635. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/iam-update-account-by-id.handler.spec.ts +428 -50
  636. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/iam-update-account-by-id.handler.ts +126 -48
  637. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/iam-update-account-by-id.service.ts +3 -3
  638. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/iam-update-accounts.handler.spec.ts +94 -11
  639. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/iam-update-accounts.handler.ts +25 -8
  640. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/iam-update-accounts.service.ts +3 -3
  641. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/subscribers/iam-account-updated-cache-invalidator.subscriber.spec.ts +62 -0
  642. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update/subscribers/iam-account-updated-cache-invalidator.subscriber.ts +59 -0
  643. package/dist/templates/backend/packages/iam/src/@app/iam/account/application/update-me/iam-update-me-account.handler.ts +2 -2
  644. package/dist/templates/backend/packages/iam/src/@app/iam/account/domain/iam-account.field-schema.ts +12 -4
  645. package/dist/templates/backend/packages/iam/src/@app/iam/account/domain/index.ts +1 -1
  646. package/dist/templates/backend/packages/iam/src/@app/iam/account/index.ts +35 -30
  647. package/dist/templates/backend/packages/iam/src/@app/iam/account/infrastructure/drizzle/iam-drizzle-account.repository.ts +4 -4
  648. package/dist/templates/backend/packages/iam/src/@app/iam/account/infrastructure/drizzle/iam-drizzle-account.schema.ts +1 -0
  649. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/create/iam-create-bounded-context.handler.ts +5 -7
  650. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/create/iam-create-bounded-context.service.ts +2 -2
  651. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/create/iam-create-bounded-contexts.handler.ts +4 -4
  652. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/create/iam-create-bounded-contexts.service.ts +2 -2
  653. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/delete/iam-delete-bounded-context-by-id.handler.ts +4 -6
  654. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/delete/iam-delete-bounded-context-by-id.service.ts +1 -1
  655. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/delete/iam-delete-bounded-contexts.handler.ts +4 -6
  656. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/delete/iam-delete-bounded-contexts.service.ts +1 -1
  657. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/find/iam-find-bounded-context-by-id.handler.ts +3 -3
  658. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/find/iam-find-bounded-context-by-id.service.ts +5 -3
  659. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/find/iam-find-bounded-context.handler.ts +3 -3
  660. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/find/iam-find-bounded-context.service.ts +5 -3
  661. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/get/iam-get-bounded-contexts.handler.ts +3 -3
  662. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/get/iam-get-bounded-contexts.service.ts +5 -3
  663. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/paginate/iam-paginate-bounded-contexts.handler.ts +3 -3
  664. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/paginate/iam-paginate-bounded-contexts.service.ts +5 -3
  665. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/update/iam-update-bounded-context-by-id.handler.ts +5 -8
  666. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/update/iam-update-bounded-context-by-id.service.ts +2 -2
  667. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/update/iam-update-bounded-contexts.handler.ts +5 -7
  668. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/application/update/iam-update-bounded-contexts.service.ts +2 -2
  669. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/domain/iam-bounded-context.field-schema.ts +1 -1
  670. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/domain/index.ts +1 -1
  671. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/index.ts +48 -48
  672. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/infrastructure/drizzle/iam-drizzle-bounded-context.repository.ts +2 -2
  673. package/dist/templates/backend/packages/iam/src/@app/iam/bounded-context/infrastructure/drizzle/iam-drizzle-bounded-context.schema.ts +4 -1
  674. package/dist/templates/backend/packages/iam/src/@app/iam/iam.relations.ts +10 -10
  675. package/dist/templates/backend/packages/iam/src/@app/iam/index.ts +10 -10
  676. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/create/iam-create-permission.handler.ts +5 -4
  677. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/create/iam-create-permission.service.ts +2 -2
  678. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/create/iam-create-permissions.handler.ts +4 -4
  679. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/create/iam-create-permissions.service.ts +2 -2
  680. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/delete/iam-delete-permission-by-id.handler.ts +4 -3
  681. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/delete/iam-delete-permission-by-id.service.ts +1 -1
  682. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/delete/iam-delete-permissions.handler.ts +4 -3
  683. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/delete/iam-delete-permissions.service.ts +1 -1
  684. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/find/iam-find-permission-by-id.handler.ts +3 -3
  685. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/find/iam-find-permission-by-id.service.ts +5 -3
  686. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/find/iam-find-permission.handler.ts +3 -3
  687. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/find/iam-find-permission.service.ts +5 -3
  688. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/get/iam-get-permissions.handler.ts +3 -3
  689. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/get/iam-get-permissions.service.ts +5 -3
  690. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/get-permissions-without-role/iam-get-permissions-without-role.handler.spec.ts +19 -19
  691. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/get-permissions-without-role/iam-get-permissions-without-role.handler.ts +1 -1
  692. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/paginate/iam-paginate-permissions.handler.ts +3 -3
  693. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/paginate/iam-paginate-permissions.service.ts +5 -3
  694. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/update/iam-update-permission-by-id.handler.ts +5 -5
  695. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/update/iam-update-permission-by-id.service.ts +2 -2
  696. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/update/iam-update-permissions.handler.ts +5 -4
  697. package/dist/templates/backend/packages/iam/src/@app/iam/permission/application/update/iam-update-permissions.service.ts +2 -2
  698. package/dist/templates/backend/packages/iam/src/@app/iam/permission/domain/iam-permission.field-schema.ts +2 -2
  699. package/dist/templates/backend/packages/iam/src/@app/iam/permission/domain/index.ts +1 -1
  700. package/dist/templates/backend/packages/iam/src/@app/iam/permission/index.ts +51 -50
  701. package/dist/templates/backend/packages/iam/src/@app/iam/permission/infrastructure/drizzle/iam-drizzle-permission.repository.ts +3 -3
  702. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/create/iam-create-permission-role.handler.ts +5 -7
  703. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/create/iam-create-permission-role.service.ts +2 -2
  704. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/create/iam-create-permissions-roles.handler.ts +4 -4
  705. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/create/iam-create-permissions-roles.service.ts +2 -2
  706. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/delete/iam-delete-permission-role-by-id.handler.ts +4 -6
  707. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/delete/iam-delete-permission-role-by-id.service.ts +1 -1
  708. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/delete/iam-delete-permissions-roles.handler.ts +4 -6
  709. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/delete/iam-delete-permissions-roles.service.ts +1 -1
  710. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/find/iam-find-permission-role-by-id.handler.ts +3 -3
  711. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/find/iam-find-permission-role-by-id.service.ts +5 -3
  712. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/find/iam-find-permission-role.handler.ts +3 -3
  713. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/find/iam-find-permission-role.service.ts +5 -3
  714. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/get/iam-get-permissions-roles.handler.ts +3 -3
  715. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/get/iam-get-permissions-roles.service.ts +5 -3
  716. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/paginate/iam-paginate-permissions-roles.handler.ts +3 -3
  717. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/paginate/iam-paginate-permissions-roles.service.ts +5 -3
  718. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/update/iam-update-permission-role-by-id.handler.ts +5 -8
  719. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/update/iam-update-permission-role-by-id.service.ts +2 -2
  720. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/update/iam-update-permissions-roles.handler.ts +5 -7
  721. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/application/update/iam-update-permissions-roles.service.ts +2 -2
  722. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/domain/iam-permission-role.field-schema.ts +2 -2
  723. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/domain/index.ts +1 -1
  724. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/index.ts +48 -48
  725. package/dist/templates/backend/packages/iam/src/@app/iam/permission-role/infrastructure/drizzle/iam-drizzle-permission-role.repository.ts +2 -2
  726. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/create/iam-create-role.handler.ts +5 -4
  727. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/create/iam-create-role.service.ts +2 -2
  728. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/create/iam-create-roles.handler.ts +4 -4
  729. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/create/iam-create-roles.service.ts +2 -2
  730. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/delete/iam-delete-role-by-id.handler.ts +4 -3
  731. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/delete/iam-delete-role-by-id.service.ts +1 -1
  732. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/delete/iam-delete-roles.handler.ts +4 -3
  733. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/delete/iam-delete-roles.service.ts +1 -1
  734. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/find/iam-find-role-by-id.handler.ts +3 -3
  735. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/find/iam-find-role-by-id.service.ts +5 -3
  736. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/find/iam-find-role.handler.ts +3 -3
  737. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/find/iam-find-role.service.ts +5 -3
  738. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/get/iam-get-roles.handler.ts +3 -3
  739. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/get/iam-get-roles.service.ts +5 -3
  740. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/inherit-permissions-role/iam-inherit-permissions-role-role.handler.ts +2 -2
  741. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/paginate/iam-paginate-roles.handler.ts +3 -3
  742. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/paginate/iam-paginate-roles.service.ts +5 -3
  743. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/update/iam-update-role-by-id.handler.ts +5 -5
  744. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/update/iam-update-role-by-id.service.ts +2 -2
  745. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/update/iam-update-roles.handler.ts +5 -4
  746. package/dist/templates/backend/packages/iam/src/@app/iam/role/application/update/iam-update-roles.service.ts +2 -2
  747. package/dist/templates/backend/packages/iam/src/@app/iam/role/domain/iam-role.field-schema.ts +2 -2
  748. package/dist/templates/backend/packages/iam/src/@app/iam/role/domain/index.ts +1 -1
  749. package/dist/templates/backend/packages/iam/src/@app/iam/role/index.ts +50 -50
  750. package/dist/templates/backend/packages/iam/src/@app/iam/role/infrastructure/drizzle/iam-drizzle-role.repository.ts +4 -4
  751. package/dist/templates/backend/packages/iam/src/@app/iam/role/infrastructure/drizzle/iam-drizzle-role.schema.ts +4 -1
  752. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/create/iam-create-role-account.handler.ts +5 -4
  753. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/create/iam-create-role-account.service.ts +2 -2
  754. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/create/iam-create-roles-accounts.handler.ts +4 -4
  755. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/create/iam-create-roles-accounts.service.ts +2 -2
  756. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/delete/iam-delete-role-account-by-id.handler.ts +4 -6
  757. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/delete/iam-delete-role-account-by-id.service.ts +1 -1
  758. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/delete/iam-delete-roles-accounts.handler.ts +4 -3
  759. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/delete/iam-delete-roles-accounts.service.ts +1 -1
  760. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/find/iam-find-role-account-by-id.handler.ts +3 -3
  761. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/find/iam-find-role-account-by-id.service.ts +5 -3
  762. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/find/iam-find-role-account.handler.ts +3 -3
  763. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/find/iam-find-role-account.service.ts +5 -3
  764. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/get/iam-get-roles-accounts.handler.ts +3 -3
  765. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/get/iam-get-roles-accounts.service.ts +5 -3
  766. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/paginate/iam-paginate-roles-accounts.handler.ts +3 -3
  767. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/paginate/iam-paginate-roles-accounts.service.ts +5 -3
  768. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/update/iam-update-role-account-by-id.handler.ts +5 -8
  769. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/update/iam-update-role-account-by-id.service.ts +2 -2
  770. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/update/iam-update-roles-accounts.handler.ts +5 -4
  771. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/application/update/iam-update-roles-accounts.service.ts +2 -2
  772. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/domain/iam-role-account.field-schema.ts +2 -2
  773. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/domain/index.ts +1 -1
  774. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/index.ts +48 -48
  775. package/dist/templates/backend/packages/iam/src/@app/iam/role-account/infrastructure/drizzle/iam-drizzle-role-account.repository.ts +2 -2
  776. package/dist/templates/backend/packages/iam/src/@app/iam/shared/functions/iam-create-permissions-from-roles.function.ts +2 -2
  777. package/dist/templates/backend/packages/iam/src/@app/iam/shared/functions/iam-resolve-account-tenants.function.spec.ts +100 -0
  778. package/dist/templates/backend/packages/iam/src/@app/iam/shared/functions/iam-resolve-account-tenants.function.ts +59 -0
  779. package/dist/templates/backend/packages/iam/src/@app/iam/shared/iam-bootstrap.constants.ts +3 -4
  780. package/dist/templates/backend/packages/iam/src/@app/iam/shared/index.ts +4 -3
  781. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/create/iam-create-tag.handler.ts +5 -4
  782. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/create/iam-create-tag.service.ts +2 -2
  783. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/delete/iam-delete-tag-by-id.handler.ts +4 -3
  784. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/delete/iam-delete-tag-by-id.service.ts +1 -1
  785. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/find/iam-find-tag-by-id.handler.ts +3 -3
  786. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/find/iam-find-tag-by-id.service.ts +2 -2
  787. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/find/iam-find-tag.handler.ts +3 -3
  788. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/find/iam-find-tag.service.ts +2 -2
  789. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/get/iam-get-tags.handler.ts +3 -3
  790. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/get/iam-get-tags.service.ts +2 -2
  791. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/paginate/iam-paginate-tags.handler.ts +3 -3
  792. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/paginate/iam-paginate-tags.service.ts +2 -2
  793. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/update/iam-update-tag-by-id.handler.ts +5 -4
  794. package/dist/templates/backend/packages/iam/src/@app/iam/tag/application/update/iam-update-tag-by-id.service.ts +2 -2
  795. package/dist/templates/backend/packages/iam/src/@app/iam/tag/domain/index.ts +1 -1
  796. package/dist/templates/backend/packages/iam/src/@app/iam/tag/index.ts +17 -17
  797. package/dist/templates/backend/packages/iam/src/@app/iam/tag/infrastructure/drizzle/iam-drizzle-tag.repository.ts +2 -2
  798. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/create/iam-create-tenant.handler.spec.ts +195 -0
  799. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/create/iam-create-tenant.handler.ts +85 -7
  800. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/create/iam-create-tenant.service.ts +2 -2
  801. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/create/iam-create-tenants.handler.spec.ts +98 -0
  802. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/create/iam-create-tenants.handler.ts +53 -7
  803. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/create/iam-create-tenants.service.ts +2 -2
  804. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/delete/iam-delete-tenant-by-id.handler.ts +4 -3
  805. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/delete/iam-delete-tenant-by-id.service.ts +1 -1
  806. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/delete/iam-delete-tenants.handler.ts +4 -3
  807. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/delete/iam-delete-tenants.service.ts +1 -1
  808. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/find/iam-find-tenant-by-id.handler.ts +3 -3
  809. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/find/iam-find-tenant-by-id.service.ts +5 -3
  810. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/find/iam-find-tenant.handler.ts +3 -3
  811. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/find/iam-find-tenant.service.ts +5 -3
  812. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/get/iam-get-tenants.handler.ts +3 -3
  813. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/get/iam-get-tenants.service.ts +5 -3
  814. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/get-with-tenant-constraint/iam-get-with-tenant-constraint-tenants.handler.ts +1 -1
  815. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/paginate/iam-paginate-tenants.handler.ts +3 -3
  816. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/paginate/iam-paginate-tenants.service.ts +5 -3
  817. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/paginate-with-tenant-constraint/iam-paginate-with-tenant-constraint-tenants.handler.ts +1 -1
  818. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/update/iam-update-tenant-by-id.handler.spec.ts +222 -0
  819. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/update/iam-update-tenant-by-id.handler.ts +78 -7
  820. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/update/iam-update-tenant-by-id.service.ts +2 -2
  821. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/update/iam-update-tenants.handler.spec.ts +75 -0
  822. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/update/iam-update-tenants.handler.ts +27 -5
  823. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/application/update/iam-update-tenants.service.ts +2 -2
  824. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/domain/iam-tenant.field-schema.ts +1 -1
  825. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/domain/index.ts +1 -1
  826. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/index.ts +52 -52
  827. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/infrastructure/drizzle/iam-drizzle-tenant.repository.ts +9 -3
  828. package/dist/templates/backend/packages/iam/src/@app/iam/tenant/infrastructure/drizzle/iam-drizzle-tenant.schema.ts +4 -1
  829. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/create/iam-create-tenant-account.handler.spec.ts +115 -0
  830. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/create/iam-create-tenant-account.handler.ts +38 -9
  831. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/create/iam-create-tenant-account.service.ts +2 -2
  832. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/create/iam-create-tenants-accounts.handler.spec.ts +105 -0
  833. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/create/iam-create-tenants-accounts.handler.ts +43 -7
  834. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/create/iam-create-tenants-accounts.service.ts +2 -2
  835. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/delete/iam-delete-tenant-account-by-id.handler.ts +4 -6
  836. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/delete/iam-delete-tenant-account-by-id.service.ts +1 -1
  837. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/delete/iam-delete-tenants-accounts.handler.ts +4 -6
  838. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/delete/iam-delete-tenants-accounts.service.ts +1 -1
  839. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/find/iam-find-tenant-account-by-id.handler.ts +3 -3
  840. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/find/iam-find-tenant-account-by-id.service.ts +5 -3
  841. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/find/iam-find-tenant-account.handler.ts +3 -3
  842. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/find/iam-find-tenant-account.service.ts +5 -3
  843. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/get/iam-get-tenants-accounts.handler.ts +3 -3
  844. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/get/iam-get-tenants-accounts.service.ts +5 -3
  845. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/paginate/iam-paginate-tenants-accounts.handler.ts +3 -3
  846. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/paginate/iam-paginate-tenants-accounts.service.ts +5 -3
  847. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/update/iam-update-tenant-account-by-id.handler.spec.ts +83 -0
  848. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/update/iam-update-tenant-account-by-id.handler.ts +27 -9
  849. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/update/iam-update-tenant-account-by-id.service.ts +2 -2
  850. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/update/iam-update-tenants-accounts.handler.spec.ts +78 -0
  851. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/update/iam-update-tenants-accounts.handler.ts +26 -8
  852. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/application/update/iam-update-tenants-accounts.service.ts +2 -2
  853. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/domain/iam-tenant-account.field-schema.ts +2 -2
  854. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/domain/index.ts +1 -1
  855. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/index.ts +48 -48
  856. package/dist/templates/backend/packages/iam/src/@app/iam/tenant-account/infrastructure/drizzle/iam-drizzle-tenant-account.repository.ts +2 -2
  857. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/count/iam-count-user.handler.ts +1 -1
  858. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/count/iam-count-user.service.ts +1 -1
  859. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/create/iam-create-user.handler.ts +5 -4
  860. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/create/iam-create-user.service.ts +2 -2
  861. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/create/iam-create-users.handler.ts +4 -4
  862. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/create/iam-create-users.service.ts +2 -2
  863. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/delete/iam-delete-user-by-id.handler.ts +4 -4
  864. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/delete/iam-delete-user-by-id.service.ts +1 -1
  865. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/delete/iam-delete-users.handler.ts +4 -4
  866. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/delete/iam-delete-users.service.ts +1 -1
  867. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/find/iam-find-user-by-id.handler.ts +3 -3
  868. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/find/iam-find-user-by-id.service.ts +5 -3
  869. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/find/iam-find-user-by-username-password.service.spec.ts +5 -4
  870. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/find/iam-find-user-by-username-password.service.ts +2 -2
  871. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/find/iam-find-user.handler.ts +3 -3
  872. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/find/iam-find-user.service.ts +5 -3
  873. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/forgot-password/iam-forgot-password-user.handler.ts +2 -2
  874. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/get/iam-get-users.handler.ts +3 -3
  875. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/get/iam-get-users.service.ts +5 -3
  876. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/paginate/iam-paginate-users.handler.ts +3 -3
  877. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/paginate/iam-paginate-users.service.ts +5 -3
  878. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/reset-password/iam-reset-password-user.handler.ts +2 -2
  879. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/update/iam-update-user-by-id.handler.ts +5 -5
  880. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/update/iam-update-user-by-id.service.ts +2 -2
  881. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/update/iam-update-users.handler.ts +5 -5
  882. package/dist/templates/backend/packages/iam/src/@app/iam/user/application/update/iam-update-users.service.ts +2 -2
  883. package/dist/templates/backend/packages/iam/src/@app/iam/user/domain/iam-user.field-schema.spec.ts +1 -10
  884. package/dist/templates/backend/packages/iam/src/@app/iam/user/domain/iam-user.field-schema.ts +1 -1
  885. package/dist/templates/backend/packages/iam/src/@app/iam/user/domain/index.ts +1 -1
  886. package/dist/templates/backend/packages/iam/src/@app/iam/user/index.ts +58 -58
  887. package/dist/templates/backend/packages/iam/src/@app/iam/user/infrastructure/drizzle/iam-drizzle-user.repository.ts +2 -2
  888. package/dist/templates/backend/packages/iam/src/@app/iam/user/infrastructure/drizzle/iam-drizzle-user.schema.ts +1 -1
  889. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/iam-account-loader.adapter.spec.ts +320 -15
  890. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/iam-account-loader.adapter.ts +126 -17
  891. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/iam-account-provisioner.adapter.spec.ts +38 -17
  892. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/iam-account-provisioner.adapter.ts +10 -4
  893. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/iam-operator-account-reader.adapter.spec.ts +4 -4
  894. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/iam-operator-account-reader.adapter.ts +2 -2
  895. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/adapters/index.ts +3 -3
  896. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/index.ts +1 -1
  897. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/ports/iam-account-provisioner.port.ts +8 -1
  898. package/dist/templates/backend/packages/iam/src/@bridges/iam/account/ports/index.ts +2 -2
  899. package/dist/templates/backend/packages/iam/src/@bridges/iam/bounded-context/adapters/iam-bounded-context-seeder.adapter.ts +2 -2
  900. package/dist/templates/backend/packages/iam/src/@bridges/iam/bounded-context/adapters/iam-bounded-context-writer.adapter.spec.ts +12 -11
  901. package/dist/templates/backend/packages/iam/src/@bridges/iam/bounded-context/adapters/iam-bounded-context-writer.adapter.ts +2 -2
  902. package/dist/templates/backend/packages/iam/src/@bridges/iam/bounded-context/adapters/index.ts +2 -2
  903. package/dist/templates/backend/packages/iam/src/@bridges/iam/bounded-context/index.ts +1 -1
  904. package/dist/templates/backend/packages/iam/src/@bridges/iam/bounded-context/ports/index.ts +4 -4
  905. package/dist/templates/backend/packages/iam/src/@bridges/iam/client/index.ts +1 -1
  906. package/dist/templates/backend/packages/iam/src/@bridges/iam/client/ports/index.ts +2 -2
  907. package/dist/templates/backend/packages/iam/src/@bridges/iam/permission/adapters/iam-permission-seeder.adapter.ts +2 -2
  908. package/dist/templates/backend/packages/iam/src/@bridges/iam/permission/adapters/iam-permission-writer.adapter.spec.ts +21 -21
  909. package/dist/templates/backend/packages/iam/src/@bridges/iam/permission/adapters/iam-permission-writer.adapter.ts +5 -5
  910. package/dist/templates/backend/packages/iam/src/@bridges/iam/permission/adapters/index.ts +2 -2
  911. package/dist/templates/backend/packages/iam/src/@bridges/iam/permission/index.ts +1 -1
  912. package/dist/templates/backend/packages/iam/src/@bridges/iam/permission/ports/index.ts +4 -4
  913. package/dist/templates/backend/packages/iam/src/@bridges/iam/tenant/adapters/iam-tenant-writer.adapter.spec.ts +15 -11
  914. package/dist/templates/backend/packages/iam/src/@bridges/iam/tenant/adapters/iam-tenant-writer.adapter.ts +11 -5
  915. package/dist/templates/backend/packages/iam/src/@bridges/iam/tenant/adapters/index.ts +1 -1
  916. package/dist/templates/backend/packages/iam/src/@bridges/iam/tenant/index.ts +1 -1
  917. package/dist/templates/backend/packages/iam/src/@bridges/iam/tenant/ports/iam-tenant-writer.port.ts +1 -1
  918. package/dist/templates/backend/packages/iam/src/@bridges/iam/tenant/ports/index.ts +2 -2
  919. package/dist/templates/backend/packages/iam/src/@bridges/iam/user/adapters/iam-credential-verifier.adapter.ts +2 -2
  920. package/dist/templates/backend/packages/iam/src/@bridges/iam/user/adapters/index.ts +1 -1
  921. package/dist/templates/backend/packages/iam/src/@bridges/providers/account-loader.bridge.ts +2 -2
  922. package/dist/templates/backend/packages/iam/src/@bridges/providers/credential-verifier.bridge.ts +2 -2
  923. package/dist/templates/backend/packages/iam/src/@bridges/providers/iam-bounded-context-seeder.bridge.ts +2 -2
  924. package/dist/templates/backend/packages/iam/src/@bridges/providers/iam-permission-seeder.bridge.ts +2 -2
  925. package/dist/templates/backend/packages/iam/test/acceptance/iam/core-back-exception-status.e2e-spec.ts +12 -30
  926. package/dist/templates/backend/packages/iam/test/acceptance/iam/user-sensitive-fields-masking.e2e-spec.ts +33 -41
  927. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/controllers/o-auth-count-access-token.controller.ts +2 -2
  928. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/controllers/o-auth-delete-access-token-by-id.controller.ts +3 -3
  929. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/controllers/o-auth-find-access-token-by-id.controller.ts +3 -3
  930. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/controllers/o-auth-find-access-token.controller.ts +3 -3
  931. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/controllers/o-auth-get-access-tokens.controller.ts +3 -3
  932. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/controllers/o-auth-paginate-access-tokens.controller.ts +2 -2
  933. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/dto/index.ts +4 -4
  934. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/dto/o-auth-access-token.dto.ts +5 -4
  935. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/dto/o-auth-create-access-token.dto.ts +4 -3
  936. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/dto/o-auth-update-access-token-by-id.dto.ts +4 -3
  937. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/dto/o-auth-update-access-tokens.dto.ts +4 -3
  938. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/graphql/o-auth-access-token.graphql +1 -4
  939. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/index.ts +18 -18
  940. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/resolvers/o-auth-count-access-token.resolver.ts +2 -2
  941. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/resolvers/o-auth-delete-access-token-by-id.resolver.ts +3 -3
  942. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/resolvers/o-auth-find-access-token-by-id.resolver.ts +3 -3
  943. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/resolvers/o-auth-find-access-token.resolver.ts +3 -3
  944. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/resolvers/o-auth-get-access-tokens.resolver.ts +3 -3
  945. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/access-token/resolvers/o-auth-paginate-access-tokens.resolver.ts +3 -3
  946. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-create-application.controller.ts +3 -3
  947. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-delete-application-by-id.controller.ts +3 -3
  948. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-find-application-by-id.controller.ts +3 -3
  949. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-find-application.controller.ts +3 -3
  950. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-get-applications.controller.ts +3 -3
  951. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-paginate-applications.controller.ts +2 -2
  952. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/controllers/o-auth-update-application-by-id.controller.ts +3 -3
  953. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/dto/index.ts +4 -4
  954. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/dto/o-auth-application.dto.ts +3 -2
  955. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/graphql/o-auth-application.graphql +12 -3
  956. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/index.ts +18 -18
  957. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-create-application.resolver.ts +3 -3
  958. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-delete-application-by-id.resolver.ts +3 -3
  959. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-find-application-by-id.resolver.ts +3 -3
  960. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-find-application.resolver.ts +3 -3
  961. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-get-applications.resolver.ts +3 -3
  962. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-paginate-applications.resolver.ts +3 -3
  963. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application/resolvers/o-auth-update-application-by-id.resolver.ts +3 -3
  964. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-create-application-client.controller.ts +3 -3
  965. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-create-applications-clients.controller.ts +3 -3
  966. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-delete-application-client-by-id.controller.ts +3 -3
  967. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-delete-applications-clients.controller.ts +3 -3
  968. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-find-application-client-by-id.controller.ts +3 -3
  969. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-find-application-client.controller.ts +3 -3
  970. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-get-applications-clients.controller.ts +3 -3
  971. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-paginate-applications-clients.controller.ts +2 -2
  972. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/controllers/o-auth-update-application-client-by-id.controller.ts +3 -3
  973. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/dto/index.ts +4 -4
  974. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/dto/o-auth-application-client.dto.ts +5 -4
  975. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/index.ts +22 -22
  976. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-create-application-client.resolver.ts +3 -3
  977. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-create-applications-clients.resolver.ts +3 -3
  978. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-delete-application-client-by-id.resolver.ts +3 -3
  979. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-delete-applications-clients.resolver.ts +3 -3
  980. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-find-application-client-by-id.resolver.ts +3 -3
  981. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-find-application-client.resolver.ts +3 -3
  982. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-get-applications-clients.resolver.ts +3 -3
  983. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-paginate-applications-clients.resolver.ts +3 -3
  984. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/application-client/resolvers/o-auth-update-application-client-by-id.resolver.ts +3 -3
  985. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-create-authorization-code.controller.ts +3 -3
  986. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-delete-authorization-code-by-id.controller.ts +3 -3
  987. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-delete-authorization-codes.controller.ts +3 -3
  988. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-find-authorization-code-by-id.controller.ts +3 -3
  989. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-find-authorization-code.controller.ts +3 -3
  990. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-get-authorization-codes.controller.ts +3 -3
  991. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-paginate-authorization-codes.controller.ts +2 -2
  992. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/controllers/o-auth-update-authorization-code-by-id.controller.ts +3 -3
  993. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/dto/index.ts +4 -4
  994. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/dto/o-auth-authorization-code.dto.ts +3 -2
  995. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/graphql/o-auth-authorization-code.graphql +2 -8
  996. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/index.ts +20 -20
  997. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-create-authorization-code.resolver.ts +3 -3
  998. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-delete-authorization-code-by-id.resolver.ts +3 -3
  999. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-delete-authorization-codes.resolver.ts +3 -3
  1000. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-find-authorization-code-by-id.resolver.ts +3 -3
  1001. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-find-authorization-code.resolver.ts +3 -3
  1002. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-get-authorization-codes.resolver.ts +3 -3
  1003. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-paginate-authorization-codes.resolver.ts +3 -3
  1004. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/authorization-code/resolvers/o-auth-update-authorization-code-by-id.resolver.ts +3 -3
  1005. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-create-client.controller.ts +3 -3
  1006. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-delete-client-by-id.controller.ts +3 -3
  1007. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-find-client-by-id.controller.ts +3 -3
  1008. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-find-client.controller.ts +3 -3
  1009. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-get-clients.controller.ts +3 -3
  1010. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-paginate-clients.controller.ts +2 -2
  1011. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/controllers/o-auth-update-client-by-id.controller.ts +3 -3
  1012. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/dto/index.ts +4 -4
  1013. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/dto/o-auth-client.dto.ts +6 -5
  1014. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/dto/o-auth-create-client.dto.ts +1 -1
  1015. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/dto/o-auth-update-client-by-id.dto.ts +1 -1
  1016. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/dto/o-auth-update-clients.dto.ts +1 -1
  1017. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/graphql/o-auth-client.graphql +3 -12
  1018. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/index.ts +18 -18
  1019. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-create-client.resolver.ts +3 -3
  1020. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-delete-client-by-id.resolver.ts +3 -3
  1021. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-find-client-by-id.resolver.ts +3 -3
  1022. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-find-client.resolver.ts +3 -3
  1023. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-get-clients.resolver.ts +3 -3
  1024. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-paginate-clients.resolver.ts +3 -3
  1025. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/client/resolvers/o-auth-update-client-by-id.resolver.ts +3 -3
  1026. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/controllers/o-auth-find-credential-by-id.controller.ts +3 -3
  1027. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/controllers/o-auth-find-credential.controller.ts +3 -3
  1028. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/controllers/o-auth-get-credentials.controller.ts +3 -3
  1029. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/controllers/o-auth-paginate-credentials.controller.ts +2 -2
  1030. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/dto/index.ts +1 -1
  1031. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/dto/o-auth-credential.dto.ts +9 -8
  1032. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/index.ts +9 -9
  1033. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/resolvers/o-auth-find-credential-by-id.resolver.ts +3 -3
  1034. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/resolvers/o-auth-find-credential.resolver.ts +3 -3
  1035. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/resolvers/o-auth-get-credentials.resolver.ts +3 -3
  1036. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/credential/resolvers/o-auth-paginate-credentials.resolver.ts +3 -3
  1037. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-authorize.controller.spec.ts +13 -12
  1038. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-authorize.controller.ts +2 -2
  1039. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-create-impersonate-token.controller.ts +7 -6
  1040. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-create-token.controller.spec.ts +5 -4
  1041. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-create-token.controller.ts +3 -3
  1042. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-get-jwks.controller.spec.ts +5 -4
  1043. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-get-jwks.controller.ts +1 -1
  1044. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-logout.controller.spec.ts +22 -27
  1045. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-logout.controller.ts +5 -6
  1046. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-revoke-token.controller.spec.ts +5 -4
  1047. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-revoke-token.controller.ts +2 -2
  1048. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-session.controller.spec.ts +13 -12
  1049. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/controllers/o-auth-session.controller.ts +1 -1
  1050. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/index.ts +10 -10
  1051. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/resolvers/o-auth-create-impersonate-token.resolver.ts +8 -7
  1052. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/resolvers/o-auth-create-token.resolver.spec.ts +10 -8
  1053. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/resolvers/o-auth-create-token.resolver.ts +8 -7
  1054. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/resolvers/o-auth-revoke-token.resolver.spec.ts +10 -10
  1055. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/flows/resolvers/o-auth-revoke-token.resolver.ts +7 -6
  1056. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/o-auth-bootstrap.seeder.spec.ts +18 -17
  1057. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/o-auth-bootstrap.seeder.ts +5 -5
  1058. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/o-auth.module.ts +18 -18
  1059. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/o-auth.seeder.ts +6 -6
  1060. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/controllers/o-auth-delete-refresh-token-by-id.controller.ts +3 -3
  1061. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/controllers/o-auth-find-refresh-token-by-id.controller.ts +3 -3
  1062. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/controllers/o-auth-find-refresh-token.controller.ts +3 -3
  1063. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/controllers/o-auth-get-refresh-tokens.controller.ts +3 -3
  1064. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/controllers/o-auth-paginate-refresh-tokens.controller.ts +2 -2
  1065. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/dto/index.ts +4 -4
  1066. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/dto/o-auth-refresh-token.dto.ts +3 -2
  1067. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/index.ts +14 -14
  1068. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/resolvers/o-auth-delete-refresh-token-by-id.resolver.ts +3 -3
  1069. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/resolvers/o-auth-find-refresh-token-by-id.resolver.ts +3 -3
  1070. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/resolvers/o-auth-find-refresh-token.resolver.ts +3 -3
  1071. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/resolvers/o-auth-get-refresh-tokens.resolver.ts +3 -3
  1072. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/refresh-token/resolvers/o-auth-paginate-refresh-tokens.resolver.ts +3 -3
  1073. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-create-scope.controller.ts +3 -3
  1074. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-delete-scope-by-id.controller.ts +3 -3
  1075. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-find-scope-by-id.controller.ts +3 -3
  1076. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-find-scope.controller.ts +3 -3
  1077. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-get-scopes.controller.ts +3 -3
  1078. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-paginate-scopes.controller.ts +2 -2
  1079. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/controllers/o-auth-update-scope-by-id.controller.ts +3 -3
  1080. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/dto/index.ts +4 -4
  1081. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/graphql/o-auth-scope.graphql +3 -12
  1082. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/index.ts +18 -18
  1083. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-create-scope.resolver.ts +3 -3
  1084. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-delete-scope-by-id.resolver.ts +3 -3
  1085. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-find-scope-by-id.resolver.ts +3 -3
  1086. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-find-scope.resolver.ts +3 -3
  1087. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-get-scopes.resolver.ts +3 -3
  1088. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-paginate-scopes.resolver.ts +3 -3
  1089. package/dist/templates/backend/packages/o-auth/src/@api/o-auth/scope/resolvers/o-auth-update-scope-by-id.resolver.ts +3 -3
  1090. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/count/o-auth-count-access-token.handler.ts +1 -1
  1091. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/count/o-auth-count-access-token.service.ts +1 -1
  1092. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/create/o-auth-create-access-token.handler.ts +5 -7
  1093. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/create/o-auth-create-access-token.service.ts +2 -2
  1094. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/delete/o-auth-delete-access-token-by-id.handler.ts +4 -4
  1095. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/delete/o-auth-delete-access-token-by-id.service.ts +1 -1
  1096. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/find/o-auth-find-access-token-by-id.handler.ts +3 -3
  1097. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/find/o-auth-find-access-token-by-id.service.ts +2 -2
  1098. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/find/o-auth-find-access-token.handler.ts +3 -3
  1099. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/find/o-auth-find-access-token.service.ts +2 -2
  1100. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/get/o-auth-get-access-tokens.handler.ts +3 -3
  1101. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/get/o-auth-get-access-tokens.service.ts +2 -2
  1102. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/paginate/o-auth-paginate-access-tokens.handler.ts +3 -3
  1103. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/application/paginate/o-auth-paginate-access-tokens.service.ts +2 -2
  1104. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/domain/index.ts +1 -1
  1105. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/domain/o-auth-access-token.field-schema.ts +2 -2
  1106. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/index.ts +36 -36
  1107. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/access-token/infrastructure/drizzle/o-auth-drizzle-access-token.repository.ts +2 -2
  1108. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/create/o-auth-create-application.handler.ts +5 -7
  1109. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/create/o-auth-create-application.service.ts +2 -2
  1110. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/delete/o-auth-delete-application-by-id.handler.ts +4 -6
  1111. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/delete/o-auth-delete-application-by-id.service.ts +1 -1
  1112. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/find/o-auth-find-application-by-id.handler.ts +3 -3
  1113. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/find/o-auth-find-application-by-id.service.ts +5 -3
  1114. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/find/o-auth-find-application.handler.ts +3 -3
  1115. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/find/o-auth-find-application.service.ts +5 -3
  1116. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/get/o-auth-get-applications.handler.ts +3 -3
  1117. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/get/o-auth-get-applications.service.ts +5 -3
  1118. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/paginate/o-auth-paginate-applications.handler.ts +3 -3
  1119. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/paginate/o-auth-paginate-applications.service.ts +5 -3
  1120. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/update/o-auth-update-application-by-id.handler.spec.ts +9 -9
  1121. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/update/o-auth-update-application-by-id.handler.ts +5 -8
  1122. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/application/update/o-auth-update-application-by-id.service.ts +2 -2
  1123. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/domain/index.ts +1 -1
  1124. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/domain/o-auth-application.field-schema.spec.ts +1 -9
  1125. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/domain/o-auth-application.field-schema.ts +1 -1
  1126. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/index.ts +36 -36
  1127. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/infrastructure/drizzle/o-auth-drizzle-application.repository.ts +3 -3
  1128. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application/infrastructure/drizzle/o-auth-drizzle-application.schema.ts +4 -1
  1129. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/create/o-auth-create-application-client.handler.ts +5 -7
  1130. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/create/o-auth-create-application-client.service.ts +2 -2
  1131. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/create/o-auth-create-applications-clients.handler.ts +4 -4
  1132. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/create/o-auth-create-applications-clients.service.ts +2 -2
  1133. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/delete/o-auth-delete-application-client-by-id.handler.ts +4 -6
  1134. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/delete/o-auth-delete-application-client-by-id.service.ts +1 -1
  1135. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/delete/o-auth-delete-applications-clients.handler.ts +4 -6
  1136. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/delete/o-auth-delete-applications-clients.service.ts +1 -1
  1137. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/find/o-auth-find-application-client-by-id.handler.ts +3 -3
  1138. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/find/o-auth-find-application-client-by-id.service.ts +5 -3
  1139. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/find/o-auth-find-application-client.handler.ts +3 -3
  1140. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/find/o-auth-find-application-client.service.ts +5 -3
  1141. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/get/o-auth-get-applications-clients.handler.ts +3 -3
  1142. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/get/o-auth-get-applications-clients.service.ts +5 -3
  1143. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/paginate/o-auth-paginate-applications-clients.handler.ts +3 -3
  1144. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/paginate/o-auth-paginate-applications-clients.service.ts +5 -3
  1145. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/update/o-auth-update-application-client-by-id.handler.ts +5 -8
  1146. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/application/update/o-auth-update-application-client-by-id.service.ts +2 -2
  1147. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/domain/index.ts +1 -1
  1148. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/domain/o-auth-application-client.field-schema.ts +2 -2
  1149. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/index.ts +44 -44
  1150. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/application-client/infrastructure/drizzle/o-auth-drizzle-application-client.repository.ts +2 -2
  1151. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/create/o-auth-create-authorization-code.handler.ts +5 -7
  1152. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/create/o-auth-create-authorization-code.service.ts +2 -2
  1153. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/delete/o-auth-delete-authorization-code-by-id.handler.ts +4 -6
  1154. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/delete/o-auth-delete-authorization-code-by-id.service.ts +1 -1
  1155. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/delete/o-auth-delete-authorization-codes.handler.ts +4 -6
  1156. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/delete/o-auth-delete-authorization-codes.service.ts +1 -1
  1157. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/find/o-auth-find-authorization-code-by-id.handler.ts +3 -3
  1158. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/find/o-auth-find-authorization-code-by-id.service.ts +5 -3
  1159. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/find/o-auth-find-authorization-code.handler.ts +3 -3
  1160. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/find/o-auth-find-authorization-code.service.ts +5 -3
  1161. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/get/o-auth-get-authorization-codes.handler.ts +3 -3
  1162. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/get/o-auth-get-authorization-codes.service.ts +5 -3
  1163. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/paginate/o-auth-paginate-authorization-codes.handler.ts +3 -3
  1164. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/paginate/o-auth-paginate-authorization-codes.service.ts +5 -3
  1165. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/update/o-auth-update-authorization-code-by-id.handler.ts +5 -8
  1166. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/application/update/o-auth-update-authorization-code-by-id.service.ts +2 -2
  1167. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/domain/index.ts +1 -1
  1168. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/domain/o-auth-authorization-code.field-schema.ts +1 -1
  1169. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/index.ts +40 -40
  1170. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/authorization-code/infrastructure/drizzle/o-auth-drizzle-authorization-code.repository.ts +2 -2
  1171. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/create/o-auth-create-client.handler.ts +5 -4
  1172. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/create/o-auth-create-client.service.ts +2 -2
  1173. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/delete/o-auth-delete-client-by-id.handler.ts +4 -3
  1174. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/delete/o-auth-delete-client-by-id.service.ts +1 -1
  1175. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/find/o-auth-find-client-by-id.handler.ts +3 -3
  1176. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/find/o-auth-find-client-by-id.service.ts +5 -3
  1177. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/find/o-auth-find-client.handler.ts +3 -3
  1178. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/find/o-auth-find-client.service.ts +5 -3
  1179. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/get/o-auth-get-clients.handler.ts +3 -3
  1180. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/get/o-auth-get-clients.service.ts +5 -3
  1181. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/paginate/o-auth-paginate-clients.handler.ts +3 -3
  1182. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/paginate/o-auth-paginate-clients.service.ts +5 -3
  1183. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/update/o-auth-update-client-by-id.handler.ts +5 -5
  1184. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/application/update/o-auth-update-client-by-id.service.ts +2 -2
  1185. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/domain/index.ts +1 -1
  1186. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/domain/o-auth-client.field-schema.ts +2 -2
  1187. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/index.ts +36 -36
  1188. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/client/infrastructure/drizzle/o-auth-drizzle-client.repository.ts +3 -3
  1189. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/create/o-auth-create-credential.service.spec.ts +13 -11
  1190. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/create/o-auth-create-credential.service.ts +2 -2
  1191. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/find/o-auth-find-credential-by-id.handler.ts +3 -3
  1192. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/find/o-auth-find-credential-by-id.service.ts +2 -2
  1193. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/find/o-auth-find-credential.handler.ts +3 -3
  1194. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/find/o-auth-find-credential.service.ts +2 -2
  1195. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/get/o-auth-get-credentials.handler.ts +3 -3
  1196. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/get/o-auth-get-credentials.service.ts +2 -2
  1197. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/paginate/o-auth-paginate-credentials.handler.ts +3 -3
  1198. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/application/paginate/o-auth-paginate-credentials.service.ts +2 -2
  1199. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/domain/index.ts +1 -1
  1200. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/domain/o-auth-credential.field-schema.ts +3 -3
  1201. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/index.ts +26 -26
  1202. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/credential/infrastructure/drizzle/o-auth-drizzle-credential.repository.ts +2 -2
  1203. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/authorize/o-auth-authorize.handler.spec.ts +17 -16
  1204. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/authorize/o-auth-authorize.handler.ts +6 -6
  1205. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/o-auth-create-token.handler.spec.ts +12 -11
  1206. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/o-auth-create-token.handler.ts +5 -5
  1207. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/services/o-auth-create-token-authorization-code.service.spec.ts +51 -31
  1208. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/services/o-auth-create-token-authorization-code.service.ts +18 -16
  1209. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/services/o-auth-create-token-password.service.spec.ts +45 -29
  1210. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/services/o-auth-create-token-password.service.ts +16 -14
  1211. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/services/o-auth-create-token-refresh.service.spec.ts +49 -33
  1212. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/create-token/services/o-auth-create-token-refresh.service.ts +19 -17
  1213. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/get-jwks/o-auth-get-jwks.handler.spec.ts +3 -3
  1214. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/get-jwks/o-auth-get-jwks.handler.ts +4 -3
  1215. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/impersonate-token/o-auth-create-impersonate-token.handler.spec.ts +12 -11
  1216. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/impersonate-token/o-auth-create-impersonate-token.handler.ts +6 -6
  1217. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/impersonate-token/services/o-auth-create-impersonate-token.service.spec.ts +35 -21
  1218. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/impersonate-token/services/o-auth-create-impersonate-token.service.ts +16 -13
  1219. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/revoke-token/o-auth-revoke-token.handler.spec.ts +7 -6
  1220. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/revoke-token/o-auth-revoke-token.handler.ts +2 -2
  1221. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/revoke-token/services/o-auth-revoke-token.service.spec.ts +23 -21
  1222. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/revoke-token/services/o-auth-revoke-token.service.ts +9 -8
  1223. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/session/o-auth-hub-session.service.spec.ts +21 -19
  1224. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/application/session/o-auth-hub-session.service.ts +4 -3
  1225. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/domain/errors/impersonation.errors.spec.ts +1 -1
  1226. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/domain/errors/index.ts +12 -12
  1227. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/domain/impersonation-privilege-denylist.spec.ts +16 -16
  1228. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/domain/impersonation-privilege-denylist.ts +1 -1
  1229. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/domain/index.ts +2 -2
  1230. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/index.ts +13 -13
  1231. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/shared/pkce/o-auth-verify-pkce-s256.spec.ts +3 -3
  1232. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/flows/shared/pkce/o-auth-verify-pkce-s256.ts +2 -2
  1233. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/index.ts +8 -8
  1234. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/o-auth.relations.ts +8 -8
  1235. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/o-auth.seed.ts +2 -2
  1236. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/create/o-auth-create-refresh-token.handler.ts +5 -7
  1237. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/create/o-auth-create-refresh-token.service.ts +2 -2
  1238. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/delete/o-auth-delete-refresh-token-by-id.handler.ts +4 -4
  1239. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/delete/o-auth-delete-refresh-token-by-id.service.ts +1 -1
  1240. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/find/o-auth-find-refresh-token-by-id.handler.ts +3 -3
  1241. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/find/o-auth-find-refresh-token-by-id.service.ts +2 -2
  1242. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/find/o-auth-find-refresh-token.handler.ts +3 -3
  1243. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/find/o-auth-find-refresh-token.service.ts +2 -2
  1244. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/get/o-auth-get-refresh-tokens.handler.ts +3 -3
  1245. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/get/o-auth-get-refresh-tokens.service.ts +2 -2
  1246. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/paginate/o-auth-paginate-refresh-tokens.handler.ts +3 -3
  1247. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/application/paginate/o-auth-paginate-refresh-tokens.service.ts +2 -2
  1248. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/domain/index.ts +1 -1
  1249. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/domain/o-auth-refresh-token.field-schema.ts +1 -1
  1250. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/index.ts +30 -30
  1251. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/refresh-token/infrastructure/drizzle/o-auth-drizzle-refresh-token.repository.ts +2 -2
  1252. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/create/o-auth-create-scope.handler.ts +5 -4
  1253. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/create/o-auth-create-scope.service.ts +2 -2
  1254. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/delete/o-auth-delete-scope-by-id.handler.ts +4 -3
  1255. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/delete/o-auth-delete-scope-by-id.service.ts +1 -1
  1256. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/find/o-auth-find-scope-by-id.handler.ts +3 -3
  1257. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/find/o-auth-find-scope-by-id.service.ts +5 -3
  1258. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/find/o-auth-find-scope.handler.ts +3 -3
  1259. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/find/o-auth-find-scope.service.ts +5 -3
  1260. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/get/o-auth-get-scopes.handler.ts +3 -3
  1261. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/get/o-auth-get-scopes.service.ts +5 -3
  1262. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/paginate/o-auth-paginate-scopes.handler.ts +3 -3
  1263. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/paginate/o-auth-paginate-scopes.service.ts +5 -3
  1264. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/update/o-auth-update-scope-by-id.handler.ts +5 -5
  1265. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/application/update/o-auth-update-scope-by-id.service.ts +2 -2
  1266. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/domain/index.ts +1 -1
  1267. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/index.ts +36 -36
  1268. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/infrastructure/drizzle/o-auth-drizzle-scope.repository.ts +2 -2
  1269. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/scope/infrastructure/drizzle/o-auth-drizzle-scope.schema.ts +4 -1
  1270. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/functions/o-auth-authenticate-application.function.spec.ts +14 -13
  1271. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/functions/o-auth-authenticate-application.function.ts +2 -2
  1272. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/functions/o-auth-generate-application-secret.function.spec.ts +1 -1
  1273. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/functions/o-auth-generate-application-secret.function.ts +3 -2
  1274. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/functions/o-auth-resolve-application-client.function.spec.ts +25 -24
  1275. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/functions/o-auth-resolve-application-client.function.ts +3 -3
  1276. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/index.ts +6 -6
  1277. package/dist/templates/backend/packages/o-auth/src/@app/o-auth/shared/services/token-retention.service.spec.ts +7 -6
  1278. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/application/adapters/index.ts +1 -1
  1279. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/application/adapters/o-auth-application-provisioner.adapter.spec.ts +60 -60
  1280. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/application/adapters/o-auth-application-provisioner.adapter.ts +12 -12
  1281. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/application/index.ts +1 -1
  1282. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/application/ports/index.ts +2 -2
  1283. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/client/adapters/index.ts +1 -1
  1284. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/client/adapters/o-auth-client-reader.adapter.spec.ts +5 -4
  1285. package/dist/templates/backend/packages/o-auth/src/@bridges/o-auth/client/adapters/o-auth-client-reader.adapter.ts +2 -2
  1286. package/dist/templates/backend/packages/o-auth/src/@bridges/providers/iam-client-reader.bridge.ts +2 -2
  1287. package/dist/templates/backend/packages/o-auth/test/acceptance/o-auth/impersonate-token-guarded-transports.e2e-spec.ts +11 -32
  1288. package/dist/templates/backend/packages/o-auth/test/acceptance/o-auth/masked-property-query-guard.e2e-spec.ts +13 -27
  1289. package/dist/templates/backend/packages/o-auth/test/acceptance/o-auth/oauth-bootstrap-seeder-idempotency.e2e-spec.ts +7 -24
  1290. package/dist/templates/backend/packages/o-auth/test/acceptance/o-auth/token-masking.e2e-spec.ts +7 -22
  1291. package/dist/templates/backend/packages/queue-manager/src/@api/queue-manager/flows/index.ts +1 -1
  1292. package/dist/templates/backend/packages/queue-manager/src/@api/queue-manager/flows/resolvers/queue-manager.resolver.auth-metadata.spec.ts +1 -22
  1293. package/dist/templates/backend/packages/queue-manager/src/@api/queue-manager/flows/resolvers/queue-manager.resolver.spec.ts +29 -39
  1294. package/dist/templates/backend/packages/queue-manager/src/@api/queue-manager/flows/resolvers/queue-manager.resolver.ts +3 -3
  1295. package/dist/templates/backend/packages/queue-manager/src/@api/queue-manager/queue-manager.module.ts +6 -6
  1296. package/dist/templates/backend/packages/queue-manager/src/@api/queue-manager/queue-manager.seeder.ts +3 -3
  1297. package/dist/templates/backend/packages/queue-manager/src/@app/queue-manager/domain/ports/index.ts +3 -3
  1298. package/dist/templates/backend/packages/queue-manager/src/@app/queue-manager/infrastructure/adapters/bull-board-queue-inspector.adapter.spec.ts +113 -24
  1299. package/dist/templates/backend/packages/queue-manager/src/@app/queue-manager/infrastructure/adapters/bull-board-queue-inspector.adapter.ts +40 -4
  1300. package/dist/templates/backend/packages/queue-manager/src/@app/queue-manager/infrastructure/adapters/index.ts +1 -1
  1301. package/dist/templates/backend/packages/queue-manager/src/@app/queue-manager/infrastructure/index.ts +1 -1
  1302. package/dist/templates/backend/packages/queue-manager/src/@app/queue-manager/queue-registry.providers.ts +2 -2
  1303. package/dist/templates/codegen/backend/@api/__bounded_context_name__.module.ts.eta +2 -2
  1304. package/dist/templates/codegen/backend/@api/__bounded_context_name__.seeder.ts.eta +3 -3
  1305. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-count-__module_name__.controller.ts.eta +9 -9
  1306. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-create-__module_name__.controller.ts.eta +10 -10
  1307. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-create-__module_names__.controller.ts.eta +10 -10
  1308. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-delete-__module_name__-by-id.controller.ts.eta +12 -10
  1309. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-delete-__module_names__.controller.ts.eta +12 -10
  1310. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-find-__module_name__-by-id.controller.ts.eta +10 -10
  1311. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-find-__module_name__.controller.ts.eta +10 -10
  1312. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-get-__module_names__.controller.ts.eta +10 -10
  1313. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-get-raw-__module_names__.controller.ts.eta +3 -19
  1314. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-max-__module_name__.controller.ts.eta +9 -9
  1315. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-min-__module_name__.controller.ts.eta +9 -9
  1316. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-paginate-__module_names__.controller.ts.eta +9 -9
  1317. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-sum-__module_name__.controller.ts.eta +9 -9
  1318. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-update-__module_name__-by-id.controller.ts.eta +15 -10
  1319. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-update-__module_names__.controller.ts.eta +17 -10
  1320. package/dist/templates/codegen/backend/@api/__module_name__/controllers/__bounded_context_name__-upsert-__module_name__.controller.ts.eta +10 -10
  1321. package/dist/templates/codegen/backend/@api/__module_name__/dto/__bounded_context_name__-__module_name__.dto.ts.eta +27 -12
  1322. package/dist/templates/codegen/backend/@api/__module_name__/dto/__bounded_context_name__-create-__module_name__.dto.ts.eta +7 -4
  1323. package/dist/templates/codegen/backend/@api/__module_name__/dto/__bounded_context_name__-update-__module_name__-by-id.dto.ts.eta +8 -5
  1324. package/dist/templates/codegen/backend/@api/__module_name__/dto/__bounded_context_name__-update-__module_names__.dto.ts.eta +8 -5
  1325. package/dist/templates/codegen/backend/@api/__module_name__/dto/index.ts.eta +4 -4
  1326. package/dist/templates/codegen/backend/@api/__module_name__/graphql/__bounded_context_name__-__module_name__.graphql.eta +52 -20
  1327. package/dist/templates/codegen/backend/@api/__module_name__/index.ts.eta +38 -38
  1328. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-__module_name__-custom-field-value.resolver.ts.eta +1 -1
  1329. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-count-__module_name__.resolver.ts.eta +9 -9
  1330. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-create-__module_name__.resolver.ts.eta +10 -10
  1331. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-create-__module_names__.resolver.ts.eta +10 -10
  1332. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-delete-__module_name__-by-id.resolver.ts.eta +13 -10
  1333. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-delete-__module_names__.resolver.ts.eta +13 -10
  1334. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-find-__module_name__-by-id.resolver.ts.eta +10 -10
  1335. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-find-__module_name__.resolver.ts.eta +10 -10
  1336. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-get-__module_names__.resolver.ts.eta +10 -10
  1337. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-get-raw-__module_names__.resolver.ts.eta +3 -19
  1338. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-max-__module_name__.resolver.ts.eta +9 -9
  1339. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-min-__module_name__.resolver.ts.eta +9 -9
  1340. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-paginate-__module_names__.resolver.ts.eta +10 -10
  1341. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-sum-__module_name__.resolver.ts.eta +9 -9
  1342. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-update-__module_name__-by-id.resolver.ts.eta +17 -10
  1343. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-update-__module_names__.resolver.ts.eta +20 -10
  1344. package/dist/templates/codegen/backend/@api/__module_name__/resolvers/__bounded_context_name__-upsert-__module_name__.resolver.ts.eta +10 -10
  1345. package/dist/templates/codegen/backend/@app/__module_name__/application/__bounded_context_name__-__module_name__.payload-types.ts.eta +1 -1
  1346. package/dist/templates/codegen/backend/@app/__module_name__/application/count/__bounded_context_name__-count-__module_name__.handler.ts.eta +4 -4
  1347. package/dist/templates/codegen/backend/@app/__module_name__/application/count/__bounded_context_name__-count-__module_name__.service.ts.eta +1 -1
  1348. package/dist/templates/codegen/backend/@app/__module_name__/application/create/__bounded_context_name__-create-__module_name__.handler.ts.eta +7 -7
  1349. package/dist/templates/codegen/backend/@app/__module_name__/application/create/__bounded_context_name__-create-__module_name__.service.ts.eta +4 -4
  1350. package/dist/templates/codegen/backend/@app/__module_name__/application/create/__bounded_context_name__-create-__module_names__.handler.ts.eta +6 -6
  1351. package/dist/templates/codegen/backend/@app/__module_name__/application/create/__bounded_context_name__-create-__module_names__.service.ts.eta +5 -5
  1352. package/dist/templates/codegen/backend/@app/__module_name__/application/delete/__bounded_context_name__-delete-__module_name__-by-id.handler.ts.eta +6 -6
  1353. package/dist/templates/codegen/backend/@app/__module_name__/application/delete/__bounded_context_name__-delete-__module_name__-by-id.service.ts.eta +3 -3
  1354. package/dist/templates/codegen/backend/@app/__module_name__/application/delete/__bounded_context_name__-delete-__module_names__.handler.ts.eta +6 -6
  1355. package/dist/templates/codegen/backend/@app/__module_name__/application/delete/__bounded_context_name__-delete-__module_names__.service.ts.eta +2 -2
  1356. package/dist/templates/codegen/backend/@app/__module_name__/application/find/__bounded_context_name__-find-__module_name__-by-id.handler.ts.eta +5 -5
  1357. package/dist/templates/codegen/backend/@app/__module_name__/application/find/__bounded_context_name__-find-__module_name__-by-id.service.ts.eta +2 -2
  1358. package/dist/templates/codegen/backend/@app/__module_name__/application/find/__bounded_context_name__-find-__module_name__.handler.ts.eta +5 -5
  1359. package/dist/templates/codegen/backend/@app/__module_name__/application/find/__bounded_context_name__-find-__module_name__.service.ts.eta +2 -2
  1360. package/dist/templates/codegen/backend/@app/__module_name__/application/get/__bounded_context_name__-get-__module_names__.handler.ts.eta +5 -5
  1361. package/dist/templates/codegen/backend/@app/__module_name__/application/get/__bounded_context_name__-get-__module_names__.service.ts.eta +2 -2
  1362. package/dist/templates/codegen/backend/@app/__module_name__/application/get/__bounded_context_name__-get-raw-__module_names__.handler.ts.eta +3 -9
  1363. package/dist/templates/codegen/backend/@app/__module_name__/application/get/__bounded_context_name__-get-raw-__module_names__.service.ts.eta +2 -2
  1364. package/dist/templates/codegen/backend/@app/__module_name__/application/max/__bounded_context_name__-max-__module_name__.handler.ts.eta +3 -3
  1365. package/dist/templates/codegen/backend/@app/__module_name__/application/max/__bounded_context_name__-max-__module_name__.service.ts.eta +1 -1
  1366. package/dist/templates/codegen/backend/@app/__module_name__/application/min/__bounded_context_name__-min-__module_name__.handler.ts.eta +3 -3
  1367. package/dist/templates/codegen/backend/@app/__module_name__/application/min/__bounded_context_name__-min-__module_name__.service.ts.eta +1 -1
  1368. package/dist/templates/codegen/backend/@app/__module_name__/application/paginate/__bounded_context_name__-paginate-__module_names__.handler.ts.eta +5 -5
  1369. package/dist/templates/codegen/backend/@app/__module_name__/application/paginate/__bounded_context_name__-paginate-__module_names__.service.ts.eta +4 -3
  1370. package/dist/templates/codegen/backend/@app/__module_name__/application/sum/__bounded_context_name__-sum-__module_name__.handler.ts.eta +3 -3
  1371. package/dist/templates/codegen/backend/@app/__module_name__/application/sum/__bounded_context_name__-sum-__module_name__.service.ts.eta +1 -1
  1372. package/dist/templates/codegen/backend/@app/__module_name__/application/update/__bounded_context_name__-update-__module_name__-by-id.handler.ts.eta +7 -7
  1373. package/dist/templates/codegen/backend/@app/__module_name__/application/update/__bounded_context_name__-update-__module_name__-by-id.service.ts.eta +4 -4
  1374. package/dist/templates/codegen/backend/@app/__module_name__/application/update/__bounded_context_name__-update-__module_names__.handler.ts.eta +7 -7
  1375. package/dist/templates/codegen/backend/@app/__module_name__/application/update/__bounded_context_name__-update-__module_names__.service.ts.eta +3 -3
  1376. package/dist/templates/codegen/backend/@app/__module_name__/application/update/__bounded_context_name__-update-and-increment-__module_names__.service.ts.eta +3 -3
  1377. package/dist/templates/codegen/backend/@app/__module_name__/application/upsert/__bounded_context_name__-upsert-__module_name__.handler.ts.eta +7 -7
  1378. package/dist/templates/codegen/backend/@app/__module_name__/application/upsert/__bounded_context_name__-upsert-__module_name__.service.ts.eta +3 -3
  1379. package/dist/templates/codegen/backend/@app/__module_name__/domain/__bounded_context_name__-__module_name__.field-schema.ts.eta +5 -2
  1380. package/dist/templates/codegen/backend/@app/__module_name__/domain/index.ts.eta +1 -1
  1381. package/dist/templates/codegen/backend/@app/__module_name__/index.ts.eta +37 -37
  1382. package/dist/templates/codegen/backend/@app/__module_name__/infrastructure/drizzle/__bounded_context_name__-drizzle-__module_name__-custom-field-value.schema.ts.eta +1 -1
  1383. package/dist/templates/codegen/backend/@app/__module_name__/infrastructure/drizzle/__bounded_context_name__-drizzle-__module_name__-i18n.repository.ts.eta +1 -1
  1384. package/dist/templates/codegen/backend/@app/__module_name__/infrastructure/drizzle/__bounded_context_name__-drizzle-__module_name__.repository.ts.eta +3 -3
  1385. package/dist/templates/codegen/backend/@app/__module_name__/infrastructure/drizzle/__bounded_context_name__-drizzle-__module_name__.schema.ts.eta +1 -1
  1386. package/dist/templates/codegen/backend/additional-@api/__module_name__/controllers/__additional_api_name__.controller.ts.eta +22 -13
  1387. package/dist/templates/codegen/backend/additional-@api/__module_name__/resolvers/__additional_api_name__.resolver.ts.eta +25 -13
  1388. package/dist/templates/codegen/backend/additional-@app/__module_name__/application/__additional_api_action__/__additional_api_name__.handler.ts.eta +24 -6
  1389. package/dist/templates/codegen/frontend/module/__module_name__/__module_name__.columns.ts.eta +5 -3
  1390. package/dist/templates/codegen/frontend/module/__module_name__/data-access/__module_name__.resolvers.ts.eta +13 -10
  1391. package/dist/templates/codegen/frontend/module/__module_name__/features/__module_name__-detail.component.ts.eta +14 -5
  1392. package/dist/templates/codegen/frontend/module/__module_name__/features/__module_name__-form-embed.component.ts.eta +185 -60
  1393. package/dist/templates/codegen/frontend/module/__module_name__/features/__module_name__-form.component.ts.eta +160 -69
  1394. package/dist/templates/codegen/frontend/module/__module_name__/features/__module_name__-list.component.ts.eta +11 -8
  1395. package/dist/templates/codegen/partials/fields/enum-field.eta +8 -6
  1396. package/dist/templates/codegen/partials/form/field-label.eta +8 -5
  1397. package/dist/templates/codegen/partials/form/form-body.eta +8 -31
  1398. package/dist/templates/codegen/partials/form/view-frame-tabbed.eta +18 -2
  1399. package/dist/templates/codegen/partials/form/view-frame.eta +22 -2
  1400. package/dist/templates/codegen/partials/i18n-recompute.eta +16 -12
  1401. package/dist/templates/codegen/partials/relationships/multiple-select.eta +12 -1
  1402. package/dist/templates/codegen/partials/relationships/select.eta +11 -1
  1403. package/dist/templates/frontend/application/public/i18n/en.json +2 -1
  1404. package/dist/templates/frontend/application/public/i18n/es.json +2 -1
  1405. package/dist/templates/frontend/application/src/@aurora/components/data-table/index.ts +1 -0
  1406. package/dist/templates/frontend/application/src/@aurora/components/data-table/lib/relation-cell.spec.ts +33 -0
  1407. package/dist/templates/frontend/application/src/@aurora/components/data-table/lib/relation-cell.ts +13 -0
  1408. package/dist/templates/frontend/application/src/@aurora/components/date-picker/date-picker.component.ts +4 -0
  1409. package/dist/templates/frontend/application/src/@aurora/components/datetime-picker/datetime-picker.component.spec.ts +22 -0
  1410. package/dist/templates/frontend/application/src/@aurora/components/datetime-picker/datetime-picker.component.ts +24 -9
  1411. package/dist/templates/frontend/application/src/@aurora/components/datetime-picker/datetime-picker.stories.ts +22 -0
  1412. package/dist/templates/frontend/application/src/@aurora/lib/calendar-i18n.spec.ts +138 -0
  1413. package/dist/templates/frontend/application/src/@aurora/lib/calendar-i18n.ts +93 -0
  1414. package/dist/templates/frontend/application/src/@aurora/lib/expand-display-field-template.ts +30 -0
  1415. package/dist/templates/frontend/application/src/@aurora/lib/format-iso-date.ts +5 -4
  1416. package/dist/templates/frontend/application/src/@aurora/lib/index.ts +2 -1
  1417. package/dist/templates/frontend/application/src/@aurora/lib/item-label-of.spec.ts +45 -0
  1418. package/dist/templates/frontend/application/src/@aurora/lib/item-label-of.ts +17 -7
  1419. package/dist/templates/frontend/application/src/@aurora/pipes/to-options.pipe.ts +2 -5
  1420. package/dist/templates/frontend/application/src/app/app.config.ts +2 -0
  1421. package/dist/templates/frontend/application/src/environments/environment.dev.ts +3 -0
  1422. package/dist/templates/frontend/application/src/environments/environment.local.ts +3 -0
  1423. package/dist/templates/frontend/application/src/environments/environment.prod.ts +3 -0
  1424. package/dist/templates/frontend/application/src/environments/environment.qa.ts +3 -0
  1425. package/dist/templates/frontend/application/src/environments/environment.ts +3 -0
  1426. package/dist/templates/frontend/application/src/environments/environment.type.ts +13 -0
  1427. package/dist/templates/frontend/packages/hub/public/i18n/hub/en.json +1 -1
  1428. package/dist/templates/frontend/packages/hub/public/i18n/hub/es.json +1 -1
  1429. package/dist/templates/frontend/packages/hub/src/app/domains/admin/apps/hub/app/app.columns.ts +4 -15
  1430. package/dist/templates/frontend/packages/hub/src/app/domains/admin/apps/hub/app/app.cross-context.spec.ts +56 -0
  1431. package/dist/templates/frontend/packages/hub/src/app/domains/admin/apps/hub/app/data-access/app.graphql.ts +9 -14
  1432. package/dist/templates/frontend/packages/hub/src/app/domains/admin/apps/hub/app/features/app-form.component.ts +24 -3
  1433. package/dist/templates/frontend/packages/hub/src/app/domains/admin/apps/hub/app/features/app-list.component.ts +2 -6
  1434. package/dist/templates/frontend/packages/hub/src/app/domains/admin/apps/hub/hub.routes.ts +1 -1
  1435. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/account/data-access/account.graphql.ts +2 -1
  1436. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/account/features/account-form.component.spec.ts +28 -0
  1437. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/account/features/account-form.component.ts +1 -9
  1438. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/iam.routes.ts +6 -10
  1439. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/permission/features/permission-form-embed.component.ts +8 -7
  1440. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/permission/features/permission-form.component.ts +12 -0
  1441. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/role/data-access/role.graphql.ts +1 -0
  1442. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/role/features/role-form.component.ts +29 -1
  1443. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/role-account/data-access/role-account.graphql.ts +1 -0
  1444. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/tenant/data-access/tenant.graphql.ts +1 -0
  1445. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/tenant/features/tenant-form.component.ts +20 -1
  1446. package/dist/templates/frontend/packages/iam/src/app/domains/admin/apps/iam/tenant-account/data-access/tenant-account.graphql.ts +1 -0
  1447. package/dist/templates/frontend/packages/o-auth/public/i18n/o-auth/en.json +1 -1
  1448. package/dist/templates/frontend/packages/o-auth/public/i18n/o-auth/es.json +1 -1
  1449. package/dist/templates/frontend/packages/o-auth/src/app/domains/admin/apps/o-auth/application/features/application-form.component.ts +43 -7
  1450. package/dist/templates/frontend/packages/o-auth/src/app/domains/admin/apps/o-auth/application/features/application-list.component.ts +1 -2
  1451. package/dist/templates/frontend/packages/o-auth/src/app/domains/admin/apps/o-auth/authorization-code/features/authorization-code-form.component.ts +22 -3
  1452. package/dist/templates/frontend/packages/o-auth/src/app/domains/admin/apps/o-auth/authorization-code/features/authorization-code-list.component.ts +1 -2
  1453. package/dist/templates/frontend/packages/o-auth/src/app/domains/admin/apps/o-auth/o-auth.routes.ts +6 -6
  1454. package/dist/templates/monorepo/.backlog/config.yml +3 -0
  1455. package/dist/templates/monorepo/.claude/agents/jd-fix-agent.md +11 -8
  1456. package/dist/templates/monorepo/.claude/agents/jd-judge-a.md +8 -3
  1457. package/dist/templates/monorepo/.claude/agents/jd-judge-b.md +8 -3
  1458. package/dist/templates/monorepo/.claude/hooks/__fixtures__/br-hr-regression-baseline.txt +54 -42
  1459. package/dist/templates/monorepo/.claude/hooks/lint-barrels.test.ts +22 -17
  1460. package/dist/templates/monorepo/.claude/hooks/lint-barrels.ts +20 -18
  1461. package/dist/templates/monorepo/.claude/rules/route-backend-test.md +1 -1
  1462. package/dist/templates/monorepo/.claude/rules/scope-backend.md +1 -1
  1463. package/dist/templates/monorepo/.claude/scripts/catalyst-dev-mode.sh +0 -1
  1464. package/dist/templates/monorepo/.claude/settings.json +3 -1
  1465. package/dist/templates/monorepo/.claude/skills/REGISTRY.md +5 -5
  1466. package/dist/templates/monorepo/.claude/skills/catalyst-backlog/SKILL.md +442 -92
  1467. package/dist/templates/monorepo/.claude/skills/catalyst-backlog/frontier-worker-addendum.md +13 -5
  1468. package/dist/templates/monorepo/.claude/skills/catalyst-backlog/worker-system-prompt.md +2 -2
  1469. package/dist/templates/monorepo/.claude/skills/catalyst-cli/references/origin-conciliation.md +72 -0
  1470. package/dist/templates/monorepo/.claude/skills/catalyst-schema/SKILL.md +62 -86
  1471. package/dist/templates/monorepo/.claude/skills/catalyst-schema/front-presentation.md +209 -0
  1472. package/dist/templates/monorepo/.claude/skills/catalyst-schema/patterns-workflow.md +2 -2
  1473. package/dist/templates/monorepo/.claude/skills/catalyst-schema/types-reference.md +184 -3
  1474. package/dist/templates/monorepo/.claude/skills/harness-rules-guard/SKILL.md +8 -2
  1475. package/dist/templates/monorepo/.claude/skills/harness-rules-guard/references/audit.md +384 -0
  1476. package/dist/templates/monorepo/.claude/skills/judgment-day/SKILL.md +18 -15
  1477. package/dist/templates/monorepo/.claude/skills/judgment-day/references/prompts-and-formats.md +46 -21
  1478. package/dist/templates/monorepo/.claude/skills-triggers-index.json +8 -1
  1479. package/dist/templates/monorepo/.husky/post-checkout +17 -0
  1480. package/dist/templates/monorepo/.husky/post-merge +15 -0
  1481. package/dist/templates/monorepo/.husky/pre-commit +3 -3
  1482. package/dist/templates/monorepo/CLAUDE.md +116 -70
  1483. package/dist/templates/monorepo/cliter/business-rules-index.json +3399 -5201
  1484. package/dist/templates/monorepo/cliter/harness-rules/barrels.md +127 -7
  1485. package/dist/templates/monorepo/cliter/harness-rules/bridges.md +126 -3
  1486. package/dist/templates/monorepo/cliter/harness-rules/generated-artifacts.md +104 -0
  1487. package/dist/templates/monorepo/cliter/harness-rules-index.json +279 -19
  1488. package/dist/templates/monorepo/docs/AURORA-CATALYST-BRIEF.md +1 -1
  1489. package/dist/templates/monorepo/docs/business-rules/INDEX.md +11 -35
  1490. package/dist/templates/monorepo/docs/harness-rules/INDEX.md +11 -8
  1491. package/dist/templates/monorepo/openspec/config.yaml +7 -3
  1492. package/dist/templates/monorepo/package.json +2 -0
  1493. package/dist/templates/monorepo/scripts/backlog/README.md +627 -1539
  1494. package/dist/templates/monorepo/scripts/backlog/attempt.ts +4 -2
  1495. package/dist/templates/monorepo/scripts/backlog/close.test.ts +643 -69
  1496. package/dist/templates/monorepo/scripts/backlog/close.ts +495 -62
  1497. package/dist/templates/monorepo/scripts/backlog/dev.aurora.backlog-dispatch.plist +8 -3
  1498. package/dist/templates/monorepo/scripts/backlog/dispatch.test.ts +725 -62
  1499. package/dist/templates/monorepo/scripts/backlog/dispatch.ts +463 -49
  1500. package/dist/templates/monorepo/scripts/backlog/entry.test.ts +172 -63
  1501. package/dist/templates/monorepo/scripts/backlog/entry.ts +69 -12
  1502. package/dist/templates/monorepo/scripts/backlog/graph-cli.ts +70 -0
  1503. package/dist/templates/monorepo/scripts/backlog/graph.test.ts +800 -0
  1504. package/dist/templates/monorepo/scripts/backlog/graph.ts +386 -0
  1505. package/dist/templates/monorepo/scripts/backlog/guards.test.ts +619 -126
  1506. package/dist/templates/monorepo/scripts/backlog/guards.ts +363 -145
  1507. package/dist/templates/monorepo/scripts/backlog/lanes/frontier.settings.json +14 -2
  1508. package/dist/templates/monorepo/scripts/backlog/lanes/local.settings.json +22 -2
  1509. package/dist/templates/monorepo/scripts/backlog/lanes.json +2 -2
  1510. package/dist/templates/monorepo/scripts/backlog/launch.test.ts +415 -39
  1511. package/dist/templates/monorepo/scripts/backlog/launch.ts +28 -28
  1512. package/dist/templates/monorepo/scripts/backlog/maintenance.test.ts +732 -55
  1513. package/dist/templates/monorepo/scripts/backlog/maintenance.ts +328 -30
  1514. package/dist/templates/monorepo/scripts/backlog/render.test.ts +74 -3
  1515. package/dist/templates/monorepo/scripts/backlog/render.ts +70 -8
  1516. package/dist/templates/monorepo/scripts/backlog/slots.test.ts +214 -26
  1517. package/dist/templates/monorepo/scripts/backlog/slots.ts +128 -17
  1518. package/dist/templates/monorepo/scripts/backlog/task-view.test.ts +230 -75
  1519. package/dist/templates/monorepo/scripts/backlog/task-view.ts +128 -59
  1520. package/dist/templates/monorepo/scripts/backlog/types.ts +47 -17
  1521. package/dist/templates/monorepo/scripts/backlog/watch.test.ts +145 -0
  1522. package/dist/templates/monorepo/scripts/backlog/watch.ts +163 -47
  1523. package/dist/templates/monorepo/scripts/backlog/worker-edit.test.ts +20 -5
  1524. package/dist/templates/monorepo/scripts/backlog/worker-edit.ts +18 -5
  1525. package/dist/templates/monorepo/scripts/harness-rules/lint-barrels.test.ts +259 -6
  1526. package/dist/templates/monorepo/scripts/harness-rules/lint-barrels.ts +81 -38
  1527. package/oclif.manifest.json +230 -230
  1528. package/package.json +1 -1
  1529. package/dist/templates/backend/application/eslint.config.mjs +0 -94
  1530. package/dist/templates/backend/application/test/jest-e2e.json +0 -21
  1531. package/dist/templates/backend/application/test/jest-global-setup.ts +0 -15
  1532. package/dist/templates/backend/application/test/mocks/mime.mock.ts +0 -10
  1533. package/dist/templates/backend/application/test/mocks/uuid.mock.ts +0 -20
  1534. package/dist/templates/frontend/application/src/@aurora/lib/to-wire-date.spec.ts +0 -63
  1535. package/dist/templates/frontend/application/src/@aurora/lib/to-wire-date.ts +0 -70
@@ -1,1601 +1,689 @@
1
1
  # `backlog` dispatcher
2
2
 
3
3
  The reconciler that turns a `Queued` Backlog.md task into a running headless worker and, on
4
- completion, into a merge-ready PR. It is triggered three ways (a `onStatusChange` callback, a
5
- `launchd` timer, and — inside the maintenance pass — a `gh` poll for merged PRs), but every trigger
6
- runs the exact same idempotent pass over observable state: sweep dead locks and orphan slots,
7
- close out merged PRs, recompute every parent's derived status, pick the next `Queued` task by
8
- priority then age, run it through six guards, verify the local model is loaded when the task needs
9
- it, acquire a worktree slot, launch the right lane (`local`, a curated LM Studio executor, or
10
- `frontier`, a headless Claude Code orchestrator), and close — board integrity, mechanical scope
11
- check, format/barrels/test, the reviewer on the local lane, the AC/DoD check on both, then a PR —
12
- or, on any failure, save the work before ever releasing the slot. See
13
- `openspec/changes/add-backlog-task-dispatch/design.md` for the full rationale and decision log;
14
- this file documents how the pieces fit together operationally.
4
+ completion, into a merge-ready PR. Three triggers fire it a `onStatusChange` callback, a
5
+ `launchd` timer, and a `gh` poll for merged PRs inside the maintenance pass — and every trigger
6
+ runs the exact same idempotent pass: sweep dead locks and orphan slots, close out merged PRs,
7
+ recompute every parent's derived status, pick the next `Queued` task by priority then age, run it
8
+ through twelve guards, verify the local model is loaded when the task needs it, acquire a worktree
9
+ slot, launch the right lane (`local`, a curated LM Studio executor, or `frontier`, a headless
10
+ Claude Code orchestrator), and close — board integrity, a mechanical scope check, format → barrels
11
+ the task's declared test, the reviewer on the local lane, the AC/DoD gate on both, then a PR — or,
12
+ on any failure, save the work before ever releasing the slot. `openspec/changes/add-backlog-task-dispatch/design.md`
13
+ (and the archived changes under `openspec/changes/archive/`) hold the rationale and decision log;
14
+ this file documents how the pieces fit together operationally, as they stand today.
15
15
 
16
16
  ## Module table
17
17
 
18
18
  | Module | Responsibility |
19
19
  | --- | --- |
20
- | `entry.ts` | Orchestration root: resolves `BACKLOG_CWD`, serializes concurrent invocations with a single-flight file lock, applies the anti-loop guard to a status-change trigger, selects the next `Queued` task, and wires maintenance → selection → guards → model readiness → slot acquisition → launch → close into one pass (`runOnce`, async). It also RELEASES the single-flight lock mid-pass — see "Process model" below |
21
- | `maintenance.ts` | Runs first on every pass, and RETURNS the post-sweep slot registry the rest of the pass acts on, in a fixed order — step 0: retries a push a previous pass could not complete, refusing (never retrying) once the branch's PR reads confirmed `merged` rather than landing commits nobody will ever look at (defect 8, 2026-09-08 — the same push gate `close.ts`'s `checkBranchNotMerged` applies before the close's own pushes); step 1: sweeps locks with a dead PID or an expired heartbeat, killing a hung worker first, then saving its work before releasing anything same confirmed-merged refusal as step 0 rather than pushing a dead worker's WIP onto an already-merged branch; step 2: releases slots with no live process; step 3: moves a task with a merged PR to `Done` (via `gh`, one poll per branch per pass) skipping any task with an ALIVE lock, since a retry runs on the same branch and the PREVIOUS attempt's merged PR would otherwise declare the task `Done` mid-run, which the cancellation sweep then reads as "not cancelled" and leaves the worker running against a closed task — deleting the task's `task/<id>` branch (local, then remote) once it reaches `Done` this way, but ONLY when the branch is first confirmed to carry no commit unreachable from its base (`MaintenanceGit.branchHasUnmergedCommits`, compared against `guards.ts`'s `taskBaseBranch` — never a hand-rolled `main`, which would block every subtask) — a branch that fails that check is left ENTIRELY alone, reported in `MaintenanceResult.branchCleanupRefused` rather than `cleanedUpBranches`, so the fail-safe `unknown`-still-pushes decision in steps 0/1 below can never again turn a rescue push landed on an already-merged branch into commits destroyed outright (the remaining T-8 point 5 hole, closed 2026-09-08) — and even once that check passes, deletion still counts as done ONLY when the remote half is CONFIRMED gone (deleted this pass, or already absent) rather than merely attempted (defect 7, 2026-09-08); step 3b: reverts a hand-written `Done` back to `In Progress` when its branch exists but GitHub does not report its PR merged; step 3c: blocks an orphan `In Progress` task (no lock, no slot, no attempt directory, and an `updated_date` older than `lanes.json`'s `orphanInProgressThresholdHours`) — entirely OFF when that threshold is `0`, the operator's explicit way to disable this step, rather than the most aggressive setting a bare millisecond conversion used to make it (defect 12, 2026-09-08); step 4: kills a manually-cancelled task's WORKER after its work is saved a cancellation being an EXPLICIT `Blocked`/`To Do`, or a task gone from a board that was read in FULL (`boardComplete`), never merely "not `In Progress`"; step 5: recomputes every parent's derived state, deleting the branch of any parent this step itself closes (same unmerged-commits check and confirmed-gone condition as step 3); step 6: commits any pending `.backlog/**` changes with a conventional message |
22
- | `guards.ts` | `evaluateGuards(task, board, slots, limits, permissions, remoteBranches)` — the dispatch guards over the selected task, in fixed order (missing triage — **also, `tier:medium` + `lane:local` (`tier-lane-mismatch`; `tier:complex` + `lane:local` is guard 2's own `complex-on-local`, unchanged), on `lane:local` no declared `Files to touch:`, and on EITHER lane no declared `Test command:`, or one the allowlist refuses** — then **guard 1c, on BOTH lanes: a task whose declared `Files to touch:` reach the HARD path list (`slot-executed-path`; T-31 — evaluated immediately after guard 1, because a task declaring a file that can never be admitted has nothing a later guard could make actionable), which does NOT fire on a soft-list declaration** — then **guard 1b, on BOTH lanes: a loaded settings allow rule with no safe deny** — Complex on local, unmet dependency, security path on local, **guard 4b: a subtask's parent branch missing from the remote (`missing-parent-branch`; T-14, 2026-09-08 — see `resolveTaskBase` below — placed AFTER security so that refusal is never masked by an actionable-looking "push a branch" message)**, attempts exhausted, no free slot), returning `launch` / `wait` (stays `Queued`, as `dependency-not-done`, `no-free-slot` or `push-pending`) / `block` (moves to `Blocked` with a Spanish cause). `limits`, `permissions` and `remoteBranches` are all REQUIRED (no defaults, T-14 fix round) — a caller that drops `remoteBranches` used to silently block every subtask on the board with a false cause, undetected by the suite because no test fixture had ever exercised a subtask through `evaluateGuards`. The two caps arrive as `limits`, derived from `lanes.json` by `launch.ts`'s `dispatchLimitsFrom` rather than from a module constant; `permissions` (the loaded settings allow list and the whole surface the launch would grant) is composed by `entry.ts`, so this module keeps taking no filesystem access. The board it reads is the one re-read AFTER the maintenance sweep, so a dependency this very pass moved to `Done` unblocks its dependent immediately. Also owns `resolveTestCommand`, the single allowlist for a declared `Test command:` line read by guard 1 here, by `launch.ts` for the per-task Bash grant, and by `close.ts` for the triad — `grantCovers`/`denyWouldRevoke`/`findPermissionConflict`, the permission-rule comparison guard 1b decides with and `launch.ts` composes its deny list from, in that dependency direction — two predicates because the two directions are different questions: coverage ("already granted, skip it") is stricter than the real matcher, revocation ("would a deny for this kill that grant?") is exactly as coarse as it — and `taskBaseBranch`/`resolveTaskBase`, the ONE place a task's base branch is named (`task/<parentId>`, or `main`) and, for `resolveTaskBase`, checked against the remote: guard 4b blocks on it, `slots.ts`'s `resolveBranch` consults it (and throws rather than falling back if it is ever violated post-guard), and `close.ts`'s `resolveBaseBranch`/`resolveBaseRef` consult the naming half — T-4.1 measured what two independent answers to "what is this task's base?" costs (a whole frontier worker run, blocked on `scope-check-failed` after finishing correctly) |
23
- | `slots.ts` | Acquires and releases one of the three reusable worktrees, provisions one on demand (`git worktree add --detach origin/main` `scripts/worktree-link.sh` `pnpm install`), the dispatch-lock lifecycle (PID + heartbeat — `writeLock`, `releaseLock` and `refreshHeartbeat` all run under the SAME per-task exclusive lock, since a mutex only one participant enters is not a mutex), the lockfile-hash install check, branch resolution (reuse the existing `task/T-nn` branch on retry, otherwise `guards.ts`'s `resolveTaskBase` names the base `origin/task/<parent>` for a subtask, `origin/main` otherwiseand `resolveBranch` THROWS if that base is missing from the remote, rather than the silent `origin/main` substitution it used to make: T-14, 2026-09-08 — see `guards.ts`'s guard 4b, which now refuses that dispatch before a slot is ever taken, making the case a programming error here rather than a fallback to route around), `slotPathForTask` (the directory holding a task's work, or `null`), `releaseSlotAndDetach` — the ONE release procedure every path uses — `releaseHeldSlotEntries` (the MANUAL rescue behind `--release-slot`, the only release that clears `heldForRecovery`), and `updateSlots`/`createRegistryLock`, the ONE mutation primitive every `slots.json` write goes through |
24
- | `launch.ts` | Per-lane launch preparation: lane/model resolution from task labels, the exact `claude` command for each lane (the lane settings' `permissions.allow`/`deny` become `--allowedTools`/`--disallowedTools`, merged on both lanes with `backlogRulesForTask`'s ONE rule — the dispatcher-owned `worker-edit.ts` wrapper bound to that task id, which both reads (`--view`) and writes — plus `testCommandRuleForTask`'s rule for the task's own declared test, with an argument containing whitespace re-quoted so the granted string is the one the close spawns), `settingsSourcePaths` + `loadSettingsAllowRules` (each loaded rule tagged with the source file it came from, since a path glob is relative to that file) + `settingsAllowRulesToDeny` + `composeGrantedAllow` (the one composition of the whole granted surface — lane list plus the per-task grants — that guard 1b compares and `buildLaunch` writes into `--allowedTools`) (BOTH lanes load a settings source on purpose and name it — `--setting-sources user` locally, `user,project` on the frontier lane, never the click-approval overlay, with `LANE_SETTING_SOURCES` the one list the flag value and the loaded files both derive from — so every allow rule those sources contribute and the lane does not grant is emitted as a deny; coverage-aware through `guards.ts`'s `findPermissionConflict`, whose no-safe-deny verdict guard 1b already turned into a block before this ran — the throw here is the invariant behind that guard), `assertLaneGrantsFileAccess` (refuses to launch unless the merged allow list actually grants a read AND a write rule — a lane holding only `Bash` rules is not a restricted worker, it is a worker that cannot open a file), `dispatchLimitsFrom` (the `maxParallel`/`attempts` caps the guards and the slot acquisition read), `sanitizeInheritedEnv` (drops every inherited `ANTHROPIC_*`/`CLAUDE_CODE_*` key and every other credential-shaped one — `isCredentialEnvKey`), the async line-streamed `spawnWorker` (detached, reporting the child pid through `onSpawn`), `killProcessTree`, and the LM Studio `/api/v0/models` readiness check before a local-lane launch |
25
- | `close.ts` | The dispatch close: `checkBoardIntegrity` (the board still says `In Progress`, and the acceptance/DoD texts, the title, the parent, the declared files and the declared test command still read as they did at launch), `checkScope` (the mirror-output prefix first — refused on both lanes regardless of the two lists — then `guards.ts`'s hard list `SLOT_EXECUTED_PATHS`/`SLOT_EXECUTED_BASENAMES` (on local, `LOCAL_FORBIDDEN_PATHS` — the hard list plus three local-only path extras — and the security paths as well), then, once nothing violated, the soft list `HUMAN_REVIEW_PATHS` admitted and reported in `humanReviewFiles`, never a violation; see "Forbidden paths, split by mechanism" below) and `runScopeCheck`/`collectChangedFiles` over the slot's real changes (plus `collectLeftoverFiles`, the same read CLASSIFIED the same way and with no verdict attached refused paths and soft-list paths in separate buckets — for the failure paths that never run the scope check: a session-level failure and a `board-check` divert), `resolveBaseBranch` (the PR's `--base`, delegating to `guards.ts`'s `taskBaseBranch` the SAME naming `slots.ts`'s branch resolution consults, since T-4.1 measured the two disagreeing when each computed its own answer) and `resolveBaseRef` (the `origin/…` ref the work is diffed against and branched from), `planMechanicalChecks` (Prettier `--write` then `--check` per workspace → barrels lint → the task's declared test — validated by `guards.ts`'s `resolveTestCommand`, which this module READS rather than owns — all scoped to the attempt's own changed files), `evaluateAcceptanceGate` (the pre-PR gate), `buildWipCommitMessage`/`buildAttemptCommitMessage`/`buildPrTitle`, `formatBlockComment`/`sanitizeCommentBody`, `buildPrCreateArgs`/`buildPrLabelArgs`/`buildPrReviewerArgs`/`buildPrBodyArgs` (the human-review mark), `collectAttemptDiff`, `planClose` (a pure planner over the ordered steps), and `executeClose` (walks the plan through injected runners, always saving work before releasing a slot on any failure) |
26
- | `parent.ts` | `deriveParentStatus(children, ownPrMerged, tier?, closeAttempted?)` — the parent-state precedence table (any child `Blocked` wins; any child `Queued`/`In Progress`, or a `Done`+`To Do` mix, means `In Progress`; all children `Done` plus the parent's own PR merged means `Done`; all children `Done`, the PR NOT merged, `tier:complex` and never yet attempted means `Queued` the ONE automated close attempt, T-8; the same shape once already attempted (`closeAttempted`) returns `null` — defers to whoever owns it now, a live retry or a human's `Blocked` review, rather than re-deriving on top of it; all children `Done`, the PR not merged, any OTHER tier means `In Progress` (pre-T-8 behavior); all `To Do` means `To Do`), applied recursively to grandchildren through the exported `effectiveStatus` (a node with `children` recomputes itself from THEM rather than trusting its own possibly-stale literal `status` — also how `dispatch.ts`'s `isParentCloseAttempt` asks the same question for one node without re-deriving); `tier`/`closeAttempted` are optional and default to "not Complex" / "never attempted", the exact pre-T-8 behavior, for a caller that predates it. Parent state is NEVER written by hand — `maintenance.ts`'s `recomputeParent` is the only writer, and it additionally gates the all-Done branch on the parent's OWN branch `mergedState` (never a caller-supplied `ownPrMerged` alone) so a `gh` outage derives nothing rather than misreading an unanswerable question as "not merged" (F1) |
27
- | `render.ts` | Maps one `stream-json` event to a human-readable log line (`renderEvent`) and replays a whole recorded session (`renderStream`); shared by the close's `run.log` writer and `watch.ts`'s live tail |
28
- | `watch.ts` | `pnpm backlog:watch <id>` tails that attempt's rendered `run.log`; with no id, lists busy slots from `slots.json`. Stops on its own once the task's lock file disappears — the close removes it as its very last step, so "the lock is gone" means "there is nothing left to tail" — flushing whatever `run.log` holds at that final tick before exiting, rather than polling forever (T-8 point 1: two watchers were measured six hours orphaned under the old bare-`setInterval` version). A missing `run.log` (a dispatch that aborted before the worker ever streamed a line) reads as "no growth yet", not as a reason to skip checking the lock, so that case still stops too (T-8 defect 9, 2026-09-08). Read-only — never writes board state, a lock, or a slot |
29
- | `notify.ts` | Fires a macOS notification (`osascript`) on `Blocked` and on PR-opened; a no-op on any non-`darwin` platform so unit tests and non-Mac runs never fail on a missing `osascript` binary |
30
- | `attempt.ts` | The per-attempt record under `.backlog/.dispatch/<TASK_ID>/intento-<N>/`: `countAttempts` (what `lanes.json`'s `attempts` cap counts), `createAttemptDir` (opened BEFORE the worker starts, so `backlog:watch` can tail it live) and `createAttemptSink` (appends `stream.jsonl` line by line, renders `run.log` on `finish`, and refreshes the lock heartbeat on a 30 s TIMER until `stopHeartbeat` which the close calls at its very end, not when the worker exits) |
31
- | `reviewer.ts` | The local lane's close reviewer: the isolated, read-only `claude` argv (`--setting-sources user --strict-mcp-config --disable-slash-commands`, no write tool — deliberately NOT `--bare`, see below) and `reviewerEnv` (drops every `ANTHROPIC_*` key, so the account's claude.ai login authenticates), the dual-verdict prompt (defects, conformity per acceptance criterion, and "would this test fail if its logic broke?") with the diff fenced as untrusted data, and the `REVIEW COMPLETE` + `VERDICT: pass|fail` parse. Fails closed — no verdict blocks the task |
32
- | `task-view.ts` | The single parser for the `backlog` CLI's plain output, with every reader bounded to the region that can legitimately answer for it. Section readers see the DECLARATION REGION — everything above the first `Implementation Plan:`/`Implementation Notes:`/`Notes:`/`Comments:` heading (heading meaning label line PLUS its dashed underline, so a description with a `Notes:` line of its own does not truncate the contract), since those are the sections a worker's own `--plan`/`--append-notes` writes into and a first-match parser read a heading it forged there as if the CLI had rendered it. Header readers (`Status:`, `Priority:`, `Created:`, `Labels:`, `Parent:`, the title heading) see the HEADER REGION — everything above the first rendered section — because those fields exist nowhere else, and a `Parent:` forged in the notes was the first match on a top-level task and rerouted the PR's base branch: `parseBoardTaskIds` (one id per `task list` row, never an id merely mentioned in a title), the `Task` shape (its `tier`/`lane`/`path` resolved against the real label values, so a typo reads as no triage rather than as a lane nothing matches), the `Files to touch:` and `Test command:` description conventions, the acceptance/DoD TEXTS snapshotted at launch for the close's integrity gate, and the AC/DoD checklists with their checked state and CLI index |
33
- | `worker-edit.ts` | The ONLY board channel a dispatched worker is granted, read included: `validateWorkerEditArgs` reads the whole argv (exactly the dispatched id, then `--check-ac`/`--notes`/`--append-notes`/`--plan`, each at most once, no value that is itself a flag — or `--view` alone) and forwards to `backlog task edit`, or to `backlog task view … --plain`, in the main checkout — which it requires `BACKLOG_CWD` to name, since `execFileSync` with no `cwd` would run in the SLOT, whose `.backlog/` copy holds no tasks; anything else exits 2 explaining the refusal. It exists because a permission rule matches a PREFIX and cannot narrow what follows it — the four per-flag grants it replaced all admitted a trailing `--status Done`, and the separate `Bash(backlog task view <id>:*)` read grant admitted any longer command line beginning with those words. Its SECOND mode, `--subtask` (mutually exclusive with the four edit flags and `--view`), is the headless way a Complex task's SDD design phase creates the subtasks a split produces — `--title`/`--labels` required, plus exactly one of `--desc` or `--desc-file <path>` (mutually exclusive; the file variant reads UTF-8 text from a path that must stay relative and inside the worker's own cwd no leading `/`/`~`, no `..` segment — the robust way to pass multi-line text without the `$'…\n…'` ANSI-C quoting a Bash permission rule reads as a `$` expansion and denies, T-6 measured, four attempts out of five), `--labels` validated against the SAME `tier:`/`lane:`/`path:`/`bc:` taxonomy (`tier:complex` forcing `lane:frontier`, and — T-6 — `lane:local` forcing `tier:minor`, the same restriction `guards.ts`'s own guard 1 now enforces on the board), the resolved description validated against `resolveTestCommand` and, on `lane:local`, `parseFilesToTouch` and never accepts `--parent`: the parent is `BACKLOG_TASK_ID` itself. Forwards to `backlog task create <title> -p <parentId> --desc … -l … [--ac …]... [--priority …] [--type …] [--depends-on …]` |
34
- | `dispatch.ts` | The executable entry point every trigger invokes: wires the REAL collaborators (real `fs` under `.backlog/.dispatch/`, real `git`/`gh`/`backlog` shell-outs, a real `claude` spawn) and calls `entry.ts`'s `runOnce`. It also owns the one flag the script takes — `releaseSlotByName`, the `--release-slot` rescue, which runs its read→decide→detach under the SAME single-flight lock a reconciler pass holds for its selection (a rescue that interleaved with a pass could detach the very worktree that pass had just acquired) and REFUSES (exit 2) both a pass already running and a slot whose task lock is still alive, unless the slot is `heldForRecovery` or `--force` is passed |
20
+ | `entry.ts` | Orchestration root: resolves the MAIN checkout every other entry point reads and writes board state in (`resolveContext`/`resolveMainCheckout` — `BACKLOG_CWD` first, `git rev-parse --git-common-dir` otherwise, so a trigger fired from a worktree still lands on the main checkout), serializes concurrent invocations with a single-flight file lock, applies the anti-loop guard to a status-change trigger, selects the next `Queued` task, and wires maintenance → selection → guards → model readiness → slot acquisition → launch → close into one pass (`runOnce`). Releases the single-flight lock mid-pass — see "Process model" |
21
+ | `maintenance.ts` | Runs first every pass and returns the post-sweep slot registry, in order: retries a pending push (refusing once the branch's PR reads `merged`); sweeps locks with a dead PID or an expired heartbeat, saving work before releasing; releases slots with no live process; attempts the «Registro de ejecución» block THEN, regardless of whether that write succeeded, moves a task with a merged PR to `Done` (see "The «Registro de ejecución» block" belowa write that fails posts ONE board comment instead and never blocks the transition) and deletes its `task/<id>` branch once confirmed free of unmerged commits and confirmed gone on the remote; reverts a hand-written `Done` back to `In Progress` when GitHub does not report the PR merged; blocks an orphan `In Progress` task past `lanes.json`'s `orphanInProgressThresholdHours` (`0` disables this step); kills a manually-cancelled task's worker after saving its work; recomputes every parent's derived state attempting the SAME block, the SAME way, for a parent this derivation itself moves to `Done` (deleting its branch the same way a leaf task's is); refreshes the graph-holder task (see "The dependency view" below) with the current dependency view when it changed; commits any pending `.backlog/**` change |
22
+ | `guards.ts` | `evaluateGuards(task, board, slots, limits, permissions, remoteBranches)` — the twelve dispatch guards over the selected task, in fixed order (see "The guard chain"). Also owns `resolveTestCommand` (the one allowlist for a declared `Test command:`, shared with `launch.ts` and `close.ts`), `grantCovers`/`denyWouldRevoke`/`findPermissionConflict` (the permission-rule comparison guard 1b and `launch.ts` both read), and `taskBaseBranch`/`resolveTaskBase` the ONE place a task's base branch is named (`task/<parentId>`, or `main`), consulted by `slots.ts`'s branch resolution and by `close.ts`'s PR-base resolution |
23
+ | `graph.ts` | The pure logic behind the dependency view (see "The dependency view" below): `renderDependencyGraph`/`renderHolderDescription` over a `Board`, `decideGraphWrite` (what, if anything, a refresh should write), and `runGraphCli` (the whole `backlog:graph` behaviourargv gate, the incomplete-board warning, the effect dispatch, the exit code) over injected effects. Never imports `dispatch.ts` |
24
+ | `graph-cli.ts` | The `backlog:graph` executable entry point: binds `graph.ts`'s `runGraphCli` to the real board (`dispatch.ts`'s `loadAllTasks`) and the real `backlog` CLI (`dispatch.ts`'s `realBacklog`), and resolves the MAIN checkout through `entry.ts`'s `resolveContext`, fed `dispatch.ts`'s `realGitCommonDir` |
25
+ | `slots.ts` | Acquires and releases one of the three reusable worktrees, provisions one on demand (`git worktree add --detach origin/main` `scripts/worktree-link.sh` `pnpm install`), andafter `prepareSlot` resets the slot onto the task's branchinstalls (never builds) `packages/cli`'s own dependencies, tracked by its own `cliLockfileHash` field. Owns the dispatch-lock lifecycle (PID + heartbeat), branch resolution (reuse the existing branch on retry; otherwise `resolveTaskBase` names the base and `resolveBranch` throws if that base is missing from the remote), `slotPathForTask`, the one release procedure (`releaseSlotAndDetach`), the manual rescue behind `--release-slot` (`releaseHeldSlotEntries`), and `updateSlots` the one mutation primitive every `slots.json` write goes through |
26
+ | `launch.ts` | Per-lane launch preparation: lane/model resolution from the task's labels, the exact `claude` argv per lane (the lane settings' `permissions.allow`/`deny` become `--allowedTools`/`--disallowedTools`, merged with the `worker-edit.ts` wrapper rule and the task's own validated test-command rule), settings-source loading and the allow→deny subtraction (`composeGrantedAllow`), `assertLaneGrantsFileAccess` (a lane must grant at least one read rule and one write rule), `dispatchLimitsFrom` (the `maxParallel`/`attempts` caps), `sanitizeInheritedEnv` (drops every inherited `ANTHROPIC_*`/`CLAUDE_CODE_*` key and every other credential-shaped one), the line-streamed `spawnWorker`, `killProcessTree`, and the LM Studio readiness check before a local-lane launch |
27
+ | `close.ts` | The dispatch close: `checkBoardIntegrity`, `checkScope`, `planMechanicalChecks` (Prettier `--write` then `--check` per workspace barrels lint the task's declared test, all scoped to the attempt's own changed files), the CLI scaffold mirror regeneration, `evaluateAcceptanceGate`, `open-pr`, and the failure-path save — see "The close". Also owns `buildExecutionRecordBlock`/`hasExecutionRecordBlock`, the PURE composer and idempotence sentinel `maintenance.ts`'s `Done` transition calls — see "The «Registro de ejecución» block" |
28
+ | `parent.ts` | `deriveParentStatus(children, ownPrMerged, tier?, closeAttempted?)` — the parent-state precedence rule (see "Load-bearing invariants"), applied recursively through `effectiveStatus`. Parent state is written ONLY by `maintenance.ts`'s `recomputeParent` |
29
+ | `render.ts` | Maps one `stream-json` event to a human-readable log line (`renderEvent`) and replays a whole recorded session (`renderStream`); shared by the close's `run.log` writer and `watch.ts` |
30
+ | `watch.ts` | `pnpm backlog:watch <id>` tails that attempt's rendered `run.log` live; with no id, lists busy slots from `slots.json`. Stops once the task's lock file disappears (the close removes it as its last step). Read-onlynever writes board state, a lock, or a slot |
31
+ | `notify.ts` | Fires a macOS notification (`osascript`) on `Blocked` and on PR-opened; a no-op on any non-`darwin` platform |
32
+ | `attempt.ts` | The per-attempt record under `.backlog/.dispatch/<TASK_ID>/intento-<N>/`: `countAttempts`, `createAttemptDir` (opened before the worker starts, so `backlog:watch` can tail it live), and `createAttemptSink` (appends `stream.jsonl` line by line, renders `run.log` once on `finish`, and refreshes the lock heartbeat every 30 s until `stopHeartbeat`) |
33
+ | `reviewer.ts` | The local lane's close reviewer: an isolated, read-only `claude` argv (`--setting-sources user --strict-mcp-config --disable-slash-commands`, no write tool, deliberately not `--bare`), the dual-verdict prompt (defects, per-criterion conformity, and "would this test fail if its logic broke?") with the diff fenced as untrusted data, and the `REVIEW COMPLETE` + `VERDICT: pass|fail` parse. Fails closedno verdict blocks the task |
34
+ | `task-view.ts` | The single parser for the `backlog` CLI's plain output: `parseBoardTaskIds`, the `Task` shape (`tier`/`lane`/`path` resolved against real label values), the `Files to touch:`/`Test command:` conventions, the acceptance/DoD texts snapshotted at launch, and the AC/DoD checklists with their checked state |
35
+ | `worker-edit.ts` | The ONLY board channel a dispatched worker is granted, read included — see "`worker-edit.ts`: the worker's only board channel" |
36
+ | `dispatch.ts` | The executable entry point every trigger invokes: wires the real collaborators (`fs`, `git`/`gh`/`backlog` shell-outs, a real `claude` spawn) and calls `entry.ts`'s `runOnce`. Owns the `--release-slot` rescue flag |
35
37
 
36
38
  `types.ts` holds the shared shapes (task labels, `slots.json`, `locks/<TASK_ID>.json`) every other
37
- module imports from, so the on-disk contract has one source of truth; `prompt.ts` assembles the
38
- local-lane executor's five-block user prompt and, with `buildFrontierAddendum`, renders the frontier
39
- lane's per-attempt system-prompt addendum from its skill-file template (see
40
- `.claude/skills/catalyst-backlog/SKILL.md` for the worker-facing side of that contract).
39
+ module imports from. `prompt.ts` assembles the local-lane executor's five-block user prompt and, with
40
+ `buildFrontierAddendum`, renders the frontier lane's per-attempt system-prompt addendum from
41
+ `.claude/skills/catalyst-backlog/frontier-worker-addendum.md`.
42
+
43
+ ## Load-bearing invariants
44
+
45
+ - Parent state is never written by hand: `maintenance.ts`'s `recomputeParent` is the only writer.
46
+ - The per-task lock's heartbeat covers the close too, not just the worker's run — it stops only
47
+ once the slot has been released or held, so a close whose own steps outlast the 10-minute TTL is
48
+ never mistaken for a dead worker.
49
+ - `guards.ts`'s `resolveTaskBase` is the ONE place a task's base branch is named; `slots.ts`'s branch
50
+ resolution and `close.ts`'s PR-base resolution both consult it rather than compute their own answer.
51
+ - A task's branch closes itself only when it is named `task/T-nn` — the merge sweep deduces the
52
+ branch from the task id and asks `gh` whether that branch's PR merged.
53
+ - A subtask's base is always `task/<parentId>` — a pure deduction from the parent's id, never a
54
+ value a task declares.
55
+ - Every `slots.json` write goes through `slots.ts`'s `updateSlots`, which takes an exclusive lock,
56
+ RE-READS the file, and applies the caller's transform to what it finds there.
57
+ - A slot never keeps a task branch checked out after release: every release path runs
58
+ `git checkout --detach` first, because git refuses to check the same branch out in two worktrees.
59
+ - Work is branched and diffed against `origin/…`, never a local ref — a reusable slot's local `main`
60
+ is whatever its last fetch left behind.
61
+ - `worker-edit.ts` is the ONLY board channel a dispatched worker is granted, reading included.
62
+ - The declared `Test command:`, `Files to touch:`, the title and the AC/DoD texts are snapshotted at
63
+ launch; the close judges the attempt against that snapshot, never a re-read of the board.
64
+ - The twelve guards run in a fixed order and the first one that fires wins — no later guard is
65
+ evaluated once an earlier one has decided the outcome.
66
+ - `--permission-mode dontAsk` denies any Edit/Write on a path carrying a `.claude` segment,
67
+ regardless of what any allow rule says, on either lane — no lane-settings change can undo this.
68
+ - The click-approval overlay (`.claude/settings.local.json`, a person's own ad-hoc approvals) is
69
+ never a loaded settings source for a dispatched worker, on either lane.
70
+ - A dispatched worker's `Bash` grant is not the only thing that lets a command run: Claude Code
71
+ itself auto-approves a `Bash` command it can statically read as read-only (a bare `ls`, `grep`,
72
+ `find` without `-exec`/`-delete`, …), whatever the allow list says — a compound line is not.
73
+ - Every headless worker runs with `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1`, forced by `launch.ts`
74
+ over any lane `env`, on both lanes — a `-p` session kills a backgrounded Bash call the moment it
75
+ ends its own turn, and kills a backgrounded Agent's longer work too, after at most one extra
76
+ relay turn.
41
77
 
42
78
  ## On-disk data layout
43
79
 
44
- Everything the dispatcher writes at runtime lives under `.backlog/.dispatch/`, which is
45
- gitignored (unlike `.backlog/` itself, which IS tracked see "Where board state lives" below):
80
+ The board (`.backlog/tasks/`, `.backlog/config.yml`) lives ONLY in the main checkout, never in a
81
+ slot; every dispatcher process, and every `backlog` CLI call it makes, is pointed there with
82
+ `BACKLOG_CWD=<main checkout>`. Both lane settings deny `Edit`/`Write` on `.backlog/**`, and the
83
+ close's scope check reports a change there as a violation on both lanes, so a slot's own `.backlog/`
84
+ copy is never the board of record. `.backlog/config.yml` sets `check_active_branches: false`
85
+ (three worktrees independently writing the same task files would be a merge-conflict generator) and
86
+ `auto_commit: false` — Backlog.md's own auto-commit message fails this repo's commitlint, so
87
+ `maintenance.ts`'s `commitBacklogChanges` commits any pending `.backlog/**` change itself, with a
88
+ Conventional Commit message, `--no-verify`, and a trailing `-- .backlog` pathspec so an unrelated
89
+ staged file never rides along.
90
+
91
+ Everything the dispatcher writes at RUNTIME lives under `.backlog/.dispatch/`, which is gitignored
92
+ (unlike `.backlog/` itself):
46
93
 
47
94
  ```
48
95
  .backlog/.dispatch/
49
96
  <TASK_ID>.log # nohup redirect of every reconciler run this task's status
50
- # transitions started — APPENDED to, so a re-queue after Blocked
51
- # does not erase the run that blocked it
52
- launchd.log # StandardOutPath/StandardErrorPath of the launchd timer — the
53
- # LAUNCHER's own output (a failing `mkdir` or `nohup`), nothing else
54
- reconciler.log # nohup redirect of the reconciler the launchd timer detached. Its
55
- # own file on purpose: a pass runs for tens of minutes, and
56
- # interleaving it with the launcher's lines made neither readable
97
+ # transitions started — APPENDED to
98
+ launchd.log # the launchd launcher's own output
99
+ reconciler.log # nohup redirect of the detached reconciler
57
100
  slots.json # [{ name, path, lane, taskId|null, pid|null, lockfileHash, heldForRecovery? }]
58
- slots.lock # exclusive lock guarding every slots.json write (see below)
101
+ slots.lock # exclusive lock guarding every slots.json write
59
102
  locks/<TASK_ID>.json # { taskId, slot, pid, workerPid, startedAt, heartbeatAt, lane, attempt, branch }
60
103
  <TASK_ID>/intento-<N>/
61
104
  stream.jsonl # raw stream-json, appended line by line while the worker runs
62
- run.log # human-rendered, written ONCE when the worker exits (this is
63
- # what `pnpm backlog:watch` tails)
64
- test.log # transcript of the close's mechanical checks, one block per check
105
+ run.log # human-rendered, written ONCE when the worker exits
106
+ test.log # transcript of the close's mechanical checks
65
107
  review.md # the close reviewer's findings (local lane); read back on a retry
66
- meta.json # NOT YET WRITTEN — design.md reserves it for sessionId, lane,
67
- # model, branch, startedAt, endedAt, exitReason
68
108
  ```
69
109
 
70
- A lock is dead when `process.kill(pid, 0)` throws (no such process) or when `heartbeatAt` is older
71
- than the TTL (10 minutes, `dispatch.ts`'s `ttlMs: 10 * 60_000`) even with a live PID. `attempt.ts`
72
- refreshes `heartbeatAt` every 30 s on a TIMER — deliberately not from the stream events, which would
73
- make "alive" mean "emitting output" and sweep a worker that is merely thinking, waiting on a long
74
- test run, or streaming one very large event.
75
-
76
- **The heartbeat covers the CLOSE too, not just the worker.** `sink.finish()` renders `run.log` and
77
- stops reading; `sink.stopHeartbeat()` is called at the very end of the close, once the slot has been
78
- released or held. That split is load-bearing: the close's own steps (the scoped test run, the
79
- reviewer subprocess, `git push` + `gh pr create`) routinely take longer than the 10-minute TTL, and
80
- the single-flight lock was already dropped when the slot was taken so a heartbeat frozen at the
81
- worker's exit made the next pass read a live close as a dead worker, kill it, and release its slot
82
- mid-PR. The reviewer subprocess is separately bounded by `lanes.json`'s `reviewerTimeoutMinutes`
83
- (default 15), because a reviewer that never returns would otherwise hold a slot forever.
84
-
85
- `slots.json` is written through ONE primitive, `slots.ts`'s `updateSlots(store, mutate)`: it takes an
86
- exclusive lock (`.backlog/.dispatch/slots.lock`, broken when older than 30 s), RE-READS the file, and
87
- applies the caller's transform to what it finds there. Nothing writes a whole registry built on an
88
- older snapshot. Two passes legitimately run at once the single-flight lock is released as soon as a
89
- slot is taken so a snapshot-based write silently reverted the other pass's acquisition, its
90
- release, or its `heldForRecovery` flag, and losing that last one means losing the only marker saying
91
- a slot still holds unpushed work. Every writer (the maintenance sweep, the acquisition write-back,
92
- `releaseSlot`, `blockKeepSlot`) mutates only the fields it owns.
93
-
94
- The lock carries TWO pids and they are not interchangeable: `pid` is the RECONCILER (what the
95
- liveness probe checks), `workerPid` is the spawned `claude` process (what a cancellation kills, as a
96
- whole process group — the worker spawns hooks, `pnpm` and sub-agents of its own).
97
-
98
- `locks/<TASK_ID>.json` has its own exclusive lock (`locks/<TASK_ID>.json.lock`, the same
99
- `createRegistryLock` primitive `slots.json` uses), and **every** mutation of the file goes through
100
- it: the launch write, the heartbeat refresh, and the sweep's removal. A one-sided mutex is not a
101
- mutex moving the heartbeat's READ inside a critical section that nothing else entered only excluded
102
- a second heartbeat, and a `releaseLock` taking no lock still landed between that read and its write,
103
- after which the write resurrected a lock for a slot already handed to another task.
104
-
105
- `slots.json` is the allocation mutex (which of the three worktrees — named `dispatch-a`,
106
- `dispatch-b`, `dispatch-c` — is occupied, by which task, for which lane); `locks/<TASK_ID>.json` is
107
- the liveness detail for whoever currently holds that task. A slot flagged `heldForRecovery` is
108
- neither free nor reassignable: its work never reached the remote, so it holds the only copy (see
109
- "Failure path" below). `slots.ts` owns the pure operations on both shapes (acquire, release,
110
- provision, lock lifecycle, heartbeat); `dispatch.ts` owns the only real reads and writes of the two
111
- files.
112
-
113
- **The worktree slots are created on demand.** There is no bootstrap step: the first time a task
114
- acquires `dispatch-a`, the dispatcher runs `git worktree add .claude/worktrees/dispatch-a --detach
115
- origin/main`, then `bash scripts/worktree-link.sh` from inside it (linking the gitignored
116
- `backend/.keys` and `backend/.env` a worktree does not inherit), then `pnpm install`. That first
117
- acquisition therefore costs a full install — minutes, not seconds. Every later acquisition reuses the
118
- worktree and skips the install unless `pnpm-lock.yaml` moved (`slots.json`'s `lockfileHash`).
119
-
120
- `run.log` is written by `attempt.ts`'s sink — but only ONCE, inside `finish()`, as a single
121
- `writeFileSync` of the WHOLE session rendered through `render.ts` at that point; `appendStreamLine`
122
- is what grows the raw `stream.jsonl` line by line while the worker runs, not `run.log`. `finish()`
123
- itself runs as soon as the worker process exits, before the close's own steps (the scope check, the
124
- scoped test, the reviewer, the PR) — so `run.log` appears in full moments after the worker is done,
125
- not incrementally while it works, and not only once the whole close has finished either. `review.md`
126
- is written by the close's reviewer step, on every branch including a crashed reviewer, because a
127
- retry's prompt reads it back.
128
-
129
- `.backlog/.dispatch/` is created by the `onStatusChange` callback itself (it is prefixed with
130
- `mkdir -p .backlog/.dispatch;` — see "Trigger wiring"), and by `dispatch.ts` on every run. Nothing
131
- has to be created by hand in a fresh clone.
110
+ There is no `meta.json` file: the per-attempt record is `stream.jsonl` + `run.log` + `test.log` +
111
+ `review.md` only.
112
+
113
+ A lock is dead when `process.kill(pid, 0)` throws, or when `heartbeatAt` is older than the TTL
114
+ (10 minutes) even with a live PID. `attempt.ts` refreshes `heartbeatAt` on a 30 s timer, deliberately
115
+ not from the stream events, so a worker merely thinking or waiting on a long test run is never
116
+ swept. The reviewer subprocess is separately bounded by `lanes.json`'s `reviewerTimeoutMinutes`.
117
+
118
+ **External call timeout (T-97).** That 30 s timer only runs BETWEEN synchronous subprocess calls
119
+ it cannot fire while `dispatch.ts` is blocked inside a single `execFileSync` (`git`, `gh`, `backlog`,
120
+ `node`, `osascript`, `npx tsx`), because that blocks the whole event loop the timer needs. Before this
121
+ task none of `dispatch.ts`'s ~20 `execFileSync` calls carried a `timeout`, so a single hung one a
122
+ stalled `ssh` inside `git ls-remote`, measured 2026-09-15: 2h23m holding `dispatch.lock` — starved the
123
+ heartbeat until the maintenance sweep declared a live pass dead. Every such call now carries a
124
+ `timeout`, well under the 10-minute lock TTL above, so a hang fails like any other failure of that
125
+ call (never a new destructive path) instead of blocking forever:
126
+
127
+ - `EXTERNAL_CALL_TIMEOUT_MS` (`dispatch.ts`, 60 s) bounds every `git`/`gh`/`backlog`/`osascript`/
128
+ `npx tsx` call metadata reads and writes that normally finish in well under a second.
129
+ - `MECHANICAL_CHECK_TIMEOUT_MS` (`dispatch.ts`, private, 8 minutes) bounds only the close's own
130
+ mechanical checks (prettier, the barrels lint, the task's declared Test command) these
131
+ legitimately run for minutes, so they get a longer leash than the metadata calls above, but one
132
+ that still fails before the 10-minute lock TTL rather than exhausting it.
133
+ - `RealGitDeps.timeoutMs` and `makeGhRunner(timeoutMs)` are the injection seams that let a test bind
134
+ a short bound instead of the production default see `dispatch.test.ts`'s "a hanging git/gh call
135
+ is bounded" suites.
136
+
137
+ `packages/cli`'s dependency install (`provisionSlot`/`provisionCliDependencies`, `stdio: 'inherit'`)
138
+ is deliberately NOT bounded by either constant: it runs before any per-task lock exists, under the
139
+ single-flight lock instead, which is PID-liveness-based rather than TTL-based a slow (not hung)
140
+ install there does not starve a heartbeat that has not started yet, and a real install can legitimately
141
+ outrun even `MECHANICAL_CHECK_TIMEOUT_MS` on a cold cache.
142
+
143
+ The lock carries TWO pids: `pid` is the RECONCILER (the liveness probe), `workerPid` is the spawned
144
+ `claude` process (what a cancellation kills, as a whole process group). `slots.json` is the
145
+ allocation mutex (which of the three worktrees — `dispatch-a`, `dispatch-b`, `dispatch-c` — is
146
+ occupied, by which task, for which lane); `locks/<TASK_ID>.json` is the liveness detail for whoever
147
+ holds it. A slot flagged `heldForRecovery` is neither free nor reassignable — it holds the only
148
+ copy of work that never reached the remote.
149
+
150
+ `packages/cli`'s dependency install (never its build) runs in the same pass, on its own tracked
151
+ field (`cliLockfileHash`) — `packages/cli` is not a pnpm workspace member, so the root `pnpm
152
+ install` never reaches it; the step is skipped in a repo with no `packages/cli` of its own. The same
153
+ pass also removes `packages/cli/dist` (gitignored) so a worker never inherits a previous occupant's
154
+ build output — building it is the worker's own job (`pnpm cli:build`).
132
155
 
133
156
  ## Process model
134
157
 
135
- One reconciler process handles at most one dispatch, but it does NOT hold the single-flight lock
136
- for the worker's lifetime. The sequence is:
158
+ One reconciler process handles at most one dispatch, but it does NOT hold the single-flight lock for
159
+ the worker's lifetime:
137
160
 
138
161
  1. Acquire the single-flight lock (`.backlog/.dispatch/dispatch.lock`, PID-based) and run the whole
139
- maintenance → selection → guards → readiness → slot acquisition sequence under it.
140
- 2. Once the slot is taken, the lock file is written and the task is `In Progress`, **release the
141
- single-flight lock**. The per-task lock is what keeps a second pass off THIS task; the
142
- single-flight lock only serializes selection.
143
- 3. Spawn the worker asynchronously (`launch.ts`'s `spawnWorker`), in its OWN process group and with
144
- a sanitized environment: every `ANTHROPIC_*` and `CLAUDE_CODE_*` key this process inherited is
145
- dropped before the lane's own `env` is layered on, so a worker can never fall back to the
146
- account's credentials and so is every OTHER credential-shaped key (`isCredentialEnvKey`:
147
- `GH_`/`GITHUB_`/`NPM_`/`NODE_AUTH_`/`SOPS_`/`AWS_`/`AZURE_`/`GOOGLE_`/`OPENAI_` by prefix, plus
148
- anything ending in `TOKEN`, `SECRET`, `PASSWORD`, `API_KEY` or `PRIVATE_KEY`). The reconciler runs
149
- from a developer's session or from launchd, so its env is whatever that shell exports; a worker
150
- holding `GITHUB_TOKEN` pushes and opens PRs through the API with no `gh` binary involved, past
151
- every deny rule the lane spent its effort on. Its pid is written to the lock as `workerPid` the moment it exists. Its
152
- stdout streams line by line into `stream.jsonl`, and a 30 s timer refreshes `heartbeatAt`.
153
- 4. When the worker exits, render `run.log`, classify the stream and run the close. The heartbeat
154
- keeps beating through all of it, and only stops once the slot has been released or held.
155
-
156
- Before step 4 does anything, the pass **re-reads its own per-task lock**. The single-flight lock is
157
- long gone by then, so a maintenance sweep in another pass may legitimately have declared this worker
158
- dead (a heartbeat that fell behind is enough), saved its work, released its slot and handed that
159
- worktree to the next task. Closing on top of that opens a PR off someone else's branch, re-statuses
160
- a task a person already moved, and releases a slot holding live work. A lock that is gone, or that
161
- names another pid, skips the close entirely: the sweep already saved and blocked.
162
-
163
- The dispatcher process therefore stays alive for the worker's whole run — which is fine, because
164
- BOTH triggers detach it with `nohup` and return: the `onStatusChange` callback, and the launchd
165
- launcher (which must, or launchd would refuse to fire its own timer again while this pass lived
166
- see "Installing the launchd recovery timer"). Holding the single-flight lock across that run instead
167
- would make the frontier cap of 2 unreachable, stall the close's `drain`, prevent the maintenance
168
- pass from cancelling a running worker, and leave a 10-minute-TTL lock stale while its worker is
169
- demonstrably alive.
170
-
171
- Everything from taking the slot to the worker exiting runs inside one try/catch. A failing
172
- `pnpm install`, a `git checkout` against a ref that vanished, a hook subprocess that dies while the
173
- prompt is assembled — any of them used to escape the pass with the slot taken, the lock written and
174
- the task sitting in `In Progress`, recoverable only by the next sweep ten TTL minutes later. Now the
175
- slot goes back to the pool, the lock is removed, and the task moves to `Blocked` carrying the error.
176
-
177
- A close that ends in `drain` sets a flag; `dispatch.ts` then re-acquires the single-flight lock and
178
- runs ONE more pass for the next `Queued` task. Two passes per invocation is the cap — a trigger can
179
- never loop the whole queue in one process.
162
+ maintenance → selection → guards → readiness → slot-acquisition sequence under it.
163
+ 2. Once the slot is taken, the per-task lock is written and the task is `In Progress`, **release the
164
+ single-flight lock** it only serializes selection, never a worker's whole run.
165
+ 3. Spawn the worker asynchronously, in its own process group, with a sanitized environment (every
166
+ `ANTHROPIC_*`/`CLAUDE_CODE_*` key and every other credential-shaped one dropped before the lane's
167
+ own `env` is layered on). Its pid is written as `workerPid` the moment it exists; its stdout
168
+ streams into `stream.jsonl`; a 30 s timer refreshes `heartbeatAt`.
169
+ 4. When the worker exits, render `run.log` and run the close. The heartbeat keeps beating through it,
170
+ stopping only once the slot has been released or held — true only because every close step's own
171
+ subprocess calls are bounded well under the lock TTL (see "External call timeout (T-97)" above);
172
+ an unbounded call inside a close step would block the 30 s timer for as long as it hung.
173
+
174
+ Before step 4 runs anything, the pass RE-READS its own per-task lock: a lock that is gone, or that
175
+ names another pid, means another pass's maintenance sweep already declared this worker dead, saved
176
+ its work and released the slot this pass skips the close entirely rather than open a PR off a
177
+ branch someone else now owns.
178
+
179
+ Both triggers detach the reconciler with `nohup` and return at once, which is why holding the
180
+ single-flight lock across a worker's whole run would be wrong: it would make the frontier cap of 2
181
+ unreachable and stall every later pass.
182
+
183
+ **Cancellation is explicit, never inferred from "not `In Progress`".** A cancellation is a task moved
184
+ by hand to `Blocked`/`To Do`, or a task missing from a board read that completed in FULL — never
185
+ merely a task the sweep does not currently see as `In Progress`. On a cancellation the worker's whole
186
+ process group is killed AFTER its work is saved, never before.
187
+
188
+ Everything from taking the slot to the worker exiting runs inside one try/catch: any failure a
189
+ failing install, a vanished ref, a dying hook — returns the slot to the pool, removes the lock, and
190
+ moves the task to `Blocked` with the error, rather than leaving it stuck `In Progress`.
191
+
192
+ A close that drains re-acquires the single-flight lock and runs ONE more pass for the next `Queued`
193
+ task; two passes per invocation is the cap.
194
+
195
+ ## The guard chain (`guards.ts`)
196
+
197
+ `evaluateGuards` runs twelve checks in this fixed order over the selected `Queued` task. The first
198
+ one that returns a result wins:
199
+
200
+ | # | Check | Fires on | Result |
201
+ | --- | --- | --- | --- |
202
+ | 0 | Supervised mode | the task carries `mode:supervised` | block |
203
+ | 1 | Triage complete | missing `tier`/`lane`/`path`/`mode`; `tier:medium` on `lane:local`; `lane:local` with no `Files to touch:`; no declared `Test command:`, or one the allowlist refuses | block |
204
+ | 1c | Declared slot-executed path | a `Files to touch:` entry reaches `SLOT_EXECUTED_PATHS`/`SLOT_EXECUTED_BASENAMES`, as a file or a containing directory | block |
205
+ | 1d | Declared `.claude` path | a `Files to touch:` entry carries a `.claude` path component at any depth | block |
206
+ | 1e | Declared supervised-only path | a `Files to touch:` entry reaches a path on `SUPERVISED_ONLY_PATHS` | block |
207
+ | 1b | Permission composition | a settings rule this worker's sources load is broader than what the launch would grant, or scopes a file tool the lane does not cover | block |
208
+ | 2 | Complex on local | `tier:complex` with `lane:local` | block |
209
+ | 3 | Dependencies | an unresolved dependency id | block; an unfinished-but-resolvable one | wait |
210
+ | 4 | Security path on local | `lane:local` declares a file under a security-surface pattern | block |
211
+ | 4b | Parent branch on remote | a subtask whose `task/<parentId>` is missing from `origin` | block |
212
+ | 5 | Attempts exhausted | `task.attempts >= lanes.json`'s `attempts` cap | block |
213
+ | 6 | Free slot | the lane is at `maxParallel` capacity | wait (`no-free-slot`); this task's own slot is held for push recovery | wait (`push-pending`) |
214
+
215
+ Falling through all twelve means the task is clear to launch. A `block` moves the task to `Blocked`
216
+ with a Spanish comment naming the cause; a `wait` leaves it `Queued` for the next pass. Guard 0 runs
217
+ before every other guard, including guard 1's triage check: a `mode:supervised` task has exactly one
218
+ true verdict, so it blocks as supervised even when it also lacks a `Test command:` (guard 1), declares
219
+ a hard-list or supervised-only path (guards 1c/1e), or has an unfinished dependency (guard 3) —
220
+ without guard 0 at the head, a person would fix one of those first, re-queue, and only then learn the
221
+ task was never dispatchable to begin with. Its `Blocked` comment names the exact edit: remove
222
+ `mode:supervised` and add `mode:headless` in the SAME `backlog task edit` (`--remove-label
223
+ mode:supervised --add-label mode:headless` — `--add-label` alone APPENDS, it does not replace, which
224
+ would leave both `mode:` labels on the task), then re-queue.
225
+
226
+ The security-surface patterns (guard 4, and re-checked at close against the real diff) are:
227
+ `o-auth/`, `iam/`, `.guard.ts`, `@auth`, `sops`, `.env` — matched as a case-insensitive substring of
228
+ each declared path.
229
+
230
+ ## The dependency view (`graph.ts`, `graph-cli.ts`)
231
+
232
+ `renderDependencyGraph` is the one pure function that decides what the board's open-task dependency
233
+ view says: a flat list — a tree would repeat a task with two parents, since dependencies form a
234
+ DAG — in two sections, `LISTAS — sin dependencias abiertas` (no recorded open wait) and `EN ESPERA`
235
+ (waits for at least one, each line naming every one it waits for, in topological order). It derives
236
+ from what the board RECORDS and nothing else, over the four open statuses (`To Do`, `Queued`,
237
+ `In Progress`, `Blocked`): each task's declared `dependencies`, AND the parent/subtask link — a
238
+ parent waits for every one of its OPEN subtasks exactly like an open dependency, merged with any it
239
+ declares, deduplicated; a subtask never waits for its own parent this way; a `Done` dependency or
240
+ `Done` subtask is never a reason to wait. It guesses no link from what files two tasks happen to
241
+ touch. `renderHolderDescription` prepends the fixed header stating the view's own limit — recorded
242
+ links only, order rather than authorization — and `decideGraphWrite` turns a rendered view into one
243
+ of `no-holder` / `ambiguous` / `incomplete` / `unchanged` / `write`, without performing any I/O
244
+ itself, so both writers below share the exact same decision.
245
+
246
+ **Two callers, one function — different resolution each.** `pnpm backlog:graph` (`graph-cli.ts`'s
247
+ entry point, which binds `graph.ts`'s pure `runGraphCli` to the real world) prints the current view
248
+ and edits nothing; `pnpm backlog:graph --write` also calls `decideGraphWrite` and applies a `write`
249
+ decision immediately. It resolves the board through the MAIN checkout with `entry.ts`'s
250
+ `resolveContext` — the same resolver every dispatcher entry point uses — so running it from a
251
+ worktree operates the main checkout's board and not the worktree's own copy, which would be a blind
252
+ reconciler. `maintenance.ts`'s step 5b (see its own module-table row and doc comment) calls
253
+ `decideGraphWrite` directly, as part of every reconciler pass, between recomputing parent state and
254
+ the board commit, so a refresh it triggers rides in the same `chore(backlog): sync board state`
255
+ commit as whatever change caused it — it needs no resolution of its own, since it reuses the
256
+ `MaintenanceBacklog.setDescription`/`readDescription` collaborators `dispatch.ts` wired for it, both
257
+ already bound to the resolved main checkout.
258
+
259
+ **The command reports failure, never silently.** `runGraphCli` returns a non-zero exit code — and
260
+ `graph-cli.ts` sets `process.exitCode` from it — on an unrecognized argument (refused before
261
+ anything runs, nothing written), a board read the loader reported partial, more than one
262
+ `board:graph` holder, or a failed underlying read/write; `0` covers every "printed / refreshed /
263
+ nothing to do" outcome and nothing else. A partial board read is reported on stderr BEFORE the view
264
+ itself, with or without `--write`: a task waiting on one that could not be read would otherwise
265
+ render under "LISTAS" with no caveat in sight.
266
+
267
+ **The graph-holder task.** Found by the label `board:graph`, never by a task id — this tooling ships
268
+ to every scaffolded application, whose boards number their tasks differently. Zero holders is a
269
+ valid state (the feature is off); two or more is an ambiguity, reported by the caller
270
+ (`console.error` on the CLI, `MaintenanceResult`'s `graphHolderAmbiguous`) — the VIEW is written to
271
+ none of them, but each holder that does not already show it gets a plain-text notice instead, naming
272
+ every id and saying to keep the label on only one, under the same write-on-difference rule as the
273
+ view itself. The CLI still exits non-zero over an ambiguous board (the refresh it was asked for did
274
+ not happen), and removing the label from all but one brings the view back on the next refresh. The
275
+ holder's description is GENERATED — nobody edits it by hand, and it is never queued, worked or
276
+ closed; `catalyst-backlog/SKILL.md` §13 has it labelled `mode:supervised`, so a `Queued` holder is
277
+ refused by guard 0 first — guard evaluation is first-wins (see "The guard chain"), so guard 1's
278
+ separate "no `Test command:`" reason never even runs against it.
279
+
280
+ **The refresh REPLACES THE WHOLE DESCRIPTION, without reading it first.** Whichever text a holder's
281
+ `--desc` carries today — the view, the ambiguity notice, or whatever a person wrote by hand — the
282
+ next refresh overwrites all of it outright (`backlog task edit --desc`), on both the CLI and
283
+ maintenance step 5b. This is accepted behaviour, not a defect: `board:graph` is a declaration that
284
+ this task's description is machine-owned from now on, so it must never be put on a task whose
285
+ description is worth keeping — see "Accepted risks" below.
180
286
 
181
287
  ## Lane profiles (`lanes.json`)
182
288
 
183
- `scripts/backlog/lanes.json` holds only what Claude Code itself cannot already express (slot
184
- pool, `maxParallel`, `attempts`, `effort`, the direct/sdd model split, the LM Studio health-check
185
- URL, and the close reviewer's model and timeout).
186
-
187
- `lanes.frontier.maxBudgetUsd` is OPTIONAL set a number when the machine authenticates with an
188
- API key and you want a hard dollar stop; omit it on a subscription login, where the estimate is not
189
- billed and the cap only truncates work; `maxTurns` and `timeoutMinutes` are the guards that always
190
- apply. `loadLaneConfig` still validates a DECLARED value — non-numeric or zero throws, same as
191
- every other field — it is absence, not presence, that is unchecked.
192
-
193
- `harnessReviewer` (top-level, T-31) is OPTIONAL too — the human-review mark's reviewer handle (see
194
- "Forbidden paths, split by mechanism" below). It ships UNSET: `gh pr create --reviewer <self>` (and
195
- the equivalent `pr edit`) fails when the reviewer is the pull request's own author, and the
196
- dispatcher opens every PR as the same account. Set it to a second account's handle to actually get a
197
- reviewer assigned; the absence is recorded once on a marked PR rather than treated as an error. A
198
- DECLARED value is validated for its SHAPE, not merely for being a string: a GitHub login (1-39
199
- characters, alphanumerics and single interior hyphens) or an `org/team-slug`. The value becomes an
200
- argv TOKEN in `gh pr edit … --add-reviewer <value>`, and `gh` reads a token starting with `-` as a
201
- FLAG — the same reason `resolveTestCommand` anchors its `--filter`/`--dir` values on a non-dash first
202
- character.
203
-
204
- `maxParallel` (per lane) and `attempts` (global) are the dispatcher's two caps, and they are LIVE:
205
- `launch.ts`'s `dispatchLimitsFrom` turns the loaded config into the object guard 5, guard 6 and
206
- `acquireSlot` all read. Editing either number in this file changes what the dispatcher does on the
207
- next pass. There is no `bare` field: the local lane is always `--bare` and the frontier lane never
208
- is — that is a property of what each lane IS, not a knob, and a knob that could not be turned only
209
- told its reader a lie.
210
- Everything Claude Code DOES already understand — `model`, `env`, `permissions` — lives in a
211
- standard settings file per lane (`scripts/backlog/lanes/local.settings.json`,
212
- `scripts/backlog/lanes/frontier.settings.json`), which `launch.ts` READS and translates into the
213
- launch itself — `model` becomes `--model`, `permissions.allow`/`deny` become
214
- `--allowedTools`/`--disallowedTools`, and `env` is injected into the spawn environment. The files
215
- keep Claude Code's own settings shape so they stay readable and reusable, but they are NOT passed
216
- with `--settings`: Phase 1 spike 1.1 measured spawn-env as the injection mechanism that actually
217
- takes effect, with `--settings` kept only as a validated fallback. This split means
218
- **changing the local model is editing one field**: swap `local.settings.json`'s `model` (and the
219
- matching `ANTHROPIC_*` env values) to point at a different LM Studio model id, nothing in
220
- `lanes.json` or any `.ts` module needs to change — the readiness check reads the model id from
221
- `local.settings.json` too, so there is exactly one place to edit. Using Sonnet locally instead of an LM Studio
222
- model is deleting `local.settings.json`'s `env` block entirely.
223
-
224
- `local.settings.json` sets every `ANTHROPIC_DEFAULT_{SONNET,OPUS,HAIKU}_MODEL` to the SAME LM
225
- Studio model id — the local lane only ever runs `tier:minor`, so there is no direct/sdd split to
226
- alias differently, but a sub-agent spawned inside the local worker that happens to ask for "opus"
227
- must still resolve to the one model actually loaded. `frontier.settings.json` carries `env: {}` —
228
- the cost knob, empty because the lane runs on the account — plus the lane's whole explicit `allow`
229
- list and its `deny` list; it declares no `model`, because `launch.ts`
230
- resolves that from the task's `path:` label (`path:direct` → Sonnet, `path:sdd` → Opus, matching
231
- `catalyst-delegation`'s model table) and passes it as `--model`, which would always beat a value in
232
- the file.
233
-
234
- **`--bare` does NOT stop settings loading, so the local lane names its source too.** Measured
235
- (T-5, 2026-09-07): `claude --help` lists what `--bare` skips — hooks, LSP, plugin sync, attribution,
236
- auto-memory, background prefetches, keychain reads, `CLAUDE.md` auto-discovery — and settings files
237
- are not on that list. The launch used to pass `--bare` and no `--setting-sources` at all, on the
238
- reading that the flag covered it; what it actually got was the DEFAULT set, so the USER file, the
239
- PROJECT file and `.claude/settings.local.json` all loaded into the executor. The consequence is in
240
- that attempt's `stream.jsonl`: the worker ran `python3 -c` (writing a file in the MAIN checkout,
241
- outside its slot, and reverting it by hand afterwards), `npx prettier` and `pnpm exec prettier`
242
- through `Bash` — this machine's overlay carries `Bash(python3 -c *)`, `Bash(git *)`, `Bash(pnpm *)`
243
- and ~60 more click-approvals, and the lane grants no such rule anywhere. The launch now passes
244
- `--setting-sources user`, the narrowest value the flag accepts (an empty one is not in the grammar —
245
- the same value the close's reviewer passes), and composes its deny list from that one loaded source
246
- exactly as the frontier lane does: `loadSettingsAllowRules` over the USER file, then
247
- `settingsAllowRulesToDeny` against the whole granted surface, with guard 1b deciding the overlaps
248
- that have no safe answer. `--bare` and `--strict-mcp-config` stay: the prefill cost and the MCP
249
- servers are what they are for. The flag does not cost the lane its credential — measured in the same
250
- probe below, a `--bare --setting-sources user` run authenticated against LM Studio through the lane's
251
- own `ANTHROPIC_BASE_URL`/`ANTHROPIC_AUTH_TOKEN` and completed normally.
252
-
253
- Two things follow, and both are load-bearing. **The `--setting-sources` value and the subtraction
254
- come from one list**, `launch.ts`'s `LANE_SETTING_SOURCES` (`local: user`, `frontier: user,project`):
255
- `settingSourcesFlag` joins it into the flag, `settingsSourcePaths` turns it into the files, so the
256
- flag and the deny list cannot describe different sets. And **guard 1b now runs on BOTH lanes** — it
257
- was frontier-only precisely because of the `--bare` misreading above.
258
-
259
- **A read-only `Bash` command needs no allow rule at all.** Measured with the free local model, from
260
- a temp git repo, `--bare --strict-mcp-config --setting-sources user --permission-mode dontAsk
261
- --allowedTools 'Read'`: a bare `ls` through `Bash` was ALLOWED, with `permission_denials: []`, while
262
- a compound `ls -la; cat a.txt; echo …` was DENIED in the same conditions. So Claude Code auto-approves
263
- a Bash command it can statically read as read-only, whatever the allow list says — which is where the
264
- T-5 run's `find`, `ls`, `pwd` and `grep` came from, not from the overlay. The lane's `--allowedTools`
265
- therefore bounds every WRITE and every non-trivial command, not literally every `Bash` invocation.
266
-
267
- Beyond that, the local lane's `--allowedTools` is its permission surface. It is path-scoped:
268
- `Edit(./**)`/`Write(./**)` rather than bare `Edit`/`Write` (the cwd is the slot), and
269
- the `deny` half additionally refuses `Edit`/`Write` on `.husky/**`, `.claude/**`, `scripts/**`,
270
- `package.json`, `pnpm-lock.yaml`, `node_modules/**` and `.git/**` — everything that GOVERNS or RUNS
271
- the dispatcher itself. The close's `SLOT_EXECUTED_PATHS`/`LOCAL_FORBIDDEN_PATHS` re-check the same paths
272
- against the real diff, because a permission rule that silently fails to match must not be the only
273
- barrier.
274
-
275
- **The `Edit(./**)` spelling is measured, not assumed.** Spike 1.2 had measured a bare relative glob
276
- (`Edit(allowed/**)`) working under `--allowedTools`; whether the `./` prefix matches was left
277
- untested until now. Same probe as above (free local model, temp git repo, `Read` plus the rule under
278
- test, prompt "append the line hello to a.txt using the Edit tool"):
279
-
280
- | Rule under test | Edit allowed? | Evidence |
289
+ `scripts/backlog/lanes.json` holds what Claude Code itself cannot express (slot pool, per-lane caps,
290
+ the direct/sdd model split, the LM Studio health-check URL, the reviewer's model and timeout);
291
+ everything Claude Code DOES understand — `model`, `env`, `permissions` — lives in a standard settings
292
+ file per lane, which `launch.ts` reads and translates into the launch (`model` → `--model`,
293
+ `permissions.allow`/`deny` `--allowedTools`/`--disallowedTools`, `env` the spawn environment).
294
+ These files are read directly, never passed with `--settings`.
295
+
296
+ | | `local` | `frontier` |
281
297
  | --- | --- | --- |
282
- | `Edit(./**)` | yes | tool_result "has been updated successfully", `permission_denials: []`, `a.txt` appended |
283
- | `Edit(**)` | yes | same, `permission_denials: []` |
284
- | `Edit(a.txt)` | yes | same; the run ended `error_max_turns` for an unrelated denied compound `Bash` |
285
-
286
- All three admit an Edit whose `file_path` argument is the ABSOLUTE path inside the cwd, so the
287
- shipped `Edit(./**)`/`Write(./**)` spelling stays it is the one that also states the intent (the
288
- scoping is the slot), and `grantCovers` already normalises a leading `./` on both sides when
289
- comparing it against a loaded rule.
290
-
291
- **A task that must change a dependency cannot be dispatched.** `package.json` (root and every
292
- workspace one the patterns are matched as substrings, so `backend/package.json` is a hit),
293
- `pnpm-lock.yaml` and `node_modules/` are in `SLOT_EXECUTED_PATHS`, so they are refused on BOTH lanes,
294
- declared or not. They are the environment this close runs its own Prettier, barrels lint and
295
- `pnpm test` in: a rewritten `test` script or lockfile is code the dispatcher executes moments later.
296
- The cost is accepted deliberately adding a dependency is a change a person makes in an
297
- interactive session, where the install and its diff are read, not one a headless attempt slips in.
298
-
299
- **The task's own test command is granted per launch, not by a standing rule.** `launch.ts` turns the
300
- task's SNAPSHOTTED `Test command:` the same line `resolveTestCommand` validates for the close
301
- into one `Bash(<command>:*)` rule and appends it, on both lanes. A task that declared none, or one
302
- the allowlist refuses, gets no rule. The rule it replaced (`Bash(pnpm --filter * test*)`) was a
303
- trailing glob that matched any pnpm subcommand whose words happened to line up.
304
-
305
- The local lane carries no standing `pnpm` rule at all, so that grant is its only one. The frontier
306
- lane carries five COMMANDS, and each is shipped as a PAIR of rules rather than one colon-terminated
307
- rule: `Bash(pnpm --filter * test)` + `Bash(pnpm --filter * test *)`,
308
- `Bash(pnpm --filter * exec prettier --check)` + `Bash(pnpm --filter * exec prettier --check *)`,
309
- `Bash(pnpm --filter * exec tsc --noEmit)` + `Bash(pnpm --filter * exec tsc --noEmit *)`,
310
- `Bash(pnpm --filter * db:generate)` + `Bash(pnpm --filter * db:generate *)`, and
311
- `Bash(pnpm --filter * db:check)` + `Bash(pnpm --filter * db:check *)` a frontier orchestrator
312
- writes tests and type-checks across workspaces as it works, and a worker that can only run the one
313
- line its task declared cannot do that. **Why a pair, and never the single `Bash(pnpm --filter *
314
- test:*)` rule this used to be:** measured (T-7, 2026-09-07, Claude Code 2.1.263) a Bash rule that
315
- combines a mid-rule `*` with a trailing `:*` matches NOTHING. `Bash(pnpm --filter * test:*)` never
316
- matched `pnpm --filter aurora-back test`, on either lane, ever; it looked like a working scoped
317
- grant in review and was actually five silent holes. The exact-form half (`Bash(pnpm --filter * test)`)
318
- matches the command with no extra argument; the with-arguments half (`Bash(pnpm --filter * test *)`)
319
- matches it with one or more. See "A mid-rule `*` is a wildcard" further down in this section for the
320
- full measurement. The last two commands are BOTH offline (`catalyst-schema-migrations`): `db:generate` diffs a
321
- workspace's `*.schema.ts` files against its last `snapshot.json`, and `db:check` runs the same
322
- comparison neither ever reaches a real database, so granting them widens no boundary the other
323
- three did not already assume. Each names a `--filter`ed workspace and a fixed verb: no
324
- `pnpm add`/`install`/`dlx`, no bare `pnpm run`, and no `pnpm test:<script>` (the root scripts,
325
- which execute `scripts/**`).
326
-
327
- **Every board access goes through a dispatcher-owned wrapper, never through the `backlog` CLI.**
328
- Under `--permission-mode dontAsk` anything unlisted is denied, so `launch.ts` appends exactly ONE
329
- board rule to `--allowedTools`, on BOTH lanes:
330
- `Bash(npx --loglevel=error tsx <main checkout>/scripts/backlog/worker-edit.ts T-nn:*)`. The read
331
- goes through it too (`--view`, accepted only on its own): a separate `Bash(backlog task view T-nn:*)`
332
- was a prefix like any other, so a command line that merely STARTED with those words matched whatever
333
- followed — a narrow write channel standing next to an open-ended one.
334
-
335
- The raw write was granted in two earlier shapes, and both were wider than they read:
336
-
337
- - a bare `Bash(backlog task edit:*)` let a worker edit, comment on and re-status ANY task on the
338
- board, including moving another one to `Queued` for the dispatcher to pick up;
339
- - one rule per allowed flag (`Bash(backlog task edit T-nn --notes:*)`) fixed the id and the FIRST
340
- flag — but **a permission rule matches a PREFIX and cannot narrow what comes after it**, so
341
- `--notes x --status Done` matched too: the worker could still set its own task to `Done` (the
342
- maintenance sweep then reads a finished task nobody verified) and rewrite the very acceptance
343
- criteria the pre-PR gate and the reviewer judge it against. "Anything else is denied" was never
344
- true of a rule with a trailing wildcard, and the prompt and this README both used to say it was.
345
-
346
- `worker-edit.ts` is the barrier that does not depend on a rule matching, because it reads the WHOLE
347
- argv before anything reaches the CLI: exactly the dispatched task id (taken from `BACKLOG_TASK_ID`
348
- in the worker env, not from the command line — comparing an argument against itself proves nothing),
349
- then one or more of `--check-ac`, `--notes`, `--append-notes` and `--plan`, each at most once, each
350
- with a value that is not itself a flag, and `--check-ac` only with the `#N` the CLI prints — or
351
- `--view` on its own, which forwards to `backlog task view <id> --plain`. Anything
352
- else exits **2** — distinct from the CLI's own 1, so a refusal never reads as a CLI error — with a
353
- message naming what it refused, and writes nothing. On success it forwards to
354
- `backlog task edit <id> <args…>` in the main checkout (`BACKLOG_CWD`).
355
-
356
- The grant names the **main checkout's** copy of the script, never the slot's: the slot's `scripts/`
357
- is a directory the worker could write to if a deny rule ever failed to match, and a barrier the
358
- thing under test can edit is not a barrier. The close's board-integrity gate is the DETECTOR behind
359
- it, for the case where a permission rule silently fails to match anyway.
360
-
361
- **The slot's own `.backlog/` copy is denied outright.** Both lane settings deny
362
- `Edit(.backlog/**)`/`Write(.backlog/**)`, and the close's scope check reports a change there as a
363
- violation on both lanes. Editing the board file directly would reach the criteria the close judges
364
- the attempt against, going around the wrapper entirely.
365
-
366
- **The frontier lane's allowlist is EXPLICIT, written out in `frontier.settings.json`.** It is not
367
- derived from anything: `launch.ts` reads that file's `permissions.allow` and emits it, plus the two
368
- grants the dispatcher itself decides on (the `worker-edit.ts` wrapper and the validated test
369
- command). As shipped:
298
+ | Settings file | `scripts/backlog/lanes/local.settings.json` | `scripts/backlog/lanes/frontier.settings.json` |
299
+ | Model | fixed in the settings file's own `env` (an LM Studio model id) | resolved from the task's `path:` label — `direct` → Sonnet, `sdd` → Opus |
300
+ | `maxParallel` | 1 | 2 |
301
+ | `maxTurns` | 40 | 120 |
302
+ | `timeoutMinutes` | 60 | 90 |
303
+ | `--bare` | yes | no |
304
+ | `--setting-sources` | `user` | `user,project` |
305
+ | Reviewer | `sonnet`, 15 min timeout | none — the AC/DoD gate is the only check |
306
+
307
+ `attempts` (global, both lanes: 3) and `orphanInProgressThresholdHours` (24) are the other two
308
+ top-level `lanes.json` fields. Both `orphanInProgressThresholdHours` and `lanes.local.reviewerTimeoutMinutes`
309
+ are MANDATORY: `lanes.json` is their only source of truth, and `loadLaneConfig` has no code-level
310
+ fallback for either an omitted key is a load-time error, not a silent default. `harnessReviewer`
311
+ (top-level, optional) is the human-review mark's `gh` reviewer handle, unset by default since `gh`
312
+ refuses to assign the PR's own author as reviewer.
313
+ `lanes.frontier.maxBudgetUsd` is optional too: set a number on an API-key login for a hard dollar
314
+ stop, omit it on a subscription login where the estimate is not billed.
315
+
316
+ Both settings files' `env` also carries `DATABASE_MIGRATE_ON_BOOT: "false"`: a slot's backend boot
317
+ (a task's own `test:e2e` `Test command:`) would otherwise apply an unreviewed branch's pending
318
+ migrations straight to the shared dev database, so applying migrations stays a human step on either
319
+ lane.
320
+
321
+ **`--bare` does not stop settings loading.** Both lanes name a `--setting-sources` value and load it
322
+ for real the local lane's `user` file, the frontier lane's `user,project` (bringing the project's
323
+ hooks and `.mcp.json`-independent tool set). Whatever loads still brings its own
324
+ `permissions.allow`, and `--allowedTools` ADDS to that rather than replacing it, so the launch also
325
+ computes a deny list: every allow rule the loaded sources contribute that the lane's own list does
326
+ not grant is emitted as a `deny`. A loaded rule already covered by a granted one is skipped
327
+ (`grantCovers`); a loaded rule BROADER than a granted one has no safe answer and blocks the task at
328
+ guard 1b instead of being silently denied or silently kept.
329
+
330
+ **A read-only `Bash` command needs no allow rule at all** Claude Code auto-approves a command it
331
+ can statically read as read-only, on both lanes, independent of any settings source. The frontier
332
+ lane's project-hook source additionally vets a wider read-only table
333
+ (`.claude/hooks/auto-allow-readonly-bash.ts`) for the same purpose.
334
+
335
+ **The task's own `Test command:` is granted per launch, never by a standing rule** `launch.ts`
336
+ turns the snapshotted line into one `Bash(<command>:*)` rule on both lanes. **Every board write goes
337
+ through exactly one rule, on both lanes:**
338
+ `Bash(npx --loglevel=error tsx <main checkout>/scripts/backlog/worker-edit.ts T-nn:*)` the grant
339
+ names the MAIN CHECKOUT's copy of the script, never the slot's.
340
+
341
+ ### As shipped: `local.settings.json`
370
342
 
371
343
  ```
372
- Read Grep Glob Edit(./**) Write(./**) Agent Skill TodoWrite
373
- Bash(git status:*) Bash(git diff:*) Bash(git log:*) Bash(git show:*)
374
- Bash(git rev-parse:*) Bash(git symbolic-ref:*)
375
- Bash(openspec:*) Bash(catalyst:*)
376
- Bash(pnpm --filter * test) Bash(pnpm --filter * test *)
377
- Bash(pnpm --filter * exec prettier --check) Bash(pnpm --filter * exec prettier --check *)
378
- Bash(pnpm --filter * exec tsc --noEmit) Bash(pnpm --filter * exec tsc --noEmit *)
379
- Bash(pnpm --filter * db:generate) Bash(pnpm --filter * db:generate *)
380
- Bash(pnpm --filter * db:check) Bash(pnpm --filter * db:check *)
344
+ allow: Read, Grep, Glob, Edit(./**), Write(./**), Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git show:*), Bash(git rev-parse:*), Bash(git symbolic-ref:*), Bash(pnpm --filter * exec prettier --check), Bash(pnpm --filter * exec prettier --check *)
345
+
346
+ deny: Bash(git push:*), Bash(git push*), Bash(git add:*), Bash(git add*), Bash(git commit:*), Bash(git commit*), Bash(git restore:*), Bash(git restore*), Bash(git branch:*), Bash(git branch*), Bash(git clean:*), Bash(git clean*), Bash(gh:*), Bash(gh *), WebFetch, WebSearch, Edit(.backlog/**), Write(.backlog/**), Edit(.husky/**), Write(.husky/**), Edit(.claude/**), Write(.claude/**), Edit(scripts/**), Write(scripts/**), Edit(package.json), Write(package.json), Edit(pnpm-lock.yaml), Write(pnpm-lock.yaml), Edit(node_modules/**), Write(node_modules/**), Edit(.git/**), Write(.git/**)
381
347
  ```
382
348
 
383
- The file tools are path-scoped to the slot like the local lane's, plus the two tools an orchestrator
384
- needs to BE one (it delegates to sub-agents and reads skills by path) under
385
- `--permission-mode dontAsk` a tool with no allow rule is DENIED, and a lane holding only `Bash` rules
386
- is not a restricted worker, it is a worker that cannot open a file. The commands are what a frontier
387
- orchestrator's job actually needs: inspect the tree it works in (read-only `git` verbs — none of them
388
- stages, commits, moves a branch or discards a file), run the SDD flow (`openspec`), run the generator
389
- (`catalyst`), verify its own work in a workspace (a scoped test, Prettier's `--check`,
390
- `tsc --noEmit`), and evolve a workspace's Drizzle schema OFFLINE (`db:generate`/`db:check` — both diff
391
- `*.schema.ts` against the last `snapshot.json`; neither touches a database, per
392
- `catalyst-schema-migrations`). **No granted command runs a script out of the tree the worker can write to** — no
393
- `node`, `tsx`, `npx`, bare `pnpm run` or `pnpm test:` rule — which is the property that makes the
394
- `Edit`/`Write` allowance over `scripts/**` safe (see the deny section below). `launch.test.ts` holds
395
- that as an assertion over the shipped file, not as a comment.
396
-
397
- It used to be the project's own list, subtracted from: `launch.ts` read `.claude/settings.json`'s 43
398
- `permissions.allow` rules at launch and dropped the dangerous ones by command prefix. The reasoning
399
- was that the rules people maintain should stay one list rather than being copied into a second one
400
- that drifts — but an inherited list is a moving target, and a SUBTRACTION over it reopens with every
401
- rule somebody adds. The filter had to be right about commands that did not exist when it was written,
402
- in a file whose whole purpose is a person approving a command for their OWN interactive session. The
403
- evidence is that file as it stands: `Bash(fd:*)`, `Bash(git restore:*)`, `Bash(git branch:*)`,
404
- `Bash(eslint:*)`, `Bash(npm test:*)` and `Bash(pnpm test:hooks:*)` are all in it, and no prefix in
405
- that filter covered one of them — a finder that reaches `--exec`, two git verbs that discard work and
406
- move branches, and three runners that execute files out of a tree the worker can write to, every one
407
- of them reaching the headless worker past a filter written before they existed. What survives review
408
- now is the list itself, and every rule in it was read once and stays read.
409
-
410
- Both `--allowedTools` and `--disallowedTools` are always emitted on BOTH lanes, even when a list is
411
- empty: `--permission-mode dontAsk` with no `--allowedTools` is unrestricted, not restricted. And the
412
- launch guard asks for CAPABILITIES, not for a non-empty list: `assertLaneGrantsFileAccess` throws
413
- unless the merged allow list carries at least one read rule (`Read`) and at least one write rule
414
- (`Edit`/`Write`, bare or path-scoped), and the task is blocked with that reason rather than burning
415
- an attempt on a worker that discovers mid-run it cannot write. "Non-empty" was the wrong
416
- question — 43 `Bash` rules satisfy it.
417
-
418
- **But the launch is not the only source of `allow`.** The frontier lane passes
419
- `--setting-sources user,project`: this worker runs the FULL harness and needs the project's hooks.
420
- The user file also loads; measured on this machine its `enabledPlugins` merely duplicates what the
421
- project file already turns on for every plugin `check-required-setup.ts` requires, so that alone
422
- would not justify loading it. What it uniquely contributes here is its own `hooks`, its
423
- `mcpServers` entry, its `model` override, and the enablement of plugins the project file does not
424
- require (`.mcp.json` is not a settings source and loads regardless). The local lane passes
425
- `--setting-sources user`, because `--bare` does not stop settings loading (see the local-lane section
426
- above) and one source is the least the flag can name. **The click-approval overlay is NOT among them,
427
- on either lane.** `.claude/settings.local.json` is where a person's ad-hoc "yes, allow that" answers
428
- pile up — 61 rules on this machine, `Bash(git *)`, `Bash(pnpm *)` and `Bash(python3 -c *)` among them,
429
- which is every git and every pnpm subcommand including the ones the lane's list deliberately withholds
430
- — and since Claude Code 2.1.211 a worktree reads the MAIN checkout's copy, so a slot would inherit the
431
- lot. A headless worker must never inherit a person's click-approvals, so the file is excluded at the
432
- source: not loaded, therefore nothing to subtract, and no dilemma between revoking a reviewed lane
433
- grant and blocking the task.
434
-
435
- Whatever DOES load still brings its `permissions.allow`, and `--allowedTools` ADDS to what that grants
436
- rather than replacing it. Writing a lane's list out therefore bounds only what the LAUNCH grants; on
437
- the frontier lane the project file's 42 approved rules load with the hooks, and on the local lane the
438
- user file loads alone (it contributes none on this machine — an empty `permissions.allow`). The
439
- layering, in order, on EITHER lane:
440
-
441
- 1. the lane's settings sources load — user, then project on the frontier lane — bringing the project
442
- hooks AND their `permissions.allow`;
443
- 2. the launch adds the lane allow list plus the two per-task grants (the `worker-edit.ts` wrapper,
444
- the validated test command);
445
- 3. the launch denies its static deny list PLUS **every allow rule those loaded sources contribute
446
- and the lane does not grant**;
447
- 4. a deny outranks every allow, whatever its source — so step 3 is what makes step 2 the whole
448
- surface.
449
-
450
- Step 3 is `launch.ts`'s `settingsSourcePaths` + `loadSettingsAllowRules` (the union of the lane's
451
- sources, in load order, deduped) + `settingsAllowRulesToDeny`. Both `settingsSourcePaths` and the
452
- `--setting-sources` value are derived from one per-lane list (`LANE_SETTING_SOURCES`), so the flag and
453
- the subtraction cannot describe different sets. They are read from the DISPATCHER's own checkout — the one every slot is a worktree
454
- of, and the same place the lane settings file comes from — never from the slot. `.claude/settings.json`
455
- is in the close's `SLOT_EXECUTED_PATHS` and the lane denies writing it, but "the file it edited decides
456
- what it may do" is not a property to rest on two other mechanisms holding; and comparing a list from
457
- the slot against a lane list from the checkout would be comparing two different files.
458
-
459
- **"Does not grant" is decided by COVERAGE, not by string inequality**, because a deny is coarse. The
460
- project file's `Bash(openspec status:*)` is already covered by the lane's `Bash(openspec:*)`, so
461
- denying it by spelling would revoke the lane's own grant — and with it the SDD flow this lane exists
462
- to run; `Bash(pnpm --filter aurora-back test:*)` sits inside `Bash(pnpm --filter * test)` the same
463
- way, with the `*` read as a wildcard. A loaded rule the granted list already covers grants nothing new
464
- and is skipped. The reverse overlap has no safe answer: a loaded rule BROADER than a rule the launch
465
- grants — the project file's `Bash(pnpm test:hooks:*)` over a task whose declared test command is
466
- `pnpm test:hooks <file>` — is either denied, revoking the task's own test grant, or kept, handing the
467
- worker a runner that executes files out of a tree it can write to. So the task is BLOCKED
468
- (`permission-conflict`) with both rules in the comment, for a person to resolve: narrow the settings
469
- rule, or the task's test command. That visibility is the point — a permission conflict nobody sees is
470
- the failure mode this whole section exists for.
471
-
472
- **That refusal is guard 1b, not a launch failure.** It is a property of the task and of the settings
473
- files in the dispatcher's own checkout, so it is knowable before anything is taken: `guards.ts`'s
474
- `checkPermissionComposition` runs right after the triage checks, on BOTH lanes (it was frontier-only
475
- while the local lane was believed to load no settings source at all), and the task never reaches slot
476
- acquisition. Deciding it inside `buildLaunch` — as it did until round 10 —
477
- cost a worktree slot, a lock, an attempt directory and a `dispatch-failed` block to report a
478
- conflict that no attempt could have resolved. `settingsAllowRulesToDeny` still throws on it, as the
479
- last-resort invariant behind the guard for a caller that composes a launch without evaluating it, and
480
- both read the same `findPermissionConflict`.
481
-
482
- **The comparison has TWO directions, and they are different questions.** "Is this loaded rule
483
- already granted, so skip it?" is `grantCovers`, and it is deliberately STRICTER than the real matcher:
484
- a false "not covered" only costs a deny for a rule the launch grants anyway, while a false "covered"
485
- hands the worker surface nobody reviewed. "Would a deny for this rule revoke that grant?" is
486
- `denyWouldRevoke`, and it must be exactly as coarse as Claude Code itself — a RAW prefix, `*` as
487
- wildcard, no token boundary, no opinion about shell operators. Asking the strict predicate in the deny
488
- direction was a live bug: the project's `Bash(pnpm test:hooks:*)` over a task declaring
489
- `pnpm test:hooks-extra` read as unrelated, so the launch emitted the deny — and the deny killed the
490
- task's own test grant. A rule that MIGHT revoke a grant is reported as a conflict, never denied.
491
-
492
- Four details of `grantCovers` are load-bearing, because a permission rule is a PREFIX and a prefix
493
- match is not the same question as coverage:
494
-
495
- - **A command candidate must resume at a token boundary and carry no shell operator.**
496
- `Bash(git status:*)` prefix-matches the string `git statusfoo`, which is a different command, and
497
- `git status && fd .`, which is two — the second of them a binary this lane spends deny rules
498
- refusing. Both read as UNCOVERED, so they are denied rather than waved through as "the lane already
499
- grants that".
500
- - **A boundary is a space OR a `:`, and a granted base can supply its own.** `:` separates a pnpm
501
- script from its subcommand, so `Bash(pnpm --filter * test)` covers
502
- `Bash(pnpm --filter aurora-back test:extra:*)`; and a granted base whose trailing boundary was
503
- consumed by its own wildcard (`Bash(git *)` → `git `) has already matched at one, so
504
- `Bash(git status:*)` is covered by it.
505
- - **A path scoping is compared with a leading `./` stripped on both sides.** The lane spells its file
506
- grants `Edit(./**)`/`Write(./**)` because the cwd is the slot, so without that normalization a
507
- loaded `Edit(frontend/**)` read as uncovered — and the deny composed for it would have taken the
508
- worker's write access to `frontend/` away.
509
- - **A scoping that LEAVES the working directory is never covered by one that stays inside it.**
510
- `Edit(/etc/**)` and `Edit(~/notes/**)` are the obvious cases; `Edit(../**)` is the one the `./`
511
- normalization hid, since `..` reads as an ordinary relative glob to a prefix match.
512
-
513
- **A non-covered FILE-tool scoping (`Read`/`Edit`/`Write`) blocks the task only when its deny would
514
- reach inside the slot** — a bare rule (`Edit`), an unscoped glob (`Edit(**)`, `Edit(./**)`), or a
515
- relative one (`Edit(frontend/**)`). A deny on those does not narrow the worker, it stops it opening
516
- files there at all, so the task is blocked for a person instead. A scoping that only reaches OUTSIDE
517
- the slot (`Edit(/etc/**)`, `Edit(~/x/**)`, `Edit(../**)`) is denied like any other rule, which is
518
- precisely what the subtraction is for.
519
-
520
- **A rule's SOURCE is part of the rule, because a path glob is relative to the file that declares it.**
521
- `Edit(**)` in the project file scopes the checkout the worker runs in; the same rule in the USER file
522
- scopes the whole home directory, which the lane has no way to grant — its own `Edit(./**)` is the
523
- slot. So `loadSettingsAllowRules` tags each rule with the source it came from (`user` or `project`,
524
- the first of the two winning when both declare it), and a USER-file path rule with no scoping of its
525
- own (`Edit`, `Edit(**)`, `Edit(./**)`) blocks the task unless the lane grants that tool BARE — the
526
- one grant that does reach outside the slot. Without the tag it read as covered by `Edit(./**)`, an
527
- artefact of the `./` normalization, and the worker got `$HOME` silently.
528
-
529
- What that denies out, measured against the shipped project file — 42 rules loaded, 30 denied, 12
530
- already covered by the lane: `Bash(fd:*)`, `Bash(find:*)`,
531
- `Bash(grep:*)`, the staging/committing/discarding git verbs, `Bash(gh auth:*)`/`Bash(gh pr:*)`,
532
- `Bash(npm run format:*)`, `Bash(npm test:*)`, the three `npx` rules, `Bash(eslint:*)`, the
533
- `pnpm exec` pair, every `Bash(pnpm test:…)` / `Bash(pnpm cli:test:*)` / `Bash(pnpm br:validate:*)` /
534
- `Bash(pnpm hr:lint-barrels:*)` / `Bash(pnpm peers check:*)` runner, `Bash(aurora load:*)`,
535
- `Bash(shasum:*)` and the two `mcp__claude-in-chrome__*` tools. Bash `grep` and `find` go with them:
536
- the `Grep`/`Glob` tools are what this worker reads with, and the read-only Bash hook cannot hand a
537
- denied command back. `launch.test.ts` asserts that outcome over the SHIPPED `.claude/settings.json`
538
- and the shipped lane file — the only loaded source that lives in the repo — so a rule somebody adds to
539
- the project list tomorrow is denied on the next launch with nobody editing `launch.ts`.
540
-
541
- ### Test commands that conflict with the project allow list
542
-
543
- **Over the two loaded sources as they stand, no launch refuses on the LANE list**: nothing in the 42
544
- rules is broader than a lane rule. What remains is per-task, and it is one shape — a declared
545
- `Test command:` that is a NARROWER form of one of the project file's script rules. Five rules in that
546
- file can swallow a task's own test grant, so a task whose test command is `pnpm test:hooks`,
547
- `pnpm test:contracts`, `pnpm test:packager`, `pnpm test:catalyst-regen` or `pnpm cli:test` WITH AN
548
- ARGUMENT is blocked with `permission-conflict` before a slot is taken:
549
-
550
- | Project rule | A declared test command it swallows |
551
- | --- | --- |
552
- | `Bash(pnpm test:hooks:*)` | `pnpm test:hooks scripts/x.test.ts` |
553
- | `Bash(pnpm test:contracts:*)` | `pnpm test:contracts <file>` |
554
- | `Bash(pnpm test:packager:*)` | `pnpm test:packager <file>` |
555
- | `Bash(pnpm test:catalyst-regen:*)` | `pnpm test:catalyst-regen <file>` |
556
- | `Bash(pnpm cli:test:*)` | `pnpm cli:test <file>` |
557
-
558
- Both rules are named in the block comment. **The resolution is per-task: declare a command the
559
- project list does not cover** — the repo's own convention, `pnpm --filter <pkg> test <file>`, which
560
- the lane's `Bash(pnpm --filter * test)` covers outright. Declaring the command exactly as the
561
- project rule spells it (no argument) also clears it, since an identical rule is covered rather than
562
- broader. **Never widen the lane's allow list to clear one of these**: the lane list is the reviewed
563
- surface of EVERY frontier task, and widening it to unblock one task grants that runner to all of
564
- them — a task-shaped problem paid for by every task that follows. (Excluding the overlay is what removed the lane-wide case:
565
- `Bash(git *)` and `Bash(pnpm *)` in it are broader than `Bash(git status:*)` and
566
- `Bash(pnpm --filter * test)`, so while that file was a source, every single frontier launch
567
- refused.)
568
-
569
- **Three assumptions under all of this were documented Claude Code behaviour; one of them has since
570
- been MEASURED, and the measurement corrected it.** The phase-9 end-to-end run (tasks.md 9.7) must
571
- still confirm the other two from `stream.jsonl` on a dispatched frontier task:
572
-
573
- 1. **Deny beats allow from any source.** A command the project list allows and the lane does not
574
- (`fd .`) is refused, and a command the lane grants under a rule broader than the project's
575
- (`openspec list`) still runs. Everything in this section rests on it.
576
- 2. **A mid-rule `*` is a wildcard — but ONLY in glob form, never combined with a trailing `:*`.**
577
- Measured (T-7, 2026-09-07, Claude Code 2.1.263, `claude -p` probes with `--setting-sources user`
578
- and 0 allow rules, `--permission-mode dontAsk`): `Bash(pnpm --filter * test:*)` does **not** allow
579
- `pnpm --filter aurora-back test` — that combination of a mid-rule `*` with a trailing `:*` matches
580
- NOTHING at all, on any command line. The coverage comparison (`grantCovers`) still treats a
581
- mid-rule `*` as a wildcard, and that stays correct for the shape the frontier lane ships instead
582
- of the retired rule: `Bash(pnpm --filter * test)` (exact form, no trailing glob) and
583
- `Bash(pnpm --filter * test *)` (with one or more arguments) — see "The task's own test command is
584
- granted per launch" above. The "12 rules already covered" result below rests on the EXACT-FORM
585
- half of that pair.
586
- 3. **Commands are split before matching.** A compound line (`git status && fd .`) is refused rather
587
- than admitted by its allowed prefix. The comparison assumes this and refuses coverage for a
588
- compound candidate; if the real matcher were to admit one, that assumption is the barrier that
589
- moved.
590
-
591
- **`Bash(catalyst:*)` is a broad grant, and it is a deliberate one.** It is the generator: one
592
- `catalyst generate <bc> <module> --force` rewrites every emitted file of a whole bounded context —
593
- far more than the task's own subject, and with no `.origin` reconciliation on this lane. The lane
594
- grants it because a frontier task that changes a schema cannot do its job without it. Nothing narrows
595
- it at launch: the review is the close's scope check over the real diff, which still stops the
596
- generator from reaching `.claude/settings*.json` or `.backlog/` (the hard list, `SLOT_EXECUTED_PATHS`)
597
- and, regardless of the two lists, the mirror output `packages/cli/src/templates/` — `packages/cli/`
598
- itself and `scripts/backlog/` are the soft list now, so a regen that reaches them is ADMITTED and
599
- marks the pull request instead of failing (see "Forbidden paths, split by mechanism" below) — and
600
- then the PR itself, which is the human gate either way. If a regen's blast radius on a
601
- slot ever needs bounding tighter than that, it is a rule change to argue for with evidence, not a
602
- comment to add here.
603
-
604
- **The effective permission surface on the frontier lane is: the lane allow list, plus the read-only
605
- commands a project hook vets, minus the deny list — where the deny list also cancels the project
606
- allow rules the lane does not grant.** The lane runs the full harness, and the
607
- project's `PreToolUse` hook on `Bash` — `.claude/hooks/auto-allow-readonly-bash.ts` — answers
608
- `permissionDecision: "allow"` for a vetted read-only table (`grep`, `sed -n`, `git log`, `find`
609
- without `-exec`/`-delete`, and the rest of `READ_ONLY_COMMANDS`, refusing redirections, command
610
- substitution, heredocs, path-invoked commands and every write-capable mode). That is deliberate and
611
- kept: an orchestrator needs to READ the repo, and the alternative is one allow rule per binary, which
612
- is the moving target this lane just stopped inheriting. So a read-only Bash command may run here even
613
- though no lane rule names it — and nothing that WRITES or EXECUTES may, because the hook refuses
614
- those and the deny list refuses them again.
615
-
616
- The hook is not the only reason that happens. Measured on the local lane (which loads no hook at all
617
- under `--bare`): with `--allowedTools 'Read'` and nothing else, a bare `ls` through `Bash` was
618
- allowed with `permission_denials: []`, while a compound `ls -la; cat a.txt; echo …` was denied. Claude
619
- Code itself auto-approves a Bash command it can statically read as read-only. The hook's value is that
620
- it is the vetted table we OWN — but "no allow rule names it, therefore it cannot run" was never true
621
- of a read-only command on either lane.
622
-
623
- **A deny rule is what holds regardless of source.** A deny outranks any allow rule, from the lane
624
- file, from whatever settings the harness loads, or from a hook answering `allow` — which is why the
625
- list below keeps rules the lane's own allowlist no longer contains.
626
-
627
- **The frontier deny list is the local one minus two documented allowances.** Both lanes deny
628
- `Bash(git push:*)`/`Bash(git push*)` and `Bash(gh:*)`/`Bash(gh *)` (each in both spellings, because
629
- they match different command shapes and a rule that fails to match denies nothing), `WebFetch`,
630
- `WebSearch`, and `Edit`/`Write` on `.backlog/**`, `.husky/**`, `node_modules/**`, `package.json`,
631
- `pnpm-lock.yaml` and `.git/**` — the board, and everything that governs or runs the dispatcher
632
- itself. The frontier list adds the git verbs that stage, commit, move a branch or throw work away
633
- (`git add`, `git commit`, `git restore`, `git branch`, `git clean` — the close is what commits and
634
- pushes, and `restore`/`clean` destroy the very work it is about to save) and the two file finders
635
- that can execute what they find (`find`, `fd`), each in both spellings.
636
-
637
- `Edit`/`Write` on `.claude/**` and `scripts/**` are the two allowances: a frontier task may
638
- legitimately edit a skill or the tooling, which is part of why it runs on the wider lane at all —
639
- and the lane's narrowed denials below carve the dangerous corners back out, with the close's hard
640
- list (`SLOT_EXECUTED_PATHS`) re-checking both `.claude/settings*.json` against the real diff
641
- regardless of what the permission rule matched. `scripts/backlog/` is SOFT now (T-31) — admitted, and
642
- marking the pull request for human review, rather than re-checked as a violation.
643
- `scripts/**` stays writable, and it is safe BECAUSE no granted command
644
- executes it: the allow list carries no `node`, `tsx`, `npx`, `pnpm test:` or bare `pnpm run` rule, so
645
- the pair is a permission to EDIT a script, never to run one — with two exceptions the CLOSE creates,
646
- not the worker: `scripts/packager/` (spawned by the mirror regeneration) and `scripts/harness-rules/`
647
- (run by the barrels lint), which is why both are on the close's hard list. `launch.test.ts` compares
648
- the FULL deny lists against that allowance set, so the wider lane can never again be guarded less by
649
- omission.
650
-
651
- Those allowances are NARROWED, not blanket. The frontier lane replaces the local lane's `.claude/**`
652
- deny with the executable corners of that directory plus BOTH settings files and the instruction
653
- files: `Edit`/`Write` on `.claude/hooks/**`, `.claude/scripts/**`, `.claude/settings.json`,
654
- `.claude/settings.local.json`,
655
- `CLAUDE.md` and `**/CLAUDE.md` (and the `Claude.md`/`claude.md` casings, since macOS is
656
- case-insensitive while a permission glob compares the spelling it was given). The reason is that the
657
- harness EXECUTES the first two inside the slot: the project's `PostToolUse` hook runs
658
- `$CLAUDE_PROJECT_DIR/.claude/hooks/format-with-prettier.ts` after every Write/Edit, and
659
- `CLAUDE_PROJECT_DIR` is the slot the worker is writing to — so a hook written there runs as the
660
- worker on its very next edit, past every other rule; `.claude/scripts/` runs the same way from
661
- `SessionStart`. `.claude/settings.json` is the file this very launch READS to compose its deny list,
662
- and the project settings source the worker itself loads — the one place where "the file it edited
663
- decides what it may do" would be literally true; `.claude/settings.local.json` is the same surface —
664
- hooks and permissions — and the file Claude Code reads LAST, so a rule written there outranks the one
665
- it overlays. `.claude/hooks/**`, `.claude/scripts/**` and both settings files are in the close's HARD
666
- list (`SLOT_EXECUTED_PATHS`) too, so the real diff is checked on BOTH lanes even if a permission rule
667
- fails to match — and `.claude/settings.local.json` needed its own entry there, because the matcher
668
- compares substrings and `.claude/settings.local.json` does not contain `.claude/settings.json`.
669
- `CLAUDE.md` is what the next reader (the next dispatched worker on this slot included) treats as law,
670
- and it is the one entry on the hard list the harness READS rather than executes: it is in
671
- `SLOT_EXECUTED_BASENAMES`, refused at close on BOTH lanes and blocked in the queue by guard 1c — see
672
- the list section for the two measured mechanisms (the local lane's AI reviewer reads it, and a failed
673
- attempt's copy is restored into the slot for the retry's executor to read). A skill under
674
- `.claude/skills/` and a tool under `scripts/` (outside `scripts/backlog/`) stay editable — that is
675
- the allowance the wider lane exists for, and `.claude/` read as INSTRUCTIONS is the gap the list
676
- section records by name.
677
-
678
- The frontier lane additionally denies the raw board write on BOTH surfaces it could reach —
679
- `Bash(backlog task edit:*)` / `Bash(backlog task edit *)` and the
680
- `mcp__backlog__task_{edit,create,complete,archive}` tools. The launch also passes
681
- `--strict-mcp-config` (T-24), the same flag the local lane and `reviewer.ts` already pass. Measured
682
- 2026-09-09 (`claude -p "ok" --output-format stream-json --verbose --max-turns 1 --model haiku`,
683
- reading the `system`/`init` event): without the flag, the frontier worker's init event listed 101
684
- tools, 68 of them `mcp__*`. `mcp_servers` declared six entries (chrome-devtools, context7, backlog,
685
- spartan-ng-mcp, angular-cli, thesvg), but only four actually supplied a tool — chrome-devtools 29,
686
- backlog 20, spartan-ng-mcp 14, angular-cli 5, summing to the 68 — while context7 was `status:
687
- "failed"` and thesvg `status: "pending"`, neither contributing one. With the flag: 30 tools, 0 of
688
- them `mcp__*`, no declared servers at all. No rule in `frontier.settings.json` grants any `mcp__*`
689
- tool, so those 68 tools were loaded only to be denied by omission under `--permission-mode dontAsk`
690
- — the flag removes that dead weight at the source. The `mcp__backlog__task_*` deny rules above stay
691
- regardless: with the MCP servers no longer loaded at all, they are defence in depth rather than the
692
- active barrier, so the protection does not depend on a single flag. A write reachable by either
693
- route re-statuses the task or rewrites the criteria the close judges it against.
694
-
695
- **The frontier lane also denies eleven personal claude.ai connector servers.** At the time (T-3,
696
- 2026-09-07), the frontier worker's init event had listed 152 tools, including
697
- `mcp__claude_ai_Gmail__*`, `mcp__claude_ai_Notion__*`, `mcp__claude_ai_Linear__*`,
698
- `mcp__claude_ai_Asana__*`, `mcp__claude_ai_Atlassian__*`, `mcp__claude_ai_Box__*`,
699
- `mcp__claude_ai_Canva__*`, `mcp__claude_ai_Figma__*`, `mcp__claude_ai_HubSpot__*`,
700
- `mcp__claude_ai_Intercom__*` and `mcp__claude_ai_monday_com__*` — loaded through the account login
701
- rather than through any settings file this launch reads, the same way `.mcp.json` "is not a settings
702
- source and loads regardless" (see Lane profiles above). That is a historical record of that one
703
- measurement, not a description of what loads today — a headless worker must never reach a person's
704
- mail or project-management tools regardless of what any given flag happens to load, so each
705
- connector's whole server is denied by name using the shape Claude Code documents for an MCP
706
- server-level spec (`mcp__<server>`, `mcp__<server>__*` or `mcp__*` remove every tool from the named
707
- server, or from all servers) — there is no glob that spans multiple distinct server names, which is
708
- why the eleven are spelled out rather than matched by a shared `claude_ai_` prefix. A deny rule
709
- holds regardless of source (see above), so it denies the connectors whichever mechanism loaded
710
- them.
711
-
712
- These eleven deny rules stay even now that the launch also passes `--strict-mcp-config` (T-24):
713
- they are deliberate defence in depth, so the protection does not depend on a single flag. Whether
714
- `--strict-mcp-config` would ALSO have kept these specific connectors from loading is UNVERIFIED —
715
- the T-24 probe measured above ran in a shell where an auth source (`ANTHROPIC_API_KEY` or another)
716
- had already disabled claude.ai connectors, taking precedence over the claude.ai login T-3 used, so
717
- T-24's probe could not observe these eleven loading or not loading either way; T-3 above is the
718
- only probe that ever observed them load. Do not read the T-24 measurement above (six declared
719
- servers, four of which supplied tools, none of them a personal connector) as evidence on this
720
- question; it ran in a different shell than T-3's.
721
-
722
- **The frontier worker gets a system prompt of its own.** It runs the harness, so it reads `CLAUDE.md`
723
- — which describes an INTERACTIVE session and says nothing about `worker-edit.ts`. Launched without
724
- one, the worker reached for `backlog task edit`, was denied, and finished with every acceptance
725
- criterion unticked, which the close's AC gate then failed it for, every time. `prompt.ts`'s
726
- `buildFrontierAddendum` renders `.claude/skills/catalyst-backlog/frontier-worker-addendum.md` — the
727
- template — into `.backlog/.dispatch/<id>/intento-N/frontier-addendum.md`, filling in the task id and
728
- the wrapper command bound to it, and the launch passes THAT path to
729
- `--append-system-prompt-file`. It carries only the facts `CLAUDE.md` cannot, because it describes an
730
- INTERACTIVE session: which directory it works in (its slot, named in full, with the main checkout
731
- named as the tree it must never touch — `{{SLOT_PATH}}`/`{{MAIN_CHECKOUT_PATH}}`, rendered per
732
- attempt like the wrapper command);
733
-
734
- **Both lanes' `--append-system-prompt-file` path is ABSOLUTE, under the main checkout.** The frontier
735
- lane's rendered addendum always was (it is written into `.backlog/.dispatch/…`); the local lane's
736
- static `worker-system-prompt.md` was a RELATIVE path until T-31 round 3, and `launch.ts` spawns the
737
- executor with `cwd` = the SLOT — so the worker's own brief was read from the tree the worker writes.
738
- `resolveWorkerSystemPromptPath` (`dispatch.ts`) resolves it against `repoRoot` instead, which closes
739
- the channel rather than watching it: `--bare` does not close it (the flag is explicit on the command
740
- line), and the two mechanisms that happened to bound it — the local lane's `.claude/**` deny and the
741
- `.claude/` entry in `LOCAL_FORBIDDEN_PATHS` — are exactly the "one mechanism is not enough" shape the
742
- hard list exists for.
743
-
744
- The invariant is ASSERTED where the argv is built (`buildLaunch`, round 4): a relative value throws and
745
- aborts the launch, which releases the slot and blocks the task. Resolving it in one of the two producers
746
- and asserting nothing at the point of use left the property untested — the two lanes compute the value
747
- differently, and the property belongs to the flag, not to either computation.
748
-
749
- The addendum also covers: running its test command EXACTLY as declared, with no pipes,
750
- `&&`, redirections or `cd` (T-3: a worker piped one through `grep`/`tail` and was denied — Claude
751
- Code evaluates each segment of a compound line separately, and the close runs the same bare command
752
- again anyway); the dispatcher already set the task `In Progress` and the worker never writes the
753
- status; the four wrapper flags and the fact that an unchecked criterion blocks the attempt; that the
754
- task's `path:` label is BINDING, not a recommendation — `path:sdd` runs the SDD flow
755
- (`/opsx:propose` then `/opsx:apply`, Automatic mode) before any code change, `path:direct` takes the
756
- direct path with the tier's gates, and `CLAUDE.md`'s interactive "recommend SDD and let the user
757
- choose" rule cannot apply headless, because there is no user to choose (T-3 measured a worker read
758
- that rule and implemented directly under `path:sdd` anyway, with no `openspec/changes/<name>` ever
759
- created); that a diff touching the security surface (`o-auth/`, `iam/`, a guard, `@Auth`, secrets or
760
- env config, a new public endpoint, an upload, a raw query, crypto/token/session handling) still gets
761
- a `/security-review` pass before finishing, reported in the task notes, exactly as the root
762
- `CLAUDE.md`'s security gate requires (the same T-3 run edited `backend/src/@app/iam/**` with no
763
- such pass — that gate has no person to trigger it headless either); a gate needing a person ends the
764
- run as `needs-guidance` (the close is what moves the task to `Blocked`); and no `git`, `gh`, or
765
- install.
766
-
767
- **Both prompts name the working directory, because the worker cannot infer it.** Measured (T-5,
768
- 2026-09-07): the local executor's FIRST `Edit` targeted the MAIN checkout's copy of the file it had to
769
- change, not its slot's. It had taken the repository root off the `File: …/.backlog/tasks/t-5 …` line
770
- of the task block — the board lives in the main checkout — and nothing in the envelope said where it
771
- actually was. `Edit(./**)` denied it, correctly (the cwd is the slot), so the attempt spent turns
772
- being refused a path nobody had told it about. The local envelope now opens, immediately after the
773
- task text, with the slot path, "every path in this task is relative to it", the main checkout named as
774
- a tree it must never read, edit or run anything in, and the reason the confusion arose ("the board
775
- file path shown in the task block lives in the main checkout; do not treat its directory as your
776
- repository root"). The frontier addendum carries the same block. A permission rule is the barrier;
777
- this is what stops a worker walking into it.
778
-
779
- **Cost knob:** `ANTHROPIC_DEFAULT_OPUS_MODEL` is the value to change if Opus-priced frontier work
780
- gets too expensive — set it in `frontier.settings.json`'s `env` (currently empty) to redirect
781
- every internal "opus" alias to a cheaper model without touching `launch.ts`'s path-to-alias logic
782
- at all. On the local lane this same key is already set (to the local model id) for the reason
783
- above.
349
+ Plus, per launch: the `worker-edit.ts` wrapper rule and the task's own `Test command:` rule. The
350
+ local lane carries no standing `pnpm` test/build rule of its own the task's own grant is its only
351
+ one.
784
352
 
785
- ## The close: what actually gates a PR
353
+ ### As shipped: `frontier.settings.json`
786
354
 
787
- **The first step is not mechanical at all: the board still has to describe the task that was
788
- launched** (`checkBoardIntegrity`). The worker can write to its own task for its whole run it
789
- must, since the wrapper is its only channel for ticking criteria — so the close re-reads the task and
790
- compares it against the snapshot taken at launch. The wrapper is the BARRIER; this gate is the
791
- DETECTOR behind it, for the case where a permission rule silently fails to match anyway:
792
-
793
- - the status must still be `In Progress`. A worker that set itself to `Done` gets a maintenance
794
- sweep reading a finished task nobody verified; one that set itself to `Queued` gets dispatched
795
- again by the next pass while this close is still running. Anything else fails the attempt with
796
- `status-changed-by-worker`.
797
- - the acceptance-criteria and Definition-of-Done TEXTS must be unchanged (`ac-tampered` otherwise).
798
- Only the texts: the CHECKED state is exactly what the worker is supposed to change. The pre-PR
799
- gate and the reviewer both judge the attempt against those criteria, so a criterion rewritten
800
- into something the attempt can meet is a gate the thing under test authored itself.
801
- - the **title**, the declared **`Files to touch:`** and the declared **`Test command:`** must be
802
- unchanged too, same `ac-tampered` reason. They are the rest of the contract the attempt is judged
803
- against — the title names the PR, the declared files are the allowlist the scope check runs, and
804
- the test command is what the triad executes — and all three are description text a board write can
805
- reach. The message attributes the drift to "worker o persona" and lists the differences: a person
806
- editing the board mid-attempt produces exactly the same drift, and the remedy is the same either
807
- way (re-queueing re-takes the snapshot).
808
-
809
- It runs FIRST because every step after it trusts the board: the scope check reads the declared
810
- files, the triad the test command, the gate and the reviewer the criteria.
811
-
812
- ### Forbidden paths, split by mechanism (T-31)
813
-
814
- The scope check (`checkScope`, `guards.ts`/`close.ts`) reads two path lists, split by ONE mechanical
815
- question: **does this file execute inside the slot during the attempt or the close?**
816
-
817
- - **`SLOT_EXECUTED_PATHS`** (hard, `guards.ts`) — the harness's own settings and its local overlay
818
- (`.claude/settings.json`, `.claude/settings.local.json`), the hook and script directories the
819
- harness runs after every edit (`.claude/hooks/`, `.claude/scripts/`), the version-control hooks the
820
- close's own commit runs (`.husky/`), the package manifest, the lockfile and the installed
821
- dependency tree the close runs Prettier, the barrels lint and the task's own test command with
822
- (`package.json`, `pnpm-lock.yaml`, `node_modules/`), the board directory holding the criteria the
823
- attempt is judged against (`.backlog/`), and the two script directories the close SPAWNS from
824
- inside the slot: `scripts/packager/` (the `mirrorRegen` step runs `node
825
- scripts/packager/publish.mjs` there, and that script GLOBS `monorepo.mjs`, `backend/*.mjs` and
826
- `frontend/*.mjs` inside its OWN directory — derived from `import.meta.url`, so the slot's copy —
827
- and spawns every match with the dispatcher's inherited environment) and `scripts/harness-rules/`
828
- (the triad runs `pnpm hr:lint-barrels`, which the root `package.json` maps to `tsx
829
- scripts/harness-rules/lint-barrels.ts`; the manifest being hard protects the script NAME, not the
830
- file it points at). Refused on BOTH lanes, whether or not the task declared it — and blocked in the
831
- QUEUE before a slot is ever taken, by guard 1c (`checkDeclaredSlotExecutedPath`), when a task
832
- DECLARES one, including when it declares a DIRECTORY whose subtree contains one.
833
-
834
- A declaration is read as reaching the list both when it lies UNDER a listed path and when it is a
835
- DIRECTORY that contains one, with or without the trailing slash: `- .claude` and `- .claude/` both
836
- reach `.claude/settings.json`. The containment direction matches on a segment boundary, so a bare
837
- textual prefix is not a declaration of what it prefixes (`- package` names `package/`, not
838
- `package.json`).
839
-
840
- **Four** things the close reaches inside the slot are deliberately NOT on this list, recorded in
841
- `openspec/changes/split-dispatcher-forbidden-paths/design.md` decision 1 rather than left silent:
842
-
843
- - the slot's own `.git/` directory — its hooks really do run, but no `diff`/`status` output ever
844
- reports a path inside it, so a list entry could never be enforced;
845
- - `.claude/` read as INSTRUCTIONS on the frontier lane — `skills/`, `rules/`, `agents/`,
846
- `commands/`. The executor reads them; no close step executes them. They are on neither list, so
847
- a frontier attempt can rewrite its own skills and neither the pull request nor the `Blocked`
848
- comment says so. This is the gap with a live self-instruction consequence, and it is wider than
849
- it looks: a failed attempt's tree is pushed to `task/<id>` and RESTORED by the retry's
850
- `checkout -B` (see the soft list below), so what attempt 1 writes there is what attempt 2's
851
- executor boots reading. Widening the criteria into a soft PATH list for `.claude/` is a
852
- follow-up;
853
- - the drift-check workflow the mirror step parses — a worker can only cost itself the attempt with
854
- it, never gain privilege;
855
- - the task's declared `Test command:` — the standing hole this dispatcher has always had, and the
856
- mechanism that makes "inert during the attempt" untrue of ANY path (below).
857
- - **`SLOT_EXECUTED_BASENAMES`** (hard, `guards.ts`) is the basename half of the hard list, and holds
858
- one entry: `CLAUDE.md`, matched by file name at any depth and case-insensitively. Refused at close
859
- on BOTH lanes and blocked in the queue by guard 1c, for two measured reasons. First, the local
860
- close runs an AI reviewer over the attempt's own diff, spawned with `cwd` = the slot, and
861
- `buildReviewerCommand` (`reviewer.ts`) does NOT pass `--bare` — the one flag that turns
862
- instruction-file auto-discovery off, and one the reviewer cannot take, because under `--bare`
863
- authentication is strictly `ANTHROPIC_API_KEY`/`apiKeyHelper` and `reviewerEnv()` strips every
864
- `ANTHROPIC_*` key: an instruction file the local executor writes is read as instructions by the
865
- judge of that same attempt. Second, on EITHER lane an instruction file written by attempt N is read
866
- by attempt N+1's executor — the failure plan opens no pull request at all, so no PR mark is applied,
867
- yet `saveWipAndPush` commits the whole slot tree to `task/<id>` and the retry's `prepareSlot` runs
868
- `checkout -B task/<id> origin/task/<id>` and restores it. A mark that only exists on the green path
869
- is not a control over a file that survives the failing one. Nothing else covers this file: the lane
870
- settings grant `Write(./**)` with no `CLAUDE.md` deny, and `.claude/` is not a substring of
871
- `claude.md`.
872
- - **`HUMAN_REVIEW_PATHS`** (soft, `guards.ts`) — the dispatcher's own sources (`scripts/backlog/`)
873
- and the generator package (`packages/cli/`). A soft path is ADMITTED, not refused, and marks the
874
- resulting pull request for human review (see "open-pr reuses the PR" below) instead of failing the
875
- close. On the local lane a soft path still has to be DECLARED to pass — the undeclared-file check
876
- is unchanged — and `scripts/backlog/` stays refused there regardless, because the local lane's
877
- wider `scripts/` extra (below) still catches it.
878
-
879
- **Soft does NOT mean inert**, and the two mechanisms that make it not mean that were measured
880
- directly, so nobody has to rediscover them:
881
-
882
- - a soft-list file CAN be executed inside the slot during the CLOSE. Admitting the diff at
883
- `scope-check` is precisely what unlocks the rest of the success plan, and the triad's last step
884
- spawns the task's own declared `Test command:` with `cwd` = the slot and the dispatcher's
885
- inherited environment. `ALLOWED_TEST_SCRIPT` admits `test:backlog`, which the root manifest maps
886
- to a runner over `scripts/backlog/**` — the SLOT's copies. This is not a privilege the soft list
887
- grants: every dispatched task's test command already runs worker-written code in the slot the
888
- same way (the fourth gap above). It is the reason the classification cannot rest on "nothing
889
- runs it";
890
- - a soft-list edit SURVIVES a failed attempt. `saveWipAndPush` commits and pushes the whole slot
891
- tree to `task/<id>`, and the retry's `prepareSlot` runs `checkout -B task/<id>
892
- origin/task/<id>`, which restores it into the slot. "The slot is hard-reset, so nothing survives
893
- the attempt" holds only for a branch with no such push behind it.
894
-
895
- What justifies the classification is narrower, and does hold: neither entry is read as INSTRUCTIONS
896
- by any process (that is the difference from `SLOT_EXECUTED_BASENAMES` above), and neither is on the
897
- path the dispatcher itself runs from — it runs from the MAIN checkout, the worker's board wrapper
898
- and the board itself live only there, and the generator is never invoked by the close. So the
899
- reachable outcome of editing either one is a test run that behaves differently, which costs the
900
- attempt and is exactly what the mark sends a person to read.
901
-
902
- The mark is not the only record. A FAILED close opens no pull request, so on that path the
903
- `Blocked` comment names the soft-list files (`BlockDetails.humanReviewFiles`) — otherwise an
904
- attempt that touched the dispatcher's own sources and then failed would leave no trace of having
905
- done so. That holds for EVERY failure shape, and the common ones are the ones with no scope check
906
- behind them: a MECHANICAL step's failure diverts a plan that already ran `scope-check`, so the files
907
- are already known, while a SESSION-level failure (`needs-guidance`, a timeout, an exhausted budget,
908
- a crash) plans straight to `save-work` and runs no mechanical step at all — and `board-check`, the
909
- one mechanical step ordered BEFORE the scope check, diverts without one too. On any of those
910
- `executeClose` asks the slot itself through the `leftoverFiles` runner (`collectLeftoverFiles`)
911
- BEFORE the WIP commit rewrites the tree; the probe is keyed on "has anything classified this tree
912
- yet", not on the plan's shape, so no future step ordering can reintroduce a divert that records
913
- nothing.
914
-
915
- That probe carries no verdict, but it does CLASSIFY — with `classifyChangedPaths`, the same function
916
- `checkScope` reads, per lane. It returns two buckets, and the `Blocked` comment renders them as two
917
- separate lines because they ask a person for opposite things: a soft-list leftover has to be READ,
918
- and a refused one (a hard-list path, or the mirror output) has to be REMOVED before the retry
919
- restores it. T-31 round 3 filtered the tree through the soft list alone, which reported a
920
- `packages/cli/src/templates/…` path as a soft-list file the close admits — the one prefix refused on
921
- both lanes — and said nothing at all about `.claude/settings.json`. A `git` failure in the probe is
922
- logged rather than allowed to fail an already-failed close.
923
- - **The mirror output** (`packages/cli/src/templates/`, `MIRROR_OUTPUT_PREFIX` in `close.ts`) stays
924
- refused on BOTH lanes regardless of the split — see "the CLI scaffold mirror is regenerated" below.
925
- It is dispatcher-owned output the close itself writes, not a worker's writing surface, and it is
926
- checked FIRST, before the two lists above: `packages/cli/src/templates/monorepo/scripts/backlog/
927
- close.ts` matches both the mirror prefix and the soft `packages/cli/` pattern, and the mirror
928
- prefix must win or a hand-written mirror edit would silently become a marked PR instead of a
929
- violation.
930
- - **`LOCAL_FORBIDDEN_PATHS`** (`guards.ts`) is `SLOT_EXECUTED_PATHS` plus the local lane's own three
931
- path extras — `.claude/`, `scripts/` and `.git/` — unchanged by the split. They are matched as
932
- substrings, so `scripts/` also catches `scripts/backlog/dispatch.ts` even though that entry is soft
933
- everywhere else: a soft path is not automatically admissible on the local lane, and being declared
934
- was never sufficient for a local-lane extra either.
935
-
936
- A pull request marked for human review carries FOUR halves, deliberately unequal (design.md
937
- decision 8), and exactly ONE of them cannot fail:
938
-
939
- 1. **the body section on a NEW pull request** — part of the `gh pr create` argv, so it either creates
940
- the PR with the section or creates no PR at all. This is the unfailable half, and the reason the
941
- mark does not rest on the three below;
942
- 2. **the body section on a REUSED pull request** (a retry pushing to a branch that already has an
943
- open PR): there is no `gh pr create` on that path to carry it, so the close applies it with its
944
- own `gh pr edit --body` — best-effort;
945
- 3. **the `harness-review` label**, a separate `gh pr edit` after the PR exists — best-effort;
946
- 4. **the reviewer handle**, when `lanes.json` configures one, another separate `gh pr edit` —
947
- best-effort.
948
-
949
- Best-effort means exactly this: the failure is logged with its reason and never fails the close,
950
- blocks the task, or discards the pull request. Halves 2-4 are best-effort; half 1 is not, because
951
- there is nothing left to fail once the PR exists with the body it was created with.
952
-
953
- The rewrite walks the body once and drops each dispatcher-authored region — every full marker pair,
954
- a trailing START with no END (a section a failed write truncated), and any stray END — writing the new
955
- section where the FIRST one was and keeping every byte between the regions. Round 3 spliced from the
956
- first START to the LAST END, which on a body holding TWO full pairs swallowed everything between them,
957
- a person's note included; that is the shape the pre-round-3 code produced on every retry, so open pull
958
- requests already hold it. The result always holds exactly one well-ordered pair, which makes the next
959
- rewrite the ordinary case again.
960
-
961
- The reuse rewrite READS the body first (`readPrBody`) and replaces only
962
- its own delimited section (`upsertHumanReviewSection`, marked with
963
- `<!-- dispatcher:human-review:start -->`/`…:end -->` HTML comments): `gh pr edit --body` is a full
964
- replacement, and these are by construction the pull requests a person was asked to read and
965
- annotate, so recomposing the body from the board destroyed every word that person had added. A body
966
- that cannot be READ is not overwritten at all — the rewrite is skipped and recorded, since with no
967
- idea what is there the safe move is to leave it. The file list any mark renders is capped on TWO
968
- budgets — the entry count (`MAX_MARKED_FILES`) and the total characters (`MAX_MARKED_LIST_CHARS`,
969
- with each path capped at `MAX_MARKED_PATH_CHARS`) — with a count of what it dropped, the same
970
- discipline `sanitizeCommentBody` carries for the worker-authored notes section beside it: the list
971
- comes from the attempt's own diff, and a wide refactor produces hundreds of entries in a public body
972
- and in the `gh` argv. Each path is also RENDERED rather than spliced verbatim (`renderMarkedPath`):
973
- paths reach the close straight out of `git diff -z`, so `<`/`>` are escaped — a filename spelling the
974
- section's own end marker would otherwise put a second marker inside the list and send the next
975
- rewrite's `indexOf` to the wrong offset — and control characters become `?`, so one changed file
976
- always renders as one entry. ONE rendering serves both channels, deliberately: the escapes render back
977
- as `<`/`>` on GitHub and show up literally (`&lt;`) in a `Blocked` comment read through
978
- `backlog task view --plain`, and a second channel-aware renderer would mean two code paths over
979
- worker-supplied bytes for a cosmetic gain — the escaped spelling still identifies the file. The
980
- label is a SEPARATE call from `pr create` on purpose — a label the repository does not have would
981
- otherwise fail the PR creation itself — and separate from the reviewer call too, so a rejected
982
- reviewer never takes the label down with it. The reviewer's rejection is the EXPECTED case, not the
983
- exception: `gh` refuses a reviewer that is the pull request's own author, and the dispatcher opens
984
- every PR as the same account — so `harnessReviewer` ships unset in `lanes.json`, and its absence is
985
- recorded once rather than treated as an error.
986
-
987
- The mechanical triad is **scoped to the attempt's own changed files** — the union of
988
- `git diff --name-only -z <base>...HEAD` and
989
- `git status --porcelain -z --untracked-files=all` — `-z` on BOTH halves, because either line format
990
- otherwise quotes and C-escapes a path holding a space, a quote, a backslash, a newline or a
991
- non-ASCII byte, and the string then compared against the path lists is not the path on disk. The
992
- measured consequence: a quoted `packages/cli/src/templates/…` misses the anchored mirror prefix while
993
- still matching the unanchored soft `packages/cli/` pattern, so a hand-written mirror edit would be
994
- admitted and merely marked — the mirror-first precedence inverted. `-c core.quotepath=false` was the
995
- first fix and it is not enough: that option governs only the non-ASCII half of the class. On the
996
- status side a rename is one entry carrying two NUL-separated paths, and only the new one is a file
997
- the attempt produced. The mirror prefix itself is matched case-insensitively, like every sibling
998
- matcher, since a casing variant names the same file on this repo's filesystem:
999
-
1000
- - **Prettier**, two runs per workspace that ships it (`backend/`, `frontend/`, `packages/core-back/`,
1001
- `packages/core-front/`): `pnpm --filter <pkg> exec prettier --write --ignore-unknown <files>`, then
1002
- the same with `--check`. design.md decision (h) puts the format hook in the close "where a
1003
- deterministic script ENFORCES them" — a bare `--check` only reports, and the executor is never
1004
- asked to run Prettier, so an indentation nit failed a whole attempt over something the close can
1005
- fix in place. The `--check` after the write is not redundant: it is what proves the write actually
1006
- took (a syntax error makes Prettier rewrite nothing). Prettier is NOT a root dependency here — `npx
1007
- prettier` at the repo root exits 127 — so a repo-wide run was a check that could never pass. A
1008
- changed file outside those four workspaces (`scripts/`, `.claude/`) has no formatter to run and is
1009
- reported in the log, not silently treated as formatted. `--ignore-unknown` is measured (T-6.1,
1010
- first real frontier dispatch): a `.sql` file with no inferrable parser otherwise exits Prettier 2
1011
- ("No parser could be inferred"), failing the whole triad over a file Prettier was never going to
1012
- format. A drizzle-kit migration folder
1013
- (`backend/src/database/migrations/drizzle/<folder>/{migration.sql,snapshot.json}`) is excluded
1014
- from BOTH runs entirely rather than merely ignored: it is tool OUTPUT, not hand-written code, the
1015
- repo's shipped `snapshot.json` files are not Prettier-formatted (measured: `--check` warns on every
1016
- one, 432 KB each), and a `--write` would turn a generated artifact into a huge noise-only diff.
1017
- - **Barrels lint**, `pnpm hr:lint-barrels <files>`, over the changed `.ts` files under the roots
1018
- HR-BARRELS actually governs. Scoped for the same reason: `pnpm hr:lint-barrels` with no arguments
1019
- sweeps the whole repo, which is red on `main` today for pre-existing violations in generated
1020
- frontend code — an unscoped run would blame every attempt for someone else's diff.
1021
- - **The task's own `Test command:`**, which is MANDATORY — guard 1 refuses to dispatch a task that
1022
- declares none, on either lane, and the pre-PR gate refuses to pass one whose "scoped tests pass"
1023
- item is still unticked (the triad ticks it only when a test actually ran and passed). The accepted
1024
- grammar is the repo's own convention and nothing else:
1025
-
1026
- ```
1027
- pnpm [--filter <pkg> | --dir <relative-path>] [run] <test | cli:test | test:*> [args…]
1028
- ```
1029
-
1030
- Naming `pnpm` was never the permission: `pnpm dlx <package>` is the same fetch-and-execute `npx`
1031
- is refused for, and `pnpm add`/`install`/`exec`/`-C` reach just as far outside this repository. So
1032
- the SCRIPT is allowlisted too, a `--filter` value must be a plain package name (never another
1033
- flag), and the line may contain no shell metacharacter. `--dir` is the alternative selector, for
1034
- `packages/cli` — deliberately NOT a workspace member (root `CLAUDE.md`, D8), so `--filter` matches
1035
- nothing there; its value must be a RELATIVE path with no `..` segment, because a test command may
1036
- only reach inside the slot it runs in. The command is spawned directly, never through a shell.
1037
-
1038
- A line that breaks any rule is refused **before dispatch**: guard 1 runs the same
1039
- `resolveTestCommand` the triad does and blocks the task with the refusal and the offending line,
1040
- so nothing is spawned at all. The validator lives in `guards.ts` for that reason — pre-launch
1041
- validation is upstream of the close, which already reads that module for its security-path list.
1042
- Reaching the close with a refused line means the board changed after launch, and the triad fails
1043
- it there with `test command no permitido`.
1044
-
1045
- The command that runs is the one SNAPSHOTTED at launch (`Task.testCommand`, parsed alongside
1046
- `Files to touch:`), never re-read from the board at close time — the worker can write to its own
1047
- task for its whole run, so a close that re-read the board would run whatever the thing under test
1048
- decided it should be verified with.
1049
-
1050
- Prettier and the barrels linter are both run only over files that still EXIST in the slot. A file the
1051
- attempt deleted is still a changed file, and neither tool can read a path that is correctly gone.
1052
- Both receive their file list after a `--` separator, so a changed path beginning with a dash is read
1053
- as a file and not as a flag.
1054
-
1055
- **Then the CLI scaffold mirror is regenerated, when — and only when — the attempt touched a root the
1056
- packager reads.** `scripts/packager/publish.mjs` mirrors `backend/`, `frontend/` and much of the
1057
- monorepo root into `packages/cli/src/templates/{backend,frontend,monorepo}`, and CI's
1058
- `Check mirror <-> source drift` fails any PR whose committed mirror no longer matches its sources.
1059
- A dispatched worker cannot satisfy that gate itself: the MIRROR OUTPUT
1060
- (`packages/cli/src/templates/`) stays refused on both lanes regardless of the split (T-31) —
1061
- `packages/cli/` itself is soft now, so a worker may legitimately edit the generator, but never its
1062
- own generated mirror — so before this step existed, **any dispatched task touching a mirrored root
1063
- could never pass CI on its own** (measured: PR #96, task T-3, which edited
1064
- `backend/src/@app/iam/**` and `frontend/src/app/domains/admin/apps/iam/**` and failed the gate with
1065
- "The committed CLI scaffold mirror is out of date").
1066
-
1067
- - **Which roots count** is read at close time from the slot's own
1068
- `.github/workflows/cli-template-drift-check.yml` — its `paths:` filter, minus `packages/cli/**`
1069
- (packager OUTPUT, not a source root). That list is not copied into the dispatcher, because
1070
- `scripts/packager/drift-check-paths.test.mjs` already fails when a `copyMonorepo()` glob is
1071
- missing from it: reading the file that is kept in lockstep is one source of truth, a second
1072
- hardcoded copy would be a third thing to drift.
1073
- - **It is conditional.** `publish.mjs` is a repo-wide copy; running it on an attempt that changed
1074
- only a `cliter/*.aurora.yaml` would spend that cost and put a several-thousand-file mirror diff in
1075
- front of the reviewer for nothing.
1076
- - **Where it sits is the whole design.** AFTER the triad, because `prettier --write` rewrites the
1077
- attempt's own source files — a mirror copied before it would be a byte-copy of the unformatted
1078
- source and stale the moment the triad ran. BEFORE the reviewer and the pre-PR gate, because the
1079
- reviewer judges the diff that will actually be pushed. And AFTER the scope check, which is what
1080
- keeps the MIRROR OUTPUT forbidden **to the worker**: the scope verdict is taken over the pre-regen
1081
- file set, so a mirror path the worker wrote by hand is still a scope violation, and the
1082
- dispatcher-owned output only appears once the judging is done. There is no exemption in
1083
- `checkScope` at all — the ordering is the exemption.
1084
- - The regenerated files stay in the working tree and travel in the attempt's own commit
1085
- (`open-pr` already runs `git add -A`).
1086
- - **A failing packager fails the attempt** (`mirror-regen-failed`, work saved then `Blocked` like
1087
- any other step), with the child's stderr folded in through `describeExecFailure` — an
1088
- `execFileSync` throw says only "Command failed: node scripts/packager/publish.mjs" on its own.
1089
- - **A repo with no drift-check workflow skips the step entirely.** A generated project is that case:
1090
- `copyMonorepo()` ships `scripts/backlog/**` but neither `.github/**` nor `scripts/packager/**`, so
1091
- there is no mirror to keep and no gate to satisfy. A workflow that IS there but whose `paths:`
1092
- list does not parse fails instead — unknown roots make the question unanswerable, and an
1093
- unverifiable answer is the one thing this close refuses to trust.
1094
-
1095
- The reviewer step (local lane) is spawned isolated from the harness — `--strict-mcp-config` keeps
1096
- every MCP server out, `--disable-slash-commands` removes the command surface, `--setting-sources
1097
- user` keeps the project's 42 allow rules out — plus an explicit deny list covering `Edit`, `Write`,
1098
- `NotebookEdit`, the push and PR commands, `WebFetch` and `WebSearch`: it judges, it never writes.
1099
-
1100
- It is the one dispatched process that does NOT get `--bare`, and that is a correctness fix rather
1101
- than a relaxation. Measured on `claude --help`: under `--bare`, "Anthropic auth is strictly
1102
- ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read)". The executor
1103
- authenticates against LM Studio through the lane's own `ANTHROPIC_BASE_URL`/`ANTHROPIC_AUTH_TOKEN`;
1104
- the reviewer runs on the ACCOUNT with all of that stripped, so under `--bare` it had no credential
1105
- left at all — and a reviewer that cannot start fails closed, blocking every local-lane attempt.
1106
- `--setting-sources user` is the narrowest value the flag accepts (it takes a comma-separated list of
1107
- `user`, `project`, `local`; an empty one is not in the grammar), and it is also where an
1108
- `apiKeyHelper` lives.
1109
-
1110
- Its environment is `reviewerEnv`, not `sanitizeInheritedEnv`: it drops every `ANTHROPIC_*` key plus
1111
- `CLAUDE_CODE_SUBAGENT_MODEL`, and applies the same `isCredentialEnvKey` filter the worker env
1112
- applies, with NO exception — the reviewer reads a diff and writes a verdict, so `GITHUB_TOKEN`,
1113
- `NPM_TOKEN` and the SOPS/cloud keys are reach it has no use for. **The reviewer authenticates with
1114
- the machine's claude.ai login; a stale `ANTHROPIC_API_KEY` in the dispatcher's shell would otherwise
1115
- take precedence and break it.** That key used to be kept, on the reading that it is the account
1116
- credential rather than a lane knob. Measured wrong (T-5, 2026-09-07): the reviewer failed to start
1117
- at all (`El revisor no se pudo ejecutar: … claude -p …`), and a probe with the reviewer's own flags
1118
- returned `terminal_reason: api_error`, 0 tokens, and stderr "claude.ai connectors are disabled
1119
- because ANTHROPIC_API_KEY or another auth source is set and takes precedence over your claude.ai
1120
- login". An inherited key can only ever REPLACE the credential this process needs, never supply one:
1121
- a machine that really authenticates by API key declares it in the settings source the reviewer loads
1122
- (`--setting-sources user`, where an `apiKeyHelper` lives), not in the shell the dispatcher happens to
1123
- be started from. The overlay half of the sweep is unchanged in effect — `ANTHROPIC_BASE_URL`,
1124
- `ANTHROPIC_AUTH_TOKEN` and the model aliases still go, so a weak local executor can never review
1125
- itself.
1126
-
1127
- **A failed reviewer subprocess reports its stderr.** `execFileSync`'s own `error.message` is
1128
- "Command failed: claude -p …" and nothing else, so the T-5 `review.md` recorded exactly that while
1129
- the auth error above sat in the stderr nobody rendered. The runner now wraps the spawn in
1130
- `describeExecFailure` (the same renderer the dispatcher's `backlog`/`git` writes use), so the step's
1131
- `Blocked` comment and `review.md` both carry the child's own message. The diff it judges is collected with an intent-to-add first (`git add -N -A -- .`), then
1132
- `diff <base>...HEAD` plus `diff HEAD`. The intent-to-add is what makes the second half honest: no
1133
- `git diff` under any flags renders an UNTRACKED file, and on a dispatched attempt every created file
1134
- is untracked — the executor may not run git, so nothing ever staged them. Without it the reviewer
1135
- was handed a diff with every new file silently missing and approved code it never saw. (Side effect,
1136
- harmless: the slot's index is left carrying those entries, and every path that continues from there
1137
- runs `git add -A` over the whole tree anyway.) It is then fenced between randomized
1138
- `===== BEGIN/END UNTRUSTED DIFF <nonce> =====` sentinels and declared data, because that text was
1139
- written by the model under review and can address the reviewer directly. The verdict is only read AFTER a `REVIEW COMPLETE` line the
1140
- reviewer emits itself — a `VERDICT: pass` quoted from the diff is not a verdict — and a reply with
1141
- no marker, or no verdict after it, fails closed.
1142
-
1143
- The **pre-PR gate** (`evaluateAcceptanceGate`) judges ACCEPTANCE CRITERIA: every one must be checked,
1144
- and a task that declares none at all fails ("la tarea no declara criterios de aceptación" — there
1145
- would be nothing to verify the work against). Definition-of-Done items split in two: the four project
1146
- defaults in `.backlog/config.yml` are dispatcher-owned and the close ticks them itself once the step
1147
- that PROVES each one has passed (the triad ticks "scoped tests pass" and "Prettier and barrels lint
1148
- pass", the gate ticks "every acceptance criterion is checked", `open-pr` ticks "PR opened to main or
1149
- to the parent branch"); any OTHER unchecked DoD item is a human duty and fails the gate. Ticking is by
1150
- item TEXT, never by a guessed index — the `#N` the CLI prints shifts as soon as a task adds one item
1151
- of its own.
1152
-
1153
- One dispatcher-owned item the gate still judges: **"scoped tests pass"**. The triad ticks it ONLY
1154
- when a test check actually ran and passed, so an unticked one at the gate means nothing tested this
1155
- attempt — and excluding it as "dispatcher-owned" let exactly that reach a PR with the box ticked by
1156
- nobody and verified by nothing. The gate now fails with `la tarea no declara Test command`.
1157
-
1158
- Nothing used to TELL the worker to tick anything, either. The operating envelope now renders each
1159
- criterion with its `#N` and the exact wrapper command (`<worker-edit> --check-ac <N>`, the same
1160
- string the permission rule was built from — passed in rather than composed twice, so the command the
1161
- prompt prints cannot drift from the one that is granted), requires the evidence in `--append-notes`,
1162
- and says that leaving one unchecked blocks the attempt — the same instructions the worker system
1163
- prompt carries.
1164
-
1165
- **`open-pr` reuses the PR already on the branch.** A retry pushes to the same `task/T-nn`, so the
1166
- previous attempt's PR is still open and that push already updated it — and creating a second one is
1167
- impossible (`gh` refuses with "a pull request for branch … already exists"), which failed a close
1168
- whose code was on the remote with a perfectly good PR to point at. The step asks first
1169
- (`gh pr view <branch> --json url,state`) and reuses an `OPEN` one, logging "PR existente
1170
- reutilizada". Only "no pull requests found" counts as absence: a `CLOSED`/`MERGED` PR is not
1171
- reusable (pushing again would leave the attempt with no open PR and the DoD item a lie), and any
1172
- other `gh` failure — a revoked token, no network — propagates instead of being read as an absent PR,
1173
- because swallowing it would create a duplicate the moment `gh` recovered.
1174
-
1175
- The dispatcher's own `gh` calls — this `gh pr view`/`gh pr create` pair, and `maintenance.ts`'s
1176
- merged-PR poll — run with an env stripped of `GITHUB_TOKEN`/`GH_TOKEN`/`GH_ENTERPRISE_TOKEN`/
1177
- `GITHUB_ENTERPRISE_TOKEN` (`dispatch.ts`'s `ghEnv`), so `gh`'s own keyring login (`gh auth login`)
1178
- is what authenticates. Without it, a stale token in the dispatcher's shell would otherwise take
1179
- precedence over that login and return `HTTP 401: Bad credentials` right here at `open-pr` — measured
1180
- (T-5, 2026-09-07): the reconciler process inherits whatever `GITHUB_TOKEN` the developer shell that
1181
- launched it exports, and `gh` prefers an env token over the keyring even when the keyring login is
1182
- valid.
1183
-
1184
- **`open-pr` marks the pull request when the scope check reported soft-list files** (T-31) — the
1185
- `humanReviewFiles` `scopeCheck` captured earlier in the run, never recomputed here (see "Forbidden
1186
- paths, split by mechanism" above for why). Applies on BOTH branches above, the reuse and the create:
1187
- a `gh pr edit <branch> --add-label harness-review`, then, when `lanes.json` configures a handle, a
1188
- second `gh pr edit <branch> --add-reviewer <handle>`. Each is its own call, wrapped so a failure is
1189
- logged with `describeExecFailure` and never fails the close. On the REUSE branch it also applies the
1190
- mark's BODY half with a third call, `gh pr edit <branch> --body <body>`: the create branch carries
1191
- that section inside `gh pr create --body`, and the reuse branch has no create call to carry it, so
1192
- without this the reused pull request would name no soft-list file at all and the whole mark would
1193
- rest on the two calls that are allowed to fail. That body is the CURRENT one, read back with
1194
- `readPrBody` and passed through `upsertHumanReviewSection` so only the delimited review section
1195
- changes — a recomposition from the board would replace the whole body and take a reviewer's own notes
1196
- with it. An unreadable body is left alone and the skip is recorded.
1197
-
1198
- A close that FAILS never reaches this step at all (the failure plan is `save-work` then `block`), so
1199
- there the leftover files are named in the `Blocked` comment instead — `formatBlockComment` renders
1200
- `BlockDetails.humanReviewFiles` and `BlockDetails.forbiddenFiles` as two lines, which `executeClose`
1201
- carries over from the scope-check result when a mechanical step failed, and reads from the slot itself
1202
- (the `leftoverFiles` runner) on every divert with no scope check behind it: a plan that started at
1203
- `save-work`, and a `board-check` failure.
1204
-
1205
- That comment is composed under an explicit priority, because `sanitizeCommentBody` truncates from the
1206
- END and the last line is the only actionable one: the reason, the branch/compare/log pointers and the
1207
- `whatToDo` line are never budgeted; the two leftover lines are capped against the room those leave
1208
- (and by `MAX_MARKED_FILES`/`MAX_MARKED_LIST_CHARS`); the worker's own report is capped against what
1209
- remains, since it is the longest part and survives in full in the `run.log` the comment names two
1210
- lines above. Round 3 gave the list a fixed 2000-char budget — half the comment's own 4000 — and
1211
- measured a comment of exactly 4000 chars with `whatToDo` cut off.
1212
-
1213
- ## Failure path: work is saved before anything is released
1214
-
1215
- On any failure the close saves first (`git add -A` + a `chore(<task-id>): wip dispatcher auto-save`
1216
- commit + push) and only then blocks and releases.
1217
-
1218
- **Every dispatcher-owned commit runs `--no-verify`**, and that is a safety property rather than a
1219
- convenience: a slot's `.husky/` hooks are files in the working tree the WORKER has been writing in,
1220
- so committing its work through them would execute code the model under dispatch authored, with the
1221
- dispatcher's privileges. The board commit takes the same flag because it runs unattended in the main
1222
- checkout, where a hook that stashes (lint-staged does) would reach into whatever a person has in
1223
- progress there. Nothing is lost by it: both messages are machine-built, in the same lowercase-scope
1224
- Conventional Commit shape, and `close.test.ts` runs them through this repo's real commitlint.
1225
-
1226
- If that push FAILS, the slot is not released. It is flagged `heldForRecovery` in `slots.json`, which
1227
- means:
1228
-
1229
- - no acquisition will ever pick it (its `reset --hard` would delete the only copy of the work);
1230
- - the dead-PID sweep and the orphan sweep both skip it;
1231
- - every later maintenance pass retries the push, and on success clears the flag, releases the slot
1232
- and appends "push recuperado" to the task. That last note is a COMMENT, not a status write, unless
1233
- the task is still sitting in `Blocked`: a person may have released it to `Queued` (or to `To Do`)
1234
- while the push was pending, and re-asserting `Blocked` would drag it straight back out.
1235
-
1236
- That retry is bounded at **three attempts** (`MAX_RECOVERY_ATTEMPTS`, counted on the slot as
1237
- `recoveryAttempts`). A push that failed three times is failing for a reason no further retry
1238
- addresses — no remote, a rejected non-fast-forward, a broken worktree — and retrying forever keeps
1239
- one of three slots out of the pool while saying nothing about it. At the cap the pass notifies,
1240
- comments `recuperación del push agotada: rescata a mano la rama task/<id> en <slot path>` — naming
1241
- the exact command that gives the slot back, `pnpm backlog:dispatch -- --release-slot <slot name>`,
1242
- since nothing automatic will take it back — keeps the slot held, and stops retrying: a person
1243
- decides from there. See "Releasing a `Blocked` task" for that step.
1244
-
1245
- While a slot is held for THIS task's recovery, guard 6 reports `push-pending` rather than
1246
- `no-free-slot` — only the first says why re-queueing changes nothing until the retry succeeds.
1247
-
1248
- The same rule governs a worker that died without closing: the sweep kills it (its whole process
1249
- group) if it is still running, saves its branch, and only then releases — leaving a `Blocked` comment
1250
- that says which pid died, on which branch, and whether the work survived.
1251
-
1252
- `Blocked` comments are sanitized before they are posted: `backlog task edit --comment` rejects a body
1253
- containing a standalone `---` line outright (exit 1, nothing written), and a reviewer verdict embeds
1254
- exactly that. The body is also capped at 4000 characters, with the rest left in `review.md`.
1255
-
1256
- ## Where board state lives (`BACKLOG_CWD`, `auto_commit: false`)
355
+ ```
356
+ allow: Read, Grep, Glob, Edit(./**), Write(./**), Agent, Skill, TodoWrite, Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git show:*), Bash(git rev-parse:*), Bash(git symbolic-ref:*), Bash(openspec:*), Bash(catalyst:*), Bash(pnpm cli:build:*), Bash(node packages/cli/bin/run.js:*), Bash(pnpm --filter * test), Bash(pnpm --filter * test *), Bash(pnpm --filter * exec prettier --check), Bash(pnpm --filter * exec prettier --check *), Bash(pnpm --filter * exec tsc --noEmit), Bash(pnpm --filter * exec tsc --noEmit *), Bash(pnpm --filter * db:generate), Bash(pnpm --filter * db:generate *), Bash(pnpm db:generate), Bash(pnpm db:generate *), Bash(pnpm --filter * db:check), Bash(pnpm --filter * db:check *), Bash(pnpm db:check), Bash(pnpm db:check *), Bash(pnpm --filter * db:query), Bash(pnpm --filter * db:query *), Bash(pnpm db:query), Bash(pnpm db:query *)
1257
357
 
1258
- The board (`.backlog/tasks/`, `.backlog/config.yml`) lives ONLY in the main checkout, never in a
1259
- slot. Every dispatcher process — the reconciler itself and every `backlog` CLI invocation it
1260
- makes — is pointed there via `BACKLOG_CWD=<main checkout>`, resolved with
1261
- `findRepoRoot`/`scripts/_catalog-runtime/repo-root.ts`. A slot never touches its own `.backlog/`
1262
- copy and that is now ENFORCED rather than assumed: both lane settings deny `Edit`/`Write` on
1263
- `.backlog/**`, and `checkScope` reports a change there as a violation on both lanes. It used to
1264
- strip `.backlog/`-prefixed paths from the diff instead, so a worker that did write there rewrote
1265
- the criteria the close judges it against, invisibly.
1266
-
1267
- Keeping the board in one place is deliberate, not an oversight — three worktrees
1268
- independently writing the same task files would be a merge-conflict generator, which is why
1269
- `check_active_branches: false` in `.backlog/config.yml` too (cross-branch resolution would read
1270
- stale copies out of three slots that never see each other's writes).
1271
-
1272
- `.backlog/config.yml` sets `auto_commit: false`, which is the opposite of what you might expect
1273
- from a tool that manages its own state file. Backlog.md's own auto-commit writes messages like
1274
- "Create task T-2" — not a Conventional Commit — and this repo's `commit-msg` hook (husky +
1275
- commitlint) rejects them; worse, with `bypass_git_hooks: false` the rejection is not a loud
1276
- failure, the task file is never persisted at all (silently losing the write). So instead, the
1277
- reconciler's maintenance pass (`maintenance.ts`, `commitBacklogChanges`) commits any pending
1278
- `.backlog/**` change itself, in the main checkout, with a Conventional Commit message —
1279
- `chore(backlog): sync board state (T-12 -> Done)` for a single transition,
1280
- `chore(backlog): sync board state (4 transitions)` with the list in the commit BODY for several
1281
- (commitlint caps the header at 100 characters). Like every other dispatcher-owned commit it runs
1282
- `--no-verify` (see "Failure path" above), and it carries a trailing `-- .backlog` **pathspec**:
1283
- staging adds to the index but does not narrow what a commit takes, so without it anything a person
1284
- already had staged in the main checkout rode along inside an unattended machine commit. The message
1285
- shape is held by `buildBoardCommitMessage`'s own tests instead of by the hook. A rejected board commit is logged and the pass continues: the slots it already released and the work it already saved
1286
- must not be undone by a bookkeeping failure.
358
+ deny: Bash(git push:*), Bash(git push*), Bash(git add:*), Bash(git add*), Bash(git commit:*), Bash(git commit*), Bash(git restore:*), Bash(git restore*), Bash(git branch:*), Bash(git branch*), Bash(git clean:*), Bash(git clean*), Bash(find:*), Bash(find *), Bash(fd:*), Bash(fd *), Bash(gh:*), Bash(gh *), Bash(backlog task edit:*), Bash(backlog task edit *), mcp__backlog__task_edit, mcp__backlog__task_create, mcp__backlog__task_complete, mcp__backlog__task_archive, WebFetch, WebSearch, mcp__claude_ai_Asana__*, mcp__claude_ai_Atlassian__*, mcp__claude_ai_Box__*, mcp__claude_ai_Canva__*, mcp__claude_ai_Figma__*, mcp__claude_ai_Gmail__*, mcp__claude_ai_HubSpot__*, mcp__claude_ai_Intercom__*, mcp__claude_ai_Linear__*, mcp__claude_ai_Notion__*, mcp__claude_ai_monday_com__*, Edit(.backlog/**), Write(.backlog/**), Edit(.husky/**), Write(.husky/**), Edit(.claude/settings.json), Write(.claude/settings.json), Edit(.claude/hooks/**), Write(.claude/hooks/**), Edit(.claude/scripts/**), Write(.claude/scripts/**), Edit(.claude/settings.local.json), Write(.claude/settings.local.json), Edit(CLAUDE.md), Write(CLAUDE.md), Edit(**/CLAUDE.md), Write(**/CLAUDE.md), Edit(Claude.md), Write(Claude.md), Edit(**/Claude.md), Write(**/Claude.md), Edit(claude.md), Write(claude.md), Edit(**/claude.md), Write(**/claude.md), Edit(package.json), Write(package.json), Edit(pnpm-lock.yaml), Write(pnpm-lock.yaml), Edit(node_modules/**), Write(node_modules/**), Edit(.git/**), Write(.git/**)
359
+ ```
360
+
361
+ Plus, per launch: the same `worker-edit.ts` wrapper rule and the task's own `Test command:` rule.
362
+ `--strict-mcp-config` also runs on this lane, so no MCP server tool loads at all the
363
+ `mcp__*` deny rules above are defence in depth, not the active barrier.
364
+
365
+ The `.claude/**` allowances this file's `allow` list carries (`.claude/hooks/**`,
366
+ `.claude/scripts/**`, both settings files, `CLAUDE.md` in every casing) never actually take effect:
367
+ `--permission-mode dontAsk` denies any Edit/Write on a `.claude`-segment path outright, on either
368
+ lane, whatever a rule grants. They exist only so a reviewer of this file sees the intent stated,
369
+ not silently relied on.
370
+
371
+ `db:generate`/`db:check`/`db:query` are all OFFLINE — they diff a workspace's `*.schema.ts` files
372
+ against its last `snapshot.json`; none of them ever reaches a real database (`catalyst-schema-migrations`).
373
+
374
+ ## Task description conventions
375
+
376
+ **`Test command:`** mandatory on both lanes, validated by `guards.ts`'s `resolveTestCommand` and
377
+ spawned directly, never through a shell:
378
+
379
+ ```
380
+ pnpm [--filter <pkg> | --dir <relative-path>] [run] <test | cli:test | test:*> [args…]
381
+ ```
382
+
383
+ `pnpm` is the only allowed binary; the script itself must match `test`, `cli:test` or
384
+ `test:<word>`; a `--filter` value must be a plain package name (never another flag); `--dir` is the
385
+ alternative selector for `packages/cli` (not a workspace member), and its value must be a relative
386
+ path with no `..` segment; the line may carry no shell metacharacter (`; & | \` $() <> {} \`).
387
+
388
+ **`Files to touch:`** — mandatory on `lane:local` (guard 1 blocks its absence), optional on
389
+ `lane:frontier`. Entries are repo-relative paths read three ways: an exact file; a directory
390
+ (trailing `/`), covering everything under it; and a declared source file's sibling `.spec.ts`/
391
+ `.test.ts`, covered without being named. It is the allowlist the close's local-lane scope check runs
392
+ the real diff against, and the list guard 4 (security paths) inspects before a task is ever
393
+ dispatched to `lane:local`.
394
+
395
+ **A subtask's base branch is always `task/<parentId>`** — a pure deduction from the parent's id,
396
+ never something a parent declares. The parent's `task/<parentId>` branch must exist on the remote
397
+ before the subtask is queued (guard 4b blocks it otherwise, naming the branch it tried and any
398
+ remote candidate that mentions the parent's id).
399
+
400
+ ## Forbidden paths, split by mechanism
401
+
402
+ The close's scope check (`checkScope`) and the pre-launch guards read lists split by whether
403
+ something EXECUTES or READS the path inside the slot, during the attempt or the close — a separate,
404
+ harness-level mechanism handles `.claude/` paths on its own.
405
+
406
+ **Contents are read from the constant, not copied here** (design.md decision 4d of
407
+ `add-backlog-dependency-graph-and-execution-mode`) — a copy would go stale the next time a list
408
+ changes, and it is exactly the reader deciding what to declare in `Files to touch:` that a stale
409
+ copy would mislead:
410
+
411
+ | List | Kind | Contents | Effect |
412
+ | --- | --- | --- | --- |
413
+ | `SLOT_EXECUTED_PATHS` | hard | see `guards.ts` — the harness's own settings and local overlay, its hook and script directories, the version-control hooks the close's own commit runs, the package manifest/lockfile/dependency tree, the board directory, and the two script directories the close spawns from inside the slot | refused on both lanes, declared or not; guard 1c blocks a DECLARATION (file or containing directory) before a slot is taken |
414
+ | `SLOT_EXECUTED_BASENAMES` | hard, by basename (any depth, case-insensitive) | see `guards.ts` — the one instruction file every later reader treats as law | same as above |
415
+ | `CLAUDE_DIR_SEGMENTS` | hard, harness-level | see `guards.ts` — any path with a `.claude` path component | guard 1d blocks the declaration; `--permission-mode dontAsk` denies the write outright regardless — there is no real diff for `checkScope` to ever check this against |
416
+ | `HUMAN_REVIEW_PATHS` | soft | see `guards.ts` — the generator package alone | admitted; the close marks the PR `harness-review` (plus the configured reviewer) instead of failing. On `lane:local` the path must still be DECLARED in `Files to touch:` to pass. On `lane:frontier` it need not be declared |
417
+ | `SUPERVISED_ONLY_PATHS` | hard, by POLICY | see `guards.ts` — the framework packages both applications compile against, and the dispatcher's own sources | refused on both lanes, declared or not; guard 1e blocks a DECLARATION before a slot is taken. Refused for a cause no other list shares: nothing in the slot executes these files and the harness does not deny the write — the DECISION is architectural. A framework change reaches every consumer at once and no test inside the changed package shows it; a dispatcher change alters the machinery every LATER task is judged by and ships to every scaffolded application, where no solution task has any business touching it. By the time such a change is a marked pull request its shape is settled, so the soft list is the wrong instrument. Measured on T-94 (2026-09-16): a framework change was written, the consumer could not compile it, and a whole frontier slot ended in `needs-guidance`. That work goes in an interactive session |
418
+ | `LOCAL_FORBIDDEN_PATHS` | hard, local-lane only | see `guards.ts` — `SLOT_EXECUTED_PATHS` plus the local lane's own extras | refused only on the local lane's close-time scope check |
419
+ | mirror output | hard | see `MIRROR_OUTPUT_PREFIXES` in `close.ts` — the dispatcher-owned regeneration output | refused on both lanes regardless of the split; checked FIRST, before either list |
420
+
421
+ **The frontier lane does not require a soft-list path to be declared** — its `checkScope` branch
422
+ never consults `declaredFiles`, so an undeclared soft-list edit is admitted the same as a declared
423
+ one, and the `harness-review` mark is the mitigation this relies on.
424
+
425
+ **Soft does not mean inert.** A soft-list file can be executed inside the slot during the close (the
426
+ task's own `Test command:` may run the generator package's own test suite), and a soft-list edit
427
+ survives a failed attempt — the failure path pushes the whole slot tree to `task/<id>`, and the
428
+ retry's `checkout -B` restores it.
429
+
430
+ A pull request marked for human review carries the section on the body (unfailable, part of
431
+ `gh pr create`), the `harness-review` label, and the configured reviewer handle — the last two are
432
+ separate best-effort `gh pr edit` calls that never fail the close. A FAILED close opens no pull
433
+ request at all, so on that path the `Blocked` comment names the soft-list files and any refused path
434
+ the attempt left behind instead.
435
+
436
+ ## The close: what actually gates a PR
437
+
438
+ `close.ts`'s `planClose` runs these steps in order, on the success path:
439
+
440
+ 1. **`board-check`** (`checkBoardIntegrity`) — the task must still read `In Progress`, with its
441
+ title, acceptance criteria, DoD texts, `Files to touch:` and `Test command:` unchanged from the
442
+ snapshot taken at launch. Everything after this trusts the board.
443
+ 2. **`scope-check`** — the mirror-output prefix first (refused regardless of the two lists below),
444
+ then the hard list (`SLOT_EXECUTED_PATHS`/`SLOT_EXECUTED_BASENAMES`, plus `LOCAL_FORBIDDEN_PATHS`
445
+ on the local lane and the security paths there too), then the soft list — admitted and recorded as
446
+ `humanReviewFiles`, never a violation — over the attempt's real changed files
447
+ (`git diff --name-only -z` ∪ `git status --porcelain -z --untracked-files=all`).
448
+ 3. **`format-lint-test`** — Prettier `--write` then `--check` per workspace that ships it, barrels
449
+ lint, then the task's own declared `Test command:`, all scoped to the attempt's changed files.
450
+ 4. **`mirror-regen`** — runs `node scripts/packager/publish.mjs`, but only when the attempt touched a
451
+ root the packager reads (read from the slot's own drift-check workflow `paths:` filter). AFTER the
452
+ triad (so it copies formatted sources) and AFTER the scope check (so the mirror stays forbidden TO
453
+ THE WORKER). A repo with no drift-check workflow skips this step entirely.
454
+ 5. **`reviewer`** — local lane only. Isolated read-only `claude`, dual verdict, fails closed.
455
+ 6. **`ac-check`** (`evaluateAcceptanceGate`) — every acceptance criterion must be checked; every
456
+ OTHER Definition-of-Done item not owned by a prior step (the four project defaults are ticked by
457
+ the step that proves them: the triad ticks "scoped tests pass" and "Prettier and barrels lint
458
+ pass", this step ticks "every AC is checked", `open-pr` ticks "PR opened").
459
+ 7. **`open-pr`** — asks `gh pr view <branch>` first and reuses an `OPEN` PR on that branch (a retry);
460
+ otherwise creates one. Applies the human-review mark when step 2 recorded soft-list files.
461
+ 8. **`release-slot`**, **`recompute-parent`**, **`drain`** (may re-arm one more pass).
462
+
463
+ **On any failure**, the plan diverts to `save-work` (commit + push the whole slot tree to
464
+ `task/<id>`, `--no-verify`) and then `block` (or `block-keep-slot` when the push itself failed). A
465
+ slot whose push failed is flagged `heldForRecovery`: no acquisition picks it, and the maintenance
466
+ pass retries the push for up to 3 attempts before stopping and asking a person to run
467
+ `pnpm backlog:dispatch -- --release-slot <name>`. The `Blocked` comment names the cause, any
468
+ soft-list files the attempt touched, and any refused path it left behind.
469
+
470
+ The attempt cap is `lanes.json`'s `attempts` (3); a task `Blocked` on its last attempt has no
471
+ automatic path back and needs a human decision.
472
+
473
+ ### The «Registro de ejecución» block (T-68)
474
+
475
+ `close.ts`'s `planClose`/`executeClose` never set `Done` — `maintenance.ts` is the ONLY module that
476
+ does, and it does it from TWO places: step 3 (a leaf task, merged PR -> `Done`) and `recomputeParent`
477
+ (a parent whose children are all `Done` and whose own PR merged — §12 says "every task", a parent
478
+ included, and `recomputeParent` is what the close's own `recompute-parent` step calls too, so a
479
+ subtask's close reaches this same path). Both write the block through the SAME
480
+ `writeExecutionRecordOnce` helper, and both write it BEFORE the `setStatus(..., DONE, ...)` call that
481
+ follows it — a successful block is on the board before the transition is — but **the write can never
482
+ block the transition**. `writeExecutionRecordOnce` never throws: a failure
483
+ (`readNotes`/`attemptStreamOutcome`/`attemptReviewVerdict`/`appendNotes` all reach the `backlog` CLI
484
+ or the filesystem, and `appendNotes` already retries through `withBoardWriteRetry` — 6 tries with
485
+ backoff — before it can throw here at all) is logged, and then reported with EXACTLY ONE board
486
+ comment through the same `comment` port every other cause already uses, naming the gap and pointing
487
+ at the skill's own manual template (§12) — sanitized through `sanitizeCommentBody` so a long error
488
+ cannot blow the comment up. If `comment` itself throws, that is caught and logged too. Either way the
489
+ caller proceeds to `setStatus(..., DONE, ...)` and everything after it (branch cleanup included)
490
+ exactly as it would on a clean write.
491
+
492
+ Skipping the transition to retry on a later pass is not an option: a task withheld from `Done`
493
+ keeps its attempt directory (so the orphan sweep ignores it), never reaches `cleanupBranchOnDone`,
494
+ and no later pass revisits it — a silent, permanent stall. A confirmed merge is never held hostage to
495
+ bookkeeping: the block is best-effort, the transition is not.
496
+
497
+ The eight fields (`.claude/skills/catalyst-backlog/SKILL.md` §12 has the full contract) are composed
498
+ by `close.ts`'s `buildExecutionRecordBlock` — a PURE function `close.test.ts` asserts directly, given
499
+ the raw facts `maintenance.ts` gathers: the task's own `attempts` count, each attempt's classified
500
+ stream outcome (`render.ts`'s `classifyStreamOutcome`, read back from `stream.jsonl` via
501
+ `MaintenanceFs.attemptStreamOutcome`), each attempt's `review.md` verdict (`reviewer.ts`'s
502
+ `parseReviewerVerdict`, read back via `MaintenanceFs.attemptReviewVerdict` — reused, never
503
+ reimplemented), and the task's current notes, scoped to the notes SECTION alone
504
+ (`task-view.ts`'s `notesRegion`, via `MaintenanceBacklog.readNotes`) — a description, an AC or a
505
+ comment can legitimately contain text that reads like the heading, and only the notes section is
506
+ this task's own write surface. The `## Registro de ejecución` heading, matched as a WHOLE LINE inside
507
+ that scoped text (`close.ts`'s `hasExecutionRecordBlock`), is the §12.3 sentinel that stops a second
508
+ pass from duplicating the block, rather than a separate marker file.
509
+
510
+ Three fields lean on that data rather than a guess:
511
+
512
+ - **"Resultado del intento 1"** carries the FIRST attempt's own cause when the stream classifier
513
+ found one (`Blocked (needs-guidance)`, `Blocked (budget)`, …), falling back to the template's
514
+ cause-free `reintento` when only the retry COUNT is known (a later, close-level failure — a scope
515
+ violation, a failed mechanical check — never touches the stream).
516
+ - **"Rondas de corrección"** / its **"revisor"** come from MEASURED `review.md` verdicts ONLY —
517
+ never from the retry count (a quota cutoff or a crash retries with no review at all: that is not a
518
+ correction round) and never from the lane label (the frontier lane's close never runs a reviewer
519
+ the dispatcher can see, so a lane-based guess would fabricate a `code-review` that never happened).
520
+ The round count is how many attempts' `review.md` verdict reads FAIL; `revisor: code-review` once
521
+ at least one `review.md` exists at all; **both halves read `desconocido`** when no attempt has one
522
+ — the ordinary case for every frontier-lane task, whose own worker runs whatever gates it runs,
523
+ invisible to the dispatcher.
524
+ - **"Fallos de entorno"** can positively detect only a budget cutoff (`STREAM_OUTCOME.BUDGET`) and
525
+ reads `desconocido` otherwise — an LM Studio or network failure is real but untraceable after the
526
+ fact, since `entry.ts`'s `onLocalModelMissing` writes only a `Blocked` COMMENT, routinely
527
+ overwritten by the next transition, never a file under `.backlog/.dispatch/`.
528
+
529
+ "Intervenciones humanas" is deliberately its OWN count (`attempts - 1`, never shared with "Rondas de
530
+ corrección"): every retry passes through a human-released `Blocked` (§10), which is measured and
531
+ certain, independent of whether that retry's attempt ever produced a `review.md`. "Tiempo de ciclo" is
532
+ `desconocido` unconditionally — no status-transition timestamp survives anywhere today (§12.2 rule 4).
533
+
534
+ **`attempts === 0` means the dispatcher never launched this task at all.** The root `CLAUDE.md`'s
535
+ Worktree Gate forces EVERY task onto a `task/T-nn` branch, a supervisada (interactive) session
536
+ included, so step 3/`recomputeParent` close such a task the moment its `task/T-nn` PR merges — the
537
+ exact same path a headless task takes. That absence of any attempt IS a measurement, so the block
538
+ records `Modo: supervisada — desconocido` (the motivo of an interactive session is recorded nowhere
539
+ the dispatcher can read), `Intervenciones humanas: desconocido — tipo: desconocido` (the dispatcher
540
+ has no visibility into a supervisada session's own human steps — a measured `ninguna` would be a
541
+ number nobody actually counted), and `Fuente` points at the merged PR instead of an attempt
542
+ directory that never existed: `PR #<n>` when `MaintenanceGh.prNumber` reads its number, `desconocido`
543
+ when the PR is confirmed to exist (both real call sites only ever reach this with a CONFIRMED merged
544
+ PR) but its number could not be read, `sin evidencia` only for the pure composer's own generic
545
+ "neither an attempt nor a PR" case. If a person already appended their own block to a supervisada
546
+ task's notes by hand, the §12.3 sentinel applies exactly as it does to any other task: the reconciler
547
+ never touches it.
548
+
549
+ ### Releasing a `Blocked` task
550
+
551
+ 1. Read the comment — it always carries the cause and the open question.
552
+ 2. Answer it (a comment, or an edit to the task body/AC while the task sits `Blocked` — the one
553
+ state where the description is still open).
554
+ 3. Move it: to `Queued` to retry on the SAME `task/T-nn` branch, with the prior comment and any
555
+ reviewer findings carried into the retry's prompt; or to `To Do` for a human to work in session.
556
+
557
+ Starting over instead of retrying means deleting the remote `task/T-nn` branch first, or the next
558
+ dispatch reuses it.
559
+
560
+ ## `worker-edit.ts`: the worker's only board channel
561
+
562
+ A permission rule matches a PREFIX and cannot narrow what follows it, so any per-flag `Bash(backlog
563
+ task edit T-nn --notes:*)`-style grant also admits `--notes x --status Done` on the same command
564
+ line. `worker-edit.ts` closes that gap by reading the WHOLE argv itself: exactly the dispatched task
565
+ id (from `BACKLOG_TASK_ID` in the worker's env, never from the command line), then one or more of
566
+ `--check-ac`, `--notes`, `--append-notes`, `--plan` — each at most once, each with a value that is
567
+ not itself a flag — or `--view` alone (forwarding to `backlog task view <id> --plain`). Anything else
568
+ exits `2` and writes nothing. Its second mode, `--subtask` (mutually exclusive with the above), is
569
+ the headless way a Complex task's SDD design phase creates the subtasks a split produces — see
570
+ `.claude/skills/catalyst-backlog/SKILL.md` §6 for its validation rules. The wrapper is granted by
571
+ naming the MAIN CHECKOUT's copy of the script, never the slot's, so the barrier itself is never
572
+ inside the tree under test.
1287
573
 
1288
574
  ## Trigger wiring
1289
575
 
1290
- `.backlog/config.yml`'s `onStatusChange` (single-quoted so YAML preserves `$TASK_ID` literally,
1291
- letting the shell expand it):
576
+ `.backlog/config.yml`'s `onStatusChange`:
1292
577
 
1293
578
  ```yaml
1294
579
  onStatusChange: 'mkdir -p .backlog/.dispatch; nohup npx --loglevel=error tsx scripts/backlog/dispatch.ts >> ".backlog/.dispatch/$TASK_ID.log" 2>&1 < /dev/null &'
1295
580
  ```
1296
581
 
1297
- The redirect APPENDS (`>>`), like the launchd launcher's. One task's log is written by every
1298
- reconciler run that task's status transitions start `Queued`, then the close's move out, then a
1299
- release after `Blocked` and a truncating `>` threw away the previous run's output each time,
1300
- which is the output someone reading a failed dispatch needs.
1301
-
1302
- The `mkdir -p` is what makes a FRESH CLONE work: `.backlog/.dispatch/` is gitignored, so it does not
1303
- exist until something creates it, and `>> "..."` cannot create its own target directory — a
1304
- redirection resolves its target BEFORE anything after it runs. That ordering is also why the
1305
- `mkdir` is joined to `nohup` with a **semicolon, not `&&`**: `&&` makes the two commands one list,
1306
- and `&` backgrounds the WHOLE list — its subshell then holds the caller's own stdio open for as
1307
- long as the reconciler runs, because the shell that opened the log file for the redirection is the
1308
- same one `&` puts in the background. A bare `;` runs `mkdir` in the FOREGROUND (near-instant, no
1309
- redirection to open early) and only backgrounds the `nohup npx ...` command that follows —
1310
- so `&` detaches exactly the long-running part. Measured: the `&&` shape returns in ~3s (however
1311
- long the dispatched run takes to get its own stdio open); the `;` shape returns in ~0.01s. The
1312
- `< /dev/null` alongside the nohup command's own `>>`/`2>&1` is what lets Backlog.md see every one
1313
- of its pipes close AT ONCE — it holds the task lock until then — rather than waiting on stdin to be
1314
- inherited from a caller that never closes it.
1315
-
1316
- The `nohup ... &` is REQUIRED, not an optional optimization: Backlog.md runs this callback
1317
- **synchronously** and blocks the caller (CLI, MCP, or web UI) until it returns. Measured: a
1318
- detached callback returns control in ~0.13s regardless of a 30s background job; a non-detached
1319
- one blocks for the job's full duration. Without `nohup ... &`, moving a task to `Queued` would
1320
- freeze whoever moved it for the entire dispatched run.
1321
-
1322
- `onStatusChange` never fires on task creation and never fires on a merge — it is a hint, not a
1323
- guarantee. Two things cover what it misses: the `launchd` timer below (a missed or crashed
1324
- callback), and the maintenance pass's `gh` poll (a merge that happened outside any callback).
1325
- Every trigger runs through the identical idempotent pass, so a missed or duplicated event
1326
- self-heals on the next one.
1327
-
1328
- ### Anti-loop: a dispatcher-owned write must not spawn its own pass
1329
-
1330
- Every `backlog task edit` this reconciler runs against ITSELF — `dispatch.ts`'s `realBacklog`
1331
- (`setStatus`, `comment`) and `tickOwnedDod`'s `--check-dod` — carries `BACKLOG_DISPATCH_ACTIVE='1'`
1332
- in its `env`, exactly like a worker's own writes through `worker-edit.ts` already do. That edit's
1333
- `onStatusChange` callback inherits the sentinel from the `backlog` CLI child it fires from, so the
1334
- nested `dispatch.ts` invocation it spawns can tell a dispatcher-owned write apart from a genuine
1335
- human one.
1336
-
1337
- `main()` checks this BEFORE resolving `BACKLOG_CWD` or running any maintenance at all
1338
- (`entry.ts`'s `isDispatcherOwnedCallback`: `TASK_ID` and `NEW_STATUS` present, and
1339
- `BACKLOG_DISPATCH_ACTIVE === '1'`) — logs one line and exits 0, no pass at all. This is a stronger
1340
- guard than `shouldDispatchFromCallback`'s: that one only ever suppressed task SELECTION, while
1341
- maintenance (including a `.backlog` git commit) ran unconditionally underneath it regardless. A
1342
- callback with no sentinel (a human moving a task) and the launchd timer / `gh`-poll trigger (no
1343
- `TASK_ID` at all) are unaffected and still run their normal pass.
1344
-
1345
- Measured (2026-09-07, T-5's first real e2e run): the reconciler's own `-s In Progress` edit fired
1346
- a nested pass with no sentinel at the time, which ran its OWN maintenance sweep — including its own
1347
- `.backlog` git commit — concurrently with the pass that made the write and was still mid-dispatch
1348
- in the SAME checkout; that race is what failed `git add .backlog` with exit 128, and the
1349
- dispatcher's own edits that followed failed too. Every `backlog`/`git` collaborator this file owns
1350
- also now captures stderr (`stdio: ['ignore', 'pipe', 'pipe']`, previously silenced) and renders it
1351
- through `describeExecFailure` before throwing or logging — the same run left every one of those
1352
- failures as exit 1 with `stderr: null`, so the actual cause never reached the `Blocked` comment or
1353
- the log at all.
1354
-
1355
- Backlog.md holds the task lock while `onStatusChange` runs; the callback detaches its stdio so it
1356
- returns at once, and the dispatcher retries a busy-board write six times with linear backoff.
1357
-
1358
- The sentinel is not pid-bound by design: it is an env var, not a lock tied to the process that set
1359
- it. A human shell that exported `BACKLOG_DISPATCH_ACTIVE=1` (to silence the callback while
1360
- debugging, say) would have every subsequent `backlog task edit` it runs — including a genuine
1361
- status change a person made — ignored by the callback exactly like a dispatcher-owned one, with
1362
- only one log line in that task's `<id>.log` to say why nothing dispatched.
1363
-
1364
- ## npm scripts
582
+ Backlog.md runs this callback synchronously and holds the task lock until it returns, so the
583
+ `nohup ... &` detachment is requiredwithout it, moving a task to `Queued` would freeze whoever
584
+ moved it for the whole dispatched run. `onStatusChange` never fires on task creation or on a merge;
585
+ the `launchd` timer and the maintenance pass's `gh` poll cover both gaps. Every trigger runs through
586
+ the identical idempotent pass, so a missed or duplicated event self-heals on the next one.
1365
587
 
1366
- | Script | Command | Use |
1367
- | --- | --- | --- |
1368
- | `backlog:dispatch` | `tsx scripts/backlog/dispatch.ts` | Run one reconciler pass manually (what every trigger ultimately invokes) |
1369
- | `backlog:dispatch -- --release-slot <name> [--force]` | same script, one flag | Rescue a slot held for push recovery: detach it, drop its lock and clear the hold. Runs NO pass, takes the reconciler's single-flight lock while it works, and REFUSES (exit 2) a running pass or a slot with a live worker unless `--force` — see "Releasing a `Blocked` task" |
1370
- | `backlog:watch` | `tsx scripts/backlog/watch.ts` | Tail a running attempt's log, or list busy slots — see below |
1371
- | `test:backlog` | `node --import tsx --test "scripts/backlog/**/*.test.ts"` | Run every dispatcher unit/contract test |
588
+ **Anti-loop:** every `backlog task edit` the reconciler runs against itself carries
589
+ `BACKLOG_DISPATCH_ACTIVE='1'` in its env; `entry.ts`'s `main()` checks this BEFORE resolving
590
+ `BACKLOG_CWD` or running any maintenance, and exits 0 with one log line rather than starting a nested
591
+ pass. A callback with no sentinel (a human moving a task) is unaffected.
1372
592
 
1373
- ## Observability: `pnpm backlog:watch`
593
+ ## Installing the `launchd` recovery timer
1374
594
 
1375
- ```bash
1376
- pnpm backlog:watch T-12 # tails the human-rendered run.log of T-12's current attempt
1377
- pnpm backlog:watch # no id: lists busy slots (name, lane, taskId, pid) from slots.json
1378
- ```
595
+ 1. Copy `scripts/backlog/dev.aurora.backlog-dispatch.plist` to
596
+ `~/Library/LaunchAgents/dev.aurora.backlog-dispatch.plist`, replacing the three absolute paths
597
+ inside it (your `which npx`, your main checkout as `WorkingDirectory`, and
598
+ `<main checkout>/.backlog/.dispatch/launchd.log` for both `StandardOutPath`/`StandardErrorPath`).
599
+ The command itself detaches the reconciler into `reconciler.log` and exits — launchd tracks the
600
+ pid of what it starts, and the reconciler lives as long as its worker, so running it directly
601
+ would silence the timer for the whole length of every dispatch.
602
+ 2. The one manual prerequisite: `gh auth login` on the machine that runs the dispatcher — its own
603
+ `gh` calls run with `GITHUB_TOKEN`/`GH_TOKEN` stripped, so the keyring login is the only
604
+ credential they get.
605
+ 3. Load: `launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.aurora.backlog-dispatch.plist`.
606
+ Remove: `launchctl bootout gui/$(id -u)/dev.aurora.backlog-dispatch`, then delete the plist.
1379
607
 
1380
- `watch.ts` only reads it never writes board state, a lock, or a slot. The log it tails is the
1381
- SAME `run.log` `attempt.ts`'s sink writes per attempt
1382
- (`.backlog/.dispatch/<TASK_ID>/intento-<N>/run.log`), rendered through the shared `render.ts` so a
1383
- live tail and a post-hoc read of the same file show identical lines. The attempt directory is
1384
- created before the worker starts, so `backlog:watch` works from the first second of a run.
1385
-
1386
- ## Installing the launchd recovery timer
1387
-
1388
- The `onStatusChange` callback in `.backlog/config.yml` is the primary trigger; the launchd agent
1389
- below is the recovery path for a trigger that never fires (a missed status change, a crash before
1390
- the callback ran). Both invoke the same `scripts/backlog/dispatch.ts` entry point.
1391
-
1392
- 1. Copy the template and replace the **three absolute paths** in the copy — the template ships this
1393
- machine's, and launchd does not expand `~` or source a login shell's `PATH` (so no nvm shim):
1394
-
1395
- | Where | What to put there |
1396
- | --- | --- |
1397
- | inside the `ProgramArguments` `/bin/sh -c` string | your `which npx` |
1398
- | `WorkingDirectory` | your main checkout |
1399
- | `StandardOutPath` / `StandardErrorPath` | `<your main checkout>/.backlog/.dispatch/launchd.log` |
1400
-
1401
- Two log files, and they are not interchangeable: `launchd.log` holds the LAUNCHER's own output
1402
- (a failing `mkdir`, a failing `nohup`), and `reconciler.log` — the `>>` redirect inside the
1403
- `sh -c` string — holds the detached reconciler's. A single file mixed a tens-of-minutes pass into
1404
- the launcher's one-line runs and made neither readable.
1405
-
1406
- ```bash
1407
- cp scripts/backlog/dev.aurora.backlog-dispatch.plist \
1408
- ~/Library/LaunchAgents/dev.aurora.backlog-dispatch.plist
1409
- ```
1410
-
1411
- The command itself is `sh -c 'mkdir -p .backlog/.dispatch; nohup <npx> --loglevel=error tsx
1412
- scripts/backlog/dispatch.ts >> .backlog/.dispatch/reconciler.log 2>&1 < /dev/null &'` — a short
1413
- LAUNCHER that detaches the reconciler and **exits**, not the reconciler itself.
1414
-
1415
- That is the load-bearing part. launchd tracks the pid of what it starts and will not start a
1416
- second instance while that process is alive, and the reconciler lives as long as its worker —
1417
- tens of minutes. Running it directly (or under `exec`, which keeps its pid as the tracked one)
1418
- silenced the timer for the whole length of every dispatch, exactly when a `StartInterval`
1419
- recovery pass matters most. Backgrounded, launchd sees a process that exited in milliseconds and
1420
- is free to fire again on the next interval — the same way the `onStatusChange` callback detaches
1421
- its own invocation.
1422
-
1423
- Two consequences of detaching, both handled in the template: the log directory is gitignored and
1424
- therefore absent on a fresh clone, and launchd opens `StandardOutPath` itself without creating
1425
- missing parents — so the first run on a new machine produced no log at all, including no record
1426
- of why, hence the `mkdir -p`; and the detached process is no longer launchd's child, so its own
1427
- output is redirected into that same log explicitly rather than inherited. That `mkdir -p` runs
1428
- BEFORE the `>>` opens `reconciler.log`, and is joined to `nohup` with a **semicolon, not `&&`** —
1429
- `&&` would make `mkdir; nohup ...` one list, and `&` backgrounds the WHOLE list, so the shell that
1430
- opened the log file stays foregrounded for as long as the reconciler runs (measured ~3s vs the
1431
- `;` shape's ~0.01s). The `< /dev/null` alongside the nohup command's own `>>`/`2>&1` is what lets
1432
- whoever is waiting on this callback (Backlog.md holds the task lock until then) see every one of
1433
- its pipes close at once, instead of blocking on a stdin nothing ever closes.
1434
- 2. The one manual prerequisite: `gh auth login` on the machine that runs the dispatcher, once. The
1435
- dispatcher's own `gh` calls (`open-pr`'s reuse check and create, the maintenance sweep's merged-PR
1436
- poll) deliberately run without an inherited `GITHUB_TOKEN`/`GH_TOKEN` — see "`open-pr` reuses the
1437
- PR already on the branch" above — so that keyring login is the only credential they ever get.
1438
- Otherwise there is no other manual setup. `.backlog/.dispatch/` is created by the `onStatusChange` callback
1439
- and by `dispatch.ts` itself, and the three worktree slots are provisioned on demand the first time
1440
- a task acquires one (`fetch origin --prune`, `worktree prune`, `worktree add --detach
1441
- origin/main`, `scripts/worktree-link.sh`, `pnpm install`) — so the first dispatch into a fresh
1442
- slot takes as long as a full install and every later one does not. The `worktree prune` is what
1443
- makes that recovery actually work: a slot directory deleted by hand leaves git's administrative
1444
- record of it behind, and `worktree add` then refuses the path as already registered — so the very
1445
- state provisioning exists to recover from would otherwise block every later dispatch.
1446
- 3. Load it:
1447
- ```bash
1448
- launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.aurora.backlog-dispatch.plist
1449
- ```
1450
- 4. To stop and remove it:
1451
- ```bash
1452
- launchctl bootout gui/$(id -u)/dev.aurora.backlog-dispatch
1453
- rm ~/Library/LaunchAgents/dev.aurora.backlog-dispatch.plist
1454
- ```
1455
-
1456
- Validate any edit to the plist before loading it: `plutil -lint dev.aurora.backlog-dispatch.plist`.
1457
-
1458
- ## Releasing a `Blocked` task
1459
-
1460
- `Blocked` is the only human column — the reconciler never takes a task out of it on its own. To
1461
- release one:
1462
-
1463
- 1. Read the `Blocked` comment: it always carries the cause and, per design.md decision (m), the
1464
- open question written in plain language (an ambiguity, an undeclared artifact, a
1465
- `judgment-day` ESCALATED verdict, an unanswered `needs-guidance`, a failed push, an
1466
- exhausted attempt budget, or a permission conflict between a settings rule and one the launch
1467
- grants — that last one names both rules and is resolved by editing one of them, not by re-queueing
1468
- as it stands).
1469
- 2. Answer the question in the task itself (a comment, or an edit to the task body/AC).
1470
- 3. Move it:
1471
- - to `Queued` — the dispatcher retries on the SAME `task/T-nn` branch, with the prior
1472
- `Blocked` comment and any reviewer findings included in the retry's prompt on BOTH lanes (the
1473
- frontier lane appends them to its `trabajemos <id>` entry; fresh context, same code). This is
1474
- the right choice for a fixable failure (a red test, a scope violation, a push that failed to
1475
- save).
1476
- - to `To Do` — a human works it in an interactive session instead of redispatching it. Choose
1477
- this when the question needs a person's judgment call the worker cannot make on retry (e.g.
1478
- a genuine scope/requirement change).
1479
-
1480
- **A slot held for push recovery needs one more step: releasing it.** When a close or a sweep could
1481
- not PUSH the work a slot holds, the slot is marked `heldForRecovery` and kept out of the pool —
1482
- it holds the only copy of that work, so no acquisition may reuse it. The maintenance pass retries the
1483
- push up to `MAX_RECOVERY_ATTEMPTS` (3) times; past that it stops and hands the slot to a person, and
1484
- the task's comment names the command that gives it back:
608
+ Validate any edit with `plutil -lint dev.aurora.backlog-dispatch.plist` first.
1485
609
 
1486
- ```bash
1487
- # After you have the branch safely on the remote
1488
- pnpm backlog:dispatch -- --release-slot dispatch-1
1489
- ```
610
+ ## Operator commands
1490
611
 
1491
- That flag runs no dispatch pass. It detaches the slot's worktree, removes any dispatch lock the slot
1492
- still carried, and clears `heldForRecovery`, `recoveryAttempts` and the task binding — the one
1493
- release that clears the hold, which the ordinary release deliberately does not
1494
- (`slots.ts`'s `releaseHeldSlotEntries`). The hand-edit it replaces is still the same thing: deleting
1495
- `heldForRecovery` and `recoveryAttempts` from that slot in `.backlog/.dispatch/slots.json`.
1496
-
1497
- **It runs under the reconciler's single-flight lock**, and exits **2** when a pass already holds it.
1498
- The rescue is a read of `slots.json`, a decision, and a `git worktree detach` the exact sequence a
1499
- pass mutates while it selects a task and acquires a slot. Unserialized, a pass that took this slot
1500
- between the read and the detach lost its worktree under a worker that was just starting. Waiting for
1501
- the pass (they are short, and the lock is dropped as soon as the worker spawns) or `--force` are the
1502
- two ways past it; `--force` proceeds without holding the lock, so it never removes the running pass's.
1503
-
1504
- **It also refuses a slot that is genuinely busy**, and exits **2** saying so — "release this slot" and
1505
- "kill what is running in it" are different requests, and only the first is what the flag advertises.
1506
- A release is allowed when the slot is flagged `heldForRecovery` (the case above: the work is committed
1507
- and only the push failed) or when the slot's task lock is absent or DEAD — no such process, or a
1508
- heartbeat past the 10-minute TTL, the same liveness question the maintenance sweep asks. Otherwise
1509
- detaching the worktree under a live `claude` would lose its uncommitted work, drop the lock the close
1510
- re-reads before it runs, and hand the directory to the next dispatch. To take a running slot anyway,
1511
- cancel the task on the board (the next maintenance pass kills the worker after saving its work), or
1512
- pass `--force` once you have looked:
612
+ | Script | Command | Use |
613
+ | --- | --- | --- |
614
+ | `backlog:dispatch` | `tsx scripts/backlog/dispatch.ts` | Run one reconciler pass manually |
615
+ | `backlog:dispatch -- --release-slot <name> [--force]` | same script, one flag | Detach a slot, drop its lock and clear a push-recovery hold. Takes the single-flight lock and refuses (exit 2) a running pass, or a slot with a live worker unless `--force` |
616
+ | `backlog:watch` | `tsx scripts/backlog/watch.ts` | Tail a running attempt's log, or list busy slots |
617
+ | `backlog:graph` | `tsx scripts/backlog/graph-cli.ts` | Print the current dependency view (see "The dependency view" above). No board write. Exits non-zero on an unrecognized argument or a partial board read |
618
+ | `backlog:graph --write` | same script, one flag | Also refresh the graph-holder task immediately, instead of waiting for the next maintenance pass. Exits non-zero instead of writing on an unrecognized argument, a partial board read, more than one holder, or a failed read/write |
619
+ | `test:backlog` | `node --import tsx --test "scripts/backlog/**/*.test.ts"` | Run every dispatcher unit/contract test |
1513
620
 
1514
621
  ```bash
1515
- pnpm backlog:dispatch -- --release-slot dispatch-1 --force
622
+ pnpm backlog:watch T-12 # tails the human-rendered run.log of T-12's current attempt
623
+ pnpm backlog:watch # no id: lists busy slots (name, lane, taskId, pid) from slots.json
1516
624
  ```
1517
625
 
1518
- Starting over from scratch (rather than retrying) means deleting the remote `task/T-nn` branch
1519
- before moving the task back to `Queued` — otherwise the next dispatch reuses it. The attempt cap is
1520
- `lanes.json`'s `attempts` (3 as shipped), read by guard 5 and by the close's terminal-block flag
1521
- alike; a task `Blocked` on its last failed attempt has no automatic path back to dispatch and needs
1522
- the human decision above regardless.
626
+ Reading a finished attempt directly: `run.log` (the whole rendered session), `test.log` (the
627
+ mechanical checks' transcript), `review.md` (the local-lane reviewer's findings, read back by a
628
+ retry's prompt).
1523
629
 
1524
630
  ## Known gotchas
1525
631
 
1526
632
  - **A board read that half-failed is not an empty board.** `loadBoard` returns
1527
- `{ tasks, complete }`, and `complete` is `false` when `backlog task list` failed outright or when
1528
- any single `task view` threw and its id was dropped. The maintenance sweep infers a MANUAL
1529
- CANCELLATION from a task's absence, so a bare empty list used to read as "a person deleted every
1530
- task" and killed every live worker at once. With `boardComplete: false` the sweep skips the
1531
- absence-based cancellation (a task it DID read as `Blocked`/`To Do` is still cancelled — that
1532
- decision rests on the task's own status) and skips the parent derivation entirely, since deriving a
1533
- parent from half its children produces a confident wrong answer. The next pass, with a readable
1534
- board, does both. The flag survives the POST-SWEEP re-read too: `entry.ts`'s `reloadTasks` returns
1535
- the whole `BoardLoad`, and the close's own parent derivation is skipped with a log when `complete`
1536
- is false it derives the same parent from the same kind of read, and a signature that returned
1537
- only the array dropped the flag on the floor.
1538
- - **A slot is the only place a close may touch.** `slotPathForTask` returns `null` when no slot
1539
- holds the task, and every runner FAILS its step on that — it never falls back to the main
1540
- checkout. It used to, and that pointed the whole close at the developer's own working tree: a
1541
- `git add -A` plus WIP commit over work in progress, a scope diff of somebody else's changes, and a
1542
- `gh pr create` off whatever branch happened to be checked out there.
1543
- - **The precomputed hooks run in the SLOT but read the board from the main checkout.**
1544
- `dispatch.ts`'s `buildHookRunners` spawns both hook scripts with the slot as `cwd` — that is where
1545
- their rule catalogs and the injector cache belong — and with `BACKLOG_CWD=<main checkout>` plus
1546
- `BACKLOG_DISPATCH_ACTIVE=1` in their env. `inject-prompt-context.ts` reads `BACKLOG_CWD` as its
1547
- BOARD root (`resolveBoardRoot`): a slot's own `.backlog/` copy holds no tasks, so without it the
1548
- hook would find no `task_prefix` and match nothing. The sentinel switches the task block's footer
1549
- from "follow the Task Gate" to "the dispatcher already set it `In Progress`; do not change its
1550
- state" pointing a headless worker at an interactive gate invites exactly the status write the
1551
- close then fails it for. **That block is a FRONTIER-lane thing**, and only there: the frontier
1552
- worker's real prompt is `trabajemos <id>`, so the hook matches it and the block is the task text
1553
- that worker gets. The local lane's precompute deliberately names NO id
1554
- (`prompt.ts`'s `buildHookPromptText` passes the bounded context and the declared files, which is
1555
- all the BR/HR/skill blocks need to resolve): block 1 of the executor envelope already carries the
1556
- whole task view verbatim, so an injected second copy meant the weakest executor read its task
1557
- twice, in two formats, one of them describing a gate it has no business walking. The env pair
1558
- still travels on both lanes it is what the hook is entitled to, and the moment anything names an
1559
- id again the block must resolve against the real board and read as dispatched.
1560
- - **`.claude/.cache/br-injected.json` must be reset per dispatched attempt.** The
1561
- `business-rules-injector.ts` PreToolUse hook tracks already-injected rule IDs across
1562
- invocations outside a real interactive session (there is no `SessionStart` to wipe it for a
1563
- headless run). Without resetting this file before each dispatched attempt, a rule injected for
1564
- a PREVIOUS task on the same lockfile-shared slot silently fails to surface for the next one —
1565
- the hook prompt-precompute step (`prompt.ts`) deletes/resets it before assembling a fresh
1566
- prompt.
1567
- - **`--max-budget-usd` stops at turn boundaries, not mid-generation.** It is a hard stop
1568
- (`is_error:true`, `subtype:"error_max_budget_usd"`), never a warning, but the turn already in
1569
- flight always completes first real spend can overshoot the configured cap, sometimes on the
1570
- very first turn. Treat it as a coarse safety net layered on top of `--max-turns`, never as a
1571
- precise or sole stop mechanism.
1572
- - **`maxBudgetUsd` compares an ESTIMATE against a cap, and on a subscription login nothing is
1573
- billed per token.** `--max-budget-usd` cuts a worker off when Claude Code's own cost ESTIMATE
1574
- crosses the configured number measured (T-3, 2026-09-07): this machine's local-lane run
1575
- printed `cost=$2.40` for a run nothing actually billed. `lanes.json`'s `maxBudgetUsd` is
1576
- therefore OPTIONAL on the frontier lane: set a number when the machine authenticates with an API
1577
- key and you want a hard dollar stop; omit it on a subscription login, where the estimate is not
1578
- billed and the cap only truncates legitimate work. `maxTurns` and `timeoutMinutes` are the guards
1579
- that always apply, on either kind of login.
1580
- - **A slot never keeps a task branch checked out.** EVERY release goes through
1581
- `slots.ts`'s `releaseSlotAndDetach` (or, in the maintenance sweep, its `git.detachSlot`
1582
- collaborator), which runs `git checkout --detach` before clearing the registry entry: the close's
1583
- own release, the abort path, the branch-in-use handback, the dead-lock sweep, the orphan sweep,
1584
- the cancellation, the recovered push. Git refuses to check the same branch out in two worktrees,
1585
- so a slot released while still sitting on `task/T-12` made EVERY later dispatch of T-12 refuse
1586
- with `branch-in-use` — and since a pass dispatches one task at a time, the whole queue starved
1587
- behind it. `prepareSlot` also checks out with `-B` rather than `-b`, so a leftover local branch
1588
- cannot fail the checkout either. If a branch IS still held elsewhere when a task is selected, the
1589
- pass hands the slot back (detaching it) and leaves the task `Queued` rather than failing — the
1590
- next pass retries.
1591
- - **Work is branched and diffed against `origin/…`, never a local ref.** A reusable slot's local
1592
- `main` is whatever its last fetch left behind. Branching new work off it silently reintroduces
1593
- days-old code, and diffing an attempt against it reports files nobody in this task touched.
1594
- - **`Write(<glob>)` path-scoped permission rules are unverified.** `Edit(<glob>)` (e.g.
1595
- `Edit(allowed/**)`) is confirmed to scope correctly — a denied edit outside the glob is recorded
1596
- in `permission_denials` with the file path. The equivalent `Write(<glob>)` rule was never
1597
- exercised in the Phase 1 spike (the local model never attempted a `Write` tool call at all under
1598
- that rule), so it is unverified, not confirmed broken — re-verify with a stronger model before
1599
- relying on it to gate new-file creation. It now carries the frontier lane too, whose `allow`
1600
- grants the same `Write(./**)`; the close's scope check and `SLOT_EXECUTED_PATHS` are the barriers
1601
- that do not depend on it.
633
+ `{ tasks, complete }`; with `complete: false` the sweep skips absence-based cancellation (an
634
+ explicit `Blocked`/`To Do` still cancels) and skips parent derivation entirely.
635
+ - **A slot is the only place a close may touch** `slotPathForTask` returning `null` fails the
636
+ step; it never falls back to the main checkout.
637
+ - **`--max-budget-usd` stops at turn boundaries**, comparing an unbilled estimate on a subscription
638
+ login; `maxTurns`/`timeoutMinutes` are the guards that always apply.
639
+ - **`Write(<glob>)` path-scoped permission rules are unverified** (`Edit(<glob>)` is confirmed to
640
+ scope correctly); the close's scope check is the barrier that does not depend on it.
641
+ - **`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS` is undocumented** absent from the public env-vars
642
+ referenceso its behaviour is measured, not guaranteed: Bash's `run_in_background` and a
643
+ backgrounded Agent both run synchronously under it (measured 2026-09-15, Claude Code 2.1.272). If
644
+ a future Claude Code version changes this, a worker's `task_started` system event would carry
645
+ `is_backgrounded: true` again, or a `task_updated` event's `patch.status` would read `"killed"`
646
+ right after a Bash/Agent call either is the signal to re-measure.
647
+ - **With background tasks disabled, every Bash call runs synchronously**, bounded by
648
+ `BASH_DEFAULT_TIMEOUT_MS` (2 minutes when the call passes no `timeout`) and
649
+ `BASH_MAX_TIMEOUT_MS` (a 10-minute ceiling).
650
+
651
+ ## Accepted risks
652
+
653
+ Measured, weighed, and deliberately left as is not oversights, and not to be re-proposed without
654
+ new evidence.
655
+
656
+ - The declared `Test command:` names a repo script; the allowlist constrains the line's shape, not
657
+ what the script does. Accepted because the script lives in the repo and reaches the slot only
658
+ through a reviewed PR. (T-36)
659
+ - The attempt directory doubles as the "was dispatched" signal for the orphan sweep, so a parent
660
+ enqueued and immediately guard-blocked becomes invisible to that sweep. (T-20 §1)
661
+ - `sanitizeCommentBody` replaces `---` with `___` in PR bodies, a restriction inherited from
662
+ `backlog task edit --comment`. (T-20 §2)
663
+ - `isParentCloseAttempt` keeps a default `isChildDone` that no production caller uses. (T-20 §3)
664
+ - Guard 1c checks the shared hard list only; the three local-lane path extras are enforced at the
665
+ close, not in the queue. (T-35)
666
+ - A worker that reports `needs-guidance` with no `questions:` block is closed as a block, not as a
667
+ completion: the close obeys the reported status, not the text. One occurrence in 39 dispatches;
668
+ it costs one attempt. (T-54 attempt 2)
669
+ - A Complex parent whose children merged to `main` through their own PRs still gets its one
670
+ automated close attempt on its own stale branch. The frontier worker refuses it (measured on T-4:
671
+ 102 s, $1.36, no PR opened). An automatic rule cannot tell that branch from one with real work
672
+ without a destructive false-Done path, so the parent is closed by hand after deleting its branch.
673
+ - A Complex parent that declares a supervised-only path, or carries `mode:supervised`, loses its one
674
+ automated close attempt: it is enqueued, the marker is written, and guard 0 or 1e blocks it,
675
+ although the close brief writes no implementation. Accepted as policy: a person closes a harness
676
+ or supervised parent in a session; from `Blocked` a manual re-queue still runs the close brief.
677
+ The alternative, exempting the close attempt from the declared-path and mode guards, waits for
678
+ evidence that the manual path is tedious. (T-113)
679
+ - `graph-cli.ts`'s `main()` — the binding of `runGraphCli` to the real board and CLI has no test
680
+ of its own; everything it decides lives in `runGraphCli`, which is covered branch by branch. (T-113)
681
+ - A task whose `Status:` line cannot be parsed reads as `Unknown`, which is not an open status, so
682
+ the dependency view omits it without marking the board read as partial; a task that waits for it
683
+ still names it. No such task has been seen on a board. (T-113)
684
+ - The holder refresh REPLACES THE WHOLE DESCRIPTION of whatever task carries `board:graph`, without
685
+ reading it first: a real task labelled by mistake loses its description — `Test command:` and
686
+ `Files to touch:` included the pass commits the loss, and a `Queued`/`In Progress` task then
687
+ fails its close's board-integrity check. Accepted: the label is the declaration, and the text is
688
+ recoverable from git history; writing only over an empty or generated description was considered
689
+ and not taken. (T-113)