@zaip-ai/cli 4.7.0 → 4.9.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 (127) hide show
  1. package/dist/services/adapters.d.ts +1 -1
  2. package/dist/services/adapters.js +1 -1
  3. package/dist/services/codex-hook-activation.d.ts.map +1 -1
  4. package/dist/services/codex-hook-activation.js +12 -0
  5. package/dist/services/codex-hook-activation.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 +86 -10
  8. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  9. package/dist/services/codex-pre-tool-hook-template.test.js +72 -0
  10. package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -1
  11. package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
  12. package/dist/services/codex-pre-tool-support-template.js +19 -2
  13. package/dist/services/codex-pre-tool-support-template.js.map +1 -1
  14. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  15. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  16. package/dist/services/codex-subagent-hook-template.js +46 -13
  17. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  18. package/dist/services/codex-validation-runtime-template.d.ts.map +1 -1
  19. package/dist/services/codex-validation-runtime-template.js +31 -10
  20. package/dist/services/codex-validation-runtime-template.js.map +1 -1
  21. package/dist/services/global-codex-config-migration-rollback.test.d.ts +2 -0
  22. package/dist/services/global-codex-config-migration-rollback.test.d.ts.map +1 -0
  23. package/dist/services/global-codex-config-migration-rollback.test.js +88 -0
  24. package/dist/services/global-codex-config-migration-rollback.test.js.map +1 -0
  25. package/dist/services/global-codex-config-migration.test.js +69 -82
  26. package/dist/services/global-codex-config-migration.test.js.map +1 -1
  27. package/dist/services/global-codex-config-transaction.test.js +5 -1
  28. package/dist/services/global-codex-config-transaction.test.js.map +1 -1
  29. package/dist/services/global-codex-config.d.ts.map +1 -1
  30. package/dist/services/global-codex-config.js +32 -53
  31. package/dist/services/global-codex-config.js.map +1 -1
  32. package/dist/services/global-codex-toml.d.ts +9 -0
  33. package/dist/services/global-codex-toml.d.ts.map +1 -0
  34. package/dist/services/global-codex-toml.js +53 -0
  35. package/dist/services/global-codex-toml.js.map +1 -0
  36. package/dist/services/logger.js +1 -1
  37. package/dist/services/logger.js.map +1 -1
  38. package/dist/services/logger.test.js +2 -2
  39. package/dist/services/logger.test.js.map +1 -1
  40. package/dist/services/runtime-template.test.js +3 -1
  41. package/dist/services/runtime-template.test.js.map +1 -1
  42. package/package.json +1 -1
  43. package/templates/.agents/README.md +6 -2
  44. package/templates/.agents/config/agents/discovery.json +1 -1
  45. package/templates/.agents/dashboard/.zaip-managed.json +48 -44
  46. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-OUjdwEcM.js → CostCalculationGuidePage-BW7Vy1cp.js} +1 -1
  47. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cei1ChjE.js → DashboardHelpDialog-Cp_hEVd8.js} +45 -10
  48. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-_woNCrTT.js → PricingSettingsDialog-Prcs-ydy.js} +1 -1
  49. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-B2_7MVOP.js → ProjectSettingsPage-Cu40wAFF.js} +1 -1
  50. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-C_jCsSZe.js → TraceabilityWorkspace-Bh3YBd3C.js} +1 -1
  51. package/templates/.agents/dashboard/apps/frontend/dist/assets/{cost-monitor-C8zQDBT7.js → cost-monitor-Co2Jiuzh.js} +1 -1
  52. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-iMPXot7Y.js → icons-vendor-DOhy6D2-.js} +1 -1
  53. package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-DiCwz0sr.js → index-qVSJnJ0_.js} +2 -2
  54. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-721Re3Ss.js → react-vendor-CkPC-yMz.js} +1 -1
  55. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BjdTkWS0.js → traceability-BEdGoIDm.js} +1 -1
  56. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  57. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  58. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  59. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  60. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.macro-metrics.test.ts +2 -1
  61. package/templates/.agents/dashboard/modules/operations/src/react/overview-duration-hint.ts +1 -3
  62. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  63. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  64. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  65. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  66. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +226 -221
  67. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +147 -147
  68. package/templates/.agents/dashboard/packages/local-runtime/package.json +3 -3
  69. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +226 -221
  70. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +17 -5
  71. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +44 -14
  72. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +9 -3
  73. package/templates/.agents/dashboard/packages/local-runtime/vitest.config.ts +12 -0
  74. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  75. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  76. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-pagination.spec.ts +13 -6
  77. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +1 -1
  78. package/templates/.agents/design/.zaip-managed.json +3 -3
  79. package/templates/.agents/design/apps/catalog/package.json +1 -1
  80. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  81. package/templates/.agents/requirements/autonomous-assurance.md +30 -3
  82. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  83. package/templates/.agents/requirements/comparative-audit.md +1 -1
  84. package/templates/.agents/requirements/context-engine.md +3 -3
  85. package/templates/.agents/requirements/cost-observability.md +1 -1
  86. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  87. package/templates/.agents/requirements/data-export.md +1 -1
  88. package/templates/.agents/requirements/design-system.md +1 -1
  89. package/templates/.agents/requirements/execution-engine.md +11 -2
  90. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  91. package/templates/.agents/requirements/model-orchestration.md +1 -1
  92. package/templates/.agents/requirements/public-distribution.md +11 -9
  93. package/templates/.agents/requirements/software-architecture.md +1 -1
  94. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  95. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  96. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  97. package/templates/.agents/rules/cloud-hostinger-autonomy.md +1 -1
  98. package/templates/.agents/rules/production-readiness.md +24 -0
  99. package/templates/.agents/rules/security.md +2 -2
  100. package/templates/.agents/rules/workflow.md +3 -3
  101. package/templates/.agents/runtime/VERSION +1 -1
  102. package/templates/.agents/runtime/bin/zaip.mjs +313 -140
  103. package/templates/.agents/runtime/checksums.sha256 +6 -6
  104. package/templates/.agents/runtime/manifest.json +1 -1
  105. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  106. package/templates/.agents/runtime/provenance.json +5 -5
  107. package/templates/.agents/runtime/sbom.cdx.json +13 -13
  108. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +4 -2
  109. package/templates/.agents/skills/zaip-skill-execution/references/controlled-release-recovery.md +30 -0
  110. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +1 -1
  111. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +2 -0
  112. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-gate-matrix.md +15 -20
  113. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +36 -3
  114. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.test.mjs +63 -4
  115. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +8 -6
  116. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/guarded-commits.mjs +5 -3
  117. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +7 -0
  118. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +6 -0
  119. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +24 -0
  120. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +9 -3
  121. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +9 -0
  122. package/templates/.agents/skills/zaip-skill-testing-strategy/SKILL.md +15 -0
  123. package/templates/.agents/zaip-aios/VERSION +1 -1
  124. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +22 -0
  125. package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +2 -2
  126. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +14 -5
  127. package/templates/template-manifest.json +111 -99
