synergyspec-selfevolving 1.3.0 → 2.0.0
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/README.md +50 -19
- package/dist/commands/learn.d.ts +12 -1
- package/dist/commands/learn.js +373 -31
- package/dist/commands/self-evolution-episode.d.ts +177 -0
- package/dist/commands/self-evolution-episode.js +423 -0
- package/dist/commands/self-evolution.d.ts +12 -190
- package/dist/commands/self-evolution.js +179 -786
- package/dist/commands/workflow/status.js +3 -1
- package/dist/core/archive.d.ts +0 -1
- package/dist/core/archive.js +0 -58
- package/dist/core/artifact-graph/instruction-loader.d.ts +2 -4
- package/dist/core/artifact-graph/instruction-loader.js +3 -31
- package/dist/core/config-prompts.js +4 -0
- package/dist/core/fitness/health/health-metrics.d.ts +26 -56
- package/dist/core/fitness/health/health-metrics.js +19 -58
- package/dist/core/fitness/health/index.d.ts +15 -2
- package/dist/core/fitness/health/index.js +25 -1
- package/dist/core/fitness/health/local-source.d.ts +43 -4
- package/dist/core/fitness/health/local-source.js +181 -25
- package/dist/core/fitness/health/metric-source.d.ts +48 -19
- package/dist/core/fitness/health/metric-source.js +8 -18
- package/dist/core/fitness/health/resolve-source.js +4 -1
- package/dist/core/fitness/loss.d.ts +7 -7
- package/dist/core/fitness/loss.js +6 -6
- package/dist/core/fitness/sample.d.ts +10 -0
- package/dist/core/fitness/test-failures.d.ts +30 -0
- package/dist/core/fitness/test-failures.js +123 -0
- package/dist/core/learn/credit-path.d.ts +36 -0
- package/dist/core/learn/credit-path.js +198 -0
- package/dist/core/learn/trajectory-discovery.d.ts +39 -0
- package/dist/core/learn/trajectory-discovery.js +140 -0
- package/dist/core/learn.d.ts +39 -5
- package/dist/core/learn.js +131 -14
- package/dist/core/project-config.d.ts +4 -0
- package/dist/core/project-config.js +52 -1
- package/dist/core/self-evolution/candidate-fitness.d.ts +23 -1
- package/dist/core/self-evolution/candidate-fitness.js +31 -5
- package/dist/core/self-evolution/candidates.d.ts +0 -9
- package/dist/core/self-evolution/canonical-targets.d.ts +8 -4
- package/dist/core/self-evolution/canonical-targets.js +8 -4
- package/dist/core/self-evolution/critic-agent.d.ts +150 -0
- package/dist/core/self-evolution/critic-agent.js +487 -0
- package/dist/core/self-evolution/edits-contract.d.ts +53 -0
- package/dist/core/self-evolution/edits-contract.js +89 -0
- package/dist/core/self-evolution/episode-orchestrator.d.ts +197 -0
- package/dist/core/self-evolution/episode-orchestrator.js +534 -0
- package/dist/core/self-evolution/episode-store.d.ts +266 -0
- package/dist/core/self-evolution/episode-store.js +573 -0
- package/dist/core/self-evolution/evolution-switches.d.ts +1 -1
- package/dist/core/self-evolution/evolution-switches.js +5 -10
- package/dist/core/self-evolution/evolving-agent.d.ts +162 -0
- package/dist/core/self-evolution/evolving-agent.js +449 -0
- package/dist/core/self-evolution/health-baseline.d.ts +25 -6
- package/dist/core/self-evolution/health-baseline.js +30 -6
- package/dist/core/self-evolution/host-harness.d.ts +1 -2
- package/dist/core/self-evolution/host-harness.js +1 -2
- package/dist/core/self-evolution/index.d.ts +10 -6
- package/dist/core/self-evolution/index.js +19 -6
- package/dist/core/self-evolution/learn-hints.d.ts +31 -0
- package/dist/core/self-evolution/learn-hints.js +16 -0
- package/dist/core/self-evolution/learn-observation-adapter.d.ts +35 -0
- package/dist/core/self-evolution/learn-observation-adapter.js +285 -10
- package/dist/core/self-evolution/line-diff.d.ts +60 -0
- package/dist/core/self-evolution/line-diff.js +130 -0
- package/dist/core/self-evolution/policy/fs-safe.d.ts +19 -0
- package/dist/core/self-evolution/policy/fs-safe.js +89 -0
- package/dist/core/self-evolution/policy/index.d.ts +13 -0
- package/dist/core/self-evolution/policy/index.js +13 -0
- package/dist/core/self-evolution/policy/policy-store.d.ts +217 -0
- package/dist/core/self-evolution/policy/policy-store.js +774 -0
- package/dist/core/self-evolution/policy/reject-buffer.d.ts +48 -0
- package/dist/core/self-evolution/policy/reject-buffer.js +168 -0
- package/dist/core/self-evolution/promote.d.ts +1 -1
- package/dist/core/self-evolution/promote.js +6 -33
- package/dist/core/self-evolution/promotion.js +1 -2
- package/dist/core/self-evolution/proposer-agent.d.ts +41 -0
- package/dist/core/self-evolution/proposer-agent.js +94 -13
- package/dist/core/self-evolution/proposer-slice.d.ts +26 -0
- package/dist/core/self-evolution/proposer-slice.js +54 -0
- package/dist/core/self-evolution/reward-agent.d.ts +234 -0
- package/dist/core/self-evolution/reward-agent.js +564 -0
- package/dist/core/self-evolution/scope-gate.d.ts +66 -0
- package/dist/core/self-evolution/scope-gate.js +107 -0
- package/dist/core/self-evolution/success-channel.d.ts +79 -0
- package/dist/core/self-evolution/success-channel.js +361 -0
- package/dist/core/self-evolution/target-evolution.d.ts +11 -0
- package/dist/core/self-evolution/target-evolution.js +2 -0
- package/dist/core/self-evolution/tool-evolution.js +2 -13
- package/dist/core/self-evolution/verdict.d.ts +8 -5
- package/dist/core/self-evolution/verdict.js +4 -7
- package/dist/core/templates/skill-templates.d.ts +1 -0
- package/dist/core/templates/skill-templates.js +1 -0
- package/dist/core/templates/workflow-manifest.js +2 -0
- package/dist/core/templates/workflows/learn.d.ts +4 -2
- package/dist/core/templates/workflows/learn.js +25 -166
- package/dist/core/templates/workflows/self-evolving.d.ts +13 -0
- package/dist/core/templates/workflows/self-evolving.js +127 -0
- package/dist/core/trajectory/facts.d.ts +16 -0
- package/dist/core/trajectory/facts.js +12 -4
- package/dist/core/trajectory/skeleton.d.ts +43 -0
- package/dist/core/trajectory/skeleton.js +239 -0
- package/dist/dashboard/data.d.ts +25 -51
- package/dist/dashboard/data.js +68 -180
- package/dist/dashboard/react-client.js +458 -503
- package/dist/dashboard/react-styles.js +3 -3
- package/dist/dashboard/server.js +23 -17
- package/dist/ui/ascii-patterns.d.ts +7 -15
- package/dist/ui/ascii-patterns.js +123 -54
- package/dist/ui/welcome-screen.d.ts +0 -14
- package/dist/ui/welcome-screen.js +16 -35
- package/package.json +3 -1
- package/scripts/code-health.py +1066 -638
- package/scripts/slop_rules.yaml +2151 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem safety primitives shared by candidate promotion (`promote.ts`)
|
|
3
|
+
* and the 策略 POLICY module(版本账本 + 否决缓冲). Extracted from `promote.ts`
|
|
4
|
+
* unchanged so both write paths go through the SAME fail-closed helpers:
|
|
5
|
+
* never write outside the repo root, and never leave a half-written file
|
|
6
|
+
* behind (sibling tmp + rename).
|
|
7
|
+
*/
|
|
8
|
+
import { promises as fs } from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as crypto from 'node:crypto';
|
|
11
|
+
/** Throw if `abs` resolves outside `repoRoot`. */
|
|
12
|
+
export function assertWithinRepo(repoRoot, abs) {
|
|
13
|
+
const base = path.resolve(repoRoot);
|
|
14
|
+
const target = path.resolve(abs);
|
|
15
|
+
const rel = path.relative(base, target);
|
|
16
|
+
if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
17
|
+
throw new Error(`Refusing to write outside repo root. root=${base} target=${target}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* fsync a single path best-effort: open it, `fdatasync`/`fsync`, close. Swallows
|
|
22
|
+
* EISDIR/EPERM/EINVAL/ENOSYS so a host (notably Windows) that refuses to fsync a
|
|
23
|
+
* directory handle does not turn a durability hardening into a hard failure. The
|
|
24
|
+
* caller's data is already on disk via the rename; this only pushes it past the
|
|
25
|
+
* OS write cache so a crash cannot lose it.
|
|
26
|
+
*/
|
|
27
|
+
async function fsyncPathBestEffort(target) {
|
|
28
|
+
let handle;
|
|
29
|
+
try {
|
|
30
|
+
handle = await fs.open(target, 'r');
|
|
31
|
+
await handle.sync();
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const code = err.code;
|
|
35
|
+
// Windows dir fsync (and some filesystems) reject the operation — best-effort.
|
|
36
|
+
if (code !== 'EISDIR' && code !== 'EPERM' && code !== 'EINVAL' && code !== 'ENOSYS') {
|
|
37
|
+
// Non-fatal even otherwise: durability is a hardening, not a correctness gate.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await handle?.close().catch(() => { });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Atomic write via sibling tmp file + rename; cleans up on rename failure. After
|
|
46
|
+
* the rename, fsync the file and (best-effort) its parent directory so a host
|
|
47
|
+
* crash cannot lose a just-renamed record a later separate process relies on —
|
|
48
|
+
* the rename is only durable once the directory entry itself is flushed.
|
|
49
|
+
*/
|
|
50
|
+
export async function writeFileAtomic(abs, content) {
|
|
51
|
+
const dir = path.dirname(abs);
|
|
52
|
+
const tmp = path.join(dir, `.${path.basename(abs)}.tmp-${crypto.randomBytes(4).toString('hex')}`);
|
|
53
|
+
await fs.writeFile(tmp, content, 'utf8');
|
|
54
|
+
try {
|
|
55
|
+
await fs.rename(tmp, abs);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
try {
|
|
59
|
+
await fs.rm(tmp, { force: true });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// ignore
|
|
63
|
+
}
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
// Durability: flush the renamed file, then the parent dir entry (dir fsync may
|
|
67
|
+
// throw on Windows — guarded inside fsyncPathBestEffort). Both best-effort.
|
|
68
|
+
await fsyncPathBestEffort(abs);
|
|
69
|
+
await fsyncPathBestEffort(dir);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Append `content` to a file and fsync the file descriptor so a host crash
|
|
73
|
+
* cannot lose the just-appended record. Used by the append-only stores (the
|
|
74
|
+
* 版本账本 ledger and the 否决缓冲 reject-buffer): a later SEPARATE process
|
|
75
|
+
* (`resumeEpisode`) relies on these records being durable, so the OS write cache
|
|
76
|
+
* must be flushed before we return. Does NOT change the bytes written (one
|
|
77
|
+
* `append` of `content`); only adds the fsync. Byte content is the caller's.
|
|
78
|
+
*/
|
|
79
|
+
export async function appendFileDurable(abs, content) {
|
|
80
|
+
const handle = await fs.open(abs, 'a');
|
|
81
|
+
try {
|
|
82
|
+
await handle.appendFile(content, 'utf8');
|
|
83
|
+
await handle.sync();
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await handle.close().catch(() => { });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=fs-safe.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 策略 POLICY module(版本账本 + 否决缓冲)— sub-barrel.
|
|
3
|
+
*
|
|
4
|
+
* The policy is the design template(主智能体的「权重」)living in the user's
|
|
5
|
+
* repo; the CLI 持有版本 (holds the VERSION): `policy-store.ts` keeps the
|
|
6
|
+
* 版本账本 ledger + snapshots + one-in-flight lock, `reject-buffer.ts` keeps
|
|
7
|
+
* the 否决缓冲, and `fs-safe.ts` holds the fail-closed write primitives
|
|
8
|
+
* shared with `promote.ts`.
|
|
9
|
+
*/
|
|
10
|
+
export * from './fs-safe.js';
|
|
11
|
+
export * from './policy-store.js';
|
|
12
|
+
export * from './reject-buffer.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 策略 POLICY module(版本账本 + 否决缓冲)— sub-barrel.
|
|
3
|
+
*
|
|
4
|
+
* The policy is the design template(主智能体的「权重」)living in the user's
|
|
5
|
+
* repo; the CLI 持有版本 (holds the VERSION): `policy-store.ts` keeps the
|
|
6
|
+
* 版本账本 ledger + snapshots + one-in-flight lock, `reject-buffer.ts` keeps
|
|
7
|
+
* the 否决缓冲, and `fs-safe.ts` holds the fail-closed write primitives
|
|
8
|
+
* shared with `promote.ts`.
|
|
9
|
+
*/
|
|
10
|
+
export * from './fs-safe.js';
|
|
11
|
+
export * from './policy-store.js';
|
|
12
|
+
export * from './reject-buffer.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
export declare const POLICY_LEDGER_FILE = "ledger.ndjson";
|
|
2
|
+
export declare const POLICY_IN_FLIGHT_FILE = "in-flight.json";
|
|
3
|
+
export declare const POLICY_REJECT_BUFFER_FILE = "reject-buffer.ndjson";
|
|
4
|
+
export declare const POLICY_SNAPSHOT_MANIFEST_FILE = "manifest.json";
|
|
5
|
+
export declare const POLICY_SNAPSHOT_FILES_DIR = "files";
|
|
6
|
+
export declare const POLICY_SNAPSHOT_DELTA_FILE = "delta.patch";
|
|
7
|
+
/** An in-flight episode older than this is stale and its slot reclaimable. */
|
|
8
|
+
export declare const IN_FLIGHT_STALE_MS: number;
|
|
9
|
+
/** What a ledger entry records happened to the lineage. */
|
|
10
|
+
export type PolicyLedgerAction = 'init' | 'evolve' | 'rollback' | 'refused';
|
|
11
|
+
/** One file the policy version covers, content-addressed for verification. */
|
|
12
|
+
export interface PolicyLedgerFileEntry {
|
|
13
|
+
/** Repo-relative POSIX path of the live policy file. */
|
|
14
|
+
relPath: string;
|
|
15
|
+
/** SHA-256 (hex) of the file's bytes at this version. */
|
|
16
|
+
sha256: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The falsifiable bet attached to an 'evolve' step: which scoreboard metric
|
|
20
|
+
* the edit is predicted to move, in which direction, and by when the
|
|
21
|
+
* prediction is checkable (so a later episode can settle it).
|
|
22
|
+
*/
|
|
23
|
+
export interface PolicyPrediction {
|
|
24
|
+
metric: 'loss' | 'passRate' | 'healthPenalty';
|
|
25
|
+
direction: 'down' | 'up';
|
|
26
|
+
checkBy: string;
|
|
27
|
+
}
|
|
28
|
+
/** Size of an 'evolve'/'rollback' step, derived from its `delta.patch`. */
|
|
29
|
+
export interface PolicyDeltaStats {
|
|
30
|
+
filesChanged: number;
|
|
31
|
+
linesAdded: number;
|
|
32
|
+
linesRemoved: number;
|
|
33
|
+
}
|
|
34
|
+
/** One line of the 版本账本 ledger (`ledger.ndjson`). */
|
|
35
|
+
export interface PolicyLedgerEntry {
|
|
36
|
+
schemaVersion: 1;
|
|
37
|
+
version: number;
|
|
38
|
+
targetId: string;
|
|
39
|
+
/** ISO-8601 UTC timestamp. */
|
|
40
|
+
at: string;
|
|
41
|
+
action: PolicyLedgerAction;
|
|
42
|
+
/** `null` only for 'init' (no episode owns lineage creation). */
|
|
43
|
+
episodeId: string | null;
|
|
44
|
+
files: PolicyLedgerFileEntry[];
|
|
45
|
+
prediction?: PolicyPrediction;
|
|
46
|
+
/** advantage = reward(主臂) − reward(基线臂), when one was measured. */
|
|
47
|
+
advantage?: number;
|
|
48
|
+
deltaStats?: PolicyDeltaStats;
|
|
49
|
+
/** Why the 演进智能体 EVOLVING AGENT refused ('refused' entries only). */
|
|
50
|
+
reason?: string;
|
|
51
|
+
}
|
|
52
|
+
/** `manifest.json` inside one `snapshots/<target-id-slug>/v<N>/` dir. */
|
|
53
|
+
export interface PolicySnapshotManifest {
|
|
54
|
+
version: number;
|
|
55
|
+
targetId: string;
|
|
56
|
+
at: string;
|
|
57
|
+
files: PolicyLedgerFileEntry[];
|
|
58
|
+
}
|
|
59
|
+
/** One in-flight episode for one target (`in-flight.json` value). */
|
|
60
|
+
export interface PolicyInFlightEntry {
|
|
61
|
+
targetId: string;
|
|
62
|
+
episodeId: string;
|
|
63
|
+
/** The lineage head version when the episode started. */
|
|
64
|
+
sinceVersion: number;
|
|
65
|
+
/** ISO-8601 UTC timestamp; staleness is measured from here. */
|
|
66
|
+
startedAt: string;
|
|
67
|
+
}
|
|
68
|
+
/** Resolved on-disk paths of the policy dir. No I/O is performed. */
|
|
69
|
+
export interface PolicyLayout {
|
|
70
|
+
repoRoot: string;
|
|
71
|
+
/** `<repoRoot>/.synergyspec-selfevolving/self-evolution/policy`. */
|
|
72
|
+
baseDir: string;
|
|
73
|
+
ledgerPath: string;
|
|
74
|
+
snapshotsDir: string;
|
|
75
|
+
inFlightPath: string;
|
|
76
|
+
rejectBufferPath: string;
|
|
77
|
+
}
|
|
78
|
+
/** Compute the policy dir layout for a repo. */
|
|
79
|
+
export declare function resolvePolicyLayout(repoRoot: string): PolicyLayout;
|
|
80
|
+
/** Kebab-case a target id for use as a snapshot directory name. */
|
|
81
|
+
export declare function targetIdSlug(targetId: string): string;
|
|
82
|
+
/** Absolute path of one version's snapshot dir. No I/O is performed. */
|
|
83
|
+
export declare function policySnapshotDir(layout: PolicyLayout, targetId: string, version: number): string;
|
|
84
|
+
/**
|
|
85
|
+
* Read one target's slice of the 版本账本 ledger, in append order. Returns
|
|
86
|
+
* `[]` when the ledger does not exist. Malformed/blank lines are skipped
|
|
87
|
+
* best-effort (forward-compatible, matching the repo's other ndjson readers).
|
|
88
|
+
*/
|
|
89
|
+
export declare function readPolicyLedger(repoRoot: string, targetId: string): Promise<PolicyLedgerEntry[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Read the ENTIRE 版本账本 ledger across all targets, in append order. Returns
|
|
92
|
+
* `[]` when the ledger does not exist. Malformed/blank lines are skipped
|
|
93
|
+
* best-effort (forward-compatible, matching the repo's other ndjson readers).
|
|
94
|
+
*/
|
|
95
|
+
export declare function readPolicyLedgerAll(repoRoot: string): Promise<PolicyLedgerEntry[]>;
|
|
96
|
+
/**
|
|
97
|
+
* The lineage head version for a target, or `null` when the lineage has not
|
|
98
|
+
* been initialized. The 单一血统 single lineage is append-only, so the head is
|
|
99
|
+
* simply the LAST ledger entry's version ('refused' entries carry the
|
|
100
|
+
* unchanged head; 'evolve'/'rollback' carry the new one).
|
|
101
|
+
*/
|
|
102
|
+
export declare function currentPolicyVersion(repoRoot: string, targetId: string): Promise<number | null>;
|
|
103
|
+
/**
|
|
104
|
+
* Read one version's snapshotted files (byte-for-byte). Verifies every file
|
|
105
|
+
* against the manifest's sha256 and throws on a mismatch — a snapshot is the
|
|
106
|
+
* restore source of truth, so corruption is a hard error, never silent.
|
|
107
|
+
*/
|
|
108
|
+
export declare function readPolicySnapshotFiles(repoRoot: string, targetId: string, version: number): Promise<{
|
|
109
|
+
relPath: string;
|
|
110
|
+
content: string;
|
|
111
|
+
}[]>;
|
|
112
|
+
/**
|
|
113
|
+
* Shape of the injectable resolver seam: the slice of
|
|
114
|
+
* {@link resolveTargetLocalFiles}'s result that init actually reads.
|
|
115
|
+
*/
|
|
116
|
+
export type PolicyResolveFiles = (targetId: string, repoRoot: string) => Promise<{
|
|
117
|
+
files: {
|
|
118
|
+
relPath: string;
|
|
119
|
+
content: string;
|
|
120
|
+
}[];
|
|
121
|
+
}>;
|
|
122
|
+
export interface InitPolicyLineageOptions {
|
|
123
|
+
repoRoot: string;
|
|
124
|
+
targetId: string;
|
|
125
|
+
/** TEST seam. Defaults to the real {@link resolveTargetLocalFiles}. */
|
|
126
|
+
resolveFiles?: PolicyResolveFiles;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Start a target's 单一血统 single lineage: snapshot v0 of the target's
|
|
130
|
+
* CURRENT resolved local files and append the 'init' ledger entry. Refuses to
|
|
131
|
+
* re-init an existing lineage (the version axis never restarts).
|
|
132
|
+
*/
|
|
133
|
+
export declare function initPolicyLineage(opts: InitPolicyLineageOptions): Promise<PolicyLedgerEntry>;
|
|
134
|
+
export interface AdvancePolicyVersionOptions {
|
|
135
|
+
repoRoot: string;
|
|
136
|
+
targetId: string;
|
|
137
|
+
episodeId: string;
|
|
138
|
+
/** Full new contents for the edited lineage file(s). */
|
|
139
|
+
edits: {
|
|
140
|
+
relPath: string;
|
|
141
|
+
content: string;
|
|
142
|
+
}[];
|
|
143
|
+
prediction: PolicyPrediction;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Apply the 演进智能体 EVOLVING AGENT's ONE bounded edit as the next policy
|
|
147
|
+
* version. 单一血统 single-lineage enforcement: the live files must still be
|
|
148
|
+
* byte-identical to the lineage head snapshot — if anything advanced or edited
|
|
149
|
+
* them out-of-band, the head is not the expected base and this throws (roll
|
|
150
|
+
* back, or re-init, before evolving again).
|
|
151
|
+
*
|
|
152
|
+
* Order is snapshot-then-write: the NEW version's snapshot dir is committed
|
|
153
|
+
* first, then the live files are written atomically; a mid-write failure
|
|
154
|
+
* restores every live file from the head content and discards the new
|
|
155
|
+
* snapshot before rethrowing. The 'evolve' ledger entry (with `prediction`
|
|
156
|
+
* and `deltaStats`) is appended only after every live write succeeded.
|
|
157
|
+
*/
|
|
158
|
+
export declare function advancePolicyVersion(opts: AdvancePolicyVersionOptions): Promise<PolicyLedgerEntry>;
|
|
159
|
+
export interface RollbackPolicyVersionOptions {
|
|
160
|
+
repoRoot: string;
|
|
161
|
+
targetId: string;
|
|
162
|
+
episodeId: string;
|
|
163
|
+
toVersion: number;
|
|
164
|
+
/** The measured (bad) advantage that triggered the rollback, when known. */
|
|
165
|
+
advantage?: number;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Restore the live policy files byte-for-byte from snapshot v<toVersion> and
|
|
169
|
+
* append a 'rollback' ledger entry. The restore is recorded as a NEW head
|
|
170
|
+
* version whose files equal the old snapshot (git-revert style) so the
|
|
171
|
+
* 单一血统 single lineage stays monotonic — the version axis never rewinds.
|
|
172
|
+
* Unlike advance, rollback does NOT require the live files to match the head:
|
|
173
|
+
* it is the recovery path, including for out-of-band live-file divergence.
|
|
174
|
+
*/
|
|
175
|
+
export declare function rollbackPolicyVersion(opts: RollbackPolicyVersionOptions): Promise<PolicyLedgerEntry>;
|
|
176
|
+
export interface RecordEvolutionRefusedOptions {
|
|
177
|
+
repoRoot: string;
|
|
178
|
+
targetId: string;
|
|
179
|
+
episodeId: string;
|
|
180
|
+
reason: string;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Record an episode where the 演进智能体 EVOLVING AGENT refused to edit. The
|
|
184
|
+
* version does NOT bump (vN+1 ≡ vN) — this entry is exactly what the
|
|
185
|
+
* CRITIC AGENT(基线智能体 baseline agent)'s skip condition reads: the policy
|
|
186
|
+
* is unchanged, so rerunning the baseline arm would compare a policy against
|
|
187
|
+
* itself. No files are touched.
|
|
188
|
+
*/
|
|
189
|
+
export declare function recordEvolutionRefused(opts: RecordEvolutionRefusedOptions): Promise<PolicyLedgerEntry>;
|
|
190
|
+
export interface AcquireInFlightOptions {
|
|
191
|
+
repoRoot: string;
|
|
192
|
+
targetId: string;
|
|
193
|
+
episodeId: string;
|
|
194
|
+
/** Injectable clock for tests; defaults to `new Date()`. */
|
|
195
|
+
now?: Date;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Claim the one in-flight slot for a target. Throws while a NON-stale entry
|
|
199
|
+
* exists for the target (one in-flight per target); an entry whose
|
|
200
|
+
* `startedAt` is ≥ {@link IN_FLIGHT_STALE_MS} old is stale and its slot is
|
|
201
|
+
* reclaimed (the abandoned episode's worktree is 产物即弃 — worktree
|
|
202
|
+
* artifacts discarded). Records `sinceVersion` = the lineage head at acquire
|
|
203
|
+
* time, so the episode knows which policy version it started from.
|
|
204
|
+
*/
|
|
205
|
+
export declare function acquireInFlight(opts: AcquireInFlightOptions): Promise<PolicyInFlightEntry>;
|
|
206
|
+
export interface ReleaseInFlightOptions {
|
|
207
|
+
repoRoot: string;
|
|
208
|
+
targetId: string;
|
|
209
|
+
episodeId: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Release a target's in-flight slot. Idempotent when no entry exists; throws
|
|
213
|
+
* when the slot is held by a DIFFERENT episode (an episode may only release
|
|
214
|
+
* its own claim).
|
|
215
|
+
*/
|
|
216
|
+
export declare function releaseInFlight(opts: ReleaseInFlightOptions): Promise<void>;
|
|
217
|
+
//# sourceMappingURL=policy-store.d.ts.map
|