@evomap/evolver-core 2.0.0-beta.19 → 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 +143 -20
- package/dist/algo/capabilityCandidates.js +10 -0
- package/dist/algo/cycleEngine.d.ts +40 -5
- package/dist/algo/cycleEngine.js +277 -37
- 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 +34 -1
- package/dist/algo/geneHealth.js +42 -0
- package/dist/algo/geneIntake.d.ts +46 -1
- package/dist/algo/geneIntake.js +121 -10
- package/dist/algo/geneSelection.d.ts +115 -6
- package/dist/algo/geneSelection.js +459 -32
- package/dist/algo/index.d.ts +4 -1
- package/dist/algo/index.js +4 -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/orchestrator.d.ts +14 -1
- package/dist/algo/orchestrator.js +9 -2
- 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.js +5 -1
- package/dist/assetstore/assetStoreHealth.d.ts +2 -3
- package/dist/assetstore/assetStoreHealth.js +4 -10
- package/dist/assetstore/foreignJsonlSource.d.ts +48 -0
- package/dist/assetstore/foreignJsonlSource.js +150 -0
- package/dist/assetstore/index.d.ts +3 -0
- package/dist/assetstore/index.js +3 -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 +8 -0
- package/dist/assetstore/localJsonl.js +128 -3
- package/dist/assetstore/provenance.d.ts +38 -3
- package/dist/assetstore/provenance.js +103 -45
- package/dist/assetstore/provider.d.ts +4 -0
- package/dist/assetstore/reviewFilter.d.ts +19 -1
- package/dist/assetstore/reviewFilter.js +36 -0
- 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 +2 -1
- package/dist/benchmark/index.js +2 -1
- package/dist/benchmark/selectionFlatAbstention.d.ts +152 -0
- package/dist/benchmark/selectionFlatAbstention.js +481 -0
- package/dist/bootstrap/envFingerprint.d.ts +9 -0
- package/dist/bootstrap/envFingerprint.js +5 -0
- package/dist/bootstrap/index.d.ts +2 -1
- package/dist/bootstrap/index.js +2 -1
- package/dist/bootstrap/lifecycleBootstrap.d.ts +111 -0
- package/dist/bootstrap/lifecycleBootstrap.js +433 -0
- package/dist/bootstrap/v1EnvCompat.d.ts +3 -0
- package/dist/bootstrap/v1EnvCompat.js +48 -1
- 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 +6 -0
- package/dist/exec/autoExec.d.ts +30 -3
- package/dist/exec/autoExec.js +294 -29
- package/dist/exec/autonomousCycle.d.ts +7 -0
- package/dist/exec/autonomousCycle.js +2 -0
- package/dist/exec/claudeBridge.d.ts +28 -6
- package/dist/exec/claudeBridge.js +411 -258
- 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/proofOfWork.d.ts +1 -1
- package/dist/exec/proofOfWork.js +2 -2
- package/dist/exec/runnerRegistry.d.ts +5 -0
- package/dist/exec/runnerRegistry.js +54 -14
- package/dist/hub/capability.d.ts +40 -1
- package/dist/hub/conversationDistiller.d.ts +19 -0
- package/dist/hub/conversationDistiller.js +115 -37
- package/dist/hub/fake.d.ts +1 -0
- package/dist/hub/fake.js +1 -0
- package/dist/hub/index.d.ts +1 -0
- package/dist/hub/index.js +1 -0
- package/dist/hub/recipeCompose.d.ts +27 -0
- package/dist/hub/recipeCompose.js +90 -0
- package/dist/hub/sanitize.js +119 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mailbox/ipcServer.d.ts +2 -0
- package/dist/mailbox/ipcServer.js +20 -0
- package/dist/mailbox/store.d.ts +52 -2
- package/dist/mailbox/store.js +546 -81
- 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/selfUpdate.d.ts +8 -0
- package/dist/ops/selfUpdate.js +24 -8
- package/dist/ops/valueOutreach.d.ts +3 -1
- package/dist/ops/valueOutreach.js +5 -1
- package/dist/personality/schema.d.ts +18 -18
- 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/shadow/shadowHub.js +1 -0
- package/dist/signals/expand.d.ts +15 -1
- package/dist/signals/expand.js +148 -0
- package/dist/signals/index.d.ts +3 -1
- package/dist/signals/index.js +3 -1
- package/dist/signals/scopeVocabulary.d.ts +75 -0
- package/dist/signals/scopeVocabulary.js +91 -0
- package/dist/signals/taskDomain.d.ts +22 -0
- package/dist/signals/taskDomain.js +43 -0
- package/dist/trace/learningTrace.d.ts +7 -0
- package/dist/trace/learningTrace.js +22 -0
- package/dist/trace/trajectory.d.ts +8 -0
- package/dist/trace/trajectory.js +14 -2
- package/dist/util/fileLock.d.ts +92 -5
- package/dist/util/fileLock.js +809 -70
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.js +1 -1
- package/dist/verify/index.d.ts +2 -1
- package/dist/verify/index.js +1 -1
- package/dist/verify/sandboxRunner.d.ts +2 -0
- package/dist/verify/sandboxRunner.js +154 -10
- package/dist/verify/sandboxedValidation.d.ts +7 -2
- package/dist/verify/sandboxedValidation.js +102 -24
- package/dist/verify/validation.d.ts +24 -3
- package/dist/verify/validation.js +141 -24
- 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/package.json +5 -4
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { KautoVerdict } from './kautoValidator.js';
|
|
2
|
+
/** The five coordinates of the K_auto projection key. Order is fixed for stable key encoding. */
|
|
3
|
+
export declare const PROJECTION_COORDINATES: readonly ["version", "claim", "scope", "runtime", "verifier"];
|
|
4
|
+
export type ProjectionCoordinate = (typeof PROJECTION_COORDINATES)[number];
|
|
5
|
+
/** The append-only event type a revocation is recorded under on the authoritative root-event stream. */
|
|
6
|
+
export declare const PROJECTION_REVOKED_EVENT_TYPE = "governance.projection.revoked";
|
|
7
|
+
/** A reinstatement withdraws a prior revocation of the SAME (coordinate, value) pair (reversibility). */
|
|
8
|
+
export declare const PROJECTION_REINSTATED_EVENT_TYPE = "governance.projection.reinstated";
|
|
9
|
+
export interface ProjectionRevocationPayload {
|
|
10
|
+
/** Which coordinate axis the distrust applies to. */
|
|
11
|
+
coordinate: ProjectionCoordinate;
|
|
12
|
+
/** The resolved coordinate value being distrusted (e.g. a verifier profile id or a runtime name). */
|
|
13
|
+
value: string;
|
|
14
|
+
/** Auditable reason; recorded, never interpreted. */
|
|
15
|
+
reason?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Minimal shape of a root event this reducer reads. Compatible with events/eventSchema RootEvent. */
|
|
18
|
+
export interface ProjectionSourceEvent {
|
|
19
|
+
type: string;
|
|
20
|
+
payload?: unknown;
|
|
21
|
+
}
|
|
22
|
+
/** Canonical revoked-set key. A revocation is identified by its (coordinate, value) pair, never by asset id. */
|
|
23
|
+
export declare function revocationKey(coordinate: ProjectionCoordinate, value: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Reduce the authoritative root-event history to the CURRENT set of revoked (coordinate, value) pairs. Pure and
|
|
26
|
+
* order-preserving: a revocation adds its key; a matching reinstatement removes it; later events win. Recomputing
|
|
27
|
+
* this from the same events yields a byte-identical set (replay invariant), because the root-event stream — not a
|
|
28
|
+
* mutable table — is the single source of truth (mirrors ops/evolutionGraphProjection.ts).
|
|
29
|
+
*/
|
|
30
|
+
export declare function projectRevocations(events: readonly ProjectionSourceEvent[]): Set<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Whether a record's current projection touches any revoked coordinate value. Only records whose five coordinates
|
|
33
|
+
* are all machine-decidable (`verdict.inKauto`) HAVE a projection under T1, so an undecidable record is never
|
|
34
|
+
* governed by projection revocation here (it routes through the deployed advisory/exclusion paths instead) — and
|
|
35
|
+
* this function returns false for it. For a decidable record, revocation is coordinate-LOCAL: it is revoked iff
|
|
36
|
+
* some coordinate's resolved value equals a distrusted (coordinate, value) pair; a sibling that differs on that
|
|
37
|
+
* coordinate is not.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isProjectionRevoked(verdict: KautoVerdict, revoked: ReadonlySet<string>): boolean;
|
|
40
|
+
/** The specific revoked coordinate(s) a record's projection matched — for auditing WHY a projection was dropped. */
|
|
41
|
+
export declare function revokedCoordinatesFor(verdict: KautoVerdict, revoked: ReadonlySet<string>): ProjectionCoordinate[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// K_auto EvidenceProjection — coordinate-level partial revocation over the five-coordinate key.
|
|
2
|
+
//
|
|
3
|
+
// WHY THIS EXISTS. The paper's headline abstraction is that an experience asset's validity is a projection
|
|
4
|
+
// over five coordinates — (asset version, claim, scope, runtime, verifier) — and that revocation is PARTIAL:
|
|
5
|
+
// distrusting one verifier profile quarantines every projection whose verifier coordinate names it, while
|
|
6
|
+
// leaving projections that differ on that coordinate (a sibling verifier, or a different runtime/scope)
|
|
7
|
+
// untouched. `algo/kautoValidator.ts` decides five-coordinate MEMBERSHIP (is each coordinate machine-decidable),
|
|
8
|
+
// but nothing consumed that verdict as a revocable projection: assembly collapsed it to a boolean `kautoMember`
|
|
9
|
+
// used only as a soft +λ selection preference (`algo/geneSelection.ts`), and the only real exclusion path
|
|
10
|
+
// (`algo/bans.ts`) keys on gene id × signal overlap, not on coordinates. This module realizes the missing
|
|
11
|
+
// consumer: an append-only revocation event names a (coordinate, value) pair, and a pure reducer projects the
|
|
12
|
+
// current revoked set from the authoritative root-event history so a selection guard can drop exactly the
|
|
13
|
+
// records whose projection touches a revoked coordinate value — coordinate-locally, recomputably, reversibly.
|
|
14
|
+
//
|
|
15
|
+
// DEPLOYMENT BOUNDARY. This is the T1 (specified) projection-revocation mechanism, exercised by a controlled
|
|
16
|
+
// experiment and an optional, default-OFF selection guard (`candidateAssembly` `opts.kautoProjection`). It does
|
|
17
|
+
// not change the deployed T2 path (signal-scoped gene-level `bannedGenesFromFailures` + soft λ preference), which
|
|
18
|
+
// stays byte-for-byte unchanged when the guard is absent.
|
|
19
|
+
/** The five coordinates of the K_auto projection key. Order is fixed for stable key encoding. */
|
|
20
|
+
export const PROJECTION_COORDINATES = ['version', 'claim', 'scope', 'runtime', 'verifier'];
|
|
21
|
+
/** The append-only event type a revocation is recorded under on the authoritative root-event stream. */
|
|
22
|
+
export const PROJECTION_REVOKED_EVENT_TYPE = 'governance.projection.revoked';
|
|
23
|
+
/** A reinstatement withdraws a prior revocation of the SAME (coordinate, value) pair (reversibility). */
|
|
24
|
+
export const PROJECTION_REINSTATED_EVENT_TYPE = 'governance.projection.reinstated';
|
|
25
|
+
const isCoordinate = (v) => typeof v === 'string' && PROJECTION_COORDINATES.includes(v);
|
|
26
|
+
/** Canonical revoked-set key. A revocation is identified by its (coordinate, value) pair, never by asset id. */
|
|
27
|
+
export function revocationKey(coordinate, value) {
|
|
28
|
+
return `${coordinate}:${value}`;
|
|
29
|
+
}
|
|
30
|
+
function readRevocationPayload(payload) {
|
|
31
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload))
|
|
32
|
+
return null;
|
|
33
|
+
const p = payload;
|
|
34
|
+
if (!isCoordinate(p['coordinate']))
|
|
35
|
+
return null;
|
|
36
|
+
const value = typeof p['value'] === 'string' ? p['value'].trim() : '';
|
|
37
|
+
if (!value)
|
|
38
|
+
return null;
|
|
39
|
+
const out = { coordinate: p['coordinate'], value };
|
|
40
|
+
if (typeof p['reason'] === 'string')
|
|
41
|
+
out.reason = p['reason'];
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reduce the authoritative root-event history to the CURRENT set of revoked (coordinate, value) pairs. Pure and
|
|
46
|
+
* order-preserving: a revocation adds its key; a matching reinstatement removes it; later events win. Recomputing
|
|
47
|
+
* this from the same events yields a byte-identical set (replay invariant), because the root-event stream — not a
|
|
48
|
+
* mutable table — is the single source of truth (mirrors ops/evolutionGraphProjection.ts).
|
|
49
|
+
*/
|
|
50
|
+
export function projectRevocations(events) {
|
|
51
|
+
const revoked = new Set();
|
|
52
|
+
for (const evt of events) {
|
|
53
|
+
if (evt.type === PROJECTION_REVOKED_EVENT_TYPE) {
|
|
54
|
+
const p = readRevocationPayload(evt.payload);
|
|
55
|
+
if (p)
|
|
56
|
+
revoked.add(revocationKey(p.coordinate, p.value));
|
|
57
|
+
}
|
|
58
|
+
else if (evt.type === PROJECTION_REINSTATED_EVENT_TYPE) {
|
|
59
|
+
const p = readRevocationPayload(evt.payload);
|
|
60
|
+
if (p)
|
|
61
|
+
revoked.delete(revocationKey(p.coordinate, p.value));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return revoked;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Whether a record's current projection touches any revoked coordinate value. Only records whose five coordinates
|
|
68
|
+
* are all machine-decidable (`verdict.inKauto`) HAVE a projection under T1, so an undecidable record is never
|
|
69
|
+
* governed by projection revocation here (it routes through the deployed advisory/exclusion paths instead) — and
|
|
70
|
+
* this function returns false for it. For a decidable record, revocation is coordinate-LOCAL: it is revoked iff
|
|
71
|
+
* some coordinate's resolved value equals a distrusted (coordinate, value) pair; a sibling that differs on that
|
|
72
|
+
* coordinate is not.
|
|
73
|
+
*/
|
|
74
|
+
export function isProjectionRevoked(verdict, revoked) {
|
|
75
|
+
if (!verdict.inKauto || revoked.size === 0)
|
|
76
|
+
return false;
|
|
77
|
+
for (const coordinate of PROJECTION_COORDINATES) {
|
|
78
|
+
const resolved = verdict.coordinates[coordinate].resolved;
|
|
79
|
+
if (resolved !== undefined && revoked.has(revocationKey(coordinate, resolved)))
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
/** The specific revoked coordinate(s) a record's projection matched — for auditing WHY a projection was dropped. */
|
|
85
|
+
export function revokedCoordinatesFor(verdict, revoked) {
|
|
86
|
+
if (!verdict.inKauto || revoked.size === 0)
|
|
87
|
+
return [];
|
|
88
|
+
const hits = [];
|
|
89
|
+
for (const coordinate of PROJECTION_COORDINATES) {
|
|
90
|
+
const resolved = verdict.coordinates[coordinate].resolved;
|
|
91
|
+
if (resolved !== undefined && revoked.has(revocationKey(coordinate, resolved)))
|
|
92
|
+
hits.push(coordinate);
|
|
93
|
+
}
|
|
94
|
+
return hits;
|
|
95
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AssetRecord } from '../assetstore/provider.js';
|
|
2
|
+
/** Why a coordinate could not be decided. `null` means it was decided. */
|
|
3
|
+
export type UndecidableReason = string | null;
|
|
4
|
+
export interface CoordinateVerdict {
|
|
5
|
+
decidable: boolean;
|
|
6
|
+
/** The resolved value when decidable, for auditing what the predicate actually accepted. */
|
|
7
|
+
resolved?: string;
|
|
8
|
+
reason: UndecidableReason;
|
|
9
|
+
}
|
|
10
|
+
export interface KautoVerdict {
|
|
11
|
+
inKauto: boolean;
|
|
12
|
+
coordinates: {
|
|
13
|
+
version: CoordinateVerdict;
|
|
14
|
+
claim: CoordinateVerdict;
|
|
15
|
+
scope: CoordinateVerdict;
|
|
16
|
+
runtime: CoordinateVerdict;
|
|
17
|
+
verifier: CoordinateVerdict;
|
|
18
|
+
};
|
|
19
|
+
/** Coordinate names that failed, most useful for aggregate reporting. */
|
|
20
|
+
blockedBy: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare function decideVersion(rec: Readonly<Record<string, unknown>>): CoordinateVerdict;
|
|
23
|
+
export declare const CLAIM_PREDICATES: readonly ["source_of_truth", "requires_service", "requires_tool", "forbids_action", "output_contract", "ordering_constraint", "environment_precondition"];
|
|
24
|
+
export declare function decideClaim(rec: Readonly<Record<string, unknown>>): CoordinateVerdict;
|
|
25
|
+
export declare function decideScope(rec: Readonly<Record<string, unknown>>): CoordinateVerdict;
|
|
26
|
+
export interface RuntimeRegistry {
|
|
27
|
+
has(id: string): boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function decideRuntime(rec: Readonly<Record<string, unknown>>, registry?: RuntimeRegistry): CoordinateVerdict;
|
|
30
|
+
export declare function decideVerifier(rec: Readonly<Record<string, unknown>>): CoordinateVerdict;
|
|
31
|
+
/**
|
|
32
|
+
* Decide K_auto membership for one record. All five coordinates must be decidable; we evaluate every
|
|
33
|
+
* coordinate rather than short-circuiting, so aggregate reporting can attribute the shortfall.
|
|
34
|
+
*/
|
|
35
|
+
export declare function decideKauto(record: Readonly<Record<string, unknown>> | AssetRecord, opts?: {
|
|
36
|
+
runtimeRegistry?: RuntimeRegistry;
|
|
37
|
+
}): KautoVerdict;
|
|
38
|
+
/**
|
|
39
|
+
* The PRESENCE proxy the original production query implemented, kept so the two can be reported side by
|
|
40
|
+
* side and the gap between them quantified rather than asserted.
|
|
41
|
+
*/
|
|
42
|
+
export declare function decideKautoPresenceProxy(record: Readonly<Record<string, unknown>> | AssetRecord): boolean;
|
|
43
|
+
export interface KautoStructuralVerdict {
|
|
44
|
+
/** True when the record STRUCTURALLY carries all five dedicated coordinates in canonical shape (regardless of
|
|
45
|
+
* whether their CONTENT clears the strict decidability bar). */
|
|
46
|
+
structurallyComplete: boolean;
|
|
47
|
+
coordinates: {
|
|
48
|
+
version: boolean;
|
|
49
|
+
claim: boolean;
|
|
50
|
+
scope: boolean;
|
|
51
|
+
runtime: boolean;
|
|
52
|
+
verifier: boolean;
|
|
53
|
+
};
|
|
54
|
+
/** Dedicated-coordinate names the writer did not emit in canonical shape. */
|
|
55
|
+
missing: string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The SECOND track of the dual-track report (user decision: 双轨并报). Where {@link decideKauto} answers "is each
|
|
59
|
+
* coordinate machine-DECIDABLE" (strict, closed-vocabulary bar), this answers the strictly weaker, writer-side
|
|
60
|
+
* question "did the producer EMIT the dedicated coordinate field at all, in its canonical minimal shape". The two
|
|
61
|
+
* are reported side by side so the paper can separate two failure modes that a single number conflates:
|
|
62
|
+
* - the dedicated field is ABSENT (writer never emitted it) — the 0%-adoption problem this batch attacks; vs
|
|
63
|
+
* - the dedicated field is PRESENT but its content is not yet strict (e.g. a scope signal that is not namespaced,
|
|
64
|
+
* a claim predicate outside the closed vocabulary) — a content-quality gap, not an adoption gap.
|
|
65
|
+
* Structural presence NEVER implies decidability; it is deliberately permissive so the adoption-vs-quality gap is
|
|
66
|
+
* visible rather than hidden inside the single strict figure.
|
|
67
|
+
*/
|
|
68
|
+
export declare function decideKautoStructural(record: Readonly<Record<string, unknown>> | AssetRecord): KautoStructuralVerdict;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
const str = (v) => (typeof v === 'string' ? v.trim() : '');
|
|
2
|
+
const arr = (v) => (Array.isArray(v) ? v.filter((x) => typeof x === 'string') : []);
|
|
3
|
+
// ---------------------------------------------------------------------------------------------------
|
|
4
|
+
// Version. Needs an identifier that pins THIS asset's immutable version. A record-format version
|
|
5
|
+
// (schema_version) is shared across the whole catalogue and cannot distinguish two versions of one asset,
|
|
6
|
+
// so it does not satisfy the coordinate even though it is always present.
|
|
7
|
+
// ---------------------------------------------------------------------------------------------------
|
|
8
|
+
const VERSION_FIELDS = ['asset_version', 'assetVersion', 'version', 'content_hash', 'contentHash'];
|
|
9
|
+
/** Content-addressed asset ids are immutable version pins (sha256 of canonical gene bytes). */
|
|
10
|
+
const CONTENT_ADDRESSED_ASSET_ID = /^sha256:[a-f0-9]{64}$/i;
|
|
11
|
+
export function decideVersion(rec) {
|
|
12
|
+
for (const f of VERSION_FIELDS) {
|
|
13
|
+
const v = str(rec[f]);
|
|
14
|
+
if (v)
|
|
15
|
+
return { decidable: true, resolved: `${f}=${v}`, reason: null };
|
|
16
|
+
}
|
|
17
|
+
// asset_id is the production content-address: intake always writes it, and it changes when any
|
|
18
|
+
// coordinate-bearing field changes. Accepting it closes the version coordinate without inventing a
|
|
19
|
+
// parallel asset_version field the gep-sdk schema does not yet declare.
|
|
20
|
+
const assetId = str(rec['asset_id']);
|
|
21
|
+
if (CONTENT_ADDRESSED_ASSET_ID.test(assetId)) {
|
|
22
|
+
return { decidable: true, resolved: `asset_id=${assetId}`, reason: null };
|
|
23
|
+
}
|
|
24
|
+
const schemaVersion = str(rec['schema_version']);
|
|
25
|
+
if (schemaVersion) {
|
|
26
|
+
return {
|
|
27
|
+
decidable: false,
|
|
28
|
+
reason: `only schema_version=${schemaVersion} is present; that is the record format version, shared across assets, and does not identify this asset's immutable version`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return { decidable: false, reason: 'no asset version identifier present' };
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------------------------------
|
|
34
|
+
// Claim. The closed claim vocabulary is a set of typed claim PREDICATES about what an asset asserts,
|
|
35
|
+
// distinct from `category`, which records the kind of intervention. A record carrying only `category` has
|
|
36
|
+
// an intervention type but no machine-checkable claim, so claim-level conflict detection has nothing to
|
|
37
|
+
// compare.
|
|
38
|
+
// ---------------------------------------------------------------------------------------------------
|
|
39
|
+
export const CLAIM_PREDICATES = Object.freeze([
|
|
40
|
+
'source_of_truth',
|
|
41
|
+
'requires_service',
|
|
42
|
+
'requires_tool',
|
|
43
|
+
'forbids_action',
|
|
44
|
+
'output_contract',
|
|
45
|
+
'ordering_constraint',
|
|
46
|
+
'environment_precondition',
|
|
47
|
+
]);
|
|
48
|
+
const CLAIM_FIELDS = ['claim', 'claims', 'claim_predicate', 'claimPredicate'];
|
|
49
|
+
/** Extract candidate predicate STRINGS from a claim field value, accepting both the legacy string/string[] form
|
|
50
|
+
* and the gep-sdk 1.13.0 object form `{predicate, kind}` (single or array). Non-conforming entries are dropped. */
|
|
51
|
+
function claimPredicateStrings(raw) {
|
|
52
|
+
const fromOne = (v) => {
|
|
53
|
+
if (typeof v === 'string')
|
|
54
|
+
return v;
|
|
55
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
56
|
+
const p = v['predicate'];
|
|
57
|
+
return typeof p === 'string' ? p : null;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
};
|
|
61
|
+
const items = Array.isArray(raw) ? raw : [raw];
|
|
62
|
+
return items.map(fromOne).filter((s) => typeof s === 'string' && s.trim().length > 0);
|
|
63
|
+
}
|
|
64
|
+
export function decideClaim(rec) {
|
|
65
|
+
const known = new Set(CLAIM_PREDICATES);
|
|
66
|
+
for (const f of CLAIM_FIELDS) {
|
|
67
|
+
const raw = rec[f];
|
|
68
|
+
if (raw === undefined || raw === null)
|
|
69
|
+
continue;
|
|
70
|
+
// A claim predicate names a closed-vocabulary term as its leading token — legacy `source_of_truth:...`
|
|
71
|
+
// strings and the gep-sdk `{predicate:'source_of_truth(...)'}` object form both reduce to the same token.
|
|
72
|
+
const candidates = claimPredicateStrings(raw);
|
|
73
|
+
const named = candidates.map((c) => str(c).split(/[:=(]/, 1)[0] ?? '').filter(Boolean);
|
|
74
|
+
const hit = named.find((n) => known.has(n));
|
|
75
|
+
if (hit)
|
|
76
|
+
return { decidable: true, resolved: hit, reason: null };
|
|
77
|
+
if (named.length > 0) {
|
|
78
|
+
return { decidable: false, reason: `claim predicate(s) ${named.join(', ')} are not in the closed claim vocabulary` };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const category = str(rec['category']);
|
|
82
|
+
if (category) {
|
|
83
|
+
return {
|
|
84
|
+
decidable: false,
|
|
85
|
+
reason: `only category=${category} is present; category is the intervention kind, not a claim predicate from the closed vocabulary`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return { decidable: false, reason: 'no claim predicate present' };
|
|
89
|
+
}
|
|
90
|
+
// ---------------------------------------------------------------------------------------------------
|
|
91
|
+
// Scope. Must parse in the closed constraint language, because scope containment has to be decidable for
|
|
92
|
+
// set-inclusion precedence to work. We accept the forms the paper enumerates: identity sets, version
|
|
93
|
+
// intervals, repository-lineage prefixes, capability-set containment, time intervals, enumerated sets, and
|
|
94
|
+
// registered compatibility relations. A bare tag is an identity-set element ONLY when it is namespaced,
|
|
95
|
+
// so that two tags from different producers cannot silently collide; an unqualified free-text tag is not
|
|
96
|
+
// decidable against another producer's tag of the same name.
|
|
97
|
+
// ---------------------------------------------------------------------------------------------------
|
|
98
|
+
const SCOPE_TERM = /^(?:repo|lineage|pkg|lang|framework|capability|tool|model|time|env):[A-Za-z0-9._@/:-]+$/;
|
|
99
|
+
const VERSION_INTERVAL = /^[A-Za-z0-9._-]+@(?:[><=^~]{1,2})?\d[\w.*-]*(?:\s*-\s*\d[\w.*-]*)?$/;
|
|
100
|
+
/** Do all of `terms` parse in the closed constraint language? Shared by the dedicated `scope` field and the
|
|
101
|
+
* legacy `signals_match` proxy so the SAME containment-decidability bar governs both. */
|
|
102
|
+
function decideScopeTerms(terms) {
|
|
103
|
+
if (terms.length === 0)
|
|
104
|
+
return { decidable: false, reason: 'signals_match is empty; no scope predicate' };
|
|
105
|
+
const parses = (t) => SCOPE_TERM.test(t) || VERSION_INTERVAL.test(t);
|
|
106
|
+
const undecidable = terms.filter((t) => {
|
|
107
|
+
// A hard facet gates on a term; the term itself must parse, so strip the marker and test what remains.
|
|
108
|
+
const bare = t.startsWith('required:') ? t.slice('required:'.length) : t;
|
|
109
|
+
return !parses(bare);
|
|
110
|
+
});
|
|
111
|
+
if (undecidable.length === 0) {
|
|
112
|
+
return { decidable: true, resolved: terms.join(','), reason: null };
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
decidable: false,
|
|
116
|
+
reason: `${undecidable.length} of ${terms.length} scope term(s) do not parse in the closed constraint language (e.g. ${undecidable.slice(0, 3).join(', ')}); containment against another scope is therefore undecidable`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function decideScope(rec) {
|
|
120
|
+
// Dedicated coordinate first (gep-sdk 1.13.0 `scope: {signals, predicate?}`). Its `signals` list carries the
|
|
121
|
+
// scope terms; a `predicate` is metadata for the reader, not a substitute for parseable signals. When the
|
|
122
|
+
// dedicated field is present but its signals are empty we fall through to the proxy, so a malformed dedicated
|
|
123
|
+
// field never DEMOTES a record that the legacy path would have admitted.
|
|
124
|
+
const scope = rec['scope'];
|
|
125
|
+
if (scope && typeof scope === 'object' && !Array.isArray(scope)) {
|
|
126
|
+
const signals = arr(scope['signals']).map((t) => str(t)).filter(Boolean);
|
|
127
|
+
if (signals.length > 0)
|
|
128
|
+
return decideScopeTerms(signals);
|
|
129
|
+
}
|
|
130
|
+
const terms = arr(rec['signals_match']).map((t) => str(t)).filter(Boolean);
|
|
131
|
+
return decideScopeTerms(terms);
|
|
132
|
+
}
|
|
133
|
+
/** Apply the runtime bar to one resolved identity string, `src` naming where it came from for the reason text. */
|
|
134
|
+
function decideRuntimeName(name, src, registry) {
|
|
135
|
+
if (!name)
|
|
136
|
+
return { decidable: false, reason: `no ${src} recorded` };
|
|
137
|
+
if (name.toLowerCase() === 'unknown') {
|
|
138
|
+
return { decidable: false, reason: `${src} is the \`unknown\` sentinel, which denotes a runtime that could not be detected` };
|
|
139
|
+
}
|
|
140
|
+
if (registry && !registry.has(name)) {
|
|
141
|
+
return { decidable: false, reason: `${src}=${name} does not resolve to a registered runtime profile` };
|
|
142
|
+
}
|
|
143
|
+
return { decidable: true, resolved: name, reason: null };
|
|
144
|
+
}
|
|
145
|
+
export function decideRuntime(rec, registry) {
|
|
146
|
+
// Dedicated coordinate first (gep-sdk 1.13.0 `runtime_profile: {runtime, env_class?}`). Same registry bar as
|
|
147
|
+
// the proxy. A present-but-empty runtime_profile falls through so it never demotes a record model_name admits.
|
|
148
|
+
const rp = rec['runtime_profile'];
|
|
149
|
+
if (rp && typeof rp === 'object' && !Array.isArray(rp)) {
|
|
150
|
+
const runtime = str(rp['runtime']);
|
|
151
|
+
if (runtime)
|
|
152
|
+
return decideRuntimeName(runtime, 'runtime_profile.runtime', registry);
|
|
153
|
+
}
|
|
154
|
+
return decideRuntimeName(str(rec['model_name']), 'model_name', registry);
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------------------------------
|
|
157
|
+
// Verifier. Must clear a minimum semantic bar: it has to exercise the asset's own claim, not merely prove
|
|
158
|
+
// that an interpreter exists. We reject the known placeholder shapes rather than counting any non-empty
|
|
159
|
+
// validation array. This is the coordinate where a permissive predicate would be most misleading, because
|
|
160
|
+
// a nominal verifier is worse than an absent one: absence is honest.
|
|
161
|
+
// ---------------------------------------------------------------------------------------------------
|
|
162
|
+
const PLACEHOLDER_VERIFIER = /^(?:node|python3?|ruby|deno|bun|go|java|npm|pnpm|yarn)\s+(?:--?v(?:ersion)?|-V)\s*$/i;
|
|
163
|
+
const TRIVIAL_VERIFIER = /^(?:true|:|echo\b.*|exit\s+0)\s*$/i;
|
|
164
|
+
const isSubstantiveVerifier = (c) => !PLACEHOLDER_VERIFIER.test(c) && !TRIVIAL_VERIFIER.test(c);
|
|
165
|
+
export function decideVerifier(rec) {
|
|
166
|
+
// Dedicated coordinate first (gep-sdk 1.13.0 `verifier_profile: {verifier, decision?}`). The verifier IDENTITY
|
|
167
|
+
// string must clear the SAME minimum semantic bar as a legacy validation command — a `node --version` identity
|
|
168
|
+
// is as hollow here as it is there. A present-but-empty verifier_profile falls through to the proxy.
|
|
169
|
+
const vp = rec['verifier_profile'];
|
|
170
|
+
if (vp && typeof vp === 'object' && !Array.isArray(vp)) {
|
|
171
|
+
const verifier = str(vp['verifier']);
|
|
172
|
+
if (verifier) {
|
|
173
|
+
if (isSubstantiveVerifier(verifier))
|
|
174
|
+
return { decidable: true, resolved: verifier, reason: null };
|
|
175
|
+
return {
|
|
176
|
+
decidable: false,
|
|
177
|
+
reason: `verifier_profile.verifier=${verifier} is a placeholder; it establishes that an interpreter exists, not that the asset's claim holds`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const cmds = arr(rec['validation']).map((c) => str(c)).filter(Boolean);
|
|
182
|
+
if (cmds.length === 0)
|
|
183
|
+
return { decidable: false, reason: 'validation is empty; no verifier profile' };
|
|
184
|
+
const substantive = cmds.filter(isSubstantiveVerifier);
|
|
185
|
+
if (substantive.length === 0) {
|
|
186
|
+
return {
|
|
187
|
+
decidable: false,
|
|
188
|
+
reason: `all ${cmds.length} validation entr${cmds.length === 1 ? 'y is' : 'ies are'} placeholders (e.g. ${cmds[0]}); they establish that an interpreter exists, not that the asset's claim holds`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return { decidable: true, resolved: substantive[0], reason: null };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Decide K_auto membership for one record. All five coordinates must be decidable; we evaluate every
|
|
195
|
+
* coordinate rather than short-circuiting, so aggregate reporting can attribute the shortfall.
|
|
196
|
+
*/
|
|
197
|
+
export function decideKauto(record, opts) {
|
|
198
|
+
const rec = record;
|
|
199
|
+
const coordinates = {
|
|
200
|
+
version: decideVersion(rec),
|
|
201
|
+
claim: decideClaim(rec),
|
|
202
|
+
scope: decideScope(rec),
|
|
203
|
+
runtime: decideRuntime(rec, opts?.runtimeRegistry),
|
|
204
|
+
verifier: decideVerifier(rec),
|
|
205
|
+
};
|
|
206
|
+
const blockedBy = Object.entries(coordinates).filter(([, v]) => !v.decidable).map(([k]) => k);
|
|
207
|
+
return { inKauto: blockedBy.length === 0, coordinates, blockedBy };
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The PRESENCE proxy the original production query implemented, kept so the two can be reported side by
|
|
211
|
+
* side and the gap between them quantified rather than asserted.
|
|
212
|
+
*/
|
|
213
|
+
export function decideKautoPresenceProxy(record) {
|
|
214
|
+
const rec = record;
|
|
215
|
+
const CATEGORIES = new Set(['repair', 'optimize', 'innovate', 'explore']);
|
|
216
|
+
return Boolean(str(rec['schema_version'])
|
|
217
|
+
&& CATEGORIES.has(str(rec['category']))
|
|
218
|
+
&& arr(rec['signals_match']).length > 0
|
|
219
|
+
&& str(rec['model_name'])
|
|
220
|
+
&& arr(rec['validation']).length > 0);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The SECOND track of the dual-track report (user decision: 双轨并报). Where {@link decideKauto} answers "is each
|
|
224
|
+
* coordinate machine-DECIDABLE" (strict, closed-vocabulary bar), this answers the strictly weaker, writer-side
|
|
225
|
+
* question "did the producer EMIT the dedicated coordinate field at all, in its canonical minimal shape". The two
|
|
226
|
+
* are reported side by side so the paper can separate two failure modes that a single number conflates:
|
|
227
|
+
* - the dedicated field is ABSENT (writer never emitted it) — the 0%-adoption problem this batch attacks; vs
|
|
228
|
+
* - the dedicated field is PRESENT but its content is not yet strict (e.g. a scope signal that is not namespaced,
|
|
229
|
+
* a claim predicate outside the closed vocabulary) — a content-quality gap, not an adoption gap.
|
|
230
|
+
* Structural presence NEVER implies decidability; it is deliberately permissive so the adoption-vs-quality gap is
|
|
231
|
+
* visible rather than hidden inside the single strict figure.
|
|
232
|
+
*/
|
|
233
|
+
export function decideKautoStructural(record) {
|
|
234
|
+
const rec = record;
|
|
235
|
+
// version has no separate dedicated shape — asset_version/content_hash IS the coordinate, so structural
|
|
236
|
+
// presence coincides with strict decidability here (there is no semantic bar beyond "an immutable id exists").
|
|
237
|
+
const version = decideVersion(rec).decidable;
|
|
238
|
+
// claim: `claims: [{predicate}]` with at least one non-empty predicate string (closed-vocabulary check is the
|
|
239
|
+
// strict track's job, not this one).
|
|
240
|
+
const claim = claimPredicateStrings(rec['claims']).length > 0;
|
|
241
|
+
// scope: `scope: {signals: [...]}` with at least one non-empty signal (parseability is the strict track's job).
|
|
242
|
+
const scopeRaw = rec['scope'];
|
|
243
|
+
const scope = Boolean(scopeRaw && typeof scopeRaw === 'object' && !Array.isArray(scopeRaw)
|
|
244
|
+
&& arr(scopeRaw['signals']).map((t) => str(t)).filter(Boolean).length > 0);
|
|
245
|
+
// runtime: `runtime_profile: {runtime}` with a non-empty runtime string (registry/sentinel is the strict track).
|
|
246
|
+
const rpRaw = rec['runtime_profile'];
|
|
247
|
+
const runtime = Boolean(rpRaw && typeof rpRaw === 'object' && !Array.isArray(rpRaw)
|
|
248
|
+
&& str(rpRaw['runtime']));
|
|
249
|
+
// verifier: `verifier_profile: {verifier}` with a non-empty verifier string (placeholder bar is the strict track).
|
|
250
|
+
const vpRaw = rec['verifier_profile'];
|
|
251
|
+
const verifier = Boolean(vpRaw && typeof vpRaw === 'object' && !Array.isArray(vpRaw)
|
|
252
|
+
&& str(vpRaw['verifier']));
|
|
253
|
+
const coordinates = { version, claim, scope, runtime, verifier };
|
|
254
|
+
const missing = Object.entries(coordinates).filter(([, present]) => !present).map(([k]) => k);
|
|
255
|
+
return { structurallyComplete: missing.length === 0, coordinates, missing };
|
|
256
|
+
}
|
|
@@ -3,11 +3,14 @@ import type { ProvenanceStore } from '../assetstore/provenance.js';
|
|
|
3
3
|
import type { ReviewLedger } from '../assetstore/reviewLedger.js';
|
|
4
4
|
import type { GepCategory } from '../wire/index.js';
|
|
5
5
|
import type { ProblemPattern } from '../schema/problem.js';
|
|
6
|
-
import type { GeneCandidateInput } from './geneSelection.js';
|
|
6
|
+
import type { GeneCandidateInput, SelectionGuardMode } from './geneSelection.js';
|
|
7
7
|
import { CycleEngine, type CycleInput, type CycleResult, type SolidifyPermitGate } from './cycleEngine.js';
|
|
8
8
|
import { type PendingSignalsContext } from '../assetstore/pendingSignals.js';
|
|
9
9
|
import { type ReuseOutcomeSummary, type ReuseOutcomeEvent } from '../ops/reuseOutcomes.js';
|
|
10
10
|
import type { MemoryGraphAdvice } from './memoryGraph.js';
|
|
11
|
+
import type { SelectionPolicy } from './ucb1.js';
|
|
12
|
+
import type { FrozenExecutionBinding } from '../exec/executionBinding.js';
|
|
13
|
+
import type { CompatibilityEvidenceIndex } from '../modelCompatibility.js';
|
|
11
14
|
export interface RunCycleOptions {
|
|
12
15
|
cycleId: string;
|
|
13
16
|
problem: ProblemPattern;
|
|
@@ -20,10 +23,18 @@ export interface RunCycleOptions {
|
|
|
20
23
|
summary: string;
|
|
21
24
|
confidence: number;
|
|
22
25
|
selectionFloor?: number;
|
|
26
|
+
/** Emergency rollback for semantic IDF. Also skips pre-admission corpus collection. */
|
|
27
|
+
disableSemanticIdf?: boolean;
|
|
28
|
+
/** Experimental plateau policy. Omit for current engine-health + random drift behavior. */
|
|
29
|
+
selectionPolicy?: SelectionPolicy;
|
|
30
|
+
/** Versioned relevance-guard rollout. Omit for legacy direct-call behavior. */
|
|
31
|
+
selectionGuard?: SelectionGuardMode;
|
|
23
32
|
/** Optional explicit gene chosen by GEP / an external runtime; forwarded to CycleEngine after assembly. */
|
|
24
33
|
forcedGeneId?: string;
|
|
25
34
|
/** The agent runtime's work: run the mutation, return the outcome. */
|
|
26
35
|
execute: CycleInput['execute'];
|
|
36
|
+
/** Immutable external execution binding; omitted for legacy local cycles. */
|
|
37
|
+
executionBinding?: FrozenExecutionBinding;
|
|
27
38
|
/** Optional triage context forwarded to CycleEngine for cycle.failed classification. */
|
|
28
39
|
failureContext?: CycleInput['failureContext'];
|
|
29
40
|
/** Optional adapter/runtime permit gate. Runs after execute succeeds and before solidify writes assets. */
|
|
@@ -63,6 +74,8 @@ export interface RunCycleOptions {
|
|
|
63
74
|
recallEvents?: readonly ReuseOutcomeEvent[];
|
|
64
75
|
/** Scoped local MemoryGraph query result. Omit to keep selection unchanged. */
|
|
65
76
|
memoryGraphAdvice?: MemoryGraphAdvice;
|
|
77
|
+
/** Exact model compatibility evidence; quarantine decisions are removed before forced selection. */
|
|
78
|
+
compatibility?: CompatibilityEvidenceIndex;
|
|
66
79
|
}
|
|
67
80
|
/** Drive one full evolution cycle end-to-end: assemble candidates from the store, then run the cycle. */
|
|
68
81
|
export declare function runEvolutionCycle(engine: CycleEngine, store: AssetStoreProvider, opts: RunCycleOptions): Promise<CycleResult>;
|
|
@@ -37,14 +37,16 @@ export async function runEvolutionCycle(engine, store, opts) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
const asmOpts = {
|
|
40
|
+
includeSemanticCorpus: opts.disableSemanticIdf !== true,
|
|
40
41
|
...(opts.candidateLimit ? { limit: opts.candidateLimit } : {}),
|
|
41
42
|
...(opts.provenance ? { provenance: opts.provenance } : {}),
|
|
42
43
|
...(opts.review ? { review: opts.review } : {}),
|
|
43
44
|
...(opts.includeProbation ? { includeProbation: true } : {}),
|
|
44
45
|
...(opts.hubCandidates && opts.hubCandidates.length > 0 ? { hubCandidates: opts.hubCandidates } : {}),
|
|
45
46
|
...(reuseCounts.size > 0 ? { reuseCounts } : {}),
|
|
47
|
+
...(opts.compatibility ? { compatibility: opts.compatibility } : {}),
|
|
46
48
|
};
|
|
47
|
-
const { candidates: assembledCandidates, distilledFallback, antiWarnings } = await assembleSelectionPool(store, selectionSignals, asmOpts);
|
|
49
|
+
const { candidates: assembledCandidates, distilledFallback, semanticCorpus, antiWarnings } = await assembleSelectionPool(store, selectionSignals, asmOpts);
|
|
48
50
|
const memoryByGene = new Map((opts.memoryGraphAdvice?.genes ?? []).map((evidence) => [evidence.geneId, evidence]));
|
|
49
51
|
const candidates = assembledCandidates.map((candidate) => {
|
|
50
52
|
const evidence = memoryByGene.get(candidate.geneId) ?? (candidate.assetId ? memoryByGene.get(candidate.assetId) : undefined);
|
|
@@ -64,6 +66,10 @@ export async function runEvolutionCycle(engine, store, opts) {
|
|
|
64
66
|
category: opts.category,
|
|
65
67
|
...(opts.strategyName !== undefined ? { strategyName: opts.strategyName } : {}),
|
|
66
68
|
candidates,
|
|
69
|
+
semanticCorpus,
|
|
70
|
+
...(opts.disableSemanticIdf ? { disableSemanticIdf: true } : {}),
|
|
71
|
+
...(opts.selectionPolicy ? { selectionPolicy: opts.selectionPolicy } : {}),
|
|
72
|
+
...(opts.selectionGuard ? { selectionGuard: opts.selectionGuard } : {}),
|
|
67
73
|
target: opts.target,
|
|
68
74
|
expectedEffect: opts.expectedEffect,
|
|
69
75
|
summary: opts.summary,
|
|
@@ -71,10 +77,11 @@ export async function runEvolutionCycle(engine, store, opts) {
|
|
|
71
77
|
...(opts.selectionFloor !== undefined ? { selectionFloor: opts.selectionFloor } : {}),
|
|
72
78
|
...(opts.forcedGeneId !== undefined ? { forcedGeneId: opts.forcedGeneId } : {}),
|
|
73
79
|
execute: opts.execute,
|
|
80
|
+
...(opts.executionBinding !== undefined ? { executionBinding: opts.executionBinding } : {}),
|
|
74
81
|
...(opts.failureContext !== undefined ? { failureContext: opts.failureContext } : {}),
|
|
75
82
|
...(opts.solidifyPermit ? { solidifyPermit: opts.solidifyPermit } : {}),
|
|
76
83
|
// #97: forward the distilled-gene fallback pool so a no-signal-match cycle reuses a distilled strategy
|
|
77
|
-
// (instead of a blind innovate) when
|
|
84
|
+
// (instead of a blind innovate) when normal selection has no reusable positive choice.
|
|
78
85
|
...(memoryDistilledFallback.length > 0 ? { distilledFallback: memoryDistilledFallback } : {}),
|
|
79
86
|
...(antiWarnings.length > 0 ? { antiWarnings } : {}),
|
|
80
87
|
...(memoryEvidence.length > 0 ? { memoryEvidence } : {}),
|
package/dist/algo/solidify.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { type Capsule } from '../wire/index.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type ProofOfWork } from '../schema/proofOfWork.js';
|
|
3
3
|
export type ResolutionStatus = 'pending' | 'suppressed_observationally' | 'resolved_by_evidence' | 'regressed' | 'inconclusive';
|
|
4
|
+
export interface FailureEvidenceIdentityInput {
|
|
5
|
+
failureId?: string;
|
|
6
|
+
rootAttemptId?: string;
|
|
7
|
+
executionId?: string;
|
|
8
|
+
verifierDigest?: string;
|
|
9
|
+
artifactDigest?: string;
|
|
10
|
+
}
|
|
4
11
|
export interface SolidifyInput {
|
|
5
12
|
geneId: string;
|
|
6
13
|
trigger: readonly string[];
|
|
@@ -11,6 +18,8 @@ export interface SolidifyInput {
|
|
|
11
18
|
score: number;
|
|
12
19
|
};
|
|
13
20
|
proofOfWork?: ProofOfWork;
|
|
21
|
+
/** Failure-threshold identity. Stored only for failed Capsules; retry roots dedupe automatic fan-out. */
|
|
22
|
+
failureIdentity?: FailureEvidenceIdentityInput;
|
|
14
23
|
/** 是否有强证据(validation/测试在证据下通过). 默认 false → 不自动升级到 resolved. */
|
|
15
24
|
strongEvidence?: boolean;
|
|
16
25
|
/** regressed 判定阈: 失败且分低于此 → regressed, 否则 inconclusive. 默认 0.3. */
|
|
@@ -22,7 +31,7 @@ export interface SolidifyResult {
|
|
|
22
31
|
producedValue: boolean;
|
|
23
32
|
reasons: string[];
|
|
24
33
|
}
|
|
25
|
-
/** ProofOfWork 是否表明有实际产出(解锁非 coding agent, 批注#17/#19). */
|
|
34
|
+
/** ProofOfWork 是否表明有实际产出(解锁非 coding agent, 批注#17/#19). #961: 兼容读 helper(snake_case 优先, 回退旧 camelCase 存量). */
|
|
26
35
|
export declare function proofIndicatesOutput(p?: ProofOfWork): boolean;
|
|
27
36
|
/**
|
|
28
37
|
* 两级 resolution(M4A-8) + ProofOfWork 判价值(M4A-5):
|