@aiwg/cli 2026.10.5 → 2026.10.7

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 (263) hide show
  1. package/agentic/code/addons/composition-engine/lib/runtime.mjs +1401 -0
  2. package/agentic/code/addons/composition-engine/lib/validator.mjs +513 -0
  3. package/agentic/code/addons/composition-engine/schemas/flow-graph.schema.json +372 -0
  4. package/agentic/code/providers/model-capabilities.v1.json +74 -50
  5. package/bin/aiwg.mjs +7 -3
  6. package/dist/src/a2a/agent-card.js +11 -0
  7. package/dist/src/api/index.d.ts +1 -0
  8. package/dist/src/api/index.js +1 -0
  9. package/dist/src/artifacts/browser-export.js +1 -0
  10. package/dist/src/artifacts/citation-parser.js +8 -1
  11. package/dist/src/artifacts/cli.js +57 -6
  12. package/dist/src/artifacts/fortemi-core-query-adapter.js +2 -0
  13. package/dist/src/artifacts/fortemi-core-sync.js +26 -8
  14. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/contract.json +103 -0
  15. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-embedding-config.schema.json +212 -0
  16. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-embedding-set.schema.json +240 -0
  17. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-manifest.schema.json +451 -0
  18. package/dist/src/artifacts/fortemi-shard-export.js +284 -0
  19. package/dist/src/artifacts/graph-query.js +18 -8
  20. package/dist/src/artifacts/index-adapters.js +339 -0
  21. package/dist/src/artifacts/index-builder.js +143 -14
  22. package/dist/src/artifacts/index-files.js +15 -4
  23. package/dist/src/artifacts/index-preparation.js +2 -0
  24. package/dist/src/artifacts/index-reader.js +44 -0
  25. package/dist/src/artifacts/index-refresh.js +114 -55
  26. package/dist/src/artifacts/index-status.js +20 -5
  27. package/dist/src/artifacts/memory-maintenance.js +503 -0
  28. package/dist/src/artifacts/prebuilt-relations.js +3 -1
  29. package/dist/src/artifacts/query-engine.js +263 -108
  30. package/dist/src/artifacts/relations-builder.js +2 -2
  31. package/dist/src/artifacts/source-graph.js +2 -2
  32. package/dist/src/artifacts/types.js +9 -1
  33. package/dist/src/auth/client.js +5 -1
  34. package/dist/src/auth/credential-store.js +5 -1
  35. package/dist/src/auth/sensitive-input.js +151 -0
  36. package/dist/src/channel/manager.mjs +3 -0
  37. package/dist/src/cli/handlers/agentcard.js +47 -25
  38. package/dist/src/cli/handlers/auth.js +22 -2
  39. package/dist/src/cli/handlers/decision.js +22 -3
  40. package/dist/src/cli/handlers/effect.js +4 -84
  41. package/dist/src/cli/handlers/guided-setup.js +470 -0
  42. package/dist/src/cli/handlers/help.js +2 -2
  43. package/dist/src/cli/handlers/housekeeper.js +1110 -0
  44. package/dist/src/cli/handlers/index.js +4 -2
  45. package/dist/src/cli/handlers/init.js +41 -6
  46. package/dist/src/cli/handlers/install.js +6 -0
  47. package/dist/src/cli/handlers/local-executor.js +5 -3
  48. package/dist/src/cli/handlers/marketplace.js +15 -4
  49. package/dist/src/cli/handlers/mc.js +509 -53
  50. package/dist/src/cli/handlers/models.js +32 -2
  51. package/dist/src/cli/handlers/ralph-launcher.js +76 -4
  52. package/dist/src/cli/handlers/rules.js +1 -1
  53. package/dist/src/cli/handlers/script-runner.js +73 -2
  54. package/dist/src/cli/handlers/serve.js +5 -3
  55. package/dist/src/cli/handlers/sessions.js +1 -0
  56. package/dist/src/cli/handlers/setup.js +432 -1
  57. package/dist/src/cli/handlers/skill-lint.js +1 -1
  58. package/dist/src/cli/handlers/subcommands.js +118 -8
  59. package/dist/src/cli/handlers/use.js +335 -107
  60. package/dist/src/cli/handlers/workspace.js +3 -1
  61. package/dist/src/cli/prompt-utils.js +81 -0
  62. package/dist/src/cli/router.js +16 -1
  63. package/dist/src/config/aiwg-config.js +42 -0
  64. package/dist/src/config/cli.js +7 -3
  65. package/dist/src/config/decision-config.js +14 -1
  66. package/dist/src/config/gitignore.js +4 -0
  67. package/dist/src/config/native-sandbox-warnings.js +25 -0
  68. package/dist/src/config/workspace.js +2 -1
  69. package/dist/src/contributors/validation.js +6 -5
  70. package/dist/src/decision/adapters/jev.js +20 -31
  71. package/dist/src/decision/admission.js +7 -3
  72. package/dist/src/decision/ask.js +6 -1
  73. package/dist/src/decision/benchmark.js +482 -0
  74. package/dist/src/decision/ledger.js +22 -3
  75. package/dist/src/decision/pricing.js +147 -0
  76. package/dist/src/decision/qualification/gate-evidence.js +23 -18
  77. package/dist/src/decision/qualification/load-staged.js +576 -0
  78. package/dist/src/decision/qualification/load.js +109 -33
  79. package/dist/src/decision/qualification/runner.js +12 -5
  80. package/dist/src/decision/review/service.js +6 -4
  81. package/dist/src/decision/review/validate.js +23 -2
  82. package/dist/src/decision/savings.js +8 -3
  83. package/dist/src/discovery/index.js +492 -0
  84. package/dist/src/discovery/interview.js +238 -0
  85. package/dist/src/discovery/plan-apply.js +567 -0
  86. package/dist/src/discovery/plan-store.js +171 -0
  87. package/dist/src/discovery/plan-types.js +2 -0
  88. package/dist/src/discovery/plan-validation.js +139 -0
  89. package/dist/src/discovery/types.js +2 -0
  90. package/dist/src/effects/host.js +91 -0
  91. package/dist/src/extensions/commands/definitions.js +49 -9
  92. package/dist/src/extensions/manifest.js +71 -44
  93. package/dist/src/extensions/project-local-discovery.js +1 -1
  94. package/dist/src/extensions/project-local-gitignore.js +2 -0
  95. package/dist/src/extensions/project-quickref.js +18 -17
  96. package/dist/src/extensions/validation.js +32 -29
  97. package/dist/src/housekeeper/daemon-config.js +148 -0
  98. package/dist/src/housekeeper/ipc.js +84 -0
  99. package/dist/src/housekeeper/lifecycle.js +148 -0
  100. package/dist/src/housekeeper/platform.js +35 -0
  101. package/dist/src/housekeeper/status.js +70 -0
  102. package/dist/src/housekeeper/units.js +114 -0
  103. package/dist/src/issues/cli.js +16 -5
  104. package/dist/src/issues/live.js +44 -12
  105. package/dist/src/jobs/flow.js +22 -21
  106. package/dist/src/lint/rule-activation.js +20 -5
  107. package/dist/src/lint/runner.js +1 -1
  108. package/dist/src/marketplace/exchange.js +18 -6
  109. package/dist/src/marketplace/provenance.js +3 -2
  110. package/dist/src/mcp/adapters/codex-runtime.js +46 -76
  111. package/dist/src/mcp/cli.mjs +22 -96
  112. package/dist/src/mcp/config-file.mjs +6 -2
  113. package/dist/src/mcp/config-layers.mjs +23 -7
  114. package/dist/src/mcp/grok-build-config.mjs +2 -1
  115. package/dist/src/mcp/muse-native-config.mjs +2 -1
  116. package/dist/src/mcp/profiles.js +18 -31
  117. package/dist/src/mcp/profiles.mjs +18 -32
  118. package/dist/src/mcp/registry.js +7 -27
  119. package/dist/src/mcp/registry.mjs +7 -28
  120. package/dist/src/mcp/server.mjs +34 -1
  121. package/dist/src/mcp/tools/agentic-sandbox.mjs +8 -7
  122. package/dist/src/mcp/tools/command-run.mjs +3 -2
  123. package/dist/src/mcp/tools/decision.mjs +49 -48
  124. package/dist/src/mcp/tools/discovery.mjs +46 -21
  125. package/dist/src/mcp/tools/orchestration.mjs +22 -22
  126. package/dist/src/mcp/tools/subsystems.mjs +9 -8
  127. package/dist/src/mcp/tools/worker-invoke.mjs +30 -6
  128. package/dist/src/mcp/tools/writer-profiles.mjs +1 -1
  129. package/dist/src/memory/audit.js +719 -0
  130. package/dist/src/memory/canonical-context.js +392 -13
  131. package/dist/src/memory/canonical-maintenance.js +95 -0
  132. package/dist/src/memory/cli-result.js +22 -0
  133. package/dist/src/memory/cli.js +176 -0
  134. package/dist/src/memory/context-pack.js +57 -6
  135. package/dist/src/memory/cost.js +512 -0
  136. package/dist/src/memory/firewall-classification.d.mts +7 -0
  137. package/dist/src/memory/firewall-classification.mjs +32 -0
  138. package/dist/src/memory/index.js +8 -0
  139. package/dist/src/memory/line-maintenance.js +68 -0
  140. package/dist/src/memory/maintenance-cli.js +286 -0
  141. package/dist/src/memory/maintenance-contract.js +136 -0
  142. package/dist/src/memory/maintenance-index.js +18 -0
  143. package/dist/src/memory/maintenance-owner.js +2 -0
  144. package/dist/src/memory/maintenance-record.js +138 -0
  145. package/dist/src/memory/maintenance.js +254 -0
  146. package/dist/src/memory/project-registry.js +2 -1
  147. package/dist/src/memory/provider-memory-adapter.js +154 -0
  148. package/dist/src/memory/recommend-cli.js +83 -0
  149. package/dist/src/memory/recommend.js +269 -0
  150. package/dist/src/memory/scheduled.js +81 -0
  151. package/dist/src/memory/taxonomy.js +44 -0
  152. package/dist/src/mission-protocol/codecs.js +19 -9
  153. package/dist/src/mission-protocol/worker-status.js +91 -1
  154. package/dist/src/models/config-loader.js +11 -1
  155. package/dist/src/models/model-capabilities.v1.json +74 -50
  156. package/dist/src/models/provider-policy.js +125 -62
  157. package/dist/src/models/resolver.js +45 -8
  158. package/dist/src/models/worker-installation.d.mts +8 -1
  159. package/dist/src/models/worker-installation.mjs +231 -38
  160. package/dist/src/models/wrapper-route.js +1 -1
  161. package/dist/src/output-modes/registry.js +8 -7
  162. package/dist/src/packages/adapters/git.js +99 -23
  163. package/dist/src/packages/adapters/gitea.js +8 -27
  164. package/dist/src/packages/adapters/github.js +7 -25
  165. package/dist/src/packages/registry.js +4 -4
  166. package/dist/src/plugin/metadata-validator.js +1 -1
  167. package/dist/src/process/cli-command.d.mts +5 -0
  168. package/dist/src/process/cli-command.mjs +42 -0
  169. package/dist/src/providers/deploy-version.d.mts +1 -0
  170. package/dist/src/providers/deploy-version.mjs +17 -0
  171. package/dist/src/providers/provider-definitions.js +19 -16
  172. package/dist/src/providers/skill-ownership.d.mts +11 -2
  173. package/dist/src/providers/skill-ownership.mjs +35 -17
  174. package/dist/src/rules/activation.d.mts +11 -2
  175. package/dist/src/rules/activation.mjs +82 -6
  176. package/dist/src/rules/inventory.js +1 -1
  177. package/dist/src/rules/rule-frontmatter.schema.json +2 -0
  178. package/dist/src/schema/zod-validation.d.mts +6 -0
  179. package/dist/src/schema/zod-validation.mjs +50 -0
  180. package/dist/src/serve/executor-registry.js +297 -20
  181. package/dist/src/serve/executor-token.d.mts +1 -0
  182. package/dist/src/serve/executor-token.mjs +8 -0
  183. package/dist/src/serve/shared-host-scheduler.js +1102 -31
  184. package/dist/src/serve/worker-invocation.js +124 -15
  185. package/dist/src/sessions/adapters/claude.js +19 -18
  186. package/dist/src/sessions/adapters/codex.js +10 -9
  187. package/dist/src/sessions/adapters/copilot.js +14 -13
  188. package/dist/src/sessions/adapters/cursor.js +19 -18
  189. package/dist/src/sessions/adapters/deepseek-harness.js +9 -8
  190. package/dist/src/sessions/adapters/factory.js +11 -10
  191. package/dist/src/sessions/adapters/generic.js +32 -23
  192. package/dist/src/sessions/adapters/grokbot.js +35 -35
  193. package/dist/src/sessions/adapters/hermes.js +20 -19
  194. package/dist/src/sessions/adapters/muse.js +50 -49
  195. package/dist/src/sessions/adapters/omp.js +5 -4
  196. package/dist/src/sessions/adapters/openclaw.js +30 -29
  197. package/dist/src/sessions/adapters/opencode.js +26 -26
  198. package/dist/src/sessions/adapters/openhuman.js +24 -23
  199. package/dist/src/sessions/adapters/pi.js +5 -4
  200. package/dist/src/sessions/adapters/windsurf.js +8 -8
  201. package/dist/src/sessions/analytics.js +10 -9
  202. package/dist/src/sessions/candidates.js +7 -6
  203. package/dist/src/sessions/contracts.js +63 -53
  204. package/dist/src/sessions/output-registration.js +11 -10
  205. package/dist/src/sessions/workspace-discovery.js +3 -4
  206. package/dist/src/smiths/context-pipeline/aiwg-md.js +18 -1
  207. package/dist/src/smiths/context-pipeline/claude-hook.js +46 -10
  208. package/dist/src/smiths/context-pipeline/context-file-safety.js +330 -9
  209. package/dist/src/smiths/context-pipeline/finalization.js +3 -2
  210. package/dist/src/smiths/context-pipeline/generator.js +7 -19
  211. package/dist/src/smiths/context-pipeline/legacy-inject.js +3 -10
  212. package/dist/src/smiths/context-pipeline/managed-hook.js +5 -5
  213. package/dist/src/smiths/context-pipeline/parallelism-section.js +72 -5
  214. package/dist/src/smiths/context-pipeline/workspace-context.js +110 -22
  215. package/dist/src/tracker/project-inputs.js +2 -0
  216. package/dist/src/update/checker.d.mts +4 -0
  217. package/dist/src/update/checker.mjs +14 -0
  218. package/dist/src/update/notifier.mjs +2 -4
  219. package/dist/src/writing/exemplar-selection.js +6 -6
  220. package/dist/src/writing/voice-evaluation.js +24 -23
  221. package/dist/src/writing/writer-migration.js +14 -13
  222. package/dist/src/writing/writer-profile.js +19 -18
  223. package/dist/src/writing/writing-brief.js +18 -17
  224. package/dist/src/writing/writing-receipt.js +47 -46
  225. package/package.json +5 -2
  226. package/schemas/decision/DecisionReview.schema.json +78 -1
  227. package/schemas/mission-v1.schema.json +3 -0
  228. package/tools/agents/deploy-agents.mjs +67 -39
  229. package/tools/agents/providers/antigravity.mjs +6 -1
  230. package/tools/agents/providers/base.mjs +24 -14
  231. package/tools/agents/providers/claude.mjs +6 -3
  232. package/tools/agents/providers/codex.mjs +54 -57
  233. package/tools/agents/providers/context-write.mjs +28 -0
  234. package/tools/agents/providers/copilot.mjs +13 -4
  235. package/tools/agents/providers/cursor.mjs +1 -1
  236. package/tools/agents/providers/deepseek-harness.mjs +1 -1
  237. package/tools/agents/providers/factory.mjs +7 -1
  238. package/tools/agents/providers/grok-build.mjs +18 -2
  239. package/tools/agents/providers/grokbot.mjs +1 -1
  240. package/tools/agents/providers/hermes.mjs +12 -15
  241. package/tools/agents/providers/muse-hooks.mjs +21 -14
  242. package/tools/agents/providers/muse.mjs +7 -2
  243. package/tools/agents/providers/omp.mjs +31 -5
  244. package/tools/agents/providers/opencode.mjs +14 -5
  245. package/tools/agents/providers/openhuman.mjs +1 -1
  246. package/tools/agents/providers/pi.mjs +1 -1
  247. package/tools/agents/providers/provider-prepare-coordinator.mjs +29 -9
  248. package/tools/agents/providers/rule-delivery.mjs +289 -80
  249. package/tools/agents/providers/warp.mjs +4 -1
  250. package/tools/agents/providers/windsurf.mjs +13 -3
  251. package/tools/cli/workspace-status.mjs +5 -0
  252. package/tools/commands/deploy-prompts-codex.mjs +11 -8
  253. package/tools/ralph-external/lib/codex-adapter.mjs +6 -2
  254. package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +26 -0
  255. package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +7 -1
  256. package/tools/ralph-external/lib/muse-adapter.mjs +12 -2
  257. package/tools/ralph-external/lib/recovery-probe.mjs +14 -4
  258. package/tools/ralph-external/lib/worker-health.mjs +1 -1
  259. package/tools/ralph-external/lib/worker-isolation.mjs +65 -9
  260. package/tools/ralph-external/process-monitor.mjs +49 -8
  261. package/tools/ralph-external/session-launcher.mjs +405 -35
  262. package/tools/skills/deploy-skills-codex.mjs +11 -7
  263. package/vscode-extension/schemas/aiwg.config.v1.json +11 -1
