@evomap/evolver-core 2.0.0-beta.2 → 2.0.0-beta.22

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 (240) hide show
  1. package/assets/gep/genes.jsonl +5 -5
  2. package/dist/algo/bans.d.ts +10 -1
  3. package/dist/algo/bans.js +56 -6
  4. package/dist/algo/candidateAssembly.d.ts +25 -2
  5. package/dist/algo/candidateAssembly.js +171 -26
  6. package/dist/algo/capabilityCandidates.js +10 -0
  7. package/dist/algo/conversationSniffer.js +25 -8
  8. package/dist/algo/cycleEngine.d.ts +63 -5
  9. package/dist/algo/cycleEngine.js +320 -42
  10. package/dist/algo/cycleFailureClassifier.d.ts +1 -1
  11. package/dist/algo/evolutionEvent.d.ts +26 -0
  12. package/dist/algo/evolutionEvent.js +32 -0
  13. package/dist/algo/exploration.d.ts +7 -0
  14. package/dist/algo/exploration.js +16 -3
  15. package/dist/algo/geneHealth.d.ts +36 -3
  16. package/dist/algo/geneHealth.js +47 -4
  17. package/dist/algo/geneIntake.d.ts +46 -1
  18. package/dist/algo/geneIntake.js +121 -10
  19. package/dist/algo/geneSelection.d.ts +126 -6
  20. package/dist/algo/geneSelection.js +479 -36
  21. package/dist/algo/index.d.ts +6 -1
  22. package/dist/algo/index.js +6 -1
  23. package/dist/algo/kautoProjection.d.ts +41 -0
  24. package/dist/algo/kautoProjection.js +95 -0
  25. package/dist/algo/kautoValidator.d.ts +68 -0
  26. package/dist/algo/kautoValidator.js +256 -0
  27. package/dist/algo/memoryGraph.d.ts +62 -0
  28. package/dist/algo/memoryGraph.js +86 -0
  29. package/dist/algo/orchestrator.d.ts +17 -1
  30. package/dist/algo/orchestrator.js +30 -4
  31. package/dist/algo/publishEligibility.d.ts +34 -0
  32. package/dist/algo/publishEligibility.js +52 -0
  33. package/dist/algo/solidify.d.ts +11 -2
  34. package/dist/algo/solidify.js +37 -7
  35. package/dist/algo/ucb1.d.ts +53 -0
  36. package/dist/algo/ucb1.js +156 -0
  37. package/dist/assetrepair/hubRejection.d.ts +12 -0
  38. package/dist/assetrepair/hubRejection.js +109 -0
  39. package/dist/assetrepair/index.d.ts +2 -0
  40. package/dist/assetrepair/index.js +2 -0
  41. package/dist/assetrepair/repair.d.ts +33 -0
  42. package/dist/assetrepair/repair.js +155 -0
  43. package/dist/assetstore/assetSidecarRecords.d.ts +28 -0
  44. package/dist/assetstore/assetSidecarRecords.js +384 -0
  45. package/dist/assetstore/assetSidecarRecovery.d.ts +48 -0
  46. package/dist/assetstore/assetSidecarRecovery.js +288 -0
  47. package/dist/assetstore/assetStoreHealth.d.ts +81 -0
  48. package/dist/assetstore/assetStoreHealth.js +319 -0
  49. package/dist/assetstore/assetStoreLayout.d.ts +2 -0
  50. package/dist/assetstore/assetStoreLayout.js +6 -0
  51. package/dist/assetstore/assetStoreStorage.d.ts +42 -0
  52. package/dist/assetstore/assetStoreStorage.js +336 -0
  53. package/dist/assetstore/assetSyncLedger.d.ts +91 -1
  54. package/dist/assetstore/assetSyncLedger.js +718 -59
  55. package/dist/assetstore/foreignJsonlSource.d.ts +48 -0
  56. package/dist/assetstore/foreignJsonlSource.js +150 -0
  57. package/dist/assetstore/index.d.ts +5 -0
  58. package/dist/assetstore/index.js +5 -0
  59. package/dist/assetstore/learningHistory.js +3 -3
  60. package/dist/assetstore/localAssetStoreSnapshot.d.ts +51 -0
  61. package/dist/assetstore/localAssetStoreSnapshot.js +329 -0
  62. package/dist/assetstore/localJsonl.d.ts +12 -1
  63. package/dist/assetstore/localJsonl.js +251 -42
  64. package/dist/assetstore/provenance.d.ts +93 -4
  65. package/dist/assetstore/provenance.js +368 -84
  66. package/dist/assetstore/provider.d.ts +63 -0
  67. package/dist/assetstore/provider.js +97 -6
  68. package/dist/assetstore/reviewFilter.d.ts +19 -1
  69. package/dist/assetstore/reviewFilter.js +39 -1
  70. package/dist/assetstore/reviewLedger.d.ts +8 -2
  71. package/dist/assetstore/reviewLedger.js +71 -45
  72. package/dist/assetstore/unionReadStore.d.ts +25 -0
  73. package/dist/assetstore/unionReadStore.js +119 -0
  74. package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
  75. package/dist/benchmark/antiGeneBenchmark.js +4 -3
  76. package/dist/benchmark/antiGeneRollout.d.ts +2 -0
  77. package/dist/benchmark/antiGeneRollout.js +4 -3
  78. package/dist/benchmark/index.d.ts +3 -1
  79. package/dist/benchmark/index.js +3 -1
  80. package/dist/benchmark/selectionFlatAbstention.d.ts +152 -0
  81. package/dist/benchmark/selectionFlatAbstention.js +481 -0
  82. package/dist/benchmark/triggerShift.d.ts +62 -0
  83. package/dist/benchmark/triggerShift.js +106 -0
  84. package/dist/bootstrap/envFingerprint.d.ts +9 -0
  85. package/dist/bootstrap/envFingerprint.js +5 -0
  86. package/dist/bootstrap/index.d.ts +3 -1
  87. package/dist/bootstrap/index.js +3 -1
  88. package/dist/bootstrap/lifecycleBootstrap.d.ts +111 -0
  89. package/dist/bootstrap/lifecycleBootstrap.js +433 -0
  90. package/dist/bootstrap/v1EnvCompat.d.ts +113 -0
  91. package/dist/bootstrap/v1EnvCompat.js +303 -0
  92. package/dist/events/eventArchive.d.ts +2 -0
  93. package/dist/events/eventArchive.js +13 -3
  94. package/dist/events/eventSchema.d.ts +7 -7
  95. package/dist/events/eventStore.d.ts +2 -0
  96. package/dist/events/eventStore.js +5 -1
  97. package/dist/events/ingest.d.ts +2 -1
  98. package/dist/events/ingest.js +15 -0
  99. package/dist/events/paths.d.ts +12 -10
  100. package/dist/events/paths.js +24 -20
  101. package/dist/events/public.d.ts +2 -2
  102. package/dist/events/public.js +2 -2
  103. package/dist/events/reports.d.ts +2 -0
  104. package/dist/events/reports.js +4 -0
  105. package/dist/exec/autoExec.d.ts +68 -4
  106. package/dist/exec/autoExec.js +392 -33
  107. package/dist/exec/autonomousCycle.d.ts +31 -4
  108. package/dist/exec/autonomousCycle.js +71 -13
  109. package/dist/exec/claudeBridge.d.ts +80 -15
  110. package/dist/exec/claudeBridge.js +845 -76
  111. package/dist/exec/executionBinding.d.ts +414 -0
  112. package/dist/exec/executionBinding.js +588 -0
  113. package/dist/exec/index.d.ts +1 -0
  114. package/dist/exec/index.js +1 -0
  115. package/dist/exec/openPrRegistry.d.ts +8 -2
  116. package/dist/exec/openPrRegistry.js +32 -22
  117. package/dist/exec/prompt.js +14 -1
  118. package/dist/exec/proofOfWork.d.ts +1 -1
  119. package/dist/exec/proofOfWork.js +2 -2
  120. package/dist/exec/runnerRegistry.d.ts +153 -36
  121. package/dist/exec/runnerRegistry.js +848 -65
  122. package/dist/exec/selfPr.js +1 -7
  123. package/dist/feedback/envelope.d.ts +61 -0
  124. package/dist/feedback/envelope.js +168 -0
  125. package/dist/feedback/index.d.ts +1 -0
  126. package/dist/feedback/index.js +1 -0
  127. package/dist/hooks/hooks.js +1 -0
  128. package/dist/hub/assetCallLog.d.ts +35 -1
  129. package/dist/hub/assetCallLog.js +124 -1
  130. package/dist/hub/bindings.d.ts +8 -1
  131. package/dist/hub/bindings.js +29 -8
  132. package/dist/hub/capability.d.ts +130 -4
  133. package/dist/hub/conversationDistiller.d.ts +19 -0
  134. package/dist/hub/conversationDistiller.js +115 -37
  135. package/dist/hub/fake.d.ts +3 -2
  136. package/dist/hub/fake.js +2 -1
  137. package/dist/hub/index.d.ts +1 -0
  138. package/dist/hub/index.js +1 -0
  139. package/dist/hub/questionGenerator.d.ts +5 -1
  140. package/dist/hub/questionGenerator.js +8 -6
  141. package/dist/hub/recipeCompose.d.ts +27 -0
  142. package/dist/hub/recipeCompose.js +90 -0
  143. package/dist/hub/sanitize.js +122 -7
  144. package/dist/index.d.ts +6 -1
  145. package/dist/index.js +7 -1
  146. package/dist/issueReporter/index.d.ts +156 -0
  147. package/dist/issueReporter/index.js +1688 -0
  148. package/dist/mailbox/dispatch.d.ts +1 -1
  149. package/dist/mailbox/dispatch.js +22 -6
  150. package/dist/mailbox/envelope.d.ts +7 -1
  151. package/dist/mailbox/envelope.js +9 -2
  152. package/dist/mailbox/ipcServer.d.ts +12 -2
  153. package/dist/mailbox/ipcServer.js +183 -13
  154. package/dist/mailbox/store.d.ts +89 -3
  155. package/dist/mailbox/store.js +895 -41
  156. package/dist/modelCompatibility.d.ts +164 -0
  157. package/dist/modelCompatibility.js +309 -0
  158. package/dist/observers/valueDigestObserver.d.ts +9 -0
  159. package/dist/observers/valueDigestObserver.js +35 -2
  160. package/dist/ops/cleanup.js +1 -1
  161. package/dist/ops/evolutionGraphProjection.d.ts +20 -0
  162. package/dist/ops/evolutionGraphProjection.js +315 -0
  163. package/dist/ops/index.d.ts +2 -1
  164. package/dist/ops/index.js +2 -1
  165. package/dist/ops/savingsCore.js +1 -2
  166. package/dist/ops/selfUpdate.d.ts +18 -1
  167. package/dist/ops/selfUpdate.js +88 -23
  168. package/dist/ops/valueOutreach.d.ts +3 -1
  169. package/dist/ops/valueOutreach.js +5 -1
  170. package/dist/personality/schema.d.ts +24 -24
  171. package/dist/schema/evolutionGraph.d.ts +784 -0
  172. package/dist/schema/evolutionGraph.js +187 -0
  173. package/dist/schema/index.d.ts +1 -0
  174. package/dist/schema/index.js +1 -0
  175. package/dist/schema/proofOfWork.d.ts +125 -6
  176. package/dist/schema/proofOfWork.js +102 -4
  177. package/dist/schema/signal.d.ts +3 -3
  178. package/dist/schema/signal.js +1 -1
  179. package/dist/shadow/shadowHub.js +1 -0
  180. package/dist/signals/curriculum.d.ts +55 -0
  181. package/dist/signals/curriculum.js +202 -0
  182. package/dist/signals/cycleHistoryFromEvents.js +17 -8
  183. package/dist/signals/expand.d.ts +15 -1
  184. package/dist/signals/expand.js +169 -1
  185. package/dist/signals/extractor.d.ts +2 -2
  186. package/dist/signals/extractor.js +31 -6
  187. package/dist/signals/index.d.ts +4 -1
  188. package/dist/signals/index.js +4 -1
  189. package/dist/signals/metaSignals.d.ts +4 -0
  190. package/dist/signals/metaSignals.js +42 -0
  191. package/dist/signals/scopeVocabulary.d.ts +75 -0
  192. package/dist/signals/scopeVocabulary.js +91 -0
  193. package/dist/signals/signalGate.js +1 -1
  194. package/dist/signals/taskDomain.d.ts +22 -0
  195. package/dist/signals/taskDomain.js +43 -0
  196. package/dist/strategy/constraintAblation.d.ts +64 -0
  197. package/dist/strategy/constraintAblation.js +2820 -0
  198. package/dist/strategy/constraintAblationPredicates.d.ts +31 -0
  199. package/dist/strategy/constraintAblationPredicates.js +339 -0
  200. package/dist/strategy/index.d.ts +2 -1
  201. package/dist/strategy/index.js +2 -1
  202. package/dist/trace/index.d.ts +3 -1
  203. package/dist/trace/index.js +3 -1
  204. package/dist/trace/learningTrace.d.ts +216 -0
  205. package/dist/trace/learningTrace.js +298 -0
  206. package/dist/trace/proxyTurns.d.ts +31 -0
  207. package/dist/trace/proxyTurns.js +137 -0
  208. package/dist/trace/trajectory.d.ts +8 -0
  209. package/dist/trace/trajectory.js +14 -2
  210. package/dist/util/fetchPort.d.ts +1 -0
  211. package/dist/util/fetchPort.js +11 -0
  212. package/dist/util/fileLock.d.ts +113 -7
  213. package/dist/util/fileLock.js +1035 -80
  214. package/dist/util/index.d.ts +3 -1
  215. package/dist/util/index.js +2 -1
  216. package/dist/verify/index.d.ts +2 -1
  217. package/dist/verify/index.js +1 -1
  218. package/dist/verify/sandboxRunner.d.ts +30 -0
  219. package/dist/verify/sandboxRunner.js +370 -27
  220. package/dist/verify/sandboxedValidation.d.ts +16 -2
  221. package/dist/verify/sandboxedValidation.js +200 -22
  222. package/dist/verify/validation.d.ts +35 -4
  223. package/dist/verify/validation.js +164 -16
  224. package/dist/wire/geneHints.d.ts +88 -16
  225. package/dist/wire/geneHints.js +124 -15
  226. package/dist/wire/index.d.ts +8 -3
  227. package/dist/wire/index.js +2 -2
  228. package/dist/wire/schemaGate.d.ts +21 -0
  229. package/dist/wire/schemaGate.js +119 -10
  230. package/dist/workflow/dsl.d.ts +24 -3
  231. package/dist/workflow/dsl.js +4 -0
  232. package/dist/workflow/engine.d.ts +5 -1
  233. package/dist/workflow/engine.js +3 -0
  234. package/dist/workflow/index.d.ts +3 -1
  235. package/dist/workflow/index.js +3 -1
  236. package/dist/workflow/runtime.d.ts +110 -0
  237. package/dist/workflow/runtime.js +1298 -0
  238. package/dist/workflow/stateStore.d.ts +172 -0
  239. package/dist/workflow/stateStore.js +1044 -0
  240. package/package.json +12 -4
