@aiwg/cli 2026.9.3 → 2026.9.5

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 (95) hide show
  1. package/README.md +21 -0
  2. package/THIRD_PARTY_NOTICES.md +16 -0
  3. package/agentic/code/providers/capability-matrix.yaml +45 -3
  4. package/agentic/code/providers/deepseek-harness/README.md +8 -0
  5. package/agentic/code/providers/deepseek-harness/aiwg.cordis.patch.yml +10 -0
  6. package/agentic/code/providers/model-capabilities.v1.json +11 -0
  7. package/agentic/code/providers/model-catalog.v1.json +8 -0
  8. package/bin/aiwg.mjs +1 -0
  9. package/dist/src/api/index.d.ts +14 -0
  10. package/dist/src/api/index.js +14 -0
  11. package/dist/src/artifacts/corpus-tools/source-types.js +1 -0
  12. package/dist/src/artifacts/index-files.js +17 -2
  13. package/dist/src/artifacts/repair.js +55 -6
  14. package/dist/src/catalog/cli.js +21 -7
  15. package/dist/src/catalog/cli.mjs +22 -7
  16. package/dist/src/cli/agent-spawn.js +10 -1
  17. package/dist/src/cli/handlers/artifacts.js +22 -3
  18. package/dist/src/cli/handlers/help.js +3 -0
  19. package/dist/src/cli/handlers/index.js +5 -1
  20. package/dist/src/cli/handlers/models.js +2 -2
  21. package/dist/src/cli/handlers/output-mode.js +1 -1
  22. package/dist/src/cli/handlers/runtime-info.js +1 -1
  23. package/dist/src/cli/handlers/sessions.js +55 -15
  24. package/dist/src/cli/handlers/steward.js +1 -1
  25. package/dist/src/cli/handlers/subcommands.js +5 -0
  26. package/dist/src/cli/handlers/use.js +37 -0
  27. package/dist/src/cli/handlers/writer-profile.js +110 -0
  28. package/dist/src/cli/handlers/writing.js +122 -0
  29. package/dist/src/cli/router.js +5 -1
  30. package/dist/src/config/project-artifacts-runtime.mjs +33 -1
  31. package/dist/src/config/project-artifacts.js +1 -1
  32. package/dist/src/dataset/fortemi-dataset-execution.d.ts +23 -0
  33. package/dist/src/dataset/fortemi-dataset-execution.js +158 -0
  34. package/dist/src/dataset/fortemi-live-qualification.d.ts +4 -2
  35. package/dist/src/dataset/fortemi-live-qualification.js +20 -21
  36. package/dist/src/dataset/fortemi-run-receipt.d.ts +44 -0
  37. package/dist/src/dataset/fortemi-run-receipt.js +74 -0
  38. package/dist/src/dataset/index.d.ts +2 -0
  39. package/dist/src/dataset/index.js +2 -0
  40. package/dist/src/extensions/commands/definitions.js +24 -0
  41. package/dist/src/extensions/manifest.js +3 -0
  42. package/dist/src/mcp/server.mjs +2 -0
  43. package/dist/src/mcp/tools/writer-profiles.mjs +40 -0
  44. package/dist/src/models/model-capabilities.v1.json +11 -0
  45. package/dist/src/models/model-catalog.v1.json +8 -0
  46. package/dist/src/models/provider-policy.js +1 -1
  47. package/dist/src/network-analysis/analyzer.js +667 -0
  48. package/dist/src/network-analysis/citations.js +107 -0
  49. package/dist/src/network-analysis/forensics.js +132 -0
  50. package/dist/src/network-analysis/governance.js +216 -0
  51. package/dist/src/network-analysis/index.js +10 -0
  52. package/dist/src/network-analysis/probe.js +405 -0
  53. package/dist/src/network-analysis/recipes.js +88 -0
  54. package/dist/src/network-analysis/research.js +181 -0
  55. package/dist/src/network-analysis/termshark.js +252 -0
  56. package/dist/src/network-analysis/verification.js +171 -0
  57. package/dist/src/output-modes/registry.js +37 -6
  58. package/dist/src/output-modes/runtime.js +164 -28
  59. package/dist/src/providers/capability-matrix.yaml +45 -3
  60. package/dist/src/providers/provider-definitions.js +49 -0
  61. package/dist/src/providers/provider-inventory.js +1 -0
  62. package/dist/src/providers/transformation-receipt.js +3 -2
  63. package/dist/src/sessions/adapters/deepseek-harness.js +178 -0
  64. package/dist/src/sessions/batch-import.js +7 -0
  65. package/dist/src/sessions/contracts.js +2 -1
  66. package/dist/src/sessions/index.js +1 -0
  67. package/dist/src/sessions/workspace-discovery.js +5 -1
  68. package/dist/src/skills/deployer.js +6 -6
  69. package/dist/src/smiths/context-pipeline/workspace-context.js +7 -0
  70. package/dist/src/writing/channel-packs.js +13 -0
  71. package/dist/src/writing/contextual-diagnostics.js +142 -0
  72. package/dist/src/writing/example-generator.js +7 -6
  73. package/dist/src/writing/exemplar-selection.js +186 -0
  74. package/dist/src/writing/fidelity.js +61 -0
  75. package/dist/src/writing/validation-engine.js +32 -15
  76. package/dist/src/writing/voice-evaluation.js +301 -0
  77. package/dist/src/writing/voice-revision.js +201 -0
  78. package/dist/src/writing/writer-migration.js +216 -0
  79. package/dist/src/writing/writer-profile-legacy.js +145 -0
  80. package/dist/src/writing/writer-profile-store.js +117 -0
  81. package/dist/src/writing/writer-profile.js +222 -0
  82. package/dist/src/writing/writing-brief.js +166 -0
  83. package/dist/src/writing/writing-channels.js +63 -0
  84. package/dist/src/writing/writing-consumer.js +39 -0
  85. package/dist/src/writing/writing-receipt.js +266 -0
  86. package/package.json +1 -1
  87. package/schemas/dataset/fortemi-live-qualification-receipt.v2.schema.json +196 -0
  88. package/schemas/dataset/fortemi-run-receipt/validation-1.0.1/authority.json +12 -0
  89. package/schemas/dataset/fortemi-run-receipt/validation-1.0.1/run-receipt.schema.json +819 -0
  90. package/tools/agents/deploy-agents.mjs +7 -3
  91. package/tools/agents/providers/antigravity.mjs +1 -1
  92. package/tools/agents/providers/base.mjs +3 -2
  93. package/tools/agents/providers/deepseek-harness.mjs +66 -0
  94. package/tools/agents/providers/hermes.mjs +1 -1
  95. package/tools/agents/providers/openhuman.mjs +2 -2
