@aiwg/cli 2026.10.11 → 2026.10.12
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.
- package/agentic/code/providers/model-catalog.v1.json +62 -12
- package/dist/src/artifacts/binding-target-identity.js +51 -0
- package/dist/src/artifacts/checksum-manifest.js +12 -0
- package/dist/src/artifacts/index-builder.js +11 -13
- package/dist/src/artifacts/query-engine.js +5 -11
- package/dist/src/cli/handlers/doctor-help.js +32 -0
- package/dist/src/cli/handlers/gates.js +19 -18
- package/dist/src/cli/handlers/models-help.js +7 -1
- package/dist/src/cli/handlers/models.js +3 -3
- package/dist/src/cli/handlers/script-runner.js +8 -5
- package/dist/src/cli/handlers/sessions-intake.js +104 -0
- package/dist/src/cli/handlers/sessions-tail.js +172 -0
- package/dist/src/cli/handlers/sessions.js +90 -17
- package/dist/src/cli/handlers/skill-lint.js +10 -3
- package/dist/src/cli/handlers/steward-format.js +100 -0
- package/dist/src/cli/handlers/steward-models.js +167 -0
- package/dist/src/cli/handlers/steward.js +14 -248
- package/dist/src/cli/handlers/use-bundle-counts.js +61 -0
- package/dist/src/cli/handlers/use.js +6 -24
- package/dist/src/cli/handlers/utilities.js +1 -24
- package/dist/src/config/aiwg-config.js +7 -0
- package/dist/src/config/authorization-cli.js +89 -0
- package/dist/src/config/cli-help.js +1 -0
- package/dist/src/config/cli.js +10 -1
- package/dist/src/decision/context-pruning.js +3 -2
- package/dist/src/decision/ensemble/contract.js +15 -4
- package/dist/src/decision/ensemble-study/artifacts.js +5 -0
- package/dist/src/decision/ensemble-study/score.js +4 -3
- package/dist/src/decision/feature-export.js +3 -9
- package/dist/src/decision/heldout/collector.js +2 -2
- package/dist/src/decision/issue-triage/runtime.js +3 -9
- package/dist/src/decision/qualification/gates.js +2 -1
- package/dist/src/decision/qualification/release.js +2 -3
- package/dist/src/decision/routing/report.js +2 -0
- package/dist/src/decision/sdlc-screening.js +3 -5
- package/dist/src/decision/sensitivity/comparative.js +5 -3
- package/dist/src/gates/driver.js +6 -77
- package/dist/src/gates/evaluate.js +4 -11
- package/dist/src/gates/floors.js +4 -4
- package/dist/src/gates/index.js +3 -3
- package/dist/src/gates/lattice.js +26 -0
- package/dist/src/gates/registry.js +2 -1
- package/dist/src/gates/report.js +19 -7
- package/dist/src/issues/audit-cli.js +120 -0
- package/dist/src/issues/audit-contract.js +64 -0
- package/dist/src/issues/audit-local.js +82 -0
- package/dist/src/issues/audit.js +220 -0
- package/dist/src/lint/rule-activation.js +15 -1
- package/dist/src/mission-protocol/canonical-codecs.js +270 -0
- package/dist/src/mission-protocol/codecs.js +22 -550
- package/dist/src/mission-protocol/health-trace-codecs.js +281 -0
- package/dist/src/mission-protocol/health-trace-types.js +43 -0
- package/dist/src/mission-protocol/types.js +2 -42
- package/dist/src/mission-protocol/worker-contract-json.js +10 -0
- package/dist/src/mission-protocol/worker-review-gate.js +100 -0
- package/dist/src/mission-protocol/worker-review-types.js +2 -0
- package/dist/src/models/catalog-policy.js +280 -0
- package/dist/src/models/index.js +1 -1
- package/dist/src/models/model-catalog.v1.json +62 -12
- package/dist/src/models/policy-resources.js +28 -0
- package/dist/src/models/provider-policy.js +10 -546
- package/dist/src/models/resolver.js +26 -8
- package/dist/src/models/router.js +15 -2
- package/dist/src/models/tiers.js +13 -0
- package/dist/src/models/types.js +0 -6
- package/dist/src/models/worker-ceilings.js +59 -0
- package/dist/src/models/worker-invocation-policy.js +243 -0
- package/dist/src/models/worker-plan.js +16 -20
- package/dist/src/models/worker-review-lineage.js +55 -0
- package/dist/src/models/worker-selection-policy.js +1 -1
- package/dist/src/models/wrapper-route.js +6 -3
- package/dist/src/policy/authorization.js +1 -0
- package/dist/src/policy/hitl-config.js +63 -0
- package/dist/src/policy/hitl-receipt.js +57 -0
- package/dist/src/policy/hitl-types.js +4 -0
- package/dist/src/policy/hitl-validation.js +39 -0
- package/dist/src/policy/hitl.js +117 -0
- package/dist/src/rules/activation.d.mts +1 -1
- package/dist/src/rules/activation.mjs +0 -2
- package/dist/src/rules/gate-coverage.js +51 -0
- package/dist/src/rules/gate-references.js +16 -0
- package/dist/src/rules/rule-frontmatter.schema.json +7 -1
- package/dist/src/serve/worker-command-request.js +21 -4
- package/dist/src/serve/worker-invocation-preparation.js +3 -1
- package/dist/src/serve/worker-invocation.js +21 -10
- package/dist/src/sessions/adapters/deepseek-harness.js +1 -0
- package/dist/src/sessions/adapters/grok-build-native.js +269 -0
- package/dist/src/sessions/adapters/grok-build.js +57 -15
- package/dist/src/sessions/adapters/hermes-state-db.js +252 -0
- package/dist/src/sessions/adapters/hermes.js +42 -3
- package/dist/src/sessions/adapters/warp.js +1 -1
- package/dist/src/sessions/batch-import.js +10 -0
- package/dist/src/sessions/contracts.js +1 -1
- package/dist/src/sessions/discovery-capability.js +38 -0
- package/dist/src/sessions/importer.js +8 -251
- package/dist/src/sessions/index.js +4 -0
- package/dist/src/sessions/intake-dir.js +71 -0
- package/dist/src/sessions/normalization.js +251 -0
- package/dist/src/sessions/tail.js +91 -0
- package/dist/src/sessions/workspace-discovery.js +83 -7
- package/dist/src/skills/agent-skill-sidecar.js +28 -0
- package/dist/src/skills/agent-skills.js +4 -23
- package/dist/src/skills/claude-surface-projection.js +25 -0
- package/dist/src/skills/deployer.js +8 -288
- package/dist/src/skills/deployment-policy.js +114 -0
- package/dist/src/skills/deployment-projection.js +152 -0
- package/dist/src/skills/deployment-types.js +20 -0
- package/dist/src/skills/exporter.js +8 -31
- package/dist/src/skills/provider-extensions.js +41 -0
- package/dist/src/skills/run.js +6 -0
- package/dist/src/skills/types.js +0 -8
- package/dist/src/skills/validator-resources.js +68 -0
- package/dist/src/skills/validator.js +6 -55
- package/dist/src/storage/cli-migrate-options.js +125 -0
- package/dist/src/storage/cli-migrate.js +111 -0
- package/dist/src/storage/cli.js +4 -279
- package/dist/src/storage/migration-adapter.js +79 -0
- package/dist/src/storage/migration-copy.js +108 -0
- package/dist/src/storage/migration-protocol.js +14 -197
- package/dist/src/storage/migration-records.js +186 -0
- package/dist/src/storage/migration-types.js +12 -0
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/tracker/issue-pages.js +110 -0
- package/package.json +1 -1
- package/schemas/mission-v1.schema.json +335 -0
- package/schemas/models/model-catalog.v1.schema.json +19 -1
- package/schemas/models/model-config-compatibility.v1.schema.json +3 -2
- package/schemas/models/model-policy.v1.schema.json +1 -1
- package/tools/agents/providers/provider-paths-staging.mjs +35 -0
- package/tools/agents/providers/rule-binding-targets.mjs +146 -0
- package/tools/agents/providers/rule-delivery.mjs +7 -126
- package/vscode-extension/schemas/aiwg.config.v1.json +177 -0
|
@@ -6,12 +6,14 @@ import { resolveRuleBindingTarget } from '../artifacts/query-engine.js';
|
|
|
6
6
|
import { collectRuleBindingEntries } from '../artifacts/index-builder.js';
|
|
7
7
|
import { resolveFrameworkIndexRoot } from '../artifacts/framework-index-paths.js';
|
|
8
8
|
import { parseRuleFrontmatter, RULE_BINDING_TYPES, coreBodyPath, validateCoreBody } from '../rules/activation.mjs';
|
|
9
|
+
import { buildGatesRegistry } from '../gates/driver.js';
|
|
10
|
+
import { ruleGateReferenceErrors } from '../rules/gate-references.js';
|
|
9
11
|
export const ruleActivationRuleset = {
|
|
10
12
|
id: 'rule-activation', name: 'Rule activation', framework: 'core', version: '1.0.0',
|
|
11
13
|
description: 'Validate rule and behavior activation contracts and exact source bindings',
|
|
12
14
|
rules: [{
|
|
13
15
|
id: 'rules/activation', name: 'Rule activation contract', severity: 'error',
|
|
14
|
-
description: 'Validate activation, summaries, paths, bindings, and migration fallback',
|
|
16
|
+
description: 'Validate activation, summaries, paths, bindings, gate references, and migration fallback',
|
|
15
17
|
appliesTo: { glob: '**/{rules/**/*.md,behaviors/**/BEHAVIOR.md}' },
|
|
16
18
|
checks: [{ type: 'rule-activation' }],
|
|
17
19
|
}],
|
|
@@ -38,6 +40,18 @@ export function lintRuleActivation(content, file, projectRoot, entries = [], abs
|
|
|
38
40
|
}));
|
|
39
41
|
if (!result.rule)
|
|
40
42
|
return diagnostics;
|
|
43
|
+
if (result.rule.enforcedBy?.length) {
|
|
44
|
+
let errors;
|
|
45
|
+
try {
|
|
46
|
+
const { registry } = buildGatesRegistry({ cwd: projectRoot, aiwgRoot: resolveFrameworkIndexRoot(projectRoot) });
|
|
47
|
+
errors = ruleGateReferenceErrors(result.rule.enforcedBy, registry);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
errors = [`enforcedBy registry: ${error instanceof Error ? error.message : String(error)}`];
|
|
51
|
+
}
|
|
52
|
+
for (const message of errors)
|
|
53
|
+
diagnostics.push({ ruleId: 'rules/activation', ruleName: 'Rule activation contract', file, severity: 'error', message });
|
|
54
|
+
}
|
|
41
55
|
if (result.rule.activation === 'core') {
|
|
42
56
|
const body = coreBodyPath(absolutePath ?? (path.isAbsolute(file) ? file : path.resolve(projectRoot, file)));
|
|
43
57
|
const problems = fs.existsSync(body)
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// Canonical Mission projections and legacy transport codecs.
|
|
2
|
+
import { assertMissionWorkerHandoff } from './codecs.js';
|
|
3
|
+
import { MISSION_API_VERSION } from './types.js';
|
|
4
|
+
const TERMINAL = new Set(['completed', 'failed', 'incomplete', 'cancelled']);
|
|
5
|
+
function object(value, label = 'Mission input') {
|
|
6
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
7
|
+
throw new Error(`${label} must be an object.`);
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
function string(value) {
|
|
11
|
+
return typeof value === 'string' && value.length ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
function requiredId(record) {
|
|
14
|
+
const metadata = record.metadata && typeof record.metadata === 'object' ? record.metadata : {};
|
|
15
|
+
const id = string(record.missionId) ?? string(record.mission_id) ?? string(record.id)
|
|
16
|
+
?? string(record.taskId) ?? string(record.task_id) ?? string(record.responseId) ?? string(metadata.id);
|
|
17
|
+
if (!id)
|
|
18
|
+
throw new Error('Mission source is missing a stable identifier.');
|
|
19
|
+
return id;
|
|
20
|
+
}
|
|
21
|
+
export function normalizeMissionState(nativeState) {
|
|
22
|
+
const state = String(nativeState ?? 'unknown').toLowerCase().replace(/_/g, '-');
|
|
23
|
+
if (['done', 'completed', 'succeeded', 'success'].includes(state))
|
|
24
|
+
return 'completed';
|
|
25
|
+
if (['aborted', 'cancelled', 'canceled'].includes(state))
|
|
26
|
+
return 'cancelled';
|
|
27
|
+
if (['failed', 'error', 'rejected', 'timed-out'].includes(state))
|
|
28
|
+
return 'failed';
|
|
29
|
+
if (['incomplete', 'budget-exhausted', 'max-iterations', 'max-tokens'].includes(state))
|
|
30
|
+
return 'incomplete';
|
|
31
|
+
if (['running', 'in-progress', 'working', 'started', 'assigned', 'admitted', 'starting'].includes(state))
|
|
32
|
+
return 'running';
|
|
33
|
+
if (['pending', 'submitted', 'queued', 'runnable', 'scheduled'].includes(state))
|
|
34
|
+
return 'pending';
|
|
35
|
+
if (['blocked', 'blocked-hitl', 'input-required', 'auth-required', 'paused', 'suspended'].includes(state))
|
|
36
|
+
return 'blocked';
|
|
37
|
+
if (['operator-review', 'operator-review-required', 'manual-review'].includes(state))
|
|
38
|
+
return 'operator-review';
|
|
39
|
+
if (['unknown', 'disconnected', 'detached', 'unreachable'].includes(state))
|
|
40
|
+
return 'unknown';
|
|
41
|
+
return 'unknown';
|
|
42
|
+
}
|
|
43
|
+
function knownKeysFor(source) {
|
|
44
|
+
const common = ['id', 'missionId', 'mission_id', 'taskId', 'task_id', 'responseId', 'title', 'goal', 'objective', 'prompt', 'completion', 'completionCriterion', 'completion_criterion', 'status', 'state', 'nativeState', 'createdAt', 'created_at', 'updatedAt', 'updated_at', 'metadata', 'spec', 'provenance', 'extensions', 'artifacts', 'output', 'partialOutput', 'error', 'checkpoint', 'cycles', 'activityLog', 'totalCost', 'runtimesUsed', 'apiVersion', 'api_version', 'schemaVersion', 'schema_version', 'kind', 'session_id', 'previous_response_id'];
|
|
45
|
+
if (source === 'uhp-2026-08-11')
|
|
46
|
+
common.push('object', 'model', 'incomplete_details', 'store', 'usage');
|
|
47
|
+
return new Set(common);
|
|
48
|
+
}
|
|
49
|
+
function extensions(record, source) {
|
|
50
|
+
const explicit = record.extensions && typeof record.extensions === 'object' ? structuredClone(record.extensions) : {};
|
|
51
|
+
if (record.metadata && typeof record.metadata === 'object')
|
|
52
|
+
explicit.metadata = structuredClone(record.metadata);
|
|
53
|
+
if (record.status && typeof record.status === 'object')
|
|
54
|
+
explicit.nativeStatus = structuredClone(record.status);
|
|
55
|
+
for (const [key, value] of Object.entries(record))
|
|
56
|
+
if (!knownKeysFor(source).has(key))
|
|
57
|
+
explicit[key] = structuredClone(value);
|
|
58
|
+
return explicit;
|
|
59
|
+
}
|
|
60
|
+
function artifacts(record) {
|
|
61
|
+
const values = Array.isArray(record.artifacts) ? record.artifacts : [];
|
|
62
|
+
return values.flatMap((item, index) => {
|
|
63
|
+
if (!item || typeof item !== 'object')
|
|
64
|
+
return [];
|
|
65
|
+
const artifact = item;
|
|
66
|
+
const id = string(artifact.id) ?? string(artifact.fileId) ?? string(artifact.file_id) ?? string(artifact.uri) ?? `artifact-${index}`;
|
|
67
|
+
return [{
|
|
68
|
+
id,
|
|
69
|
+
kind: string(artifact.kind) ?? 'other',
|
|
70
|
+
...(string(artifact.uri) ? { uri: string(artifact.uri) } : {}),
|
|
71
|
+
...(string(artifact.sha256) ? { sha256: string(artifact.sha256) } : {}),
|
|
72
|
+
...(string(artifact.mediaType) ?? string(artifact.media_type) ? { mediaType: string(artifact.mediaType) ?? string(artifact.media_type) } : {}),
|
|
73
|
+
extensions: structuredClone(artifact),
|
|
74
|
+
}];
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function uhpOutputArtifacts(record) {
|
|
78
|
+
const found = new Map();
|
|
79
|
+
function visit(value) {
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
value.forEach(visit);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!value || typeof value !== 'object')
|
|
85
|
+
return;
|
|
86
|
+
const item = value;
|
|
87
|
+
const id = string(item.file_id);
|
|
88
|
+
if (id)
|
|
89
|
+
found.set(id, { id, kind: 'uhp-file', ...(string(item.media_type) ? { mediaType: string(item.media_type) } : {}), extensions: { 'uhp.file': structuredClone(item) } });
|
|
90
|
+
Object.values(item).forEach(visit);
|
|
91
|
+
}
|
|
92
|
+
visit(record.output);
|
|
93
|
+
return [...found.values()];
|
|
94
|
+
}
|
|
95
|
+
function nativeStateFor(source, record, statusRecord) {
|
|
96
|
+
const explicit = string(statusRecord.state) ?? string(record.nativeState) ?? string(record.status)
|
|
97
|
+
?? string(record.state) ?? string(record.observed_state) ?? string(record.observedState) ?? string(record.nodeState);
|
|
98
|
+
if (explicit)
|
|
99
|
+
return explicit;
|
|
100
|
+
if (source === 'mission-ledger' && record.checkpoint && typeof record.checkpoint === 'object') {
|
|
101
|
+
const checkpoint = record.checkpoint;
|
|
102
|
+
if (Array.isArray(checkpoint.pending) && checkpoint.pending.length)
|
|
103
|
+
return 'running';
|
|
104
|
+
if (Array.isArray(checkpoint.failed) && checkpoint.failed.length)
|
|
105
|
+
return 'failed';
|
|
106
|
+
if (Array.isArray(checkpoint.completed) && checkpoint.completed.length)
|
|
107
|
+
return 'completed';
|
|
108
|
+
}
|
|
109
|
+
return 'unknown';
|
|
110
|
+
}
|
|
111
|
+
function sourceVersion(source, record) {
|
|
112
|
+
if (source === 'canonical')
|
|
113
|
+
return string(record.apiVersion) ?? 'unknown';
|
|
114
|
+
if (source === 'uhp-2026-08-11')
|
|
115
|
+
return '2026-08-11';
|
|
116
|
+
if (source === 'executor-v1')
|
|
117
|
+
return 'executor.aiwg.io/v1';
|
|
118
|
+
if (source === 'fleet-workload-v1')
|
|
119
|
+
return 'fleet-workload/v1';
|
|
120
|
+
if (source === 'graph-flow-v1')
|
|
121
|
+
return 'graph.flow.aiwg.io/v1';
|
|
122
|
+
if (source === 'activity-v1')
|
|
123
|
+
return 'activity.aiwg.io/v1';
|
|
124
|
+
return string(record.apiVersion) ?? string(record.api_version) ?? string(record.schemaVersion) ?? string(record.schema_version) ?? 'unversioned';
|
|
125
|
+
}
|
|
126
|
+
function assertSupported(version) {
|
|
127
|
+
const supported = new Set(['unversioned', MISSION_API_VERSION, '2026-08-11', 'executor.aiwg.io/v1', 'fleet-workload/v1', 'graph.flow.aiwg.io/v1', 'activity.aiwg.io/v1']);
|
|
128
|
+
if (supported.has(version))
|
|
129
|
+
return;
|
|
130
|
+
const major = version.match(/(?:^|\/)v(\d+)(?:$|[.-])/)?.[1];
|
|
131
|
+
if (major && major !== '1')
|
|
132
|
+
throw new Error(`Unsupported Mission source major version '${version}'; supported major is v1.`);
|
|
133
|
+
throw new Error(`Unsupported Mission source version '${version}'.`);
|
|
134
|
+
}
|
|
135
|
+
export function validateCanonicalMission(value) {
|
|
136
|
+
const record = object(value, 'Canonical Mission');
|
|
137
|
+
assertMissionWorkerHandoff(record, 'canonical');
|
|
138
|
+
if (record.apiVersion !== MISSION_API_VERSION)
|
|
139
|
+
throw new Error(`Unsupported canonical Mission version '${String(record.apiVersion)}'.`);
|
|
140
|
+
if (record.kind !== 'Mission')
|
|
141
|
+
throw new Error("Canonical Mission kind must be 'Mission'.");
|
|
142
|
+
const metadata = object(record.metadata, 'Mission metadata');
|
|
143
|
+
const spec = object(record.spec, 'Mission spec');
|
|
144
|
+
const status = object(record.status, 'Mission status');
|
|
145
|
+
const provenance = object(record.provenance, 'Mission provenance');
|
|
146
|
+
if (!string(metadata.id) || !string(spec.objective) || !string(provenance.sourceContract) || !string(provenance.sourceVersion))
|
|
147
|
+
throw new Error('Canonical Mission is missing required identity, objective, or provenance.');
|
|
148
|
+
const state = normalizeMissionState(status.state);
|
|
149
|
+
if (status.state !== state)
|
|
150
|
+
throw new Error(`Canonical Mission state '${String(status.state)}' is not normalized.`);
|
|
151
|
+
if (status.terminal !== TERMINAL.has(state))
|
|
152
|
+
throw new Error(`Canonical Mission terminal flag contradicts state '${state}'.`);
|
|
153
|
+
if (!Array.isArray(status.artifacts))
|
|
154
|
+
throw new Error('Canonical Mission artifacts must be an array.');
|
|
155
|
+
return structuredClone(value);
|
|
156
|
+
}
|
|
157
|
+
export function decodeMission(input, source, workerConsumer) {
|
|
158
|
+
const record = object(input);
|
|
159
|
+
assertMissionWorkerHandoff(record, source, workerConsumer);
|
|
160
|
+
if (source === 'canonical') {
|
|
161
|
+
const value = validateCanonicalMission(record);
|
|
162
|
+
return { value, sourceVersion: MISSION_API_VERSION, warnings: [], preservedExtensions: structuredClone(value.extensions ?? {}), lossReport: [] };
|
|
163
|
+
}
|
|
164
|
+
const version = sourceVersion(source, record);
|
|
165
|
+
assertSupported(version);
|
|
166
|
+
const statusRecord = record.status && typeof record.status === 'object' ? record.status : {};
|
|
167
|
+
const nativeState = nativeStateFor(source, record, statusRecord);
|
|
168
|
+
const state = normalizeMissionState(nativeState);
|
|
169
|
+
const objective = string(record.goal) ?? string(record.objective) ?? string(record.title) ?? string(record.prompt) ?? '(legacy mission objective unavailable)';
|
|
170
|
+
const completionCriterion = string(record.completionCriterion) ?? string(record.completion_criterion) ?? string(record.completion);
|
|
171
|
+
const preserved = extensions(record, source);
|
|
172
|
+
const warnings = [];
|
|
173
|
+
const lossReport = [];
|
|
174
|
+
if (objective.startsWith('(legacy'))
|
|
175
|
+
warnings.push('Source did not contain a mission objective; placeholder retained.');
|
|
176
|
+
if (state === 'unknown' && nativeState !== 'unknown')
|
|
177
|
+
warnings.push(`Unknown native state '${nativeState}' preserved beside normalized unknown state.`);
|
|
178
|
+
const sourceArtifacts = artifacts(record);
|
|
179
|
+
if (source === 'uhp-2026-08-11') {
|
|
180
|
+
const ids = new Set(sourceArtifacts.map(artifact => artifact.id));
|
|
181
|
+
for (const artifact of uhpOutputArtifacts(record))
|
|
182
|
+
if (!ids.has(artifact.id))
|
|
183
|
+
sourceArtifacts.push(artifact);
|
|
184
|
+
}
|
|
185
|
+
const budgets = record.budgets && typeof record.budgets === 'object' ? record.budgets : undefined;
|
|
186
|
+
const lineage = Array.isArray(record.lineage) ? record.lineage.flatMap(item => {
|
|
187
|
+
if (!item || typeof item !== 'object')
|
|
188
|
+
return [];
|
|
189
|
+
const entry = item;
|
|
190
|
+
return string(entry.relation) && string(entry.id) ? [{ relation: string(entry.relation), id: string(entry.id) }] : [];
|
|
191
|
+
}) : undefined;
|
|
192
|
+
const value = {
|
|
193
|
+
apiVersion: MISSION_API_VERSION,
|
|
194
|
+
kind: 'Mission',
|
|
195
|
+
metadata: {
|
|
196
|
+
id: requiredId(record),
|
|
197
|
+
...(string(record.createdAt) ?? string(record.created_at) ? { createdAt: string(record.createdAt) ?? string(record.created_at) } : {}),
|
|
198
|
+
...(string(record.updatedAt) ?? string(record.updated_at) ? { updatedAt: string(record.updatedAt) ?? string(record.updated_at) } : {}),
|
|
199
|
+
...(string(record.previous_response_id) ? { previousId: string(record.previous_response_id) } : {}),
|
|
200
|
+
...(lineage?.length ? { lineage } : {}),
|
|
201
|
+
},
|
|
202
|
+
spec: { objective, ...(completionCriterion ? { completionCriterion } : {}), ...(budgets ? { budgets: structuredClone(budgets) } : {}) },
|
|
203
|
+
status: {
|
|
204
|
+
state,
|
|
205
|
+
terminal: TERMINAL.has(state),
|
|
206
|
+
nativeState,
|
|
207
|
+
artifacts: sourceArtifacts,
|
|
208
|
+
...(record.output !== undefined || record.partialOutput !== undefined || record.partial_output !== undefined ? { partialOutput: structuredClone(record.partialOutput ?? record.partial_output ?? record.output) } : {}),
|
|
209
|
+
},
|
|
210
|
+
provenance: { sourceContract: source, sourceVersion: version, ...(source === 'a2a' || source.startsWith('uhp') ? { transport: source.split('-')[0] } : {}), sourceId: requiredId(record) },
|
|
211
|
+
...(Object.keys(preserved).length ? { extensions: { [`aiwg.source.${source}`]: preserved } } : {}),
|
|
212
|
+
};
|
|
213
|
+
return { value, sourceVersion: version, warnings, preservedExtensions: preserved, lossReport };
|
|
214
|
+
}
|
|
215
|
+
function projectionLosses(value, target) {
|
|
216
|
+
const losses = [];
|
|
217
|
+
if (value.status.verification?.length)
|
|
218
|
+
losses.push({ path: '/status/verification', reason: `${target} has no native verification ledger`, severity: 'warning' });
|
|
219
|
+
if (value.metadata.lineage?.length && !['mission-ledger', 'fleet-workload-v1', 'canonical'].includes(target))
|
|
220
|
+
losses.push({ path: '/metadata/lineage', reason: `${target} cannot represent full lineage`, severity: 'required' });
|
|
221
|
+
if (value.spec.budgets && !['fleet-workload-v1', 'canonical'].includes(target))
|
|
222
|
+
losses.push({ path: '/spec/budgets', reason: `${target} cannot represent every canonical budget`, severity: 'warning' });
|
|
223
|
+
return losses;
|
|
224
|
+
}
|
|
225
|
+
export function encodeMission(value, target, options = {}) {
|
|
226
|
+
assertMissionWorkerHandoff(value, target, options.workerConsumer);
|
|
227
|
+
const mission = validateCanonicalMission(value);
|
|
228
|
+
if (target === 'canonical')
|
|
229
|
+
return { value: mission, targetVersion: MISSION_API_VERSION, warnings: [], lossReport: [] };
|
|
230
|
+
const lossReport = projectionLosses(mission, target);
|
|
231
|
+
const required = lossReport.filter(loss => loss.severity === 'required');
|
|
232
|
+
if (required.length && !options.allowLoss)
|
|
233
|
+
throw new Error(`Projection to ${target} would silently lose required semantics: ${required.map(loss => loss.path).join(', ')}.`);
|
|
234
|
+
const base = {
|
|
235
|
+
missionId: mission.metadata.id,
|
|
236
|
+
goal: mission.spec.objective,
|
|
237
|
+
completionCriterion: mission.spec.completionCriterion,
|
|
238
|
+
status: mission.status.nativeState ?? mission.status.state,
|
|
239
|
+
artifacts: structuredClone(mission.status.artifacts),
|
|
240
|
+
partialOutput: structuredClone(mission.status.partialOutput),
|
|
241
|
+
lineage: structuredClone(mission.metadata.lineage ?? []),
|
|
242
|
+
extensions: {
|
|
243
|
+
'aiwg.mission.canonical': { apiVersion: mission.apiVersion, state: mission.status.state, lossReport },
|
|
244
|
+
...(mission.extensions ?? {}),
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
let projected = base;
|
|
248
|
+
if (target === 'mission-plan')
|
|
249
|
+
projected = { missionId: base.missionId, goal: base.goal, completionCriterion: base.completionCriterion ?? '', cycles: [], extensions: base.extensions };
|
|
250
|
+
else if (target === 'mission-ledger')
|
|
251
|
+
projected = { ...base, activityLog: [], cycles: [], totalCost: 0, checkpoint: { completed: [], pending: [], failed: [] }, runtimesUsed: [] };
|
|
252
|
+
else if (target === 'uhp-2026-08-11')
|
|
253
|
+
projected = { id: mission.provenance.sourceId ?? mission.metadata.id, object: 'response', created_at: 0, status: base.status, model: '', output: mission.status.partialOutput ?? [], metadata: base.extensions };
|
|
254
|
+
else if (target === 'a2a')
|
|
255
|
+
projected = { id: mission.provenance.sourceId ?? mission.metadata.id, status: { state: base.status }, artifacts: base.artifacts, partialOutput: base.partialOutput, metadata: base.extensions };
|
|
256
|
+
else if (target === 'graph-flow-v1')
|
|
257
|
+
projected = { schemaVersion: 'graph.flow.aiwg.io/v1', runId: mission.metadata.id, nodeState: mission.status.state, metadata: base.extensions };
|
|
258
|
+
else if (target === 'cockpit')
|
|
259
|
+
projected = { id: mission.metadata.id, session_id: mission.metadata.id, source: mission.provenance.transport ?? mission.provenance.sourceContract, title: mission.spec.objective, completion: mission.spec.completionCriterion, status: mission.status.state, artifacts: base.artifacts, partialOutput: base.partialOutput, extensions: base.extensions };
|
|
260
|
+
else if (target === 'activity-v1')
|
|
261
|
+
projected = { event: 'mission.projected', missionId: mission.metadata.id, objective: mission.spec.objective, state: mission.status.state, metadata: base.extensions };
|
|
262
|
+
else if (target === 'executor-v1')
|
|
263
|
+
projected = { mission_id: mission.metadata.id, objective: mission.spec.objective, completion_criterion: mission.spec.completionCriterion, state: base.status, artifacts: base.artifacts, partial_output: base.partialOutput, metadata: base.extensions };
|
|
264
|
+
else if (target === 'fleet-workload-v1')
|
|
265
|
+
projected = { mission_id: mission.metadata.id, objective: mission.spec.objective, completion_criterion: mission.spec.completionCriterion, observed_state: base.status, budgets: mission.spec.budgets, artifacts: base.artifacts, partial_output: base.partialOutput, lineage: base.lineage, metadata: base.extensions };
|
|
266
|
+
else if (target === 'mission-control-session')
|
|
267
|
+
projected = { id: mission.metadata.id, objective: mission.spec.objective, status: mission.status.state, completion: mission.spec.completionCriterion, artifacts: base.artifacts, partialOutput: base.partialOutput, extensions: base.extensions };
|
|
268
|
+
return { value: projected, targetVersion: target, warnings: lossReport.map(loss => `${loss.path}: ${loss.reason}`), lossReport };
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=canonical-codecs.js.map
|