@@ -3,15 +3,14 @@
3
3
  * router (routing_hint) or restrict tools (tool_policy). Ported from v1 src/gep/schemas/gene.js (PR #93,
4
4
  * "wire routing_hint and tool_policy into Gene schema").
5
5
  *
6
- * v2-delta (feature-gate): these fields are NOT yet in @evomap/gep-sdk's gene.schema.json
7
- * (additionalProperties:false), so a Gene carrying them is not a schema-valid gep-sdk asset until a
8
- * gep-sdk gene-schema bump exactly how Capsule's proof_of_work / resolution_status were v2-delta before
9
- * the 1.11.0 bump made them first-class. That invalidity is surfaced ONLY by the advisory validateWire
10
- * (wire/schemaGate) at intake on the hint-stripped core, and via the evolver_gep_build pre-publish
11
- * preview — plus the hub's own schema check on receipt; there is NO enforced local egress gate (the
12
- * publish/egress path is sanitize-only and does not call validateWire). Until a bump the hints ride along
13
- * LOCALLY (intake pool + v1→v2 import fidelity); nothing in this repo wires them to a runtime consumer yet
14
- * (the proxy model router's `gene_hint` seam is the eventual tier consumer — see
6
+ * routing_hint / tool_policy and the K_auto coordinates are first-class in @evomap/gep-sdk 1.13.0, so they
7
+ * are normalized here rather than stripped. generation_meta and model_name remain local-only annotations for
8
+ * now. The advisory validateWire still surfaces any malformed shape at intake on the local-only slice, and
9
+ * via the evolver_gep_build pre-publish preview plus the hub's own schema check on receipt; there is NO
10
+ * enforced local egress gate (the publish/egress path is sanitize-only and does not call validateWire).
11
+ *
12
+ * Until a future schema bump, nothing in this repo wires these annotations to a runtime consumer yet (the
13
+ * proxy model router's `gene_hint` seam is the eventual tier consumer see
15
14
  * packages/evolver-proxy/src/router/modelRouter.ts).
16
15
  *
17
16
  * Enum strings are matched case-sensitively by the consuming router / tool-gate — keep them EXACT. The
@@ -55,7 +54,7 @@ export interface GeneGenerationHeuristics {
55
54
  has_corrective_insight?: boolean;
56
55
  }
57
56
  /**
58
- * The full provenance + quality metadata block (V1 `gene._source`). Lives on Gene as the v2-delta field
57
+ * The full provenance + quality metadata block (V1 `gene._source`). Lives on Gene as the local-only field
59
58
  * `generation_meta`. `source` is the only required key; the rest is descriptive for reviewers / future
60
59
  * governance. `quality_score` is a coarse [0,1] tier-anchored score (evolved 0.7 / distilled 0.4 / manual 0.3
61
60
  * baseline + bonuses); `overcame_errors` is the mutation_log copy that the trajectory overcame.
@@ -67,12 +66,56 @@ export interface GenerationMeta {
67
66
  overcame_errors?: string[];
68
67
  }
69
68
  /**
70
- * The v2-delta hint field names, in one place the intake gate strips these before the gep-sdk schema check.
71
- * IMPORTANT: when a gep-sdk gene-schema bump makes one of these first-class, REMOVE it from this list in the
72
- * same change. Otherwise intakeGene keeps stripping a now-validated field before validateWire (fail-open the
73
- * field's new schema constraints go unchecked at intake) while asset_id still commits it.
69
+ * K_auto projection-key coordinates a Gene MAY carry so its record is machine-decidable in the strict
70
+ * automatic-governance subdomain (paper §K_auto; validator: algo/kautoValidator.ts). These four fields are the
71
+ * DEDICATED, structured form of the coordinates that production previously expressed only through proxy fields
72
+ * (category≈claim, signals_match≈scope, model_name≈runtime, validation≈verifier). The strict measurement
73
+ * (bench/thesis/result-kauto-strict.json) found the dedicated fields populated at 0% and three coordinates
74
+ * (version/claim/scope) undecidable for 100% of 5,665 real rows — the writer side simply never emitted them.
75
+ *
76
+ * Shapes mirror gep-sdk 1.13.0 gene.schema.json (PR: add Gene K_auto coordinates), the schema-authoritative
77
+ * definition, EXACTLY so a gene minted here validates once the SDK bump lands:
78
+ * claims: {predicate:string, kind?:'behavioral'|'structural'|'performance'|'safety'}[]
79
+ * scope: {signals:string[], predicate?:string}
80
+ * runtime_profile: {runtime:string, env_class?:'ci'|'local'|'prod'|'sandbox'}
81
+ * verifier_profile: {verifier:string, decision?:'pass'|'fail'|'inconclusive'}
82
+ *
83
+ * Since gep-sdk 1.13.0, these four coordinates are first-class Gene fields: the intake schema gate validates
84
+ * their dedicated structure instead of stripping them as local-only hints. They still ride along in asset_id
85
+ * (canonicalize hashes every own key), so a silent strip on the hub side would change the hashed bytes and fail
86
+ * gene_asset_id_verification_failed; the hub allowlist admits them for exactly this reason.
87
+ */
88
+ export declare const CLAIM_KINDS: readonly ["behavioral", "structural", "performance", "safety"];
89
+ export type ClaimKind = (typeof CLAIM_KINDS)[number];
90
+ export interface GeneClaim {
91
+ predicate: string;
92
+ kind?: ClaimKind;
93
+ }
94
+ export declare const ENV_CLASSES: readonly ["ci", "local", "prod", "sandbox"];
95
+ export type EnvClass = (typeof ENV_CLASSES)[number];
96
+ export interface GeneRuntimeProfile {
97
+ runtime: string;
98
+ env_class?: EnvClass;
99
+ }
100
+ export declare const VERIFIER_DECISIONS: readonly ["pass", "fail", "inconclusive"];
101
+ export type VerifierDecision = (typeof VERIFIER_DECISIONS)[number];
102
+ export interface GeneVerifierProfile {
103
+ verifier: string;
104
+ decision?: VerifierDecision;
105
+ }
106
+ export interface GeneScope {
107
+ signals: string[];
108
+ predicate?: string;
109
+ }
110
+ /**
111
+ * The still-local-only Gene field names, in one place — the intake gate strips these before the gep-sdk schema
112
+ * check. IMPORTANT: when a gep-sdk gene-schema bump makes one of these first-class, REMOVE it from this list in
113
+ * the same change. Otherwise intakeGene keeps stripping a now-validated field before validateWire (fail-open —
114
+ * the field's new schema constraints go unchecked at intake) while asset_id still commits it.
115
+ *
116
+ * Only generation_meta and model_name remain local-only annotations for now, so the strip list is just those two.
74
117
  */
75
- export declare const GENE_HINT_FIELDS: readonly ["routing_hint", "tool_policy", "generation_meta"];
118
+ export declare const GENE_HINT_FIELDS: readonly ["generation_meta", "model_name"];
76
119
  /**
77
120
  * Normalize an arbitrary routing_hint fragment to a strict { tier?, reasoning_level? } object, or null.
78
121
  * Unknown enum values are dropped (a stray tier would fail the consumer's exhaustive match and route as if
@@ -101,5 +144,34 @@ export declare function normalizeToolPolicy(raw: unknown): GeneToolPolicy | null
101
144
  * alone is a meaningful provenance tag); only a missing/unknown source yields null.
102
145
  */
103
146
  export declare function normalizeGenerationMeta(raw: unknown): GenerationMeta | null;
104
- /** Strip the v2-delta hint fields from a gene-shaped object (used to validate the gep-sdk-known core). */
147
+ /**
148
+ * Normalize an arbitrary claims fragment to a strict GeneClaim[] or null. A claim survives only with a
149
+ * non-empty string `predicate`; `kind` is kept only if it is one of the closed enum members (a stray kind is
150
+ * dropped, mirroring the enum typeguards for tier/severity). Predicates are trimmed and length-bounded so a
151
+ * runaway string cannot bloat the hashed bytes. An empty result → null ("no explicit claim"), which keeps the
152
+ * gene OUT of strict K_auto rather than fabricating a coordinate.
153
+ */
154
+ export declare function normalizeClaims(raw: unknown): GeneClaim[] | null;
155
+ /**
156
+ * Normalize an arbitrary scope fragment to a strict { signals, predicate? } object or null. `signals` keeps only
157
+ * non-empty trimmed strings; the block collapses to null when none survive (an empty signal list is not a scope).
158
+ * `predicate` is kept only as a non-empty trimmed string. Deliberately lossy like the hint normalizers.
159
+ */
160
+ export declare function normalizeGeneScope(raw: unknown): GeneScope | null;
161
+ /**
162
+ * Normalize an arbitrary runtime_profile fragment to { runtime, env_class? } or null. `runtime` must be a
163
+ * non-empty trimmed string (the coordinate is meaningless without it); `env_class` is kept only if it is a
164
+ * closed enum member. Note this is DISTINCT from the flat `model_name` field — model_name records WHICH LLM
165
+ * produced the gene (an authorship/tier signal); runtime_profile records the EXECUTION environment class the
166
+ * claims were established under. A producer may set either, both, or neither.
167
+ */
168
+ export declare function normalizeRuntimeProfile(raw: unknown): GeneRuntimeProfile | null;
169
+ /**
170
+ * Normalize an arbitrary verifier_profile fragment to { verifier, decision? } or null. `verifier` must be a
171
+ * non-empty trimmed string; `decision` is kept only if it is a closed enum member. This is the verifier IDENTITY
172
+ * axis (e.g. 'npm-test', 'gep-verify@1.4'); the substantive-command bar the strict validator applies is checked
173
+ * downstream in kautoValidator.decideVerifier, not here — this layer only shapes the field.
174
+ */
175
+ export declare function normalizeVerifierProfile(raw: unknown): GeneVerifierProfile | null;
176
+ /** Strip only local-only Gene annotations before validating against the gep-sdk schema. */
105
177
  export declare function stripGeneHints(gene: Record<string, unknown>): Record<string, unknown>;
@@ -3,15 +3,14 @@
3
3
  * router (routing_hint) or restrict tools (tool_policy). Ported from v1 src/gep/schemas/gene.js (PR #93,
4
4
  * "wire routing_hint and tool_policy into Gene schema").
5
5
  *
6
- * v2-delta (feature-gate): these fields are NOT yet in @evomap/gep-sdk's gene.schema.json
7
- * (additionalProperties:false), so a Gene carrying them is not a schema-valid gep-sdk asset until a
8
- * gep-sdk gene-schema bump exactly how Capsule's proof_of_work / resolution_status were v2-delta before
9
- * the 1.11.0 bump made them first-class. That invalidity is surfaced ONLY by the advisory validateWire
10
- * (wire/schemaGate) at intake on the hint-stripped core, and via the evolver_gep_build pre-publish
11
- * preview — plus the hub's own schema check on receipt; there is NO enforced local egress gate (the
12
- * publish/egress path is sanitize-only and does not call validateWire). Until a bump the hints ride along
13
- * LOCALLY (intake pool + v1→v2 import fidelity); nothing in this repo wires them to a runtime consumer yet
14
- * (the proxy model router's `gene_hint` seam is the eventual tier consumer — see
6
+ * routing_hint / tool_policy and the K_auto coordinates are first-class in @evomap/gep-sdk 1.13.0, so they
7
+ * are normalized here rather than stripped. generation_meta and model_name remain local-only annotations for
8
+ * now. The advisory validateWire still surfaces any malformed shape at intake on the local-only slice, and
9
+ * via the evolver_gep_build pre-publish preview plus the hub's own schema check on receipt; there is NO
10
+ * enforced local egress gate (the publish/egress path is sanitize-only and does not call validateWire).
11
+ *
12
+ * Until a future schema bump, nothing in this repo wires these annotations to a runtime consumer yet (the
13
+ * proxy model router's `gene_hint` seam is the eventual tier consumer see
15
14
  * packages/evolver-proxy/src/router/modelRouter.ts).
16
15
  *
17
16
  * Enum strings are matched case-sensitively by the consuming router / tool-gate — keep them EXACT. The
@@ -32,12 +31,37 @@ export const TOOL_POLICY_SEVERITIES = ['warn', 'block'];
32
31
  */
33
32
  export const GENERATION_SOURCES = ['evolved', 'distilled', 'manual'];
34
33
  /**
35
- * The v2-delta hint field names, in one place the intake gate strips these before the gep-sdk schema check.
36
- * IMPORTANT: when a gep-sdk gene-schema bump makes one of these first-class, REMOVE it from this list in the
37
- * same change. Otherwise intakeGene keeps stripping a now-validated field before validateWire (fail-open the
38
- * field's new schema constraints go unchecked at intake) while asset_id still commits it.
34
+ * K_auto projection-key coordinates a Gene MAY carry so its record is machine-decidable in the strict
35
+ * automatic-governance subdomain (paper §K_auto; validator: algo/kautoValidator.ts). These four fields are the
36
+ * DEDICATED, structured form of the coordinates that production previously expressed only through proxy fields
37
+ * (category≈claim, signals_match≈scope, model_name≈runtime, validation≈verifier). The strict measurement
38
+ * (bench/thesis/result-kauto-strict.json) found the dedicated fields populated at 0% and three coordinates
39
+ * (version/claim/scope) undecidable for 100% of 5,665 real rows — the writer side simply never emitted them.
40
+ *
41
+ * Shapes mirror gep-sdk 1.13.0 gene.schema.json (PR: add Gene K_auto coordinates), the schema-authoritative
42
+ * definition, EXACTLY so a gene minted here validates once the SDK bump lands:
43
+ * claims: {predicate:string, kind?:'behavioral'|'structural'|'performance'|'safety'}[]
44
+ * scope: {signals:string[], predicate?:string}
45
+ * runtime_profile: {runtime:string, env_class?:'ci'|'local'|'prod'|'sandbox'}
46
+ * verifier_profile: {verifier:string, decision?:'pass'|'fail'|'inconclusive'}
47
+ *
48
+ * Since gep-sdk 1.13.0, these four coordinates are first-class Gene fields: the intake schema gate validates
49
+ * their dedicated structure instead of stripping them as local-only hints. They still ride along in asset_id
50
+ * (canonicalize hashes every own key), so a silent strip on the hub side would change the hashed bytes and fail
51
+ * gene_asset_id_verification_failed; the hub allowlist admits them for exactly this reason.
39
52
  */
40
- export const GENE_HINT_FIELDS = ['routing_hint', 'tool_policy', 'generation_meta'];
53
+ export const CLAIM_KINDS = ['behavioral', 'structural', 'performance', 'safety'];
54
+ export const ENV_CLASSES = ['ci', 'local', 'prod', 'sandbox'];
55
+ export const VERIFIER_DECISIONS = ['pass', 'fail', 'inconclusive'];
56
+ /**
57
+ * The still-local-only Gene field names, in one place — the intake gate strips these before the gep-sdk schema
58
+ * check. IMPORTANT: when a gep-sdk gene-schema bump makes one of these first-class, REMOVE it from this list in
59
+ * the same change. Otherwise intakeGene keeps stripping a now-validated field before validateWire (fail-open —
60
+ * the field's new schema constraints go unchecked at intake) while asset_id still commits it.
61
+ *
62
+ * Only generation_meta and model_name remain local-only annotations for now, so the strip list is just those two.
63
+ */
64
+ export const GENE_HINT_FIELDS = ['generation_meta', 'model_name'];
41
65
  function includesEnum(set, v) {
42
66
  return typeof v === 'string' && set.includes(v);
43
67
  }
@@ -140,7 +164,92 @@ export function normalizeGenerationMeta(raw) {
140
164
  out.overcame_errors = errs;
141
165
  return out;
142
166
  }
143
- /** Strip the v2-delta hint fields from a gene-shaped object (used to validate the gep-sdk-known core). */
167
+ /**
168
+ * Normalize an arbitrary claims fragment to a strict GeneClaim[] or null. A claim survives only with a
169
+ * non-empty string `predicate`; `kind` is kept only if it is one of the closed enum members (a stray kind is
170
+ * dropped, mirroring the enum typeguards for tier/severity). Predicates are trimmed and length-bounded so a
171
+ * runaway string cannot bloat the hashed bytes. An empty result → null ("no explicit claim"), which keeps the
172
+ * gene OUT of strict K_auto rather than fabricating a coordinate.
173
+ */
174
+ export function normalizeClaims(raw) {
175
+ if (!Array.isArray(raw))
176
+ return null;
177
+ const out = [];
178
+ for (const item of raw) {
179
+ if (!item || typeof item !== 'object')
180
+ continue;
181
+ const r = item;
182
+ const predicate = typeof r['predicate'] === 'string' ? r['predicate'].trim().slice(0, 500) : '';
183
+ if (!predicate)
184
+ continue;
185
+ const claim = { predicate };
186
+ if (includesEnum(CLAIM_KINDS, r['kind']))
187
+ claim.kind = r['kind'];
188
+ out.push(claim);
189
+ }
190
+ return out.length > 0 ? out : null;
191
+ }
192
+ /**
193
+ * Normalize an arbitrary scope fragment to a strict { signals, predicate? } object or null. `signals` keeps only
194
+ * non-empty trimmed strings; the block collapses to null when none survive (an empty signal list is not a scope).
195
+ * `predicate` is kept only as a non-empty trimmed string. Deliberately lossy like the hint normalizers.
196
+ */
197
+ export function normalizeGeneScope(raw) {
198
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
199
+ return null;
200
+ const r = raw;
201
+ // Trim signals and drop whitespace-only ones (cleanToolList keeps by raw length, which would leak ' ' and an
202
+ // untrimmed ' x ' into the hashed bytes). A scope signal is an identity/constraint term, so its canonical form
203
+ // is the trimmed token — the strict validator reads it trimmed anyway (decideScope maps through str()).
204
+ const signals = Array.isArray(r['signals'])
205
+ ? r['signals'].filter((x) => typeof x === 'string').map((s) => s.trim()).filter((s) => s.length > 0)
206
+ : [];
207
+ if (signals.length === 0)
208
+ return null;
209
+ const out = { signals };
210
+ const predicate = typeof r['predicate'] === 'string' ? r['predicate'].trim().slice(0, 500) : '';
211
+ if (predicate)
212
+ out.predicate = predicate;
213
+ return out;
214
+ }
215
+ /**
216
+ * Normalize an arbitrary runtime_profile fragment to { runtime, env_class? } or null. `runtime` must be a
217
+ * non-empty trimmed string (the coordinate is meaningless without it); `env_class` is kept only if it is a
218
+ * closed enum member. Note this is DISTINCT from the flat `model_name` field — model_name records WHICH LLM
219
+ * produced the gene (an authorship/tier signal); runtime_profile records the EXECUTION environment class the
220
+ * claims were established under. A producer may set either, both, or neither.
221
+ */
222
+ export function normalizeRuntimeProfile(raw) {
223
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
224
+ return null;
225
+ const r = raw;
226
+ const runtime = typeof r['runtime'] === 'string' ? r['runtime'].trim().slice(0, 100) : '';
227
+ if (!runtime)
228
+ return null;
229
+ const out = { runtime };
230
+ if (includesEnum(ENV_CLASSES, r['env_class']))
231
+ out.env_class = r['env_class'];
232
+ return out;
233
+ }
234
+ /**
235
+ * Normalize an arbitrary verifier_profile fragment to { verifier, decision? } or null. `verifier` must be a
236
+ * non-empty trimmed string; `decision` is kept only if it is a closed enum member. This is the verifier IDENTITY
237
+ * axis (e.g. 'npm-test', 'gep-verify@1.4'); the substantive-command bar the strict validator applies is checked
238
+ * downstream in kautoValidator.decideVerifier, not here — this layer only shapes the field.
239
+ */
240
+ export function normalizeVerifierProfile(raw) {
241
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
242
+ return null;
243
+ const r = raw;
244
+ const verifier = typeof r['verifier'] === 'string' ? r['verifier'].trim().slice(0, 100) : '';
245
+ if (!verifier)
246
+ return null;
247
+ const out = { verifier };
248
+ if (includesEnum(VERIFIER_DECISIONS, r['decision']))
249
+ out.decision = r['decision'];
250
+ return out;
251
+ }
252
+ /** Strip only local-only Gene annotations before validating against the gep-sdk schema. */
144
253
  export function stripGeneHints(gene) {
145
254
  const hidden = GENE_HINT_FIELDS;
146
255
  const out = {};
@@ -2,7 +2,7 @@
2
2
  * 资产 wire 层. SSOT = @evomap/gep-sdk/schemas/*.schema.json (D19).
3
3
  * 字段一律 snake_case 锁定 (asset_id 跨实现契约); 本仓不发明 wire 字段, 只镜像 + 重导出工具.
4
4
  */
5
- import type { GeneRoutingHint, GeneToolPolicy, GenerationMeta } from './geneHints.js';
5
+ import type { GeneRoutingHint, GeneToolPolicy, GenerationMeta, GeneClaim, GeneScope, GeneRuntimeProfile, GeneVerifierProfile } from './geneHints.js';
6
6
  export { SCHEMA_VERSION, canonicalize, computeAssetId, verifyAssetId } from '@evomap/gep-sdk';
7
7
  export type GepCategory = typeof import('@evomap/gep-sdk').GEP_GENE_CATEGORIES[number];
8
8
  export type OutcomeStatus = typeof import('@evomap/gep-sdk').GEP_OUTCOME_STATUSES[number];
@@ -35,6 +35,11 @@ export interface Gene {
35
35
  routing_hint?: GeneRoutingHint | null;
36
36
  tool_policy?: GeneToolPolicy | null;
37
37
  generation_meta?: GenerationMeta | null;
38
+ model_name?: string;
39
+ claims?: GeneClaim[] | null;
40
+ scope?: GeneScope | null;
41
+ runtime_profile?: GeneRuntimeProfile | null;
42
+ verifier_profile?: GeneVerifierProfile | null;
38
43
  asset_id: string;
39
44
  }
40
45
  /** Capsule = 表现型/纯进化产物 (capsule.schema.json). */
@@ -99,5 +104,5 @@ export interface Mutation {
99
104
  expected_effect: string;
100
105
  risk_level: RiskLevel;
101
106
  }
102
- export { validateWire, schemaProperties, type WireValidation } from './schemaGate.js';
103
- export { ROUTING_TIERS, REASONING_LEVELS, TOOL_POLICY_SEVERITIES, GENERATION_SOURCES, GENE_HINT_FIELDS, normalizeRoutingHint, normalizeToolPolicy, normalizeGenerationMeta, stripGeneHints, type RoutingTier, type ReasoningLevel, type ToolPolicySeverity, type GenerationSource, type GeneRoutingHint, type GeneToolPolicy, type GeneGenerationHeuristics, type GenerationMeta, } from './geneHints.js';
107
+ export { validateWire, validateWireDeep, wireSchemaIssues, schemaProperties, type WireValidation, type WireSchemaIssue, } from './schemaGate.js';
108
+ export { ROUTING_TIERS, REASONING_LEVELS, TOOL_POLICY_SEVERITIES, GENERATION_SOURCES, CLAIM_KINDS, ENV_CLASSES, VERIFIER_DECISIONS, GENE_HINT_FIELDS, normalizeRoutingHint, normalizeToolPolicy, normalizeGenerationMeta, normalizeClaims, normalizeGeneScope, normalizeRuntimeProfile, normalizeVerifierProfile, stripGeneHints, type RoutingTier, type ReasoningLevel, type ToolPolicySeverity, type GenerationSource, type ClaimKind, type EnvClass, type VerifierDecision, type GeneRoutingHint, type GeneToolPolicy, type GeneGenerationHeuristics, type GenerationMeta, type GeneClaim, type GeneScope, type GeneRuntimeProfile, type GeneVerifierProfile, } from './geneHints.js';
@@ -1,3 +1,3 @@
1
1
  export { SCHEMA_VERSION, canonicalize, computeAssetId, verifyAssetId } from '@evomap/gep-sdk';
2
- export { validateWire, schemaProperties } from './schemaGate.js';
3
- export { ROUTING_TIERS, REASONING_LEVELS, TOOL_POLICY_SEVERITIES, GENERATION_SOURCES, GENE_HINT_FIELDS, normalizeRoutingHint, normalizeToolPolicy, normalizeGenerationMeta, stripGeneHints, } from './geneHints.js';
2
+ export { validateWire, validateWireDeep, wireSchemaIssues, schemaProperties, } from './schemaGate.js';
3
+ export { ROUTING_TIERS, REASONING_LEVELS, TOOL_POLICY_SEVERITIES, GENERATION_SOURCES, CLAIM_KINDS, ENV_CLASSES, VERIFIER_DECISIONS, GENE_HINT_FIELDS, normalizeRoutingHint, normalizeToolPolicy, normalizeGenerationMeta, normalizeClaims, normalizeGeneScope, normalizeRuntimeProfile, normalizeVerifierProfile, stripGeneHints, } from './geneHints.js';
@@ -2,10 +2,31 @@ export interface WireValidation {
2
2
  ok: boolean;
3
3
  errors: string[];
4
4
  }
5
+ /** One schema violation located at a concrete field, so a caller can decide what to do about THAT field.
6
+ * `validateWireDeep`'s message strings are deliberately stable/opaque; repair needs the location instead. */
7
+ export interface WireSchemaIssue {
8
+ /** Dotted path into the record (`constraints.forbidden_paths`); `''` for a record-level violation. */
9
+ path: string;
10
+ /** Ajv keyword that failed (`required`, `additionalProperties`, `minItems`, `pattern`, …). */
11
+ keyword: string;
12
+ /** Field named by a record-level violation: the missing required prop or the rejected extra prop. */
13
+ property?: string;
14
+ message: string;
15
+ }
5
16
  /**
6
17
  * 结构校验(required 齐 + additionalProperties:false 不许多字段). 轻量, 不做深类型校验(那是发版 CI conformance 的活).
7
18
  * 用途: 发 hub 前确认资产能被 gep-sdk schema 接受; v2-delta(proof_of_work/resolution_status)在 bump 前会在此暴露.
8
19
  */
9
20
  export declare function validateWire(asset: Record<string, unknown>): WireValidation;
21
+ /**
22
+ * Full Draft-07 runtime validation against the gep-sdk JSON Schema SSOT.
23
+ * Validation is observational: values are never coerced, defaulted, stripped, or otherwise mutated.
24
+ */
25
+ export declare function validateWireDeep(asset: Record<string, unknown>): WireValidation;
26
+ /**
27
+ * Every schema violation of `asset`, located by field. Same SSOT and same verdict as {@link validateWireDeep}
28
+ * (empty ⇔ ok) — this form exists for callers that must ACT on a specific field rather than only report.
29
+ */
30
+ export declare function wireSchemaIssues(asset: Record<string, unknown>): WireSchemaIssue[];
10
31
  /** schema 已声明的字段白名单(给上层判断哪些 v2-delta 尚未进 SDK). */
11
32
  export declare function schemaProperties(type: string): string[];
@@ -1,5 +1,6 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import { readFileSync } from 'node:fs';
3
+ import { Ajv } from 'ajv';
3
4
  const nodeRequire = createRequire(import.meta.url);
4
5
  const SCHEMA_SUBPATH = {
5
6
  Gene: '@evomap/gep-sdk/schemas/gene.schema.json',
@@ -19,6 +20,76 @@ function loadSchema(type) {
19
20
  cache.set(type, schema);
20
21
  return schema;
21
22
  }
23
+ function validateObjectShape(value, schema, path, errors) {
24
+ if (!schema.properties && schema.additionalProperties !== false)
25
+ return;
26
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
27
+ return;
28
+ const record = value;
29
+ for (const req of schema.required ?? []) {
30
+ if (record[req] === undefined || record[req] === null)
31
+ errors.push(`${path}: 缺 required 字段: ${req}`);
32
+ }
33
+ if (schema.additionalProperties === false && schema.properties) {
34
+ const allowed = new Set(Object.keys(schema.properties));
35
+ for (const k of Object.keys(record))
36
+ if (!allowed.has(k))
37
+ errors.push(`${path}: 多余字段(additionalProperties:false 会 reject): ${k}`);
38
+ }
39
+ for (const [key, child] of Object.entries(schema.properties ?? {})) {
40
+ const childValue = record[key];
41
+ if (childValue === undefined || childValue === null)
42
+ continue;
43
+ if (Array.isArray(childValue) && child.items) {
44
+ const itemSchema = child.items;
45
+ childValue.forEach((item, index) => validateObjectShape(item, itemSchema, `${path}.${key}[${index}]`, errors));
46
+ }
47
+ else {
48
+ validateObjectShape(childValue, child, `${path}.${key}`, errors);
49
+ }
50
+ }
51
+ }
52
+ const deepValidatorCache = new Map();
53
+ const issueValidatorCache = new Map();
54
+ const deepValidator = new Ajv({
55
+ allErrors: false,
56
+ coerceTypes: false,
57
+ removeAdditional: false,
58
+ useDefaults: false,
59
+ });
60
+ // Repair needs EVERY violation in one pass — a first-error validator would make repair converge one field per
61
+ // round-trip. Kept as a second instance so the gate's own fail-fast cost is unchanged.
62
+ const issueValidator = new Ajv({
63
+ allErrors: true,
64
+ coerceTypes: false,
65
+ removeAdditional: false,
66
+ useDefaults: false,
67
+ });
68
+ function loadDeepValidator(type) {
69
+ const schema = loadSchema(type);
70
+ if (!schema)
71
+ return undefined;
72
+ const cached = deepValidatorCache.get(type);
73
+ if (cached)
74
+ return cached;
75
+ const validator = deepValidator.compile(schema);
76
+ deepValidatorCache.set(type, validator);
77
+ return validator;
78
+ }
79
+ function loadIssueValidator(type) {
80
+ const schema = loadSchema(type);
81
+ if (!schema)
82
+ return undefined;
83
+ const cached = issueValidatorCache.get(type);
84
+ if (cached)
85
+ return cached;
86
+ const validator = issueValidator.compile(schema);
87
+ issueValidatorCache.set(type, validator);
88
+ return validator;
89
+ }
90
+ function stableSchemaError(error) {
91
+ return `wire schema violation: ${error.schemaPath} (${error.keyword})`;
92
+ }
22
93
  /**
23
94
  * 结构校验(required 齐 + additionalProperties:false 不许多字段). 轻量, 不做深类型校验(那是发版 CI conformance 的活).
24
95
  * 用途: 发 hub 前确认资产能被 gep-sdk schema 接受; v2-delta(proof_of_work/resolution_status)在 bump 前会在此暴露.
@@ -31,18 +102,56 @@ export function validateWire(asset) {
31
102
  const schema = loadSchema(type);
32
103
  if (!schema)
33
104
  return { ok: false, errors: [`未知资产类型: ${type}`] };
34
- for (const req of schema.required ?? []) {
35
- if (asset[req] === undefined || asset[req] === null)
36
- errors.push(`缺 required 字段: ${req}`);
37
- }
38
- if (schema.additionalProperties === false && schema.properties) {
39
- const allowed = new Set(Object.keys(schema.properties));
40
- for (const k of Object.keys(asset))
41
- if (!allowed.has(k))
42
- errors.push(`多余字段(additionalProperties:false 会 reject): ${k}`);
43
- }
105
+ validateObjectShape(asset, schema, type, errors);
44
106
  return { ok: errors.length === 0, errors };
45
107
  }
108
+ /**
109
+ * Full Draft-07 runtime validation against the gep-sdk JSON Schema SSOT.
110
+ * Validation is observational: values are never coerced, defaulted, stripped, or otherwise mutated.
111
+ */
112
+ export function validateWireDeep(asset) {
113
+ const type = asset['type'];
114
+ if (typeof type !== 'string')
115
+ return { ok: false, errors: ['wire schema requires a string type'] };
116
+ const validator = loadDeepValidator(type);
117
+ if (!validator)
118
+ return { ok: false, errors: ['unsupported wire type'] };
119
+ if (validator(asset))
120
+ return { ok: true, errors: [] };
121
+ return {
122
+ ok: false,
123
+ errors: (validator.errors ?? []).map(stableSchemaError),
124
+ };
125
+ }
126
+ function issueFrom(error) {
127
+ const property = error.keyword === 'required'
128
+ ? String(error.params.missingProperty ?? '')
129
+ : error.keyword === 'additionalProperties'
130
+ ? String(error.params.additionalProperty ?? '')
131
+ : '';
132
+ const instancePath = error.instancePath.replace(/^\//, '').replace(/\//g, '.');
133
+ return {
134
+ path: property ? [instancePath, property].filter(Boolean).join('.') : instancePath,
135
+ keyword: error.keyword,
136
+ ...(property ? { property } : {}),
137
+ message: error.message ?? stableSchemaError(error),
138
+ };
139
+ }
140
+ /**
141
+ * Every schema violation of `asset`, located by field. Same SSOT and same verdict as {@link validateWireDeep}
142
+ * (empty ⇔ ok) — this form exists for callers that must ACT on a specific field rather than only report.
143
+ */
144
+ export function wireSchemaIssues(asset) {
145
+ const type = asset['type'];
146
+ if (typeof type !== 'string')
147
+ return [{ path: 'type', keyword: 'type', property: 'type', message: 'wire schema requires a string type' }];
148
+ const validator = loadIssueValidator(type);
149
+ if (!validator)
150
+ return [{ path: 'type', keyword: 'enum', property: 'type', message: 'unsupported wire type' }];
151
+ if (validator(asset))
152
+ return [];
153
+ return (validator.errors ?? []).map(issueFrom);
154
+ }
46
155
  /** schema 已声明的字段白名单(给上层判断哪些 v2-delta 尚未进 SDK). */
47
156
  export function schemaProperties(type) {
48
157
  return Object.keys(loadSchema(type)?.properties ?? {});
@@ -14,13 +14,26 @@ export interface CoreCall {
14
14
  fn: string;
15
15
  args: Value[];
16
16
  }
17
- export interface ScriptStep {
17
+ export type WorkflowErrorClass = 'transient' | 'permanent' | 'safety' | 'unknown';
18
+ export declare function containsWorkflowSensitiveText(value: string): boolean;
19
+ export interface WorkflowRetryPolicy {
20
+ maxAttempts: number;
21
+ initialDelayMs?: number;
22
+ maxDelayMs?: number;
23
+ multiplier?: number;
24
+ }
25
+ export interface DurableStepOptions {
26
+ /** Agent steps default to non-idempotent; script steps default to idempotent. */
27
+ idempotency?: 'idempotent' | 'non_idempotent';
28
+ retry?: WorkflowRetryPolicy;
29
+ }
30
+ export interface ScriptStep extends DurableStepOptions {
18
31
  id: string;
19
32
  kind: 'script';
20
33
  setOutput: string;
21
34
  call: CoreCall;
22
35
  }
23
- export interface AgentStep {
36
+ export interface AgentStep extends DurableStepOptions {
24
37
  id: string;
25
38
  kind: 'agent';
26
39
  prompt: string;
@@ -42,8 +55,16 @@ export interface IfStep {
42
55
  then: WorkflowStep[];
43
56
  else?: WorkflowStep[];
44
57
  }
45
- export type WorkflowStep = ScriptStep | AgentStep | ForeachStep | IfStep;
58
+ /** Durable human gate. Execution stops before subsequent steps until an operator approves or rejects it. */
59
+ export interface ApprovalStep {
60
+ id: string;
61
+ kind: 'approval';
62
+ label?: string;
63
+ }
64
+ export type WorkflowStep = ScriptStep | AgentStep | ForeachStep | IfStep | ApprovalStep;
46
65
  export interface WorkflowSpec {
66
+ /** Stable caller-supplied identity. If omitted, the durable runtime derives one from the definition. */
67
+ workflowId?: string;
47
68
  name: string;
48
69
  input?: Record<string, unknown>;
49
70
  steps: WorkflowStep[];
@@ -3,6 +3,10 @@
3
3
  * 表达式表示为**结构化对象**(非字符串解析): 引用 Ref + 白名单 core 调用, 安全 by-construction.
4
4
  */
5
5
  export function isRef(v) { return typeof v === 'object' && v !== null && 'ref' in v; }
6
+ const WORKFLOW_SENSITIVE_TEXT_RE = /(?:\bBearer\s+[A-Za-z0-9._~+/=-]{8,}|\bsk-[A-Za-z0-9_-]{12,}|\b(?:gh[oprsu]|npm)_[A-Za-z0-9_-]{8,}|\bgithub_pat_[A-Za-z0-9_]{8,}|\b(?:AKIA|ASIA)[0-9A-Z]{16}\b|\bAIza[0-9A-Za-z_-]{35}\b|-----BEGIN [A-Z ]*PRIVATE KEY-----|\b(?:password|passwd|secret|token|api[_-]?key|accountkey)\s*[:=]\s*\S+)/i;
7
+ export function containsWorkflowSensitiveText(value) {
8
+ return WORKFLOW_SENSITIVE_TEXT_RE.test(value);
9
+ }
6
10
  export const CORE_WHITELIST = {
7
11
  list_len: (a) => (Array.isArray(a) ? a.length : 0),
8
12
  filter_by_mask: (items, mask) => (Array.isArray(items) && Array.isArray(mask) ? items.filter((_, i) => Boolean(mask[i])) : []),
@@ -4,8 +4,12 @@ export interface WorkflowContext {
4
4
  steps: Record<string, unknown>;
5
5
  item?: unknown;
6
6
  }
7
+ export interface AgentBridgeOptions {
8
+ /** Cooperative cancellation for the current durable attempt. */
9
+ signal?: AbortSignal;
10
+ }
7
11
  /** agent step 桥(注入 runtime; 孵化期可注 stub). */
8
- export type AgentBridge = (prompt: string, ctx: WorkflowContext) => Promise<unknown> | unknown;
12
+ export type AgentBridge = (prompt: string, ctx: WorkflowContext, options?: AgentBridgeOptions) => Promise<unknown> | unknown;
9
13
  export interface WorkflowEngineDeps {
10
14
  core?: Record<string, CoreFn>;
11
15
  agent: AgentBridge;
@@ -68,6 +68,9 @@ export class WorkflowEngine {
68
68
  await this.runSteps(branch, ctx);
69
69
  return;
70
70
  }
71
+ case 'approval': {
72
+ throw new WorkflowError('approval steps require DurableWorkflowRuntime');
73
+ }
71
74
  case 'foreach': {
72
75
  const items = resolveRef(step.over.ref, ctx);
73
76
  if (!Array.isArray(items))
@@ -1,2 +1,4 @@
1
1
  export * from './dsl.js';
2
- export * from './engine.js';
2
+ export * from './engine.js';
3
+ export * from './stateStore.js';
4
+ export * from './runtime.js';
@@ -1,2 +1,4 @@
1
1
  export * from './dsl.js';
2
- export * from './engine.js';
2
+ export * from './engine.js';
3
+ export * from './stateStore.js';
4
+ export * from './runtime.js';