@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.
- package/assets/gep/genes.jsonl +5 -5
- package/dist/algo/bans.d.ts +10 -1
- package/dist/algo/bans.js +56 -6
- package/dist/algo/candidateAssembly.d.ts +25 -2
- package/dist/algo/candidateAssembly.js +171 -26
- package/dist/algo/capabilityCandidates.js +10 -0
- package/dist/algo/conversationSniffer.js +25 -8
- package/dist/algo/cycleEngine.d.ts +63 -5
- package/dist/algo/cycleEngine.js +320 -42
- package/dist/algo/cycleFailureClassifier.d.ts +1 -1
- package/dist/algo/evolutionEvent.d.ts +26 -0
- package/dist/algo/evolutionEvent.js +32 -0
- package/dist/algo/exploration.d.ts +7 -0
- package/dist/algo/exploration.js +16 -3
- package/dist/algo/geneHealth.d.ts +36 -3
- package/dist/algo/geneHealth.js +47 -4
- package/dist/algo/geneIntake.d.ts +46 -1
- package/dist/algo/geneIntake.js +121 -10
- package/dist/algo/geneSelection.d.ts +126 -6
- package/dist/algo/geneSelection.js +479 -36
- package/dist/algo/index.d.ts +6 -1
- package/dist/algo/index.js +6 -1
- package/dist/algo/kautoProjection.d.ts +41 -0
- package/dist/algo/kautoProjection.js +95 -0
- package/dist/algo/kautoValidator.d.ts +68 -0
- package/dist/algo/kautoValidator.js +256 -0
- package/dist/algo/memoryGraph.d.ts +62 -0
- package/dist/algo/memoryGraph.js +86 -0
- package/dist/algo/orchestrator.d.ts +17 -1
- package/dist/algo/orchestrator.js +30 -4
- package/dist/algo/publishEligibility.d.ts +34 -0
- package/dist/algo/publishEligibility.js +52 -0
- package/dist/algo/solidify.d.ts +11 -2
- package/dist/algo/solidify.js +37 -7
- package/dist/algo/ucb1.d.ts +53 -0
- package/dist/algo/ucb1.js +156 -0
- package/dist/assetrepair/hubRejection.d.ts +12 -0
- package/dist/assetrepair/hubRejection.js +109 -0
- package/dist/assetrepair/index.d.ts +2 -0
- package/dist/assetrepair/index.js +2 -0
- package/dist/assetrepair/repair.d.ts +33 -0
- package/dist/assetrepair/repair.js +155 -0
- package/dist/assetstore/assetSidecarRecords.d.ts +28 -0
- package/dist/assetstore/assetSidecarRecords.js +384 -0
- package/dist/assetstore/assetSidecarRecovery.d.ts +48 -0
- package/dist/assetstore/assetSidecarRecovery.js +288 -0
- package/dist/assetstore/assetStoreHealth.d.ts +81 -0
- package/dist/assetstore/assetStoreHealth.js +319 -0
- package/dist/assetstore/assetStoreLayout.d.ts +2 -0
- package/dist/assetstore/assetStoreLayout.js +6 -0
- package/dist/assetstore/assetStoreStorage.d.ts +42 -0
- package/dist/assetstore/assetStoreStorage.js +336 -0
- package/dist/assetstore/assetSyncLedger.d.ts +91 -1
- package/dist/assetstore/assetSyncLedger.js +718 -59
- package/dist/assetstore/foreignJsonlSource.d.ts +48 -0
- package/dist/assetstore/foreignJsonlSource.js +150 -0
- package/dist/assetstore/index.d.ts +5 -0
- package/dist/assetstore/index.js +5 -0
- package/dist/assetstore/learningHistory.js +3 -3
- package/dist/assetstore/localAssetStoreSnapshot.d.ts +51 -0
- package/dist/assetstore/localAssetStoreSnapshot.js +329 -0
- package/dist/assetstore/localJsonl.d.ts +12 -1
- package/dist/assetstore/localJsonl.js +251 -42
- package/dist/assetstore/provenance.d.ts +93 -4
- package/dist/assetstore/provenance.js +368 -84
- package/dist/assetstore/provider.d.ts +63 -0
- package/dist/assetstore/provider.js +97 -6
- package/dist/assetstore/reviewFilter.d.ts +19 -1
- package/dist/assetstore/reviewFilter.js +39 -1
- package/dist/assetstore/reviewLedger.d.ts +8 -2
- package/dist/assetstore/reviewLedger.js +71 -45
- package/dist/assetstore/unionReadStore.d.ts +25 -0
- package/dist/assetstore/unionReadStore.js +119 -0
- package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
- package/dist/benchmark/antiGeneBenchmark.js +4 -3
- package/dist/benchmark/antiGeneRollout.d.ts +2 -0
- package/dist/benchmark/antiGeneRollout.js +4 -3
- package/dist/benchmark/index.d.ts +3 -1
- package/dist/benchmark/index.js +3 -1
- package/dist/benchmark/selectionFlatAbstention.d.ts +152 -0
- package/dist/benchmark/selectionFlatAbstention.js +481 -0
- package/dist/benchmark/triggerShift.d.ts +62 -0
- package/dist/benchmark/triggerShift.js +106 -0
- package/dist/bootstrap/envFingerprint.d.ts +9 -0
- package/dist/bootstrap/envFingerprint.js +5 -0
- package/dist/bootstrap/index.d.ts +3 -1
- package/dist/bootstrap/index.js +3 -1
- package/dist/bootstrap/lifecycleBootstrap.d.ts +111 -0
- package/dist/bootstrap/lifecycleBootstrap.js +433 -0
- package/dist/bootstrap/v1EnvCompat.d.ts +113 -0
- package/dist/bootstrap/v1EnvCompat.js +303 -0
- package/dist/events/eventArchive.d.ts +2 -0
- package/dist/events/eventArchive.js +13 -3
- package/dist/events/eventSchema.d.ts +7 -7
- package/dist/events/eventStore.d.ts +2 -0
- package/dist/events/eventStore.js +5 -1
- package/dist/events/ingest.d.ts +2 -1
- package/dist/events/ingest.js +15 -0
- package/dist/events/paths.d.ts +12 -10
- package/dist/events/paths.js +24 -20
- package/dist/events/public.d.ts +2 -2
- package/dist/events/public.js +2 -2
- package/dist/events/reports.d.ts +2 -0
- package/dist/events/reports.js +4 -0
- package/dist/exec/autoExec.d.ts +68 -4
- package/dist/exec/autoExec.js +392 -33
- package/dist/exec/autonomousCycle.d.ts +31 -4
- package/dist/exec/autonomousCycle.js +71 -13
- package/dist/exec/claudeBridge.d.ts +80 -15
- package/dist/exec/claudeBridge.js +845 -76
- package/dist/exec/executionBinding.d.ts +414 -0
- package/dist/exec/executionBinding.js +588 -0
- package/dist/exec/index.d.ts +1 -0
- package/dist/exec/index.js +1 -0
- package/dist/exec/openPrRegistry.d.ts +8 -2
- package/dist/exec/openPrRegistry.js +32 -22
- package/dist/exec/prompt.js +14 -1
- package/dist/exec/proofOfWork.d.ts +1 -1
- package/dist/exec/proofOfWork.js +2 -2
- package/dist/exec/runnerRegistry.d.ts +153 -36
- package/dist/exec/runnerRegistry.js +848 -65
- package/dist/exec/selfPr.js +1 -7
- package/dist/feedback/envelope.d.ts +61 -0
- package/dist/feedback/envelope.js +168 -0
- package/dist/feedback/index.d.ts +1 -0
- package/dist/feedback/index.js +1 -0
- package/dist/hooks/hooks.js +1 -0
- package/dist/hub/assetCallLog.d.ts +35 -1
- package/dist/hub/assetCallLog.js +124 -1
- package/dist/hub/bindings.d.ts +8 -1
- package/dist/hub/bindings.js +29 -8
- package/dist/hub/capability.d.ts +130 -4
- package/dist/hub/conversationDistiller.d.ts +19 -0
- package/dist/hub/conversationDistiller.js +115 -37
- package/dist/hub/fake.d.ts +3 -2
- package/dist/hub/fake.js +2 -1
- package/dist/hub/index.d.ts +1 -0
- package/dist/hub/index.js +1 -0
- package/dist/hub/questionGenerator.d.ts +5 -1
- package/dist/hub/questionGenerator.js +8 -6
- package/dist/hub/recipeCompose.d.ts +27 -0
- package/dist/hub/recipeCompose.js +90 -0
- package/dist/hub/sanitize.js +122 -7
- package/dist/index.d.ts +6 -1
- package/dist/index.js +7 -1
- package/dist/issueReporter/index.d.ts +156 -0
- package/dist/issueReporter/index.js +1688 -0
- package/dist/mailbox/dispatch.d.ts +1 -1
- package/dist/mailbox/dispatch.js +22 -6
- package/dist/mailbox/envelope.d.ts +7 -1
- package/dist/mailbox/envelope.js +9 -2
- package/dist/mailbox/ipcServer.d.ts +12 -2
- package/dist/mailbox/ipcServer.js +183 -13
- package/dist/mailbox/store.d.ts +89 -3
- package/dist/mailbox/store.js +895 -41
- package/dist/modelCompatibility.d.ts +164 -0
- package/dist/modelCompatibility.js +309 -0
- package/dist/observers/valueDigestObserver.d.ts +9 -0
- package/dist/observers/valueDigestObserver.js +35 -2
- package/dist/ops/cleanup.js +1 -1
- package/dist/ops/evolutionGraphProjection.d.ts +20 -0
- package/dist/ops/evolutionGraphProjection.js +315 -0
- package/dist/ops/index.d.ts +2 -1
- package/dist/ops/index.js +2 -1
- package/dist/ops/savingsCore.js +1 -2
- package/dist/ops/selfUpdate.d.ts +18 -1
- package/dist/ops/selfUpdate.js +88 -23
- package/dist/ops/valueOutreach.d.ts +3 -1
- package/dist/ops/valueOutreach.js +5 -1
- package/dist/personality/schema.d.ts +24 -24
- package/dist/schema/evolutionGraph.d.ts +784 -0
- package/dist/schema/evolutionGraph.js +187 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/proofOfWork.d.ts +125 -6
- package/dist/schema/proofOfWork.js +102 -4
- package/dist/schema/signal.d.ts +3 -3
- package/dist/schema/signal.js +1 -1
- package/dist/shadow/shadowHub.js +1 -0
- package/dist/signals/curriculum.d.ts +55 -0
- package/dist/signals/curriculum.js +202 -0
- package/dist/signals/cycleHistoryFromEvents.js +17 -8
- package/dist/signals/expand.d.ts +15 -1
- package/dist/signals/expand.js +169 -1
- package/dist/signals/extractor.d.ts +2 -2
- package/dist/signals/extractor.js +31 -6
- package/dist/signals/index.d.ts +4 -1
- package/dist/signals/index.js +4 -1
- package/dist/signals/metaSignals.d.ts +4 -0
- package/dist/signals/metaSignals.js +42 -0
- package/dist/signals/scopeVocabulary.d.ts +75 -0
- package/dist/signals/scopeVocabulary.js +91 -0
- package/dist/signals/signalGate.js +1 -1
- package/dist/signals/taskDomain.d.ts +22 -0
- package/dist/signals/taskDomain.js +43 -0
- package/dist/strategy/constraintAblation.d.ts +64 -0
- package/dist/strategy/constraintAblation.js +2820 -0
- package/dist/strategy/constraintAblationPredicates.d.ts +31 -0
- package/dist/strategy/constraintAblationPredicates.js +339 -0
- package/dist/strategy/index.d.ts +2 -1
- package/dist/strategy/index.js +2 -1
- package/dist/trace/index.d.ts +3 -1
- package/dist/trace/index.js +3 -1
- package/dist/trace/learningTrace.d.ts +216 -0
- package/dist/trace/learningTrace.js +298 -0
- package/dist/trace/proxyTurns.d.ts +31 -0
- package/dist/trace/proxyTurns.js +137 -0
- package/dist/trace/trajectory.d.ts +8 -0
- package/dist/trace/trajectory.js +14 -2
- package/dist/util/fetchPort.d.ts +1 -0
- package/dist/util/fetchPort.js +11 -0
- package/dist/util/fileLock.d.ts +113 -7
- package/dist/util/fileLock.js +1035 -80
- package/dist/util/index.d.ts +3 -1
- package/dist/util/index.js +2 -1
- package/dist/verify/index.d.ts +2 -1
- package/dist/verify/index.js +1 -1
- package/dist/verify/sandboxRunner.d.ts +30 -0
- package/dist/verify/sandboxRunner.js +370 -27
- package/dist/verify/sandboxedValidation.d.ts +16 -2
- package/dist/verify/sandboxedValidation.js +200 -22
- package/dist/verify/validation.d.ts +35 -4
- package/dist/verify/validation.js +164 -16
- package/dist/wire/geneHints.d.ts +88 -16
- package/dist/wire/geneHints.js +124 -15
- package/dist/wire/index.d.ts +8 -3
- package/dist/wire/index.js +2 -2
- package/dist/wire/schemaGate.d.ts +21 -0
- package/dist/wire/schemaGate.js +119 -10
- package/dist/workflow/dsl.d.ts +24 -3
- package/dist/workflow/dsl.js +4 -0
- package/dist/workflow/engine.d.ts +5 -1
- package/dist/workflow/engine.js +3 -0
- package/dist/workflow/index.d.ts +3 -1
- package/dist/workflow/index.js +3 -1
- package/dist/workflow/runtime.d.ts +110 -0
- package/dist/workflow/runtime.js +1298 -0
- package/dist/workflow/stateStore.d.ts +172 -0
- package/dist/workflow/stateStore.js +1044 -0
- package/package.json +12 -4
package/dist/wire/geneHints.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
|
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
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
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 ["
|
|
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
|
-
/**
|
|
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>;
|
package/dist/wire/geneHints.js
CHANGED
|
@@ -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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
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 = {};
|
package/dist/wire/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/wire/index.js
CHANGED
|
@@ -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[];
|
package/dist/wire/schemaGate.js
CHANGED
|
@@ -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
|
-
|
|
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 ?? {});
|
package/dist/workflow/dsl.d.ts
CHANGED
|
@@ -14,13 +14,26 @@ export interface CoreCall {
|
|
|
14
14
|
fn: string;
|
|
15
15
|
args: Value[];
|
|
16
16
|
}
|
|
17
|
-
export
|
|
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
|
-
|
|
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[];
|
package/dist/workflow/dsl.js
CHANGED
|
@@ -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;
|
package/dist/workflow/engine.js
CHANGED
|
@@ -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))
|
package/dist/workflow/index.d.ts
CHANGED
package/dist/workflow/index.js
CHANGED