@zaip-ai/cli 4.8.0 → 5.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 (195) hide show
  1. package/dist/services/adapter-hook-sources.d.ts +3 -0
  2. package/dist/services/adapter-hook-sources.d.ts.map +1 -1
  3. package/dist/services/adapter-hook-sources.js +3 -0
  4. package/dist/services/adapter-hook-sources.js.map +1 -1
  5. package/dist/services/adapters.d.ts +1 -1
  6. package/dist/services/adapters.d.ts.map +1 -1
  7. package/dist/services/adapters.js +5 -2
  8. package/dist/services/adapters.js.map +1 -1
  9. package/dist/services/adapters.test.js +1 -1
  10. package/dist/services/adapters.test.js.map +1 -1
  11. package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
  12. package/dist/services/codex-conversation-lifecycle-hook.js +16 -6
  13. package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
  14. package/dist/services/codex-hook-activation.d.ts +1 -1
  15. package/dist/services/codex-hook-activation.d.ts.map +1 -1
  16. package/dist/services/codex-hook-activation.js +116 -10
  17. package/dist/services/codex-hook-activation.js.map +1 -1
  18. package/dist/services/codex-pre-tool-cli-capture-template.d.ts +2 -0
  19. package/dist/services/codex-pre-tool-cli-capture-template.d.ts.map +1 -0
  20. package/dist/services/codex-pre-tool-cli-capture-template.js +104 -0
  21. package/dist/services/codex-pre-tool-cli-capture-template.js.map +1 -0
  22. package/dist/services/codex-pre-tool-cloud-template.d.ts +2 -0
  23. package/dist/services/codex-pre-tool-cloud-template.d.ts.map +1 -0
  24. package/dist/services/codex-pre-tool-cloud-template.js +190 -0
  25. package/dist/services/codex-pre-tool-cloud-template.js.map +1 -0
  26. package/dist/services/codex-pre-tool-dependencies.test-support.d.ts +2 -0
  27. package/dist/services/codex-pre-tool-dependencies.test-support.d.ts.map +1 -0
  28. package/dist/services/codex-pre-tool-dependencies.test-support.js +9 -0
  29. package/dist/services/codex-pre-tool-dependencies.test-support.js.map +1 -0
  30. package/dist/services/codex-pre-tool-hook-fixture.test-support.d.ts +5 -0
  31. package/dist/services/codex-pre-tool-hook-fixture.test-support.d.ts.map +1 -0
  32. package/dist/services/codex-pre-tool-hook-fixture.test-support.js +19 -0
  33. package/dist/services/codex-pre-tool-hook-fixture.test-support.js.map +1 -0
  34. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.d.ts +2 -0
  35. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.d.ts.map +1 -0
  36. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.js +107 -0
  37. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.js.map +1 -0
  38. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  39. package/dist/services/codex-pre-tool-hook-template.js +152 -190
  40. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  41. package/dist/services/codex-pre-tool-hook-template.test.js +63 -75
  42. package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -1
  43. package/dist/services/codex-pre-tool-host-context-template.d.ts +2 -0
  44. package/dist/services/codex-pre-tool-host-context-template.d.ts.map +1 -0
  45. package/dist/services/codex-pre-tool-host-context-template.js +139 -0
  46. package/dist/services/codex-pre-tool-host-context-template.js.map +1 -0
  47. package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
  48. package/dist/services/codex-pre-tool-support-template.js +77 -100
  49. package/dist/services/codex-pre-tool-support-template.js.map +1 -1
  50. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  51. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  52. package/dist/services/codex-subagent-hook-template.js +59 -15
  53. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  54. package/dist/services/codex-validation-runtime-template.d.ts.map +1 -1
  55. package/dist/services/codex-validation-runtime-template.js +37 -10
  56. package/dist/services/codex-validation-runtime-template.js.map +1 -1
  57. package/dist/services/runtime-template-test-support.d.ts +1 -0
  58. package/dist/services/runtime-template-test-support.d.ts.map +1 -1
  59. package/dist/services/runtime-template-test-support.js +23 -2
  60. package/dist/services/runtime-template-test-support.js.map +1 -1
  61. package/dist/services/runtime-template.test.js +7 -24
  62. package/dist/services/runtime-template.test.js.map +1 -1
  63. package/package.json +1 -1
  64. package/templates/.agents/README-ENG.md +49 -7
  65. package/templates/.agents/README.md +41 -10
  66. package/templates/.agents/config/agents/discovery.json +1 -1
  67. package/templates/.agents/dashboard/.zaip-managed.json +125 -73
  68. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-BW7Vy1cp.js → CostCalculationGuidePage-w6pjt4OM.js} +1 -1
  69. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-BN8KQPrr.js → DashboardHelpDialog-DhlntQcR.js} +117 -17
  70. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Prcs-ydy.js → PricingSettingsDialog-BHoZT2an.js} +1 -1
  71. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-HqGUImIG.js → ProjectSettingsPage-IcncIZ9Y.js} +1 -1
  72. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CNpmQMO4.js → TraceabilityWorkspace-C6rORjpr.js} +1 -1
  73. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-uPnOBShc.js +68 -0
  74. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-CF7B1Hjn.js → dashboard-localization-DWXjEIgc.js} +49 -7
  75. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DOhy6D2-.js → icons-vendor-Hc9fp_gs.js} +1 -1
  76. package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-DX65Ufuu.js → index-BqeOEZW5.js} +2 -2
  77. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CkPC-yMz.js → react-vendor-C9ta_O10.js} +1 -1
  78. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BEdGoIDm.js → traceability-IcefoTOv.js} +1 -1
  79. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  80. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  81. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  82. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +10 -3
  83. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts +5 -1
  84. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.period-values.test.tsx +2 -2
  85. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +5 -5
  86. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +36 -43
  87. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-loaders.ts +1 -0
  88. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-formatters.ts +6 -4
  89. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +2 -2
  90. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +1 -1
  91. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +11 -25
  92. package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-summary-defaults.ts +26 -0
  93. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  94. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +11 -16
  95. package/templates/.agents/dashboard/modules/operations/src/planning-contracts.ts +14 -0
  96. package/templates/.agents/dashboard/modules/operations/src/react/DecisionTable.tsx +65 -0
  97. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +5 -71
  98. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +10 -36
  99. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +7 -2
  100. package/templates/.agents/dashboard/modules/operations/src/react/use-operations-filter-sync.ts +66 -0
  101. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  102. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  103. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  104. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  105. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +229 -222
  106. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +167 -167
  107. package/templates/.agents/dashboard/packages/local-runtime/package.json +3 -3
  108. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +229 -222
  109. package/templates/.agents/dashboard/packages/local-runtime/src/active-capture-failure.test.ts +38 -0
  110. package/templates/.agents/dashboard/packages/local-runtime/src/active-capture-failure.ts +35 -0
  111. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +69 -6
  112. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +62 -15
  113. package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +8 -2
  114. package/templates/.agents/dashboard/packages/local-runtime/src/server-capture-projection-order.test.ts +118 -0
  115. package/templates/.agents/dashboard/packages/local-runtime/src/server-cost-run-search.test.ts +90 -0
  116. package/templates/.agents/dashboard/packages/local-runtime/src/server-cost-run-search.ts +86 -0
  117. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-routes.ts +8 -1
  118. package/templates/.agents/dashboard/packages/local-runtime/src/server-projection-loaders.ts +13 -0
  119. package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +30 -74
  120. package/templates/.agents/dashboard/packages/local-runtime/src/server-route-handlers.ts +42 -0
  121. package/templates/.agents/dashboard/packages/local-runtime/src/server-routes.test.ts +60 -0
  122. package/templates/.agents/dashboard/packages/local-runtime/src/server-run-projections.test.ts +12 -2
  123. package/templates/.agents/dashboard/packages/local-runtime/src/server-telemetry-command.test.ts +29 -4
  124. package/templates/.agents/dashboard/packages/local-runtime/src/server-telemetry-refresh.ts +7 -0
  125. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +51 -54
  126. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +37 -48
  127. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +5 -0
  128. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.test.ts +49 -0
  129. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.ts +44 -1
  130. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-cached-cost-page.ts +11 -10
  131. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +1 -1
  132. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +18 -1
  133. package/templates/.agents/dashboard/packages/local-runtime/vitest.config.ts +12 -0
  134. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  135. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  136. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-pagination.spec.ts +13 -6
  137. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +1 -1
  138. package/templates/.agents/design/.zaip-managed.json +3 -3
  139. package/templates/.agents/design/apps/catalog/package.json +1 -1
  140. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  141. package/templates/.agents/requirements/autonomous-assurance.md +39 -3
  142. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  143. package/templates/.agents/requirements/comparative-audit.md +1 -1
  144. package/templates/.agents/requirements/context-engine.md +3 -3
  145. package/templates/.agents/requirements/cost-observability.md +1 -1
  146. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  147. package/templates/.agents/requirements/data-export.md +1 -1
  148. package/templates/.agents/requirements/design-system.md +1 -1
  149. package/templates/.agents/requirements/execution-engine.md +11 -2
  150. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  151. package/templates/.agents/requirements/model-orchestration.md +1 -1
  152. package/templates/.agents/requirements/public-distribution.md +1 -1
  153. package/templates/.agents/requirements/software-architecture.md +1 -1
  154. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  155. package/templates/.agents/requirements/work-lifecycle.md +2 -1
  156. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  157. package/templates/.agents/rules/cloud-hostinger-autonomy.md +1 -1
  158. package/templates/.agents/rules/production-readiness.md +24 -0
  159. package/templates/.agents/rules/run-lifecycle-closure.md +2 -1
  160. package/templates/.agents/rules/security.md +2 -2
  161. package/templates/.agents/rules/workflow.md +4 -3
  162. package/templates/.agents/runtime/VERSION +1 -1
  163. package/templates/.agents/runtime/bin/zaip.mjs +1185 -610
  164. package/templates/.agents/runtime/checksums.sha256 +6 -6
  165. package/templates/.agents/runtime/manifest.json +1 -1
  166. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  167. package/templates/.agents/runtime/provenance.json +5 -5
  168. package/templates/.agents/runtime/sbom.cdx.json +71 -71
  169. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +4 -2
  170. package/templates/.agents/skills/zaip-skill-execution/references/controlled-release-recovery.md +44 -0
  171. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +1 -1
  172. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +7 -1
  173. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-gate-matrix.md +15 -20
  174. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +38 -2
  175. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.test.mjs +62 -4
  176. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +8 -6
  177. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/guarded-commits.mjs +5 -3
  178. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +7 -0
  179. package/templates/.agents/skills/zaip-skill-maintenance-enter/SKILL.md +23 -0
  180. package/templates/.agents/skills/zaip-skill-maintenance-enter/agents/openai.yaml +4 -0
  181. package/templates/.agents/skills/zaip-skill-maintenance-enter/scripts/maintenance.mjs +213 -0
  182. package/templates/.agents/skills/zaip-skill-maintenance-enter/scripts/maintenance.test.mjs +207 -0
  183. package/templates/.agents/skills/zaip-skill-maintenance-exit/SKILL.md +21 -0
  184. package/templates/.agents/skills/zaip-skill-maintenance-exit/agents/openai.yaml +4 -0
  185. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +6 -0
  186. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +26 -0
  187. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +46 -11
  188. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +9 -0
  189. package/templates/.agents/skills/zaip-skill-testing-strategy/SKILL.md +15 -0
  190. package/templates/.agents/zaip-aios/VERSION +1 -1
  191. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +22 -0
  192. package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +1 -1
  193. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +52 -5
  194. package/templates/template-manifest.json +210 -126
  195. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Co2Jiuzh.js +0 -68