@@ -17,7 +17,7 @@ afterEach(async () => {
17
17
  });
18
18
 
19
19
  describe("active Codex telemetry capture", () => {
20
- it("allows the measured catch-up budget and still rejects incomplete output", async () => {
20
+ it("bounds one automatic pass and rejects a partial receipt without progress", async () => {
21
21
  const root = await runtimeFixture("");
22
22
  const execute = vi.fn(async (_file: string, _args: string[], _options: unknown) => ({
23
23
  stdout: JSON.stringify({
@@ -26,10 +26,10 @@ describe("active Codex telemetry capture", () => {
26
26
  stderr: "",
27
27
  }));
28
28
  await expect(captureActiveCodexTelemetry(root, root, execute as never)).rejects.toThrow(
29
- "incomplete",
29
+ "bounded pending progress",
30
30
  );
31
31
  expect(execute.mock.calls[0]?.[2]).toMatchObject({
32
- timeout: 600_000,
32
+ timeout: 120_000,
33
33
  windowsHide: true,
34
34
  cwd: root,
35
35
  });
@@ -77,7 +77,7 @@ describe("active Codex telemetry capture", () => {
77
77
 
78
78
  it("does not let an empty or stale active index suppress terminal usage capture", async () => {
79
79
  const root = await runtimeFixture(
80
- "if(!process.argv.includes('--recent') || !process.argv.includes('--drain') || process.argv.includes('--active') || process.argv[process.argv.indexOf('--limit')+1]!=='32') process.exit(8); process.stdout.write(JSON.stringify({telemetry:{mode:'recent_exact_session',complete:true,captured:[{captured:true}]}}));\n",
80
+ "if(!process.argv.includes('--recent') || process.argv.includes('--drain') || process.argv.includes('--active') || process.argv[process.argv.indexOf('--limit')+1]!=='32') process.exit(8); process.stdout.write(JSON.stringify({telemetry:{mode:'recent_exact_session',complete:true,captured:[{captured:true}]}}));\n",
81
81
  );
82
82
  await writeFile(
83
83
  join(root, ".agents/records/lifecycle/active-work.json"),
@@ -150,7 +150,19 @@ describe("active Codex telemetry capture", () => {
150
150
  const root = await runtimeFixture(
151
151
  "process.stdout.write(JSON.stringify({telemetry:{mode:'recent_exact_session',complete:false,captured:[]}}));",
152
152
  );
153
- await expect(captureActiveCodexTelemetry(root)).rejects.toThrow("incomplete");
153
+ await expect(captureActiveCodexTelemetry(root)).rejects.toThrow("bounded pending progress");
154
+ });
155
+ it("reports an examined partial window as pending without inventing missing usage", async () => {
156
+ const root = await runtimeFixture(
157
+ "process.stdout.write(JSON.stringify({telemetry:{mode:'recent_exact_session',complete:false,candidate_count:70,processed_count:32,pending_count:38,captured:[{captured:false}]}}));",
158
+ );
159
+ await expect(captureActiveCodexTelemetry(root)).resolves.toMatchObject({
160
+ captured_runs: 0,
161
+ captured_segments: 0,
162
+ catch_up_complete: false,
163
+ pending_runs: 38,
164
+ skipped_reason: "catch_up_pending",
165
+ });
154
166
  });
155
167
  it.each([
156
168
  "active_exact_session",
@@ -6,13 +6,13 @@ import { lifecycleManifestState } from "./server-lifecycle-diagnostics.js";
6
6
  import { dashboardCanonicalSourceRoots } from "./sqlite-read-model-source-fingerprint.js";
7
7
 
8
8
  const execFileAsync = promisify(execFile);
9
- // Measured complete catch-up of a 98-Run / 30k-envelope backlog exceeded the
10
- // old 55s deadline. Keep the UI updating while this finite selection commits;
11
- // expiry remains a failure and can never promote a partial capture to current.
12
- export const RECENT_CODEX_CAPTURE_TIMEOUT_MS = 600_000;
9
+ // One automatic pass examines at most 32 Runs. Manual --drain remains separate.
10
+ export const RECENT_CODEX_CAPTURE_TIMEOUT_MS = 120_000;
13
11
 
14
12
  export type ActiveCodexTelemetryCapture = {
15
13
  captured_runs: number;
14
+ catch_up_complete?: boolean;
15
+ pending_runs?: number;
16
16
  /** The active CLI reports whether a Run changed, not its segment cardinality. */
17
17
  captured_segments: number | null;
18
18
  manifest_state: "initialized" | "missing" | "invalid";
@@ -23,6 +23,7 @@ export type ActiveCodexTelemetryCapture = {
23
23
  | "no_recent_active_runs"
24
24
  | "no_recent_runs"
25
25
  | "no_new_segments"
26
+ | "catch_up_pending"
26
27
  | null;
27
28
  last_capture_at: string;
28
29
  };
@@ -61,7 +62,6 @@ export async function captureActiveCodexTelemetry(
61
62
  "--recent",
62
63
  "--limit",
63
64
  "32",
64
- "--drain",
65
65
  "--disable-codex-raw",
66
66
  "--json",
67
67
  ],
@@ -74,16 +74,24 @@ export async function captureActiveCodexTelemetry(
74
74
  },
75
75
  );
76
76
  const payload = parseJsonResult(outcome.stdout);
77
- const captured = readCaptured(payload);
77
+ const receipt = readCaptured(payload);
78
+ const captured = receipt.captured;
78
79
  const capturedRuns = captured.filter((item) => item.captured).length;
79
80
  return {
80
81
  captured_runs: capturedRuns,
82
+ catch_up_complete: receipt.complete,
83
+ pending_runs: receipt.pending,
81
84
  // Zero is factual for an idle pass. A non-idle pass has no segment count
82
85
  // in the CLI contract, so retain unavailable rather than inventing one.
83
86
  captured_segments: capturedRuns === 0 ? 0 : null,
84
87
  manifest_state: "initialized",
85
- skipped_reason:
86
- captured.length === 0 ? "no_recent_runs" : capturedRuns === 0 ? "no_new_segments" : null,
88
+ skipped_reason: !receipt.complete
89
+ ? "catch_up_pending"
90
+ : captured.length === 0
91
+ ? "no_recent_runs"
92
+ : capturedRuns === 0
93
+ ? "no_new_segments"
94
+ : null,
87
95
  last_capture_at: new Date().toISOString(),
88
96
  };
89
97
  } catch (error) {
@@ -117,10 +125,13 @@ export async function captureRepositoryActiveCodexTelemetry(
117
125
  const capturedRuns = results.reduce((count, result) => count + result.captured_runs, 0);
118
126
  return {
119
127
  captured_runs: capturedRuns,
128
+ catch_up_complete: results.every((result) => result.catch_up_complete !== false),
129
+ pending_runs: results.reduce((count, result) => count + (result.pending_runs ?? 0), 0),
120
130
  captured_segments: capturedRuns === 0 ? 0 : null,
121
131
  manifest_state: primary.manifest_state,
122
- skipped_reason:
123
- capturedRuns > 0
132
+ skipped_reason: results.some((result) => result.catch_up_complete === false)
133
+ ? "catch_up_pending"
134
+ : capturedRuns > 0
124
135
  ? null
125
136
  : results.some((result) => result.skipped_reason === "no_new_segments")
126
137
  ? "no_new_segments"
@@ -138,17 +149,26 @@ function parseJsonResult(stdout: string): unknown {
138
149
  }
139
150
  }
140
151
 
141
- function readCaptured(payload: unknown): Array<{ captured: boolean }> {
152
+ function readCaptured(payload: unknown): {
153
+ captured: Array<{ captured: boolean }>;
154
+ complete: boolean;
155
+ pending: number;
156
+ } {
142
157
  if (typeof payload !== "object" || payload === null) throw new Error("Invalid capture payload");
143
158
  const telemetry = (payload as { telemetry?: unknown }).telemetry;
144
159
  if (typeof telemetry !== "object" || telemetry === null)
145
160
  throw new Error("Invalid capture telemetry");
146
- const receipt = telemetry as { mode?: unknown; complete?: unknown };
147
- if (receipt.mode !== "recent_exact_session" || receipt.complete !== true)
161
+ const receipt = telemetry as {
162
+ mode?: unknown;
163
+ complete?: unknown;
164
+ candidate_count?: unknown;
165
+ pending_count?: unknown;
166
+ };
167
+ if (receipt.mode !== "recent_exact_session" || typeof receipt.complete !== "boolean")
148
168
  throw new Error("Recent telemetry capture is incomplete");
149
169
  const captured = (telemetry as { captured?: unknown }).captured;
150
170
  if (!Array.isArray(captured)) throw new Error("Invalid capture entries");
151
- return captured.map((item) => {
171
+ const items = captured.map((item) => {
152
172
  if (
153
173
  typeof item !== "object" ||
154
174
  item === null ||
@@ -157,6 +177,16 @@ function readCaptured(payload: unknown): Array<{ captured: boolean }> {
157
177
  throw new Error("Invalid capture entry");
158
178
  return { captured: (item as { captured: boolean }).captured };
159
179
  });
180
+ const pending = receipt.complete ? 0 : receipt.pending_count;
181
+ if (
182
+ !receipt.complete &&
183
+ (!Number.isSafeInteger(pending) ||
184
+ (pending as number) < 1 ||
185
+ !Number.isSafeInteger(receipt.candidate_count) ||
186
+ (receipt.candidate_count as number) < items.length + (pending as number))
187
+ )
188
+ throw new Error("Recent telemetry capture lacks bounded pending progress");
189
+ return { captured: items, complete: receipt.complete, pending: pending as number };
160
190
  }
161
191
 
162
192
  function isManifestUninitialized(error: unknown): boolean {
@@ -190,6 +190,7 @@ export function createDashboardApp(
190
190
  const projectionRefreshDiagnostics = createProjectionRefreshDiagnostics();
191
191
  let activeCaptureFailure: { code: string; occurred_at: string; cause: string } | null = null;
192
192
  let activeCapture: ActiveCodexTelemetryCapture | null = null;
193
+ let activeCapturePending = false;
193
194
  let projectionRefreshInFlight: Promise<void> | null = null;
194
195
  let projectionRefreshRequested = false;
195
196
  const associatedRefreshJobs = new Set<string>();
@@ -270,6 +271,7 @@ export function createDashboardApp(
270
271
  onCaptureSuccess: (result) => {
271
272
  activeCapture = result;
272
273
  activeCaptureFailure = null;
274
+ activeCapturePending = result.catch_up_complete === false;
273
275
  },
274
276
  onCaptureFailure: (error) => {
275
277
  activeCaptureFailure = {
@@ -280,7 +282,9 @@ export function createDashboardApp(
280
282
  },
281
283
  });
282
284
  const visibleSnapshotState = () =>
283
- telemetryRefresh.pending || activeCaptureFailure !== null ? "updating" : snapshotState;
285
+ telemetryRefresh.pending || activeCaptureFailure !== null || activeCapturePending
286
+ ? "updating"
287
+ : snapshotState;
284
288
  startSnapshotSynchronization({
285
289
  workspaceRoot,
286
290
  discoverSourceRoots: () => dashboardCanonicalSourceRoots(workspaceRoot),
@@ -440,7 +444,7 @@ export function createDashboardApp(
440
444
  server_pid: process.pid,
441
445
  service: "zaip-aios-dashboard",
442
446
  status:
443
- manifestState === "initialized" && activeCaptureFailure === null
447
+ manifestState === "initialized" && activeCaptureFailure === null && !activeCapturePending
444
448
  ? projectionRefreshDiagnostics.healthStatus
445
449
  : "degraded",
446
450
  api_version: 2,
@@ -481,7 +485,9 @@ export function createDashboardApp(
481
485
  lifecycleManifestState(canonicalFilesystem),
482
486
  ]);
483
487
  const readinessStatus =
484
- manifestState === "initialized" && activeCaptureFailure === null ? "ready" : "degraded";
488
+ manifestState === "initialized" && activeCaptureFailure === null && !activeCapturePending
489
+ ? "ready"
490
+ : "degraded";
485
491
  if (isSqliteSnapshot) {
486
492
  const revision = readCommittedSnapshotRevision(workspaceRoot);
487
493
  if (observedSnapshotRevision !== null && observedSnapshotRevision !== revision) {
@@ -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.7.0",
3
+ "version": "4.9.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.7.0",
3
+ "version": "4.9.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.7.0",
3
+ "version": "4.9.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": "16b609f2cc84fbca57eac28dbf45969f8969fcac8d3a964a211530a69d76e007"
279
+ "sha256": "51e5b590cefb6e579380f6bd25aefacecdaae63e0334452d802cfed620ff8626"
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": "f42120a471dd8ea2816129960206cc9952360645e4a3cd6d09cbbe891973cde8"
411
+ "sha256": "36000642ad5ec75354a48998989c41030e3fc1990998d521ac417bed51595d85"
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.7.0",
3
+ "version": "4.9.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.7.0",
3
+ "version": "4.9.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: 5
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Garantia adaptativa e execução autônoma
@@ -36,6 +36,15 @@ Entregar uma SPEC ou PRD deve exigir prova no nível do produto planejado, além
36
36
 
37
37
  O framework deve preservar execução manual como padrão e permitir autonomia somente por configuração explícita.
38
38
 
39
+ Esta seção mantém o contrato de compatibilidade do runtime gerenciado legado.
40
+ Configuração ausente resolve para `manual`; novos projetos gerados pela v4
41
+ declaram explicitamente `codex_native`, executado pelo host. O teto legado de
42
+ três tentativas em AC-AUTO-001-06 não substitui os perfis congelados de
43
+ `autonomy.version: 1`: seus limites e critérios de recuperação pertencem a
44
+ RULE-AUTONOMY-DECISION. A presença da configuração, isoladamente, não comprova
45
+ que uma Task possui ledger de recuperação; `task recovery-status` deve informar
46
+ esse estado, mantendo `legacy_or_unmigrated` quando o registro estiver ausente.
47
+
39
48
  - `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
49
  - `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
50
  - `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.
@@ -57,7 +66,25 @@ Aprendizado e alegações de maturidade devem ser derivados de fatos verificáve
57
66
 
58
67
  O release deve falhar de modo discriminante quando código, distribuição ou evidência não atingirem o contrato publicado.
59
68
 
60
- - `AC-QUALITY-001-01`: release crítico inclui unit, E2E, arquitetura, CQRS, módulos, profile, segurança e testes negativos.
69
+ - `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
70
  - `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
71
  - `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
72
  - `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.
73
+
74
+ Na criação de PRD, SPEC e AC, selecione por impacto os testes de código e os fluxos
75
+ de dashboard alterados. Integre os contratos modificados antes do release e
76
+ qualifique o pacote completo uma vez no candidato final antes de publicar;
77
+ correções posteriores revalidam as provas afetadas. Reuse Evidence apenas quando
78
+ candidato, ambiente, contrato e impacto ainda coincidirem. Teste de código não
79
+ promove comportamento não observado a prova servida.
80
+
81
+ Na consolidação 4.9, a Decision
82
+ `DEC-AI-2026-10-03-22-18-TAREFA2-ACEITE-CODIGO-XFQFBLLYRN` delimita a
83
+ Task de recuperação a regressões de código dirigidas por seus deltas, revisão
84
+ independente e finalização. Coleta operacional e configurações sem prova servida
85
+ permanecem `unverified`; testes de código não as promovem a observação servida.
86
+ Integração dos fluxos e contratos alterados pertence à fase de integração; a
87
+ qualificação integral do pacote final ocorre uma vez antes da publicação,
88
+ conforme `DEC-AI-2026-10-03-22-16-QUALIFICACAO-FINAL-UNICA-UPQGEC6JJV`.
89
+ Evidence, candidato exato e controles críticos aplicáveis continuam obrigatórios;
90
+ 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.7.0"
9
+ source_release: "4.9.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.7.0"
9
+ source_release: "4.9.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.7.0"
9
+ source_release: "4.9.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.7.0"
9
+ source_release: "4.9.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.7.0"
9
+ source_release: "4.9.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.7.0"
9
+ source_release: "4.9.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.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Design system
@@ -4,9 +4,9 @@ id: REQUIREMENTS-EXECUTION-ENGINE
4
4
  area: execution-engine
5
5
  title: Preparação, materialização e DAG
6
6
  status: active
7
- version: 11
7
+ version: 13
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Execution engine
@@ -25,6 +25,13 @@ source_release: "4.7.0"
25
25
  `execute` deve materializar Changes, Tasks e Execution antes da primeira mutação, preservando snapshot da DAG para retomada e auditoria. A tentativa explícita já pertence à fase `execution`, independentemente de produzir diff.
26
26
 
27
27
  - `AC-EXEC-002-01`: repetir `execute` não duplica artefatos, e cada tentativa explicitamente iniciada possui Run atribuído.
28
+
29
+ Se uma definição de SPEC no mesmo turno físico já terminou com Gui e uma
30
+ autorização explícita observada manda executar aquela SPEC pronta, `spec execute`
31
+ pode registrar um segmento lógico sucessor de delivery. A Run de definição
32
+ permanece imutável; claim, alvo e hash da autorização vinculam a sucessora,
33
+ sem dois proprietários ativos ou contagem dupla de uso quando a fronteira de
34
+ tokens não é observável. Sem esses fatos, vale o guard normal de turno único.
28
35
  - `AC-EXEC-002-02`: cada Task executável possui dependências e Execution explícitas; Task encerrada como conversa read-only não materializa DAG sintética.
29
36
  - `AC-EXEC-002-03`: falha parcial pode ser retomada sem corromper o plano.
30
37
  - `AC-EXEC-002-04`: início da fase `execution` não implica mutação; `changed_files` e `result` registram separadamente se houve mudança real e qual foi o desfecho.
@@ -60,3 +67,5 @@ Execuções devem limitar repetição por checkpoints suaves e verificar somente
60
67
  - `AC-EXEC-005-05`: a skill de execução exige refresh seletivo e checkpoint compacto ao atingir os budgets suaves.
61
68
  - `AC-EXEC-005-06`: quando um plano visível é útil, cada passo começa com `DEFINE:`, `PLAN:`, `EXECUTE:` ou `VERIFY:`, usa somente fases aplicáveis, contém no máximo 5 passos e combina ações triviais; tarefas simples podem omitir o plano.
62
69
  - `AC-EXEC-005-07`: checkpoints suaves de contexto são acionados somente por ciclos; telemetria de input não cacheado do provider e contexto observável permanece registrada com sua origem, sem inventar valores ausentes. Checkpoints de segurança por esgotamento de tentativas semânticas são distintos desse contador. Observações de convergência não concedem aprovação nem cancelam trabalho por duração; tempo não observado permanece indisponível.
70
+
71
+ Para novas avaliações de PRD/SPEC/DAG e release, a política `proportional-acceptance-v1` de `@zaip-ai/specs` exige critério obrigatório rastreável a pedido humano, Requirement ativo ou risco concreto, com aplicabilidade, resultado observável, prova suficiente, responsável e condição de parada. Todos os obrigatórios precisam passar no candidato aplicável; melhoria opcional pendente não bloqueia. Uma Task avulsa conserva o assurance proporcional existente, sem escala nova. Snapshots antigos não são recalculados: adoção retroativa exige migração explícita, versionada e atribuída.
@@ -6,7 +6,7 @@ title: Projeções operacionais e analíticas
6
6
  status: active
7
7
  version: 14
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Kanban and dashboard
@@ -6,7 +6,7 @@ title: Seleção automática e observável de modelo e effort
6
6
  status: active
7
7
  version: 10
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Orquestração de modelos
@@ -4,9 +4,9 @@ id: REQUIREMENTS-PUBLIC-DISTRIBUTION
4
4
  area: public-distribution
5
5
  title: Distribuição pública e ativação
6
6
  status: active
7
- version: 9
7
+ version: 10
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Distribuição pública e ativação
@@ -44,15 +44,17 @@ Restrições explícitas prevalecem. No init sem force, catálogo oficial legado
44
44
  ser atualizado e passa a integrar o lock; catálogo personalizado permanece protegido. Discovery
45
45
  gerenciada é uma projeção única, regenerada a partir do catálogo da versão instalada.
46
46
 
47
- ## REQ-DIST-003 — Configuração global portátil do Codex
47
+ ## REQ-DIST-003 — Hooks do Codex restritos ao projeto
48
48
 
49
- O CLI público deve descobrir o diretório inicial do usuário em execução e reconciliar a proteção
50
- global do Codex sem apagar preferências, integrações ou identidades canônicas do usuário e sem
51
- introduzir paths ou identidades locais fixas.
49
+ O CLI público deve instalar a proteção do Codex exclusivamente no projeto em instalação,
50
+ por meio de `.codex/config.toml` e `.codex/hooks`. A migração pode remover hooks globais
51
+ legados comprovadamente pertencentes ao ZAIP após backup recuperável, preservando as demais
52
+ preferências globais, identidades canônicas, integrações e hooks de terceiros. Nenhum caminho
53
+ ou identidade do ambiente de build pode ser fixado no pacote.
52
54
 
53
- - `AC-DIST-003-01`: em uma instalação limpa ou existente, o CLI preserva as configurações globais e identidades canônicas, remove somente aliases `codex_name` obsoletos declarados pelo catálogo instalado e adiciona o hook portátil canônico, sem referência a nome de usuário ou path absoluto do ambiente de build.
54
- - `AC-DIST-003-02`: se a escrita global falhar, o CLI conclui a instalação do projeto sem ocultar a falha, informa o destino exato e o erro, e mantém na documentação os passos de reconciliação manual que preservam a configuração existente.
55
- - `AC-DIST-003-03`: a reconciliação substitui todo hook `PreToolUse` identificado como ZAIP por exatamente um bloco canônico e preserva hooks de terceiros; reexecuções são idempotentes.
55
+ - `AC-DIST-003-01`: em instalação limpa ou atualização, o CLI registra exatamente o hook canônico do ZAIP no `.codex/config.toml` do projeto e instala seu script em `.codex/hooks`; não cria nem atualiza hook global como fallback, não altera preferências ou identidades globais e não embute nome de usuário ou caminho absoluto do ambiente de build.
56
+ - `AC-DIST-003-02`: a migração identifica por assinatura/ownership os registros globais legados de hooks do ZAIP, verifica primeiro os hooks canônicos do projeto, produz e verifica backup recuperável antes de remover somente essas entradas reconhecidas da configuração global, e preserva integralmente hooks de terceiros e as demais configurações globais. Se a verificação local falhar, preserva também o hook global legado e relata a pendência; conteúdo global sem prova de ownership permanece intacto para revisão manual.
57
+ - `AC-DIST-003-03`: a instalação e a migração são idempotentes; falha ao gravar o hook do projeto, verificar o backup ou limpar um legado reconhecido é informada com destino, erro, estado parcial e passos de recuperação, sem declarar proteção concluída nem recorrer a um hook global.
56
58
 
57
59
  ## Verificação
58
60
 
@@ -6,7 +6,7 @@ title: Layout modular e limites de código-fonte
6
6
  status: active
7
7
  version: 5
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Software architecture
@@ -6,7 +6,7 @@ title: Melhorias estratégicas de custo, qualidade e resiliência
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Melhorias estratégicas de custo, qualidade e resiliência
@@ -6,7 +6,7 @@ title: Ciclo de vida do trabalho
6
6
  status: active
7
7
  version: 26
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Work lifecycle
@@ -6,7 +6,7 @@ title: Evidências, custo por Task e autonomia por SPEC
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "4.7.0"
9
+ source_release: "4.9.0"
10
10
  ---
11
11
 
12
12
  # Evidências, custo por Task e autonomia por SPEC
@@ -17,7 +17,7 @@ domains: [terraform, hostinger, cloudflare, ssh]
17
17
  - `.env` na raiz é a fonte local preferida; `.agents/.env` é alternativa configurável. Ambos são ignorados e só fornecem credenciais e identificadores ao subprocesso mínimo. Eles nunca autorizam alvo. Antes de operação remota, confira perfil `autonomous-cloud`, conta+zona Cloudflare, conta Hostinger, IDs das VPS e fingerprints SSH contra a execução ativa. Ausência, diferença ou ambiguidade bloqueia.
18
18
  - Quando a Task registrar autorização permanente e o `.env` da raiz contiver identificadores deliberados, descoberta somente de leitura pode derivar e registrar esse escopo antes da configuração; não exija JSON manual nem nova autorização. Fora desse contexto, credencial sem mandato e alvos delimitados permanece insuficiente.
19
19
  - Autonomia autorizada pelo usuário começa somente após esse preflight. Não peça a mesma autorização novamente para recursos já delimitados: abrir portas aprovadas, alterar firewall, rotacionar chave, configurar DNS, criar/editar recursos e testar são autônomos dentro da arquitetura e do orçamento aprovados. Nova zona, conta, VPS, destino, plano, datacenter, teto de custo, recurso desconhecido ou efeito irreversível ainda não aprovado exige escopo atualizado.
20
- - VPS 1 recebe somente ingress público Cloudflare; VPS 2 recebe somente transporte privado autenticado da VPS 1 e administração permitida. Redis, BullMQ, exporters, Grafana, Prometheus, Uptime Kuma e painéis não expõem DNS ou portas públicas. Produção e beta têm dados e redes independentes.
20
+ - Se o contrato de infraestrutura aprovado declarar a topologia de duas VPS, VPS 1 recebe somente ingress público Cloudflare e VPS 2 somente transporte privado autenticado da VPS 1 e administração permitida. Para outra topologia, derive limites de rede do contrato aprovado antes de agir; não crie uma segunda VPS por inferência. Redis, BullMQ, exporters, Grafana, Prometheus, Uptime Kuma e painéis não expõem DNS ou portas públicas. Produção e beta têm dados e redes independentes quando ambos os ambientes estiverem no escopo.
21
21
  - O provider Hostinger não prova firewall, malha privada ou configuração de containers. Declare o executor e valide essas camadas por observação; não invente recursos ou campos de provider não verificados.
22
22
  - Exija backend remoto com criptografia, versionamento e locking antes de apply compartilhado. Execute `fmt`, `validate`, plano revisado, apply do arquivo de plano e read-after-write. Nunca persista segredo, state, plano binário ou material de chave.
23
23
  - Só declare infraestrutura funcional após evidência observada de DNS, TLS, health checks, portas privadas negadas e restauração. Sem acesso/execução observada, reporte apenas validação estática/local.