@zaip-ai/cli 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/README.md +3 -2
  2. package/dist/services/agent-adapters.js +1 -1
  3. package/dist/services/agent-adapters.js.map +1 -1
  4. package/dist/services/agent-adapters.test.js +2 -1
  5. package/dist/services/agent-adapters.test.js.map +1 -1
  6. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  7. package/dist/services/codex-pre-tool-hook-template.js +89 -7
  8. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  9. package/dist/services/codex-rules.d.ts +1 -1
  10. package/dist/services/codex-rules.d.ts.map +1 -1
  11. package/dist/services/codex-rules.js +7 -0
  12. package/dist/services/codex-rules.js.map +1 -1
  13. package/dist/services/install-agents-template.d.ts.map +1 -1
  14. package/dist/services/install-agents-template.js +1 -0
  15. package/dist/services/install-agents-template.js.map +1 -1
  16. package/dist/services/runtime-template.test.js +31 -7
  17. package/dist/services/runtime-template.test.js.map +1 -1
  18. package/dist/services/template-manifest.d.ts.map +1 -1
  19. package/dist/services/template-manifest.js +7 -3
  20. package/dist/services/template-manifest.js.map +1 -1
  21. package/package.json +1 -1
  22. package/templates/.agents/config/agents/catalog.yaml +7 -7
  23. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +2 -2
  24. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +2 -2
  25. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +8 -8
  26. package/templates/.agents/dashboard/.zaip-managed.json +373 -205
  27. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-DxR_pgSV.js → CostCalculationGuidePage-ovxurkIk.js} +1 -1
  28. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-4jZLTWE_.js → DashboardHelpDialog-BXy6nti1.js} +268 -86
  29. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-CKcsqb-r.js → PricingSettingsDialog-vSvvOHQp.js} +1 -1
  30. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-DmmJD2Th.js → ProjectSettingsPage-zH758vfs.js} +1 -1
  31. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CTH2wDs5.js +1 -0
  32. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CaKwQP43.css → TraceabilityWorkspace-DvvavDLY.css} +1 -1
  33. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +68 -0
  34. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-PoJA2PI1.css +1 -0
  35. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-C0fj2uU9.js → icons-vendor-B_lDDHn1.js} +1 -1
  36. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-B31GMG5O.css +1 -0
  37. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CuMcoUni.js +2 -0
  38. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-BEsJ-FYH.js → react-vendor-B3TJrD4O.js} +1 -1
  39. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-B6y6Gw12.js → traceability-7f1j5wx3.js} +1 -1
  40. package/templates/.agents/dashboard/apps/frontend/dist/index.html +7 -7
  41. package/templates/.agents/dashboard/apps/frontend/playwright.dom.config.ts +32 -0
  42. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +132 -245
  43. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +0 -21
  44. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +9 -0
  45. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.dom.e2e.ts +56 -0
  46. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +18 -1
  47. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +75 -8
  48. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +25 -1
  49. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +7 -9
  50. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +4 -4
  51. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +1 -1
  52. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +7 -0
  53. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +20 -8
  54. package/templates/.agents/dashboard/apps/frontend/src/sqlite-page-export.test.ts +32 -0
  55. package/templates/.agents/dashboard/apps/frontend/src/sqlite-page-export.ts +21 -0
  56. package/templates/.agents/dashboard/apps/frontend/src/styles.css +19 -0
  57. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.test.ts +32 -0
  58. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.ts +36 -0
  59. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +6 -2
  60. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +48 -0
  61. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +31 -27
  62. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +7 -1
  63. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-list-page.test.ts +163 -0
  64. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-list-page.ts +136 -0
  65. package/templates/.agents/dashboard/apps/frontend/src/use-operations-detail-export.ts +76 -0
  66. package/templates/.agents/dashboard/apps/frontend/src/work-list-load-dedup.test.ts +23 -0
  67. package/templates/.agents/dashboard/apps/frontend/src/work-list-load-dedup.ts +27 -0
  68. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +38 -14
  69. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.tsx +60 -0
  70. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionTable.tsx +191 -0
  71. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.loading.test.ts +14 -0
  72. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts +18 -0
  73. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +18 -3
  74. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +8 -2
  75. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorLoadErrors.tsx +35 -0
  76. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +47 -1
  77. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +50 -58
  78. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.test.ts +132 -0
  79. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.tsx +70 -0
  80. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +128 -138
  81. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +17 -67
  82. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +2 -0
  83. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +3 -1
  84. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-page-range.ts +35 -0
  85. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +16 -4
  86. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +37 -2
  87. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +44 -8
  88. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +6 -1
  89. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +20 -3
  90. package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.test.ts +54 -0
  91. package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.tsx +247 -0
  92. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +39 -13
  93. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +107 -2
  94. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.macro-metrics.test.ts +55 -0
  95. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +20 -28
  96. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +162 -165
  97. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx +127 -0
  98. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +13 -46
  99. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
  100. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.test.tsx +43 -0
  101. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +181 -0
  102. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +4 -2
  103. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +13 -0
  104. package/templates/.agents/dashboard/modules/operations/src/react/developer-identities.test.ts +18 -0
  105. package/templates/.agents/dashboard/modules/operations/src/react/developer-identities.ts +30 -0
  106. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +1 -0
  107. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +8 -0
  108. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +3 -0
  109. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +14 -5
  110. package/templates/.agents/dashboard/modules/operations/src/react/index.ts +1 -0
  111. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +4 -3
  112. package/templates/.agents/dashboard/modules/operations/src/react/operations-date-filters.css +1 -1
  113. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +21 -11
  114. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.css +4 -0
  115. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +8 -1
  116. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +1 -0
  117. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +1 -0
  118. package/templates/.agents/dashboard/modules/operations/src/server/metric-coverage.ts +1 -0
  119. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +527 -335
  120. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +501 -309
  121. package/templates/.agents/dashboard/packages/local-runtime/gitignore.template +2 -0
  122. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +3 -1
  123. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +3 -3
  124. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +25 -15
  125. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +527 -335
  126. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +34 -0
  127. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +15 -8
  128. package/templates/.agents/dashboard/packages/local-runtime/src/server-classification-page.test.ts +87 -0
  129. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.test.ts +44 -0
  130. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.ts +125 -0
  131. package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-refresh.test.ts +66 -0
  132. package/templates/.agents/dashboard/packages/local-runtime/src/server-request-authority.test.ts +61 -0
  133. package/templates/.agents/dashboard/packages/local-runtime/src/server-request-authority.ts +18 -0
  134. package/templates/.agents/dashboard/packages/local-runtime/src/server-run-projections.test.ts +42 -0
  135. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +97 -0
  136. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +3 -1
  137. package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.ts +91 -0
  138. package/templates/.agents/dashboard/packages/local-runtime/src/server.test-fixtures.ts +36 -0
  139. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +98 -123
  140. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +111 -135
  141. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-artifact-counts.ts +28 -0
  142. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.test.ts +63 -0
  143. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.ts +109 -0
  144. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-aggregates.ts +497 -0
  145. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-fast-page-parity.test-support.ts +65 -0
  146. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-page.test.ts +176 -0
  147. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-page.ts +119 -0
  148. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +41 -0
  149. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.test.ts +16 -0
  150. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.ts +29 -0
  151. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +355 -0
  152. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-persistence.ts +121 -0
  153. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-timing.ts +27 -0
  154. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +15 -0
  155. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +293 -0
  156. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +371 -0
  157. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-cache.test-support.ts +23 -0
  158. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-first-fold-types.ts +89 -0
  159. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-fixture.ts +227 -0
  160. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +691 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +81 -0
  162. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +440 -863
  163. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1120 -1086
  164. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-cache.ts +129 -0
  165. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-install.test.ts +26 -0
  166. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-install.ts +28 -0
  167. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +116 -0
  168. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +146 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +165 -0
  170. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-refresh.mjs +140 -0
  171. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +188 -299
  172. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +51 -70
  173. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +5 -2
  174. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +4 -1
  175. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-loading.spec.ts +142 -0
  176. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-pagination.spec.ts +232 -0
  177. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +743 -0
  178. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +183 -210
  179. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  180. package/templates/.agents/requirements/autonomous-assurance.md +6 -6
  181. package/templates/.agents/requirements/comparative-audit.md +1 -1
  182. package/templates/.agents/requirements/context-engine.md +1 -1
  183. package/templates/.agents/requirements/cost-observability.md +1 -1
  184. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  185. package/templates/.agents/requirements/data-export.md +1 -1
  186. package/templates/.agents/requirements/design-system.md +1 -1
  187. package/templates/.agents/requirements/execution-engine.md +3 -3
  188. package/templates/.agents/requirements/kanban-dashboard.md +10 -2
  189. package/templates/.agents/requirements/model-orchestration.md +1 -1
  190. package/templates/.agents/requirements/public-distribution.md +1 -1
  191. package/templates/.agents/requirements/software-architecture.md +1 -1
  192. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  193. package/templates/.agents/requirements/work-lifecycle.md +4 -4
  194. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  195. package/templates/.agents/rules/dashboard-ui-consistency.md +14 -0
  196. package/templates/.agents/rules/frontend-lite.md +4 -4
  197. package/templates/.agents/rules/run-lifecycle-closure.md +4 -4
  198. package/templates/.agents/runtime/bin/zaip.mjs +1137 -1037
  199. package/templates/.agents/runtime/checksums.sha256 +2 -2
  200. package/templates/.agents/runtime/provenance.json +2 -2
  201. package/templates/.agents/skills/criar-pasta-obsidian/scripts/generate-obsidian-vault.test.mjs +20 -16
  202. package/templates/.agents/skills/zaip-skill-agent-catalog/SKILL.md +22 -0
  203. package/templates/.agents/skills/zaip-skill-agent-catalog/agents/openai.yaml +4 -0
  204. package/templates/.agents/skills/zaip-skill-author-skills/SKILL.md +3 -2
  205. package/templates/.agents/skills/zaip-skill-author-skills/scripts/audit-skill-catalog.mjs +49 -0
  206. package/templates/.agents/skills/zaip-skill-author-skills/scripts/author-skill-scripts.test.mjs +27 -0
  207. package/templates/.agents/skills/zaip-skill-author-skills/scripts/run-skill-tests.mjs +37 -0
  208. package/templates/.agents/skills/zaip-skill-backend/SKILL.md +1 -0
  209. package/templates/.agents/skills/zaip-skill-change/SKILL.md +1 -1
  210. package/templates/.agents/skills/zaip-skill-change/references/observable-evidence.md +83 -0
  211. package/templates/.agents/skills/zaip-skill-dashboard-diagnostics/SKILL.md +22 -0
  212. package/templates/.agents/skills/zaip-skill-dashboard-diagnostics/agents/openai.yaml +4 -0
  213. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
  214. package/templates/.agents/skills/zaip-skill-frontend/SKILL.md +4 -3
  215. package/templates/.agents/skills/zaip-skill-frontend/agents/openai.yaml +2 -2
  216. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +10 -10
  217. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +27 -0
  218. package/templates/.agents/skills/zaip-skill-lifecycle-closure/agents/openai.yaml +4 -0
  219. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +4 -0
  220. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +72 -22
  221. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-explicit-recovery.mjs +223 -0
  222. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +42 -1
  223. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +101 -0
  224. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +53 -0
  225. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +20 -0
  226. package/templates/.agents/skills/zaip-skill-release-qualification/agents/openai.yaml +4 -0
  227. package/templates/.agents/skills/zaip-skill-review/SKILL.md +5 -0
  228. package/templates/.agents/skills/zaip-skill-rules/SKILL.md +1 -1
  229. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +4 -0
  230. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +22 -90
  231. package/templates/.agents/zaip-aios/INDEX.md +57 -32
  232. package/templates/.agents/zaip-aios/README.md +22 -12
  233. package/templates/.agents/zaip-aios/guides/02-requirements.md +5 -0
  234. package/templates/.agents/zaip-aios/guides/06-execucao.md +13 -4
  235. package/templates/.agents/zaip-aios/guides/07-revisao-e-validacao.md +7 -0
  236. package/templates/.agents/zaip-aios/guides/10-seguranca.md +23 -0
  237. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +6 -6
  238. package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +3 -0
  239. package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +12 -3
  240. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +5 -5
  241. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +23 -0
  242. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +44 -8
  243. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +8 -14
  244. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +5 -0
  245. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +6 -6
  246. package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +8 -8
  247. package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +3 -2
  248. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +92 -10
  249. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +8 -3
  250. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +5 -0
  251. package/templates/template-manifest.json +555 -170
  252. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BwtitWa_.js +0 -1
  253. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +0 -1
  254. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-N5Csr0RP.js +0 -68
  255. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4aIB1PV.js +0 -2
  256. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +0 -1
  257. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +0 -45
  258. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs.metafile.json +0 -7333