@@ -1,5 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { z } from 'zod';
3
+ import { integer, dateTime } from '../schema/zod-validation.mjs';
3
4
  const id = z.string().min(1).max(120);
4
5
  const nonempty = z.string().min(1);
5
6
  const sha = z.string().regex(/^[a-f0-9]{64}$/);
@@ -10,18 +11,18 @@ export const EVALUATION_CONDITIONS = Array.from({ length: 8 }, (_, n) => ({
10
11
  rules: Boolean(n & 4), voiceDescription: Boolean(n & 2), exemplars: Boolean(n & 1),
11
12
  }));
12
13
  export const EVALUATION_DIMENSIONS = ['factual-fidelity', 'author-authenticity', 'reader-suitability', 'effort', 'within-author-preservation', 'between-author-diversity'];
13
- const model = z.object({ id, family: nonempty, provider: nonempty, snapshot: nonempty, decoding: z.record(z.string(), z.union([z.string(), z.number().finite(), z.boolean(), z.null()])), promptSha256: sha }).strict();
14
- const document = z.object({ id, authorId: id, topic: nonempty, split: z.enum(['development', 'enrollment', 'heldout']), text: nonempty, sha256: sha }).strict();
15
- export const evaluationManifestSchema = z.object({
14
+ const model = z.strictObject({ id, family: nonempty, provider: nonempty, snapshot: nonempty, decoding: z.record(z.string(), z.union([z.string(), z.number().finite(), z.boolean(), z.null()])), promptSha256: sha });
15
+ const document = z.strictObject({ id, authorId: id, topic: nonempty, split: z.enum(['development', 'enrollment', 'heldout']), text: nonempty, sha256: sha });
16
+ export const evaluationManifestSchema = z.strictObject({
16
17
  schemaVersion: z.literal(1), id,
17
18
  developmentAuthorIds: z.array(id), finalAuthorIds: z.array(id), documents: z.array(document),
18
- duplicatePolicy: z.object({ metric: z.literal('normalized-word-trigram-jaccard-v1'), threshold: z.number().gt(0).lte(1), justification: nonempty }).strict(),
19
- controls: z.array(z.object({ kind: z.enum(['same-author-different-topic', 'different-author-same-topic']), leftDocumentId: id, rightDocumentId: id }).strict()),
19
+ duplicatePolicy: z.strictObject({ metric: z.literal('normalized-word-trigram-jaccard-v1'), threshold: z.number().gt(0).lte(1), justification: nonempty }),
20
+ controls: z.array(z.strictObject({ kind: z.enum(['same-author-different-topic', 'different-author-same-topic']), leftDocumentId: id, rightDocumentId: id })),
20
21
  models: z.array(model), extractionModelIds: z.array(id),
21
- judges: z.array(z.object({ id, modelId: id, role: z.literal('reader').default('reader'), independentCalibrationSha256: sha, selfPreferenceAuditSha256: sha }).strict()),
22
- humanJudges: z.array(z.object({ id, role: z.enum(['author', 'reader']), authorId: id.optional() }).strict()).default([]),
23
- voluntaryStrata: z.array(z.object({ authorId: id, suppliedByAuthor: z.literal(true), language: nonempty.optional(), proficiency: nonempty.optional() }).strict()),
24
- }).strict();
22
+ judges: z.array(z.strictObject({ id, modelId: id, role: z.literal('reader').default('reader'), independentCalibrationSha256: sha, selfPreferenceAuditSha256: sha })),
23
+ humanJudges: z.array(z.strictObject({ id, role: z.enum(['author', 'reader']), authorId: id.optional() })).prefault([]),
24
+ voluntaryStrata: z.array(z.strictObject({ authorId: id, suppliedByAuthor: z.literal(true), language: nonempty.optional(), proficiency: nonempty.optional() })),
25
+ });
25
26
  const unique = (items) => new Set(items).size === items.length;