@@ -0,0 +1,266 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { z } from 'zod';
5
+ import { redactStructured } from '../governance/redaction.js';
6
+ import { resolveProjectAiwgDirForWrite } from '../config/project-artifacts.js';
7
+ const sha = z.string().regex(/^[a-f0-9]{64}$/);
8
+ const id = z.string().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
9
+ 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 hash = (text) => createHash('sha256').update(text, 'utf8').digest('hex');
12
+ function canonicalize(value) {
13
+ if (Array.isArray(value))
14
+ return value.map(canonicalize);
15
+ if (value && typeof value === 'object') {
16
+ return Object.fromEntries(Object.entries(value)
17
+ .filter(([, child]) => child !== undefined)
18
+ .sort(([a], [b]) => a.localeCompare(b))
19
+ .map(([key, child]) => [key, canonicalize(child)]));
20
+ }
21
+ return value;
22
+ }
23
+ function receiptDigest(receipt) {
24
+ return hash(JSON.stringify(canonicalize(receipt)));
25
+ }
26
+ function rejectSensitiveReceipt(value) {
27
+ const redacted = redactStructured(value);
28
+ if (redacted.sensitivity !== 'none')
29
+ throw new Error('Writing receipt contains a known secret or credential field');
30
+ }
31
+ const budgetSchema = z.object({
32
+ limit: z.number().int().nonnegative(),
33
+ used: z.number().int().nonnegative(),
34
+ unit: z.enum(['tokens', 'utf8-bytes', 'characters']),
35
+ measurement: z.enum(['exact', 'upper-bound', 'estimated']),
36
+ tokenizerId: z.string().min(1).max(120),
37
+ 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({
40
+ action: z.enum(['plan', 'proofread', 'draft', 'edit', 'continue']),
41
+ correctionIds: z.array(id).default([]),
42
+ channel: z.enum(['article', 'social', 'email', 'engineering', 'conversation']).optional(),
43
+ configSha256: sha.optional(),
44
+ }).strict();
45
+ const receiptInputBaseSchema = z.object({
46
+ schemaVersion: z.literal('aiwg.writing-receipt.v1').default('aiwg.writing-receipt.v1'),
47
+ id: stableId.optional(),
48
+ createdAt: isoDate.default(() => new Date().toISOString()),
49
+ operation: z.enum(['draft-from-notes', 'edit-existing', 'proofread-only', 'continue-author-text']),
50
+ profile: z.object({
51
+ id: stableId,
52
+ version: z.string().regex(/^\d+\.\d+\.\d+$/),
53
+ revision: z.number().int().positive(),
54
+ cacheEpoch: z.number().int().nonnegative(),
55
+ compiledModeSha256: sha.optional(),
56
+ fallback: z.boolean(),
57
+ }).strict(),
58
+ examples: z.object({
59
+ receiptSha256: sha.optional(),
60
+ cacheKey: sha.optional(),
61
+ selections: z.array(z.object({ sampleId: id, sha256: sha }).strict()).default([]),
62
+ budget: budgetSchema.optional(),
63
+ fallback: z.boolean().default(false),
64
+ }).strict().optional(),
65
+ modes: z.array(z.object({
66
+ id: stableId,
67
+ version: z.string().min(1).max(120),
68
+ 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([]),
75
+ deliveredTo: z.enum(['local-transform-callback', 'none']),
76
+ fallback: z.enum(['none', 'unaltered']),
77
+ }).strict().optional(),
78
+ modelPrompt: z.object({
79
+ execution: z.enum(['none', 'local-callback', 'hosted']).default('none'),
80
+ provider: z.string().min(1).max(120).optional(),
81
+ model: z.string().min(1).max(120).optional(),
82
+ promptSha256: sha,
83
+ templateSha256: sha.optional(),
84
+ decoding: z.object({
85
+ temperature: z.number().finite().min(0).max(2).optional(),
86
+ topP: z.number().finite().min(0).max(1).optional(),
87
+ maxOutputTokens: z.number().int().positive().optional(),
88
+ seed: z.number().int().optional(),
89
+ stopSha256: sha.optional(),
90
+ }).strict().optional(),
91
+ promptConfigSha256: sha.optional(),
92
+ hostedVersion: z.object({
93
+ attested: z.literal(false),
94
+ 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({
98
+ id,
99
+ role: z.enum(['source', 'author-notes', 'existing-draft', 'brief', 'configuration']),
100
+ sha256: sha,
101
+ }).strict()).min(1),
102
+ operationConfig: operationConfigSchema.optional(),
103
+ output: z.object({
104
+ sha256: sha,
105
+ path: z.string().min(1).max(2000).optional(),
106
+ }).strict().optional(),
107
+ budget: budgetSchema,
108
+ fallback: z.object({
109
+ applied: z.boolean(),
110
+ reason: z.string().min(1).max(400).optional(),
111
+ }).strict(),
112
+ validators: z.array(z.object({
113
+ id,
114
+ version: z.string().min(1).max(120),
115
+ sha256: sha.optional(),
116
+ outcome: z.enum(['pass', 'fail', 'uncertain', 'not-run']),
117
+ }).strict()).default([]),
118
+ evaluation: z.array(z.object({
119
+ id,
120
+ method: z.string().min(1).max(120),
121
+ sha256: sha,
122
+ outcome: z.enum(['pass', 'fail', 'uncertain', 'not-established']),
123
+ }).strict()).default([]),
124
+ authorAcceptance: z.object({
125
+ status: z.enum(['accepted', 'pending', 'rejected', 'not-required']),
126
+ acceptedAt: isoDate.optional(),
127
+ acceptedBy: z.string().min(1).max(120).optional(),
128
+ }).strict(),
129
+ }).strict();
130
+ const enforceReceiptRules = (value, ctx) => {
131
+ if (new Set(value.inputs.map(input => input.id)).size !== value.inputs.length) {
132
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Input IDs must be unique' });
133
+ }
134
+ if (value.fallback.applied && !value.fallback.reason) {
135
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Fallback receipts require a reason' });
136
+ }
137
+ if (!value.fallback.applied && value.fallback.reason) {
138
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Fallback reason is only valid when fallback is applied' });
139
+ }
140
+ if (value.authorAcceptance.status === 'accepted' && (!value.authorAcceptance.acceptedAt || !value.authorAcceptance.acceptedBy)) {
141
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Accepted receipts require acceptedAt and acceptedBy' });
142
+ }
143
+ if (value.authorAcceptance.status !== 'accepted' && (value.authorAcceptance.acceptedAt || value.authorAcceptance.acceptedBy)) {
144
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Acceptance identity is only valid for accepted receipts' });
145
+ }
146
+ if (new Set(value.modes.map(mode => mode.id)).size !== value.modes.length) {
147
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Mode IDs must be unique' });
148
+ }
149
+ if (value.state) {
150
+ const knownModes = new Set(value.modes.map(mode => mode.id));
151
+ const stateGroups = [value.state.selected, value.state.delivered, value.state.applied, value.state.validated];
152
+ if (stateGroups.some(group => new Set(group).size !== group.length)) {
153
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Mode state IDs must be unique within each state set' });
154
+ }
155
+ if (stateGroups.some(group => group.some(modeId => !knownModes.has(modeId)))) {
156
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Mode state can reference only declared mode IDs' });
157
+ }
158
+ if (value.state.applied.some(modeId => !value.state.delivered.includes(modeId))) {
159
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Applied modes must be a subset of delivered modes' });
160
+ }
161
+ if (value.state.validated.some(modeId => !value.state.applied.includes(modeId))) {
162
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Validated modes must be a subset of applied modes' });
163
+ }
164
+ if (value.state.deliveredTo === 'none' && value.state.delivered.length > 0) {
165
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'No delivery target means no delivered modes' });
166
+ }
167
+ if (value.fallback.applied !== (value.state.fallback !== 'none')) {
168
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Mode state fallback must agree with receipt fallback' });
169
+ }
170
+ }
171
+ if (value.modelPrompt.execution !== 'hosted' && value.modelPrompt.hostedVersion) {
172
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Hosted uncertainty is only valid for hosted execution receipts' });
173
+ }
174
+ if ((value.fallback.applied || value.state?.fallback !== 'none') && value.state && (value.state.applied.length > 0 || value.state.validated.length > 0)) {
175
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Fallback receipts cannot report applied or validated modes' });
176
+ }
177
+ };
178
+ const receiptInputSchema = receiptInputBaseSchema.superRefine(enforceReceiptRules);
179
+ export const writingReceiptSchema = receiptInputBaseSchema.extend({ id: stableId, operationConfig: operationConfigSchema, receiptSha256: sha }).strict().superRefine(enforceReceiptRules);
180
+ export function createWritingReceipt(input) {
181
+ const parsed = receiptInputSchema.parse(input);
182
+ const defaultAction = {
183
+ 'draft-from-notes': 'draft',
184
+ 'edit-existing': 'edit',
185
+ 'proofread-only': 'proofread',
186
+ 'continue-author-text': 'continue',
187
+ }[parsed.operation];
188
+ const body = {
189
+ ...parsed,
190
+ id: parsed.id ?? `wr-${hash(JSON.stringify(canonicalize({ ...parsed, createdAt: undefined }))).slice(0, 24)}`,
191
+ operationConfig: parsed.operationConfig ?? { action: defaultAction, correctionIds: [] },
192
+ modelPrompt: parsed.modelPrompt.execution === 'hosted' && !parsed.modelPrompt.hostedVersion
193
+ ? { ...parsed.modelPrompt, hostedVersion: { attested: false, reason: 'Hosted provider prompt/version cannot be attested from this local receipt.' } }
194
+ : parsed.modelPrompt,
195
+ };
196
+ rejectSensitiveReceipt(body);
197
+ const receiptSha256 = receiptDigest(body);
198
+ return writingReceiptSchema.parse({ ...body, receiptSha256 });
199
+ }
200
+ export function validateWritingReceipt(value) {
201
+ const parsed = writingReceiptSchema.parse(value);
202
+ const { receiptSha256, ...body } = parsed;
203
+ if (receiptDigest(body) !== receiptSha256)
204
+ throw new Error('Writing receipt integrity mismatch');
205
+ rejectSensitiveReceipt(parsed);
206
+ return parsed;
207
+ }
208
+ export function writingReceiptPath(cwd, receiptId) {
209
+ if (!/^[a-z0-9][a-z0-9.-]*$/.test(receiptId))
210
+ throw new Error('Invalid writing receipt ID');
211
+ return join(resolveProjectAiwgDirForWrite(cwd), 'writing', 'receipts', `${receiptId}.json`);
212
+ }
213
+ export async function writeWritingReceipt(cwd, receiptInput) {
214
+ const receipt = validateWritingReceipt(receiptInput);
215
+ const destination = writingReceiptPath(cwd, receipt.id);
216
+ await mkdir(dirname(destination), { recursive: true, mode: 0o700 });
217
+ const payload = JSON.stringify(receipt, null, 2) + '\n';
218
+ const existing = await readFile(destination, 'utf8').catch(error => {
219
+ if (error.code === 'ENOENT')
220
+ return null;
221
+ throw error;
222
+ });
223
+ if (existing !== null) {
224
+ if (existing === payload)
225
+ return { path: destination, sha256: hash(payload) };
226
+ throw new Error('Writing receipt already exists with different content');
227
+ }
228
+ const temporary = `${destination}.${randomUUID()}.tmp`;
229
+ const lock = `${destination}.lock`;
230
+ let locked = false;
231
+ try {
232
+ await mkdir(lock, { mode: 0o700 });
233
+ locked = true;
234
+ await writeFile(temporary, payload, { mode: 0o600, flag: 'wx' });
235
+ const raced = await readFile(destination, 'utf8').catch(error => {
236
+ if (error.code === 'ENOENT')
237
+ return null;
238
+ throw error;
239
+ });
240
+ if (raced !== null) {
241
+ if (raced === payload)
242
+ return { path: destination, sha256: hash(payload) };
243
+ throw new Error('Writing receipt already exists with different content');
244
+ }
245
+ await rename(temporary, destination);
246
+ }
247
+ finally {
248
+ await rm(temporary, { force: true });
249
+ if (locked)
250
+ await rm(lock, { recursive: true, force: true });
251
+ }
252
+ return { path: destination, sha256: hash(payload) };
253
+ }
254
+ export async function readWritingReceipt(cwd, receiptId) {
255
+ const path = writingReceiptPath(cwd, receiptId);
256
+ const payload = await readFile(path, 'utf8');
257
+ let parsed;
258
+ try {
259
+ parsed = JSON.parse(payload);
260
+ }
261
+ catch {
262
+ throw new Error('Writing receipt is corrupt or not JSON');
263
+ }
264
+ return { receipt: validateWritingReceipt(parsed), path, sha256: hash(payload) };
265
+ }
266
+ //# sourceMappingURL=writing-receipt.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwg/cli",
3
- "version": "2026.9.3",
3
+ "version": "2026.9.5",
4
4
  "description": "Lightweight AIWG CLI for signed, versioned web-backed resources.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,196 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://aiwg.io/schemas/dataset/fortemi-live-qualification-receipt.v2.schema.json",
4
+ "title": "AIWG Fortemi Dataset Live Qualification Receipt v2",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "contract",
9
+ "outcome",
10
+ "diagnostic",
11
+ "receiptDigest",
12
+ "bindings",
13
+ "observed",
14
+ "namespace",
15
+ "operations",
16
+ "mutation",
17
+ "resources",
18
+ "startedAt",
19
+ "endedAt"
20
+ ],
21
+ "properties": {
22
+ "contract": {
23
+ "const": "aiwg.fortemi-dataset-live-qualification/v2"
24
+ },
25
+ "outcome": {
26
+ "enum": [
27
+ "pending",
28
+ "supported"
29
+ ]
30
+ },
31
+ "diagnostic": {
32
+ "enum": [
33
+ "CONFORMANCE_FORTEMI_DATASET_CONTRACT_UNAVAILABLE",
34
+ "CONFORMANCE_FORTEMI_DATASET_PREFLIGHT_SUPPORTED"
35
+ ]
36
+ },
37
+ "receiptDigest": {
38
+ "$ref": "#/$defs/digest"
39
+ },
40
+ "bindings": {
41
+ "type": "object",
42
+ "additionalProperties": false,
43
+ "required": [
44
+ "aiwgCommit",
45
+ "endpointFingerprint",
46
+ "toolSchemaDigest"
47
+ ],
48
+ "properties": {
49
+ "aiwgCommit": {
50
+ "type": "string",
51
+ "pattern": "^[0-9a-f]{40}$"
52
+ },
53
+ "endpointFingerprint": {
54
+ "$ref": "#/$defs/digest"
55
+ },
56
+ "toolSchemaDigest": {
57
+ "$ref": "#/$defs/digest"
58
+ }
59
+ }
60
+ },
61
+ "observed": {
62
+ "type": "object",
63
+ "additionalProperties": false,
64
+ "required": [
65
+ "serverName",
66
+ "serverVersion"
67
+ ],
68
+ "properties": {
69
+ "serverName": {
70
+ "$ref": "#/$defs/safe"
71
+ },
72
+ "serverVersion": {
73
+ "$ref": "#/$defs/safe"
74
+ }
75
+ }
76
+ },
77
+ "namespace": {
78
+ "type": "string",
79
+ "pattern": "^aiwg-dataset-qualification-[0-9a-f-]{36}$"
80
+ },
81
+ "operations": {
82
+ "type": "array",
83
+ "minItems": 1,
84
+ "maxItems": 1,
85
+ "items": {
86
+ "type": "object",
87
+ "additionalProperties": false,
88
+ "required": [
89
+ "tool",
90
+ "compatible",
91
+ "code"
92
+ ],
93
+ "properties": {
94
+ "tool": {
95
+ "const": "manage_dataset_execution"
96
+ },
97
+ "compatible": {
98
+ "type": "boolean"
99
+ },
100
+ "code": {
101
+ "enum": [
102
+ "FORTEMI_DATASET_TOOL_SCHEMA_COMPATIBLE",
103
+ "FORTEMI_DATASET_TOOL_SCHEMA_DRIFT",
104
+ "FORTEMI_DATASET_TOOL_MISSING"
105
+ ]
106
+ }
107
+ }
108
+ }
109
+ },
110
+ "mutation": {
111
+ "type": "object",
112
+ "additionalProperties": false,
113
+ "required": [
114
+ "authorized",
115
+ "attempted"
116
+ ],
117
+ "properties": {
118
+ "authorized": {
119
+ "const": false
120
+ },
121
+ "attempted": {
122
+ "const": false
123
+ }
124
+ }
125
+ },
126
+ "resources": {
127
+ "type": "object",
128
+ "additionalProperties": false,
129
+ "required": [
130
+ "maxDurationMs",
131
+ "durationMs",
132
+ "maxToolCount",
133
+ "observedToolCount",
134
+ "maxSchemaBytes",
135
+ "observedSchemaBytes",
136
+ "networkAttempts",
137
+ "toolCalls"
138
+ ],
139
+ "properties": {
140
+ "maxDurationMs": {
141
+ "type": "integer",
142
+ "minimum": 250,
143
+ "maximum": 30000
144
+ },
145
+ "durationMs": {
146
+ "type": "integer",
147
+ "minimum": 0
148
+ },
149
+ "maxToolCount": {
150
+ "const": 256
151
+ },
152
+ "observedToolCount": {
153
+ "type": "integer",
154
+ "minimum": 0,
155
+ "maximum": 256
156
+ },
157
+ "maxSchemaBytes": {
158
+ "const": 1048576
159
+ },
160
+ "observedSchemaBytes": {
161
+ "type": "integer",
162
+ "minimum": 0,
163
+ "maximum": 1048576
164
+ },
165
+ "networkAttempts": {
166
+ "const": 1
167
+ },
168
+ "toolCalls": {
169
+ "const": 0
170
+ }
171
+ }
172
+ },
173
+ "startedAt": {
174
+ "$ref": "#/$defs/time"
175
+ },
176
+ "endedAt": {
177
+ "$ref": "#/$defs/time"
178
+ }
179
+ },
180
+ "$defs": {
181
+ "digest": {
182
+ "type": "string",
183
+ "pattern": "^sha256:[0-9a-f]{64}$"
184
+ },
185
+ "safe": {
186
+ "type": "string",
187
+ "minLength": 1,
188
+ "pattern": "^[A-Za-z0-9._:/-]+$"
189
+ },
190
+ "time": {
191
+ "type": "string",
192
+ "format": "date-time",
193
+ "pattern": "Z$"
194
+ }
195
+ }
196
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "producer": "Fortemi/fortemi",
3
+ "producerIssue": 1131,
4
+ "consumerIssue": 2242,
5
+ "validationRevision": "1.0.1",
6
+ "wireSchemaVersion": "1.0.0",
7
+ "schemaSha256": "ef99ec0fb7cde6b59746c61ed80a308a25fe1a54fb3052f0f4af97798ee0af5c",
8
+ "source": "contracts/dataset-execution/validation/1.0.1/run-receipt.schema.json",
9
+ "producerCommit": "5ba6c39a7021ae30f28f4085813e8b2b88e27fd8",
10
+ "qualification": "bounded local PostgreSQL live run passed; final delivery pins pending",
11
+ "requestBindingRevision": "1.0.1"
12
+ }