@zaip-ai/cli 5.4.0 → 5.6.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 (68) hide show
  1. package/dist/services/adapters.d.ts +1 -1
  2. package/dist/services/adapters.js +1 -1
  3. package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
  4. package/dist/services/codex-conversation-lifecycle-hook.js +37 -8
  5. package/dist/services/codex-conversation-lifecycle-hook.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 +5 -198
  8. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  9. package/dist/services/codex-pre-tool-policy-template.d.ts +2 -0
  10. package/dist/services/codex-pre-tool-policy-template.d.ts.map +1 -0
  11. package/dist/services/codex-pre-tool-policy-template.js +136 -0
  12. package/dist/services/codex-pre-tool-policy-template.js.map +1 -0
  13. package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
  14. package/dist/services/codex-pre-tool-support-template.js +62 -0
  15. package/dist/services/codex-pre-tool-support-template.js.map +1 -1
  16. package/package.json +1 -1
  17. package/templates/.agents/README-ENG.md +10 -2
  18. package/templates/.agents/README.md +9 -1
  19. package/templates/.agents/config/agents/discovery.json +1 -1
  20. package/templates/.agents/dashboard/.zaip-managed.json +29 -29
  21. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Bw42VT15.js → DashboardHelpDialog-B5YEOEej.js} +10 -2
  22. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-C3Y-jqQe.js → PricingSettingsDialog--irvqUl5.js} +1 -1
  23. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-Bx54lj7x.js → ProjectSettingsPage-DxyjL1__.js} +1 -1
  24. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-BNxFpGCt.js → TraceabilityWorkspace-BWEEMNV-.js} +1 -1
  25. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-BQDxpGq0.js → dashboard-localization-C45x75cf.js} +10 -2
  26. package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-CsSv72iu.js → index-DGUs5bRP.js} +2 -2
  27. package/templates/.agents/dashboard/apps/frontend/dist/index.html +1 -1
  28. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  29. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  30. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  31. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  32. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  33. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  34. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  35. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +161 -160
  36. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +59 -59
  37. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  38. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +161 -160
  39. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  40. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  41. package/templates/.agents/design/.zaip-managed.json +3 -3
  42. package/templates/.agents/design/apps/catalog/package.json +1 -1
  43. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  44. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  45. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  46. package/templates/.agents/requirements/comparative-audit.md +1 -1
  47. package/templates/.agents/requirements/context-engine.md +1 -1
  48. package/templates/.agents/requirements/cost-observability.md +1 -1
  49. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  50. package/templates/.agents/requirements/data-export.md +1 -1
  51. package/templates/.agents/requirements/design-system.md +1 -1
  52. package/templates/.agents/requirements/execution-engine.md +1 -1
  53. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  54. package/templates/.agents/requirements/model-orchestration.md +1 -1
  55. package/templates/.agents/requirements/public-distribution.md +1 -1
  56. package/templates/.agents/requirements/software-architecture.md +1 -1
  57. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  58. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  59. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  60. package/templates/.agents/runtime/VERSION +1 -1
  61. package/templates/.agents/runtime/bin/zaip.mjs +185 -153
  62. package/templates/.agents/runtime/checksums.sha256 +5 -5
  63. package/templates/.agents/runtime/manifest.json +1 -1
  64. package/templates/.agents/runtime/provenance.json +4 -4
  65. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  66. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -0
  67. package/templates/.agents/zaip-aios/VERSION +1 -1
  68. package/templates/template-manifest.json +63 -63
@@ -1,6 +1,6 @@
1
1
  import { type PublicAgentCatalog } from "./agent-adapters.js";
2
2
  export { isManagedAdapter } from "./managed-adapter.js";
