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
|
@@ -17,10 +17,25 @@
|
|
|
17
17
|
* first run records & allows), and writes are best-effort (a write failure must
|
|
18
18
|
* never turn a successful promote into an error). Callers supply the timestamp,
|
|
19
19
|
* so this module never calls Date.now (deterministic + replay-safe).
|
|
20
|
+
*
|
|
21
|
+
* Baselines are SCHEMA-VERSIONED ({@link HEALTH_METRICS_VERSION}): when the
|
|
22
|
+
* meaning/scale of `healthPenalty` changes (e.g. the move from the 7-metric
|
|
23
|
+
* blend to the SlopCodeBench structural_erosion⊕verbosity scores), reading a
|
|
24
|
+
* baseline stamped with a different version returns `null`, so an old-scale
|
|
25
|
+
* number can never mis-gate a new-scale measurement — the gate no-ops and the
|
|
26
|
+
* next promote re-seeds the baseline on the new scale.
|
|
20
27
|
*/
|
|
21
28
|
import { promises as fs } from 'node:fs';
|
|
22
29
|
import * as path from 'node:path';
|
|
23
30
|
export const HEALTH_BASELINE_FILE = 'health-baseline.json';
|
|
31
|
+
/**
|
|
32
|
+
* Schema version of the health-metrics scale behind `healthPenalty`. Bump
|
|
33
|
+
* whenever the meaning/scale of `healthPenalty` changes so stale baselines
|
|
34
|
+
* read as `null` instead of mis-gating. v2 = SlopCodeBench
|
|
35
|
+
* structural_erosion⊕verbosity; v1 (implicit/absent in old files) was the
|
|
36
|
+
* 7-metric blend.
|
|
37
|
+
*/
|
|
38
|
+
export const HEALTH_METRICS_VERSION = 2;
|
|
24
39
|
function baselinePath(repoRoot) {
|
|
25
40
|
return path.join(path.resolve(repoRoot), '.synergyspec-selfevolving', 'self-evolution', HEALTH_BASELINE_FILE);
|
|
26
41
|
}
|
|
@@ -29,8 +44,10 @@ function isFiniteNumber(v) {
|
|
|
29
44
|
}
|
|
30
45
|
/**
|
|
31
46
|
* Read the recorded baseline. Returns `null` when the file is absent, unreadable,
|
|
32
|
-
* unparseable,
|
|
33
|
-
*
|
|
47
|
+
* unparseable, carries a non-finite `healthPenalty`, or was stamped with a
|
|
48
|
+
* `metricsVersion` other than {@link HEALTH_METRICS_VERSION} (an absent field ⇒
|
|
49
|
+
* a pre-versioning, old-scale baseline). All cases are treated as "no baseline
|
|
50
|
+
* yet" ⇒ the gate does not fire and the next promote re-seeds it.
|
|
34
51
|
*/
|
|
35
52
|
export async function readHealthBaseline(repoRoot) {
|
|
36
53
|
let raw;
|
|
@@ -52,23 +69,30 @@ export async function readHealthBaseline(repoRoot) {
|
|
|
52
69
|
const obj = parsed;
|
|
53
70
|
if (!isFiniteNumber(obj.healthPenalty))
|
|
54
71
|
return null;
|
|
72
|
+
if (obj.metricsVersion !== HEALTH_METRICS_VERSION)
|
|
73
|
+
return null;
|
|
55
74
|
return {
|
|
56
75
|
healthPenalty: obj.healthPenalty,
|
|
57
76
|
updatedAt: typeof obj.updatedAt === 'string' ? obj.updatedAt : '',
|
|
77
|
+
metricsVersion: obj.metricsVersion,
|
|
58
78
|
...(typeof obj.sourceChange === 'string' ? { sourceChange: obj.sourceChange } : {}),
|
|
59
79
|
...(typeof obj.candidateId === 'string' ? { candidateId: obj.candidateId } : {}),
|
|
60
80
|
};
|
|
61
81
|
}
|
|
62
82
|
/**
|
|
63
|
-
* Write/overwrite the recorded baseline
|
|
64
|
-
*
|
|
65
|
-
*
|
|
83
|
+
* Write/overwrite the recorded baseline, stamping the current
|
|
84
|
+
* {@link HEALTH_METRICS_VERSION} (callers never supply it, so every written
|
|
85
|
+
* baseline is on the scale this build measures). Best-effort: creates the
|
|
86
|
+
* parent dir if needed and swallows any error (a failed baseline write must not
|
|
87
|
+
* fail a promote that already succeeded). Returns `true` on a successful write,
|
|
88
|
+
* `false` otherwise.
|
|
66
89
|
*/
|
|
67
90
|
export async function writeHealthBaseline(repoRoot, baseline) {
|
|
68
91
|
const file = baselinePath(repoRoot);
|
|
92
|
+
const stamped = { ...baseline, metricsVersion: HEALTH_METRICS_VERSION };
|
|
69
93
|
try {
|
|
70
94
|
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
71
|
-
await fs.writeFile(file, `${JSON.stringify(
|
|
95
|
+
await fs.writeFile(file, `${JSON.stringify(stamped, null, 2)}\n`, 'utf8');
|
|
72
96
|
return true;
|
|
73
97
|
}
|
|
74
98
|
catch {
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
* Back-compat is load-bearing: when the harness resolves to 'claude' (the
|
|
20
20
|
* default - no CODEX_ or OPENCODE_ env present, as in the unit tests), the built
|
|
21
21
|
* command is byte-identical to the previous behavior - `binary` + `['-p', prompt]`
|
|
22
|
-
* with no stdin - so the existing
|
|
23
|
-
* unchanged.
|
|
22
|
+
* with no stdin - so the existing headless-agent tests pass unchanged.
|
|
24
23
|
*/
|
|
25
24
|
import { spawn as nodeSpawn } from 'node:child_process';
|
|
26
25
|
export type AgentHarness = 'claude' | 'codex' | 'opencode';
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
* Back-compat is load-bearing: when the harness resolves to 'claude' (the
|
|
20
20
|
* default - no CODEX_ or OPENCODE_ env present, as in the unit tests), the built
|
|
21
21
|
* command is byte-identical to the previous behavior - `binary` + `['-p', prompt]`
|
|
22
|
-
* with no stdin - so the existing
|
|
23
|
-
* unchanged.
|
|
22
|
+
* with no stdin - so the existing headless-agent tests pass unchanged.
|
|
24
23
|
*/
|
|
25
24
|
import { spawn as nodeSpawn } from 'node:child_process';
|
|
26
25
|
const HARNESSES = ['claude', 'codex', 'opencode'];
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './shared.js';
|
|
2
2
|
export * from './evolution-switches.js';
|
|
3
|
-
export * from './template-variants.js';
|
|
4
3
|
export * from './archive-memory.js';
|
|
5
4
|
export * from './task-quality.js';
|
|
6
5
|
export * from './alignment-verifier.js';
|
|
@@ -14,16 +13,21 @@ export * from './candidates.js';
|
|
|
14
13
|
export * from './candidate-fitness.js';
|
|
15
14
|
export * from './verdict.js';
|
|
16
15
|
export * from './health-baseline.js';
|
|
17
|
-
export * from './ga-selection.js';
|
|
18
|
-
export * from './trajectory.js';
|
|
19
16
|
export * from './host-harness.js';
|
|
20
|
-
export * from './replay.js';
|
|
21
|
-
export * from './replay-runner.js';
|
|
22
17
|
export * from './credit-assignment.js';
|
|
23
18
|
export * from './local-targets.js';
|
|
24
19
|
export * from './promote.js';
|
|
25
20
|
export * from './candidate-gates.js';
|
|
26
21
|
export * from './eval-report.js';
|
|
27
|
-
export * from './
|
|
22
|
+
export * from './edits-contract.js';
|
|
23
|
+
export * from './proposer-slice.js';
|
|
28
24
|
export * from './promotion.js';
|
|
25
|
+
export * from './policy/index.js';
|
|
26
|
+
export * from './episode-store.js';
|
|
27
|
+
export * from './line-diff.js';
|
|
28
|
+
export { checkScopeWithinDiagnosis, type ScopeViolation, type ScopeGateResult, type CheckScopeWithinDiagnosisInput, } from './scope-gate.js';
|
|
29
|
+
export * from './critic-agent.js';
|
|
30
|
+
export * from './reward-agent.js';
|
|
31
|
+
export * from './evolving-agent.js';
|
|
32
|
+
export * from './episode-orchestrator.js';
|
|
29
33
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './shared.js';
|
|
2
2
|
export * from './evolution-switches.js';
|
|
3
|
-
export * from './template-variants.js';
|
|
4
3
|
export * from './archive-memory.js';
|
|
5
4
|
export * from './task-quality.js';
|
|
6
5
|
export * from './alignment-verifier.js';
|
|
@@ -14,16 +13,30 @@ export * from './candidates.js';
|
|
|
14
13
|
export * from './candidate-fitness.js';
|
|
15
14
|
export * from './verdict.js';
|
|
16
15
|
export * from './health-baseline.js';
|
|
17
|
-
export * from './ga-selection.js';
|
|
18
|
-
export * from './trajectory.js';
|
|
19
16
|
export * from './host-harness.js';
|
|
20
|
-
export * from './replay.js';
|
|
21
|
-
export * from './replay-runner.js';
|
|
22
17
|
export * from './credit-assignment.js';
|
|
23
18
|
export * from './local-targets.js';
|
|
24
19
|
export * from './promote.js';
|
|
25
20
|
export * from './candidate-gates.js';
|
|
26
21
|
export * from './eval-report.js';
|
|
27
|
-
export * from './
|
|
22
|
+
export * from './edits-contract.js';
|
|
23
|
+
export * from './proposer-slice.js';
|
|
28
24
|
export * from './promotion.js';
|
|
25
|
+
// ── Loop v2 (self-evolution as in-context RL) ────────────────────────────────
|
|
26
|
+
// Policy (ledger + reject-buffer + fs-safe), the disk episode store, the three
|
|
27
|
+
// agents (critic / reward / evolving), the line-diff + scope gate, and the
|
|
28
|
+
// rollback-before-evolution episode orchestrator. ArmObjective is the SINGLE
|
|
29
|
+
// canonical on-disk type from critic-agent.js; reward-agent.js reads it via its
|
|
30
|
+
// own null-safe RewardArmObjectiveInput, so this barrel has no ambiguous re-export.
|
|
31
|
+
export * from './policy/index.js';
|
|
32
|
+
export * from './episode-store.js';
|
|
33
|
+
export * from './line-diff.js';
|
|
34
|
+
// scope-gate.js also declares a DiagnosisGap ({file, section}); the richer
|
|
35
|
+
// reward-agent.js DiagnosisGap ({file, section, description}) is the one the
|
|
36
|
+
// barrel surfaces. Re-export the scope gate WITHOUT its DiagnosisGap.
|
|
37
|
+
export { checkScopeWithinDiagnosis, } from './scope-gate.js';
|
|
38
|
+
export * from './critic-agent.js';
|
|
39
|
+
export * from './reward-agent.js';
|
|
40
|
+
export * from './evolving-agent.js';
|
|
41
|
+
export * from './episode-orchestrator.js';
|
|
29
42
|
//# sourceMappingURL=index.js.map
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* has no side effects, no dependencies, and never mutates inputs.
|
|
13
13
|
*/
|
|
14
14
|
import type { CanonicalTargetKind } from './canonical-targets.js';
|
|
15
|
+
import type { CreditPath } from '../learn/credit-path.js';
|
|
15
16
|
/**
|
|
16
17
|
* Closed enumeration of proposed change types a learn-stage hint may carry.
|
|
17
18
|
*
|
|
@@ -58,6 +59,20 @@ export interface LearnEvolutionHintEvidence {
|
|
|
58
59
|
quoteOrSummary: string;
|
|
59
60
|
/** Severity of the observation in isolation. */
|
|
60
61
|
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
62
|
+
/**
|
|
63
|
+
* Where the evidence came from: `'observed'` = re-sourced from the observed
|
|
64
|
+
* runner output (the source the observed-verified gate trusts);
|
|
65
|
+
* `'authored'` = grepped from agent-authored artifacts. OPTIONAL — absent on
|
|
66
|
+
* legacy persisted hints (treated as authored).
|
|
67
|
+
*/
|
|
68
|
+
provenance?: 'observed' | 'authored';
|
|
69
|
+
/**
|
|
70
|
+
* Rendered credit-path address from the failing signal back to the suspected
|
|
71
|
+
* producing canonical target, e.g. `test … → UC1-S2 → task 3.2 → design
|
|
72
|
+
* §"Normalizer" → artifact-template:design`. SUSPECT framing — recurrence
|
|
73
|
+
* across changes (the grouping machinery) is the confirmer. OPTIONAL.
|
|
74
|
+
*/
|
|
75
|
+
address?: string;
|
|
61
76
|
}
|
|
62
77
|
/**
|
|
63
78
|
* Structured hint emitted by `learn` for downstream candidate proposal.
|
|
@@ -100,6 +115,22 @@ export interface LearnEvolutionHint {
|
|
|
100
115
|
* todo/learn-self-evolution-migration-plan.md.
|
|
101
116
|
*/
|
|
102
117
|
loss?: number;
|
|
118
|
+
/**
|
|
119
|
+
* Full neutral credit paths (hops + bounded real-text excerpts) behind the
|
|
120
|
+
* evidence items' rendered `address` strings — the substrate the proposer
|
|
121
|
+
* slice is built from. Optional; absent on legacy persisted hints.
|
|
122
|
+
*/
|
|
123
|
+
creditPaths?: CreditPath[];
|
|
124
|
+
/**
|
|
125
|
+
* `'policy-focus'` marks a hint SYNTHESIZED by the evolution-focus switch:
|
|
126
|
+
* every heuristic hint of this change bound to a frozen kind, so their
|
|
127
|
+
* evidence was re-aimed at an explicitly evolvable target instead of being
|
|
128
|
+
* silently dropped. SUSPECT framing — the hint asks the proposer to evaluate
|
|
129
|
+
* whether the focused target could prevent the signals' recurrence; it does
|
|
130
|
+
* NOT claim the focused target caused them. Optional; absent on ordinary
|
|
131
|
+
* heuristic hints and on legacy persisted hints.
|
|
132
|
+
*/
|
|
133
|
+
origin?: 'policy-focus';
|
|
103
134
|
}
|
|
104
135
|
/**
|
|
105
136
|
* Result of `validateLearnEvolutionHint`.
|
|
@@ -76,6 +76,14 @@ function validateEvidenceItem(item, index, errors) {
|
|
|
76
76
|
else if (!EVIDENCE_SEVERITY_SET.has(item.severity)) {
|
|
77
77
|
errors.push(`${path}.severity must be one of low|medium|high|critical (got "${item.severity}")`);
|
|
78
78
|
}
|
|
79
|
+
// Optional fields are validated ONLY when present, so legacy persisted hints
|
|
80
|
+
// (which predate them) keep validating unchanged.
|
|
81
|
+
if (item.provenance !== undefined && item.provenance !== 'observed' && item.provenance !== 'authored') {
|
|
82
|
+
errors.push(`${path}.provenance must be 'observed' or 'authored' when present`);
|
|
83
|
+
}
|
|
84
|
+
if (item.address !== undefined) {
|
|
85
|
+
pushNonEmptyStringError(errors, `${path}.address`, item.address);
|
|
86
|
+
}
|
|
79
87
|
}
|
|
80
88
|
/**
|
|
81
89
|
* Runtime contract enforcer for `LearnEvolutionHint`.
|
|
@@ -144,6 +152,14 @@ export function validateLearnEvolutionHint(value) {
|
|
|
144
152
|
if (value.loss !== undefined && (typeof value.loss !== 'number' || Number.isNaN(value.loss))) {
|
|
145
153
|
errors.push('loss must be a number when present');
|
|
146
154
|
}
|
|
155
|
+
// Optional, validated only when present (legacy persisted hints lack it).
|
|
156
|
+
if (value.creditPaths !== undefined && !Array.isArray(value.creditPaths)) {
|
|
157
|
+
errors.push('creditPaths must be an array when present');
|
|
158
|
+
}
|
|
159
|
+
// Optional, validated only when present (ordinary heuristic hints lack it).
|
|
160
|
+
if (value.origin !== undefined && value.origin !== 'policy-focus') {
|
|
161
|
+
errors.push(`origin must be 'policy-focus' when present (got "${String(value.origin)}")`);
|
|
162
|
+
}
|
|
147
163
|
if (errors.length > 0) {
|
|
148
164
|
return { ok: false, errors };
|
|
149
165
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type LearnEvolutionHint } from './learn-hints.js';
|
|
2
2
|
import { type TargetEvolutionPolicy } from './target-evolution.js';
|
|
3
|
+
import { type CreditPath } from '../learn/credit-path.js';
|
|
3
4
|
import { type LearnReport, type LearnObservation } from '../learn.js';
|
|
4
5
|
/** The learn signals the interpreter reads (everything except the neutral observations). */
|
|
5
6
|
type LearnSignals = Omit<LearnReport, 'observations'>;
|
|
@@ -24,6 +25,8 @@ type LearnSignals = Omit<LearnReport, 'observations'>;
|
|
|
24
25
|
* should still wrap in try/catch and fall back to the registry source path.
|
|
25
26
|
*/
|
|
26
27
|
export declare function resolveTargetLocalFilesReadonly(targetId: string, repoRoot: string): Promise<string[]>;
|
|
28
|
+
/** Raw producing-target id for a path's last node (no policy annotation). */
|
|
29
|
+
export declare function producingTargetIdForCreditPath(creditPath: CreditPath): string | undefined;
|
|
27
30
|
/**
|
|
28
31
|
* Derive structured evolution hints from a learn report's signals.
|
|
29
32
|
*
|
|
@@ -47,6 +50,20 @@ export declare function generateEvolutionHints(report: LearnSignals, policy?: Ta
|
|
|
47
50
|
* hint entirely (no evolvable target of its kind exists).
|
|
48
51
|
*/
|
|
49
52
|
export declare function resolveKindOnlyPinTarget(draft: LearnEvolutionHint, policy: TargetEvolutionPolicy): string | undefined | null;
|
|
53
|
+
/**
|
|
54
|
+
* The evolution-focus target ids: the explicitly evolvable, REGISTERED
|
|
55
|
+
* canonical targets of a frozen-by-default policy, with the focus switch ON.
|
|
56
|
+
*
|
|
57
|
+
* Empty (focus inactive) when:
|
|
58
|
+
* - the switch is off (`selfEvolution.focus: false` / `learn --no-focus`),
|
|
59
|
+
* - the policy default is `evolvable` (nothing is dropped as frozen-kind in the
|
|
60
|
+
* way focus rescues — and "evolve everything" needs no focus), or
|
|
61
|
+
* - no explicit target survives (freeze-wins already resolved into `explicit`).
|
|
62
|
+
*
|
|
63
|
+
* Exported for the learn command's transparency rendering, so the printed focus
|
|
64
|
+
* line cannot drift from the hint-synthesis pass.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveEvolutionFocusTargets(policy: TargetEvolutionPolicy | undefined): string[];
|
|
50
67
|
/**
|
|
51
68
|
* Surface an AMBIGUOUS kind-only evolution hint as an action-required
|
|
52
69
|
* observation. After {@link scopeHintsByPolicy} runs, a hint that still has no
|
|
@@ -63,12 +80,30 @@ export declare function resolveKindOnlyPinTarget(draft: LearnEvolutionHint, poli
|
|
|
63
80
|
* unbindable, keeping learn output byte-identical in the common case.
|
|
64
81
|
*/
|
|
65
82
|
export declare function detectUnbindableHintObservations(hints: LearnEvolutionHint[], policy: TargetEvolutionPolicy | undefined): LearnObservation[];
|
|
83
|
+
/**
|
|
84
|
+
* Surface health offenders whose routing lands on a FROZEN target as ONE
|
|
85
|
+
* aggregated ACTION-REQUIRED observation — the honest dead-end. Without this,
|
|
86
|
+
* a freezing policy makes the offender signal vanish silently: the enrichment
|
|
87
|
+
* in {@link generateEvolutionHints} only rides on drafts that survive scoping.
|
|
88
|
+
* Mirrors {@link detectUnbindableHintObservations}' shape and wiring (call it
|
|
89
|
+
* wherever that one is called, on evolving runs). Returns `[]` when `policy`
|
|
90
|
+
* is absent or the routing target is evolvable — the enrichment path already
|
|
91
|
+
* carries the signal there — so the common case stays byte-identical.
|
|
92
|
+
*/
|
|
93
|
+
export declare function detectFrozenHealthRoutingObservations(report: LearnSignals, policy?: TargetEvolutionPolicy): LearnObservation[];
|
|
66
94
|
/**
|
|
67
95
|
* Persist hints to the canonical handoff path that `propose-canonical
|
|
68
96
|
* --from-learn` reads (`{ evolutionHints: [...] }`). This is the one-motion
|
|
69
97
|
* learn → propose bridge: it writes an ARTIFACT under `learn-handoffs/` (never a
|
|
70
98
|
* canonical file), so it is proposal-only. Reuses the existing
|
|
71
99
|
* `learn-handoffs/<change>/<timestamp>/` convention. Returns the file path.
|
|
100
|
+
*
|
|
101
|
+
* When any hint carries credit paths, a sibling `slice.md` is written next to
|
|
102
|
+
* `hints.json` (and referenced via the optional top-level `slice` key) so the
|
|
103
|
+
* HOST author on the `--from-edits` path can read the real artifact text along
|
|
104
|
+
* the failing paths — the same CREDIT-PATH SLICE the `--agent` prompt renders.
|
|
105
|
+
* Old readers ignore unknown top-level keys (`extractHintCandidates` reads only
|
|
106
|
+
* the hint arrays), so the addition is back-compatible.
|
|
72
107
|
*/
|
|
73
108
|
export declare function persistLearnHints(opts: {
|
|
74
109
|
projectRoot: string;
|