@@ -3,10 +3,10 @@ import { basename, resolve } from "node:path";
3
3
  import { serve } from "@hono/node-server";
4
4
  import { serveStatic } from "@hono/node-server/serve-static";
5
5
  import { WorkspaceFileSystem, type WorkspaceLayout } from "@zaip-ai/core";
6
- import { fxRateSchema, PricingRepository, pricingCatalogSchema } from "@zaip-ai/costs";
7
6
  import { type Context, Hono } from "hono";
8
7
  import { getCookie, setCookie } from "hono/cookie";
9
8
  import { createDashboardDiagnostics } from "../dashboard-diagnostics.mjs";
9
+ import { activeCaptureFailure as describeActiveCaptureFailure } from "./active-capture-failure.js";
10
10
  import {
11
11
  type ActiveCodexTelemetryCapture,
12
12
  captureRepositoryActiveCodexTelemetry,
@@ -37,6 +37,7 @@ import {
37
37
  registerReconciliationRoute,
38
38
  } from "./server-reconciliation-route.js";
39
39
  import { isAllowedDashboardAuthority } from "./server-request-authority.js";
40
+ import { registerPricingRoutes } from "./server-route-handlers.js";
40
41
  import { refreshSqliteSnapshotInWorker } from "./server-snapshot-refresh.js";
41
42
  import { readCommittedSnapshotRevision } from "./server-snapshot-revision.js";
42
43
  import { startSnapshotSynchronization } from "./server-snapshot-synchronization.js";
@@ -188,13 +189,17 @@ export function createDashboardApp(
188
189
  };
189
190
  let observedSnapshotRevision: string | null = null;
190
191
  const projectionRefreshDiagnostics = createProjectionRefreshDiagnostics();
191
- let activeCaptureFailure: { code: string; occurred_at: string; cause: string } | null = null;
192
+ let activeCaptureFailure: ReturnType<typeof describeActiveCaptureFailure> | null = null;
192
193
  let activeCapture: ActiveCodexTelemetryCapture | null = null;
194
+ let activeCapturePending = false;
193
195
  let projectionRefreshInFlight: Promise<void> | null = null;
194
196
  let projectionRefreshRequested = false;
195
197
  const associatedRefreshJobs = new Set<string>();
196
- const rebuildProjection = async (associatedJobId: string | null = null) => {
198
+ const rebuildProjection = async (associatedJobId: string | null = null): Promise<void> => {
197
199
  if (associatedJobId !== null) associatedRefreshJobs.add(associatedJobId);
200
+ // Capture writes canonical records. Watcher events from those writes must
201
+ // join the ordered pass, not launch a competing SQLite rebuild.
202
+ if (telemetryRefresh.capturing) return telemetryRefresh.refresh();
198
203
  if (projectionRefreshInFlight !== null) {
199
204
  projectionRefreshRequested = true;
200
205
  return projectionRefreshInFlight;
@@ -258,29 +263,40 @@ export function createDashboardApp(
258
263
  });
259
264
  return projectionRefreshInFlight;
260
265
  };
266
+ const captureTelemetry =
267
+ options.captureTelemetry ??
268
+ (isSqliteSnapshot &&
269
+ options.watchSources === true &&
270
+ process.env.ZAIP_DASHBOARD_WATCH_SOURCES !== "0"
271
+ ? () => captureRepositoryActiveCodexTelemetry(workspaceRoot)
272
+ : undefined);
261
273
  const telemetryRefresh = createTelemetryProjectionRefresh({
262
274
  refresh: rebuildProjection,
263
- ...(options.captureTelemetry !== undefined
264
- ? { capture: options.captureTelemetry }
265
- : isSqliteSnapshot &&
266
- options.watchSources === true &&
267
- process.env.ZAIP_DASHBOARD_WATCH_SOURCES !== "0"
268
- ? { capture: () => captureRepositoryActiveCodexTelemetry(workspaceRoot) }
269
- : {}),
275
+ ...(captureTelemetry === undefined
276
+ ? {}
277
+ : {
278
+ capture: async () => {
279
+ // A source-only projection can precede the periodic capture. Drain it
280
+ // while the capture reservation prevents new watcher projections.
281
+ if (projectionRefreshInFlight !== null)
282
+ await projectionRefreshInFlight.catch(() => undefined);
283
+ return captureTelemetry();
284
+ },
285
+ }),
270
286
  onCaptureSuccess: (result) => {
271
287
  activeCapture = result;
272
288
  activeCaptureFailure = null;
289
+ activeCapturePending = result.catch_up_complete === false;
273
290
  },
274
291
  onCaptureFailure: (error) => {
275
- activeCaptureFailure = {
276
- code: "active_telemetry_capture_failed",
277
- occurred_at: new Date().toISOString(),
278
- cause: error instanceof Error ? error.name : "unknown_error",
279
- };
292
+ activeCaptureFailure = describeActiveCaptureFailure(error);
293
+ diagnostics.log("active_telemetry_capture_failed", activeCaptureFailure);
280
294
  },
281
295
  });
282
296
  const visibleSnapshotState = () =>
283
- telemetryRefresh.pending || activeCaptureFailure !== null ? "updating" : snapshotState;
297
+ telemetryRefresh.pending || activeCaptureFailure !== null || activeCapturePending
298
+ ? "updating"
299
+ : snapshotState;
284
300
  startSnapshotSynchronization({
285
301
  workspaceRoot,
286
302
  discoverSourceRoots: () => dashboardCanonicalSourceRoots(workspaceRoot),
@@ -440,7 +456,7 @@ export function createDashboardApp(
440
456
  server_pid: process.pid,
441
457
  service: "zaip-aios-dashboard",
442
458
  status:
443
- manifestState === "initialized" && activeCaptureFailure === null
459
+ manifestState === "initialized" && activeCaptureFailure === null && !activeCapturePending
444
460
  ? projectionRefreshDiagnostics.healthStatus
445
461
  : "degraded",
446
462
  api_version: 2,
@@ -481,7 +497,9 @@ export function createDashboardApp(
481
497
  lifecycleManifestState(canonicalFilesystem),
482
498
  ]);
483
499
  const readinessStatus =
484
- manifestState === "initialized" && activeCaptureFailure === null ? "ready" : "degraded";
500
+ manifestState === "initialized" && activeCaptureFailure === null && !activeCapturePending
501
+ ? "ready"
502
+ : "degraded";
485
503
  if (isSqliteSnapshot) {
486
504
  const revision = readCommittedSnapshotRevision(workspaceRoot);
487
505
  if (observedSnapshotRevision !== null && observedSnapshotRevision !== revision) {
@@ -606,36 +624,7 @@ export function createDashboardApp(
606
624
  readAggregate,
607
625
  clearSnapshotCache,
608
626
  });
609
- app.on(["GET", "HEAD"], `${API_PREFIX}/pricing`, async (context) =>
610
- headOrJson(
611
- context,
612
- pricingCatalogSchema.parse(
613
- JSON.parse(await filesystem.readText(".agents/config/pricing/models.json")),
614
- ),
615
- ),
616
- );
617
- app.put(`${API_PREFIX}/pricing`, async (context) => {
618
- const catalog = pricingCatalogSchema.parse({
619
- ...(await context.req.json()),
620
- updated_at: new Date().toISOString(),
621
- });
622
- await filesystem.writeTextAtomic(
623
- ".agents/config/pricing/models.json",
624
- `${JSON.stringify(catalog, null, 2)}\n`,
625
- );
626
- clearSnapshotCache();
627
- return context.json(catalog);
628
- });
629
- app.on(["GET", "HEAD"], `${API_PREFIX}/fx-rate`, async (context) => {
630
- const rate = await new PricingRepository(filesystem).readLatestFxRate();
631
- return headOrJson(context, rate);
632
- });
633
- app.put(`${API_PREFIX}/fx-rate`, async (context) => {
634
- const input = fxRateSchema.pick({ rate: true }).parse(await context.req.json());
635
- const rate = await new PricingRepository(filesystem).writeCurrentFxRate(input.rate);
636
- clearSnapshotCache();
637
- return context.json(rate);
638
- });
627
+ registerPricingRoutes(app, filesystem, clearSnapshotCache);
639
628
  registerAgentCatalogRoutes(app, {
640
629
  filesystem,
641
630
  workspaceRoot,
@@ -60,6 +60,11 @@ it.each([
60
60
  );
61
61
  await rebuildSqliteReadModel(root);
62
62
  fs = new SqliteReadModelFileSystem(root);
63
+ if (status === "completed") {
64
+ const fast = fs.viewPage("cost_monitor_agent_invocations", { query: "ainv-low", limit: 1 });
65
+ const sql = fs.viewPage("cost_monitor_agent_invocations", { query: "%AINV-LOW%", limit: 1 });
66
+ expect(fast).toEqual(sql);
67
+ }
63
68
  const summary = fs.costMonitorSummaryAggregate({ from: null, to: null });
64
69
  // Summary first paint remains aggregate-only, but its controls retain
65
70
  // factual filter choices from the same SQLite population.
@@ -1,7 +1,56 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { filterCostInvocationProjection } from "./sqlite-cost-invocation-page.js";
3
+ import { readCachedCostViewPage } from "./sqlite-query-cached-cost-page.js";
4
+ import type { SqliteQueryContext } from "./sqlite-query-context.js";
3
5
 
4
6
  describe("cost invocation projection page", () => {
7
+ it("searches the immutable projection before pagination, preserving nulls and empty results", () => {
8
+ const context = {
9
+ technicalPayloadRows: () => [
10
+ {
11
+ agent_invocation_id: "AINV-OTHER",
12
+ task_id: null,
13
+ occurred_at: "2026-08-01T12:00:00Z",
14
+ total_tokens: 20,
15
+ },
16
+ {
17
+ agent_invocation_id: "AINV-TARGET-1",
18
+ task_id: null,
19
+ occurred_at: "2026-08-01T11:00:00Z",
20
+ total_tokens: 12,
21
+ },
22
+ {
23
+ agent_invocation_id: "AINV-TARGET-2",
24
+ task_id: null,
25
+ occurred_at: "2026-08-01T10:00:00Z",
26
+ total_tokens: null,
27
+ },
28
+ ],
29
+ } as unknown as SqliteQueryContext;
30
+ expect(
31
+ readCachedCostViewPage(context, "cost_monitor_agent_invocations", {
32
+ query: "target",
33
+ offset: 1,
34
+ limit: 1,
35
+ }),
36
+ ).toMatchObject({
37
+ total_count: 2,
38
+ has_more: false,
39
+ rows: [{ agent_invocation_id: "AINV-TARGET-2", total_tokens: null }],
40
+ });
41
+ expect(
42
+ readCachedCostViewPage(context, "cost_monitor_agent_invocations", { query: "absent" }),
43
+ ).toMatchObject({ total_count: 0, rows: [] });
44
+ expect(
45
+ readCachedCostViewPage(context, "cost_monitor_agent_invocations", { query: "TARGET%" }),
46
+ ).toBeNull();
47
+ expect(
48
+ readCachedCostViewPage(context, "cost_monitor_agent_invocations", {
49
+ query: "target",
50
+ provider: "openai",
51
+ }),
52
+ ).toBeNull();
53
+ });
5
54
  it("uses the Sao Paulo source day for the fast date-only page", () => {
6
55
  const rows = [
7
56
  { agent_invocation_id: "before", source_started_at: "2026-08-01T02:30:00.000Z" },
@@ -1,4 +1,6 @@
1
- type CostInvocationDateFilter = { from?: string | null; to?: string | null };
1
+ import type { DatabaseSync } from "node:sqlite";
2
+
3
+ type CostInvocationDateFilter = { from?: string | null; to?: string | null; query?: string };
2
4
 
3
5
  function costDay(value: string | null | undefined): string | null {
4
6
  if (!value) return null;
@@ -21,9 +23,50 @@ export function filterCostInvocationProjection(
21
23
  ) {
22
24
  const from = costDay(input.from);
23
25
  const to = costDay(input.to);
26
+ // SQLite LIKE folds ASCII only. Wildcard queries remain on the SQL reader.
27
+ const fold = (value: string) => value.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
28
+ const query = input.query ? fold(input.query) : null;
24
29
  return rows.filter((row) => {
30
+ if (
31
+ query !== null &&
32
+ ![row.agent_invocation_id, row.task_id, row.execution_id].some(
33
+ (value) => typeof value === "string" && fold(value).includes(query),
34
+ )
35
+ )
36
+ return false;
25
37
  const timestamp = row.source_started_at ?? row.source_occurred_at ?? row.occurred_at;
26
38
  const day = typeof timestamp === "string" ? costDay(timestamp) : null;
27
39
  return day !== null && (from === null || day >= from) && (to === null || day <= to);
28
40
  });
29
41
  }
42
+
43
+ /** Enrich only the selected page, matching the original SQL left join. */
44
+ export function enrichCostInvocationPage(
45
+ database: DatabaseSync,
46
+ rows: Array<Record<string, unknown>>,
47
+ ) {
48
+ const ids = [
49
+ ...new Set(rows.flatMap((row) => (typeof row.task_id === "string" ? [row.task_id] : []))),
50
+ ];
51
+ const tasks =
52
+ ids.length === 0
53
+ ? []
54
+ : (database
55
+ .prepare(
56
+ "SELECT id, priority, risk, status AS task_status, title AS task_title FROM tasks WHERE id IN (" +
57
+ ids.map(() => "?").join(",") +
58
+ ")",
59
+ )
60
+ .all(...ids) as Array<Record<string, unknown>>);
61
+ const byId = new Map(tasks.map((task) => [task.id, task]));
62
+ return rows.map((row) => {
63
+ const task = byId.get(row.task_id);
64
+ return {
65
+ ...row,
66
+ priority: task?.priority ?? null,
67
+ risk: task?.risk ?? null,
68
+ task_status: task?.task_status ?? null,
69
+ task_title: task?.task_title ?? null,
70
+ };
71
+ });
72
+ }
@@ -1,4 +1,7 @@
1
- import { filterCostInvocationProjection } from "./sqlite-cost-invocation-page.js";
1
+ import {
2
+ enrichCostInvocationPage,
3
+ filterCostInvocationProjection,
4
+ } from "./sqlite-cost-invocation-page.js";
2
5
  import type { SqliteQueryContext, SqliteViewPage } from "./sqlite-query-context.js";
3
6
  import type { SqliteViewName } from "./sqlite-read-model-types.js";
4
7
 
@@ -38,9 +41,9 @@ export function readCachedCostViewPage(
38
41
  !input.origin &&
39
42
  !input.workType &&
40
43
  !input.priority;
41
- const isDateOnlyCostInvocationPage =
44
+ const isCompactCostInvocationPage =
42
45
  view === "cost_monitor_agent_invocations" &&
43
- !input.query &&
46
+ !/[\0%_]/.test(input.query ?? "") &&
44
47
  !input.status &&
45
48
  !input.risk &&
46
49
  !input.provider &&
@@ -50,12 +53,10 @@ export function readCachedCostViewPage(
50
53
  !input.origin &&
51
54
  !input.workType &&
52
55
  !input.priority;
53
- if (isDateOnlyCostInvocationPage) {
54
- const projection = filterCostInvocationProjection(
55
- context.technicalPayloadRows("cost_agent_invocation_projection_v1"),
56
- input,
57
- );
58
- if (projection.length > 0) {
56
+ if (isCompactCostInvocationPage) {
57
+ const cachedRows = context.technicalPayloadRows("cost_agent_invocation_projection_v1");
58
+ const projection = filterCostInvocationProjection(cachedRows, input);
59
+ if (cachedRows.length > 0) {
59
60
  const limit = Math.min(200, Math.max(1, input.limit ?? 100));
60
61
  const offset = Math.max(0, input.offset ?? 0);
61
62
  const rows = projection.slice(offset, offset + limit);
@@ -66,7 +67,7 @@ export function readCachedCostViewPage(
66
67
  limit,
67
68
  total_count: projection.length,
68
69
  has_more: offset + rows.length < projection.length,
69
- rows,
70
+ rows: input.query ? enrichCostInvocationPage(context.database, rows) : rows,
70
71
  };
71
72
  }
72
73
  }
@@ -110,7 +110,7 @@ export function queryCostMonitorSummaryAggregate(
110
110
  add("work_type", filter.workTypes);
111
111
  if (filter.query) {
112
112
  clauses.push(
113
- "(a.task_id LIKE ? OR a.spec_id LIKE ? OR a.prd_id LIKE ? OR a.execution_id LIKE ? OR a.conversation_id LIKE ? OR a.zaip_agent LIKE ? OR a.model LIKE ? OR a.run_id LIKE ? OR a.agent_run_id LIKE ? OR EXISTS (SELECT 1 FROM canonical_work_items task WHERE task.id=a.task_id AND task.title LIKE ?))",
113
+ "(a.task_id LIKE ? OR a.spec_id LIKE ? OR a.prd_id LIKE ? OR a.execution_id LIKE ? OR a.conversation_id LIKE ? OR a.zaip_agent LIKE ? OR a.model LIKE ? OR a.run_id LIKE ? OR a.agent_run_id LIKE ? OR EXISTS (SELECT 1 FROM canonical_work_items task WHERE task.entity_kind='task' AND task.id=a.task_id AND task.title LIKE ?))",
114
114
  );
115
115
  values.push(...Array(10).fill(`%${filter.query}%`));
116
116
  }
@@ -2,7 +2,7 @@ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { DatabaseSync } from "node:sqlite";
5
- import { afterEach, describe, expect, it } from "vitest";
5
+ import { afterEach, describe, expect, it, vi } from "vitest";
6
6
  import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
7
7
 
8
8
  const roots: string[] = [];
@@ -35,6 +35,23 @@ describe("SQLite work-item identity index", () => {
35
35
  ).toContain("TASK-INDEXED");
36
36
  const database = new DatabaseSync(process.env.ZAIP_SQLITE_DB_PATH, { readOnly: true });
37
37
  try {
38
+ const reader = new SqliteReadModelFileSystem(root, database);
39
+ const prepared = vi.spyOn(database, "prepare");
40
+ reader.costMonitorSummaryAggregate({ from: null, to: null, query: "Indexed" });
41
+ const searchSql = prepared.mock.calls
42
+ .map(([sql]) => sql)
43
+ .find(
44
+ (sql) =>
45
+ sql.startsWith("WITH selected AS MATERIALIZED") && sql.includes("task.title LIKE"),
46
+ );
47
+ prepared.mockRestore();
48
+ expect(searchSql).toBeDefined();
49
+ const searchPlan = database
50
+ .prepare(`EXPLAIN QUERY PLAN ${searchSql}`)
51
+ .all(null, null, null, null, ...Array(10).fill("%Indexed%")) as Array<{ detail: string }>;
52
+ expect(searchPlan.map((row) => row.detail).join("\n")).toContain(
53
+ "zaip_activities_work_item_identity",
54
+ );
38
55
  const plan = database
39
56
  .prepare(`EXPLAIN QUERY PLAN
40
57
  SELECT a.task_id FROM zaip_vw_activities a WHERE a.task_id IS NOT NULL
@@ -0,0 +1,12 @@
1
+ import { availableParallelism } from "node:os";
2
+ import { defineConfig } from "vitest/config";
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ include: ["src/**/*.test.ts", "*.test.mjs"],
7
+ // This suite uses node:test and is executed explicitly by the package script.
8
+ exclude: ["dashboard-diagnostics.test.mjs"],
9
+ maxWorkers: Math.min(4, availableParallelism()),
10
+ testTimeout: 60_000,
11
+ },
12
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-ui",
3
- "version": "4.8.0",
3
+ "version": "5.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-e2e",
3
- "version": "4.8.0",
3
+ "version": "5.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -126,12 +126,19 @@ for (const target of targets) {
126
126
  const button = tabs.getByRole("button", { exact: true, name: target.tab });
127
127
  await requestPage(page, target.sqliteView, 0, 10, () => button.click());
128
128
  await page.getByRole("button", { name: "Exportar Excel" }).click();
129
- await expect
130
- .poll(() => page.evaluate(() => window.__paginationExportProbe.closes), { timeout: 300_000 })
131
- .toBe(1);
132
- await expect(page.getByText("Exportação concluída.", { exact: true })).toBeVisible({
133
- timeout: 30_000,
134
- });
129
+ // Observe the transient success notice while the export runs. Waiting for
130
+ // the writer first can miss the notice when a busy host delays polling.
131
+ await Promise.all([
132
+ expect
133
+ .poll(() => page.evaluate(() => window.__paginationExportProbe.closes), {
134
+ timeout: 300_000,
135
+ })
136
+ .toBe(1),
137
+ expect(page.getByText("Exportação concluída.", { exact: true })).toBeVisible({
138
+ timeout: 300_000,
139
+ }),
140
+ ]);
141
+ expect(await page.evaluate(() => window.__paginationExportProbe.writes)).toBeGreaterThan(0);
135
142
  await expect.poll(() => pages.some((entry) => !entry.has_more), { timeout: 30_000 }).toBe(true);
136
143
 
137
144
  expect(pages.length).toBeGreaterThan(0);
@@ -458,7 +458,7 @@ test("filters the all-work board into Tasks, SPECs and PRDs after hydration", as
458
458
  await expect(spec.locator(".operations-work-card-counts")).toHaveText(/Tasks \d+\/\d+/);
459
459
  await spec.locator(".operations-work-card-open").click();
460
460
  await expect(page.getByRole("dialog", { name: "Detalhes do SPEC" })).toBeVisible();
461
- await page.getByRole("button", { name: "Fechar" }).click();
461
+ await page.getByRole("button", { name: "Fechar", exact: true }).click();
462
462
  }
463
463
 
464
464
  await selectWorkBoardType(page, "PRDs", "prd");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "4.8.0",
3
+ "version": "5.0.0",
4
4
  "files": [
5
5
  {
6
6
  "path": "DESIGN.md",
@@ -276,7 +276,7 @@
276
276
  },
277
277
  {
278
278
  "path": "apps/catalog/package.json",
279
- "sha256": "042f7b0a8b2fcfae031c268bfc07f41c96957ce3a6724b9ca8f0c8bd5ce4f3ab"
279
+ "sha256": "dcd0c6a84e8c1cdc34fafca8ce9089ea55db196d82ac8ef9e8bb9234168dd3c2"
280
280
  },
281
281
  {
282
282
  "path": "apps/catalog/public/logo_novo_azul.png",
@@ -408,7 +408,7 @@
408
408
  },
409
409
  {
410
410
  "path": "packages/local-runtime/package.json",
411
- "sha256": "95c9a31264d488e61280b0f3b6955a9c4c3c96aa388c8c2f9b92dc84092dd920"
411
+ "sha256": "74dea06fa11afb30713fd1c286bc38833fe60ab782d5f9ed83ff380d9c032606"
412
412
  },
413
413
  {
414
414
  "path": "packages/local-runtime/runtime.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/design-catalog",
3
- "version": "4.8.0",
3
+ "version": "5.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/design-local-runtime",
3
- "version": "4.8.0",
3
+ "version": "5.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -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: 3
7
+ version: 6
8
8
  source_change: null
9
- source_release: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Garantia adaptativa e execução autônoma
@@ -22,6 +22,14 @@ Uma Task avulsa deve provar todos os Acceptance Criteria com profundidade propor
22
22
  - `AC-ASSURE-001-05`: uma Task sensível a segurança, migração, irreversibilidade ou múltiplos domínios não pode usar `lite` para contornar controles críticos.
23
23
  - `AC-ASSURE-001-06`: somente sob `assurance.version: 1`, uma Task `lite` com `editorial_delivery:true`, `verification_scope:"scoped"`, write scope editorial estreito e candidato textual regular pode dispensar a Decision das seis etapas. Ela ainda exige check tipado real, Evidence tipada cobrindo os ACs, commit/candidato Git, revisão e finalização. Código, configuração, controles de agente, ação externa, dado sensível, migração, risco `standard|critical` ou sinal sensível rejeitam a exceção; qualquer Task sem esse opt-in preserva a Decision.
24
24
 
25
+ A rota editorial de `AC-ASSURE-001-06` inclui os literais `README.md` e
26
+ `README-ENG.md`, Markdown literal em `docs/` e subdiretório documental estreito
27
+ como `docs/quality/**`, além das raízes editoriais de negócio existentes.
28
+ `docs/**` amplo não concede exceção. A prova usa o diff Git completo, modo de
29
+ arquivo regular não executável e conteúdo textual; controles de agente,
30
+ código, configuração, links, binários e sinais sensíveis continuam rejeitados.
31
+ Uma alteração nesses controles é mudança de código/regra e conserva seu risco.
32
+
25
33
  ## REQ-ASSURE-002 — Garantia parental para SPEC e PRD
26
34
 
27
35
  Entregar uma SPEC ou PRD deve exigir prova no nível do produto planejado, além da soma dos testes das Tasks descendentes.
@@ -36,6 +44,15 @@ Entregar uma SPEC ou PRD deve exigir prova no nível do produto planejado, além
36
44
 
37
45
  O framework deve preservar execução manual como padrão e permitir autonomia somente por configuração explícita.
38
46
 
47
+ Esta seção mantém o contrato de compatibilidade do runtime gerenciado legado.
48
+ Configuração ausente resolve para `manual`; novos projetos gerados pela v4
49
+ declaram explicitamente `codex_native`, executado pelo host. O teto legado de
50
+ três tentativas em AC-AUTO-001-06 não substitui os perfis congelados de
51
+ `autonomy.version: 1`: seus limites e critérios de recuperação pertencem a
52
+ RULE-AUTONOMY-DECISION. A presença da configuração, isoladamente, não comprova
53
+ que uma Task possui ledger de recuperação; `task recovery-status` deve informar
54
+ esse estado, mantendo `legacy_or_unmigrated` quando o registro estiver ausente.
55
+
39
56
  - `AC-AUTO-001-01`: ausência de `execution` ou `execution.runtime: manual` materializa o trabalho sem invocar provider; `autonomous` exige provider, modelo, lease e paralelismo limitados.
40
57
  - `AC-AUTO-001-02`: o paralelismo efetivo é o menor limite entre projeto, plano, provider e squad. SPECs independentes podem usar Executions-filhas isoladas sob coordenação do PRD, mas locks globais de DAG e write scopes, além do orçamento global, continuam soberanos; SPECs sem elegibilidade permanecem na DAG global.
41
58
  - `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.
@@ -52,12 +69,31 @@ Aprendizado e alegações de maturidade devem ser derivados de fatos verificáve
52
69
  - `AC-EVOL-001-02`: lesson exige finding e locator verificável; opinião isolada não promove Rule, Requirement ou skill.
53
70
  - `AC-EVOL-001-03`: maturidade progride sequencialmente por `declared`, `implemented`, `locally_evidenced`, `cleanroom_validated`, `representative_validated` e `production_observed`.
54
71
  - `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.
72
+ - No fechamento pós-publicação de `AC-EVOL-001-04`, o SHA validado permanece o candidato original. Um SHA publicado descendente só é aceito se cada commit intermediário, inclusive cada pai de merge, alterar exclusivamente `.agents/records/**`; igualdade final de bytes ou reversão posterior não substitui essa prova. O ciclo deve conter um único append com o SHA publicado exato, e Evidence/Validation selecionadas são vinculadas por hash de conteúdo. Mutação do limite de produto deve falhar no teste isolado.
55
73
 
56
74
  ## REQ-QUALITY-001 — Gates de release e cobertura sem regressão
57
75
 
58
76
  O release deve falhar de modo discriminante quando código, distribuição ou evidência não atingirem o contrato publicado.
59
77
 
60
- - `AC-QUALITY-001-01`: release crítico inclui unit, E2E, arquitetura, CQRS, módulos, profile, segurança e testes negativos.
78
+ - `AC-QUALITY-001-01`: release crítico executa testes unitários, E2E, arquitetura, CQRS, módulos, profile, segurança e negativos conforme impacto e riscos do candidato. O gate essencial de distribuição mantém integridade, assinatura, instalação/rollback e smoke do pacote exato; uma suíte completa transversal só é obrigatória quando impacto, finding específico ou perfil explicitamente solicitado a exigir.
61
79
  - `AC-QUALITY-001-02`: cobertura usa baseline versionada e ratchet `max(piso, baseline anterior)` com pisos de 80% para lines/functions/statements e 75% para branches.
62
80
  - `AC-QUALITY-001-03`: baseline observada abaixo do piso pode ser registrada para transparência, mas não reduz o gate nem torna a release aprovada.
63
81
  - `AC-QUALITY-001-04`: release verifica paridade entre fonte canônica, template público e artefato distribuído, além de smoke/cleanroom sobre o candidato exato.
82
+
83
+ Na criação de PRD, SPEC e AC, selecione por impacto os testes de código e os fluxos
84
+ de dashboard alterados. Integre os contratos modificados antes do release e
85
+ qualifique o pacote completo uma vez no candidato final antes de publicar;
86
+ correções posteriores revalidam as provas afetadas. Reuse Evidence apenas quando
87
+ candidato, ambiente, contrato e impacto ainda coincidirem. Teste de código não
88
+ promove comportamento não observado a prova servida.
89
+
90
+ Na consolidação 4.9, a Decision
91
+ `DEC-AI-2026-10-03-22-18-TAREFA2-ACEITE-CODIGO-XFQFBLLYRN` delimita a
92
+ Task de recuperação a regressões de código dirigidas por seus deltas, revisão
93
+ independente e finalização. Coleta operacional e configurações sem prova servida
94
+ permanecem `unverified`; testes de código não as promovem a observação servida.
95
+ Integração dos fluxos e contratos alterados pertence à fase de integração; a
96
+ qualificação integral do pacote final ocorre uma vez antes da publicação,
97
+ conforme `DEC-AI-2026-10-03-22-16-QUALIFICACAO-FINAL-UNICA-UPQGEC6JJV`.
98
+ Evidence, candidato exato e controles críticos aplicáveis continuam obrigatórios;
99
+ esta divisão de fases não reaprova snapshots antigos nem dispensa findings reais.
@@ -6,7 +6,7 @@ title: Autonomia delimitada para Cloudflare e Hostinger
6
6
  status: proposed
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Cloudflare e Hostinger (proposta de requisito)
@@ -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: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Auditoria comparativa e plano de evolução
@@ -4,9 +4,9 @@ id: REQUIREMENTS-CONTEXT-ENGINE
4
4
  area: context-engine
5
5
  title: Contexto mínimo, seguro e navegável
6
6
  status: active
7
- version: 8
7
+ version: 9
8
8
  source_change: null
9
- source_release: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Context engine
@@ -37,7 +37,7 @@ Coleções de trabalho devem ser navegadas pelos manifests canônicos compactos
37
37
  - `AC-CONTEXT-003-02`: listagens de PRD, SPEC e Task omitem o PreparedPlan completo e retornam somente resumo de preparação.
38
38
  - `AC-CONTEXT-003-03`: corpos e eventos JSONL são lidos somente após selecionar IDs específicos.
39
39
  - `AC-CONTEXT-003-04`: operações comuns consultam somente manifests lifecycle e `InvocationSummary` canônicos, com paginação cursor-estável; varredura integral de `.agents/records` ou `.agents/data` exige comando e confirmação explícitos.
40
- - `AC-CONTEXT-003-05`: o dashboard não depende de cache ou projeção local; migrações preservam somente os manifests canônicos Git-native em `.agents/records/lifecycle` e backfill verificável.
40
+ - `AC-CONTEXT-003-05`: registros Git-native e seus manifests em `.agents/records/lifecycle` são a fonte canônica. O dashboard pode consultar SQLite/read model local reconstruível e API como projeções; perda ou rebuild da projeção não altera identidade nem estado canônico. Migração preserva registros e manifests, reconstrói/backfill da projeção com verificação de paridade e não trata cache como fonte de verdade.
41
41
  - `AC-CONTEXT-003-06`: `.agents/data` e partições diárias anteriores são fallback legado somente leitura; novas escritas usam `.agents/records/<kind>/<ano>/<mês>`.
42
42
  - `AC-CONTEXT-003-07`: `context build` descobre paths e relações antes de ler conteúdo; inventário integral exige comando explícito.
43
43
  - `AC-CONTEXT-003-08`: uma consulta com ID lifecycle explícito não incorpora outros itens de `active-work`; fallback de path aceita somente o arquivo V3 canônico existente sem varrer records.
@@ -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: "4.8.0"
9
+ source_release: "5.0.0"
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: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Inicialização e hidratação confiável do dashboard
@@ -6,7 +6,7 @@ title: Exportação contextual de dados para Excel
6
6
  status: proposed
7
7
  version: 2
8
8
  source_change: null
9
- source_release: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Exportação contextual de dados
@@ -6,7 +6,7 @@ title: Contrato visual e catálogo executável
6
6
  status: active
7
7
  version: 5
8
8
  source_change: null
9
- source_release: "4.8.0"
9
+ source_release: "5.0.0"
10
10
  ---
11
11
 
12
12
  # Design system