@cleocode/contracts 2026.5.122 → 2026.5.124
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/dist/__tests__/completion-operation-contracts.test.d.ts +8 -0
- package/dist/__tests__/completion-operation-contracts.test.d.ts.map +1 -0
- package/dist/__tests__/completion-operation-contracts.test.js +114 -0
- package/dist/__tests__/completion-operation-contracts.test.js.map +1 -0
- package/dist/__tests__/operation-envelope-validation.test.d.ts +8 -0
- package/dist/__tests__/operation-envelope-validation.test.d.ts.map +1 -0
- package/dist/__tests__/operation-envelope-validation.test.js +105 -0
- package/dist/__tests__/operation-envelope-validation.test.js.map +1 -0
- package/dist/__tests__/satisfies-atom.test.js +21 -3
- package/dist/__tests__/satisfies-atom.test.js.map +1 -1
- package/dist/__tests__/workgraph-context-scaffold-contracts.test.d.ts +8 -0
- package/dist/__tests__/workgraph-context-scaffold-contracts.test.d.ts.map +1 -0
- package/dist/__tests__/workgraph-context-scaffold-contracts.test.js +188 -0
- package/dist/__tests__/workgraph-context-scaffold-contracts.test.js.map +1 -0
- package/dist/__tests__/workgraph-operation-contracts.test.d.ts +8 -0
- package/dist/__tests__/workgraph-operation-contracts.test.d.ts.map +1 -0
- package/dist/__tests__/workgraph-operation-contracts.test.js +115 -0
- package/dist/__tests__/workgraph-operation-contracts.test.js.map +1 -0
- package/dist/data-accessor.d.ts +77 -0
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/dispatch/__tests__/docs-update-registry.test.d.ts +2 -0
- package/dist/dispatch/__tests__/docs-update-registry.test.d.ts.map +1 -0
- package/dist/dispatch/__tests__/docs-update-registry.test.js +27 -0
- package/dist/dispatch/__tests__/docs-update-registry.test.js.map +1 -0
- package/dist/dispatch/__tests__/operation-envelope-snapshots.test.d.ts +2 -0
- package/dist/dispatch/__tests__/operation-envelope-snapshots.test.d.ts.map +1 -0
- package/dist/dispatch/__tests__/operation-envelope-snapshots.test.js +271 -0
- package/dist/dispatch/__tests__/operation-envelope-snapshots.test.js.map +1 -0
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +487 -7
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/evidence-atom-schema.d.ts +4 -4
- package/dist/evidence-atom-schema.d.ts.map +1 -1
- package/dist/evidence-atom-schema.js +9 -9
- package/dist/evidence-atom-schema.js.map +1 -1
- package/dist/index.d.ts +12 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/operation-envelope-validation.d.ts +79 -0
- package/dist/operation-envelope-validation.d.ts.map +1 -0
- package/dist/operation-envelope-validation.js +219 -0
- package/dist/operation-envelope-validation.js.map +1 -0
- package/dist/operations/__tests__/agent-operation-contract.test.d.ts +2 -0
- package/dist/operations/__tests__/agent-operation-contract.test.d.ts.map +1 -0
- package/dist/operations/__tests__/agent-operation-contract.test.js +128 -0
- package/dist/operations/__tests__/agent-operation-contract.test.js.map +1 -0
- package/dist/operations/__tests__/tasks-input-contracts.test.js +15 -0
- package/dist/operations/__tests__/tasks-input-contracts.test.js.map +1 -1
- package/dist/operations/agent-operation-contract.d.ts +227 -0
- package/dist/operations/agent-operation-contract.d.ts.map +1 -0
- package/dist/operations/agent-operation-contract.js +38 -0
- package/dist/operations/agent-operation-contract.js.map +1 -0
- package/dist/operations/docs.d.ts +19 -1
- package/dist/operations/docs.d.ts.map +1 -1
- package/dist/operations/docs.js +20 -0
- package/dist/operations/docs.js.map +1 -1
- package/dist/operations/focus.d.ts +1 -1
- package/dist/operations/index.d.ts +1 -0
- package/dist/operations/index.d.ts.map +1 -1
- package/dist/operations/index.js +1 -0
- package/dist/operations/index.js.map +1 -1
- package/dist/operations/orchestrate.d.ts +66 -0
- package/dist/operations/orchestrate.d.ts.map +1 -1
- package/dist/operations/tasks.d.ts +568 -11
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js +22 -3
- package/dist/operations/tasks.js.map +1 -1
- package/dist/task-record.d.ts +15 -0
- package/dist/task-record.d.ts.map +1 -1
- package/dist/task.d.ts +15 -6
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js.map +1 -1
- package/dist/tasks.d.ts +944 -0
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +198 -1
- package/dist/tasks.js.map +1 -1
- package/dist/workgraph.d.ts +1950 -0
- package/dist/workgraph.d.ts.map +1 -0
- package/dist/workgraph.js +449 -0
- package/dist/workgraph.js.map +1 -0
- package/package.json +10 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/__tests__/completion-operation-contracts.test.ts +154 -0
- package/src/__tests__/operation-envelope-validation.test.ts +140 -0
- package/src/__tests__/satisfies-atom.test.ts +23 -3
- package/src/__tests__/workgraph-context-scaffold-contracts.test.ts +232 -0
- package/src/__tests__/workgraph-operation-contracts.test.ts +151 -0
- package/src/data-accessor.ts +94 -1
- package/src/dispatch/__tests__/docs-update-registry.test.ts +35 -0
- package/src/dispatch/__tests__/operation-envelope-snapshots.test.ts +289 -0
- package/src/dispatch/operations-registry.ts +502 -7
- package/src/evidence-atom-schema.ts +10 -10
- package/src/index.ts +193 -2
- package/src/operation-envelope-validation.ts +319 -0
- package/src/operations/__tests__/agent-operation-contract.test.ts +161 -0
- package/src/operations/__tests__/tasks-input-contracts.test.ts +30 -0
- package/src/operations/agent-operation-contract.ts +253 -0
- package/src/operations/docs.ts +27 -7
- package/src/operations/focus.ts +1 -1
- package/src/operations/index.ts +1 -0
- package/src/operations/orchestrate.ts +71 -0
- package/src/operations/tasks.ts +612 -15
- package/src/task-record.ts +16 -0
- package/src/task.ts +16 -6
- package/src/tasks.ts +558 -0
- package/src/workgraph.ts +1153 -0
package/src/index.ts
CHANGED
|
@@ -199,7 +199,7 @@ export {
|
|
|
199
199
|
} from './branch-lock.js';
|
|
200
200
|
export type { AdapterCapabilities } from './capabilities.js';
|
|
201
201
|
// === Changesets (CLEO-native task-anchored DSL — T9738) ===
|
|
202
|
-
export type { ChangesetEntry, ChangesetKind } from './changesets.js';
|
|
202
|
+
export type { ChangesetEntry, ChangesetKind, ChangesetReleaseNoteSection } from './changesets.js';
|
|
203
203
|
export { CHANGESET_KINDS, ChangesetEntrySchema } from './changesets.js';
|
|
204
204
|
// === CLI Category Types (help renderer grouping SSoT) ===
|
|
205
205
|
export type { CliCategory } from './cli-category.js';
|
|
@@ -291,12 +291,18 @@ export { parseClaudeCodeCredentials } from './credentials.js';
|
|
|
291
291
|
// === DataAccessor Interface ===
|
|
292
292
|
export type {
|
|
293
293
|
AcBindingRow,
|
|
294
|
+
AcProjectionAuditFinding,
|
|
295
|
+
AcProjectionAuditFindingCode,
|
|
296
|
+
AcProjectionAuditResult,
|
|
297
|
+
AcProjectionAuditStatus,
|
|
294
298
|
AcRow,
|
|
295
299
|
ArchiveFields,
|
|
296
300
|
ArchiveFile,
|
|
297
301
|
DataAccessor,
|
|
298
302
|
DataAccessorAgentInstance,
|
|
299
303
|
QueryTasksResult,
|
|
304
|
+
TaskAuditLogQuery,
|
|
305
|
+
TaskAuditLogRow,
|
|
300
306
|
TaskFieldUpdates,
|
|
301
307
|
TaskQueryFilters,
|
|
302
308
|
TransactionAccessor,
|
|
@@ -841,6 +847,20 @@ export type {
|
|
|
841
847
|
WikiStateFile,
|
|
842
848
|
WikiSymbolRow,
|
|
843
849
|
} from './nexus-wiki-ops.js';
|
|
850
|
+
// === Operation-aware LAFS envelope validation (T10610) ===
|
|
851
|
+
export type {
|
|
852
|
+
OperationEnvelopeName,
|
|
853
|
+
OperationEnvelopeValidationIssue,
|
|
854
|
+
OperationEnvelopeValidationOptions,
|
|
855
|
+
OperationEnvelopeValidationResult,
|
|
856
|
+
} from './operation-envelope-validation.js';
|
|
857
|
+
export {
|
|
858
|
+
E_LAFS_OPERATION_ERROR_SHAPE,
|
|
859
|
+
E_LAFS_OPERATION_RESULT_SCHEMA,
|
|
860
|
+
E_LAFS_OPERATION_UNREGISTERED,
|
|
861
|
+
OPERATION_RESULT_SCHEMAS,
|
|
862
|
+
validateOperationEnvelope,
|
|
863
|
+
} from './operation-envelope-validation.js';
|
|
844
864
|
// Admin operation param/result types — re-exported at top level for typed-dispatch consumers
|
|
845
865
|
// (T1426 Wave D · typed-narrowing migration for admin domain)
|
|
846
866
|
export type {
|
|
@@ -926,6 +946,14 @@ export type {
|
|
|
926
946
|
EvaluateDialecticParams,
|
|
927
947
|
EvaluateDialecticResult,
|
|
928
948
|
} from './operations/dialectic.js';
|
|
949
|
+
// === Docs Operation Types (T10618 — docs.update lifecycle status SSoT) ===
|
|
950
|
+
// Re-exported at top level so core and CLI layers can consume the same
|
|
951
|
+
// operation contract without relying on an unexported package subpath.
|
|
952
|
+
export {
|
|
953
|
+
DOCS_LIFECYCLE_STATUSES,
|
|
954
|
+
type DocsLifecycleStatus,
|
|
955
|
+
type DocsUpdateParams,
|
|
956
|
+
} from './operations/docs.js';
|
|
929
957
|
// === Operations Types (API wire format, namespaced to avoid collision with domain types) ===
|
|
930
958
|
export * as ops from './operations/index.js';
|
|
931
959
|
// === Operation Input Contracts (T9914 / Saga T9855 / E7) ===
|
|
@@ -1203,7 +1231,12 @@ export type {
|
|
|
1203
1231
|
UserProfileTrait,
|
|
1204
1232
|
} from './operations/nexus-user-profile.js';
|
|
1205
1233
|
// Commonly used ops types re-exported at top level for convenience
|
|
1206
|
-
export type {
|
|
1234
|
+
export type {
|
|
1235
|
+
BrainState,
|
|
1236
|
+
OrchestrateReportEntry,
|
|
1237
|
+
OrchestrateReportGroup,
|
|
1238
|
+
OrchestrateReportParams,
|
|
1239
|
+
} from './operations/orchestrate.js';
|
|
1207
1240
|
// ParamDef contract — re-exported at top level (SSoT for all operation param descriptors)
|
|
1208
1241
|
export type {
|
|
1209
1242
|
CittyArgDef,
|
|
@@ -1288,6 +1321,7 @@ export type {
|
|
|
1288
1321
|
DepsTreeNode,
|
|
1289
1322
|
TaskShowAcRowEntry,
|
|
1290
1323
|
TaskShowAttachmentEntry,
|
|
1324
|
+
TaskShowRelationsEntry,
|
|
1291
1325
|
TasksAddBatchEntry,
|
|
1292
1326
|
TasksAddBatchParams,
|
|
1293
1327
|
TasksAddBatchResult,
|
|
@@ -1307,6 +1341,15 @@ export type {
|
|
|
1307
1341
|
TasksCompleteQueryResult,
|
|
1308
1342
|
TasksComplexityEstimateParams,
|
|
1309
1343
|
TasksComplexityEstimateResult,
|
|
1344
|
+
// T10629 — task context pack types
|
|
1345
|
+
TasksContextAcceptanceEntry,
|
|
1346
|
+
TasksContextActivityEvent,
|
|
1347
|
+
TasksContextBlockerEntry,
|
|
1348
|
+
TasksContextBudget,
|
|
1349
|
+
TasksContextDocEntry,
|
|
1350
|
+
TasksContextOmission,
|
|
1351
|
+
TasksContextParams,
|
|
1352
|
+
TasksContextResult,
|
|
1310
1353
|
TasksCurrentParams,
|
|
1311
1354
|
TasksCurrentResult,
|
|
1312
1355
|
TasksDeleteQueryParams,
|
|
@@ -1333,6 +1376,9 @@ export type {
|
|
|
1333
1376
|
TasksOps,
|
|
1334
1377
|
TasksPlanParams,
|
|
1335
1378
|
TasksPlanResult,
|
|
1379
|
+
TasksRelatesAddBatchEntry,
|
|
1380
|
+
TasksRelatesAddBatchParams,
|
|
1381
|
+
TasksRelatesAddBatchResult,
|
|
1336
1382
|
TasksRelatesAddParams,
|
|
1337
1383
|
TasksRelatesAddResult,
|
|
1338
1384
|
TasksRelatesParams,
|
|
@@ -1357,8 +1403,14 @@ export type {
|
|
|
1357
1403
|
TasksSagaMembersResult,
|
|
1358
1404
|
TasksSagaRollupParams,
|
|
1359
1405
|
TasksSagaRollupResult,
|
|
1406
|
+
TasksScopeMember,
|
|
1407
|
+
TasksScopeReadyEntry,
|
|
1408
|
+
TasksScopeRollup,
|
|
1360
1409
|
TasksShowParams,
|
|
1361
1410
|
TasksShowResult,
|
|
1411
|
+
TasksSliceNode,
|
|
1412
|
+
TasksSliceParams,
|
|
1413
|
+
TasksSliceResult,
|
|
1362
1414
|
TasksStartQueryParams,
|
|
1363
1415
|
TasksStartQueryResult,
|
|
1364
1416
|
TasksStopQueryParams,
|
|
@@ -1893,6 +1945,7 @@ export type {
|
|
|
1893
1945
|
MinimalTaskRecord,
|
|
1894
1946
|
TaskRecord,
|
|
1895
1947
|
TaskRecordRelation,
|
|
1948
|
+
TaskRecordRelationCounts,
|
|
1896
1949
|
ValidationHistoryEntry,
|
|
1897
1950
|
} from './task-record.js';
|
|
1898
1951
|
// === Task Sync Types (provider-agnostic reconciliation) ===
|
|
@@ -1923,10 +1976,40 @@ export {
|
|
|
1923
1976
|
} from './tasks/archive.js';
|
|
1924
1977
|
// === Task Domain Result Types (T1703 — canonical shapes for operations/tasks.ts stubs) ===
|
|
1925
1978
|
export type {
|
|
1979
|
+
CompletionBlockerReason,
|
|
1980
|
+
CompletionContextPack,
|
|
1981
|
+
CompletionContextPackOptions,
|
|
1982
|
+
CompletionContextPackSummary,
|
|
1983
|
+
CompletionCriterionEvaluation,
|
|
1984
|
+
CompletionCriterionKind,
|
|
1985
|
+
CompletionCriterionReplacement,
|
|
1986
|
+
CompletionCriterionStatus,
|
|
1987
|
+
CompletionCriterionWaiver,
|
|
1988
|
+
CompletionEvaluateParams,
|
|
1989
|
+
CompletionEvaluateResult,
|
|
1990
|
+
CompletionEvaluation,
|
|
1991
|
+
CompletionExplainParams,
|
|
1992
|
+
CompletionExplainResult,
|
|
1993
|
+
CompletionExplanation,
|
|
1994
|
+
CompletionHistoryEvent,
|
|
1995
|
+
CompletionHistoryEventAction,
|
|
1996
|
+
CompletionHistoryEventRelation,
|
|
1997
|
+
CompletionListParams,
|
|
1998
|
+
CompletionListResult,
|
|
1999
|
+
CompletionProjectionRepairError,
|
|
2000
|
+
CompletionProjectionRepairErrorCode,
|
|
2001
|
+
CompletionProjectionRepairParams,
|
|
2002
|
+
CompletionProjectionRepairResult,
|
|
2003
|
+
CompletionStaleReason,
|
|
1926
2004
|
TaskComplexityFactor,
|
|
1927
2005
|
TaskDependsRef,
|
|
1928
2006
|
TaskDependsResult,
|
|
1929
2007
|
TaskLabelInfo,
|
|
2008
|
+
TaskMutationBucket,
|
|
2009
|
+
TaskMutationDryRunSummary,
|
|
2010
|
+
TaskMutationEnvelope,
|
|
2011
|
+
TaskMutationWarning,
|
|
2012
|
+
TaskMutationWarningSeverity,
|
|
1930
2013
|
TaskPlanBlockedTask,
|
|
1931
2014
|
TaskPlanInProgressEpic,
|
|
1932
2015
|
TaskPlanMetrics,
|
|
@@ -1941,6 +2024,19 @@ export type {
|
|
|
1941
2024
|
TaskViewNextAction,
|
|
1942
2025
|
TaskViewPipelineStage,
|
|
1943
2026
|
} from './tasks.js';
|
|
2027
|
+
export {
|
|
2028
|
+
completionCriterionEvaluationSchema,
|
|
2029
|
+
completionEvaluateParamsSchema,
|
|
2030
|
+
completionEvaluationSchema,
|
|
2031
|
+
completionExplainParamsSchema,
|
|
2032
|
+
completionExplanationSchema,
|
|
2033
|
+
completionListParamsSchema,
|
|
2034
|
+
completionListResultSchema,
|
|
2035
|
+
completionProjectionRepairErrorSchema,
|
|
2036
|
+
completionProjectionRepairParamsSchema,
|
|
2037
|
+
completionProjectionRepairResultSchema,
|
|
2038
|
+
unsatisfiedCompletionCriterionSchema,
|
|
2039
|
+
} from './tasks.js';
|
|
1944
2040
|
// === Template Manifest (T9875 / Saga T9855) ===
|
|
1945
2041
|
export type {
|
|
1946
2042
|
PlaceholderSource,
|
|
@@ -2046,4 +2142,99 @@ export type {
|
|
|
2046
2142
|
WarpLink,
|
|
2047
2143
|
WarpStage,
|
|
2048
2144
|
} from './warp-chain.js';
|
|
2145
|
+
export type {
|
|
2146
|
+
TasksFrontierParamsInput,
|
|
2147
|
+
TasksRollupParamsInput,
|
|
2148
|
+
TasksTraverseParamsInput,
|
|
2149
|
+
TasksTreeParamsInput,
|
|
2150
|
+
TasksWorkGraphAuditParamsInput,
|
|
2151
|
+
WorkGraphAudienceMode,
|
|
2152
|
+
WorkGraphAuditOptions,
|
|
2153
|
+
WorkGraphAuditResult,
|
|
2154
|
+
WorkGraphContainmentAncestorsResult,
|
|
2155
|
+
WorkGraphContainmentChildrenResult,
|
|
2156
|
+
WorkGraphContainmentNode,
|
|
2157
|
+
WorkGraphContainmentQueryService,
|
|
2158
|
+
WorkGraphContextBudget,
|
|
2159
|
+
WorkGraphContextPack,
|
|
2160
|
+
WorkGraphContextPackParams,
|
|
2161
|
+
WorkGraphDependencyEdge,
|
|
2162
|
+
WorkGraphDirectEdge,
|
|
2163
|
+
WorkGraphEdge,
|
|
2164
|
+
WorkGraphEdgeDirection,
|
|
2165
|
+
WorkGraphEdgeSource,
|
|
2166
|
+
WorkGraphHierarchyInputNode,
|
|
2167
|
+
WorkGraphHierarchyValidationOptions,
|
|
2168
|
+
WorkGraphHierarchyValidationResult,
|
|
2169
|
+
WorkGraphHierarchyViolation,
|
|
2170
|
+
WorkGraphNode,
|
|
2171
|
+
WorkGraphNodeRef,
|
|
2172
|
+
WorkGraphOmission,
|
|
2173
|
+
WorkGraphOmissionReason,
|
|
2174
|
+
WorkGraphPageInfo,
|
|
2175
|
+
WorkGraphPaginationOptions,
|
|
2176
|
+
WorkGraphPercentDenominator,
|
|
2177
|
+
WorkGraphPlanningDoc,
|
|
2178
|
+
WorkGraphPlanningDocParams,
|
|
2179
|
+
WorkGraphProjectionMismatch,
|
|
2180
|
+
WorkGraphReader,
|
|
2181
|
+
WorkGraphReadinessParams,
|
|
2182
|
+
WorkGraphReadinessResult,
|
|
2183
|
+
WorkGraphReadyFrontierBlockedBy,
|
|
2184
|
+
WorkGraphReadyFrontierOptions,
|
|
2185
|
+
WorkGraphReadyFrontierResult,
|
|
2186
|
+
WorkGraphReadyFrontierTask,
|
|
2187
|
+
WorkGraphRelationEdge,
|
|
2188
|
+
WorkGraphRelationEdgesOptions,
|
|
2189
|
+
WorkGraphRelationEdgesResult,
|
|
2190
|
+
WorkGraphRelationKind,
|
|
2191
|
+
WorkGraphRelationQueryService,
|
|
2192
|
+
WorkGraphRollupCounts,
|
|
2193
|
+
WorkGraphScaffoldApplyParams,
|
|
2194
|
+
WorkGraphScaffoldApplyResult,
|
|
2195
|
+
WorkGraphScaffoldValidateParams,
|
|
2196
|
+
WorkGraphScaffoldValidateResult,
|
|
2197
|
+
WorkGraphScaffoldValidationIssue,
|
|
2198
|
+
WorkGraphSlice,
|
|
2199
|
+
WorkGraphSliceParams,
|
|
2200
|
+
WorkGraphSnapshot,
|
|
2201
|
+
WorkGraphSubtreePercentages,
|
|
2202
|
+
WorkGraphSubtreeSummaryOptions,
|
|
2203
|
+
WorkGraphSubtreeSummaryResult,
|
|
2204
|
+
WorkGraphTaskRelationType,
|
|
2205
|
+
WorkGraphTraversalDirection,
|
|
2206
|
+
WorkGraphTraversalOptions,
|
|
2207
|
+
WorkGraphTraversalResult,
|
|
2208
|
+
WorkGraphTreeNode,
|
|
2209
|
+
WorkGraphTreeOptions,
|
|
2210
|
+
WorkGraphTreeResult,
|
|
2211
|
+
} from './workgraph.js';
|
|
2212
|
+
// === PM-Core V2 WorkGraph public contracts ===
|
|
2213
|
+
export {
|
|
2214
|
+
E_WORKGRAPH_PARENT_TYPE_MATRIX,
|
|
2215
|
+
tasksFrontierParamsSchema,
|
|
2216
|
+
tasksFrontierResultSchema,
|
|
2217
|
+
tasksRollupParamsSchema,
|
|
2218
|
+
tasksRollupResultSchema,
|
|
2219
|
+
tasksTraverseParamsSchema,
|
|
2220
|
+
tasksTraverseResultSchema,
|
|
2221
|
+
tasksTreeParamsSchema,
|
|
2222
|
+
tasksTreeResultSchema,
|
|
2223
|
+
tasksWorkGraphAuditParamsSchema,
|
|
2224
|
+
tasksWorkGraphAuditResultSchema,
|
|
2225
|
+
validateWorkGraphHierarchy,
|
|
2226
|
+
WorkGraphHierarchyInvariantError,
|
|
2227
|
+
workGraphContextPackParamsSchema,
|
|
2228
|
+
workGraphContextPackSchema,
|
|
2229
|
+
workGraphPlanningDocParamsSchema,
|
|
2230
|
+
workGraphPlanningDocSchema,
|
|
2231
|
+
workGraphReadinessParamsSchema,
|
|
2232
|
+
workGraphReadinessResultSchema,
|
|
2233
|
+
workGraphScaffoldApplyParamsSchema,
|
|
2234
|
+
workGraphScaffoldApplyResultSchema,
|
|
2235
|
+
workGraphScaffoldValidateParamsSchema,
|
|
2236
|
+
workGraphScaffoldValidateResultSchema,
|
|
2237
|
+
workGraphSliceParamsSchema,
|
|
2238
|
+
workGraphSliceSchema,
|
|
2239
|
+
} from './workgraph.js';
|
|
2049
2240
|
// === WASM SDK (Rust crate bindings) ===
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation-aware LAFS envelope validation.
|
|
3
|
+
*
|
|
4
|
+
* The base LAFS shape proves that an envelope is structurally valid. This
|
|
5
|
+
* module adds the dispatch-layer contract checks that require `_meta.operation`
|
|
6
|
+
* to resolve to a registered CLEO operation and, when a result schema is known,
|
|
7
|
+
* validates successful payloads against that operation's result contract.
|
|
8
|
+
*
|
|
9
|
+
* @task T10610
|
|
10
|
+
* @saga T10538
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { OperationDef } from './dispatch/operation-def.js';
|
|
14
|
+
import { OPERATIONS } from './dispatch/operations-registry.js';
|
|
15
|
+
import type { LAFSEnvelope, LAFSErrorCategory, LAFSTransport, MVILevel } from './lafs.js';
|
|
16
|
+
import {
|
|
17
|
+
tasksFrontierResultSchema,
|
|
18
|
+
tasksRollupResultSchema,
|
|
19
|
+
tasksTraverseResultSchema,
|
|
20
|
+
tasksTreeResultSchema,
|
|
21
|
+
tasksWorkGraphAuditResultSchema,
|
|
22
|
+
} from './workgraph.js';
|
|
23
|
+
|
|
24
|
+
interface SafeParseIssue {
|
|
25
|
+
readonly path: readonly PropertyKey[];
|
|
26
|
+
readonly message: string;
|
|
27
|
+
readonly code?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface SafeParseError {
|
|
31
|
+
readonly issues: readonly SafeParseIssue[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface ResultSchema {
|
|
35
|
+
safeParse(
|
|
36
|
+
input: unknown,
|
|
37
|
+
): { success: true; data: unknown } | { success: false; error: SafeParseError };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Stable issue code emitted when `_meta.operation` is absent or unknown. */
|
|
41
|
+
export const E_LAFS_OPERATION_UNREGISTERED = 'E_LAFS_OPERATION_UNREGISTERED';
|
|
42
|
+
|
|
43
|
+
/** Stable issue code emitted when an operation result fails its contract schema. */
|
|
44
|
+
export const E_LAFS_OPERATION_RESULT_SCHEMA = 'E_LAFS_OPERATION_RESULT_SCHEMA';
|
|
45
|
+
|
|
46
|
+
/** Stable issue code emitted when success/error envelope invariants are violated. */
|
|
47
|
+
export const E_LAFS_OPERATION_ERROR_SHAPE = 'E_LAFS_OPERATION_ERROR_SHAPE';
|
|
48
|
+
|
|
49
|
+
/** Dot-delimited operation name, e.g. `tasks.frontier`. */
|
|
50
|
+
export type OperationEnvelopeName = `${string}.${string}`;
|
|
51
|
+
|
|
52
|
+
/** One issue produced by operation-aware envelope validation. */
|
|
53
|
+
export interface OperationEnvelopeValidationIssue {
|
|
54
|
+
/** JSON Pointer path into the envelope. */
|
|
55
|
+
readonly path: string;
|
|
56
|
+
/** Stable machine-readable issue code. */
|
|
57
|
+
readonly code: string;
|
|
58
|
+
/** Human-readable validation failure. */
|
|
59
|
+
readonly message: string;
|
|
60
|
+
/** Optional underlying schema keyword or parser code. */
|
|
61
|
+
readonly keyword?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Result of validating a LAFS envelope against the dispatch operation registry. */
|
|
65
|
+
export interface OperationEnvelopeValidationResult {
|
|
66
|
+
/** True only when base LAFS shape, registry lookup, and result schema checks pass. */
|
|
67
|
+
readonly valid: boolean;
|
|
68
|
+
/** Base LAFS structural verdict. */
|
|
69
|
+
readonly envelopeValid: boolean;
|
|
70
|
+
/** Resolved operation definition, if `_meta.operation` matched the registry. */
|
|
71
|
+
readonly operation?: OperationDef;
|
|
72
|
+
/** Result schema key that was enforced, when available. */
|
|
73
|
+
readonly resultSchemaOperation?: OperationEnvelopeName;
|
|
74
|
+
/** Structured issue list, including base LAFS and operation-aware issues. */
|
|
75
|
+
readonly issues: readonly OperationEnvelopeValidationIssue[];
|
|
76
|
+
/** Human-readable issue messages for CLI/reporting callers. */
|
|
77
|
+
readonly errors: readonly string[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Options for operation-aware LAFS validation. */
|
|
81
|
+
export interface OperationEnvelopeValidationOptions {
|
|
82
|
+
/** Registry to resolve `_meta.operation` against. Defaults to canonical OPERATIONS. */
|
|
83
|
+
readonly operations?: readonly OperationDef[];
|
|
84
|
+
/** Per-operation result schemas. Defaults to the currently contracted WorkGraph reads. */
|
|
85
|
+
readonly resultSchemas?: ReadonlyMap<OperationEnvelopeName, ResultSchema>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Canonical result schemas currently promoted to operation-aware LAFS validation. */
|
|
89
|
+
export const OPERATION_RESULT_SCHEMAS: ReadonlyMap<OperationEnvelopeName, ResultSchema> = new Map<
|
|
90
|
+
OperationEnvelopeName,
|
|
91
|
+
ResultSchema
|
|
92
|
+
>([
|
|
93
|
+
['tasks.traverse', tasksTraverseResultSchema as ResultSchema],
|
|
94
|
+
['tasks.tree', tasksTreeResultSchema as ResultSchema],
|
|
95
|
+
['tasks.rollup', tasksRollupResultSchema as ResultSchema],
|
|
96
|
+
['tasks.frontier', tasksFrontierResultSchema as ResultSchema],
|
|
97
|
+
['tasks.workgraph.audit', tasksWorkGraphAuditResultSchema as ResultSchema],
|
|
98
|
+
]);
|
|
99
|
+
|
|
100
|
+
const LAFS_SCHEMA_URL = 'https://lafs.dev/schemas/v1/envelope.schema.json';
|
|
101
|
+
const LAFS_TRANSPORTS: ReadonlySet<LAFSTransport> = new Set(['cli', 'http', 'grpc', 'sdk']);
|
|
102
|
+
const LAFS_MVI_LEVELS: ReadonlySet<MVILevel> = new Set(['minimal', 'standard', 'full', 'custom']);
|
|
103
|
+
const LAFS_ERROR_CATEGORIES: ReadonlySet<LAFSErrorCategory> = new Set([
|
|
104
|
+
'VALIDATION',
|
|
105
|
+
'AUTH',
|
|
106
|
+
'PERMISSION',
|
|
107
|
+
'NOT_FOUND',
|
|
108
|
+
'CONFLICT',
|
|
109
|
+
'RATE_LIMIT',
|
|
110
|
+
'TRANSIENT',
|
|
111
|
+
'INTERNAL',
|
|
112
|
+
'CONTRACT',
|
|
113
|
+
'MIGRATION',
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
function issue(path: string, message: string, keyword = 'type'): OperationEnvelopeValidationIssue {
|
|
117
|
+
return { path, code: `LAFS_SCHEMA_${keyword.toUpperCase()}`, keyword, message };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function isRecord(input: unknown): input is Record<string, unknown> {
|
|
121
|
+
return typeof input === 'object' && input !== null && !Array.isArray(input);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function validateBaseLafsEnvelope(input: unknown): OperationEnvelopeValidationIssue[] {
|
|
125
|
+
if (!isRecord(input)) return [issue('/', 'LAFS envelope must be an object')];
|
|
126
|
+
|
|
127
|
+
const issues: OperationEnvelopeValidationIssue[] = [];
|
|
128
|
+
if (input.$schema !== LAFS_SCHEMA_URL) {
|
|
129
|
+
issues.push(issue('/$schema', `must equal ${LAFS_SCHEMA_URL}`, 'const'));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!isRecord(input._meta)) {
|
|
133
|
+
issues.push(issue('/_meta', 'must be an object'));
|
|
134
|
+
} else {
|
|
135
|
+
const meta = input._meta;
|
|
136
|
+
for (const field of ['specVersion', 'schemaVersion', 'timestamp', 'operation', 'requestId']) {
|
|
137
|
+
if (typeof meta[field] !== 'string' || meta[field].length === 0) {
|
|
138
|
+
issues.push(issue(`/_meta/${field}`, 'must be a non-empty string'));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (
|
|
142
|
+
typeof meta.transport !== 'string' ||
|
|
143
|
+
!LAFS_TRANSPORTS.has(meta.transport as LAFSTransport)
|
|
144
|
+
) {
|
|
145
|
+
issues.push(issue('/_meta/transport', 'must be a valid LAFS transport', 'enum'));
|
|
146
|
+
}
|
|
147
|
+
if (typeof meta.strict !== 'boolean') {
|
|
148
|
+
issues.push(issue('/_meta/strict', 'must be a boolean'));
|
|
149
|
+
}
|
|
150
|
+
if (typeof meta.mvi !== 'string' || !LAFS_MVI_LEVELS.has(meta.mvi as MVILevel)) {
|
|
151
|
+
issues.push(issue('/_meta/mvi', 'must be a valid LAFS MVI level', 'enum'));
|
|
152
|
+
}
|
|
153
|
+
if (!Number.isInteger(meta.contextVersion) || Number(meta.contextVersion) < 0) {
|
|
154
|
+
issues.push(issue('/_meta/contextVersion', 'must be a non-negative integer'));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (typeof input.success !== 'boolean') {
|
|
159
|
+
issues.push(issue('/success', 'must be a boolean'));
|
|
160
|
+
}
|
|
161
|
+
if (!('result' in input)) {
|
|
162
|
+
issues.push(issue('/result', 'is required', 'required'));
|
|
163
|
+
} else if (input.result !== null && !isRecord(input.result) && !Array.isArray(input.result)) {
|
|
164
|
+
issues.push(issue('/result', 'must be an object, array, or null'));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (input.error !== null && input.error !== undefined) {
|
|
168
|
+
if (!isRecord(input.error)) {
|
|
169
|
+
issues.push(issue('/error', 'must be an object or null'));
|
|
170
|
+
} else {
|
|
171
|
+
const error = input.error;
|
|
172
|
+
if (typeof error.code !== 'string' || error.code.length === 0) {
|
|
173
|
+
issues.push(issue('/error/code', 'must be a non-empty string'));
|
|
174
|
+
}
|
|
175
|
+
if (typeof error.message !== 'string' || error.message.length === 0) {
|
|
176
|
+
issues.push(issue('/error/message', 'must be a non-empty string'));
|
|
177
|
+
}
|
|
178
|
+
if (
|
|
179
|
+
typeof error.category !== 'string' ||
|
|
180
|
+
!LAFS_ERROR_CATEGORIES.has(error.category as LAFSErrorCategory)
|
|
181
|
+
) {
|
|
182
|
+
issues.push(issue('/error/category', 'must be a valid LAFS error category', 'enum'));
|
|
183
|
+
}
|
|
184
|
+
if (typeof error.retryable !== 'boolean') {
|
|
185
|
+
issues.push(issue('/error/retryable', 'must be a boolean'));
|
|
186
|
+
}
|
|
187
|
+
if (
|
|
188
|
+
error.retryAfterMs !== null &&
|
|
189
|
+
error.retryAfterMs !== undefined &&
|
|
190
|
+
(!Number.isInteger(error.retryAfterMs) || Number(error.retryAfterMs) < 0)
|
|
191
|
+
) {
|
|
192
|
+
issues.push(issue('/error/retryAfterMs', 'must be a non-negative integer or null'));
|
|
193
|
+
}
|
|
194
|
+
if (!isRecord(error.details)) {
|
|
195
|
+
issues.push(issue('/error/details', 'must be an object'));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return issues;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function pointer(path: readonly PropertyKey[]): string {
|
|
204
|
+
if (path.length === 0) return '/result';
|
|
205
|
+
return `/result/${path
|
|
206
|
+
.map((segment) => String(segment).split('~').join('~0').split('/').join('~1'))
|
|
207
|
+
.join('/')}`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function resolveOperation(
|
|
211
|
+
operationName: string,
|
|
212
|
+
operations: readonly OperationDef[],
|
|
213
|
+
): OperationDef | undefined {
|
|
214
|
+
return operations.find(
|
|
215
|
+
(candidate) => `${candidate.domain}.${candidate.operation}` === operationName,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function hasCanonicalSuccessShape(envelope: LAFSEnvelope): OperationEnvelopeValidationIssue[] {
|
|
220
|
+
if (envelope.success) {
|
|
221
|
+
if (envelope.result === null) {
|
|
222
|
+
return [
|
|
223
|
+
{
|
|
224
|
+
path: '/result',
|
|
225
|
+
code: E_LAFS_OPERATION_ERROR_SHAPE,
|
|
226
|
+
message: 'successful LAFS envelopes must include a non-null result payload',
|
|
227
|
+
},
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
if (envelope.error !== null && envelope.error !== undefined) {
|
|
231
|
+
return [
|
|
232
|
+
{
|
|
233
|
+
path: '/error',
|
|
234
|
+
code: E_LAFS_OPERATION_ERROR_SHAPE,
|
|
235
|
+
message: 'successful LAFS envelopes must not include an error payload',
|
|
236
|
+
},
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const issues: OperationEnvelopeValidationIssue[] = [];
|
|
243
|
+
if (envelope.error === null || envelope.error === undefined) {
|
|
244
|
+
issues.push({
|
|
245
|
+
path: '/error',
|
|
246
|
+
code: E_LAFS_OPERATION_ERROR_SHAPE,
|
|
247
|
+
message: 'failed LAFS envelopes must include the canonical error payload',
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (envelope.result !== null) {
|
|
251
|
+
issues.push({
|
|
252
|
+
path: '/result',
|
|
253
|
+
code: E_LAFS_OPERATION_ERROR_SHAPE,
|
|
254
|
+
message: 'failed LAFS envelopes must set result to null',
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return issues;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Validate a LAFS envelope against the dispatch operation registry and known
|
|
262
|
+
* operation result contracts.
|
|
263
|
+
*/
|
|
264
|
+
export function validateOperationEnvelope(
|
|
265
|
+
input: unknown,
|
|
266
|
+
options: OperationEnvelopeValidationOptions = {},
|
|
267
|
+
): OperationEnvelopeValidationResult {
|
|
268
|
+
const issues: OperationEnvelopeValidationIssue[] = validateBaseLafsEnvelope(input);
|
|
269
|
+
|
|
270
|
+
if (issues.length > 0) {
|
|
271
|
+
return {
|
|
272
|
+
valid: false,
|
|
273
|
+
envelopeValid: false,
|
|
274
|
+
issues,
|
|
275
|
+
errors: issues.map((issue) => `${issue.path} ${issue.message}`.trim()),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const envelope = input as LAFSEnvelope;
|
|
280
|
+
const operationName = envelope._meta.operation;
|
|
281
|
+
const operations = options.operations ?? OPERATIONS;
|
|
282
|
+
const resultSchemas = options.resultSchemas ?? OPERATION_RESULT_SCHEMAS;
|
|
283
|
+
const operation = resolveOperation(operationName, operations);
|
|
284
|
+
|
|
285
|
+
if (operation === undefined) {
|
|
286
|
+
issues.push({
|
|
287
|
+
path: '/_meta/operation',
|
|
288
|
+
code: E_LAFS_OPERATION_UNREGISTERED,
|
|
289
|
+
message: `unknown LAFS operation '${operationName}'`,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
issues.push(...hasCanonicalSuccessShape(envelope));
|
|
294
|
+
|
|
295
|
+
const schema = resultSchemas.get(operationName as OperationEnvelopeName);
|
|
296
|
+
if (envelope.success && schema !== undefined && envelope.result !== null) {
|
|
297
|
+
const parsed = schema.safeParse(envelope.result);
|
|
298
|
+
if (!parsed.success) {
|
|
299
|
+
for (const zodIssue of parsed.error.issues) {
|
|
300
|
+
issues.push({
|
|
301
|
+
path: pointer(zodIssue.path),
|
|
302
|
+
code: E_LAFS_OPERATION_RESULT_SCHEMA,
|
|
303
|
+
keyword: zodIssue.code,
|
|
304
|
+
message: zodIssue.message,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
valid: issues.length === 0,
|
|
312
|
+
envelopeValid: true,
|
|
313
|
+
operation,
|
|
314
|
+
resultSchemaOperation:
|
|
315
|
+
schema === undefined ? undefined : (operationName as OperationEnvelopeName),
|
|
316
|
+
issues,
|
|
317
|
+
errors: issues.map((issue) => `${issue.path} ${issue.message}`.trim()),
|
|
318
|
+
};
|
|
319
|
+
}
|