3
- export declare const ADAPTERS_VERSION = "5.4.0";
3
+ export declare const ADAPTERS_VERSION = "5.6.0";
4
4
  export interface AdapterFile {
5
5
  path: string;
6
6
  content: string;
@@ -11,7 +11,7 @@ export { isManagedAdapter } from "./managed-adapter.js";
11
11
  import { CODEX_GITHUB_DEPLOY_RULES, CODEX_SECURITY_RULES } from "./codex-rules.js";
12
12
  import { codexWindowsHookCommand } from "./codex-windows-hook-command.js";
13
13
  import { applyTransactionalChanges, assertSafeDestination } from "./transactional-files.js";
14
- export const ADAPTERS_VERSION = "5.4.0";
14
+ export const ADAPTERS_VERSION = "5.6.0";
15
15
  const ROOT_GUIDANCE = `# ZAIP-AIOS
16
16
 
17
17
  Read \`.agents/config/project.yaml\` first. Apply ZAIP only for literal boolean \`zaip.enabled: true\`, except framework maintenance or \`zaip enable\`. \`AGENTS.md\` is a bootstrap; canonical guidance lives in \`.agents/\`.
@@ -1 +1 @@
1
- {"version":3,"file":"codex-conversation-lifecycle-hook.d.ts","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,QAmQ7C,CAAC"}
1
+ {"version":3,"file":"codex-conversation-lifecycle-hook.d.ts","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,QAgS7C,CAAC"}
@@ -21,7 +21,7 @@ const text = value => typeof value === "string" && value.length > 0 && value.len
21
21
  const inside = (path, base = root) => { const p = relative(base, resolve(path)); return p === "" || (!p.startsWith("..") && !isAbsolute(p)); };
22
22
  let raw = ""; for await (const chunk of process.stdin) raw += chunk;
23
23
  const event = parse(raw), session = text(event?.session_id), turn = text(event?.turn_id);
24
- let receipt, receiptPath, lease;
24
+ let receipt, receiptPath, lease, closureVerified = false;
25
25
  function reply(pending = false) {
26
26
  if (!replay && governanceEnabled) activation?.recordActivation(root, event, pending ? "pending" : "observed");
27
27
  // Closure belongs to the live orchestrator. Stop only records/reconciles;
@@ -202,8 +202,11 @@ try {
202
202
  receipt = old?.schema_version === 1 && old.session_id === session && old.turn_id === turn ? old : { schema_version: 1, session_id: session, turn_id: turn, state: "pending", attempts: 0 };
203
203
  const transcriptPath = text(event.transcript_path) ?? text(receipt.event?.transcript_path);
204
204
  receipt.event = { hook_event_name: "Stop", cwd: root, session_id: session, turn_id: turn, transcript_path: transcriptPath, stop_hook_active: true };
205
- if (receipt.state === "persisted") { reply(); } else {
206
- receipt.attempts += 1; receipt.state = "pending"; await save(receiptPath, receipt);
205
+ const telemetryReplay = replay && !automatic && receipt.state === "persisted" &&
206
+ !["observed", "disabled"].includes(receipt.telemetry?.state);
207
+ if (receipt.state === "persisted" && !telemetryReplay) { reply(); } else {
208
+ const closurePersisted = receipt.state === "persisted";
209
+ if (!closurePersisted) { receipt.attempts += 1; receipt.state = "pending"; await save(receiptPath, receipt); }
207
210
  let status = null;
208
211
  for (const delay of automatic ? [0] : [0, 250, 750]) { if (delay) await new Promise(r => setTimeout(r, delay)); status = await terminal(transcriptPath); if (status) break; }
209
212
  if (!status) throw new Error("transcript_pending");
@@ -219,7 +222,7 @@ try {
219
222
  intake = parse(started.out);
220
223
  }
221
224
  const run = intake?.run?.run_id;
222
- if (automatic && receipt.run_id !== undefined && receipt.run_id !== run) throw new Error("recovery_run_mismatch");
225
+ if (receipt.run_id !== undefined && receipt.run_id !== run) throw new Error("recovery_run_mismatch");
223
226
  if (typeof run !== "string" || (intake.task !== null && typeof intake.task?.id !== "string")) throw new Error("start_pending");
224
227
  receipt.run_id = run; await save(receiptPath, receipt);
225
228
  const result = await call(cli, ["subagent", "reconcile-stop", "--session", session, "--turn", turn], transcriptPath);
@@ -246,15 +249,41 @@ try {
246
249
  throw new Error("owned_task_recoverable");
247
250
  }
248
251
  }
252
+ closureVerified = true; receipt.error = null;
253
+ if (!closurePersisted) {
254
+ receipt.state = "persisted"; receipt.persisted_at = new Date().toISOString(); receipt.error = null;
255
+ receipt.telemetry = { state: !trackingEnabled ? "disabled" : intake.task === null ? "unavailable" : "pending", error: null };
256
+ await save(receiptPath, receipt);
257
+ }
249
258
  if (intake.task !== null && trackingEnabled) {
259
+ receipt.telemetry = { state: "pending", error: null }; await save(receiptPath, receipt);
250
260
  const usage = await call(cli, ["run", "usage", run, "--disable-codex-raw"], transcriptPath);
251
- if (usage.code !== 0 || parse(usage.out) === null) throw new Error("telemetry_pending");
261
+ const collected = parse(usage.out);
262
+ if (usage.code !== 0 || collected === null || collected.run?.id !== run) {
263
+ receipt.telemetry = { state: "pending", error: "telemetry_pending" };
264
+ } else {
265
+ const coverage = collected.run.usage?.coverage;
266
+ const observed = [coverage?.tokens, coverage?.usd, coverage?.brl].some(value => Number.isSafeInteger(value) && value > 0);
267
+ receipt.telemetry = { state: observed ? "observed" : "unavailable", error: null };
268
+ }
269
+ await save(receiptPath, receipt);
270
+ } else if (closurePersisted) {
271
+ receipt.telemetry = { state: trackingEnabled ? "unavailable" : "disabled", error: null };
272
+ await save(receiptPath, receipt);
252
273
  }
253
- receipt.state = "persisted"; receipt.persisted_at = new Date().toISOString(); receipt.error = null;
254
- await save(receiptPath, receipt); reply();
274
+ reply();
255
275
  }
256
276
  } catch (error) {
257
- if (receipt && receiptPath) { receipt.state = "pending"; receipt.error = String(error.message ?? error); await save(receiptPath, receipt).catch(() => {}); }
277
+ if (receipt && receiptPath) {
278
+ if (receipt.state === "persisted" && !closureVerified) {
279
+ receipt.error = "replay_proof_failed:" + String(error.message ?? error);
280
+ } else if (receipt.state === "persisted") {
281
+ receipt.error = null;
282
+ if (!["observed", "disabled"].includes(receipt.telemetry?.state))
283
+ receipt.telemetry = { state: "pending", error: String(error.message ?? error) };
284
+ } else { receipt.state = "pending"; receipt.error = String(error.message ?? error); }
285
+ await save(receiptPath, receipt).catch(() => {});
286
+ }
258
287
  await note(String(error.message ?? error)).catch(() => {}); reply(true);
259
288
  } finally { if (lease) { await lease.close(); await unlink(receiptPath + ".lock").catch(() => {}); } }
260
289
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"codex-conversation-lifecycle-hook.js","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmQ1D,CAAC"}
1
+ {"version":3,"file":"codex-conversation-lifecycle-hook.js","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgS1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,QAspB/B,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,QAod/B,CAAC"}
@@ -1,139 +1,6 @@
1
+ import { CODEX_PRE_TOOL_POLICY_HEADER } from "./codex-pre-tool-policy-template.js";
1
2
  import { CODEX_STALE_GIT_LOCK_HELPER } from "./codex-stale-git-lock-template.js";
2
- export const CODEX_PRE_TOOL_HOOK = String.raw `import { execFile } from "node:child_process";
3
- import { writeSync } from "node:fs";
4
- import { lstat, readFile, realpath } from "node:fs/promises";
5
- import { dirname, isAbsolute, relative, resolve } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- import { promisify } from "node:util";
8
- import { captureCliTurn, createHookBudget, checkDestructivePatterns, configuredDeploymentBranches, configuredPermissionProfile, gitInvocation, inside, isLiteralReadSequence, readBoundedCanonicalText, requiresShellMutationRun, reviewedContextReadPaths, reviewedReleasePaths, rewriteCliInput, selectHookExecutionWorkspace, selectHookRepositoryRoot, shellSyntax, tokenizeLiteralCommand, validateInlineExecution } from "./zaip-pre-tool-support.mjs";
9
- import { createCloudValidators } from "./zaip-pre-tool-cloud.mjs";
10
- const { execute, parseEvent } = createHookBudget(promisify(execFile));
11
- const nativeAuthority = await import("./zaip-native-tool-authority.mjs").catch(() => null);
12
- const activation = await import("./zaip-hook-activation.mjs").catch(() => null);
13
- const installedRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
14
- let repositoryRoot = installedRoot;
15
- let principalFullAccess = false;
16
- let principalFullNetwork = false;
17
- const deletionCommandPattern = /\b(?:Remove-Item|ri|rm|rmdir|rd|del|erase)\b/i;
18
- const allowedExplicitNetworkHosts = new Set([
19
- "127.0.0.1", "api.github.com", "github.com", "localhost", "objects.githubusercontent.com", "releases.hashicorp.com", "::1",
20
- ]);
21
- const networkClientPattern = /\b(?:curl|wget|Invoke-WebRequest|Invoke-RestMethod|iwr|irm)\b/i;
22
- const cloudRunnerScript = ".agents/tools/cloud-runner.mjs";
23
- const cloudContractPath = ".agents/config/autonomous-cloud-contract.json";
24
- const cloudOperationProviders = new Map([
25
- ["cloudflare:dns:read", "cloudflare"], ["cloudflare:dns:create", "cloudflare"], ["cloudflare:dns:edit", "cloudflare"],
26
- ["hostinger:vps:read", "hostinger"],
27
- ["hostinger:ssh:read", "hostinger"],
28
- ["hostinger:ssh:configure", "hostinger"],
29
- ["hostinger:ssh:test", "hostinger"],
30
- ["terraform:plan", "terraform"],
31
- ["terraform:apply", "terraform"],
32
- ["terraform:import", "terraform"],
33
- ]);
34
- const homeReferencePattern = /(?:\$HOME\b|\$env:(?:USERPROFILE|HOMEDRIVE|HOMEPATH)\b|%(?:USERPROFILE|HOMEDRIVE|HOMEPATH)%|(?:^|[\s"'=])~[\\/])/i;
35
- const credentialReferencePattern = /(?:^|[\\/\s"'=])(?:\.ssh|\.aws|\.azure|\.kube|\.docker|\.gnupg|\.git-credentials|\.npmrc|\.pypirc|id_(?:rsa|ed25519)|[^\\/\s"']+\.(?:pem|key|p12|pfx))(?:[\\/\s"'=]|$)|(?:^|[\\/\s"'=])\.env(?:\.[A-Za-z0-9_-]+)*(?:[\\/\s"']|$)/i;
36
- const sensitiveEnvironmentPattern = /(?:\$env:|%|\$)[A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY|CREDENTIAL)[A-Z0-9_]*%?/i;
37
- const destructivePatterns = [
38
- {
39
- pattern: /\b(?:Restart-Computer|Stop-Computer|Restart-Host|shutdown(?:\.exe)?|reboot|poweroff|halt|Suspend-Computer|hibernate|logoff|Win32Shutdown)\b/i,
40
- reason: "Local computer restart, shutdown, suspension, hibernation and session termination are blocked.",
41
- },
42
- {
43
- pattern: /\b(?:Clear-Content|shred)\b/i,
44
- reason: "Unbounded content destruction is blocked.",
45
- },
46
- {
47
- pattern: /\bgit\s+(?:clean\b|reset\s+--hard\b|checkout\s+--\b|restore\b|branch\s+-d\b|tag\s+-d\b)/i,
48
- reason: "Destructive Git state changes are blocked.",
49
- },
50
- {
51
- pattern: /\bgit\s+push\b[\s\S]*(?:--force(?:-with-lease|-if-includes)?\b|-f\b|--mirror\b|--delete\b|--all\b|(?:^|\s):\S+)/i,
52
- reason: "Force, mirror, bulk, and deletion pushes are blocked.",
53
- },
54
- {
55
- pattern: /\bgit\s+commit\b[\s\S]*(?:--amend\b|--no-verify\b|-n\b)/i,
56
- reason: "Commit history rewrites and hook bypasses are blocked.",
57
- },
58
- {
59
- pattern: /\bgit\s+(?:-c\b|--config(?:-env)?\b|--git-dir\b|--work-tree\b|--namespace\b)/,
60
- reason: "Git global configuration and repository-routing overrides are blocked.",
61
- },
62
- {
63
- pattern: /\bgit\s+fetch\b[\s\S]*(?:--all\b|--prune\b|--prune-tags\b)/i,
64
- reason: "Bulk or pruning fetches are outside the bounded deploy flow.",
65
- },
66
- {
67
- pattern: /\bgit\s+add\b[\s\S]*(?:--force\b|-f\b|(?:^|[\\/\s])(?:\.env(?:\.|\s|$)|[^\s]*\.(?:pem|key|p12|pfx)\b|id_(?:rsa|ed25519)\b))/i,
68
- reason: "Force-adding or explicitly staging credential-like files is blocked.",
69
- },
70
- {
71
- pattern: /\bgit\s+add\b[\s\S]*(?:\s-A\b|--all\b|(?:^|\s)\.(?:\s|$)|\s-u\b)/i,
72
- reason: "Broad Git staging is blocked; authorized deploy commits require explicit pathspecs.",
73
- },
74
- {
75
- pattern: /\bgit\s+(?:remote\s+(?:add|set-url|remove|rename)|config\b[\s\S]*(?:sshCommand|credential|url\.))/i,
76
- reason: "Remote, SSH, and credential configuration changes are blocked.",
77
- },
78
- {
79
- pattern: /\bgh(?:\.exe)?\b[\s\S]*\s(?:--repo|-R)(?:=|\s|(?=[A-Za-z0-9]))/i,
80
- reason: "GitHub CLI commands must target the current repository.",
81
- },
82
- {
83
- pattern: /\b(?:drop\s+(?:database|schema|table)|truncate\s+table|supabase\s+db\s+reset)\b/i,
84
- reason: "Destructive database operations are blocked.",
85
- },
86
- {
87
- pattern: /\b(?:rmSync|rmdirSync|unlinkSync|rmtree|remove|unlink|Directory\.Delete|File\.Delete)\s*\(/i,
88
- reason: "Inline deletion APIs are blocked.",
89
- },
90
- {
91
- pattern: /(?:curl|wget|Invoke-WebRequest|Invoke-RestMethod|\biwr\b|\birm\b)[\s\S]*\|[\s&]*(?:bash|sh|zsh|pwsh|powershell|cmd|node|python|iex|Invoke-Expression)\b/i,
92
- reason: "Downloaded content cannot be piped into an interpreter.",
93
- },
94
- {
95
- pattern: /(?:-(?:EncodedCommand|enc)\b|FromBase64String\s*\(|certutil\s+-(?:decode|urlcache)\b|mshta\s+https?:|rundll32\s+javascript:)/i,
96
- reason: "Encoded or evasive command execution is blocked.",
97
- },
98
- {
99
- pattern: /\b(?:Set-MpPreference|Add-MpPreference|Remove-MpPreference|Set-NetFirewallProfile|New-NetFirewallRule|Remove-NetFirewallRule|Disable-NetFirewallRule|Enable-PSRemoting|Set-WSManQuickConfig)\b|\bnetsh\s+advfirewall[\s\S]*(?:\boff\b|\badd\b|\bdelete\b|\bset\b)/i,
100
- reason: "Firewall, antivirus, and remote-management changes are blocked.",
101
- },
102
- {
103
- pattern: /\b(?:reg(?:\.exe)?\s+(?:add|delete)|schtasks(?:\.exe)?\s+\/(?:create|delete|change)|sc(?:\.exe)?\s+(?:create|delete|stop|config)|New-Service|Set-Service|Stop-Service)\b/i,
104
- reason: "OS persistence and service changes are blocked.",
105
- },
106
- {
107
- pattern: /\b(?:diskpart|bcdedit|fsutil|takeown|icacls|Set-Acl|chmod|chown)\b|(?:^|[;&|({\r\n])\s*(?:&\s*)?["']?format(?:\.(?:com|exe))?["']?(?=\s|$)|\bcipher\s+\/w\b/i,
108
- reason: "Disk, boot, ownership, and access-control changes are blocked.",
109
- },
110
- {
111
- pattern: /\b(?:runas|sudo|gsudo)\b|Start-Process[\s\S]*-Verb\s+RunAs|\bSet-ExecutionPolicy\b/i,
112
- reason: "Privilege escalation and persistent execution-policy changes are blocked.",
113
- },
114
- {
115
- pattern: /\b(?:Start-Process|saps)\b[^\r\n;|]*(?:[$(]|\b(?:-FilePath\s+)?['"]?git(?:\.exe)?['"]?(?:\s|$))/i,
116
- reason: "Dynamic or indirect Git process launch is blocked; use a reviewed repository script.",
117
- },
118
- {
119
- pattern: /\b(?:winget|choco|scoop)\s+(?:install|uninstall|upgrade)\b|\b(?:npm|pnpm|yarn)\s+(?:install|add|remove|uninstall)[\s\S]*(?:--global|-g)\b/i,
120
- reason: "System-wide package changes are blocked.",
121
- },
122
- {
123
- pattern: /(?:--host|--hostname|--listen(?:-address)?)\s+(?:0\.0\.0\.0|\*|::)\b/i,
124
- reason: "Non-loopback listeners are blocked.",
125
- },
126
- {
127
- pattern: /\bgh(?:\.exe)?\s+(?:pr\s+(?:create|merge|close|reopen)|issue\s+(?:create|close|reopen|delete)|release\s+(?:create|delete|upload)|repo\s+(?:create|delete|archive)|api\b[\s\S]*(?:(?:--method|-X)(?:=|\s*)(?:POST|PUT|PATCH|DELETE)\b|(?:--field|--raw-field|--input)(?:=|\s+)|(?:^|\s)-[fF](?:=|\s+)))/i,
128
- reason: "Unreviewed GitHub mutations are blocked; use the bounded deploy workflow.",
129
- },
130
- {
131
- pattern: /\b(?:npm|pnpm|yarn)\s+(?:publish|login|logout|token|owner|deprecate)\b/i,
132
- reason: "Package-registry publication and credential changes are blocked.",
133
- },
134
- ];
135
-
136
- function deny(reason, record = true) {
3
+ export const CODEX_PRE_TOOL_HOOK = String.raw `${CODEX_PRE_TOOL_POLICY_HEADER}function deny(reason, record = true) {
137
4
  if (record) activation?.recordActivation(repositoryRoot, event, "denied");
138
5
  writeSync(
139
6
  1,
@@ -305,67 +172,7 @@ async function validateGitPublication(command) {
305
172
  }
306
173
  }
307
174
 
308
- // These CLI values are data, never shell programs. Only one literal invocation of
309
- // the canonical runtime qualifies; interpolation, pipelines and other scripts do not.
310
- function executionPolicyCommand(command) {
311
- const tokens = tokenizeLiteralCommand(command);
312
- if (!tokens || !/^(?:.*[\\/])?node(?:\.exe)?$/i.test(tokens[0] ?? "") ||
313
- resolve(event.cwd, tokens[1] ?? "") !== resolve(repositoryRoot, ".agents/runtime/bin/zaip.mjs") ||
314
- tokens[2] !== "conversation" || tokens[3] !== "finish") return command;
315
- const result = [...tokens];
316
- for (let index = 4; index < result.length; index++) {
317
- if (result[index] === "--summary" && index + 1 < result.length) result[++index] = "literal-summary";
318
- else if (result[index].startsWith("--summary=")) result[index] = "--summary=literal-summary";
319
- }
320
- return result.map(token => JSON.stringify(token)).join(" ");
321
- }
322
-
323
- async function isCurrentRepositoryRead(command) {
324
- const tokens = tokenizeLiteralCommand(command);
325
- if (!tokens || !/^gh(?:\.exe)?$/i.test(tokens[0] ?? "")) return false;
326
- const rest = [], repositories = [];
327
- for (let index = 0; index < tokens.length; index++) {
328
- const token = tokens[index];
329
- if (token === "--repo" || token === "-R") repositories.push(tokens[++index]);
330
- else if (token.startsWith("--repo=")) repositories.push(token.slice(7));
331
- else if (token.startsWith("-R") && token.length > 2) repositories.push(token.slice(2));
332
- else rest.push(token);
333
- }
334
- if (repositories.length !== 1 || !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repositories[0] ?? "") ||
335
- rest.some(token => token.includes("'")) || !isLiteralReadSequence(rest.map(token => "'" + token + "'").join(" "))) return false;
336
- try {
337
- const origin = (await execute("git", ["remote", "get-url", "origin"], { cwd: repositoryRoot, encoding: "utf8", windowsHide: true })).stdout.trim();
338
- const match = /^(?:git@github\.com:|https:\/\/github\.com\/|ssh:\/\/git@github\.com\/)([^/]+\/[^/]+?)\.git$|^(?:git@github\.com:|https:\/\/github\.com\/|ssh:\/\/git@github\.com\/)([^/]+\/[^/]+?)\/?$/.exec(origin);
339
- return !!match && (match[1] ?? match[2]).toLowerCase() === repositories[0].toLowerCase();
340
- } catch { return false; }
341
- }
342
175
 
343
- function validateHashicorpRead(command) {
344
- const tokens = tokenizeLiteralCommand(command);
345
- if (!tokens || !/^(?:curl(?:\.exe)?|Invoke-WebRequest|Invoke-RestMethod|iwr|irm)$/i.test(tokens[0]))
346
- deny("HashiCorp releases require a literal supported read command.");
347
- let urlCount = 0;
348
- for (let i = 1; i < tokens.length; i++) {
349
- const token = tokens[i];
350
- if (/^https:\/\//i.test(token)) {
351
- const url = new URL(token);
352
- if (url.hostname !== "releases.hashicorp.com" || url.username || url.password || url.port)
353
- deny("HashiCorp reads require one exact HTTPS destination.");
354
- urlCount++; continue;
355
- }
356
- if (["-I", "--head", "-s", "-S", "-sS", "--silent", "--show-error", "--fail", "-q", "--disable"].includes(token)) continue;
357
- const namedMethod = /^(?:--request|--method|-Method)(?:=(.*))?$/i.exec(token);
358
- const curlMethod = /^-X(.*)$/.exec(token);
359
- if (namedMethod || curlMethod) {
360
- const value = namedMethod ? (namedMethod[1] ?? tokens[++i]) : (curlMethod[1] || tokens[++i]);
361
- if (!/^(?:GET|HEAD)$/i.test(value ?? "")) deny("HashiCorp releases permit only GET or HEAD requests.");
362
- continue;
363
- }
364
- if (/^(?:-Uri|--url)$/i.test(token) && /^https:\/\//i.test(tokens[i + 1] ?? "")) continue;
365
- deny("Unsupported option in the bounded HashiCorp read command.");
366
- }
367
- if (urlCount !== 1) deny("HashiCorp reads require exactly one HTTPS URL.");
368
- }
369
176
 
370
177
  function validateExplicitNetwork(command) {
371
178
  if (/(?:^|[;&|]\s*)\b(?:ssh|scp|sftp|rsync|ftp|telnet|nc|ncat)\b/i.test(command)) {
@@ -393,7 +200,7 @@ function validateExplicitNetwork(command) {
393
200
  if (host === "releases.hashicorp.com") {
394
201
  if (target.protocol !== "https:" || target.username || target.password)
395
202
  deny("HashiCorp releases require an exact HTTPS read target.");
396
- validateHashicorpRead(command);
203
+ validateHashicorpRead(command, deny);
397
204
  }
398
205
  }
399
206
  }
@@ -647,9 +454,9 @@ else {
647
454
  ...await reviewedContextReadPaths(command, credentialReferencePattern, installedRoot), ...await (nativeAuthority?.reviewedValidationRuntimePaths?.(command, tokenizeLiteralCommand, repositoryRoot) ?? []),
648
455
  ];
649
456
  await validateExplicitFilesystemReferences(command, event.cwd, reviewedPaths);
650
- const policyCommand = executionPolicyCommand(command);
457
+ const policyCommand = executionPolicyCommand(command, event.cwd, repositoryRoot);
651
458
  validateInlineExecution(policyCommand, deny);
652
- if (!isLiteralReadSequence(policyCommand) && !await isCurrentRepositoryRead(policyCommand)) {
459
+ if (!isLiteralReadSequence(policyCommand) && !await isCurrentRepositoryRead(policyCommand, repositoryRoot, execute)) {
653
460
  await validateGitPublication(policyCommand);
654
461
  await validateCloudRunner(policyCommand);
655
462
  validateDirectCloudProviderMutation(policyCommand);
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAEjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgZ3C,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsQ5B,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAEjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA,GAAG,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8M1E,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsQ5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const CODEX_PRE_TOOL_POLICY_HEADER: string;
2
+ //# sourceMappingURL=codex-pre-tool-policy-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-pre-tool-policy-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-policy-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,QAsIxC,CAAC"}
@@ -0,0 +1,136 @@
1
+ export const CODEX_PRE_TOOL_POLICY_HEADER = String.raw `import { execFile } from "node:child_process";
2
+ import { writeSync } from "node:fs";
3
+ import { lstat, readFile, realpath } from "node:fs/promises";
4
+ import { dirname, isAbsolute, relative, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { promisify } from "node:util";
7
+ import { captureCliTurn, createHookBudget, checkDestructivePatterns, configuredDeploymentBranches, configuredPermissionProfile, executionPolicyCommand, gitInvocation, inside, isCurrentRepositoryRead, isLiteralReadSequence, readBoundedCanonicalText, requiresShellMutationRun, reviewedContextReadPaths, reviewedReleasePaths, rewriteCliInput, selectHookExecutionWorkspace, selectHookRepositoryRoot, shellSyntax, tokenizeLiteralCommand, validateHashicorpRead, validateInlineExecution } from "./zaip-pre-tool-support.mjs";
8
+ import { createCloudValidators } from "./zaip-pre-tool-cloud.mjs";
9
+ const { execute, parseEvent } = createHookBudget(promisify(execFile));
10
+ const nativeAuthority = await import("./zaip-native-tool-authority.mjs").catch(() => null);
11
+ const activation = await import("./zaip-hook-activation.mjs").catch(() => null);
12
+ const installedRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
13
+ let repositoryRoot = installedRoot;
14
+ let principalFullAccess = false;
15
+ let principalFullNetwork = false;
16
+ const deletionCommandPattern = /\b(?:Remove-Item|ri|rm|rmdir|rd|del|erase)\b/i;
17
+ const allowedExplicitNetworkHosts = new Set([
18
+ "127.0.0.1", "api.github.com", "github.com", "localhost", "objects.githubusercontent.com", "releases.hashicorp.com", "::1",
19
+ ]);
20
+ const networkClientPattern = /\b(?:curl|wget|Invoke-WebRequest|Invoke-RestMethod|iwr|irm)\b/i;
21
+ const cloudRunnerScript = ".agents/tools/cloud-runner.mjs";
22
+ const cloudContractPath = ".agents/config/autonomous-cloud-contract.json";
23
+ const cloudOperationProviders = new Map([
24
+ ["cloudflare:dns:read", "cloudflare"], ["cloudflare:dns:create", "cloudflare"], ["cloudflare:dns:edit", "cloudflare"],
25
+ ["hostinger:vps:read", "hostinger"],
26
+ ["hostinger:ssh:read", "hostinger"],
27
+ ["hostinger:ssh:configure", "hostinger"],
28
+ ["hostinger:ssh:test", "hostinger"],
29
+ ["terraform:plan", "terraform"],
30
+ ["terraform:apply", "terraform"],
31
+ ["terraform:import", "terraform"],
32
+ ]);
33
+ const homeReferencePattern = /(?:\$HOME\b|\$env:(?:USERPROFILE|HOMEDRIVE|HOMEPATH)\b|%(?:USERPROFILE|HOMEDRIVE|HOMEPATH)%|(?:^|[\s"'=])~[\\/])/i;
34
+ const credentialReferencePattern = /(?:^|[\\/\s"'=])(?:\.ssh|\.aws|\.azure|\.kube|\.docker|\.gnupg|\.git-credentials|\.npmrc|\.pypirc|id_(?:rsa|ed25519)|[^\\/\s"']+\.(?:pem|key|p12|pfx))(?:[\\/\s"'=]|$)|(?:^|[\\/\s"'=])\.env(?:\.[A-Za-z0-9_-]+)*(?:[\\/\s"']|$)/i;
35
+ const sensitiveEnvironmentPattern = /(?:\$env:|%|\$)[A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY|CREDENTIAL)[A-Z0-9_]*%?/i;
36
+ const destructivePatterns = [
37
+ {
38
+ pattern: /\b(?:Restart-Computer|Stop-Computer|Restart-Host|shutdown(?:\.exe)?|reboot|poweroff|halt|Suspend-Computer|hibernate|logoff|Win32Shutdown)\b/i,
39
+ reason: "Local computer restart, shutdown, suspension, hibernation and session termination are blocked.",
40
+ },
41
+ {
42
+ pattern: /\b(?:Clear-Content|shred)\b/i,
43
+ reason: "Unbounded content destruction is blocked.",
44
+ },
45
+ {
46
+ pattern: /\bgit\s+(?:clean\b|reset\s+--hard\b|checkout\s+--\b|restore\b|branch\s+-d\b|tag\s+-d\b)/i,
47
+ reason: "Destructive Git state changes are blocked.",
48
+ },
49
+ {
50
+ pattern: /\bgit\s+push\b[\s\S]*(?:--force(?:-with-lease|-if-includes)?\b|-f\b|--mirror\b|--delete\b|--all\b|(?:^|\s):\S+)/i,
51
+ reason: "Force, mirror, bulk, and deletion pushes are blocked.",
52
+ },
53
+ {
54
+ pattern: /\bgit\s+commit\b[\s\S]*(?:--amend\b|--no-verify\b|-n\b)/i,
55
+ reason: "Commit history rewrites and hook bypasses are blocked.",
56
+ },
57
+ {
58
+ pattern: /\bgit\s+(?:-c\b|--config(?:-env)?\b|--git-dir\b|--work-tree\b|--namespace\b)/,
59
+ reason: "Git global configuration and repository-routing overrides are blocked.",
60
+ },
61
+ {
62
+ pattern: /\bgit\s+fetch\b[\s\S]*(?:--all\b|--prune\b|--prune-tags\b)/i,
63
+ reason: "Bulk or pruning fetches are outside the bounded deploy flow.",
64
+ },
65
+ {
66
+ pattern: /\bgit\s+add\b[\s\S]*(?:--force\b|-f\b|(?:^|[\\/\s])(?:\.env(?:\.|\s|$)|[^\s]*\.(?:pem|key|p12|pfx)\b|id_(?:rsa|ed25519)\b))/i,
67
+ reason: "Force-adding or explicitly staging credential-like files is blocked.",
68
+ },
69
+ {
70
+ pattern: /\bgit\s+add\b[\s\S]*(?:\s-A\b|--all\b|(?:^|\s)\.(?:\s|$)|\s-u\b)/i,
71
+ reason: "Broad Git staging is blocked; authorized deploy commits require explicit pathspecs.",
72
+ },
73
+ {
74
+ pattern: /\bgit\s+(?:remote\s+(?:add|set-url|remove|rename)|config\b[\s\S]*(?:sshCommand|credential|url\.))/i,
75
+ reason: "Remote, SSH, and credential configuration changes are blocked.",
76
+ },
77
+ {
78
+ pattern: /\bgh(?:\.exe)?\b[\s\S]*\s(?:--repo|-R)(?:=|\s|(?=[A-Za-z0-9]))/i,
79
+ reason: "GitHub CLI commands must target the current repository.",
80
+ },
81
+ {
82
+ pattern: /\b(?:drop\s+(?:database|schema|table)|truncate\s+table|supabase\s+db\s+reset)\b/i,
83
+ reason: "Destructive database operations are blocked.",
84
+ },
85
+ {
86
+ pattern: /\b(?:rmSync|rmdirSync|unlinkSync|rmtree|remove|unlink|Directory\.Delete|File\.Delete)\s*\(/i,
87
+ reason: "Inline deletion APIs are blocked.",
88
+ },
89
+ {
90
+ pattern: /(?:curl|wget|Invoke-WebRequest|Invoke-RestMethod|\biwr\b|\birm\b)[\s\S]*\|[\s&]*(?:bash|sh|zsh|pwsh|powershell|cmd|node|python|iex|Invoke-Expression)\b/i,
91
+ reason: "Downloaded content cannot be piped into an interpreter.",
92
+ },
93
+ {
94
+ pattern: /(?:-(?:EncodedCommand|enc)\b|FromBase64String\s*\(|certutil\s+-(?:decode|urlcache)\b|mshta\s+https?:|rundll32\s+javascript:)/i,
95
+ reason: "Encoded or evasive command execution is blocked.",
96
+ },
97
+ {
98
+ pattern: /\b(?:Set-MpPreference|Add-MpPreference|Remove-MpPreference|Set-NetFirewallProfile|New-NetFirewallRule|Remove-NetFirewallRule|Disable-NetFirewallRule|Enable-PSRemoting|Set-WSManQuickConfig)\b|\bnetsh\s+advfirewall[\s\S]*(?:\boff\b|\badd\b|\bdelete\b|\bset\b)/i,
99
+ reason: "Firewall, antivirus, and remote-management changes are blocked.",
100
+ },
101
+ {
102
+ pattern: /\b(?:reg(?:\.exe)?\s+(?:add|delete)|schtasks(?:\.exe)?\s+\/(?:create|delete|change)|sc(?:\.exe)?\s+(?:create|delete|stop|config)|New-Service|Set-Service|Stop-Service)\b/i,
103
+ reason: "OS persistence and service changes are blocked.",
104
+ },
105
+ {
106
+ pattern: /\b(?:diskpart|bcdedit|fsutil|takeown|icacls|Set-Acl|chmod|chown)\b|(?:^|[;&|({\r\n])\s*(?:&\s*)?["']?format(?:\.(?:com|exe))?["']?(?=\s|$)|\bcipher\s+\/w\b/i,
107
+ reason: "Disk, boot, ownership, and access-control changes are blocked.",
108
+ },
109
+ {
110
+ pattern: /\b(?:runas|sudo|gsudo)\b|Start-Process[\s\S]*-Verb\s+RunAs|\bSet-ExecutionPolicy\b/i,
111
+ reason: "Privilege escalation and persistent execution-policy changes are blocked.",
112
+ },
113
+ {
114
+ pattern: /\b(?:Start-Process|saps)\b[^\r\n;|]*(?:[$(]|\b(?:-FilePath\s+)?['"]?git(?:\.exe)?['"]?(?:\s|$))/i,
115
+ reason: "Dynamic or indirect Git process launch is blocked; use a reviewed repository script.",
116
+ },
117
+ {
118
+ pattern: /\b(?:winget|choco|scoop)\s+(?:install|uninstall|upgrade)\b|\b(?:npm|pnpm|yarn)\s+(?:install|add|remove|uninstall)[\s\S]*(?:--global|-g)\b/i,
119
+ reason: "System-wide package changes are blocked.",
120
+ },
121
+ {
122
+ pattern: /(?:--host|--hostname|--listen(?:-address)?)\s+(?:0\.0\.0\.0|\*|::)\b/i,
123
+ reason: "Non-loopback listeners are blocked.",
124
+ },
125
+ {
126
+ pattern: /\bgh(?:\.exe)?\s+(?:pr\s+(?:create|merge|close|reopen)|issue\s+(?:create|close|reopen|delete)|release\s+(?:create|delete|upload)|repo\s+(?:create|delete|archive)|api\b[\s\S]*(?:(?:--method|-X)(?:=|\s*)(?:POST|PUT|PATCH|DELETE)\b|(?:--field|--raw-field|--input)(?:=|\s+)|(?:^|\s)-[fF](?:=|\s+)))/i,
127
+ reason: "Unreviewed GitHub mutations are blocked; use the bounded deploy workflow.",
128
+ },
129
+ {
130
+ pattern: /\b(?:npm|pnpm|yarn)\s+(?:publish|login|logout|token|owner|deprecate)\b/i,
131
+ reason: "Package-registry publication and credential changes are blocked.",
132
+ },
133
+ ];
134
+
135
+ `;
136
+ //# sourceMappingURL=codex-pre-tool-policy-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-pre-tool-policy-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-policy-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsIrD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-support-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,QA8UvC,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-support-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,QA4YvC,CAAC"}
@@ -326,6 +326,68 @@ export function validateInlineExecution(command, deny) {
326
326
  }
327
327
  }
328
328
 
329
+ // These CLI values are data, never shell programs. Only one literal invocation of
330
+ // the canonical runtime qualifies; interpolation, pipelines and other scripts do not.
331
+ export function executionPolicyCommand(command, cwd, repositoryRoot) {
332
+ const tokens = tokenizeLiteralCommand(command);
333
+ if (!tokens || !/^(?:.*[\\/])?node(?:\.exe)?$/i.test(tokens[0] ?? "") ||
334
+ resolve(cwd, tokens[1] ?? "") !== resolve(repositoryRoot, ".agents/runtime/bin/zaip.mjs") ||
335
+ tokens[2] !== "conversation" || tokens[3] !== "finish") return command;
336
+ const result = [...tokens];
337
+ for (let index = 4; index < result.length; index++) {
338
+ if (result[index] === "--summary" && index + 1 < result.length) result[++index] = "literal-summary";
339
+ else if (result[index].startsWith("--summary=")) result[index] = "--summary=literal-summary";
340
+ }
341
+ return result.map(token => JSON.stringify(token)).join(" ");
342
+ }
343
+
344
+ export async function isCurrentRepositoryRead(command, repositoryRoot, execute) {
345
+ const tokens = tokenizeLiteralCommand(command);
346
+ if (!tokens || !/^gh(?:\.exe)?$/i.test(tokens[0] ?? "")) return false;
347
+ const rest = [], repositories = [];
348
+ for (let index = 0; index < tokens.length; index++) {
349
+ const token = tokens[index];
350
+ if (token === "--repo" || token === "-R") repositories.push(tokens[++index]);
351
+ else if (token.startsWith("--repo=")) repositories.push(token.slice(7));
352
+ else if (token.startsWith("-R") && token.length > 2) repositories.push(token.slice(2));
353
+ else rest.push(token);
354
+ }
355
+ if (repositories.length !== 1 || !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repositories[0] ?? "") ||
356
+ rest.some(token => token.includes("'")) || !isLiteralReadSequence(rest.map(token => "'" + token + "'").join(" "))) return false;
357
+ try {
358
+ const origin = (await execute("git", ["remote", "get-url", "origin"], { cwd: repositoryRoot, encoding: "utf8", windowsHide: true })).stdout.trim();
359
+ const match = /^(?:git@github\.com:|https:\/\/github\.com\/|ssh:\/\/git@github\.com\/)([^/]+\/[^/]+?)\.git$|^(?:git@github\.com:|https:\/\/github\.com\/|ssh:\/\/git@github\.com\/)([^/]+\/[^/]+?)\/?$/.exec(origin);
360
+ return !!match && (match[1] ?? match[2]).toLowerCase() === repositories[0].toLowerCase();
361
+ } catch { return false; }
362
+ }
363
+
364
+ export function validateHashicorpRead(command, deny) {
365
+ const tokens = tokenizeLiteralCommand(command);
366
+ if (!tokens || !/^(?:curl(?:\.exe)?|Invoke-WebRequest|Invoke-RestMethod|iwr|irm)$/i.test(tokens[0]))
367
+ deny("HashiCorp releases require a literal supported read command.");
368
+ let urlCount = 0;
369
+ for (let i = 1; i < tokens.length; i++) {
370
+ const token = tokens[i];
371
+ if (/^https:\/\//i.test(token)) {
372
+ const url = new URL(token);
373
+ if (url.hostname !== "releases.hashicorp.com" || url.username || url.password || url.port)
374
+ deny("HashiCorp reads require one exact HTTPS destination.");
375
+ urlCount++; continue;
376
+ }
377
+ if (["-I", "--head", "-s", "-S", "-sS", "--silent", "--show-error", "--fail", "-q", "--disable"].includes(token)) continue;
378
+ const namedMethod = /^(?:--request|--method|-Method)(?:=(.*))?$/i.exec(token);
379
+ const curlMethod = /^-X(.*)$/.exec(token);
380
+ if (namedMethod || curlMethod) {
381
+ const value = namedMethod ? (namedMethod[1] ?? tokens[++i]) : (curlMethod[1] || tokens[++i]);
382
+ if (!/^(?:GET|HEAD)$/i.test(value ?? "")) deny("HashiCorp releases permit only GET or HEAD requests.");
383
+ continue;
384
+ }
385
+ if (/^(?:-Uri|--url)$/i.test(token) && /^https:\/\//i.test(tokens[i + 1] ?? "")) continue;
386
+ deny("Unsupported option in the bounded HashiCorp read command.");
387
+ }
388
+ if (urlCount !== 1) deny("HashiCorp reads require exactly one HTTPS URL.");
389
+ }
390
+
329
391
  export function rewriteCliInput(toolInput, command, commandFromCmd) {
330
392
  return { hookSpecificOutput: {
331
393
  hookEventName: "PreToolUse", permissionDecision: "allow",
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-support-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8UpD,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-support-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4YpD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/cli",
3
- "version": "5.4.0",
3
+ "version": "5.6.0",
4
4
  "description": "CLI oficial para instalar e configurar o ZAIP-AIOS em qualquer repositório",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -6,6 +6,14 @@ English | [Português](README.md)
6
6
 
7
7
  ## Quick overview
8
8
 
9
+ The [v5.6 guide](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v56-publicacao-reproduzivel.md) describes the reproducible release runtime, immutable candidate review, and early impact-based validation. Reused coverage requires proof for the same candidate; functional changes and missing evidence retain the applicable gates.
10
+
11
+ The [v5.5 guide](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v55-eficiencia-operacional.md) describes evidence
12
+ obligations exposed at intake, direct replay of completed lifecycle closure,
13
+ bounded journal segments, and impact-based test selection. Timing diagnostics
14
+ do not invalidate the cache; actual changes still do. Native hook evidence
15
+ limitations are reported separately.
16
+
9
17
  The [v5.4 guide](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v54-fechamento-cache-hooks.md) describes restricted
10
18
  administrative closure after publication, the distinction between text and commands
11
19
  in hooks, GitHub queries targeting the current repository, and objective acceptance
@@ -626,10 +634,10 @@ already-terminal Gui while the responsible Run is open. No decision means no
626
634
  approval. A trusted fallback must persist `blocked` with a reason when the
627
635
  finalizer cannot run; the current CLI does not yet prove that path for every
628
636
  native Stop or interruption. Direct standalone work with explicit direct
629
- authorization is a legacy route, not the v4 default. See
637
+ authorization is a legacy compatibility route, not the default for new installations. See
630
638
  [closure and recovery](zaip-aios/guides/16-lifecycle-e-reconciliacao.md).
631
639
 
632
- Proof depth is adaptive: a standalone `lite` Task requires at least one typed validation and one Evidence, normally one of each, but accepts legitimate additional proof. `standard` requires two or three validations according to `verification_scope` and at least one consolidated Evidence; `critical` requires three or more, independent review, and persisted risk signals determining additional controls. SPEC and PRD deliveries add a parent matrix, at least three validations and three Evidences, real integration, and independent review. Current templates use managed PRDs/SPECs and direct standalone Tasks; after implementation and installer qualification, v4 targets Codex-native as the operational default. Worktrees, write scopes, budgets, commits, and typed gates still apply where relevant. See [Adaptive assurance and opt-in autonomy](zaip-aios/guides/19-assurance-e-autonomia.md).
640
+ Proof depth is adaptive: a standalone `lite` Task requires at least one typed validation and one Evidence, normally one of each, but accepts legitimate additional proof. `standard` requires two or three validations according to `verification_scope` and at least one consolidated Evidence; `critical` requires three or more, independent review, and persisted risk signals determining additional controls. SPEC and PRD deliveries add a parent matrix, at least three validations and three Evidences, real integration, and independent review. New installations use Codex-native by default. Existing installations retain their effective configuration and must be checked against the installed version; publication does not prove client hook activation. Worktrees, write scopes, budgets, commits, and typed gates still apply where relevant. See [Adaptive assurance and opt-in autonomy](zaip-aios/guides/19-assurance-e-autonomia.md).
633
641
 
634
642
  ## Autonomous engineering principles
635
643