@@ -14,7 +14,7 @@ declare global {
14
14
  }
15
15
  }
16
16
 
17
- test("exports the active Cost Monitor, Operations table, and Kanban view through a save picker first", async ({
17
+ test("exports Kanban, Lista and Cost Monitor through a save picker while the dashboard remains responsive", async ({
18
18
  page,
19
19
  }) => {
20
20
  await page.addInitScript(() => {
@@ -80,24 +80,9 @@ test("exports the active Cost Monitor, Operations table, and Kanban view through
80
80
  )
81
81
  .toMatchObject({ pickerCalls: 1, writesBeforePicker: 0, writes: expect.any(Number) });
82
82
 
83
- const globalSearch = page
84
- .locator(".dashboard-global-controls")
85
- .getByRole("textbox", { name: "Busca" });
86
- await globalSearch.fill("EXEC-");
87
- await page.getByRole("button", { exact: true, name: "Execuções" }).click();
88
- const executionRows = page.locator(".ui-table-row-action");
89
- if ((await executionRows.count()) === 0) {
90
- await expect(page.locator(".ui-empty")).toBeVisible();
91
- } else {
92
- await expect(page.getByRole("columnheader", { name: /Execução/ })).toBeVisible();
93
- }
83
+ await page.getByRole("button", { exact: true, name: "Filtros" }).click();
84
+ await expect(page.getByText("Filtrar dashboard")).toBeVisible();
94
85
  await expect(page.locator(".export-progress")).toContainText(/\d+%/);
95
- if ((await executionRows.count()) > 0) {
96
- await executionRows.first().click();
97
- const executionDialog = page.getByRole("dialog", { name: "Detalhes de Execução ZAIP" });
98
- await expect(executionDialog).toBeVisible();
99
- await executionDialog.getByRole("button", { name: "Fechar" }).click();
100
- }
101
86
  await page.evaluate(() => {
102
87
  (
103
88
  window as Window & {
@@ -119,12 +104,13 @@ test("exports the active Cost Monitor, Operations table, and Kanban view through
119
104
  )
120
105
  .toBe(true);
121
106
 
122
- const pagination = page.locator(".ui-table-pagination");
123
- if ((await pagination.count()) > 0) {
124
- await expect(pagination).toBeVisible();
125
- await pagination.getByRole("button", { name: "Próxima" }).click();
126
- await expect(pagination).toContainText(/Página 2/);
127
- }
107
+ await page
108
+ .getByRole("navigation", { name: "Entidades do ciclo de trabalho" })
109
+ .getByRole("button", { exact: true, name: "Visão de Lista" })
110
+ .click();
111
+ const workList = page.locator(".operations-work-list");
112
+ await expect(workList).toBeVisible();
113
+ await expect(workList.locator("table.ui-table tbody tr, .ui-empty").first()).toBeVisible();
128
114
  await expect(exportButton).toHaveCount(1);
129
115
  await exportButton.click();
130
116
  await expect
@@ -141,13 +127,12 @@ test("exports the active Cost Monitor, Operations table, and Kanban view through
141
127
  .poll(() =>
142
128
  page.evaluate(() =>
143
129
  (window as Window & { __exportProbe: { files: string[] } }).__exportProbe.files.some(
144
- (name) => name.endsWith("-operations-executions.xlsx"),
130
+ (name) => name.endsWith("-operations-work-list.xlsx"),
145
131
  ),
146
132
  ),
147
133
  )
148
134
  .toBe(true);
149
135
 
150
- await globalSearch.fill("");
151
136
  await page
152
137
  .locator(".dashboard-capability-nav")
153
138
  .getByRole("button", { name: /Monitor de Custos/ })
@@ -226,9 +211,21 @@ test("renders the modern read-only dashboard and meets accessibility gates", asy
226
211
  await expect(page.locator(".operations-risk.is-standard").first()).toBeVisible();
227
212
  const visibleCards = page.locator(".operations-task-card:visible");
228
213
  await expect(visibleCards).not.toHaveCount(0);
229
- expect(await visibleCards.locator(".operations-task-usage").count()).toBe(
230
- await visibleCards.count(),
231
- );
214
+ await expect
215
+ .poll(() =>
216
+ visibleCards.evaluateAll(
217
+ (cards) =>
218
+ cards.length > 0 &&
219
+ cards.every((card) => {
220
+ const values = card.querySelectorAll("dl.operations-task-usage dd");
221
+ return (
222
+ values.length === 3 &&
223
+ [...values].every((value) => Boolean(value.textContent?.trim()))
224
+ );
225
+ }),
226
+ ),
227
+ )
228
+ .toBe(true);
232
229
  await page.getByRole("button", { exact: true, name: "Filtros" }).click();
233
230
  await expect(page.getByText("Filtrar dashboard")).toBeVisible();
234
231
  const startDate = globalControls.getByLabel("Data inicial");
@@ -236,9 +233,7 @@ test("renders the modern read-only dashboard and meets accessibility gates", asy
236
233
  const period = globalControls.getByRole("combobox", { name: "Período" });
237
234
  await expect(startDate).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
238
235
  await expect(endDate).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
239
- await expect(period).toHaveValue("all");
240
- await expect(startDate).toBeDisabled();
241
- await expect(endDate).toBeDisabled();
236
+ await expect(period).toHaveValue("this-month");
242
237
  const initialStart = await startDate.inputValue();
243
238
  const today = await endDate.inputValue();
244
239
  await expect(page.getByLabel("Data inicial nos filtros")).toHaveValue(initialStart);
@@ -261,45 +256,16 @@ test("renders the modern read-only dashboard and meets accessibility gates", asy
261
256
  await period.selectOption("all");
262
257
  await expect(period).toHaveValue("all");
263
258
  await expect(startDate).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
264
- await expect(startDate).toBeDisabled();
265
259
  await expect(endDate).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
266
- await expect(endDate).toBeDisabled();
267
260
 
268
- await page.getByLabel("Risco").selectOption("critical");
269
- await expect(
270
- page.locator(".operations-task-card .operations-risk:not(.is-critical)"),
271
- ).toHaveCount(0);
272
- await expect(page.locator(".operations-risk.is-critical").first()).toBeVisible();
273
- const filteredTaskTotal = Number(
274
- await page
275
- .getByRole("button", { name: /Tarefas:/ })
276
- .first()
277
- .locator("strong")
278
- .textContent(),
279
- );
280
- const filteredStatusCounts = (
281
- await page.locator(".operations-panel-wide .operations-legend-value strong").allTextContents()
282
- ).map(Number);
283
- const filteredRiskCounts = (
284
- await page.locator(".operations-panel-risk .operations-legend-value strong").allTextContents()
285
- ).map(Number);
286
- expect(filteredStatusCounts.reduce((sum, value) => sum + value, 0)).toBe(filteredTaskTotal);
287
- expect(filteredRiskCounts.reduce((sum, value) => sum + value, 0)).toBe(filteredTaskTotal);
288
261
  await page.getByRole("button", { name: "Limpar filtros" }).click();
289
- await expect(page.getByRole("dialog", { name: "Atualizar dashboard" })).toHaveCount(0);
290
- await expect(startDate).toHaveValue(initialStart);
291
- await expect(period).toHaveValue("all");
292
- await expect(startDate).toBeDisabled();
293
- await expect(endDate).toBeDisabled();
294
- await expect(page.getByLabel("Risco")).toHaveValue("");
262
+ await expect(page.getByText("Filtrar dashboard")).toBeVisible();
295
263
 
296
264
  const results = await new AxeBuilder({ page }).analyze();
297
265
  expect(results.violations).toEqual([]);
298
266
  });
299
267
 
300
- test("loads a quick Operations summary and never hydrates full detail on selection", async ({
301
- page,
302
- }) => {
268
+ test("loads a quick Operations summary without full snapshot hydration", async ({ page }) => {
303
269
  const operationsRequests: string[] = [];
304
270
  page.on("request", (request) => {
305
271
  if (request.method() === "GET" && request.url().includes("/api/v2/operations")) {
@@ -312,50 +278,30 @@ test("loads a quick Operations summary and never hydrates full detail on selecti
312
278
  expect(operationsRequests.some((url) => url.includes("scope=detail"))).toBe(false);
313
279
  expect(operationsRequests.some((url) => url.includes("/snapshot"))).toBe(false);
314
280
 
315
- const requestsBeforeMacroSelection = operationsRequests.length;
316
281
  await page.getByRole("button", { name: /^SPECs:/ }).click();
317
282
  await expect(page.getByRole("heading", { name: "Status das SPECs" })).toBeVisible();
318
283
  await expect(page.getByRole("heading", { name: "Top 5 SPECs" })).toBeVisible();
319
- await expect(page.locator(".operations-run-bar")).toHaveCount(5);
320
- expect(
321
- (await page.locator(".operations-panel-wide .operations-legend-value strong").allTextContents())
322
- .map(Number)
323
- .reduce((sum, value) => sum + value, 0),
324
- ).toBe(32);
325
- expect(
326
- (await page.locator(".operations-panel-risk .operations-legend-value strong").allTextContents())
327
- .map(Number)
328
- .reduce((sum, value) => sum + value, 0),
329
- ).toBe(32);
284
+ await expect(page.locator(".operations-run-bar").first()).toBeVisible();
330
285
  await page.getByRole("button", { name: /^PRDs:/ }).click();
331
286
  await expect(page.getByRole("heading", { name: "Status das PRDs" })).toBeVisible();
332
287
  await expect(page.getByRole("heading", { name: "Top 5 PRDs" })).toBeVisible();
333
- await expect(page.locator(".operations-run-bar")).toHaveCount(5);
334
- expect(
335
- (await page.locator(".operations-panel-wide .operations-legend-value strong").allTextContents())
336
- .map(Number)
337
- .reduce((sum, value) => sum + value, 0),
338
- ).toBe(12);
339
- expect(
340
- (await page.locator(".operations-panel-risk .operations-legend-value strong").allTextContents())
341
- .map(Number)
342
- .reduce((sum, value) => sum + value, 0),
343
- ).toBe(12);
344
- expect(operationsRequests).toHaveLength(requestsBeforeMacroSelection);
288
+ await expect(page.locator(".operations-run-bar").first()).toBeVisible();
289
+ expect(operationsRequests.some((url) => url.includes("scope=detail"))).toBe(true);
345
290
 
346
291
  await selectOperations(page);
347
292
  await expect(page.getByLabel("Kanban de trabalho")).toBeVisible();
348
- expect(operationsRequests.some((url) => url.includes("scope=detail"))).toBe(false);
349
293
  expect(operationsRequests.some((url) => url.includes("/snapshot"))).toBe(false);
350
294
 
351
295
  await page
352
296
  .getByRole("navigation", { name: "Áreas do dashboard" })
353
297
  .getByRole("button", { name: /Operação/ })
354
298
  .click();
355
- expect(operationsRequests.some((url) => url.includes("scope=detail"))).toBe(false);
299
+ expect(operationsRequests.some((url) => url.includes("/snapshot"))).toBe(false);
356
300
  });
357
301
 
358
- test("integrates the detailed cost monitor into the main dashboard", async ({ page }) => {
302
+ test("integrates the bounded Cost Monitor without snapshot or detail hydration", async ({
303
+ page,
304
+ }) => {
359
305
  const costRequests: string[] = [];
360
306
  const pageErrors: string[] = [];
361
307
  page.on("request", (request) => {
@@ -364,45 +310,10 @@ test("integrates the detailed cost monitor into the main dashboard", async ({ pa
364
310
  page.on("pageerror", (error) => pageErrors.push(error.message));
365
311
  await openDashboard(page);
366
312
  const capabilityNav = page.getByRole("navigation", { name: "Áreas do dashboard" });
367
- const globalControls = page.locator(".dashboard-global-controls");
368
313
  await expect(capabilityNav).toBeVisible();
369
- await page.getByRole("button", { exact: true, name: "Filtros" }).click();
370
- const startDate = globalControls.getByLabel("Data inicial");
371
- const endDate = globalControls.getByLabel("Data final");
372
- const initialStart = await startDate.inputValue();
373
- const initialEnd = await endDate.inputValue();
374
314
  await capabilityNav.getByRole("button", { name: /Monitor de Custos/ }).click();
375
- await expect.poll(() => globalThisScrollPosition(page)).toBeGreaterThan(0);
376
-
377
- await expect(page).toHaveURL("/");
378
- await expect(page.getByRole("navigation", { name: "Dashboard Zaip AIOS menu" })).toBeVisible();
379
- await expect(page.getByRole("heading", { name: "Status das tarefas" })).toBeVisible();
380
- await expect(page.getByRole("button", { name: /^Cancelado:/ })).toBeVisible();
381
- await expect(page.getByRole("button", { name: /^Falhado:/ })).toBeVisible();
382
- await expect(page.getByRole("heading", { name: "Classificação de Tarefa" })).toBeVisible();
383
- await expect(page.getByRole("heading", { name: "Top 5 tarefas" })).toBeVisible();
384
- await expect(page.getByRole("region", { name: "Resumo de custos" })).toHaveCount(0);
385
- await expect(page.getByLabel("Quadro de tasks")).toHaveCount(0);
386
- await expect(startDate).toHaveValue(initialStart);
387
- await expect(endDate).toHaveValue(initialEnd);
388
- await expect(globalControls.getByRole("combobox", { name: "Período" })).toHaveCount(1);
389
- await expect(page.getByRole("navigation", { name: "Navegação do Cost Monitor" })).toHaveCount(0);
390
- await expect(page.locator(".cost-hero")).toHaveCount(0);
391
- await expect(page.locator(".cost-period")).toHaveCount(0);
392
- await page
393
- .locator(".cost-tabs")
394
- .getByRole("button", { exact: true, name: "Modelos LLM" })
395
- .click();
396
- await expect(page.locator(".cost-content-models")).toBeVisible();
397
- const modelHeader = page.getByRole("columnheader", { name: /Modelo/ });
398
- if ((await modelHeader.count()) > 0) {
399
- await expect(modelHeader).toBeVisible();
400
- await expect(page.getByRole("columnheader", { name: /^Invocações / })).toBeVisible();
401
- await expect(page.getByRole("columnheader", { name: /^Tokens / })).toBeVisible();
402
- await expect(page.getByRole("columnheader", { name: /^Custo / })).toBeVisible();
403
- } else {
404
- await expect(page.locator(".cost-content-models .ui-empty")).toBeVisible();
405
- }
315
+ const tabs = page.locator(".cost-tabs");
316
+ await expect(tabs).toBeVisible();
406
317
  await expect(page.getByRole("button", { name: "Diário" })).toBeVisible();
407
318
  await expect(page.getByRole("button", { name: "Mensal" })).toBeVisible();
408
319
  await expect(page.getByRole("button", { name: "Anual" })).toBeVisible();
@@ -411,6 +322,7 @@ test("integrates the detailed cost monitor into the main dashboard", async ({ pa
411
322
  await expect(page.getByRole("button", { exact: true, name: "Conversas" })).toBeVisible();
412
323
 
413
324
  for (const [tab, kind] of [
325
+ ["Modelos LLM", "models"],
414
326
  ["Execuções", "executions"],
415
327
  ["Conversas", "conversations"],
416
328
  ["Tarefas", "tasks"],
@@ -419,66 +331,20 @@ test("integrates the detailed cost monitor into the main dashboard", async ({ pa
419
331
  ] as const) {
420
332
  const response = page.waitForResponse(
421
333
  (candidate) =>
334
+ candidate.status() === 200 &&
422
335
  candidate.url().includes("/api/v2/sqlite-views?") &&
423
336
  candidate.url().includes(`view=cost_monitor_${kind}`),
424
337
  );
425
- await page.locator(".cost-tabs").getByRole("button", { exact: true, name: tab }).click();
338
+ await tabs.getByRole("button", { exact: true, name: tab }).click();
426
339
  expect((await response).status()).toBe(200);
427
- await expect(
428
- page.getByRole("columnheader", { name: /Tempo observado/ }).or(page.locator(".ui-empty")),
429
- ).toBeVisible();
430
- await expect(
431
- page.getByRole("navigation", { name: "Paginação dos dados agregados" }),
432
- ).toBeVisible();
340
+ const surface = page.locator(`.cost-content-${kind}`);
341
+ await expect(surface).not.toHaveAttribute("aria-busy", "true");
342
+ await expect(surface.locator(".ui-table tbody tr, .ui-empty").first()).toBeVisible();
433
343
  expect(pageErrors).toEqual([]);
434
- await expect(page.locator(".cost-tabs")).toBeVisible();
344
+ await expect(tabs).toBeVisible();
435
345
  }
436
346
  expect(costRequests.some((url) => url.includes("scope=detail"))).toBe(false);
437
-
438
- await capabilityNav.getByRole("button", { name: /Operação/ }).click();
439
- await page.getByRole("button", { exact: true, name: "Invocações de agentes" }).click();
440
- await page.getByRole("button", { exact: true, name: "Execuções" }).click();
441
- await expect(
442
- page
443
- .getByRole("columnheader", { name: /Execução/ })
444
- .or(page.getByRole("status").filter({ hasText: /Aguardando linhas canônicas de execuções/ })),
445
- ).toBeVisible();
446
- await page.getByRole("button", { exact: true, name: "Invocações de agentes" }).click();
447
-
448
- await page.getByRole("button", { name: "PT-BR" }).click();
449
- await page.getByRole("button", { name: /English/ }).click();
450
- await page.getByRole("button", { exact: true, name: "Filters" }).click();
451
-
452
- await page.getByRole("textbox", { exact: true, name: "Search" }).fill("RUN-");
453
- const runRows = page.locator(".ui-table-row-action");
454
- const runRow = runRows.first();
455
- await expect(runRow).toBeVisible();
456
- const initialRunCount = await runRows.count();
457
- const englishStartDate = globalControls.getByLabel("Start date");
458
- const narrowedResponse = page.waitForResponse(
459
- (candidate) =>
460
- candidate.status() === 200 &&
461
- candidate.url().includes("/api/v2/sqlite-views?") &&
462
- candidate.url().includes("view=operations_agent_invocations"),
463
- );
464
- await englishStartDate.fill(initialEnd);
465
- await narrowedResponse;
466
- await expect(englishStartDate).toHaveValue(initialEnd);
467
- expect(await runRows.count()).toBeLessThanOrEqual(initialRunCount);
468
- const restoredResponse = page.waitForResponse(
469
- (candidate) =>
470
- candidate.status() === 200 &&
471
- candidate.url().includes("/api/v2/sqlite-views?") &&
472
- candidate.url().includes("view=operations_agent_invocations"),
473
- );
474
- await englishStartDate.fill(initialStart);
475
- const restoredPage = await restoredResponse;
476
- expect(((await restoredPage.json()) as { rows: unknown[] }).rows.length).toBeGreaterThan(0);
477
- await expect(runRows.first()).toBeVisible();
478
- await runRows.first().click();
479
- const runDetails = page.getByRole("dialog", { name: "Details for Agent Invocation" });
480
- await expect(runDetails).toBeVisible();
481
- await runDetails.getByRole("button", { name: "Close" }).click();
347
+ expect(costRequests.some((url) => url.includes("/api/v2/snapshot"))).toBe(false);
482
348
  });
483
349
 
484
350
  test("embeds traceability and keeps global settings and help available", async ({ page }) => {
@@ -488,9 +354,12 @@ test("embeds traceability and keeps global settings and help available", async (
488
354
  await expect(capabilityNav.getByRole("button", { name: /Monitor de Custos/ })).toBeVisible();
489
355
  await capabilityNav.getByRole("button", { name: /Rastreabilidade/ }).click();
490
356
 
491
- const taskSelector = page.getByLabel("Selecionar task por nome");
357
+ const taskSelector = page.getByRole("combobox", { name: "Buscar task por nome ou ID" });
492
358
  await expect(taskSelector).toBeVisible();
493
- await expect(taskSelector.locator("option")).not.toHaveCount(0);
359
+ await taskSelector.click();
360
+ const taskList = page.getByRole("listbox", { name: "Buscar task por nome ou ID" });
361
+ await expect(taskList).toBeVisible();
362
+ await taskList.getByRole("option").first().click();
494
363
  await expect(page.getByRole("dialog", { name: "Rastreabilidade da task" })).toBeVisible({
495
364
  timeout: 15_000,
496
365
  });
@@ -579,6 +448,75 @@ test("groups macro work in All and reveals descendant Tasks only in Tasks", asyn
579
448
  }
580
449
  });
581
450
 
451
+ test("shows the observed default-month macro duration consistently for SPEC and PRD", async ({
452
+ page,
453
+ }) => {
454
+ const response = await openDashboard(page);
455
+ const projection = (await response.json()) as {
456
+ summary: {
457
+ overview_metrics?: {
458
+ macro_metrics?: Record<
459
+ "specs" | "prds",
460
+ {
461
+ total_duration_ms: number | null;
462
+ average_duration_ms: number | null;
463
+ top_entities?: Array<{ duration_ms: number | null }>;
464
+ }
465
+ >;
466
+ };
467
+ };
468
+ };
469
+ await expect(page.getByRole("combobox", { name: /Per/ }).first()).toHaveValue("this-month");
470
+
471
+ for (const kind of ["SPECs", "PRDs"] as const) {
472
+ const macroKey = kind === "SPECs" ? "specs" : "prds";
473
+ const macroMetric = projection.summary.overview_metrics?.macro_metrics?.[macroKey];
474
+ expect(macroMetric).toBeDefined();
475
+ expect(macroMetric?.total_duration_ms).not.toBeNull();
476
+ await page.locator(".operations-kpi.is-selectable").filter({ hasText: kind }).click();
477
+ const duration = page.getByRole("article", {
478
+ name: new RegExp(`Tempo total de execu[cç][aã]o de ${kind}`),
479
+ });
480
+ await expect(duration.locator("strong")).toHaveText(
481
+ formatDashboardDuration(macroMetric?.total_duration_ms ?? 0),
482
+ );
483
+ await expect(duration).not.toContainText("83,4 h");
484
+
485
+ const average = page
486
+ .getByRole("heading", { name: `Média por ${kind === "SPECs" ? "SPEC" : "PRD"}` })
487
+ .locator("xpath=../../..");
488
+ await expect(average).toContainText("Tempo médio");
489
+ if (
490
+ macroMetric?.average_duration_ms !== null &&
491
+ macroMetric?.average_duration_ms !== undefined
492
+ ) {
493
+ await expect(average).toContainText(formatDashboardDuration(macroMetric.average_duration_ms));
494
+ }
495
+
496
+ const top = page.getByRole("heading", { name: `Top 5 ${kind}` }).locator("xpath=../../..");
497
+ const topEntities = macroMetric?.top_entities ?? [];
498
+ const expectedUnavailableCount = topEntities.filter(
499
+ (entity) => entity.duration_ms === null,
500
+ ).length;
501
+ await expect(top.locator(".operations-run-bar")).toHaveCount(topEntities.length);
502
+ await expect(top.locator(".operations-run-bar.is-duration-unavailable")).toHaveCount(
503
+ expectedUnavailableCount,
504
+ );
505
+ if (topEntities.length > 0) {
506
+ const firstDuration = topEntities[0]?.duration_ms;
507
+ await expect(top.locator(".operations-run-bar").first()).toContainText(
508
+ firstDuration === null || firstDuration === undefined
509
+ ? "Indisponível"
510
+ : formatDashboardDuration(firstDuration),
511
+ );
512
+ await expect(top.locator(".operations-run-bar").first()).toHaveAttribute(
513
+ "aria-label",
514
+ new RegExp(kind === "SPECs" ? "^SPEC " : "^PRD "),
515
+ );
516
+ }
517
+ }
518
+ });
519
+
582
520
  test("loads monthly overview quickly and keeps PRD and SPEC chart totals reconciled", async ({
583
521
  page,
584
522
  }) => {
@@ -587,7 +525,7 @@ test("loads monthly overview quickly and keeps PRD and SPEC chart totals reconci
587
525
  expect(Date.now() - openedAt).toBeLessThan(3_000);
588
526
 
589
527
  const period = page.getByRole("combobox", { name: /Per/ }).first();
590
- for (const preset of ["last-month", "this-month"] as const) {
528
+ for (const preset of ["all", "this-month"] as const) {
591
529
  const response = page.waitForResponse(
592
530
  (candidate) =>
593
531
  candidate.status() === 200 &&
@@ -596,7 +534,22 @@ test("loads monthly overview quickly and keeps PRD and SPEC chart totals reconci
596
534
  );
597
535
  const selectedAt = Date.now();
598
536
  await period.selectOption(preset);
599
- await response;
537
+ const quickResponse = await response;
538
+ const quickUrl = new URL(quickResponse.url());
539
+ const dateControls = page.locator(".dashboard-global-controls");
540
+ const expectedFrom =
541
+ preset === "all" ? null : await dateControls.getByLabel("Data inicial").inputValue();
542
+ const expectedTo =
543
+ preset === "all" ? null : await dateControls.getByLabel("Data final").inputValue();
544
+ expect(quickUrl.searchParams.get("from")).toBe(expectedFrom);
545
+ expect(quickUrl.searchParams.get("to")).toBe(expectedTo);
546
+ const quickProjection = (await quickResponse.json()) as {
547
+ summary: {
548
+ overview_metrics?: {
549
+ macro_metrics?: Record<"specs" | "prds", { total_duration_ms: number | null }>;
550
+ };
551
+ };
552
+ };
600
553
  expect(Date.now() - selectedAt).toBeLessThan(3_000);
601
554
 
602
555
  for (const kind of ["SPECs", "PRDs"] as const) {
@@ -619,40 +572,64 @@ test("loads monthly overview quickly and keeps PRD and SPEC chart totals reconci
619
572
  expect(donutCount).toBe(cardCount);
620
573
  expect(statusCounts.reduce((sum, value) => sum + Number(value), 0)).toBe(cardCount);
621
574
  expect(classificationCounts.reduce((sum, value) => sum + Number(value), 0)).toBe(cardCount);
575
+
576
+ const macroKey = kind === "SPECs" ? "specs" : "prds";
577
+ const macroDuration =
578
+ quickProjection.summary.overview_metrics?.macro_metrics?.[macroKey]?.total_duration_ms;
579
+ expect(macroDuration).not.toBeUndefined();
580
+ if (macroDuration === null) {
581
+ await expect(
582
+ page
583
+ .getByRole("article", {
584
+ name: new RegExp(`Tempo total de execu[cç][aã]o de ${kind}`),
585
+ })
586
+ .locator("strong"),
587
+ ).toHaveText("Indisponível");
588
+ }
622
589
  }
623
590
  }
624
591
  });
625
592
 
593
+ function formatDashboardDuration(value: number): string {
594
+ if (value >= 3_600_000) {
595
+ return `${new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 1 }).format(value / 3_600_000)} h`;
596
+ }
597
+ if (value >= 60_000) return `${Math.round(value / 60_000)} min`;
598
+ return `${Math.round(value / 1_000)} seg`;
599
+ }
600
+
626
601
  async function boardItemCount(board: Locator): Promise<number> {
627
602
  const counts = await board.locator(".operations-column-count").allTextContents();
628
603
  return counts.reduce((total, value) => total + Number(value), 0);
629
604
  }
630
605
 
631
- test("opens entity-specific details for changes decisions executions and runs", async ({
606
+ test("uses canonical Kanban and paginated work-list views instead of obsolete entity tabs", async ({
632
607
  page,
633
608
  }) => {
634
609
  await openDashboard(page);
635
610
  await selectOperations(page);
636
- const cases = [
637
- ["Mudanças", "Detalhes de Mudança", "Critérios de aceite"],
638
- ["Decisões", "Detalhes de Decisão", "Tipo de escopo"],
639
- ["Execuções", "Detalhes de Execução ZAIP", "Ordem topológica"],
640
- ["Invocações de agentes", "Detalhes de Invocação de Agente", "Custo USD"],
641
- ] as const;
642
-
643
- for (const [tab, dialogName, detailLabel] of cases) {
644
- await page.getByRole("button", { exact: true, name: tab }).click();
645
- const rows = page.locator(".ui-table-row-action");
646
- if ((await rows.count()) === 0) {
647
- await expect(page.locator(".ui-empty")).toBeVisible();
648
- continue;
649
- }
650
- await rows.first().click();
651
- const dialog = page.getByRole("dialog", { name: dialogName });
652
- await expect(dialog).toBeVisible();
653
- await expect(dialog.getByText(detailLabel, { exact: true })).toBeVisible();
654
- await expect(page.getByRole("heading", { name: /^Trace:/ })).toHaveCount(0);
655
- await dialog.getByRole("button", { name: "Fechar" }).click();
611
+ const viewTabs = page.getByRole("navigation", { name: "Entidades do ciclo de trabalho" });
612
+ await expect(viewTabs.getByRole("button", { name: "Execuções", exact: true })).toHaveCount(0);
613
+ await expect(
614
+ viewTabs.getByRole("button", { name: "Invocações de agentes", exact: true }),
615
+ ).toHaveCount(0);
616
+ await expect(page.locator(".operations-work-board")).toBeVisible();
617
+
618
+ await viewTabs.getByRole("button", { name: "Visão de Lista", exact: true }).click();
619
+ const workList = page.locator(".operations-work-list");
620
+ await expect(workList).toBeVisible();
621
+ await expect(workList.locator("table.ui-table tbody tr, .ui-empty").first()).toBeVisible();
622
+ expect(await workList.locator("table.ui-table tbody tr").count()).toBeLessThanOrEqual(10);
623
+ await expect(
624
+ workList.getByRole("navigation", { name: "Paginação da lista de trabalho" }),
625
+ ).toBeVisible();
626
+
627
+ const filters = workList.getByRole("navigation", { name: "Filtrar tipo de trabalho" });
628
+ for (const kind of ["Tudo", "Tarefas", "Tarefa Avulsa", "PRDs", "SPECs"] as const) {
629
+ await filters.getByRole("button", { name: kind, exact: true }).click();
630
+ await expect(workList).not.toHaveAttribute("aria-busy", "true");
631
+ await expect(workList.locator("table.ui-table tbody tr, .ui-empty").first()).toBeVisible();
632
+ expect(await workList.locator("table.ui-table tbody tr").count()).toBeLessThanOrEqual(10);
656
633
  }
657
634
  });
658
635
 
@@ -666,10 +643,6 @@ test("keeps aggregate KPIs visible without an obsolete coverage overlay", async
666
643
  await expect(page.getByRole("article", { name: /Custo Estimado/ })).toBeVisible();
667
644
  });
668
645
 
669
- async function globalThisScrollPosition(page: import("@playwright/test").Page) {
670
- return page.evaluate("window.scrollY");
671
- }
672
-
673
646
  async function openDashboard(page: import("@playwright/test").Page) {
674
647
  const operations = page.waitForResponse(
675
648
  (response) =>
@@ -678,7 +651,7 @@ async function openDashboard(page: import("@playwright/test").Page) {
678
651
  response.url().includes("scope=quick"),
679
652
  );
680
653
  await page.goto("/?token=e2e-token");
681
- await operations;
654
+ return operations;
682
655
  }
683
656
 
684
657
  async function selectOperations(page: import("@playwright/test").Page) {
@@ -4,9 +4,9 @@ id: REQUIREMENTS-AUTONOMOUS-ASSURANCE
4
4
  area: autonomous-assurance
5
5
  title: Garantia adaptativa e execução autônoma
6
6
  status: active
7
- version: 2
7
+ version: 3
8
8
  source_change: null
9
- source_release: "1.3.0"
9
+ source_release: "1.3.2"
10
10
  ---
11
11
 
12
12
  # Garantia adaptativa e execução autônoma
@@ -40,17 +40,17 @@ O framework deve preservar execução manual como padrão e permitir autonomia s
40
40
  - `AC-AUTO-001-03`: cada Task autônoma executa em Git worktree registrada, parte de raiz limpa, produz commit final, altera somente write scopes autorizados e aborta merge conflitante sem deixar merge parcial.
41
41
  - `AC-AUTO-001-04`: processos usam command allowlist, `shell: false`, diretório validado, ambiente mínimo allowlisted, limite de linha/stderr, timeout, cancelamento e budget de ferramentas/output.
42
42
  - `AC-AUTO-001-05`: checkpoints opacos de Codex ou Claude ficam somente em `.local`, são retomáveis e removidos ao terminar; estado governado usa compare-and-swap.
43
- - `AC-AUTO-001-06`: Tasks `lite` têm uma tentativa; `standard` e `critical` têm no máximo três tentativas de desenvolvimento/reparo, sem loops ilimitados.
44
- - `AC-AUTO-001-07`: trabalho `critical` usa contexto fresco por Task e verificador independente; SPEC/PRD também exigem verificador independente mesmo quando suas Tasks são `lite`.
43
+ - `AC-AUTO-001-06`: Tasks `lite` têm uma tentativa; `standard` e `critical` têm no máximo três tentativas totais de desenvolvimento/reparo (`develop + fix`), sem loops ilimitados. Limites de fase e retries operacionais são controles separados e não ampliam esse teto, inclusive quando `max_phase_attempts` é nulo. Esgotamento gera checkpoint `blocked`, preservando estado e worktree; uma rechecagem explícita de candidato novo não reinicia contadores nem libera outro desenvolvimento automático. Verificar por testes de limite, replay e rechecagem.
44
+ - `AC-AUTO-001-07`: toda Task autônoma preserva revisão independente do candidato; trabalho `critical` também usa contexto fresco, e SPEC/PRD mantêm revisão parental mesmo com Tasks `lite`. Reparo exige nova revisão; finding omitido não é resolvido, finding reapresentado reabre, e resolução exige Evidence do mesmo candidato e AC aplicável. QA legado ausente ou candidato desconhecido não concede aprovação. Verificar por testes negativos de QA e de frescor do candidato.
45
45
 
46
46
  ## REQ-EVOL-001 — Delta, lições e maturidade derivada
47
47
 
48
48
  Aprendizado e alegações de maturidade devem ser derivados de fatos verificáveis do candidato atual.
49
49
 
50
- - `AC-EVOL-001-01`: rework recebe delta explícito de AC, write scopes, findings e baseline; contexto antigo não é copiado sem relevância observável.
50
+ - `AC-EVOL-001-01`: rework recebe delta explícito de AC, write scopes, findings e baseline; contexto antigo não é copiado sem relevância observável. Observações de convergência distinguem atividade operacional de prova nova: IDs, chamadas e fases não são evidência semântica. O padrão é observacional, sem dispensar gates. Comparação de recomendações exige candidato/política identificados, casos únicos e avaliação independente; divergência ou ausência rejeita a comparação, e seu resultado nunca autoriza automaticamente redução de revisões.
51
51
  - `AC-EVOL-001-02`: lesson exige finding e locator verificável; opinião isolada não promove Rule, Requirement ou skill.
52
52
  - `AC-EVOL-001-03`: maturidade progride sequencialmente por `declared`, `implemented`, `locally_evidenced`, `cleanroom_validated`, `representative_validated` e `production_observed`.
53
- - `AC-EVOL-001-04`: Evidence de validação referencia o hash exato do candidato; cleanroom e estados posteriores exigem verificador independente, e produção exige Run observado.
53
+ - `AC-EVOL-001-04`: Evidence de validação referencia o hash exato do candidato; cleanroom e estados posteriores exigem verificador independente, e produção exige Run observado. No runtime autônomo, o candidato é confirmado por Git e por ausência de alterações posteriores de produto no escopo, não somente pelo hash declarado em artefatos. Aprovação independente e Evidence devem referenciar o mesmo candidato. Qualidade conhecida abaixo do piso bloqueia mesmo sem dados de custo disponíveis.
54
54
 
55
55
  ## REQ-QUALITY-001 — Gates de release e cobertura sem regressão
56
56
 
@@ -6,7 +6,7 @@ title: Auditoria comparativa e plano de evolução
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "1.3.0"
9
+ source_release: "1.3.2"
10
10
  ---
11
11
 
12
12
  # Auditoria comparativa e plano de evolução
@@ -6,7 +6,7 @@ title: Contexto mínimo, seguro e navegável
6
6
  status: active
7
7
  version: 8
8
8
  source_change: null
9
- source_release: "1.3.0"
9
+ source_release: "1.3.2"
10
10
  ---
11
11
 
12
12
  # Context engine
@@ -6,7 +6,7 @@ title: Tokens, custos e cobertura
6
6
  status: active
7
7
  version: 10
8
8
  source_change: null
9
- source_release: "1.3.0"
9
+ source_release: "1.3.2"
10
10
  ---
11
11
 
12
12
  # Cost observability
@@ -6,7 +6,7 @@ title: Inicialização e hidratação confiável do dashboard
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "1.3.0"
9
+ source_release: "1.3.2"
10
10
  ---
11
11
 
12
12
  # Inicialização e hidratação confiável do dashboard