26
27
  const words = (text) => text.normalize('NFKC').toLowerCase().match(/[\p{L}\p{M}\p{N}]+/gu) ?? [];
27
28
  function shingles(text) {
@@ -80,15 +81,15 @@ export function parseEvaluationManifest(value) {
80
81
  throw new Error('Unknown voluntary stratum author');
81
82
  return m;
82
83
  }
83
- const preregistrationSchema = z.object({
84
+ const preregistrationSchema = z.strictObject({
84
85
  schemaVersion: z.literal(1), id, manifestSha256: sha,
85
- pilot: z.object({ artifactSha256: sha, completedAt: z.string().datetime(), authorIds: z.array(id).min(1), findings: nonempty }).strict(),
86
- registeredAt: z.string().datetime(), finalDataNotAccessed: z.literal(true),
87
- plannedAuthors: z.number().int().min(2), sampleSizeJustification: nonempty,
88
- thresholds: z.array(z.object({ dimension: z.enum(EVALUATION_DIMENSIONS), value: z.number().finite(), direction: z.enum(['at-least', 'at-most']), justification: nonempty }).strict()).min(1),
86
+ pilot: z.strictObject({ artifactSha256: sha, completedAt: dateTime(), authorIds: z.array(id).min(1), findings: nonempty }),
87
+ registeredAt: dateTime(), finalDataNotAccessed: z.literal(true),
88
+ plannedAuthors: integer().min(2), sampleSizeJustification: nonempty,
89
+ thresholds: z.array(z.strictObject({ dimension: z.enum(EVALUATION_DIMENSIONS), value: z.number().finite(), direction: z.enum(['at-least', 'at-most']), justification: nonempty })).min(1),
89
90
  primaryOutcomes: z.array(z.enum(EVALUATION_DIMENSIONS)).min(1), analysisPlan: nonempty,
90
- selectorPoliciesSha256: sha, budget: z.object({ limit: z.number().int().positive(), tokenizerId: nonempty, tokenizerVersion: nonempty }).strict(),
91
- }).strict();
91
+ selectorPoliciesSha256: sha, budget: z.strictObject({ limit: integer().positive(), tokenizerId: nonempty, tokenizerVersion: nonempty }),
92
+ });
92
93
  /** Records caller declarations; hashes/timestamps do not attest that a pilot occurred or final data stayed unseen. */
93
94
  export function preregisterEvaluation(manifest, value) {
94
95
  const m = parseEvaluationManifest(manifest);
@@ -103,13 +104,13 @@ export function preregisterEvaluation(manifest, value) {
103
104
  throw new Error('Duplicate preregistered outcomes');
104
105
  return p;
105
106
  }
106
- const stimulusSchema = z.object({ id, taskId: id, authorId: id, heldoutDocumentId: id, text: nonempty, sha256: sha, budgetUsed: z.number().int().nonnegative(), tokenizerId: nonempty, tokenizerVersion: nonempty, conditionId: z.enum(['r0v0e0', 'r0v0e1', 'r0v1e0', 'r0v1e1', 'r1v0e0', 'r1v0e1', 'r1v1e0', 'r1v1e1']), workflow: z.enum(EVALUATION_WORKFLOWS), modelId: id.nullable(), genre: nonempty, lengthBand: nonempty, editingStrength: nonempty }).strict();
107
+ const stimulusSchema = z.strictObject({ id, taskId: id, authorId: id, heldoutDocumentId: id, text: nonempty, sha256: sha, budgetUsed: integer().nonnegative(), tokenizerId: nonempty, tokenizerVersion: nonempty, conditionId: z.enum(['r0v0e0', 'r0v0e1', 'r0v1e0', 'r0v1e1', 'r1v0e0', 'r1v0e1', 'r1v1e0', 'r1v1e1']), workflow: z.enum(EVALUATION_WORKFLOWS), modelId: id.nullable(), genre: nonempty, lengthBand: nonempty, editingStrength: nonempty });
107
108
  /** Latin-square rotations plus reversed blocks. Balance is exact only for complete 2N-judge blocks per role. */
108
109
  export function createBlindEvaluationPackets(stimuliInput, judges, seed) {
109
110
  const stimuli = z.array(stimulusSchema).min(2).parse(stimuliInput);
110
111
  if (stimuli.some(s => evaluationHash(s.text) !== s.sha256))
111
112
  throw new Error('Stimulus integrity mismatch');
112
- z.array(z.object({ id, role: z.enum(['author', 'reader']) }).strict()).min(1).parse(judges);
113
+ z.array(z.strictObject({ id, role: z.enum(['author', 'reader']) })).min(1).parse(judges);
113
114
  if (!seed || !unique(stimuli.map(s => s.id)) || !unique(judges.map(j => j.id)))
114
115
  throw new Error('Seed and unique stimulus/judge IDs required');
115
116
  if (new Set(stimuli.map(s => `${s.authorId}\0${s.taskId}\0${s.heldoutDocumentId}`)).size !== 1)
@@ -150,7 +151,7 @@ function validateManifestStimuli(m, input) {
150
151
  return stimuli;
151
152
  }
152
153
  function ingestRatings(ratings, context) {
153
- const parsed = z.array(z.object({ stimulusId: id, authorId: id, judgeId: id, role: z.enum(['author', 'reader']), dimension: z.enum(EVALUATION_DIMENSIONS), value: z.number().finite().nullable(), missingReason: nonempty.optional(), tie: z.boolean() }).strict()).parse(ratings);
154
+ const parsed = z.array(z.strictObject({ stimulusId: id, authorId: id, judgeId: id, role: z.enum(['author', 'reader']), dimension: z.enum(EVALUATION_DIMENSIONS), value: z.number().finite().nullable(), missingReason: nonempty.optional(), tie: z.boolean() })).parse(ratings);
154
155
  if (!unique(parsed.map(r => JSON.stringify([r.stimulusId, r.judgeId, r.role, r.dimension]))))
155
156
  throw new Error('Duplicate rating observations');
156
157
  if (parsed.some(r => r.value === null && (!r.missingReason || r.tie) || r.value !== null && r.missingReason !== undefined))
@@ -172,7 +173,7 @@ function ingestRatings(ratings, context) {
172
173
  if (validate(r).authorId !== r.authorId)
173
174
  throw new Error('Rating/stimulus author mismatch');
174
175
  if (context.assignments !== undefined) {
175
- const assignments = z.array(z.object({ stimulusId: id, judgeId: id, role: z.enum(['author', 'reader']), dimension: z.enum(EVALUATION_DIMENSIONS) }).strict()).parse(context.assignments);
176
+ const assignments = z.array(z.strictObject({ stimulusId: id, judgeId: id, role: z.enum(['author', 'reader']), dimension: z.enum(EVALUATION_DIMENSIONS) })).parse(context.assignments);
176
177
  if (!unique(assignments.map(key)))
177
178
  throw new Error('Duplicate rating assignments');
178
179
  for (const assignment of assignments)
@@ -205,7 +206,7 @@ function random(seed) {
205
206
  }
206
207
  /** Equal-weight author means, then author-cluster percentile bootstrap; no independent-text pseudo-replication. */
207
208
  export function bootstrapAuthorMeans(rows, options) {
208
- z.array(z.object({ authorId: id, value: z.number().finite().nullable() }).strict()).parse(rows);
209
+ z.array(z.strictObject({ authorId: id, value: z.number().finite().nullable() })).parse(rows);
209
210
  if (!options.seed || !Number.isSafeInteger(options.iterations) || options.iterations < 2 || !Number.isFinite(options.confidence) || options.confidence <= 0 || options.confidence >= 1)
210
211
  throw new Error('Invalid bootstrap options');
211
212
  const authors = [...new Set(rows.map(r => r.authorId))].sort();
@@ -227,9 +228,9 @@ export function bootstrapAuthorMeans(rows, options) {
227
228
  }
228
229
  /** Outcomes must already share a preregistered decision rule; never compare arbitrary raw scales. */
229
230
  export function reportMetricDisagreement(rows, calibration) {
230
- z.object({ humanReferenceSha256: sha, independentOfFinalData: z.literal(true), decisionRule: nonempty }).strict().parse(calibration);
231
+ z.strictObject({ humanReferenceSha256: sha, independentOfFinalData: z.literal(true), decisionRule: nonempty }).parse(calibration);
231
232
  const outcome = z.enum(['pass', 'fail', 'tie']).nullable();
232
- z.array(z.object({ itemId: id, human: outcome, metric: outcome }).strict()).parse(rows);
233
+ z.array(z.strictObject({ itemId: id, human: outcome, metric: outcome })).parse(rows);
233
234
  if (!unique(rows.map(r => r.itemId)))
234
235
  throw new Error('Duplicate metric comparison IDs');
235
236
  const paired = rows.filter(r => r.human !== null && r.metric !== null);
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from 'node:crypto';
2
2
  import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
3
  import { isAbsolute, resolve, join } from 'node:path';
4
4
  import { z } from 'zod';
5
+ import { integer, dateTime } from '../schema/zod-validation.mjs';
5
6
  import { importLegacyWriterProfile } from './writer-profile-legacy.js';
6
7
  import { parseWriterProfile } from './writer-profile.js';
7
8
  import { WriterProfileStore } from './writer-profile-store.js';
@@ -19,38 +20,38 @@ function canonicalize(value) {
19
20
  }
20
21
  return value;
21
22
  }
22
- const requestSchema = z.object({
23
+ const requestSchema = z.strictObject({
23
24
  cwd: z.string().min(1),
24
25
  sourcePath: z.string().min(1),
25
26
  format: z.enum(['yaml', 'json']),
26
27
  scope: z.enum(['project', 'user']).default('project'),
27
28
  userConfigDir: z.string().min(1).optional(),
28
- profile: z.object({
29
+ profile: z.strictObject({
29
30
  id: profileId,
30
31
  name: z.string().min(1).max(200),
31
32
  version: z.string().regex(/^\d+\.\d+\.\d+$/).default('1.0.0'),
32
- provenance: z.object({ source: z.string().min(1).max(2000), license: z.string().min(1).max(200) }).strict(),
33
- }).strict(),
34
- }).strict();
35
- const planSchema = z.object({
33
+ provenance: z.strictObject({ source: z.string().min(1).max(2000), license: z.string().min(1).max(200) }),
34
+ }),
35
+ });
36
+ const planSchema = z.strictObject({
36
37
  schemaVersion: z.literal('aiwg.writer-migration-plan.v1'),
37
38
  id: z.string().regex(/^wm-[a-f0-9]{24}$/),
38
39
  planSha256: digest,
39
- createdAt: z.string().datetime(),
40
+ createdAt: dateTime(),
40
41
  dryRun: z.literal(true),
41
42
  cwd: z.string().min(1),
42
- source: z.object({ path: z.string().min(1), format: z.enum(['yaml', 'json']), sha256: digest, bytes: z.number().int().nonnegative(), legacyKind: z.string().min(1).max(80) }).strict(),
43
- target: z.object({
43
+ source: z.strictObject({ path: z.string().min(1), format: z.enum(['yaml', 'json']), sha256: digest, bytes: integer().nonnegative(), legacyKind: z.string().min(1).max(80) }),
44
+ target: z.strictObject({
44
45
  scope: z.enum(['project', 'user']),
45
46
  profileId,
46
47
  userConfigDir: z.string().min(1).optional(),
47
- existingProfile: z.object({ revision: z.number().int().positive(), sha256: digest }).strict().nullable(),
48
+ existingProfile: z.strictObject({ revision: integer().positive(), sha256: digest }).nullable(),
48
49
  activatesProfile: z.literal(false),
49
- }).strict(),
50
+ }),
50
51
  actions: z.array(z.string().min(1).max(200)).min(1),
51
52
  warnings: z.array(z.string().min(1).max(400)),
52
- profileTemplate: z.unknown(),
53
- }).strict();
53
+ profileTemplate: z.unknown().optional(),
54
+ });
54
55
  function planDigest(plan) {
55
56
  return hash(JSON.stringify(canonicalize(plan)));
56
57
  }
@@ -1,11 +1,12 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { z } from 'zod';
3
+ import { integer } from '../schema/zod-validation.mjs';
3
4
  import { redactText } from '../governance/redaction.js';
4
5
  import { validateLegacyWriterProfile } from './writer-profile-legacy.js';
5
6
  const hash = (text) => createHash('sha256').update(text).digest('hex');
6
7
  const id = z.string().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
7
- const provenance = z.object({ source: z.string().min(1).max(2000), license: z.string().min(1).max(200) }).strict();
8
- const evidence = z.object({ sampleId: id, start: z.number().int().nonnegative(), end: z.number().int().positive() }).strict();
8
+ const provenance = z.strictObject({ source: z.string().min(1).max(2000), license: z.string().min(1).max(200) });
9
+ const evidence = z.strictObject({ sampleId: id, start: integer().nonnegative(), end: integer().positive() });
9
10
  /** Closed expression controls exclude identity, personality and generated signature phrases. */
10
11
  export const writerPreferenceValues = {
11
12
  dialect: ['unspecified', 'en-US', 'en-GB', 'en-AU', 'en-CA', 'fr-FR', 'fr-CA'],
@@ -22,29 +23,29 @@ export const writerPreferenceValues = {
22
23
  structure: ['prose', 'lists', 'contextual'],
23
24
  };
24
25
  const preferenceKey = z.enum(Object.keys(writerPreferenceValues));
25
- const preference = z.object({
26
+ const preference = z.strictObject({
26
27
  id, key: preferenceKey, value: z.string(), origin: z.enum(['explicit', 'inferred']),
27
- confidence: z.enum(['low', 'moderate', 'high']), evidence: z.array(evidence).default([]),
28
+ confidence: z.enum(['low', 'moderate', 'high']), evidence: z.array(evidence).prefault([]),
28
29
  task: z.string().max(120).optional(), status: z.enum(['accepted', 'rejected']).default('accepted'),
29
- }).strict();
30
- const override = z.object({ key: preferenceKey, action: z.enum(['set', 'reject', 'reset']), value: z.string().optional(), task: z.string().max(120).optional() }).strict();
31
- const sample = z.object({
30
+ });
31
+ const override = z.strictObject({ key: preferenceKey, action: z.enum(['set', 'reject', 'reset']), value: z.string().optional(), task: z.string().max(120).optional() });
32
+ const sample = z.strictObject({
32
33
  id, text: z.string().max(1_000_000).optional(), sha256: z.string().regex(/^[a-f0-9]{64}$/), approved: z.boolean(),
33
34
  status: z.enum(['active', 'revoked']), provenance,
34
- rights: z.object({ useForVoice: z.boolean(), shareText: z.boolean() }).strict(),
35
+ rights: z.strictObject({ useForVoice: z.boolean(), shareText: z.boolean() }),
35
36
  sensitivity: z.enum(['public', 'private', 'secret']),
36
- }).strict();
37
- export const legacyProfileAttachmentSchema = z.object({
37
+ });
38
+ export const legacyProfileAttachmentSchema = z.strictObject({
38
39
  format: z.enum(['yaml', 'json']),
39
40
  kind: z.enum(['addon-template', 'python-generated', 'python-analyzed', 'python-blended', 'ts-analyzer', 'ts-calibration']),
40
- raw: z.string(), sha256: z.string().regex(/^[a-f0-9]{64}$/), payload: z.unknown(),
41
- }).strict();
42
- export const writerProfileSchema = z.object({
43
- schemaVersion: z.literal(1), revision: z.number().int().positive().default(1), metadataSharingApproved: z.boolean().default(false), id: z.string().regex(/^[a-z0-9][a-z0-9.-]{0,79}$/).refine(v => !v.includes('..')), version: z.string().regex(/^\d+\.\d+\.\d+$/), name: z.string().min(1).max(200), provenance,
44
- samples: z.array(sample), preferences: z.array(preference), overrides: z.array(override).default([]),
45
- counterexamples: z.array(evidence).default([]), legacy: legacyProfileAttachmentSchema.optional(),
46
- cacheEpoch: z.number().int().nonnegative().default(0),
47
- }).strict().superRefine((p, ctx) => {
41
+ raw: z.string(), sha256: z.string().regex(/^[a-f0-9]{64}$/), payload: z.unknown().optional(),
42
+ });
43
+ export const writerProfileSchema = z.strictObject({
44
+ schemaVersion: z.literal(1), revision: integer().positive().default(1), metadataSharingApproved: z.boolean().default(false), id: z.string().regex(/^[a-z0-9][a-z0-9.-]{0,79}$/).refine(v => !v.includes('..')), version: z.string().regex(/^\d+\.\d+\.\d+$/), name: z.string().min(1).max(200), provenance,
45
+ samples: z.array(sample), preferences: z.array(preference), overrides: z.array(override).prefault([]),
46
+ counterexamples: z.array(evidence).prefault([]), legacy: legacyProfileAttachmentSchema.optional(),
47
+ cacheEpoch: integer().nonnegative().default(0),
48
+ }).superRefine((p, ctx) => {
48
49
  const problem = (message) => ctx.addIssue({ code: z.ZodIssueCode.custom, message });
49
50
  if (new Set(p.samples.map(s => s.id)).size !== p.samples.length)
50
51
  problem('Duplicate sample IDs');
@@ -1,36 +1,37 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { z } from 'zod';
3
+ import { integer } from '../schema/zod-validation.mjs';
3
4
  const id = z.string().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
4
5
  const digest = z.string().regex(/^[a-f0-9]{64}$/);
5
6
  const text = z.string().min(1);
6
- const span = { start: z.number().int().nonnegative(), end: z.number().int().nonnegative() };
7
- const evidence = z.object({ inputId: id, ...span }).strict();
8
- const input = z.object({
7
+ const span = { start: integer().nonnegative(), end: integer().nonnegative() };
8
+ const evidence = z.strictObject({ inputId: id, ...span });
9
+ const input = z.strictObject({
9
10
  id, kind: z.enum(['source', 'author-notes', 'existing-draft']), text,
10
- sha256: digest, provenance: z.object({ source: text, version: text }).strict(),
11
+ sha256: digest, provenance: z.strictObject({ source: text, version: text }),
11
12
  authorApproved: z.boolean(),
12
- }).strict();
13
- const proposition = z.object({
13
+ });
14
+ const proposition = z.strictObject({
14
15
  id, text, evidenceStrength: z.enum(['verified', 'reported', 'preliminary', 'experimental', 'unverified']),
15
16
  evidence: z.array(evidence).min(1), qualifiers: z.array(text),
16
- }).strict();
17
- const authorClaim = z.object({
17
+ });
18
+ const authorClaim = z.strictObject({
18
19
  id, kind: z.enum(['experience', 'opinion', 'intent', 'rationale']), text,
19
20
  evidence: z.array(evidence).min(1),
20
- }).strict();
21
- const correction = z.object({
21
+ });
22
+ const correction = z.strictObject({
22
23
  id, ...span, expected: z.string(), replacement: z.string(), reason: text,
23
24
  authorAuthorized: z.literal(true),
24
- }).strict();
25
- export const writingBriefSchema = z.object({
25
+ });
26
+ export const writingBriefSchema = z.strictObject({
26
27
  schemaVersion: z.literal(1), id,
27
28
  operation: z.enum(['draft-from-notes', 'edit-existing', 'proofread-only', 'continue-author-text']),
28
- reader: z.object({ task: z.string(), audience: text, requirements: z.array(text) }).strict(),
29
+ reader: z.strictObject({ task: z.string(), audience: text, requirements: z.array(text) }),
29
30
  intendedAction: z.string(), exclusions: z.array(text), inputs: z.array(input),
30
31
  propositions: z.array(proposition), limitations: z.array(proposition), authorClaims: z.array(authorClaim),
31
32
  sourceInputId: id.optional(),
32
- permissions: z.object({ rephrase: z.boolean(), reorder: z.boolean(), addContent: z.boolean(), corrections: z.array(correction) }).strict(),
33
- }).strict();
33
+ permissions: z.strictObject({ rephrase: z.boolean(), reorder: z.boolean(), addContent: z.boolean(), corrections: z.array(correction) }),
34
+ });
34
35
  export const writingBriefHash = (value) => createHash('sha256').update(value, 'utf8').digest('hex');
35
36
  function boundary(source, offset) {
36
37
  return offset >= 0 && offset <= source.length
@@ -101,7 +102,7 @@ export function parseWritingBrief(value) {
101
102
  /** Parameterization changes presentation targets only, never the brief or confidence. */
102
103
  export function prepareWritingBrief(value, target) {
103
104
  const b = parseWritingBrief(value);
104
- const selection = z.object({ profileId: id, channel: z.enum(['article', 'social', 'email', 'engineering', 'conversation']) }).strict().safeParse(target);
105
+ const selection = z.strictObject({ profileId: id, channel: z.enum(['article', 'social', 'email', 'engineering', 'conversation']) }).safeParse(target);
105
106
  if (!selection.success)
106
107
  throw new Error('Invalid writing brief target; input text is omitted.');
107
108
  return { brief: structuredClone(b), target: selection.data, briefDigest: writingBriefHash(JSON.stringify(b)),
@@ -114,7 +115,7 @@ export function validateBriefClaims(value, proposed) {
114
115
  if (!check.valid)
115
116
  return check;
116
117
  const b = parseWritingBrief(value);
117
- const proposal = z.array(z.object({ kind: z.enum(['proposition', 'experience', 'opinion', 'intent', 'rationale']), text, groundedIn: z.array(id) }).strict()).safeParse(proposed);
118
+ const proposal = z.array(z.strictObject({ kind: z.enum(['proposition', 'experience', 'opinion', 'intent', 'rationale']), text, groundedIn: z.array(id) })).safeParse(proposed);
118
119
  if (!proposal.success)
119
120
  return { valid: false, diagnostics: [{ code: 'schema', message: 'Invalid proposed claim shape; input text is omitted.' }] };
120
121
  const claims = [...b.propositions.map(p => ({ ...p, kind: 'proposition' })), ...b.limitations.map(p => ({ ...p, kind: 'proposition' })), ...b.authorClaims];
@@ -2,12 +2,13 @@ import { createHash, randomUUID } from 'node:crypto';
2
2
  import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { z } from 'zod';
5
+ import { integer, dateTime } from '../schema/zod-validation.mjs';
5
6
  import { redactStructured } from '../governance/redaction.js';
6
7
  import { resolveProjectAiwgDirForWrite } from '../config/project-artifacts.js';
7
8
  const sha = z.string().regex(/^[a-f0-9]{64}$/);
8
9
  const id = z.string().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
9
10
  const stableId = z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9.-]*$/).refine(value => !value.includes('..'));
10
- const isoDate = z.string().datetime();
11
+ const isoDate = dateTime();
11
12
  const hash = (text) => createHash('sha256').update(text, 'utf8').digest('hex');
12
13
  function canonicalize(value) {
13
14
  if (Array.isArray(value))
@@ -28,105 +29,105 @@ function rejectSensitiveReceipt(value) {
28
29
  if (redacted.sensitivity !== 'none')
29
30
  throw new Error('Writing receipt contains a known secret or credential field');
30
31
  }
31
- const budgetSchema = z.object({
32
- limit: z.number().int().nonnegative(),
33
- used: z.number().int().nonnegative(),
32
+ const budgetSchema = z.strictObject({
33
+ limit: integer().nonnegative(),
34
+ used: integer().nonnegative(),
34
35
  unit: z.enum(['tokens', 'utf8-bytes', 'characters']),
35
36
  measurement: z.enum(['exact', 'upper-bound', 'estimated']),
36
37
  tokenizerId: z.string().min(1).max(120),
37
38
  tokenizerVersion: z.string().min(1).max(120),
38
- }).strict().refine(value => value.used <= value.limit, 'Budget use cannot exceed limit');
39
- const operationConfigSchema = z.object({
39
+ }).refine(value => value.used <= value.limit, 'Budget use cannot exceed limit');
40
+ const operationConfigSchema = z.strictObject({
40
41
  action: z.enum(['plan', 'proofread', 'draft', 'edit', 'continue']),
41
- correctionIds: z.array(id).default([]),
42
+ correctionIds: z.array(id).prefault([]),
42
43
  channel: z.enum(['article', 'social', 'email', 'engineering', 'conversation']).optional(),
43
44
  configSha256: sha.optional(),
44
- }).strict();
45
- const receiptInputBaseSchema = z.object({
45
+ });
46
+ const receiptInputBaseSchema = z.strictObject({
46
47
  schemaVersion: z.literal('aiwg.writing-receipt.v1').default('aiwg.writing-receipt.v1'),
47
48
  id: stableId.optional(),
48
49
  createdAt: isoDate.default(() => new Date().toISOString()),
49
50
  operation: z.enum(['draft-from-notes', 'edit-existing', 'proofread-only', 'continue-author-text']),
50
- profile: z.object({
51
+ profile: z.strictObject({
51
52
  id: stableId,
52
53
  version: z.string().regex(/^\d+\.\d+\.\d+$/),
53
- revision: z.number().int().positive(),
54
- cacheEpoch: z.number().int().nonnegative(),
54
+ revision: integer().positive(),
55
+ cacheEpoch: integer().nonnegative(),
55
56
  compiledModeSha256: sha.optional(),
56
57
  fallback: z.boolean(),
57
- }).strict(),
58
- examples: z.object({
58
+ }),
59
+ examples: z.strictObject({
59
60
  receiptSha256: sha.optional(),
60
61
  cacheKey: sha.optional(),
61
- selections: z.array(z.object({ sampleId: id, sha256: sha }).strict()).default([]),
62
+ selections: z.array(z.strictObject({ sampleId: id, sha256: sha })).prefault([]),
62
63
  budget: budgetSchema.optional(),
63
64
  fallback: z.boolean().default(false),
64
- }).strict().optional(),
65
- modes: z.array(z.object({
65
+ }).optional(),
66
+ modes: z.array(z.strictObject({
66
67
  id: stableId,
67
68
  version: z.string().min(1).max(120),
68
69
  profileSha256: sha.optional(),
69
- }).strict()).default([]),
70
- state: z.object({
71
- selected: z.array(stableId).default([]),
72
- delivered: z.array(stableId).default([]),
73
- applied: z.array(stableId).default([]),
74
- validated: z.array(stableId).default([]),
70
+ })).prefault([]),
71
+ state: z.strictObject({
72
+ selected: z.array(stableId).prefault([]),
73
+ delivered: z.array(stableId).prefault([]),
74
+ applied: z.array(stableId).prefault([]),
75
+ validated: z.array(stableId).prefault([]),
75
76
  deliveredTo: z.enum(['local-transform-callback', 'none']),
76
77
  fallback: z.enum(['none', 'unaltered']),
77
- }).strict().optional(),
78
- modelPrompt: z.object({
78
+ }).optional(),
79
+ modelPrompt: z.strictObject({
79
80
  execution: z.enum(['none', 'local-callback', 'hosted']).default('none'),
80
81
  provider: z.string().min(1).max(120).optional(),
81
82
  model: z.string().min(1).max(120).optional(),
82
83
  promptSha256: sha,
83
84
  templateSha256: sha.optional(),
84
- decoding: z.object({
85
+ decoding: z.strictObject({
85
86
  temperature: z.number().finite().min(0).max(2).optional(),
86
87
  topP: z.number().finite().min(0).max(1).optional(),
87
- maxOutputTokens: z.number().int().positive().optional(),
88
- seed: z.number().int().optional(),
88
+ maxOutputTokens: integer().positive().optional(),
89
+ seed: integer().optional(),
89
90
  stopSha256: sha.optional(),
90
- }).strict().optional(),
91
+ }).optional(),
91
92
  promptConfigSha256: sha.optional(),
92
- hostedVersion: z.object({
93
+ hostedVersion: z.strictObject({
93
94
  attested: z.literal(false),
94
95
  reason: z.literal('Hosted provider prompt/version cannot be attested from this local receipt.'),
95
- }).strict().optional(),
96
- }).strict(),
97
- inputs: z.array(z.object({
96
+ }).optional(),
97
+ }),
98
+ inputs: z.array(z.strictObject({
98
99
  id,
99
100
  role: z.enum(['source', 'author-notes', 'existing-draft', 'brief', 'configuration']),
100
101
  sha256: sha,
101
- }).strict()).min(1),
102
+ })).min(1),
102
103
  operationConfig: operationConfigSchema.optional(),
103
- output: z.object({
104
+ output: z.strictObject({
104
105
  sha256: sha,
105
106
  path: z.string().min(1).max(2000).optional(),
106
- }).strict().optional(),
107
+ }).optional(),
107
108
  budget: budgetSchema,
108
- fallback: z.object({
109
+ fallback: z.strictObject({
109
110
  applied: z.boolean(),
110
111
  reason: z.string().min(1).max(400).optional(),
111
- }).strict(),
112
- validators: z.array(z.object({
112
+ }),
113
+ validators: z.array(z.strictObject({
113
114
  id,
114
115
  version: z.string().min(1).max(120),
115
116
  sha256: sha.optional(),
116
117
  outcome: z.enum(['pass', 'fail', 'uncertain', 'not-run']),
117
- }).strict()).default([]),
118
- evaluation: z.array(z.object({
118
+ })).prefault([]),
119
+ evaluation: z.array(z.strictObject({
119
120
  id,
120
121
  method: z.string().min(1).max(120),
121
122
  sha256: sha,
122
123
  outcome: z.enum(['pass', 'fail', 'uncertain', 'not-established']),
123
- }).strict()).default([]),
124
- authorAcceptance: z.object({
124
+ })).prefault([]),
125
+ authorAcceptance: z.strictObject({
125
126
  status: z.enum(['accepted', 'pending', 'rejected', 'not-required']),
126
127
  acceptedAt: isoDate.optional(),
127
128
  acceptedBy: z.string().min(1).max(120).optional(),
128
- }).strict(),
129
- }).strict();
129
+ }),
130
+ });
130
131
  const enforceReceiptRules = (value, ctx) => {
131
132
  if (new Set(value.inputs.map(input => input.id)).size !== value.inputs.length) {
132
133
  ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Input IDs must be unique' });
@@ -176,7 +177,7 @@ const enforceReceiptRules = (value, ctx) => {
176
177
  }
177
178
  };
178
179
  const receiptInputSchema = receiptInputBaseSchema.superRefine(enforceReceiptRules);
179
- export const writingReceiptSchema = receiptInputBaseSchema.extend({ id: stableId, operationConfig: operationConfigSchema, receiptSha256: sha }).strict().superRefine(enforceReceiptRules);
180
+ export const writingReceiptSchema = receiptInputBaseSchema.extend({ id: stableId, operationConfig: operationConfigSchema, receiptSha256: sha }).superRefine(enforceReceiptRules);
180
181
  export function createWritingReceipt(input) {
181
182
  const parsed = receiptInputSchema.parse(input);
182
183
  const defaultAction = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwg/cli",
3
- "version": "2026.10.5",
3
+ "version": "2026.10.7",
4
4
  "description": "Lightweight AIWG CLI for signed, versioned web-backed resources.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,6 +27,9 @@
27
27
  "THIRD_PARTY_NOTICES.md",
28
28
  "bin/",
29
29
  "agentic/code/providers/",
30
+ "agentic/code/addons/composition-engine/lib/runtime.mjs",
31
+ "agentic/code/addons/composition-engine/lib/validator.mjs",
32
+ "agentic/code/addons/composition-engine/schemas/flow-graph.schema.json",
30
33
  "schemas/security/",
31
34
  "schemas/decision/",
32
35
  "schemas/dataset/",
@@ -115,7 +118,7 @@
115
118
  "semver": "^7.8.5",
116
119
  "toml-eslint-parser": "0.10.0",
117
120
  "yaml": "^2.9.0",
118
- "zod": "^3.25.0"
121
+ "zod": "^4.6.6"
119
122
  },
120
123
  "optionalDependencies": {
121
124
  "@hono/node-server": "2.0.11",
@@ -17,12 +17,89 @@
17
17
  "lifecycle": { "type": "object", "additionalProperties": false, "required": ["legalHold"], "properties": { "legalHold": { "type": "boolean" }, "tombstonedAtEpochMs": { "type": "integer", "minimum": 0 }, "tombstoneReason": { "type": "string" } } }
18
18
  },
19
19
  "$defs": {
20
+ "evaluation": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "description": "Observed evaluator provenance and evidence. Agreement does not establish independent errors or proof.",
24
+ "properties": {
25
+ "evaluatorModel": {
26
+ "type": "string",
27
+ "minLength": 1,
28
+ "maxLength": 8192,
29
+ "pattern": "\\S"
30
+ },
31
+ "evaluatorVendor": {
32
+ "type": "string",
33
+ "minLength": 1,
34
+ "maxLength": 8192,
35
+ "pattern": "\\S"
36
+ },
37
+ "evaluatorFamily": {
38
+ "type": "string",
39
+ "minLength": 1,
40
+ "maxLength": 8192,
41
+ "pattern": "\\S",
42
+ "description": "Observed model family; unknown remains unknown. CLI names are not model families."
43
+ },
44
+ "acceptanceCriteriaRef": {
45
+ "type": "string",
46
+ "minLength": 1,
47
+ "maxLength": 8192,
48
+ "pattern": "\\S"
49
+ },
50
+ "reReviewOf": {
51
+ "type": "string",
52
+ "minLength": 1,
53
+ "maxLength": 8192,
54
+ "pattern": "\\S",
55
+ "description": "Reference to the previous review/decision, recorded on a re-review after material fixes."
56
+ },
57
+ "disagreements": {
58
+ "type": "array",
59
+ "items": {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": [
63
+ "claimRef",
64
+ "generatorPosition",
65
+ "evaluatorPosition"
66
+ ],
67
+ "properties": {
68
+ "claimRef": {
69
+ "type": "string",
70
+ "minLength": 1,
71
+ "maxLength": 8192,
72
+ "pattern": "\\S"
73
+ },
74
+ "generatorPosition": {
75
+ "type": "string",
76
+ "minLength": 1,
77
+ "maxLength": 8192,
78
+ "pattern": "\\S"
79
+ },
80
+ "evaluatorPosition": {
81
+ "type": "string",
82
+ "minLength": 1,
83
+ "maxLength": 8192,
84
+ "pattern": "\\S"
85
+ },
86
+ "resolutionRef": {
87
+ "type": "string",
88
+ "minLength": 1,
89
+ "maxLength": 8192,
90
+ "pattern": "\\S"
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ },
20
97
  "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
21
98
  "actor": { "type": "object", "additionalProperties": false, "required": ["id", "roles", "authorityContext"], "properties": { "id": { "type": "string", "minLength": 1 }, "roles": { "type": "array", "items": { "type": "string" } }, "authorityContext": { "type": "string" } } },
22
99
  "pin": { "type": "object", "additionalProperties": false, "required": ["id", "version", "digest"], "properties": { "id": { "type": "string" }, "version": { "type": "string" }, "digest": { "$ref": "#/$defs/digest" } } },
23
100
  "sourceReceipt": { "type": "object", "additionalProperties": false, "required": ["id", "digest"], "properties": { "id": { "type": "string" }, "digest": { "$ref": "#/$defs/digest" } } },
24
101
  "proposal": { "type": "object", "additionalProperties": false, "required": ["version", "action", "actionDigest", "createdAtEpochMs", "editor", "rationale"], "properties": { "version": { "type": "integer", "minimum": 1 }, "action": {}, "actionDigest": { "$ref": "#/$defs/digest" }, "createdAtEpochMs": { "type": "integer" }, "editor": { "$ref": "#/$defs/actor" }, "rationale": { "type": "string" } } },
25
- "decision": { "type": "object", "additionalProperties": false, "required": ["reviewer", "proposalVersion", "decision", "rationale", "atEpochMs"], "properties": { "reviewer": { "$ref": "#/$defs/actor" }, "proposalVersion": { "type": "integer" }, "decision": { "enum": ["approve", "reject"] }, "rationale": { "type": "string" }, "atEpochMs": { "type": "integer" } } },
102
+ "decision": { "type": "object", "additionalProperties": false, "required": ["reviewer", "proposalVersion", "decision", "rationale", "atEpochMs"], "properties": { "reviewer": { "$ref": "#/$defs/actor" }, "proposalVersion": { "type": "integer" }, "decision": { "enum": ["approve", "reject"] }, "rationale": { "type": "string" }, "atEpochMs": { "type": "integer" }, "evaluation": { "$ref": "#/$defs/evaluation" } } },
26
103
  "event": { "type": "object", "additionalProperties": false, "required": ["sequence", "type", "atEpochMs", "actor", "proposalVersion", "rationale"], "properties": { "sequence": { "type": "integer" }, "type": { "enum": ["created", "claimed", "approved", "rejected", "edited", "expired", "escalated", "canceled", "resumed", "execution-completed", "execution-failed", "legal-hold-placed", "legal-hold-released", "tombstoned", "authorization-denied", "sensitive-view-accessed"] }, "atEpochMs": { "type": "integer" }, "actor": { "$ref": "#/$defs/actor" }, "proposalVersion": { "type": "integer" }, "rationale": { "type": "string" }, "operatorDecisionEventId": { "type": "string", "minLength": 1 }, "data": { "type": "object" } } },
27
104
  "effect": { "type": "object", "additionalProperties": false, "required": ["effectId", "continuationId", "proposalVersion", "completedAtEpochMs", "result"], "properties": { "effectId": { "type": "string" }, "continuationId": { "type": "string" }, "proposalVersion": { "type": "integer" }, "completedAtEpochMs": { "type": "integer" }, "result": {} } }
28
105
  }
@@ -1643,6 +1643,9 @@
1643
1643
  "type": "object",
1644
1644
  "additionalProperties": false,
1645
1645
  "properties": {
1646
+ "isolation": {
1647
+ "enum": ["systemd-unit", "native-sandbox"]
1648
+ },
1646
1649
  "version": {
1647
1650
  "const": 1
1648
1651
  },